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