sqlparser/ast/
data_type.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#[cfg(not(feature = "std"))]
19use alloc::{boxed::Box, format, string::String, vec::Vec};
20use core::fmt;
21
22#[cfg(feature = "serde")]
23use serde::{Deserialize, Serialize};
24
25#[cfg(feature = "visitor")]
26use yachtsql_sqlparser_derive::{Visit, VisitMut};
27
28use crate::ast::{display_comma_separated, Expr, ObjectName, StructField, UnionField};
29
30use super::{value::escape_single_quote_string, ColumnDef};
31
32#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
33#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
34#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
35pub enum EnumMember {
36    Name(String),
37    /// ClickHouse allows to specify an integer value for each enum value.
38    ///
39    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/data-types/enum)
40    NamedValue(String, Expr),
41}
42
43/// SQL data types
44#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
45#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
46#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
47pub enum DataType {
48    /// Table type in [PostgreSQL], e.g. CREATE FUNCTION RETURNS TABLE(...).
49    ///
50    /// [PostgreSQL]: https://www.postgresql.org/docs/15/sql-createfunction.html
51    /// [MsSQL]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql?view=sql-server-ver16#c-create-a-multi-statement-table-valued-function
52    Table(Option<Vec<ColumnDef>>),
53    /// Table type with a name, e.g. CREATE FUNCTION RETURNS @result TABLE(...).
54    ///
55    /// [MsSQl]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql?view=sql-server-ver16#table
56    NamedTable {
57        /// Table name.
58        name: ObjectName,
59        /// Table columns.
60        columns: Vec<ColumnDef>,
61    },
62    /// Fixed-length character type, e.g. CHARACTER(10).
63    Character(Option<CharacterLength>),
64    /// Fixed-length char type, e.g. CHAR(10).
65    Char(Option<CharacterLength>),
66    /// Character varying type, e.g. CHARACTER VARYING(10).
67    CharacterVarying(Option<CharacterLength>),
68    /// Char varying type, e.g. CHAR VARYING(10).
69    CharVarying(Option<CharacterLength>),
70    /// Variable-length character type, e.g. VARCHAR(10).
71    Varchar(Option<CharacterLength>),
72    /// Variable-length character type, e.g. NVARCHAR(10).
73    Nvarchar(Option<CharacterLength>),
74    /// Uuid type.
75    Uuid,
76    /// Large character object with optional length,
77    /// e.g. CHARACTER LARGE OBJECT, CHARACTER LARGE OBJECT(1000), [SQL Standard].
78    ///
79    /// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-large-object-type
80    CharacterLargeObject(Option<u64>),
81    /// Large character object with optional length,
82    /// e.g. CHAR LARGE OBJECT, CHAR LARGE OBJECT(1000), [SQL Standard].
83    ///
84    /// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-large-object-type
85    CharLargeObject(Option<u64>),
86    /// Large character object with optional length,
87    /// e.g. CLOB, CLOB(1000), [SQL Standard].
88    ///
89    /// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-large-object-type
90    /// [Oracle]: https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html
91    Clob(Option<u64>),
92    /// Fixed-length binary type with optional length,
93    /// see [SQL Standard], [MS SQL Server].
94    ///
95    /// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type
96    /// [MS SQL Server]: https://learn.microsoft.com/pt-br/sql/t-sql/data-types/binary-and-varbinary-transact-sql?view=sql-server-ver16
97    Binary(Option<u64>),
98    /// Variable-length binary with optional length type,
99    /// see [SQL Standard], [MS SQL Server].
100    ///
101    /// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type
102    /// [MS SQL Server]: https://learn.microsoft.com/pt-br/sql/t-sql/data-types/binary-and-varbinary-transact-sql?view=sql-server-ver16
103    Varbinary(Option<BinaryLength>),
104    /// Large binary object with optional length,
105    /// see [SQL Standard], [Oracle].
106    ///
107    /// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-large-object-string-type
108    /// [Oracle]: https://docs.oracle.com/javadb/10.8.3.0/ref/rrefblob.html
109    Blob(Option<u64>),
110    /// [MySQL] blob with up to 2**8 bytes.
111    ///
112    /// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
113    TinyBlob,
114    /// [MySQL] blob with up to 2**24 bytes.
115    ///
116    /// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
117    MediumBlob,
118    /// [MySQL] blob with up to 2**32 bytes.
119    ///
120    /// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
121    LongBlob,
122    /// Variable-length binary data with optional length.
123    ///
124    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#bytes_type
125    Bytes(Option<u64>),
126    /// Numeric type with optional precision and scale, e.g. NUMERIC(10,2), [SQL Standard][1].
127    ///
128    /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type
129    Numeric(ExactNumberInfo),
130    /// Decimal type with optional precision and scale, e.g. DECIMAL(10,2), [SQL Standard][1].
131    ///
132    /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type
133    Decimal(ExactNumberInfo),
134    /// [MySQL] unsigned decimal with optional precision and scale, e.g. DECIMAL UNSIGNED or DECIMAL(10,2) UNSIGNED.
135    /// Note: Using UNSIGNED with DECIMAL is deprecated in recent versions of MySQL.
136    ///
137    /// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/numeric-type-syntax.html
138    DecimalUnsigned(ExactNumberInfo),
139    /// [BigNumeric] type used in BigQuery.
140    ///
141    /// [BigNumeric]: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#bignumeric_literals
142    BigNumeric(ExactNumberInfo),
143    /// This is alias for `BigNumeric` type used in BigQuery.
144    ///
145    /// [BigDecimal]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#decimal_types
146    BigDecimal(ExactNumberInfo),
147    /// Dec type with optional precision and scale, e.g. DEC(10,2), [SQL Standard][1].
148    ///
149    /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type
150    Dec(ExactNumberInfo),
151    /// [MySQL] unsigned decimal (DEC alias) with optional precision and scale, e.g. DEC UNSIGNED or DEC(10,2) UNSIGNED.
152    /// Note: Using UNSIGNED with DEC is deprecated in recent versions of MySQL.
153    ///
154    /// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/numeric-type-syntax.html
155    DecUnsigned(ExactNumberInfo),
156    /// Floating point with optional precision and scale, e.g. FLOAT, FLOAT(8), or FLOAT(8,2).
157    Float(ExactNumberInfo),
158    /// [MySQL] unsigned floating point with optional precision and scale, e.g.
159    /// FLOAT UNSIGNED, FLOAT(10) UNSIGNED or FLOAT(10,2) UNSIGNED.
160    /// Note: Using UNSIGNED with FLOAT is deprecated in recent versions of MySQL.
161    ///
162    /// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/numeric-type-syntax.html
163    FloatUnsigned(ExactNumberInfo),
164    /// Tiny integer with optional display width, e.g. TINYINT or TINYINT(3).
165    TinyInt(Option<u64>),
166    /// Unsigned tiny integer with optional display width,
167    /// e.g. TINYINT UNSIGNED or TINYINT(3) UNSIGNED.
168    TinyIntUnsigned(Option<u64>),
169    /// Unsigned tiny integer, e.g. UTINYINT
170    UTinyInt,
171    /// Int2 is an alias for SmallInt in [PostgreSQL].
172    /// Note: Int2 means 2 bytes in PostgreSQL (not 2 bits).
173    /// Int2 with optional display width, e.g. INT2 or INT2(5).
174    ///
175    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype.html
176    Int2(Option<u64>),
177    /// Unsigned Int2 with optional display width, e.g. INT2 UNSIGNED or INT2(5) UNSIGNED.
178    Int2Unsigned(Option<u64>),
179    /// Small integer with optional display width, e.g. SMALLINT or SMALLINT(5).
180    SmallInt(Option<u64>),
181    /// Unsigned small integer with optional display width,
182    /// e.g. SMALLINT UNSIGNED or SMALLINT(5) UNSIGNED.
183    SmallIntUnsigned(Option<u64>),
184    /// Unsigned small integer, e.g. USMALLINT.
185    USmallInt,
186    /// MySQL medium integer ([1]) with optional display width,
187    /// e.g. MEDIUMINT or MEDIUMINT(5).
188    ///
189    /// [1]: https://dev.mysql.com/doc/refman/8.0/en/integer-types.html
190    MediumInt(Option<u64>),
191    /// Unsigned medium integer ([1]) with optional display width,
192    /// e.g. MEDIUMINT UNSIGNED or MEDIUMINT(5) UNSIGNED.
193    ///
194    /// [1]: https://dev.mysql.com/doc/refman/8.0/en/integer-types.html
195    MediumIntUnsigned(Option<u64>),
196    /// Int with optional display width, e.g. INT or INT(11).
197    Int(Option<u64>),
198    /// Int4 is an alias for Integer in [PostgreSQL].
199    /// Note: Int4 means 4 bytes in PostgreSQL (not 4 bits).
200    /// Int4 with optional display width, e.g. Int4 or Int4(11).
201    ///
202    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype.html
203    Int4(Option<u64>),
204    /// Int8 is an alias for BigInt in [PostgreSQL] and Integer type in [ClickHouse].
205    /// Int8 with optional display width, e.g. INT8 or INT8(11).
206    /// Note: Int8 means 8 bytes in [PostgreSQL], but 8 bits in [ClickHouse].
207    ///
208    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype.html
209    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
210    Int8(Option<u64>),
211    /// Integer type in [ClickHouse].
212    /// Note: Int16 means 16 bits in [ClickHouse].
213    ///
214    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
215    Int16,
216    /// Integer type in [ClickHouse].
217    /// Note: Int32 means 32 bits in [ClickHouse].
218    ///
219    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
220    Int32,
221    /// Integer type in [BigQuery], [ClickHouse].
222    ///
223    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#integer_types
224    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
225    Int64,
226    /// Integer type in [ClickHouse].
227    /// Note: Int128 means 128 bits in [ClickHouse].
228    ///
229    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
230    Int128,
231    /// Integer type in [ClickHouse].
232    /// Note: Int256 means 256 bits in [ClickHouse].
233    ///
234    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
235    Int256,
236    /// Integer with optional display width, e.g. INTEGER or INTEGER(11).
237    Integer(Option<u64>),
238    /// Unsigned int with optional display width, e.g. INT UNSIGNED or INT(11) UNSIGNED.
239    IntUnsigned(Option<u64>),
240    /// Unsigned int4 with optional display width, e.g. INT4 UNSIGNED or INT4(11) UNSIGNED.
241    Int4Unsigned(Option<u64>),
242    /// Unsigned integer with optional display width, e.g. INTEGER UNSIGNED or INTEGER(11) UNSIGNED.
243    IntegerUnsigned(Option<u64>),
244    /// 128-bit integer type, e.g. HUGEINT.
245    HugeInt,
246    /// Unsigned 128-bit integer type, e.g. UHUGEINT.
247    UHugeInt,
248    /// Unsigned integer type in [ClickHouse].
249    /// Note: UInt8 means 8 bits in [ClickHouse].
250    ///
251    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
252    UInt8,
253    /// Unsigned integer type in [ClickHouse].
254    /// Note: UInt16 means 16 bits in [ClickHouse].
255    ///
256    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
257    UInt16,
258    /// Unsigned integer type in [ClickHouse].
259    /// Note: UInt32 means 32 bits in [ClickHouse].
260    ///
261    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
262    UInt32,
263    /// Unsigned integer type in [ClickHouse].
264    /// Note: UInt64 means 64 bits in [ClickHouse].
265    ///
266    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
267    UInt64,
268    /// Unsigned integer type in [ClickHouse].
269    /// Note: UInt128 means 128 bits in [ClickHouse].
270    ///
271    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
272    UInt128,
273    /// Unsigned integer type in [ClickHouse].
274    /// Note: UInt256 means 256 bits in [ClickHouse].
275    ///
276    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint
277    UInt256,
278    /// Big integer with optional display width, e.g. BIGINT or BIGINT(20).
279    BigInt(Option<u64>),
280    /// Unsigned big integer with optional display width, e.g. BIGINT UNSIGNED or BIGINT(20) UNSIGNED.
281    BigIntUnsigned(Option<u64>),
282    /// Unsigned big integer, e.g. UBIGINT.
283    UBigInt,
284    /// Unsigned Int8 with optional display width, e.g. INT8 UNSIGNED or INT8(11) UNSIGNED.
285    Int8Unsigned(Option<u64>),
286    /// Signed integer as used in [MySQL CAST] target types, without optional `INTEGER` suffix,
287    /// e.g. `SIGNED`
288    ///
289    /// [MySQL CAST]: https://dev.mysql.com/doc/refman/8.4/en/cast-functions.html
290    Signed,
291    /// Signed integer as used in [MySQL CAST] target types, with optional `INTEGER` suffix,
292    /// e.g. `SIGNED INTEGER`
293    ///
294    /// [MySQL CAST]: https://dev.mysql.com/doc/refman/8.4/en/cast-functions.html
295    SignedInteger,
296    /// Signed integer as used in [MySQL CAST] target types, without optional `INTEGER` suffix,
297    /// e.g. `SIGNED`
298    ///
299    /// [MySQL CAST]: https://dev.mysql.com/doc/refman/8.4/en/cast-functions.html
300    Unsigned,
301    /// Unsigned integer as used in [MySQL CAST] target types, with optional `INTEGER` suffix,
302    /// e.g. `UNSIGNED INTEGER`.
303    ///
304    /// [MySQL CAST]: https://dev.mysql.com/doc/refman/8.4/en/cast-functions.html
305    UnsignedInteger,
306    /// Float4 is an alias for Real in [PostgreSQL].
307    ///
308    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype.html
309    Float4,
310    /// Floating point in [ClickHouse].
311    ///
312    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/float
313    Float32,
314    /// Floating point in [BigQuery].
315    ///
316    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#floating_point_types
317    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/float
318    Float64,
319    /// Floating point, e.g. REAL.
320    Real,
321    /// [MySQL] unsigned real, e.g. REAL UNSIGNED.
322    /// Note: Using UNSIGNED with REAL is deprecated in recent versions of MySQL.
323    ///
324    /// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/numeric-type-syntax.html
325    RealUnsigned,
326    /// Float8 is an alias for Double in [PostgreSQL].
327    ///
328    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype.html
329    Float8,
330    /// Double
331    Double(ExactNumberInfo),
332    /// [MySQL] unsigned double precision with optional precision, e.g. DOUBLE UNSIGNED or DOUBLE(10,2) UNSIGNED.
333    /// Note: Using UNSIGNED with DOUBLE is deprecated in recent versions of MySQL.
334    ///
335    /// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/numeric-type-syntax.html
336    DoubleUnsigned(ExactNumberInfo),
337    /// Double Precision, see [SQL Standard], [PostgreSQL].
338    ///
339    /// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#approximate-numeric-type
340    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype-numeric.html
341    DoublePrecision,
342    /// [MySQL] unsigned double precision, e.g. DOUBLE PRECISION UNSIGNED.
343    /// Note: Using UNSIGNED with DOUBLE PRECISION is deprecated in recent versions of MySQL.
344    ///
345    /// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/numeric-type-syntax.html
346    DoublePrecisionUnsigned,
347    /// Bool is an alias for Boolean, see [PostgreSQL].
348    ///
349    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype.html
350    Bool,
351    /// Boolean type.
352    Boolean,
353    /// Date type.
354    Date,
355    /// Date32 with the same range as Datetime64.
356    ///
357    /// [1]: https://clickhouse.com/docs/en/sql-reference/data-types/date32
358    Date32,
359    /// Time with optional time precision and time zone information, see [SQL Standard][1].
360    ///
361    /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#datetime-type
362    Time(Option<u64>, TimezoneInfo),
363    /// Datetime with optional time precision, see [MySQL][1].
364    ///
365    /// [1]: https://dev.mysql.com/doc/refman/8.0/en/datetime.html
366    Datetime(Option<u64>),
367    /// Datetime with time precision and optional timezone, see [ClickHouse][1].
368    ///
369    /// [1]: https://clickhouse.com/docs/en/sql-reference/data-types/datetime64
370    Datetime64(u64, Option<String>),
371    /// Timestamp with optional time precision and time zone information, see [SQL Standard][1].
372    ///
373    /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#datetime-type
374    Timestamp(Option<u64>, TimezoneInfo),
375    /// Databricks timestamp without time zone. See [1].
376    ///
377    /// [1]: https://docs.databricks.com/aws/en/sql/language-manual/data-types/timestamp-ntz-type
378    TimestampNtz,
379    /// Interval type.
380    Interval {
381        /// [PostgreSQL] fields specification like `INTERVAL YEAR TO MONTH`.
382        ///
383        /// [PostgreSQL]: https://www.postgresql.org/docs/17/datatype-datetime.html
384        fields: Option<IntervalFields>,
385        /// [PostgreSQL] subsecond precision like `INTERVAL HOUR TO SECOND(3)`
386        ///
387        /// [PostgreSQL]: https://www.postgresql.org/docs/17/datatype-datetime.html
388        precision: Option<u64>,
389    },
390    /// JSON type.
391    JSON,
392    /// Binary JSON type.
393    JSONB,
394    /// Regclass used in [PostgreSQL] serial.
395    ///
396    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype.html
397    Regclass,
398    /// Text type.
399    Text,
400    /// [MySQL] text with up to 2**8 bytes.
401    ///
402    /// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
403    TinyText,
404    /// [MySQL] text with up to 2**24 bytes.
405    ///
406    /// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
407    MediumText,
408    /// [MySQL] text with up to 2**32 bytes.
409    ///
410    /// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
411    LongText,
412    /// String with optional length.
413    String(Option<u64>),
414    /// A fixed-length string e.g [ClickHouse][1].
415    ///
416    /// [1]: https://clickhouse.com/docs/en/sql-reference/data-types/fixedstring
417    FixedString(u64),
418    /// Bytea type, see [PostgreSQL].
419    ///
420    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype-bit.html
421    Bytea,
422    /// Bit string, see [PostgreSQL], [MySQL], or [MSSQL].
423    ///
424    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype-bit.html
425    /// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/bit-type.html
426    /// [MSSQL]: https://learn.microsoft.com/en-us/sql/t-sql/data-types/bit-transact-sql?view=sql-server-ver16
427    Bit(Option<u64>),
428    /// `BIT VARYING(n)`: Variable-length bit string, see [PostgreSQL].
429    ///
430    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype-bit.html
431    BitVarying(Option<u64>),
432    /// `VARBIT(n)`: Variable-length bit string. [PostgreSQL] alias for `BIT VARYING`.
433    ///
434    /// [PostgreSQL]: https://www.postgresql.org/docs/current/datatype.html
435    VarBit(Option<u64>),
436    /// Custom types.
437    Custom(ObjectName, Vec<String>),
438    /// Arrays.
439    Array(ArrayElemTypeDef),
440    /// Range type for BigQuery, see [BigQuery].
441    ///
442    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#range_type
443    Range(Box<DataType>),
444    /// Map, see [ClickHouse].
445    ///
446    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/map
447    Map(Box<DataType>, Box<DataType>),
448    /// Tuple, see [ClickHouse].
449    ///
450    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/tuple
451    Tuple(Vec<StructField>),
452    /// Nested type, see [ClickHouse].
453    ///
454    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/nested-data-structures/nested
455    Nested(Vec<ColumnDef>),
456    /// Enum type.
457    Enum(Vec<EnumMember>, Option<u8>),
458    /// Set type.
459    Set(Vec<String>),
460    /// Struct type, see [Hive], [BigQuery].
461    ///
462    /// [Hive]: https://docs.cloudera.com/cdw-runtime/cloud/impala-sql-reference/topics/impala-struct.html
463    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
464    Struct(Vec<StructField>, StructBracketKind),
465    /// Union type, see [DuckDB].
466    ///
467    /// [DuckDB]: https://duckdb.org/docs/sql/data_types/union.html
468    Union(Vec<UnionField>),
469    /// Nullable - special marker NULL represents in ClickHouse as a data type.
470    ///
471    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/nullable
472    Nullable(Box<DataType>),
473    /// LowCardinality - changes the internal representation of other data types to be dictionary-encoded.
474    ///
475    /// [ClickHouse]: https://clickhouse.com/docs/en/sql-reference/data-types/lowcardinality
476    LowCardinality(Box<DataType>),
477    /// No type specified - only used with
478    /// [`SQLiteDialect`](crate::dialect::SQLiteDialect), from statements such
479    /// as `CREATE TABLE t1 (a)`.
480    Unspecified,
481    /// Trigger data type, returned by functions associated with triggers, see [PostgreSQL].
482    ///
483    /// [PostgreSQL]: https://www.postgresql.org/docs/current/plpgsql-trigger.html
484    Trigger,
485    /// Any data type, used in BigQuery UDF definitions for templated parameters, see [BigQuery].
486    ///
487    /// [BigQuery]: https://cloud.google.com/bigquery/docs/user-defined-functions#templated-sql-udf-parameters
488    AnyType,
489    /// Geometric type, see [PostgreSQL].
490    ///
491    /// [PostgreSQL]: https://www.postgresql.org/docs/9.5/functions-geometry.html
492    GeometricType(GeometricTypeKind),
493    /// PostgreSQL text search vectors, see [PostgreSQL].
494    ///
495    /// [PostgreSQL]: https://www.postgresql.org/docs/17/datatype-textsearch.html
496    TsVector,
497    /// PostgreSQL text search query, see [PostgreSQL].
498    ///
499    /// [PostgreSQL]: https://www.postgresql.org/docs/17/datatype-textsearch.html
500    TsQuery,
501}
502
503impl fmt::Display for DataType {
504    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
505        match self {
506            DataType::Character(size) => format_character_string_type(f, "CHARACTER", size),
507            DataType::Char(size) => format_character_string_type(f, "CHAR", size),
508            DataType::CharacterVarying(size) => {
509                format_character_string_type(f, "CHARACTER VARYING", size)
510            }
511            DataType::CharVarying(size) => format_character_string_type(f, "CHAR VARYING", size),
512            DataType::Varchar(size) => format_character_string_type(f, "VARCHAR", size),
513            DataType::Nvarchar(size) => format_character_string_type(f, "NVARCHAR", size),
514            DataType::Uuid => write!(f, "UUID"),
515            DataType::CharacterLargeObject(size) => {
516                format_type_with_optional_length(f, "CHARACTER LARGE OBJECT", size, false)
517            }
518            DataType::CharLargeObject(size) => {
519                format_type_with_optional_length(f, "CHAR LARGE OBJECT", size, false)
520            }
521            DataType::Clob(size) => format_type_with_optional_length(f, "CLOB", size, false),
522            DataType::Binary(size) => format_type_with_optional_length(f, "BINARY", size, false),
523            DataType::Varbinary(size) => format_varbinary_type(f, "VARBINARY", size),
524            DataType::Blob(size) => format_type_with_optional_length(f, "BLOB", size, false),
525            DataType::TinyBlob => write!(f, "TINYBLOB"),
526            DataType::MediumBlob => write!(f, "MEDIUMBLOB"),
527            DataType::LongBlob => write!(f, "LONGBLOB"),
528            DataType::Bytes(size) => format_type_with_optional_length(f, "BYTES", size, false),
529            DataType::Numeric(info) => {
530                write!(f, "NUMERIC{info}")
531            }
532            DataType::Decimal(info) => {
533                write!(f, "DECIMAL{info}")
534            }
535            DataType::DecimalUnsigned(info) => {
536                write!(f, "DECIMAL{info} UNSIGNED")
537            }
538            DataType::Dec(info) => {
539                write!(f, "DEC{info}")
540            }
541            DataType::DecUnsigned(info) => {
542                write!(f, "DEC{info} UNSIGNED")
543            }
544            DataType::BigNumeric(info) => write!(f, "BIGNUMERIC{info}"),
545            DataType::BigDecimal(info) => write!(f, "BIGDECIMAL{info}"),
546            DataType::Float(info) => write!(f, "FLOAT{info}"),
547            DataType::FloatUnsigned(info) => write!(f, "FLOAT{info} UNSIGNED"),
548            DataType::TinyInt(zerofill) => {
549                format_type_with_optional_length(f, "TINYINT", zerofill, false)
550            }
551            DataType::TinyIntUnsigned(zerofill) => {
552                format_type_with_optional_length(f, "TINYINT", zerofill, true)
553            }
554            DataType::Int2(zerofill) => {
555                format_type_with_optional_length(f, "INT2", zerofill, false)
556            }
557            DataType::Int2Unsigned(zerofill) => {
558                format_type_with_optional_length(f, "INT2", zerofill, true)
559            }
560            DataType::SmallInt(zerofill) => {
561                format_type_with_optional_length(f, "SMALLINT", zerofill, false)
562            }
563            DataType::SmallIntUnsigned(zerofill) => {
564                format_type_with_optional_length(f, "SMALLINT", zerofill, true)
565            }
566            DataType::MediumInt(zerofill) => {
567                format_type_with_optional_length(f, "MEDIUMINT", zerofill, false)
568            }
569            DataType::MediumIntUnsigned(zerofill) => {
570                format_type_with_optional_length(f, "MEDIUMINT", zerofill, true)
571            }
572            DataType::Int(zerofill) => format_type_with_optional_length(f, "INT", zerofill, false),
573            DataType::IntUnsigned(zerofill) => {
574                format_type_with_optional_length(f, "INT", zerofill, true)
575            }
576            DataType::Int4(zerofill) => {
577                format_type_with_optional_length(f, "INT4", zerofill, false)
578            }
579            DataType::Int8(zerofill) => {
580                format_type_with_optional_length(f, "INT8", zerofill, false)
581            }
582            DataType::Int16 => {
583                write!(f, "Int16")
584            }
585            DataType::Int32 => {
586                write!(f, "Int32")
587            }
588            DataType::Int64 => {
589                write!(f, "INT64")
590            }
591            DataType::Int128 => {
592                write!(f, "Int128")
593            }
594            DataType::Int256 => {
595                write!(f, "Int256")
596            }
597            DataType::HugeInt => {
598                write!(f, "HUGEINT")
599            }
600            DataType::Int4Unsigned(zerofill) => {
601                format_type_with_optional_length(f, "INT4", zerofill, true)
602            }
603            DataType::Integer(zerofill) => {
604                format_type_with_optional_length(f, "INTEGER", zerofill, false)
605            }
606            DataType::IntegerUnsigned(zerofill) => {
607                format_type_with_optional_length(f, "INTEGER", zerofill, true)
608            }
609            DataType::BigInt(zerofill) => {
610                format_type_with_optional_length(f, "BIGINT", zerofill, false)
611            }
612            DataType::BigIntUnsigned(zerofill) => {
613                format_type_with_optional_length(f, "BIGINT", zerofill, true)
614            }
615            DataType::Int8Unsigned(zerofill) => {
616                format_type_with_optional_length(f, "INT8", zerofill, true)
617            }
618            DataType::UTinyInt => {
619                write!(f, "UTINYINT")
620            }
621            DataType::USmallInt => {
622                write!(f, "USMALLINT")
623            }
624            DataType::UBigInt => {
625                write!(f, "UBIGINT")
626            }
627            DataType::UHugeInt => {
628                write!(f, "UHUGEINT")
629            }
630            DataType::UInt8 => {
631                write!(f, "UInt8")
632            }
633            DataType::UInt16 => {
634                write!(f, "UInt16")
635            }
636            DataType::UInt32 => {
637                write!(f, "UInt32")
638            }
639            DataType::UInt64 => {
640                write!(f, "UInt64")
641            }
642            DataType::UInt128 => {
643                write!(f, "UInt128")
644            }
645            DataType::UInt256 => {
646                write!(f, "UInt256")
647            }
648            DataType::Signed => {
649                write!(f, "SIGNED")
650            }
651            DataType::SignedInteger => {
652                write!(f, "SIGNED INTEGER")
653            }
654            DataType::Unsigned => {
655                write!(f, "UNSIGNED")
656            }
657            DataType::UnsignedInteger => {
658                write!(f, "UNSIGNED INTEGER")
659            }
660            DataType::Real => write!(f, "REAL"),
661            DataType::RealUnsigned => write!(f, "REAL UNSIGNED"),
662            DataType::Float4 => write!(f, "FLOAT4"),
663            DataType::Float32 => write!(f, "Float32"),
664            DataType::Float64 => write!(f, "FLOAT64"),
665            DataType::Double(info) => write!(f, "DOUBLE{info}"),
666            DataType::DoubleUnsigned(info) => write!(f, "DOUBLE{info} UNSIGNED"),
667            DataType::Float8 => write!(f, "FLOAT8"),
668            DataType::DoublePrecision => write!(f, "DOUBLE PRECISION"),
669            DataType::DoublePrecisionUnsigned => write!(f, "DOUBLE PRECISION UNSIGNED"),
670            DataType::Bool => write!(f, "BOOL"),
671            DataType::Boolean => write!(f, "BOOLEAN"),
672            DataType::Date => write!(f, "DATE"),
673            DataType::Date32 => write!(f, "Date32"),
674            DataType::Time(precision, timezone_info) => {
675                format_datetime_precision_and_tz(f, "TIME", precision, timezone_info)
676            }
677            DataType::Datetime(precision) => {
678                format_type_with_optional_length(f, "DATETIME", precision, false)
679            }
680            DataType::Timestamp(precision, timezone_info) => {
681                format_datetime_precision_and_tz(f, "TIMESTAMP", precision, timezone_info)
682            }
683            DataType::TimestampNtz => write!(f, "TIMESTAMP_NTZ"),
684            DataType::Datetime64(precision, timezone) => {
685                format_clickhouse_datetime_precision_and_timezone(
686                    f,
687                    "DateTime64",
688                    precision,
689                    timezone,
690                )
691            }
692            DataType::Interval { fields, precision } => {
693                write!(f, "INTERVAL")?;
694                if let Some(fields) = fields {
695                    write!(f, " {fields}")?;
696                }
697                if let Some(precision) = precision {
698                    write!(f, "({precision})")?;
699                }
700                Ok(())
701            }
702            DataType::JSON => write!(f, "JSON"),
703            DataType::JSONB => write!(f, "JSONB"),
704            DataType::Regclass => write!(f, "REGCLASS"),
705            DataType::Text => write!(f, "TEXT"),
706            DataType::TinyText => write!(f, "TINYTEXT"),
707            DataType::MediumText => write!(f, "MEDIUMTEXT"),
708            DataType::LongText => write!(f, "LONGTEXT"),
709            DataType::String(size) => format_type_with_optional_length(f, "STRING", size, false),
710            DataType::Bytea => write!(f, "BYTEA"),
711            DataType::Bit(size) => format_type_with_optional_length(f, "BIT", size, false),
712            DataType::BitVarying(size) => {
713                format_type_with_optional_length(f, "BIT VARYING", size, false)
714            }
715            DataType::VarBit(size) => format_type_with_optional_length(f, "VARBIT", size, false),
716            DataType::Array(ty) => match ty {
717                ArrayElemTypeDef::None => write!(f, "ARRAY"),
718                ArrayElemTypeDef::SquareBracket(t, None) => write!(f, "{t}[]"),
719                ArrayElemTypeDef::SquareBracket(t, Some(size)) => write!(f, "{t}[{size}]"),
720                ArrayElemTypeDef::AngleBracket(t) => write!(f, "ARRAY<{t}>"),
721                ArrayElemTypeDef::Parenthesis(t) => write!(f, "Array({t})"),
722            },
723            DataType::Range(inner) => write!(f, "RANGE<{inner}>"),
724            DataType::Custom(ty, modifiers) => {
725                if modifiers.is_empty() {
726                    write!(f, "{ty}")
727                } else {
728                    write!(f, "{}({})", ty, modifiers.join(", "))
729                }
730            }
731            DataType::Enum(vals, bits) => {
732                match bits {
733                    Some(bits) => write!(f, "ENUM{bits}"),
734                    None => write!(f, "ENUM"),
735                }?;
736                write!(f, "(")?;
737                for (i, v) in vals.iter().enumerate() {
738                    if i != 0 {
739                        write!(f, ", ")?;
740                    }
741                    match v {
742                        EnumMember::Name(name) => {
743                            write!(f, "'{}'", escape_single_quote_string(name))?
744                        }
745                        EnumMember::NamedValue(name, value) => {
746                            write!(f, "'{}' = {}", escape_single_quote_string(name), value)?
747                        }
748                    }
749                }
750                write!(f, ")")
751            }
752            DataType::Set(vals) => {
753                write!(f, "SET(")?;
754                for (i, v) in vals.iter().enumerate() {
755                    if i != 0 {
756                        write!(f, ", ")?;
757                    }
758                    write!(f, "'{}'", escape_single_quote_string(v))?;
759                }
760                write!(f, ")")
761            }
762            DataType::Struct(fields, bracket) => {
763                if !fields.is_empty() {
764                    match bracket {
765                        StructBracketKind::Parentheses => {
766                            write!(f, "STRUCT({})", display_comma_separated(fields))
767                        }
768                        StructBracketKind::AngleBrackets => {
769                            write!(f, "STRUCT<{}>", display_comma_separated(fields))
770                        }
771                    }
772                } else {
773                    write!(f, "STRUCT")
774                }
775            }
776            DataType::Union(fields) => {
777                write!(f, "UNION({})", display_comma_separated(fields))
778            }
779            // ClickHouse
780            DataType::Nullable(data_type) => {
781                write!(f, "Nullable({data_type})")
782            }
783            DataType::FixedString(character_length) => {
784                write!(f, "FixedString({character_length})")
785            }
786            DataType::LowCardinality(data_type) => {
787                write!(f, "LowCardinality({data_type})")
788            }
789            DataType::Map(key_data_type, value_data_type) => {
790                write!(f, "Map({key_data_type}, {value_data_type})")
791            }
792            DataType::Tuple(fields) => {
793                write!(f, "Tuple({})", display_comma_separated(fields))
794            }
795            DataType::Nested(fields) => {
796                write!(f, "Nested({})", display_comma_separated(fields))
797            }
798            DataType::Unspecified => Ok(()),
799            DataType::Trigger => write!(f, "TRIGGER"),
800            DataType::AnyType => write!(f, "ANY TYPE"),
801            DataType::Table(fields) => match fields {
802                Some(fields) => {
803                    write!(f, "TABLE({})", display_comma_separated(fields))
804                }
805                None => {
806                    write!(f, "TABLE")
807                }
808            },
809            DataType::NamedTable { name, columns } => {
810                write!(f, "{} TABLE ({})", name, display_comma_separated(columns))
811            }
812            DataType::GeometricType(kind) => write!(f, "{kind}"),
813            DataType::TsVector => write!(f, "TSVECTOR"),
814            DataType::TsQuery => write!(f, "TSQUERY"),
815        }
816    }
817}
818
819fn format_type_with_optional_length(
820    f: &mut fmt::Formatter,
821    sql_type: &'static str,
822    len: &Option<u64>,
823    unsigned: bool,
824) -> fmt::Result {
825    write!(f, "{sql_type}")?;
826    if let Some(len) = len {
827        write!(f, "({len})")?;
828    }
829    if unsigned {
830        write!(f, " UNSIGNED")?;
831    }
832    Ok(())
833}
834
835fn format_character_string_type(
836    f: &mut fmt::Formatter,
837    sql_type: &str,
838    size: &Option<CharacterLength>,
839) -> fmt::Result {
840    write!(f, "{sql_type}")?;
841    if let Some(size) = size {
842        write!(f, "({size})")?;
843    }
844    Ok(())
845}
846
847fn format_varbinary_type(
848    f: &mut fmt::Formatter,
849    sql_type: &str,
850    size: &Option<BinaryLength>,
851) -> fmt::Result {
852    write!(f, "{sql_type}")?;
853    if let Some(size) = size {
854        write!(f, "({size})")?;
855    }
856    Ok(())
857}
858
859fn format_datetime_precision_and_tz(
860    f: &mut fmt::Formatter,
861    sql_type: &'static str,
862    len: &Option<u64>,
863    time_zone: &TimezoneInfo,
864) -> fmt::Result {
865    write!(f, "{sql_type}")?;
866    let len_fmt = len.as_ref().map(|l| format!("({l})")).unwrap_or_default();
867
868    match time_zone {
869        TimezoneInfo::Tz => {
870            write!(f, "{time_zone}{len_fmt}")?;
871        }
872        _ => {
873            write!(f, "{len_fmt}{time_zone}")?;
874        }
875    }
876
877    Ok(())
878}
879
880fn format_clickhouse_datetime_precision_and_timezone(
881    f: &mut fmt::Formatter,
882    sql_type: &'static str,
883    len: &u64,
884    time_zone: &Option<String>,
885) -> fmt::Result {
886    write!(f, "{sql_type}({len}")?;
887
888    if let Some(time_zone) = time_zone {
889        write!(f, ", '{time_zone}'")?;
890    }
891
892    write!(f, ")")?;
893
894    Ok(())
895}
896
897/// Type of brackets used for `STRUCT` literals.
898#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
899#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
900#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
901pub enum StructBracketKind {
902    /// Example: `STRUCT(a INT, b STRING)`
903    Parentheses,
904    /// Example: `STRUCT<a INT, b STRING>`
905    AngleBrackets,
906}
907
908/// Timestamp and Time data types information about TimeZone formatting.
909///
910/// This is more related to a display information than real differences between each variant. To
911/// guarantee compatibility with the input query we must maintain its exact information.
912#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
913#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
914#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
915pub enum TimezoneInfo {
916    /// No information about time zone, e.g. TIMESTAMP
917    None,
918    /// Temporal type 'WITH TIME ZONE', e.g. TIMESTAMP WITH TIME ZONE, [SQL Standard], [Oracle]
919    ///
920    /// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#datetime-type
921    /// [Oracle]: https://docs.oracle.com/en/database/oracle/oracle-database/12.2/nlspg/datetime-data-types-and-time-zone-support.html#GUID-3F1C388E-C651-43D5-ADBC-1A49E5C2CA05
922    WithTimeZone,
923    /// Temporal type 'WITHOUT TIME ZONE', e.g. TIME WITHOUT TIME ZONE, [SQL Standard], [Postgresql]
924    ///
925    /// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#datetime-type
926    /// [Postgresql]: https://www.postgresql.org/docs/current/datatype-datetime.html
927    WithoutTimeZone,
928    /// Postgresql specific `WITH TIME ZONE` formatting, for both TIME and TIMESTAMP, e.g. TIMETZ, [Postgresql]
929    ///
930    /// [Postgresql]: https://www.postgresql.org/docs/current/datatype-datetime.html
931    Tz,
932}
933
934impl fmt::Display for TimezoneInfo {
935    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
936        match self {
937            TimezoneInfo::None => {
938                write!(f, "")
939            }
940            TimezoneInfo::WithTimeZone => {
941                write!(f, " WITH TIME ZONE")
942            }
943            TimezoneInfo::WithoutTimeZone => {
944                write!(f, " WITHOUT TIME ZONE")
945            }
946            TimezoneInfo::Tz => {
947                // TZ is the only one that is displayed BEFORE the precision, so the datatype display
948                // must be aware of that. Check <https://www.postgresql.org/docs/14/datatype-datetime.html>
949                // for more information
950                write!(f, "TZ")
951            }
952        }
953    }
954}
955
956/// Fields for [Postgres] `INTERVAL` type.
957///
958/// [Postgres]: https://www.postgresql.org/docs/17/datatype-datetime.html
959#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
960#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
961#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
962pub enum IntervalFields {
963    Year,
964    Month,
965    Day,
966    Hour,
967    Minute,
968    Second,
969    YearToMonth,
970    DayToHour,
971    DayToMinute,
972    DayToSecond,
973    HourToMinute,
974    HourToSecond,
975    MinuteToSecond,
976}
977
978impl fmt::Display for IntervalFields {
979    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
980        match self {
981            IntervalFields::Year => write!(f, "YEAR"),
982            IntervalFields::Month => write!(f, "MONTH"),
983            IntervalFields::Day => write!(f, "DAY"),
984            IntervalFields::Hour => write!(f, "HOUR"),
985            IntervalFields::Minute => write!(f, "MINUTE"),
986            IntervalFields::Second => write!(f, "SECOND"),
987            IntervalFields::YearToMonth => write!(f, "YEAR TO MONTH"),
988            IntervalFields::DayToHour => write!(f, "DAY TO HOUR"),
989            IntervalFields::DayToMinute => write!(f, "DAY TO MINUTE"),
990            IntervalFields::DayToSecond => write!(f, "DAY TO SECOND"),
991            IntervalFields::HourToMinute => write!(f, "HOUR TO MINUTE"),
992            IntervalFields::HourToSecond => write!(f, "HOUR TO SECOND"),
993            IntervalFields::MinuteToSecond => write!(f, "MINUTE TO SECOND"),
994        }
995    }
996}
997
998/// Additional information for `NUMERIC`, `DECIMAL`, and `DEC` data types
999/// following the 2016 [SQL Standard].
1000///
1001/// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type
1002#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1003#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1004#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1005pub enum ExactNumberInfo {
1006    /// No additional information, e.g. `DECIMAL`
1007    None,
1008    /// Only precision information, e.g. `DECIMAL(10)`
1009    Precision(u64),
1010    /// Precision and scale information, e.g. `DECIMAL(10,2)`
1011    PrecisionAndScale(u64, i64),
1012}
1013
1014impl fmt::Display for ExactNumberInfo {
1015    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1016        match self {
1017            ExactNumberInfo::None => {
1018                write!(f, "")
1019            }
1020            ExactNumberInfo::Precision(p) => {
1021                write!(f, "({p})")
1022            }
1023            ExactNumberInfo::PrecisionAndScale(p, s) => {
1024                write!(f, "({p},{s})")
1025            }
1026        }
1027    }
1028}
1029
1030/// Information about [character length][1], including length and possibly unit.
1031///
1032/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-length
1033#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1034#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1035#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1036pub enum CharacterLength {
1037    IntegerLength {
1038        /// Default (if VARYING) or maximum (if not VARYING) length
1039        length: u64,
1040        /// Optional unit. If not informed, the ANSI handles it as CHARACTERS implicitly
1041        unit: Option<CharLengthUnits>,
1042    },
1043    /// VARCHAR(MAX) or NVARCHAR(MAX), used in T-SQL (Microsoft SQL Server)
1044    Max,
1045}
1046
1047impl fmt::Display for CharacterLength {
1048    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1049        match self {
1050            CharacterLength::IntegerLength { length, unit } => {
1051                write!(f, "{length}")?;
1052                if let Some(unit) = unit {
1053                    write!(f, " {unit}")?;
1054                }
1055            }
1056            CharacterLength::Max => {
1057                write!(f, "MAX")?;
1058            }
1059        }
1060        Ok(())
1061    }
1062}
1063
1064/// Possible units for characters, initially based on 2016 ANSI [SQL Standard][1].
1065///
1066/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#char-length-units
1067#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1068#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1069#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1070pub enum CharLengthUnits {
1071    /// CHARACTERS unit
1072    Characters,
1073    /// OCTETS unit
1074    Octets,
1075}
1076
1077impl fmt::Display for CharLengthUnits {
1078    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1079        match self {
1080            Self::Characters => {
1081                write!(f, "CHARACTERS")
1082            }
1083            Self::Octets => {
1084                write!(f, "OCTETS")
1085            }
1086        }
1087    }
1088}
1089
1090#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1091#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1092#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1093pub enum BinaryLength {
1094    IntegerLength {
1095        /// Default (if VARYING)
1096        length: u64,
1097    },
1098    /// VARBINARY(MAX) used in T-SQL (Microsoft SQL Server)
1099    Max,
1100}
1101
1102impl fmt::Display for BinaryLength {
1103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1104        match self {
1105            BinaryLength::IntegerLength { length } => {
1106                write!(f, "{length}")?;
1107            }
1108            BinaryLength::Max => {
1109                write!(f, "MAX")?;
1110            }
1111        }
1112        Ok(())
1113    }
1114}
1115
1116/// Represents the data type of the elements in an array (if any) as well as
1117/// the syntax used to declare the array.
1118///
1119/// For example: Bigquery/Hive use `ARRAY<INT>` whereas snowflake uses ARRAY.
1120#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1121#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1122#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1123pub enum ArrayElemTypeDef {
1124    /// `ARRAY`
1125    None,
1126    /// `ARRAY<INT>`
1127    AngleBracket(Box<DataType>),
1128    /// `INT[]` or `INT[2]`
1129    SquareBracket(Box<DataType>, Option<u64>),
1130    /// `Array(Int64)`
1131    Parenthesis(Box<DataType>),
1132}
1133
1134/// Represents different types of geometric shapes which are commonly used in
1135/// PostgreSQL/Redshift for spatial operations and geometry-related computations.
1136///
1137/// [PostgreSQL]: https://www.postgresql.org/docs/9.5/functions-geometry.html
1138#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1139#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1140#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1141pub enum GeometricTypeKind {
1142    Point,
1143    Line,
1144    LineSegment,
1145    GeometricBox,
1146    GeometricPath,
1147    Polygon,
1148    Circle,
1149}
1150
1151impl fmt::Display for GeometricTypeKind {
1152    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1153        match self {
1154            GeometricTypeKind::Point => write!(f, "point"),
1155            GeometricTypeKind::Line => write!(f, "line"),
1156            GeometricTypeKind::LineSegment => write!(f, "lseg"),
1157            GeometricTypeKind::GeometricBox => write!(f, "box"),
1158            GeometricTypeKind::GeometricPath => write!(f, "path"),
1159            GeometricTypeKind::Polygon => write!(f, "polygon"),
1160            GeometricTypeKind::Circle => write!(f, "circle"),
1161        }
1162    }
1163}