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