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