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