Skip to main content

rbdc_pg/
type_info.rs

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