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