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