cdbc_pg/
type_info.rs

1#![allow(dead_code)]
2
3use std::borrow::Cow;
4use std::fmt::{self, Display, Formatter};
5use std::ops::Deref;
6use std::sync::Arc;
7
8use cdbc::utils::ustr::UStr;
9use cdbc::type_info::TypeInfo;
10
11
12/// Type information for a PostgreSQL type.
13#[derive(Debug, Clone, PartialEq)]
14#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
15pub struct PgTypeInfo(pub(crate) PgType);
16
17impl Deref for PgTypeInfo {
18    type Target = PgType;
19
20    fn deref(&self) -> &Self::Target {
21        &self.0
22    }
23}
24
25#[derive(Debug, Clone)]
26#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
27#[repr(u32)]
28pub enum PgType {
29    Bool,
30    Bytea,
31    Char,
32    Name,
33    Int8,
34    Int2,
35    Int4,
36    Text,
37    Oid,
38    Json,
39    JsonArray,
40    Point,
41    Lseg,
42    Path,
43    Box,
44    Polygon,
45    Line,
46    LineArray,
47    Cidr,
48    CidrArray,
49    Float4,
50    Float8,
51    Unknown,
52    Circle,
53    CircleArray,
54    Macaddr8,
55    Macaddr8Array,
56    Macaddr,
57    Inet,
58    BoolArray,
59    ByteaArray,
60    CharArray,
61    NameArray,
62    Int2Array,
63    Int4Array,
64    TextArray,
65    BpcharArray,
66    VarcharArray,
67    Int8Array,
68    PointArray,
69    LsegArray,
70    PathArray,
71    BoxArray,
72    Float4Array,
73    Float8Array,
74    PolygonArray,
75    OidArray,
76    MacaddrArray,
77    InetArray,
78    Bpchar,
79    Varchar,
80    Date,
81    Time,
82    Timestamp,
83    TimestampArray,
84    DateArray,
85    TimeArray,
86    Timestamptz,
87    TimestamptzArray,
88    Interval,
89    IntervalArray,
90    NumericArray,
91    Timetz,
92    TimetzArray,
93    Bit,
94    BitArray,
95    Varbit,
96    VarbitArray,
97    Numeric,
98    Record,
99    RecordArray,
100    Uuid,
101    UuidArray,
102    Jsonb,
103    JsonbArray,
104    Int4Range,
105    Int4RangeArray,
106    NumRange,
107    NumRangeArray,
108    TsRange,
109    TsRangeArray,
110    TstzRange,
111    TstzRangeArray,
112    DateRange,
113    DateRangeArray,
114    Int8Range,
115    Int8RangeArray,
116    Jsonpath,
117    JsonpathArray,
118    Money,
119    MoneyArray,
120
121    // https://www.postgresql.org/docs/9.3/datatype-pseudo.html
122    Void,
123
124    // A realized user-defined type. When a connection sees a DeclareXX variant it resolves
125    // into this one before passing it along to `accepts` or inside of `Value` objects.
126    Custom(Arc<PgCustomType>),
127
128    // From [`PgTypeInfo::with_name`]
129    DeclareWithName(UStr),
130
131    // NOTE: Do we want to bring back type declaration by ID? It's notoriously fragile but
132    //       someone may have a user for it
133    DeclareWithOid(u32),
134}
135
136#[derive(Debug, Clone)]
137#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
138pub struct PgCustomType {
139    #[cfg_attr(feature = "offline", serde(skip))]
140    pub(crate) oid: u32,
141    pub(crate) name: UStr,
142    pub(crate) kind: PgTypeKind,
143}
144
145#[derive(Debug, Clone)]
146#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
147pub enum PgTypeKind {
148    Simple,
149    Pseudo,
150    Domain(PgTypeInfo),
151    Composite(Arc<[(String, PgTypeInfo)]>),
152    Array(PgTypeInfo),
153    Enum(Arc<[String]>),
154    Range(PgTypeInfo),
155}
156
157impl PgTypeInfo {
158    /// Returns the corresponding `PgTypeInfo` if the OID is a built-in type and recognized by SQLx.
159    pub(crate) fn try_from_oid(oid: u32) -> Option<Self> {
160        PgType::try_from_oid(oid).map(Self)
161    }
162
163    /// Returns the _kind_ (simple, array, enum, etc.) for this type.
164    pub fn kind(&self) -> &PgTypeKind {
165        self.0.kind()
166    }
167
168    #[doc(hidden)]
169    pub fn __type_feature_gate(&self) -> Option<&'static str> {
170        if [
171            PgTypeInfo::DATE,
172            PgTypeInfo::TIME,
173            PgTypeInfo::TIMESTAMP,
174            PgTypeInfo::TIMESTAMPTZ,
175            PgTypeInfo::DATE_ARRAY,
176            PgTypeInfo::TIME_ARRAY,
177            PgTypeInfo::TIMESTAMP_ARRAY,
178            PgTypeInfo::TIMESTAMPTZ_ARRAY,
179        ]
180            .contains(self)
181        {
182            Some("time")
183        } else if [PgTypeInfo::UUID, PgTypeInfo::UUID_ARRAY].contains(self) {
184            Some("uuid")
185        } else if [
186            PgTypeInfo::JSON,
187            PgTypeInfo::JSONB,
188            PgTypeInfo::JSON_ARRAY,
189            PgTypeInfo::JSONB_ARRAY,
190        ]
191            .contains(self)
192        {
193            Some("json")
194        } else if [
195            PgTypeInfo::CIDR,
196            PgTypeInfo::INET,
197            PgTypeInfo::CIDR_ARRAY,
198            PgTypeInfo::INET_ARRAY,
199        ]
200            .contains(self)
201        {
202            Some("ipnetwork")
203        } else if [PgTypeInfo::MACADDR].contains(self) {
204            Some("mac_address")
205        } else if [PgTypeInfo::NUMERIC, PgTypeInfo::NUMERIC_ARRAY].contains(self) {
206            Some("bigdecimal")
207        } else {
208            None
209        }
210    }
211
212    /// Create a `PgTypeInfo` from a type name.
213    ///
214    /// The OID for the type will be fetched from Postgres on use of
215    /// a value of this type. The fetched OID will be cached per-connection.
216    pub const fn with_name(name: &'static str) -> Self {
217        Self(PgType::DeclareWithName(UStr::Static(name)))
218    }
219
220    /// Create a `PgTypeInfo` from an OID.
221    ///
222    /// Note that the OID for a type is very dependent on the environment. If you only ever use
223    /// one database or if this is an unhandled build-in type, you should be fine. Otherwise,
224    /// you will be better served using [`with_name`](Self::with_name).
225    pub const fn with_oid(oid: u32) -> Self {
226        Self(PgType::DeclareWithOid(oid))
227    }
228}
229
230// DEVELOPER PRO TIP: find builtin type OIDs easily by grepping this file
231// https://github.com/postgres/postgres/blob/master/src/include/catalog/pg_type.dat
232//
233// If you have Postgres running locally you can also try
234// SELECT oid, typarray FROM pg_type where typname = '<type name>'
235
236impl PgType {
237    /// Returns the corresponding `PgType` if the OID is a built-in type and recognized by SQLx.
238    pub(crate) fn try_from_oid(oid: u32) -> Option<Self> {
239        Some(match oid {
240            16 => PgType::Bool,
241            17 => PgType::Bytea,
242            18 => PgType::Char,
243            19 => PgType::Name,
244            20 => PgType::Int8,
245            21 => PgType::Int2,
246            23 => PgType::Int4,
247            25 => PgType::Text,
248            26 => PgType::Oid,
249            114 => PgType::Json,
250            199 => PgType::JsonArray,
251            600 => PgType::Point,
252            601 => PgType::Lseg,
253            602 => PgType::Path,
254            603 => PgType::Box,
255            604 => PgType::Polygon,
256            628 => PgType::Line,
257            629 => PgType::LineArray,
258            650 => PgType::Cidr,
259            651 => PgType::CidrArray,
260            700 => PgType::Float4,
261            701 => PgType::Float8,
262            705 => PgType::Unknown,
263            718 => PgType::Circle,
264            719 => PgType::CircleArray,
265            774 => PgType::Macaddr8,
266            775 => PgType::Macaddr8Array,
267            790 => PgType::Money,
268            791 => PgType::MoneyArray,
269            829 => PgType::Macaddr,
270            869 => PgType::Inet,
271            1000 => PgType::BoolArray,
272            1001 => PgType::ByteaArray,
273            1002 => PgType::CharArray,
274            1003 => PgType::NameArray,
275            1005 => PgType::Int2Array,
276            1007 => PgType::Int4Array,
277            1009 => PgType::TextArray,
278            1014 => PgType::BpcharArray,
279            1015 => PgType::VarcharArray,
280            1016 => PgType::Int8Array,
281            1017 => PgType::PointArray,
282            1018 => PgType::LsegArray,
283            1019 => PgType::PathArray,
284            1020 => PgType::BoxArray,
285            1021 => PgType::Float4Array,
286            1022 => PgType::Float8Array,
287            1027 => PgType::PolygonArray,
288            1028 => PgType::OidArray,
289            1040 => PgType::MacaddrArray,
290            1041 => PgType::InetArray,
291            1042 => PgType::Bpchar,
292            1043 => PgType::Varchar,
293            1082 => PgType::Date,
294            1083 => PgType::Time,
295            1114 => PgType::Timestamp,
296            1115 => PgType::TimestampArray,
297            1182 => PgType::DateArray,
298            1183 => PgType::TimeArray,
299            1184 => PgType::Timestamptz,
300            1185 => PgType::TimestamptzArray,
301            1186 => PgType::Interval,
302            1187 => PgType::IntervalArray,
303            1231 => PgType::NumericArray,
304            1266 => PgType::Timetz,
305            1270 => PgType::TimetzArray,
306            1560 => PgType::Bit,
307            1561 => PgType::BitArray,
308            1562 => PgType::Varbit,
309            1563 => PgType::VarbitArray,
310            1700 => PgType::Numeric,
311            2278 => PgType::Void,
312            2249 => PgType::Record,
313            2287 => PgType::RecordArray,
314            2950 => PgType::Uuid,
315            2951 => PgType::UuidArray,
316            3802 => PgType::Jsonb,
317            3807 => PgType::JsonbArray,
318            3904 => PgType::Int4Range,
319            3905 => PgType::Int4RangeArray,
320            3906 => PgType::NumRange,
321            3907 => PgType::NumRangeArray,
322            3908 => PgType::TsRange,
323            3909 => PgType::TsRangeArray,
324            3910 => PgType::TstzRange,
325            3911 => PgType::TstzRangeArray,
326            3912 => PgType::DateRange,
327            3913 => PgType::DateRangeArray,
328            3926 => PgType::Int8Range,
329            3927 => PgType::Int8RangeArray,
330            4072 => PgType::Jsonpath,
331            4073 => PgType::JsonpathArray,
332
333            _ => {
334                return None;
335            }
336        })
337    }
338
339    pub(crate) fn oid(&self) -> u32 {
340        match self.try_oid() {
341            Some(oid) => oid,
342            None => unreachable!("(bug) use of unresolved type declaration [oid]"),
343        }
344    }
345
346    pub(crate) fn try_oid(&self) -> Option<u32> {
347        Some(match self {
348            PgType::Bool => 16,
349            PgType::Bytea => 17,
350            PgType::Char => 18,
351            PgType::Name => 19,
352            PgType::Int8 => 20,
353            PgType::Int2 => 21,
354            PgType::Int4 => 23,
355            PgType::Text => 25,
356            PgType::Oid => 26,
357            PgType::Json => 114,
358            PgType::JsonArray => 199,
359            PgType::Point => 600,
360            PgType::Lseg => 601,
361            PgType::Path => 602,
362            PgType::Box => 603,
363            PgType::Polygon => 604,
364            PgType::Line => 628,
365            PgType::LineArray => 629,
366            PgType::Cidr => 650,
367            PgType::CidrArray => 651,
368            PgType::Float4 => 700,
369            PgType::Float8 => 701,
370            PgType::Unknown => 705,
371            PgType::Circle => 718,
372            PgType::CircleArray => 719,
373            PgType::Macaddr8 => 774,
374            PgType::Macaddr8Array => 775,
375            PgType::Money => 790,
376            PgType::MoneyArray => 791,
377            PgType::Macaddr => 829,
378            PgType::Inet => 869,
379            PgType::BoolArray => 1000,
380            PgType::ByteaArray => 1001,
381            PgType::CharArray => 1002,
382            PgType::NameArray => 1003,
383            PgType::Int2Array => 1005,
384            PgType::Int4Array => 1007,
385            PgType::TextArray => 1009,
386            PgType::BpcharArray => 1014,
387            PgType::VarcharArray => 1015,
388            PgType::Int8Array => 1016,
389            PgType::PointArray => 1017,
390            PgType::LsegArray => 1018,
391            PgType::PathArray => 1019,
392            PgType::BoxArray => 1020,
393            PgType::Float4Array => 1021,
394            PgType::Float8Array => 1022,
395            PgType::PolygonArray => 1027,
396            PgType::OidArray => 1028,
397            PgType::MacaddrArray => 1040,
398            PgType::InetArray => 1041,
399            PgType::Bpchar => 1042,
400            PgType::Varchar => 1043,
401            PgType::Date => 1082,
402            PgType::Time => 1083,
403            PgType::Timestamp => 1114,
404            PgType::TimestampArray => 1115,
405            PgType::DateArray => 1182,
406            PgType::TimeArray => 1183,
407            PgType::Timestamptz => 1184,
408            PgType::TimestamptzArray => 1185,
409            PgType::Interval => 1186,
410            PgType::IntervalArray => 1187,
411            PgType::NumericArray => 1231,
412            PgType::Timetz => 1266,
413            PgType::TimetzArray => 1270,
414            PgType::Bit => 1560,
415            PgType::BitArray => 1561,
416            PgType::Varbit => 1562,
417            PgType::VarbitArray => 1563,
418            PgType::Numeric => 1700,
419            PgType::Void => 2278,
420            PgType::Record => 2249,
421            PgType::RecordArray => 2287,
422            PgType::Uuid => 2950,
423            PgType::UuidArray => 2951,
424            PgType::Jsonb => 3802,
425            PgType::JsonbArray => 3807,
426            PgType::Int4Range => 3904,
427            PgType::Int4RangeArray => 3905,
428            PgType::NumRange => 3906,
429            PgType::NumRangeArray => 3907,
430            PgType::TsRange => 3908,
431            PgType::TsRangeArray => 3909,
432            PgType::TstzRange => 3910,
433            PgType::TstzRangeArray => 3911,
434            PgType::DateRange => 3912,
435            PgType::DateRangeArray => 3913,
436            PgType::Int8Range => 3926,
437            PgType::Int8RangeArray => 3927,
438            PgType::Jsonpath => 4072,
439            PgType::JsonpathArray => 4073,
440            PgType::Custom(ty) => ty.oid,
441
442            PgType::DeclareWithOid(oid) => *oid,
443            PgType::DeclareWithName(_) => {
444                return None;
445            }
446        })
447    }
448
449    pub(crate) fn display_name(&self) -> &str {
450        match self {
451            PgType::Bool => "BOOL",
452            PgType::Bytea => "BYTEA",
453            PgType::Char => "\"CHAR\"",
454            PgType::Name => "NAME",
455            PgType::Int8 => "INT8",
456            PgType::Int2 => "INT2",
457            PgType::Int4 => "INT4",
458            PgType::Text => "TEXT",
459            PgType::Oid => "OID",
460            PgType::Json => "JSON",
461            PgType::JsonArray => "JSON[]",
462            PgType::Point => "POINT",
463            PgType::Lseg => "LSEG",
464            PgType::Path => "PATH",
465            PgType::Box => "BOX",
466            PgType::Polygon => "POLYGON",
467            PgType::Line => "LINE",
468            PgType::LineArray => "LINE[]",
469            PgType::Cidr => "CIDR",
470            PgType::CidrArray => "CIDR[]",
471            PgType::Float4 => "FLOAT4",
472            PgType::Float8 => "FLOAT8",
473            PgType::Unknown => "UNKNOWN",
474            PgType::Circle => "CIRCLE",
475            PgType::CircleArray => "CIRCLE[]",
476            PgType::Macaddr8 => "MACADDR8",
477            PgType::Macaddr8Array => "MACADDR8[]",
478            PgType::Macaddr => "MACADDR",
479            PgType::Inet => "INET",
480            PgType::BoolArray => "BOOL[]",
481            PgType::ByteaArray => "BYTEA[]",
482            PgType::CharArray => "\"CHAR\"[]",
483            PgType::NameArray => "NAME[]",
484            PgType::Int2Array => "INT2[]",
485            PgType::Int4Array => "INT4[]",
486            PgType::TextArray => "TEXT[]",
487            PgType::BpcharArray => "CHAR[]",
488            PgType::VarcharArray => "VARCHAR[]",
489            PgType::Int8Array => "INT8[]",
490            PgType::PointArray => "POINT[]",
491            PgType::LsegArray => "LSEG[]",
492            PgType::PathArray => "PATH[]",
493            PgType::BoxArray => "BOX[]",
494            PgType::Float4Array => "FLOAT4[]",
495            PgType::Float8Array => "FLOAT8[]",
496            PgType::PolygonArray => "POLYGON[]",
497            PgType::OidArray => "OID[]",
498            PgType::MacaddrArray => "MACADDR[]",
499            PgType::InetArray => "INET[]",
500            PgType::Bpchar => "CHAR",
501            PgType::Varchar => "VARCHAR",
502            PgType::Date => "DATE",
503            PgType::Time => "TIME",
504            PgType::Timestamp => "TIMESTAMP",
505            PgType::TimestampArray => "TIMESTAMP[]",
506            PgType::DateArray => "DATE[]",
507            PgType::TimeArray => "TIME[]",
508            PgType::Timestamptz => "TIMESTAMPTZ",
509            PgType::TimestamptzArray => "TIMESTAMPTZ[]",
510            PgType::Interval => "INTERVAL",
511            PgType::IntervalArray => "INTERVAL[]",
512            PgType::NumericArray => "NUMERIC[]",
513            PgType::Timetz => "TIMETZ",
514            PgType::TimetzArray => "TIMETZ[]",
515            PgType::Bit => "BIT",
516            PgType::BitArray => "BIT[]",
517            PgType::Varbit => "VARBIT",
518            PgType::VarbitArray => "VARBIT[]",
519            PgType::Numeric => "NUMERIC",
520            PgType::Record => "RECORD",
521            PgType::RecordArray => "RECORD[]",
522            PgType::Uuid => "UUID",
523            PgType::UuidArray => "UUID[]",
524            PgType::Jsonb => "JSONB",
525            PgType::JsonbArray => "JSONB[]",
526            PgType::Int4Range => "INT4RANGE",
527            PgType::Int4RangeArray => "INT4RANGE[]",
528            PgType::NumRange => "NUMRANGE",
529            PgType::NumRangeArray => "NUMRANGE[]",
530            PgType::TsRange => "TSRANGE",
531            PgType::TsRangeArray => "TSRANGE[]",
532            PgType::TstzRange => "TSTZRANGE",
533            PgType::TstzRangeArray => "TSTZRANGE[]",
534            PgType::DateRange => "DATERANGE",
535            PgType::DateRangeArray => "DATERANGE[]",
536            PgType::Int8Range => "INT8RANGE",
537            PgType::Int8RangeArray => "INT8RANGE[]",
538            PgType::Jsonpath => "JSONPATH",
539            PgType::JsonpathArray => "JSONPATH[]",
540            PgType::Money => "MONEY",
541            PgType::MoneyArray => "MONEY[]",
542            PgType::Void => "VOID",
543            PgType::Custom(ty) => &*ty.name,
544            PgType::DeclareWithOid(_) => "?",
545            PgType::DeclareWithName(name) => name,
546        }
547    }
548
549    pub(crate) fn name(&self) -> &str {
550        match self {
551            PgType::Bool => "bool",
552            PgType::Bytea => "bytea",
553            PgType::Char => "char",
554            PgType::Name => "name",
555            PgType::Int8 => "int8",
556            PgType::Int2 => "int2",
557            PgType::Int4 => "int4",
558            PgType::Text => "text",
559            PgType::Oid => "oid",
560            PgType::Json => "json",
561            PgType::JsonArray => "_json",
562            PgType::Point => "point",
563            PgType::Lseg => "lseg",
564            PgType::Path => "path",
565            PgType::Box => "box",
566            PgType::Polygon => "polygon",
567            PgType::Line => "line",
568            PgType::LineArray => "_line",
569            PgType::Cidr => "cidr",
570            PgType::CidrArray => "_cidr",
571            PgType::Float4 => "float4",
572            PgType::Float8 => "float8",
573            PgType::Unknown => "unknown",
574            PgType::Circle => "circle",
575            PgType::CircleArray => "_circle",
576            PgType::Macaddr8 => "macaddr8",
577            PgType::Macaddr8Array => "_macaddr8",
578            PgType::Macaddr => "macaddr",
579            PgType::Inet => "inet",
580            PgType::BoolArray => "_bool",
581            PgType::ByteaArray => "_bytea",
582            PgType::CharArray => "_char",
583            PgType::NameArray => "_name",
584            PgType::Int2Array => "_int2",
585            PgType::Int4Array => "_int4",
586            PgType::TextArray => "_text",
587            PgType::BpcharArray => "_bpchar",
588            PgType::VarcharArray => "_varchar",
589            PgType::Int8Array => "_int8",
590            PgType::PointArray => "_point",
591            PgType::LsegArray => "_lseg",
592            PgType::PathArray => "_path",
593            PgType::BoxArray => "_box",
594            PgType::Float4Array => "_float4",
595            PgType::Float8Array => "_float8",
596            PgType::PolygonArray => "_polygon",
597            PgType::OidArray => "_oid",
598            PgType::MacaddrArray => "_macaddr",
599            PgType::InetArray => "_inet",
600            PgType::Bpchar => "bpchar",
601            PgType::Varchar => "varchar",
602            PgType::Date => "date",
603            PgType::Time => "time",
604            PgType::Timestamp => "timestamp",
605            PgType::TimestampArray => "_timestamp",
606            PgType::DateArray => "_date",
607            PgType::TimeArray => "_time",
608            PgType::Timestamptz => "timestamptz",
609            PgType::TimestamptzArray => "_timestamptz",
610            PgType::Interval => "interval",
611            PgType::IntervalArray => "_interval",
612            PgType::NumericArray => "_numeric",
613            PgType::Timetz => "timetz",
614            PgType::TimetzArray => "_timetz",
615            PgType::Bit => "bit",
616            PgType::BitArray => "_bit",
617            PgType::Varbit => "varbit",
618            PgType::VarbitArray => "_varbit",
619            PgType::Numeric => "numeric",
620            PgType::Record => "record",
621            PgType::RecordArray => "_record",
622            PgType::Uuid => "uuid",
623            PgType::UuidArray => "_uuid",
624            PgType::Jsonb => "jsonb",
625            PgType::JsonbArray => "_jsonb",
626            PgType::Int4Range => "int4range",
627            PgType::Int4RangeArray => "_int4range",
628            PgType::NumRange => "numrange",
629            PgType::NumRangeArray => "_numrange",
630            PgType::TsRange => "tsrange",
631            PgType::TsRangeArray => "_tsrange",
632            PgType::TstzRange => "tstzrange",
633            PgType::TstzRangeArray => "_tstzrange",
634            PgType::DateRange => "daterange",
635            PgType::DateRangeArray => "_daterange",
636            PgType::Int8Range => "int8range",
637            PgType::Int8RangeArray => "_int8range",
638            PgType::Jsonpath => "jsonpath",
639            PgType::JsonpathArray => "_jsonpath",
640            PgType::Money => "money",
641            PgType::MoneyArray => "_money",
642            PgType::Void => "void",
643            PgType::Custom(ty) => &*ty.name,
644            PgType::DeclareWithOid(_) => "?",
645            PgType::DeclareWithName(name) => name,
646        }
647    }
648
649    pub(crate) fn kind(&self) -> &PgTypeKind {
650        match self {
651            PgType::Bool => &PgTypeKind::Simple,
652            PgType::Bytea => &PgTypeKind::Simple,
653            PgType::Char => &PgTypeKind::Simple,
654            PgType::Name => &PgTypeKind::Simple,
655            PgType::Int8 => &PgTypeKind::Simple,
656            PgType::Int2 => &PgTypeKind::Simple,
657            PgType::Int4 => &PgTypeKind::Simple,
658            PgType::Text => &PgTypeKind::Simple,
659            PgType::Oid => &PgTypeKind::Simple,
660            PgType::Json => &PgTypeKind::Simple,
661            PgType::JsonArray => &PgTypeKind::Array(PgTypeInfo(PgType::Json)),
662            PgType::Point => &PgTypeKind::Simple,
663            PgType::Lseg => &PgTypeKind::Simple,
664            PgType::Path => &PgTypeKind::Simple,
665            PgType::Box => &PgTypeKind::Simple,
666            PgType::Polygon => &PgTypeKind::Simple,
667            PgType::Line => &PgTypeKind::Simple,
668            PgType::LineArray => &PgTypeKind::Array(PgTypeInfo(PgType::Line)),
669            PgType::Cidr => &PgTypeKind::Simple,
670            PgType::CidrArray => &PgTypeKind::Array(PgTypeInfo(PgType::Cidr)),
671            PgType::Float4 => &PgTypeKind::Simple,
672            PgType::Float8 => &PgTypeKind::Simple,
673            PgType::Unknown => &PgTypeKind::Simple,
674            PgType::Circle => &PgTypeKind::Simple,
675            PgType::CircleArray => &PgTypeKind::Array(PgTypeInfo(PgType::Circle)),
676            PgType::Macaddr8 => &PgTypeKind::Simple,
677            PgType::Macaddr8Array => &PgTypeKind::Array(PgTypeInfo(PgType::Macaddr8)),
678            PgType::Macaddr => &PgTypeKind::Simple,
679            PgType::Inet => &PgTypeKind::Simple,
680            PgType::BoolArray => &PgTypeKind::Array(PgTypeInfo(PgType::Bool)),
681            PgType::ByteaArray => &PgTypeKind::Array(PgTypeInfo(PgType::Bytea)),
682            PgType::CharArray => &PgTypeKind::Array(PgTypeInfo(PgType::Char)),
683            PgType::NameArray => &PgTypeKind::Array(PgTypeInfo(PgType::Name)),
684            PgType::Int2Array => &PgTypeKind::Array(PgTypeInfo(PgType::Int2)),
685            PgType::Int4Array => &PgTypeKind::Array(PgTypeInfo(PgType::Int4)),
686            PgType::TextArray => &PgTypeKind::Array(PgTypeInfo(PgType::Text)),
687            PgType::BpcharArray => &PgTypeKind::Array(PgTypeInfo(PgType::Bpchar)),
688            PgType::VarcharArray => &PgTypeKind::Array(PgTypeInfo(PgType::Varchar)),
689            PgType::Int8Array => &PgTypeKind::Array(PgTypeInfo(PgType::Int8)),
690            PgType::PointArray => &PgTypeKind::Array(PgTypeInfo(PgType::Point)),
691            PgType::LsegArray => &PgTypeKind::Array(PgTypeInfo(PgType::Lseg)),
692            PgType::PathArray => &PgTypeKind::Array(PgTypeInfo(PgType::Path)),
693            PgType::BoxArray => &PgTypeKind::Array(PgTypeInfo(PgType::Box)),
694            PgType::Float4Array => &PgTypeKind::Array(PgTypeInfo(PgType::Float4)),
695            PgType::Float8Array => &PgTypeKind::Array(PgTypeInfo(PgType::Float8)),
696            PgType::PolygonArray => &PgTypeKind::Array(PgTypeInfo(PgType::Polygon)),
697            PgType::OidArray => &PgTypeKind::Array(PgTypeInfo(PgType::Oid)),
698            PgType::MacaddrArray => &PgTypeKind::Array(PgTypeInfo(PgType::Macaddr)),
699            PgType::InetArray => &PgTypeKind::Array(PgTypeInfo(PgType::Inet)),
700            PgType::Bpchar => &PgTypeKind::Simple,
701            PgType::Varchar => &PgTypeKind::Simple,
702            PgType::Date => &PgTypeKind::Simple,
703            PgType::Time => &PgTypeKind::Simple,
704            PgType::Timestamp => &PgTypeKind::Simple,
705            PgType::TimestampArray => &PgTypeKind::Array(PgTypeInfo(PgType::Timestamp)),
706            PgType::DateArray => &PgTypeKind::Array(PgTypeInfo(PgType::Date)),
707            PgType::TimeArray => &PgTypeKind::Array(PgTypeInfo(PgType::Time)),
708            PgType::Timestamptz => &PgTypeKind::Simple,
709            PgType::TimestamptzArray => &PgTypeKind::Array(PgTypeInfo(PgType::Timestamptz)),
710            PgType::Interval => &PgTypeKind::Simple,
711            PgType::IntervalArray => &PgTypeKind::Array(PgTypeInfo(PgType::Interval)),
712            PgType::NumericArray => &PgTypeKind::Array(PgTypeInfo(PgType::Numeric)),
713            PgType::Timetz => &PgTypeKind::Simple,
714            PgType::TimetzArray => &PgTypeKind::Array(PgTypeInfo(PgType::Timetz)),
715            PgType::Bit => &PgTypeKind::Simple,
716            PgType::BitArray => &PgTypeKind::Array(PgTypeInfo(PgType::Bit)),
717            PgType::Varbit => &PgTypeKind::Simple,
718            PgType::VarbitArray => &PgTypeKind::Array(PgTypeInfo(PgType::Varbit)),
719            PgType::Numeric => &PgTypeKind::Simple,
720            PgType::Record => &PgTypeKind::Simple,
721            PgType::RecordArray => &PgTypeKind::Array(PgTypeInfo(PgType::Record)),
722            PgType::Uuid => &PgTypeKind::Simple,
723            PgType::UuidArray => &PgTypeKind::Array(PgTypeInfo(PgType::Uuid)),
724            PgType::Jsonb => &PgTypeKind::Simple,
725            PgType::JsonbArray => &PgTypeKind::Array(PgTypeInfo(PgType::Jsonb)),
726            PgType::Int4Range => &PgTypeKind::Range(PgTypeInfo::INT4),
727            PgType::Int4RangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::Int4Range)),
728            PgType::NumRange => &PgTypeKind::Range(PgTypeInfo::NUMERIC),
729            PgType::NumRangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::NumRange)),
730            PgType::TsRange => &PgTypeKind::Range(PgTypeInfo::TIMESTAMP),
731            PgType::TsRangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::TsRange)),
732            PgType::TstzRange => &PgTypeKind::Range(PgTypeInfo::TIMESTAMPTZ),
733            PgType::TstzRangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::TstzRange)),
734            PgType::DateRange => &PgTypeKind::Range(PgTypeInfo::DATE),
735            PgType::DateRangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::DateRange)),
736            PgType::Int8Range => &PgTypeKind::Range(PgTypeInfo::INT8),
737            PgType::Int8RangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::Int8Range)),
738            PgType::Jsonpath => &PgTypeKind::Simple,
739            PgType::JsonpathArray => &PgTypeKind::Array(PgTypeInfo(PgType::Jsonpath)),
740            PgType::Money => &PgTypeKind::Simple,
741            PgType::MoneyArray => &PgTypeKind::Array(PgTypeInfo(PgType::Money)),
742
743            PgType::Void => &PgTypeKind::Pseudo,
744
745            PgType::Custom(ty) => &ty.kind,
746
747            PgType::DeclareWithOid(oid) => {
748                unreachable!("(bug) use of unresolved type declaration [oid={}]", oid);
749            }
750            PgType::DeclareWithName(name) => {
751                unreachable!("(bug) use of unresolved type declaration [name={}]", name);
752            }
753        }
754    }
755
756    /// If `self` is an array type, return the type info for its element.
757    ///
758    /// This method should only be called on resolved types: calling it on
759    /// a type that is merely declared (DeclareWithOid/Name) is a bug.
760    pub(crate) fn try_array_element(&self) -> Option<Cow<'_, PgTypeInfo>> {
761        // We explicitly match on all the `None` cases to ensure an exhaustive match.
762        match self {
763            PgType::Bool => None,
764            PgType::BoolArray => Some(Cow::Owned(PgTypeInfo(PgType::Bool))),
765            PgType::Bytea => None,
766            PgType::ByteaArray => Some(Cow::Owned(PgTypeInfo(PgType::Bytea))),
767            PgType::Char => None,
768            PgType::CharArray => Some(Cow::Owned(PgTypeInfo(PgType::Char))),
769            PgType::Name => None,
770            PgType::NameArray => Some(Cow::Owned(PgTypeInfo(PgType::Name))),
771            PgType::Int8 => None,
772            PgType::Int8Array => Some(Cow::Owned(PgTypeInfo(PgType::Int8))),
773            PgType::Int2 => None,
774            PgType::Int2Array => Some(Cow::Owned(PgTypeInfo(PgType::Int2))),
775            PgType::Int4 => None,
776            PgType::Int4Array => Some(Cow::Owned(PgTypeInfo(PgType::Int4))),
777            PgType::Text => None,
778            PgType::TextArray => Some(Cow::Owned(PgTypeInfo(PgType::Text))),
779            PgType::Oid => None,
780            PgType::OidArray => Some(Cow::Owned(PgTypeInfo(PgType::Oid))),
781            PgType::Json => None,
782            PgType::JsonArray => Some(Cow::Owned(PgTypeInfo(PgType::Json))),
783            PgType::Point => None,
784            PgType::PointArray => Some(Cow::Owned(PgTypeInfo(PgType::Point))),
785            PgType::Lseg => None,
786            PgType::LsegArray => Some(Cow::Owned(PgTypeInfo(PgType::Lseg))),
787            PgType::Path => None,
788            PgType::PathArray => Some(Cow::Owned(PgTypeInfo(PgType::Path))),
789            PgType::Box => None,
790            PgType::BoxArray => Some(Cow::Owned(PgTypeInfo(PgType::Box))),
791            PgType::Polygon => None,
792            PgType::PolygonArray => Some(Cow::Owned(PgTypeInfo(PgType::Polygon))),
793            PgType::Line => None,
794            PgType::LineArray => Some(Cow::Owned(PgTypeInfo(PgType::Line))),
795            PgType::Cidr => None,
796            PgType::CidrArray => Some(Cow::Owned(PgTypeInfo(PgType::Cidr))),
797            PgType::Float4 => None,
798            PgType::Float4Array => Some(Cow::Owned(PgTypeInfo(PgType::Float4))),
799            PgType::Float8 => None,
800            PgType::Float8Array => Some(Cow::Owned(PgTypeInfo(PgType::Float8))),
801            PgType::Circle => None,
802            PgType::CircleArray => Some(Cow::Owned(PgTypeInfo(PgType::Circle))),
803            PgType::Macaddr8 => None,
804            PgType::Macaddr8Array => Some(Cow::Owned(PgTypeInfo(PgType::Macaddr8))),
805            PgType::Money => None,
806            PgType::MoneyArray => Some(Cow::Owned(PgTypeInfo(PgType::Money))),
807            PgType::Macaddr => None,
808            PgType::MacaddrArray => Some(Cow::Owned(PgTypeInfo(PgType::Macaddr))),
809            PgType::Inet => None,
810            PgType::InetArray => Some(Cow::Owned(PgTypeInfo(PgType::Inet))),
811            PgType::Bpchar => None,
812            PgType::BpcharArray => Some(Cow::Owned(PgTypeInfo(PgType::Bpchar))),
813            PgType::Varchar => None,
814            PgType::VarcharArray => Some(Cow::Owned(PgTypeInfo(PgType::Varchar))),
815            PgType::Date => None,
816            PgType::DateArray => Some(Cow::Owned(PgTypeInfo(PgType::Date))),
817            PgType::Time => None,
818            PgType::TimeArray => Some(Cow::Owned(PgTypeInfo(PgType::Time))),
819            PgType::Timestamp => None,
820            PgType::TimestampArray => Some(Cow::Owned(PgTypeInfo(PgType::Timestamp))),
821            PgType::Timestamptz => None,
822            PgType::TimestamptzArray => Some(Cow::Owned(PgTypeInfo(PgType::Timestamptz))),
823            PgType::Interval => None,
824            PgType::IntervalArray => Some(Cow::Owned(PgTypeInfo(PgType::Interval))),
825            PgType::Timetz => None,
826            PgType::TimetzArray => Some(Cow::Owned(PgTypeInfo(PgType::Timetz))),
827            PgType::Bit => None,
828            PgType::BitArray => Some(Cow::Owned(PgTypeInfo(PgType::Bit))),
829            PgType::Varbit => None,
830            PgType::VarbitArray => Some(Cow::Owned(PgTypeInfo(PgType::Varbit))),
831            PgType::Numeric => None,
832            PgType::NumericArray => Some(Cow::Owned(PgTypeInfo(PgType::Numeric))),
833            PgType::Record => None,
834            PgType::RecordArray => Some(Cow::Owned(PgTypeInfo(PgType::Record))),
835            PgType::Uuid => None,
836            PgType::UuidArray => Some(Cow::Owned(PgTypeInfo(PgType::Uuid))),
837            PgType::Jsonb => None,
838            PgType::JsonbArray => Some(Cow::Owned(PgTypeInfo(PgType::Jsonb))),
839            PgType::Int4Range => None,
840            PgType::Int4RangeArray => Some(Cow::Owned(PgTypeInfo(PgType::Int4Range))),
841            PgType::NumRange => None,
842            PgType::NumRangeArray => Some(Cow::Owned(PgTypeInfo(PgType::NumRange))),
843            PgType::TsRange => None,
844            PgType::TsRangeArray => Some(Cow::Owned(PgTypeInfo(PgType::TsRange))),
845            PgType::TstzRange => None,
846            PgType::TstzRangeArray => Some(Cow::Owned(PgTypeInfo(PgType::TstzRange))),
847            PgType::DateRange => None,
848            PgType::DateRangeArray => Some(Cow::Owned(PgTypeInfo(PgType::DateRange))),
849            PgType::Int8Range => None,
850            PgType::Int8RangeArray => Some(Cow::Owned(PgTypeInfo(PgType::Int8Range))),
851            PgType::Jsonpath => None,
852            PgType::JsonpathArray => Some(Cow::Owned(PgTypeInfo(PgType::Jsonpath))),
853            // There is no `UnknownArray`
854            PgType::Unknown => None,
855            // There is no `VoidArray`
856            PgType::Void => None,
857            PgType::Custom(ty) => match &ty.kind {
858                PgTypeKind::Simple => None,
859                PgTypeKind::Pseudo => None,
860                PgTypeKind::Domain(_) => None,
861                PgTypeKind::Composite(_) => None,
862                PgTypeKind::Array(ref elem_type_info) => Some(Cow::Borrowed(elem_type_info)),
863                PgTypeKind::Enum(_) => None,
864                PgTypeKind::Range(_) => None,
865            },
866            PgType::DeclareWithOid(oid) => {
867                unreachable!("(bug) use of unresolved type declaration [oid={}]", oid);
868            }
869            PgType::DeclareWithName(name) => {
870                unreachable!("(bug) use of unresolved type declaration [name={}]", name);
871            }
872        }
873    }
874}
875
876impl TypeInfo for PgTypeInfo {
877    fn name(&self) -> &str {
878        self.0.display_name()
879    }
880
881    fn is_null(&self) -> bool {
882        false
883    }
884
885    fn is_void(&self) -> bool {
886        matches!(self.0, PgType::Void)
887    }
888}
889
890impl PartialEq<PgCustomType> for PgCustomType {
891    fn eq(&self, other: &PgCustomType) -> bool {
892        other.oid == self.oid
893    }
894}
895
896impl PgTypeInfo {
897    // boolean, state of true or false
898    pub(crate) const BOOL: Self = Self(PgType::Bool);
899    pub(crate) const BOOL_ARRAY: Self = Self(PgType::BoolArray);
900
901    // binary data types, variable-length binary string
902    pub(crate) const BYTEA: Self = Self(PgType::Bytea);
903    pub(crate) const BYTEA_ARRAY: Self = Self(PgType::ByteaArray);
904
905    // uuid
906    pub(crate) const UUID: Self = Self(PgType::Uuid);
907    pub(crate) const UUID_ARRAY: Self = Self(PgType::UuidArray);
908
909    // record
910    pub(crate) const RECORD: Self = Self(PgType::Record);
911    pub(crate) const RECORD_ARRAY: Self = Self(PgType::RecordArray);
912
913    //
914    // JSON types
915    // https://www.postgresql.org/docs/current/datatype-json.html
916    //
917
918    pub(crate) const JSON: Self = Self(PgType::Json);
919    pub(crate) const JSON_ARRAY: Self = Self(PgType::JsonArray);
920
921    pub(crate) const JSONB: Self = Self(PgType::Jsonb);
922    pub(crate) const JSONB_ARRAY: Self = Self(PgType::JsonbArray);
923
924    pub(crate) const JSONPATH: Self = Self(PgType::Jsonpath);
925    pub(crate) const JSONPATH_ARRAY: Self = Self(PgType::JsonpathArray);
926
927    //
928    // network address types
929    // https://www.postgresql.org/docs/current/datatype-net-types.html
930    //
931
932    pub(crate) const CIDR: Self = Self(PgType::Cidr);
933    pub(crate) const CIDR_ARRAY: Self = Self(PgType::CidrArray);
934
935    pub(crate) const INET: Self = Self(PgType::Inet);
936    pub(crate) const INET_ARRAY: Self = Self(PgType::InetArray);
937
938    pub(crate) const MACADDR: Self = Self(PgType::Macaddr);
939    pub(crate) const MACADDR_ARRAY: Self = Self(PgType::MacaddrArray);
940
941    pub(crate) const MACADDR8: Self = Self(PgType::Macaddr8);
942    pub(crate) const MACADDR8_ARRAY: Self = Self(PgType::Macaddr8Array);
943
944    //
945    // character types
946    // https://www.postgresql.org/docs/current/datatype-character.html
947    //
948
949    // internal type for object names
950    pub(crate) const NAME: Self = Self(PgType::Name);
951    pub(crate) const NAME_ARRAY: Self = Self(PgType::NameArray);
952
953    // character type, fixed-length, blank-padded
954    pub(crate) const BPCHAR: Self = Self(PgType::Bpchar);
955    pub(crate) const BPCHAR_ARRAY: Self = Self(PgType::BpcharArray);
956
957    // character type, variable-length with limit
958    pub(crate) const VARCHAR: Self = Self(PgType::Varchar);
959    pub(crate) const VARCHAR_ARRAY: Self = Self(PgType::VarcharArray);
960
961    // character type, variable-length
962    pub(crate) const TEXT: Self = Self(PgType::Text);
963    pub(crate) const TEXT_ARRAY: Self = Self(PgType::TextArray);
964
965    // unknown type, transmitted as text
966    pub(crate) const UNKNOWN: Self = Self(PgType::Unknown);
967
968    //
969    // numeric types
970    // https://www.postgresql.org/docs/current/datatype-numeric.html
971    //
972
973    // single-byte internal type
974    pub(crate) const CHAR: Self = Self(PgType::Char);
975    pub(crate) const CHAR_ARRAY: Self = Self(PgType::CharArray);
976
977    // internal type for type ids
978    pub(crate) const OID: Self = Self(PgType::Oid);
979    pub(crate) const OID_ARRAY: Self = Self(PgType::OidArray);
980
981    // small-range integer; -32768 to +32767
982    pub(crate) const INT2: Self = Self(PgType::Int2);
983    pub(crate) const INT2_ARRAY: Self = Self(PgType::Int2Array);
984
985    // typical choice for integer; -2147483648 to +2147483647
986    pub(crate) const INT4: Self = Self(PgType::Int4);
987    pub(crate) const INT4_ARRAY: Self = Self(PgType::Int4Array);
988
989    // large-range integer; -9223372036854775808 to +9223372036854775807
990    pub(crate) const INT8: Self = Self(PgType::Int8);
991    pub(crate) const INT8_ARRAY: Self = Self(PgType::Int8Array);
992
993    // variable-precision, inexact, 6 decimal digits precision
994    pub(crate) const FLOAT4: Self = Self(PgType::Float4);
995    pub(crate) const FLOAT4_ARRAY: Self = Self(PgType::Float4Array);
996
997    // variable-precision, inexact, 15 decimal digits precision
998    pub(crate) const FLOAT8: Self = Self(PgType::Float8);
999    pub(crate) const FLOAT8_ARRAY: Self = Self(PgType::Float8Array);
1000
1001    // user-specified precision, exact
1002    pub(crate) const NUMERIC: Self = Self(PgType::Numeric);
1003    pub(crate) const NUMERIC_ARRAY: Self = Self(PgType::NumericArray);
1004
1005    // user-specified precision, exact
1006    pub(crate) const MONEY: Self = Self(PgType::Money);
1007    pub(crate) const MONEY_ARRAY: Self = Self(PgType::MoneyArray);
1008
1009    //
1010    // date/time types
1011    // https://www.postgresql.org/docs/current/datatype-datetime.html
1012    //
1013
1014    // both date and time (no time zone)
1015    pub(crate) const TIMESTAMP: Self = Self(PgType::Timestamp);
1016    pub(crate) const TIMESTAMP_ARRAY: Self = Self(PgType::TimestampArray);
1017
1018    // both date and time (with time zone)
1019    pub(crate) const TIMESTAMPTZ: Self = Self(PgType::Timestamptz);
1020    pub(crate) const TIMESTAMPTZ_ARRAY: Self = Self(PgType::TimestamptzArray);
1021
1022    // date (no time of day)
1023    pub(crate) const DATE: Self = Self(PgType::Date);
1024    pub(crate) const DATE_ARRAY: Self = Self(PgType::DateArray);
1025
1026    // time of day (no date)
1027    pub(crate) const TIME: Self = Self(PgType::Time);
1028    pub(crate) const TIME_ARRAY: Self = Self(PgType::TimeArray);
1029
1030    // time of day (no date), with time zone
1031    pub(crate) const TIMETZ: Self = Self(PgType::Timetz);
1032    pub(crate) const TIMETZ_ARRAY: Self = Self(PgType::TimetzArray);
1033
1034    // time interval
1035    pub(crate) const INTERVAL: Self = Self(PgType::Interval);
1036    pub(crate) const INTERVAL_ARRAY: Self = Self(PgType::IntervalArray);
1037
1038    //
1039    // geometric types
1040    // https://www.postgresql.org/docs/current/datatype-geometric.html
1041    //
1042
1043    // point on a plane
1044    pub(crate) const POINT: Self = Self(PgType::Point);
1045    pub(crate) const POINT_ARRAY: Self = Self(PgType::PointArray);
1046
1047    // infinite line
1048    pub(crate) const LINE: Self = Self(PgType::Line);
1049    pub(crate) const LINE_ARRAY: Self = Self(PgType::LineArray);
1050
1051    // finite line segment
1052    pub(crate) const LSEG: Self = Self(PgType::Lseg);
1053    pub(crate) const LSEG_ARRAY: Self = Self(PgType::LsegArray);
1054
1055    // rectangular box
1056    pub(crate) const BOX: Self = Self(PgType::Box);
1057    pub(crate) const BOX_ARRAY: Self = Self(PgType::BoxArray);
1058
1059    // open or closed path
1060    pub(crate) const PATH: Self = Self(PgType::Path);
1061    pub(crate) const PATH_ARRAY: Self = Self(PgType::PathArray);
1062
1063    // polygon
1064    pub(crate) const POLYGON: Self = Self(PgType::Polygon);
1065    pub(crate) const POLYGON_ARRAY: Self = Self(PgType::PolygonArray);
1066
1067    // circle
1068    pub(crate) const CIRCLE: Self = Self(PgType::Circle);
1069    pub(crate) const CIRCLE_ARRAY: Self = Self(PgType::CircleArray);
1070
1071    //
1072    // bit string types
1073    // https://www.postgresql.org/docs/current/datatype-bit.html
1074    //
1075
1076    pub(crate) const BIT: Self = Self(PgType::Bit);
1077    pub(crate) const BIT_ARRAY: Self = Self(PgType::BitArray);
1078
1079    pub(crate) const VARBIT: Self = Self(PgType::Varbit);
1080    pub(crate) const VARBIT_ARRAY: Self = Self(PgType::VarbitArray);
1081
1082    //
1083    // range types
1084    // https://www.postgresql.org/docs/current/rangetypes.html
1085    //
1086
1087    pub(crate) const INT4_RANGE: Self = Self(PgType::Int4Range);
1088    pub(crate) const INT4_RANGE_ARRAY: Self = Self(PgType::Int4RangeArray);
1089
1090    pub(crate) const NUM_RANGE: Self = Self(PgType::NumRange);
1091    pub(crate) const NUM_RANGE_ARRAY: Self = Self(PgType::NumRangeArray);
1092
1093    pub(crate) const TS_RANGE: Self = Self(PgType::TsRange);
1094    pub(crate) const TS_RANGE_ARRAY: Self = Self(PgType::TsRangeArray);
1095
1096    pub(crate) const TSTZ_RANGE: Self = Self(PgType::TstzRange);
1097    pub(crate) const TSTZ_RANGE_ARRAY: Self = Self(PgType::TstzRangeArray);
1098
1099    pub(crate) const DATE_RANGE: Self = Self(PgType::DateRange);
1100    pub(crate) const DATE_RANGE_ARRAY: Self = Self(PgType::DateRangeArray);
1101
1102    pub(crate) const INT8_RANGE: Self = Self(PgType::Int8Range);
1103    pub(crate) const INT8_RANGE_ARRAY: Self = Self(PgType::Int8RangeArray);
1104
1105    //
1106    // pseudo types
1107    // https://www.postgresql.org/docs/9.3/datatype-pseudo.html
1108    //
1109
1110    pub(crate) const VOID: Self = Self(PgType::Void);
1111}
1112
1113impl Display for PgTypeInfo {
1114    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1115        f.pad(self.name())
1116    }
1117}
1118
1119impl PartialEq<PgType> for PgType {
1120    fn eq(&self, other: &PgType) -> bool {
1121        if let (Some(a), Some(b)) = (self.try_oid(), other.try_oid()) {
1122            // If there are OIDs available, use OIDs to perform a direct match
1123            a == b
1124        } else if matches!(
1125            (self, other),
1126            (PgType::DeclareWithName(_), PgType::DeclareWithOid(_))
1127                | (PgType::DeclareWithOid(_), PgType::DeclareWithName(_))
1128        ) {
1129            // One is a declare-with-name and the other is a declare-with-id
1130            // This only occurs in the TEXT protocol with custom types
1131            // Just opt-out of type checking here
1132            true
1133        } else {
1134            // Otherwise, perform a match on the name
1135            self.name().eq_ignore_ascii_case(other.name())
1136        }
1137    }
1138}