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