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#[derive(Debug, Clone, PartialEq)]
43#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
44pub struct PgTypeInfo(pub(crate) PgType);
45
46impl Deref for PgTypeInfo {
47    type Target = PgType;
48
49    fn deref(&self) -> &Self::Target {
50        &self.0
51    }
52}
53
54#[derive(Debug, Clone)]
55#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
56#[repr(u32)]
57pub enum PgType {
58    Bool,
59    Bytea,
60    Char,
61    Name,
62    Int8,
63    Int2,
64    Int4,
65    Text,
66    Oid,
67    Json,
68    JsonArray,
69    Point,
70    Lseg,
71    Path,
72    Box,
73    Polygon,
74    Line,
75    LineArray,
76    Cidr,
77    CidrArray,
78    Float4,
79    Float8,
80    Unknown,
81    Circle,
82    CircleArray,
83    Macaddr8,
84    Macaddr8Array,
85    Macaddr,
86    Inet,
87    BoolArray,
88    ByteaArray,
89    CharArray,
90    NameArray,
91    Int2Array,
92    Int4Array,
93    TextArray,
94    BpcharArray,
95    VarcharArray,
96    Int8Array,
97    PointArray,
98    LsegArray,
99    PathArray,
100    BoxArray,
101    Float4Array,
102    Float8Array,
103    PolygonArray,
104    OidArray,
105    MacaddrArray,
106    InetArray,
107    Bpchar,
108    Varchar,
109    Date,
110    Time,
111    Timestamp,
112    TimestampArray,
113    DateArray,
114    TimeArray,
115    Timestamptz,
116    TimestamptzArray,
117    Interval,
118    IntervalArray,
119    NumericArray,
120    Timetz,
121    TimetzArray,
122    Bit,
123    BitArray,
124    Varbit,
125    VarbitArray,
126    Numeric,
127    Record,
128    RecordArray,
129    Uuid,
130    UuidArray,
131    Jsonb,
132    JsonbArray,
133    Int4Range,
134    Int4RangeArray,
135    NumRange,
136    NumRangeArray,
137    TsRange,
138    TsRangeArray,
139    TstzRange,
140    TstzRangeArray,
141    DateRange,
142    DateRangeArray,
143    Int8Range,
144    Int8RangeArray,
145    Jsonpath,
146    JsonpathArray,
147    Money,
148    MoneyArray,
149
150    Void,
152
153    Custom(Arc<PgCustomType>),
156
157    DeclareWithName(UStr),
159
160    DeclareWithOid(Oid),
163
164    DeclareArrayOf(Arc<PgArrayOf>),
165}
166
167#[derive(Debug, Clone)]
168#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
169pub struct PgCustomType {
170    #[cfg_attr(feature = "offline", serde(skip))]
171    pub(crate) oid: Oid,
172    pub(crate) name: UStr,
173    pub(crate) kind: PgTypeKind,
174}
175
176#[derive(Debug, Clone)]
177#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
178pub enum PgTypeKind {
179    Simple,
180    Pseudo,
181    Domain(PgTypeInfo),
182    Composite(Arc<[(String, PgTypeInfo)]>),
183    Array(PgTypeInfo),
184    Enum(Arc<[String]>),
185    Range(PgTypeInfo),
186}
187
188#[derive(Debug, Clone)]
189#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
190pub struct PgArrayOf {
191    pub(crate) elem_name: UStr,
192    pub(crate) name: Box<str>,
193}
194
195impl PgTypeInfo {
196    pub(crate) fn try_from_oid(oid: Oid) -> Option<Self> {
198        PgType::try_from_oid(oid).map(Self)
199    }
200
201    pub fn kind(&self) -> &PgTypeKind {
203        self.0.kind()
204    }
205
206    pub fn oid(&self) -> Option<Oid> {
222        self.0.try_oid()
223    }
224
225    #[doc(hidden)]
226    pub fn __type_feature_gate(&self) -> Option<&'static str> {
227        if [
228            PgTypeInfo::DATE,
229            PgTypeInfo::TIME,
230            PgTypeInfo::TIMESTAMP,
231            PgTypeInfo::TIMESTAMPTZ,
232            PgTypeInfo::DATE_ARRAY,
233            PgTypeInfo::TIME_ARRAY,
234            PgTypeInfo::TIMESTAMP_ARRAY,
235            PgTypeInfo::TIMESTAMPTZ_ARRAY,
236        ]
237        .contains(self)
238        {
239            Some("time")
240        } else if [PgTypeInfo::UUID, PgTypeInfo::UUID_ARRAY].contains(self) {
241            Some("uuid")
242        } else if [
243            PgTypeInfo::JSON,
244            PgTypeInfo::JSONB,
245            PgTypeInfo::JSON_ARRAY,
246            PgTypeInfo::JSONB_ARRAY,
247        ]
248        .contains(self)
249        {
250            Some("json")
251        } else if [
252            PgTypeInfo::CIDR,
253            PgTypeInfo::INET,
254            PgTypeInfo::CIDR_ARRAY,
255            PgTypeInfo::INET_ARRAY,
256        ]
257        .contains(self)
258        {
259            Some("ipnetwork")
260        } else if [PgTypeInfo::MACADDR].contains(self) {
261            Some("mac_address")
262        } else if [PgTypeInfo::NUMERIC, PgTypeInfo::NUMERIC_ARRAY].contains(self) {
263            Some("bigdecimal")
264        } else {
265            None
266        }
267    }
268
269    pub const fn with_name(name: &'static str) -> Self {
311        Self(PgType::DeclareWithName(UStr::Static(name)))
312    }
313
314    pub fn array_of(elem_name: &'static str) -> Self {
319        Self(PgType::DeclareArrayOf(Arc::new(PgArrayOf {
321            elem_name: elem_name.into(),
322            name: format!("{elem_name}[]").into(),
323        })))
324    }
325
326    pub const fn with_oid(oid: Oid) -> Self {
337        Self(PgType::DeclareWithOid(oid))
338    }
339
340    pub fn type_eq(&self, other: &Self) -> bool {
344        self.eq_impl(other, false)
345    }
346}
347
348impl PgType {
355    pub(crate) fn try_from_oid(oid: Oid) -> Option<Self> {
357        Some(match oid.0 {
358            16 => PgType::Bool,
359            17 => PgType::Bytea,
360            18 => PgType::Char,
361            19 => PgType::Name,
362            20 => PgType::Int8,
363            21 => PgType::Int2,
364            23 => PgType::Int4,
365            25 => PgType::Text,
366            26 => PgType::Oid,
367            114 => PgType::Json,
368            199 => PgType::JsonArray,
369            600 => PgType::Point,
370            601 => PgType::Lseg,
371            602 => PgType::Path,
372            603 => PgType::Box,
373            604 => PgType::Polygon,
374            628 => PgType::Line,
375            629 => PgType::LineArray,
376            650 => PgType::Cidr,
377            651 => PgType::CidrArray,
378            700 => PgType::Float4,
379            701 => PgType::Float8,
380            705 => PgType::Unknown,
381            718 => PgType::Circle,
382            719 => PgType::CircleArray,
383            774 => PgType::Macaddr8,
384            775 => PgType::Macaddr8Array,
385            790 => PgType::Money,
386            791 => PgType::MoneyArray,
387            829 => PgType::Macaddr,
388            869 => PgType::Inet,
389            1000 => PgType::BoolArray,
390            1001 => PgType::ByteaArray,
391            1002 => PgType::CharArray,
392            1003 => PgType::NameArray,
393            1005 => PgType::Int2Array,
394            1007 => PgType::Int4Array,
395            1009 => PgType::TextArray,
396            1014 => PgType::BpcharArray,
397            1015 => PgType::VarcharArray,
398            1016 => PgType::Int8Array,
399            1017 => PgType::PointArray,
400            1018 => PgType::LsegArray,
401            1019 => PgType::PathArray,
402            1020 => PgType::BoxArray,
403            1021 => PgType::Float4Array,
404            1022 => PgType::Float8Array,
405            1027 => PgType::PolygonArray,
406            1028 => PgType::OidArray,
407            1040 => PgType::MacaddrArray,
408            1041 => PgType::InetArray,
409            1042 => PgType::Bpchar,
410            1043 => PgType::Varchar,
411            1082 => PgType::Date,
412            1083 => PgType::Time,
413            1114 => PgType::Timestamp,
414            1115 => PgType::TimestampArray,
415            1182 => PgType::DateArray,
416            1183 => PgType::TimeArray,
417            1184 => PgType::Timestamptz,
418            1185 => PgType::TimestamptzArray,
419            1186 => PgType::Interval,
420            1187 => PgType::IntervalArray,
421            1231 => PgType::NumericArray,
422            1266 => PgType::Timetz,
423            1270 => PgType::TimetzArray,
424            1560 => PgType::Bit,
425            1561 => PgType::BitArray,
426            1562 => PgType::Varbit,
427            1563 => PgType::VarbitArray,
428            1700 => PgType::Numeric,
429            2278 => PgType::Void,
430            2249 => PgType::Record,
431            2287 => PgType::RecordArray,
432            2950 => PgType::Uuid,
433            2951 => PgType::UuidArray,
434            3802 => PgType::Jsonb,
435            3807 => PgType::JsonbArray,
436            3904 => PgType::Int4Range,
437            3905 => PgType::Int4RangeArray,
438            3906 => PgType::NumRange,
439            3907 => PgType::NumRangeArray,
440            3908 => PgType::TsRange,
441            3909 => PgType::TsRangeArray,
442            3910 => PgType::TstzRange,
443            3911 => PgType::TstzRangeArray,
444            3912 => PgType::DateRange,
445            3913 => PgType::DateRangeArray,
446            3926 => PgType::Int8Range,
447            3927 => PgType::Int8RangeArray,
448            4072 => PgType::Jsonpath,
449            4073 => PgType::JsonpathArray,
450
451            _ => {
452                return None;
453            }
454        })
455    }
456
457    pub(crate) fn oid(&self) -> Oid {
458        match self.try_oid() {
459            Some(oid) => oid,
460            None => unreachable!("(bug) use of unresolved type declaration [oid]"),
461        }
462    }
463
464    pub(crate) fn try_oid(&self) -> Option<Oid> {
465        Some(match self {
466            PgType::Bool => Oid(16),
467            PgType::Bytea => Oid(17),
468            PgType::Char => Oid(18),
469            PgType::Name => Oid(19),
470            PgType::Int8 => Oid(20),
471            PgType::Int2 => Oid(21),
472            PgType::Int4 => Oid(23),
473            PgType::Text => Oid(25),
474            PgType::Oid => Oid(26),
475            PgType::Json => Oid(114),
476            PgType::JsonArray => Oid(199),
477            PgType::Point => Oid(600),
478            PgType::Lseg => Oid(601),
479            PgType::Path => Oid(602),
480            PgType::Box => Oid(603),
481            PgType::Polygon => Oid(604),
482            PgType::Line => Oid(628),
483            PgType::LineArray => Oid(629),
484            PgType::Cidr => Oid(650),
485            PgType::CidrArray => Oid(651),
486            PgType::Float4 => Oid(700),
487            PgType::Float8 => Oid(701),
488            PgType::Unknown => Oid(705),
489            PgType::Circle => Oid(718),
490            PgType::CircleArray => Oid(719),
491            PgType::Macaddr8 => Oid(774),
492            PgType::Macaddr8Array => Oid(775),
493            PgType::Money => Oid(790),
494            PgType::MoneyArray => Oid(791),
495            PgType::Macaddr => Oid(829),
496            PgType::Inet => Oid(869),
497            PgType::BoolArray => Oid(1000),
498            PgType::ByteaArray => Oid(1001),
499            PgType::CharArray => Oid(1002),
500            PgType::NameArray => Oid(1003),
501            PgType::Int2Array => Oid(1005),
502            PgType::Int4Array => Oid(1007),
503            PgType::TextArray => Oid(1009),
504            PgType::BpcharArray => Oid(1014),
505            PgType::VarcharArray => Oid(1015),
506            PgType::Int8Array => Oid(1016),
507            PgType::PointArray => Oid(1017),
508            PgType::LsegArray => Oid(1018),
509            PgType::PathArray => Oid(1019),
510            PgType::BoxArray => Oid(1020),
511            PgType::Float4Array => Oid(1021),
512            PgType::Float8Array => Oid(1022),
513            PgType::PolygonArray => Oid(1027),
514            PgType::OidArray => Oid(1028),
515            PgType::MacaddrArray => Oid(1040),
516            PgType::InetArray => Oid(1041),
517            PgType::Bpchar => Oid(1042),
518            PgType::Varchar => Oid(1043),
519            PgType::Date => Oid(1082),
520            PgType::Time => Oid(1083),
521            PgType::Timestamp => Oid(1114),
522            PgType::TimestampArray => Oid(1115),
523            PgType::DateArray => Oid(1182),
524            PgType::TimeArray => Oid(1183),
525            PgType::Timestamptz => Oid(1184),
526            PgType::TimestamptzArray => Oid(1185),
527            PgType::Interval => Oid(1186),
528            PgType::IntervalArray => Oid(1187),
529            PgType::NumericArray => Oid(1231),
530            PgType::Timetz => Oid(1266),
531            PgType::TimetzArray => Oid(1270),
532            PgType::Bit => Oid(1560),
533            PgType::BitArray => Oid(1561),
534            PgType::Varbit => Oid(1562),
535            PgType::VarbitArray => Oid(1563),
536            PgType::Numeric => Oid(1700),
537            PgType::Void => Oid(2278),
538            PgType::Record => Oid(2249),
539            PgType::RecordArray => Oid(2287),
540            PgType::Uuid => Oid(2950),
541            PgType::UuidArray => Oid(2951),
542            PgType::Jsonb => Oid(3802),
543            PgType::JsonbArray => Oid(3807),
544            PgType::Int4Range => Oid(3904),
545            PgType::Int4RangeArray => Oid(3905),
546            PgType::NumRange => Oid(3906),
547            PgType::NumRangeArray => Oid(3907),
548            PgType::TsRange => Oid(3908),
549            PgType::TsRangeArray => Oid(3909),
550            PgType::TstzRange => Oid(3910),
551            PgType::TstzRangeArray => Oid(3911),
552            PgType::DateRange => Oid(3912),
553            PgType::DateRangeArray => Oid(3913),
554            PgType::Int8Range => Oid(3926),
555            PgType::Int8RangeArray => Oid(3927),
556            PgType::Jsonpath => Oid(4072),
557            PgType::JsonpathArray => Oid(4073),
558
559            PgType::Custom(ty) => ty.oid,
560
561            PgType::DeclareWithOid(oid) => *oid,
562            PgType::DeclareWithName(_) => {
563                return None;
564            }
565            PgType::DeclareArrayOf(_) => {
566                return None;
567            }
568        })
569    }
570
571    pub(crate) fn display_name(&self) -> &str {
572        match self {
573            PgType::Bool => "BOOL",
574            PgType::Bytea => "BYTEA",
575            PgType::Char => "\"CHAR\"",
576            PgType::Name => "NAME",
577            PgType::Int8 => "INT8",
578            PgType::Int2 => "INT2",
579            PgType::Int4 => "INT4",
580            PgType::Text => "TEXT",
581            PgType::Oid => "OID",
582            PgType::Json => "JSON",
583            PgType::JsonArray => "JSON[]",
584            PgType::Point => "POINT",
585            PgType::Lseg => "LSEG",
586            PgType::Path => "PATH",
587            PgType::Box => "BOX",
588            PgType::Polygon => "POLYGON",
589            PgType::Line => "LINE",
590            PgType::LineArray => "LINE[]",
591            PgType::Cidr => "CIDR",
592            PgType::CidrArray => "CIDR[]",
593            PgType::Float4 => "FLOAT4",
594            PgType::Float8 => "FLOAT8",
595            PgType::Unknown => "UNKNOWN",
596            PgType::Circle => "CIRCLE",
597            PgType::CircleArray => "CIRCLE[]",
598            PgType::Macaddr8 => "MACADDR8",
599            PgType::Macaddr8Array => "MACADDR8[]",
600            PgType::Macaddr => "MACADDR",
601            PgType::Inet => "INET",
602            PgType::BoolArray => "BOOL[]",
603            PgType::ByteaArray => "BYTEA[]",
604            PgType::CharArray => "\"CHAR\"[]",
605            PgType::NameArray => "NAME[]",
606            PgType::Int2Array => "INT2[]",
607            PgType::Int4Array => "INT4[]",
608            PgType::TextArray => "TEXT[]",
609            PgType::BpcharArray => "CHAR[]",
610            PgType::VarcharArray => "VARCHAR[]",
611            PgType::Int8Array => "INT8[]",
612            PgType::PointArray => "POINT[]",
613            PgType::LsegArray => "LSEG[]",
614            PgType::PathArray => "PATH[]",
615            PgType::BoxArray => "BOX[]",
616            PgType::Float4Array => "FLOAT4[]",
617            PgType::Float8Array => "FLOAT8[]",
618            PgType::PolygonArray => "POLYGON[]",
619            PgType::OidArray => "OID[]",
620            PgType::MacaddrArray => "MACADDR[]",
621            PgType::InetArray => "INET[]",
622            PgType::Bpchar => "CHAR",
623            PgType::Varchar => "VARCHAR",
624            PgType::Date => "DATE",
625            PgType::Time => "TIME",
626            PgType::Timestamp => "TIMESTAMP",
627            PgType::TimestampArray => "TIMESTAMP[]",
628            PgType::DateArray => "DATE[]",
629            PgType::TimeArray => "TIME[]",
630            PgType::Timestamptz => "TIMESTAMPTZ",
631            PgType::TimestamptzArray => "TIMESTAMPTZ[]",
632            PgType::Interval => "INTERVAL",
633            PgType::IntervalArray => "INTERVAL[]",
634            PgType::NumericArray => "NUMERIC[]",
635            PgType::Timetz => "TIMETZ",
636            PgType::TimetzArray => "TIMETZ[]",
637            PgType::Bit => "BIT",
638            PgType::BitArray => "BIT[]",
639            PgType::Varbit => "VARBIT",
640            PgType::VarbitArray => "VARBIT[]",
641            PgType::Numeric => "NUMERIC",
642            PgType::Record => "RECORD",
643            PgType::RecordArray => "RECORD[]",
644            PgType::Uuid => "UUID",
645            PgType::UuidArray => "UUID[]",
646            PgType::Jsonb => "JSONB",
647            PgType::JsonbArray => "JSONB[]",
648            PgType::Int4Range => "INT4RANGE",
649            PgType::Int4RangeArray => "INT4RANGE[]",
650            PgType::NumRange => "NUMRANGE",
651            PgType::NumRangeArray => "NUMRANGE[]",
652            PgType::TsRange => "TSRANGE",
653            PgType::TsRangeArray => "TSRANGE[]",
654            PgType::TstzRange => "TSTZRANGE",
655            PgType::TstzRangeArray => "TSTZRANGE[]",
656            PgType::DateRange => "DATERANGE",
657            PgType::DateRangeArray => "DATERANGE[]",
658            PgType::Int8Range => "INT8RANGE",
659            PgType::Int8RangeArray => "INT8RANGE[]",
660            PgType::Jsonpath => "JSONPATH",
661            PgType::JsonpathArray => "JSONPATH[]",
662            PgType::Money => "MONEY",
663            PgType::MoneyArray => "MONEY[]",
664            PgType::Void => "VOID",
665            PgType::Custom(ty) => &ty.name,
666            PgType::DeclareWithOid(_) => "?",
667            PgType::DeclareWithName(name) => name,
668            PgType::DeclareArrayOf(array) => &array.name,
669        }
670    }
671
672    pub(crate) fn name(&self) -> &str {
673        match self {
674            PgType::Bool => "bool",
675            PgType::Bytea => "bytea",
676            PgType::Char => "char",
677            PgType::Name => "name",
678            PgType::Int8 => "int8",
679            PgType::Int2 => "int2",
680            PgType::Int4 => "int4",
681            PgType::Text => "text",
682            PgType::Oid => "oid",
683            PgType::Json => "json",
684            PgType::JsonArray => "_json",
685            PgType::Point => "point",
686            PgType::Lseg => "lseg",
687            PgType::Path => "path",
688            PgType::Box => "box",
689            PgType::Polygon => "polygon",
690            PgType::Line => "line",
691            PgType::LineArray => "_line",
692            PgType::Cidr => "cidr",
693            PgType::CidrArray => "_cidr",
694            PgType::Float4 => "float4",
695            PgType::Float8 => "float8",
696            PgType::Unknown => "unknown",
697            PgType::Circle => "circle",
698            PgType::CircleArray => "_circle",
699            PgType::Macaddr8 => "macaddr8",
700            PgType::Macaddr8Array => "_macaddr8",
701            PgType::Macaddr => "macaddr",
702            PgType::Inet => "inet",
703            PgType::BoolArray => "_bool",
704            PgType::ByteaArray => "_bytea",
705            PgType::CharArray => "_char",
706            PgType::NameArray => "_name",
707            PgType::Int2Array => "_int2",
708            PgType::Int4Array => "_int4",
709            PgType::TextArray => "_text",
710            PgType::BpcharArray => "_bpchar",
711            PgType::VarcharArray => "_varchar",
712            PgType::Int8Array => "_int8",
713            PgType::PointArray => "_point",
714            PgType::LsegArray => "_lseg",
715            PgType::PathArray => "_path",
716            PgType::BoxArray => "_box",
717            PgType::Float4Array => "_float4",
718            PgType::Float8Array => "_float8",
719            PgType::PolygonArray => "_polygon",
720            PgType::OidArray => "_oid",
721            PgType::MacaddrArray => "_macaddr",
722            PgType::InetArray => "_inet",
723            PgType::Bpchar => "bpchar",
724            PgType::Varchar => "varchar",
725            PgType::Date => "date",
726            PgType::Time => "time",
727            PgType::Timestamp => "timestamp",
728            PgType::TimestampArray => "_timestamp",
729            PgType::DateArray => "_date",
730            PgType::TimeArray => "_time",
731            PgType::Timestamptz => "timestamptz",
732            PgType::TimestamptzArray => "_timestamptz",
733            PgType::Interval => "interval",
734            PgType::IntervalArray => "_interval",
735            PgType::NumericArray => "_numeric",
736            PgType::Timetz => "timetz",
737            PgType::TimetzArray => "_timetz",
738            PgType::Bit => "bit",
739            PgType::BitArray => "_bit",
740            PgType::Varbit => "varbit",
741            PgType::VarbitArray => "_varbit",
742            PgType::Numeric => "numeric",
743            PgType::Record => "record",
744            PgType::RecordArray => "_record",
745            PgType::Uuid => "uuid",
746            PgType::UuidArray => "_uuid",
747            PgType::Jsonb => "jsonb",
748            PgType::JsonbArray => "_jsonb",
749            PgType::Int4Range => "int4range",
750            PgType::Int4RangeArray => "_int4range",
751            PgType::NumRange => "numrange",
752            PgType::NumRangeArray => "_numrange",
753            PgType::TsRange => "tsrange",
754            PgType::TsRangeArray => "_tsrange",
755            PgType::TstzRange => "tstzrange",
756            PgType::TstzRangeArray => "_tstzrange",
757            PgType::DateRange => "daterange",
758            PgType::DateRangeArray => "_daterange",
759            PgType::Int8Range => "int8range",
760            PgType::Int8RangeArray => "_int8range",
761            PgType::Jsonpath => "jsonpath",
762            PgType::JsonpathArray => "_jsonpath",
763            PgType::Money => "money",
764            PgType::MoneyArray => "_money",
765            PgType::Void => "void",
766            PgType::Custom(ty) => &ty.name,
767            PgType::DeclareWithOid(_) => "?",
768            PgType::DeclareWithName(name) => name,
769            PgType::DeclareArrayOf(array) => &array.name,
770        }
771    }
772
773    pub(crate) fn kind(&self) -> &PgTypeKind {
774        match self {
775            PgType::Bool => &PgTypeKind::Simple,
776            PgType::Bytea => &PgTypeKind::Simple,
777            PgType::Char => &PgTypeKind::Simple,
778            PgType::Name => &PgTypeKind::Simple,
779            PgType::Int8 => &PgTypeKind::Simple,
780            PgType::Int2 => &PgTypeKind::Simple,
781            PgType::Int4 => &PgTypeKind::Simple,
782            PgType::Text => &PgTypeKind::Simple,
783            PgType::Oid => &PgTypeKind::Simple,
784            PgType::Json => &PgTypeKind::Simple,
785            PgType::JsonArray => &PgTypeKind::Array(PgTypeInfo(PgType::Json)),
786            PgType::Point => &PgTypeKind::Simple,
787            PgType::Lseg => &PgTypeKind::Simple,
788            PgType::Path => &PgTypeKind::Simple,
789            PgType::Box => &PgTypeKind::Simple,
790            PgType::Polygon => &PgTypeKind::Simple,
791            PgType::Line => &PgTypeKind::Simple,
792            PgType::LineArray => &PgTypeKind::Array(PgTypeInfo(PgType::Line)),
793            PgType::Cidr => &PgTypeKind::Simple,
794            PgType::CidrArray => &PgTypeKind::Array(PgTypeInfo(PgType::Cidr)),
795            PgType::Float4 => &PgTypeKind::Simple,
796            PgType::Float8 => &PgTypeKind::Simple,
797            PgType::Unknown => &PgTypeKind::Simple,
798            PgType::Circle => &PgTypeKind::Simple,
799            PgType::CircleArray => &PgTypeKind::Array(PgTypeInfo(PgType::Circle)),
800            PgType::Macaddr8 => &PgTypeKind::Simple,
801            PgType::Macaddr8Array => &PgTypeKind::Array(PgTypeInfo(PgType::Macaddr8)),
802            PgType::Macaddr => &PgTypeKind::Simple,
803            PgType::Inet => &PgTypeKind::Simple,
804            PgType::BoolArray => &PgTypeKind::Array(PgTypeInfo(PgType::Bool)),
805            PgType::ByteaArray => &PgTypeKind::Array(PgTypeInfo(PgType::Bytea)),
806            PgType::CharArray => &PgTypeKind::Array(PgTypeInfo(PgType::Char)),
807            PgType::NameArray => &PgTypeKind::Array(PgTypeInfo(PgType::Name)),
808            PgType::Int2Array => &PgTypeKind::Array(PgTypeInfo(PgType::Int2)),
809            PgType::Int4Array => &PgTypeKind::Array(PgTypeInfo(PgType::Int4)),
810            PgType::TextArray => &PgTypeKind::Array(PgTypeInfo(PgType::Text)),
811            PgType::BpcharArray => &PgTypeKind::Array(PgTypeInfo(PgType::Bpchar)),
812            PgType::VarcharArray => &PgTypeKind::Array(PgTypeInfo(PgType::Varchar)),
813            PgType::Int8Array => &PgTypeKind::Array(PgTypeInfo(PgType::Int8)),
814            PgType::PointArray => &PgTypeKind::Array(PgTypeInfo(PgType::Point)),
815            PgType::LsegArray => &PgTypeKind::Array(PgTypeInfo(PgType::Lseg)),
816            PgType::PathArray => &PgTypeKind::Array(PgTypeInfo(PgType::Path)),
817            PgType::BoxArray => &PgTypeKind::Array(PgTypeInfo(PgType::Box)),
818            PgType::Float4Array => &PgTypeKind::Array(PgTypeInfo(PgType::Float4)),
819            PgType::Float8Array => &PgTypeKind::Array(PgTypeInfo(PgType::Float8)),
820            PgType::PolygonArray => &PgTypeKind::Array(PgTypeInfo(PgType::Polygon)),
821            PgType::OidArray => &PgTypeKind::Array(PgTypeInfo(PgType::Oid)),
822            PgType::MacaddrArray => &PgTypeKind::Array(PgTypeInfo(PgType::Macaddr)),
823            PgType::InetArray => &PgTypeKind::Array(PgTypeInfo(PgType::Inet)),
824            PgType::Bpchar => &PgTypeKind::Simple,
825            PgType::Varchar => &PgTypeKind::Simple,
826            PgType::Date => &PgTypeKind::Simple,
827            PgType::Time => &PgTypeKind::Simple,
828            PgType::Timestamp => &PgTypeKind::Simple,
829            PgType::TimestampArray => &PgTypeKind::Array(PgTypeInfo(PgType::Timestamp)),
830            PgType::DateArray => &PgTypeKind::Array(PgTypeInfo(PgType::Date)),
831            PgType::TimeArray => &PgTypeKind::Array(PgTypeInfo(PgType::Time)),
832            PgType::Timestamptz => &PgTypeKind::Simple,
833            PgType::TimestamptzArray => &PgTypeKind::Array(PgTypeInfo(PgType::Timestamptz)),
834            PgType::Interval => &PgTypeKind::Simple,
835            PgType::IntervalArray => &PgTypeKind::Array(PgTypeInfo(PgType::Interval)),
836            PgType::NumericArray => &PgTypeKind::Array(PgTypeInfo(PgType::Numeric)),
837            PgType::Timetz => &PgTypeKind::Simple,
838            PgType::TimetzArray => &PgTypeKind::Array(PgTypeInfo(PgType::Timetz)),
839            PgType::Bit => &PgTypeKind::Simple,
840            PgType::BitArray => &PgTypeKind::Array(PgTypeInfo(PgType::Bit)),
841            PgType::Varbit => &PgTypeKind::Simple,
842            PgType::VarbitArray => &PgTypeKind::Array(PgTypeInfo(PgType::Varbit)),
843            PgType::Numeric => &PgTypeKind::Simple,
844            PgType::Record => &PgTypeKind::Simple,
845            PgType::RecordArray => &PgTypeKind::Array(PgTypeInfo(PgType::Record)),
846            PgType::Uuid => &PgTypeKind::Simple,
847            PgType::UuidArray => &PgTypeKind::Array(PgTypeInfo(PgType::Uuid)),
848            PgType::Jsonb => &PgTypeKind::Simple,
849            PgType::JsonbArray => &PgTypeKind::Array(PgTypeInfo(PgType::Jsonb)),
850            PgType::Int4Range => &PgTypeKind::Range(PgTypeInfo::INT4),
851            PgType::Int4RangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::Int4Range)),
852            PgType::NumRange => &PgTypeKind::Range(PgTypeInfo::NUMERIC),
853            PgType::NumRangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::NumRange)),
854            PgType::TsRange => &PgTypeKind::Range(PgTypeInfo::TIMESTAMP),
855            PgType::TsRangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::TsRange)),
856            PgType::TstzRange => &PgTypeKind::Range(PgTypeInfo::TIMESTAMPTZ),
857            PgType::TstzRangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::TstzRange)),
858            PgType::DateRange => &PgTypeKind::Range(PgTypeInfo::DATE),
859            PgType::DateRangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::DateRange)),
860            PgType::Int8Range => &PgTypeKind::Range(PgTypeInfo::INT8),
861            PgType::Int8RangeArray => &PgTypeKind::Array(PgTypeInfo(PgType::Int8Range)),
862            PgType::Jsonpath => &PgTypeKind::Simple,
863            PgType::JsonpathArray => &PgTypeKind::Array(PgTypeInfo(PgType::Jsonpath)),
864            PgType::Money => &PgTypeKind::Simple,
865            PgType::MoneyArray => &PgTypeKind::Array(PgTypeInfo(PgType::Money)),
866
867            PgType::Void => &PgTypeKind::Pseudo,
868
869            PgType::Custom(ty) => &ty.kind,
870
871            PgType::DeclareWithOid(oid) => {
872                unreachable!("(bug) use of unresolved type declaration [oid={}]", oid.0);
873            }
874            PgType::DeclareWithName(name) => {
875                unreachable!("(bug) use of unresolved type declaration [name={name}]");
876            }
877            PgType::DeclareArrayOf(array) => {
878                unreachable!(
879                    "(bug) use of unresolved type declaration [array of={}]",
880                    array.elem_name
881                );
882            }
883        }
884    }
885
886    pub(crate) fn try_array_element(&self) -> Option<Cow<'_, PgTypeInfo>> {
888        match self {
890            PgType::Bool => None,
891            PgType::BoolArray => Some(Cow::Owned(PgTypeInfo(PgType::Bool))),
892            PgType::Bytea => None,
893            PgType::ByteaArray => Some(Cow::Owned(PgTypeInfo(PgType::Bytea))),
894            PgType::Char => None,
895            PgType::CharArray => Some(Cow::Owned(PgTypeInfo(PgType::Char))),
896            PgType::Name => None,
897            PgType::NameArray => Some(Cow::Owned(PgTypeInfo(PgType::Name))),
898            PgType::Int8 => None,
899            PgType::Int8Array => Some(Cow::Owned(PgTypeInfo(PgType::Int8))),
900            PgType::Int2 => None,
901            PgType::Int2Array => Some(Cow::Owned(PgTypeInfo(PgType::Int2))),
902            PgType::Int4 => None,
903            PgType::Int4Array => Some(Cow::Owned(PgTypeInfo(PgType::Int4))),
904            PgType::Text => None,
905            PgType::TextArray => Some(Cow::Owned(PgTypeInfo(PgType::Text))),
906            PgType::Oid => None,
907            PgType::OidArray => Some(Cow::Owned(PgTypeInfo(PgType::Oid))),
908            PgType::Json => None,
909            PgType::JsonArray => Some(Cow::Owned(PgTypeInfo(PgType::Json))),
910            PgType::Point => None,
911            PgType::PointArray => Some(Cow::Owned(PgTypeInfo(PgType::Point))),
912            PgType::Lseg => None,
913            PgType::LsegArray => Some(Cow::Owned(PgTypeInfo(PgType::Lseg))),
914            PgType::Path => None,
915            PgType::PathArray => Some(Cow::Owned(PgTypeInfo(PgType::Path))),
916            PgType::Box => None,
917            PgType::BoxArray => Some(Cow::Owned(PgTypeInfo(PgType::Box))),
918            PgType::Polygon => None,
919            PgType::PolygonArray => Some(Cow::Owned(PgTypeInfo(PgType::Polygon))),
920            PgType::Line => None,
921            PgType::LineArray => Some(Cow::Owned(PgTypeInfo(PgType::Line))),
922            PgType::Cidr => None,
923            PgType::CidrArray => Some(Cow::Owned(PgTypeInfo(PgType::Cidr))),
924            PgType::Float4 => None,
925            PgType::Float4Array => Some(Cow::Owned(PgTypeInfo(PgType::Float4))),
926            PgType::Float8 => None,
927            PgType::Float8Array => Some(Cow::Owned(PgTypeInfo(PgType::Float8))),
928            PgType::Circle => None,
929            PgType::CircleArray => Some(Cow::Owned(PgTypeInfo(PgType::Circle))),
930            PgType::Macaddr8 => None,
931            PgType::Macaddr8Array => Some(Cow::Owned(PgTypeInfo(PgType::Macaddr8))),
932            PgType::Money => None,
933            PgType::MoneyArray => Some(Cow::Owned(PgTypeInfo(PgType::Money))),
934            PgType::Macaddr => None,
935            PgType::MacaddrArray => Some(Cow::Owned(PgTypeInfo(PgType::Macaddr))),
936            PgType::Inet => None,
937            PgType::InetArray => Some(Cow::Owned(PgTypeInfo(PgType::Inet))),
938            PgType::Bpchar => None,
939            PgType::BpcharArray => Some(Cow::Owned(PgTypeInfo(PgType::Bpchar))),
940            PgType::Varchar => None,
941            PgType::VarcharArray => Some(Cow::Owned(PgTypeInfo(PgType::Varchar))),
942            PgType::Date => None,
943            PgType::DateArray => Some(Cow::Owned(PgTypeInfo(PgType::Date))),
944            PgType::Time => None,
945            PgType::TimeArray => Some(Cow::Owned(PgTypeInfo(PgType::Time))),
946            PgType::Timestamp => None,
947            PgType::TimestampArray => Some(Cow::Owned(PgTypeInfo(PgType::Timestamp))),
948            PgType::Timestamptz => None,
949            PgType::TimestamptzArray => Some(Cow::Owned(PgTypeInfo(PgType::Timestamptz))),
950            PgType::Interval => None,
951            PgType::IntervalArray => Some(Cow::Owned(PgTypeInfo(PgType::Interval))),
952            PgType::Timetz => None,
953            PgType::TimetzArray => Some(Cow::Owned(PgTypeInfo(PgType::Timetz))),
954            PgType::Bit => None,
955            PgType::BitArray => Some(Cow::Owned(PgTypeInfo(PgType::Bit))),
956            PgType::Varbit => None,
957            PgType::VarbitArray => Some(Cow::Owned(PgTypeInfo(PgType::Varbit))),
958            PgType::Numeric => None,
959            PgType::NumericArray => Some(Cow::Owned(PgTypeInfo(PgType::Numeric))),
960            PgType::Record => None,
961            PgType::RecordArray => Some(Cow::Owned(PgTypeInfo(PgType::Record))),
962            PgType::Uuid => None,
963            PgType::UuidArray => Some(Cow::Owned(PgTypeInfo(PgType::Uuid))),
964            PgType::Jsonb => None,
965            PgType::JsonbArray => Some(Cow::Owned(PgTypeInfo(PgType::Jsonb))),
966            PgType::Int4Range => None,
967            PgType::Int4RangeArray => Some(Cow::Owned(PgTypeInfo(PgType::Int4Range))),
968            PgType::NumRange => None,
969            PgType::NumRangeArray => Some(Cow::Owned(PgTypeInfo(PgType::NumRange))),
970            PgType::TsRange => None,
971            PgType::TsRangeArray => Some(Cow::Owned(PgTypeInfo(PgType::TsRange))),
972            PgType::TstzRange => None,
973            PgType::TstzRangeArray => Some(Cow::Owned(PgTypeInfo(PgType::TstzRange))),
974            PgType::DateRange => None,
975            PgType::DateRangeArray => Some(Cow::Owned(PgTypeInfo(PgType::DateRange))),
976            PgType::Int8Range => None,
977            PgType::Int8RangeArray => Some(Cow::Owned(PgTypeInfo(PgType::Int8Range))),
978            PgType::Jsonpath => None,
979            PgType::JsonpathArray => Some(Cow::Owned(PgTypeInfo(PgType::Jsonpath))),
980            PgType::Unknown => None,
982            PgType::Void => None,
984
985            PgType::Custom(ty) => match &ty.kind {
986                PgTypeKind::Simple => None,
987                PgTypeKind::Pseudo => None,
988                PgTypeKind::Domain(_) => None,
989                PgTypeKind::Composite(_) => None,
990                PgTypeKind::Array(ref elem_type_info) => Some(Cow::Borrowed(elem_type_info)),
991                PgTypeKind::Enum(_) => None,
992                PgTypeKind::Range(_) => None,
993            },
994            PgType::DeclareWithOid(_) => None,
995            PgType::DeclareWithName(name) => {
996                UStr::strip_prefix(name, "_")
998                    .map(|elem| Cow::Owned(PgTypeInfo(PgType::DeclareWithName(elem))))
999            }
1000            PgType::DeclareArrayOf(array) => Some(Cow::Owned(PgTypeInfo(PgType::DeclareWithName(
1001                array.elem_name.clone(),
1002            )))),
1003        }
1004    }
1005
1006    fn is_declare_with_oid(&self) -> bool {
1008        matches!(self, Self::DeclareWithOid(_))
1009    }
1010
1011    fn eq_impl(&self, other: &Self, soft_eq: bool) -> bool {
1016        if let (Some(a), Some(b)) = (self.try_base_oid(), other.try_base_oid()) {
1017            return a == b;
1019        }
1020
1021        if soft_eq && (self.is_declare_with_oid() || other.is_declare_with_oid()) {
1022            return true;
1028        }
1029
1030        if let (Some(elem_a), Some(elem_b)) = (self.try_array_element(), other.try_array_element())
1031        {
1032            return elem_a == elem_b;
1033        }
1034
1035        name_eq(self.name(), other.name())
1037    }
1038
1039    #[inline(always)]
1041    fn try_base_oid(&self) -> Option<Oid> {
1042        match self {
1043            PgType::Custom(custom) => match &custom.kind {
1044                PgTypeKind::Domain(domain) => domain.try_oid(),
1045                _ => Some(custom.oid),
1046            },
1047            ty => ty.try_oid(),
1048        }
1049    }
1050}
1051
1052impl TypeInfo for PgTypeInfo {
1053    fn name(&self) -> &str {
1054        self.0.display_name()
1055    }
1056
1057    fn is_null(&self) -> bool {
1058        false
1059    }
1060
1061    fn is_void(&self) -> bool {
1062        matches!(self.0, PgType::Void)
1063    }
1064
1065    fn type_compatible(&self, other: &Self) -> bool
1066    where
1067        Self: Sized,
1068    {
1069        self == other
1070    }
1071}
1072
1073impl PartialEq<PgCustomType> for PgCustomType {
1074    fn eq(&self, other: &PgCustomType) -> bool {
1075        other.oid == self.oid
1076    }
1077}
1078
1079impl PgTypeInfo {
1080    pub(crate) const BOOL: Self = Self(PgType::Bool);
1082    pub(crate) const BOOL_ARRAY: Self = Self(PgType::BoolArray);
1083
1084    pub(crate) const BYTEA: Self = Self(PgType::Bytea);
1086    pub(crate) const BYTEA_ARRAY: Self = Self(PgType::ByteaArray);
1087
1088    pub(crate) const UUID: Self = Self(PgType::Uuid);
1090    pub(crate) const UUID_ARRAY: Self = Self(PgType::UuidArray);
1091
1092    pub(crate) const RECORD: Self = Self(PgType::Record);
1094    pub(crate) const RECORD_ARRAY: Self = Self(PgType::RecordArray);
1095
1096    pub(crate) const JSON: Self = Self(PgType::Json);
1102    pub(crate) const JSON_ARRAY: Self = Self(PgType::JsonArray);
1103
1104    pub(crate) const JSONB: Self = Self(PgType::Jsonb);
1105    pub(crate) const JSONB_ARRAY: Self = Self(PgType::JsonbArray);
1106
1107    pub(crate) const JSONPATH: Self = Self(PgType::Jsonpath);
1108    pub(crate) const JSONPATH_ARRAY: Self = Self(PgType::JsonpathArray);
1109
1110    pub(crate) const CIDR: Self = Self(PgType::Cidr);
1116    pub(crate) const CIDR_ARRAY: Self = Self(PgType::CidrArray);
1117
1118    pub(crate) const INET: Self = Self(PgType::Inet);
1119    pub(crate) const INET_ARRAY: Self = Self(PgType::InetArray);
1120
1121    pub(crate) const MACADDR: Self = Self(PgType::Macaddr);
1122    pub(crate) const MACADDR_ARRAY: Self = Self(PgType::MacaddrArray);
1123
1124    pub(crate) const MACADDR8: Self = Self(PgType::Macaddr8);
1125    pub(crate) const MACADDR8_ARRAY: Self = Self(PgType::Macaddr8Array);
1126
1127    pub(crate) const NAME: Self = Self(PgType::Name);
1134    pub(crate) const NAME_ARRAY: Self = Self(PgType::NameArray);
1135
1136    pub(crate) const BPCHAR: Self = Self(PgType::Bpchar);
1138    pub(crate) const BPCHAR_ARRAY: Self = Self(PgType::BpcharArray);
1139
1140    pub(crate) const VARCHAR: Self = Self(PgType::Varchar);
1142    pub(crate) const VARCHAR_ARRAY: Self = Self(PgType::VarcharArray);
1143
1144    pub(crate) const TEXT: Self = Self(PgType::Text);
1146    pub(crate) const TEXT_ARRAY: Self = Self(PgType::TextArray);
1147
1148    pub(crate) const UNKNOWN: Self = Self(PgType::Unknown);
1150
1151    pub(crate) const CHAR: Self = Self(PgType::Char);
1158    pub(crate) const CHAR_ARRAY: Self = Self(PgType::CharArray);
1159
1160    pub(crate) const OID: Self = Self(PgType::Oid);
1162    pub(crate) const OID_ARRAY: Self = Self(PgType::OidArray);
1163
1164    pub(crate) const INT2: Self = Self(PgType::Int2);
1166    pub(crate) const INT2_ARRAY: Self = Self(PgType::Int2Array);
1167
1168    pub(crate) const INT4: Self = Self(PgType::Int4);
1170    pub(crate) const INT4_ARRAY: Self = Self(PgType::Int4Array);
1171
1172    pub(crate) const INT8: Self = Self(PgType::Int8);
1174    pub(crate) const INT8_ARRAY: Self = Self(PgType::Int8Array);
1175
1176    pub(crate) const FLOAT4: Self = Self(PgType::Float4);
1178    pub(crate) const FLOAT4_ARRAY: Self = Self(PgType::Float4Array);
1179
1180    pub(crate) const FLOAT8: Self = Self(PgType::Float8);
1182    pub(crate) const FLOAT8_ARRAY: Self = Self(PgType::Float8Array);
1183
1184    pub(crate) const NUMERIC: Self = Self(PgType::Numeric);
1186    pub(crate) const NUMERIC_ARRAY: Self = Self(PgType::NumericArray);
1187
1188    pub(crate) const MONEY: Self = Self(PgType::Money);
1190    pub(crate) const MONEY_ARRAY: Self = Self(PgType::MoneyArray);
1191
1192    pub(crate) const TIMESTAMP: Self = Self(PgType::Timestamp);
1199    pub(crate) const TIMESTAMP_ARRAY: Self = Self(PgType::TimestampArray);
1200
1201    pub(crate) const TIMESTAMPTZ: Self = Self(PgType::Timestamptz);
1203    pub(crate) const TIMESTAMPTZ_ARRAY: Self = Self(PgType::TimestamptzArray);
1204
1205    pub(crate) const DATE: Self = Self(PgType::Date);
1207    pub(crate) const DATE_ARRAY: Self = Self(PgType::DateArray);
1208
1209    pub(crate) const TIME: Self = Self(PgType::Time);
1211    pub(crate) const TIME_ARRAY: Self = Self(PgType::TimeArray);
1212
1213    pub(crate) const TIMETZ: Self = Self(PgType::Timetz);
1215    pub(crate) const TIMETZ_ARRAY: Self = Self(PgType::TimetzArray);
1216
1217    pub(crate) const INTERVAL: Self = Self(PgType::Interval);
1219    pub(crate) const INTERVAL_ARRAY: Self = Self(PgType::IntervalArray);
1220
1221    pub(crate) const POINT: Self = Self(PgType::Point);
1228    pub(crate) const POINT_ARRAY: Self = Self(PgType::PointArray);
1229
1230    pub(crate) const LINE: Self = Self(PgType::Line);
1232    pub(crate) const LINE_ARRAY: Self = Self(PgType::LineArray);
1233
1234    pub(crate) const LSEG: Self = Self(PgType::Lseg);
1236    pub(crate) const LSEG_ARRAY: Self = Self(PgType::LsegArray);
1237
1238    pub(crate) const BOX: Self = Self(PgType::Box);
1240    pub(crate) const BOX_ARRAY: Self = Self(PgType::BoxArray);
1241
1242    pub(crate) const PATH: Self = Self(PgType::Path);
1244    pub(crate) const PATH_ARRAY: Self = Self(PgType::PathArray);
1245
1246    pub(crate) const POLYGON: Self = Self(PgType::Polygon);
1248    pub(crate) const POLYGON_ARRAY: Self = Self(PgType::PolygonArray);
1249
1250    pub(crate) const CIRCLE: Self = Self(PgType::Circle);
1252    pub(crate) const CIRCLE_ARRAY: Self = Self(PgType::CircleArray);
1253
1254    pub(crate) const BIT: Self = Self(PgType::Bit);
1260    pub(crate) const BIT_ARRAY: Self = Self(PgType::BitArray);
1261
1262    pub(crate) const VARBIT: Self = Self(PgType::Varbit);
1263    pub(crate) const VARBIT_ARRAY: Self = Self(PgType::VarbitArray);
1264
1265    pub(crate) const INT4_RANGE: Self = Self(PgType::Int4Range);
1271    pub(crate) const INT4_RANGE_ARRAY: Self = Self(PgType::Int4RangeArray);
1272
1273    pub(crate) const NUM_RANGE: Self = Self(PgType::NumRange);
1274    pub(crate) const NUM_RANGE_ARRAY: Self = Self(PgType::NumRangeArray);
1275
1276    pub(crate) const TS_RANGE: Self = Self(PgType::TsRange);
1277    pub(crate) const TS_RANGE_ARRAY: Self = Self(PgType::TsRangeArray);
1278
1279    pub(crate) const TSTZ_RANGE: Self = Self(PgType::TstzRange);
1280    pub(crate) const TSTZ_RANGE_ARRAY: Self = Self(PgType::TstzRangeArray);
1281
1282    pub(crate) const DATE_RANGE: Self = Self(PgType::DateRange);
1283    pub(crate) const DATE_RANGE_ARRAY: Self = Self(PgType::DateRangeArray);
1284
1285    pub(crate) const INT8_RANGE: Self = Self(PgType::Int8Range);
1286    pub(crate) const INT8_RANGE_ARRAY: Self = Self(PgType::Int8RangeArray);
1287
1288    pub(crate) const VOID: Self = Self(PgType::Void);
1294}
1295
1296impl Display for PgTypeInfo {
1297    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1298        f.pad(self.name())
1299    }
1300}
1301
1302impl PartialEq<PgType> for PgType {
1303    fn eq(&self, other: &PgType) -> bool {
1304        self.eq_impl(other, true)
1305    }
1306}
1307
1308fn name_eq(name1: &str, name2: &str) -> bool {
1312    if name1.starts_with("U&") {
1314        return name1 == name2;
1316    }
1317
1318    let mut chars1 = identifier_chars(name1);
1319    let mut chars2 = identifier_chars(name2);
1320
1321    while let (Some(a), Some(b)) = (chars1.next(), chars2.next()) {
1322        if !a.eq(&b) {
1323            return false;
1324        }
1325    }
1326
1327    chars1.next().is_none() && chars2.next().is_none()
1328}
1329
1330struct IdentifierChar {
1331    ch: char,
1332    case_sensitive: bool,
1333}
1334
1335impl IdentifierChar {
1336    fn eq(&self, other: &Self) -> bool {
1337        if self.case_sensitive || other.case_sensitive {
1338            self.ch == other.ch
1339        } else {
1340            self.ch.eq_ignore_ascii_case(&other.ch)
1341        }
1342    }
1343}
1344
1345fn identifier_chars(ident: &str) -> impl Iterator<Item = IdentifierChar> + '_ {
1349    let mut case_sensitive = false;
1350    let mut last_char_quote = false;
1351
1352    ident.chars().filter_map(move |ch| {
1353        if ch == '"' {
1354            if last_char_quote {
1355                last_char_quote = false;
1356            } else {
1357                last_char_quote = true;
1358                return None;
1359            }
1360        } else if last_char_quote {
1361            last_char_quote = false;
1362            case_sensitive = !case_sensitive;
1363        }
1364
1365        Some(IdentifierChar { ch, case_sensitive })
1366    })
1367}
1368
1369#[test]
1370fn test_name_eq() {
1371    let test_values = [
1372        ("foo", "foo", true),
1373        ("foo", "Foo", true),
1374        ("foo", "FOO", true),
1375        ("foo", r#""foo""#, true),
1376        ("foo", r#""Foo""#, false),
1377        ("foo", "foo.foo", false),
1378        ("foo.foo", "foo.foo", true),
1379        ("foo.foo", "foo.Foo", true),
1380        ("foo.foo", "foo.FOO", true),
1381        ("foo.foo", "Foo.foo", true),
1382        ("foo.foo", "Foo.Foo", true),
1383        ("foo.foo", "FOO.FOO", true),
1384        ("foo.foo", "foo", false),
1385        ("foo.foo", r#"foo."foo""#, true),
1386        ("foo.foo", r#"foo."Foo""#, false),
1387        ("foo.foo", r#"foo."FOO""#, false),
1388    ];
1389
1390    for (left, right, eq) in test_values {
1391        assert_eq!(
1392            name_eq(left, right),
1393            eq,
1394            "failed check for name_eq({left:?}, {right:?})"
1395        );
1396        assert_eq!(
1397            name_eq(right, left),
1398            eq,
1399            "failed check for name_eq({right:?}, {left:?})"
1400        );
1401    }
1402}