pub struct TypeNameSyntax {Show 20 fields
pub extended_scalar_type_names: bool,
pub enum_type: bool,
pub set_type: bool,
pub numeric_modifiers: bool,
pub integer_display_width: bool,
pub composite_types: bool,
pub angle_bracket_types: bool,
pub varchar_requires_length: bool,
pub zoned_temporal_types: bool,
pub empty_type_parens: bool,
pub character_set_annotation: bool,
pub signed_type_modifier: bool,
pub nullable_type: bool,
pub low_cardinality_type: bool,
pub fixed_string_type: bool,
pub datetime64_type: bool,
pub nested_type: bool,
pub bit_width_integer_names: bool,
pub liberal_type_names: bool,
pub string_type_modifiers: bool,
}Expand description
Dialect-owned type-name vocabulary extensions accepted by the parser.
The standard/PostgreSQL scalar type names are always recognized; these flags
gate type-name surfaces which the shared vocabulary does not cover.
Each is a recognition gate, not a parser-side dialect check: when off,
a name like TINYINT is not matched as a built-in and falls through to the
user-defined-type path (so ANSI/PostgreSQL read it as an ordinary type name),
while a structural form like ENUM('a','b') surfaces as a clean parse error
(its value list is not a numeric type modifier). The modelling — new
DataType variants, spelling tags, and value-list/wrapper
shapes — lives with the AST; this struct only decides which dialects recognize it.
Fields§
§extended_scalar_type_names: boolRecognize extended scalar type names: the TINYINT/MEDIUMINT
integer widths, bare DOUBLE, DATETIME, the TINYTEXT/MEDIUMTEXT/
LONGTEXT character-LOB family, and the TINYBLOB/BLOB/MEDIUMBLOB/
LONGBLOB binary-LOB family.
enum_type: boolRecognize the ENUM(...) value-list type in data-type position — MySQL’s column
type and DuckDB’s x::ENUM('a', 'b') cast target (which rides the same
DataType::Enum shape; DuckDB’s CREATE TYPE ... AS ENUM
statement uses a separate dedicated production, see
CreateTypeDefinition). Split from
set_type because DuckDB has ENUM but no SET type
(x::SET('a','b') is an unknown-type error there, not a value-list type).
set_type: boolRecognize the SET(...) value-list type in data-type position (MySQL only). Kept
distinct from enum_type: the two share one value-list shape but
SET is MySQL-specific, so DuckDB enables only ENUM.
numeric_modifiers: boolRecognize the SIGNED/UNSIGNED/ZEROFILL numeric modifiers (as a postfix
on a numeric type) and the standalone SIGNED/UNSIGNED integer cast
targets, e.g. CAST(x AS UNSIGNED) (MySQL).
integer_display_width: boolRecognize an optional display width (M) on a built-in integer type name —
INT(11), TINYINT(1), BIGINT(20) — stored on the integer
DataType variant’s display_width field. Canonical
to MySQL (deprecated in 8.0.17+ but ubiquitous in dumps); SQLite accepts it
through affinity type-name absorption. When off, the trailing ( on a
built-in integer is not consumed and surfaces as a clean parse error, so
ANSI/PostgreSQL reject INT(11) (verified against pg_query). Independent of
extended_scalar_type_names (SQLite wants the width
without the TINYINT/MEDIUMINT scalar names) and of
numeric_modifiers ((M) is a prefix arg on the
type name; UNSIGNED/ZEROFILL are a separate postfix).
composite_types: boolRecognize DuckDB’s anonymous composite / nested type constructors in type
position: STRUCT(a INT, ...) and the standard ROW(...) spelling of the same
shape, the tagged UNION(tag T, ...), and MAP(K, V). A grammar-position gate
keyed on the keyword immediately followed by (; when off, the leading word falls
through to the user-defined-type path (a bare struct/map name still resolves),
so ANSI/PostgreSQL reject the anonymous form — PostgreSQL has only named
composite types and spells ROW as a value constructor, never a type (verified
against a live server: x::STRUCT(a int) / x::ROW(a int) / x::MAP(int,text)
each syntax-error). On for DuckDb/Lenient. The array-type suffixes (T[]/T[n]/
T ARRAY[n]) are not gated here — PostgreSQL accepts them too — they ride the
always-parsed array-suffix grammar.
angle_bracket_types: boolAccept BigQuery angle-bracket type forms STRUCT<field TYPE, …> and ARRAY<T>
in type position (CAST(x AS STRUCT<a INT64>), column definitions). On for
BigQuery/Lenient. Distinct from composite_types
(DuckDB paren form STRUCT(a INT)) and from expression-position
struct_constructor.
varchar_requires_length: boolRequire an explicit length parameter on VARCHAR and VARBINARY
(VARCHAR(255), VARBINARY(16)). On for MySQL, whose VARCHAR/VARBINARY are a
syntax error without a length (CREATE TABLE t (a VARCHAR) is an ER_PARSE_ERROR on
mysql:8, while the fixed-width CHAR/BINARY default to length 1 and stay valid).
Off for ANSI/PostgreSQL/SQLite/DuckDB/Lenient, where a length-less VARCHAR is
accepted; when off the missing size is simply left None.
zoned_temporal_types: boolAccept time-zone-aware temporal type names — TIMESTAMPTZ / TIMESTAMP WITH TIME ZONE, TIMETZ / TIME WITH TIME ZONE. On for ANSI/PostgreSQL/SQLite/DuckDB/Lenient.
MySQL has no zoned temporal type (its TIMESTAMP stores UTC but the type carries no
zone qualifier), so TIMESTAMPTZ and the WITH TIME ZONE spellings are an
ER_PARSE_ERROR on mysql:8; it is off there and a parsed temporal type carrying a
zone qualifier is rejected. The zone-less TIMESTAMP/TIME/DATETIME forms are
unaffected.
empty_type_parens: boolAccept an EMPTY type-parameter parenthesis list on the DECIMAL/DEC/NUMERIC
type names — DECIMAL(), DEC(), NUMERIC() — meaning the default precision/scale.
DuckDB normalizes DECIMAL() to DECIMAL(18,3), byte-identical to a bare DECIMAL
(probed on 1.5.4: typeof(x::DECIMAL()) == typeof(x::DECIMAL) == DECIMAL(18,3)),
so the empty form carries no information and folds onto the same precision: None, scale: None DataType::Decimal shape — the canonical render
drops the parens (an ADR-0011 spelling trade; the verbatim () survives on the node
span). On for DuckDb/Lenient. Off elsewhere, where the empty ( on a DECIMAL needs
a precision and the missing modifier surfaces as a clean parse error (verified against
pg_query: PostgreSQL rejects DECIMAL()).
Scoped to the DECIMAL family (the surface the core-tranche corpus exercises). DuckDB
also admits empty parens on its generic/user-resolved type names and a handful of
dedicated built-ins (DOUBLE(), TEXT(), DATE(), JSON(), TIMESTAMPTZ(),
UUID(), HUGEINT(), …) via the same opt_type_modifiers grammar, while the other
hard-coded keyword types keep rejecting it (VARCHAR()/TIMESTAMP()/FLOAT() need a
value; INT()/REAL()/BOOLEAN() admit no parens at all) — an asymmetric,
separately-testable extension deferred (probe matrix on duckdb-empty-type-parens).
character_set_annotation: boolRecognize MySQL’s character-set annotation on a char-family type — the grammar’s
opt_charset_with_opt_binary production: CHARACTER SET <name>, the CHARSET
synonym, the ASCII/UNICODE/BYTE shortcuts, and/or the BINARY binary-collation
modifier, in either order (CHAR CHARACTER SET x BINARY, CHAR BINARY ASCII). Stored
on the DataType::Character node’s charset field because it
is part of the type — it must immediately follow the type and its length, and is an
ER_PARSE_ERROR on mysql:8 once a column attribute intervenes (CHAR(5) NOT NULL CHARACTER SET x), unlike the free-floating COLLATE column attribute. Admitted in
both the cast target (CAST(x AS CHAR(5) CHARACTER SET utf8mb4)) and column-definition
positions that funnel through the shared type grammar, on the non-national spellings
only (CHAR/CHARACTER/VARCHAR; the NCHAR/NATIONAL forms fix their own charset
and reject it). On for MySQL/Lenient. Off elsewhere — PostgreSQL rejects CHARACTER SET in its modern grammar (verified against pg_query: CHAR(5) CHARACTER SET utf8
is a syntax error), so when off the annotation keyword is left unconsumed and surfaces
as a clean parse error.
signed_type_modifier: boolAccept a leading sign on a numeric/decimal precision/scale type modifier
(numeric(5, -2), numeric(-3, 6)). PostgreSQL parses the modifier arguments as a
general expression list at raw-parse time, so a signed integer is accepted and only
validated later. On for PostgreSQL/Lenient. Off elsewhere (ANSI/MySQL/SQLite/DuckDB
require an unsigned modifier), where the leading - on a modifier surfaces as a clean
parse error.
nullable_type: boolRecognize ClickHouse’s Nullable(T) parametric type combinator in type position —
the inner type extended with a NULL value, carried on the
DataType::Wrapped shape. A grammar-position gate keyed on
the keyword immediately followed by ( (the composite-type precedent), so a bare
Nullable with no ( stays an ordinary type/column name and, when off, the whole
Nullable(...) head falls through to the user-defined-type path. The inner type is a
full recursive type, so Nullable(DECIMAL(10, 2)) / Nullable(String)[] parse;
ClickHouse’s Nullable(Nullable(T)) / Nullable(Array(T)) composability rejects are
a bind-time DB::Exception, not a grammar error, so they parse-accept here.
On for the ClickHouse preset and Lenient. ClickHouse has no differential oracle, so
the no-oracle acceptance addition belongs to the ClickHouse preset and Lenient (the
composite_types / format_clause precedent): off for every oracle-compared preset,
which parse-reject Nullable(...) (its head resolves to a user-defined type name whose
(String) modifier list then fails to parse).
low_cardinality_type: boolRecognize ClickHouse’s LowCardinality(T) parametric type combinator in type
position — a dictionary-encoding wrapper transparent to query semantics, carried on
the DataType::Wrapped shape (the same single-inner-type
wrapper as nullable_type, its own flag per one-behaviour-one-flag). A
grammar-position gate keyed on the keyword immediately followed by (, so a bare
LowCardinality with no ( stays an ordinary type/column name and, when off, the
whole LowCardinality(...) head falls through to the user-defined-type path. The
inner type is a full recursive type, so the canonical LowCardinality(Nullable(String))
composition and LowCardinality(DECIMAL(10, 2)) parse; ClickHouse constrains which
inner T is valid at type resolution (a bind-time DB::Exception, not a grammar
error), so any single inner type parse-accepts here.
On for the ClickHouse preset and Lenient. ClickHouse has no differential oracle, so
the no-oracle acceptance addition belongs to the ClickHouse preset and Lenient (the
composite_types / nullable_type precedent): off for every oracle-compared preset,
which parse-reject LowCardinality(...) (its head resolves to a user-defined type
name whose (String) modifier list then fails to parse).
fixed_string_type: boolRecognize ClickHouse’s FixedString(N) type constructor in type position — a
fixed-length byte string of exactly N bytes, carried on the
DataType::FixedString shape. Unlike the Nullable/
LowCardinality wrappers its argument is a scalar length, not an inner type, so it
is its own variant, not a WrappedTypeKind arm; its
own flag per one-behaviour-one-flag. A grammar-position gate keyed on the keyword
immediately followed by ( (the composite/wrapper precedent), so a bare
FixedString with no ( stays an ordinary type/column name and, when off, the whole
FixedString(...) head falls through to the user-defined-type path. N is mandatory
(a bare FixedString is an invalid ClickHouse spelling) and parsed as any u32
literal; ClickHouse’s positive-length requirement (FixedString(0) reject) is a
bind-time DB::Exception, not a grammar error, so it parse-accepts here.
On for the ClickHouse preset and Lenient. ClickHouse has no differential oracle, so
the no-oracle acceptance addition belongs to the ClickHouse preset and Lenient (the
nullable_type / low_cardinality_type precedent): off for every oracle-compared
preset, which parse-reject FixedString(...) (its head resolves to a user-defined
type name whose (N) modifier list then fails to parse).
datetime64_type: boolRecognize ClickHouse’s DateTime64(P[, 'timezone']) type constructor in type
position — a sub-second timestamp carried on the
DataType::DateTime64 shape. Its own flag per
one-behaviour-one-flag; like fixed_string_type its
leading argument is a mandatory scalar (the precision P), not an inner type, so it
is a dedicated variant, not a WrappedTypeKind arm.
The optional second argument is a single-quoted time-zone string literal, not the
ANSI WITH TIME ZONE flag. A grammar-position gate keyed on the keyword immediately
followed by ( (the composite/wrapper precedent), so a bare DateTime64 with no (
stays an ordinary type/column name and, when off, the whole DateTime64(...) head
falls through to the user-defined-type path. P is parsed as any u32 literal;
ClickHouse’s documented 0..=9 range is a bind-time reject, not a grammar error, so
it parse-accepts here.
On for the ClickHouse preset and Lenient. ClickHouse has no differential oracle, so
the no-oracle acceptance addition belongs to the ClickHouse preset and Lenient (the
fixed_string_type precedent): off for every oracle-compared preset. Off-gate the
boundary is asymmetric — DateTime64(3) still parse-accepts as a user-defined type
name with a (3) numeric-modifier list, but DateTime64(3, 'UTC') parse-rejects,
because the string second argument does not fit the u32-only modifier grammar.
nested_type: boolRecognize ClickHouse’s Nested(name1 Type1, name2 Type2, ...) named-field composite
type in type position — a repeated group carried on the
DataType::Nested shape (the named-field
StructTypeField list of composite_types, but a
distinct variant and its own flag per one-behaviour-one-flag: Nested round-trips as
Nested, never STRUCT, and its semantics are a repeated structure, not a product).
A grammar-position gate keyed on the keyword immediately followed by ( (the
composite/wrapper precedent), so a bare Nested with no ( stays an ordinary
type/column name and, when off, the whole Nested(...) head falls through to the
user-defined-type path. A field type is a full recursive type, so Nested(x Nested(...)) parses; ClickHouse’s nesting-level limit is a flatten_nested setting /
bind concern, not a grammar error, so it parse-accepts here.
On for the ClickHouse preset and Lenient. ClickHouse has no differential oracle, so
the no-oracle acceptance addition belongs to the ClickHouse preset and Lenient (the
datetime64_type precedent): off for every oracle-compared preset, which parse-reject
Nested(a UInt8) — its head resolves to a user-defined type name whose modifier list
is u32-only, so the two-word a UInt8 field has no grammar to fit (the wrapper
off-gate reject, not the asymmetric DateTime64(3) accept).
bit_width_integer_names: boolRecognize ClickHouse’s fixed-bit-width integer type names — the signed
Int8/Int16/Int32/Int64/Int128/Int256 family and their unsigned
UInt8…UInt256 siblings — carried on the
DataType::FixedWidthInt shape. One flag for the whole
bit-width family: the names always travel together in a dialect, exactly as MySQL’s
TINYINT/MEDIUMINT/… ride one extended_scalar_type_names
gate, so this is one behaviour, not one flag per width. Unlike the
Nullable/FixedString constructors these names take no arguments, so recognition is a
bare-name gate (the TINYINT/extended_scalar precedent, not the keyword-then-(
lookahead): when off, a bare Int256 simply falls through to the user-defined-type path
(its trivial off-gate boundary, like a bare Nullable).
On for the ClickHouse preset and Lenient. ClickHouse has no differential oracle, so the
no-oracle acceptance addition belongs to the ClickHouse preset and Lenient (the nullable_type
/ fixed_string_type / datetime64_type precedent): off for every oracle-compared
preset, which read Int256 as an ordinary user-defined type name.
liberal_type_names: boolWiden the type-name grammar to SQLite’s liberal affinity form: a column/cast type is
any run of one-or-more space-separated words (UNSIGNED BIG INT, LONG INTEGER, the
misspelled INTEGEB PRIMARI KEY) with an optional two-argument parenthesized
modifier (VARCHAR(123,456), FLOATING POINT(5,10)), carried on the
DataType::Liberal shape. SQLite has no closed type
vocabulary — every declared type is affinity text — so its grammar’s typename
accepts an arbitrary ids ... token run terminated by a column-constraint keyword, a
comma, or a close paren (engine-probed on rusqlite/sqlite3 3.53.2 & 3.43.2).
A strict FALLBACK: the typed variants and the single-word user-defined path win
wherever they can faithfully represent the input, so a bare INT, DOUBLE PRECISION,
VARCHAR(255), NATIONAL CHARACTER(15), or single-word affinity BANANA keep their
existing shapes with the flag on; only a trailing type-word or a two-argument paren
list that no typed / user-defined parse can hold falls to DataType::Liberal. The
word run terminates at a column-constraint keyword (PRIMARY/NOT/NULL/UNIQUE/
CHECK/DEFAULT/COLLATE/REFERENCES/CONSTRAINT/AS/GENERATED), so
GENERATED ALWAYS AS generated columns are unaffected.
On for SQLite and Lenient. Off elsewhere, where a multi-word type name or a
two-argument built-in modifier surfaces as a clean parse error (the standard/
PostgreSQL/MySQL/DuckDB have a closed type vocabulary; pg_query rejects
LONG INTEGER and VARCHAR(123,456)).
string_type_modifiers: boolAdmit a string-literal argument in a user-defined type name’s modifier list —
DuckDB’s GEOMETRY('OGC:CRS84') coordinate-system annotation, and more generally
any type_name('constant', ...) where DuckDB’s grammar accepts constants (string or
numeric) as type modifiers (engine-measured on DuckDB 1.5.4: MYTYPE('abc') reaches
the binder — a parse-accept — while a non-constant like (['abc']) stays a parser
error). The modifiers ride the DataType::UserDefined
shape’s modifiers list as Literals.
When off, only unsigned-integer modifiers parse (FOO(3)), so a string modifier
surfaces as a clean parse error — the standard/PostgreSQL/MySQL user-type grammar
admits no string modifier there. On for DuckDB only. Numeric modifiers parse
under every dialect regardless of this flag; it gates only the string form.
Implementations§
Source§impl TypeNameSyntax
impl TypeNameSyntax
Sourcepub const CLICKHOUSE: Self
Available on crate feature clickhouse only.
pub const CLICKHOUSE: Self
clickhouse only.ClickHouse type surface: the ANSI baseline plus the six ClickHouse type
constructors, each a contextual keyword + (-lookahead form (a bare Nullable
or Int256 with no ( stays an ordinary type/column name), so none reserves a
word. Every other type knob is conservatively ANSI: ClickHouse types with no
modelled gate (Array(T), Map(K, V), Tuple(...), Enum8/Enum16,
Decimal32, AggregateFunction, …) are deferred to focused tickets.
Trait Implementations§
Source§impl Clone for TypeNameSyntax
impl Clone for TypeNameSyntax
Source§fn clone(&self) -> TypeNameSyntax
fn clone(&self) -> TypeNameSyntax
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more