Skip to main content

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