pub struct FeatureSet {Show 50 fields
pub identifier_casing: Casing,
pub identifier_quotes: &'static [IdentifierQuote],
pub default_null_ordering: NullOrdering,
pub reserved_column_name: KeywordSet,
pub reserved_function_name: KeywordSet,
pub reserved_type_name: KeywordSet,
pub reserved_bare_alias: KeywordSet,
pub reserved_as_label: KeywordSet,
pub catalog_qualified_names: bool,
pub byte_classes: ByteClasses,
pub binding_powers: BindingPowerTable,
pub set_operation_powers: SetOperationBindingPowerTable,
pub string_literals: StringLiteralSyntax,
pub numeric_literals: NumericLiteralSyntax,
pub parameters: ParameterSyntax,
pub session_variables: SessionVariableSyntax,
pub identifier_syntax: IdentifierSyntax,
pub table_expressions: TableExpressionSyntax,
pub join_syntax: JoinSyntax,
pub table_factor_syntax: TableFactorSyntax,
pub expression_syntax: ExpressionSyntax,
pub operator_syntax: OperatorSyntax,
pub call_syntax: CallSyntax,
pub string_func_forms: StringFuncForms,
pub aggregate_call_syntax: AggregateCallSyntax,
pub predicate_syntax: PredicateSyntax,
pub pipe_operator: PipeOperator,
pub double_ampersand: DoubleAmpersand,
pub keyword_operators: KeywordOperators,
pub caret_operator: CaretOperator,
pub hash_bitwise_xor: bool,
pub comment_syntax: CommentSyntax,
pub mutation_syntax: MutationSyntax,
pub statement_ddl_gates: StatementDdlGates,
pub view_sequence_clause_syntax: ViewSequenceClauseSyntax,
pub create_table_clause_syntax: CreateTableClauseSyntax,
pub column_definition_syntax: ColumnDefinitionSyntax,
pub constraint_syntax: ConstraintSyntax,
pub index_alter_syntax: IndexAlterSyntax,
pub existence_guards: ExistenceGuards,
pub select_syntax: SelectSyntax,
pub query_tail_syntax: QueryTailSyntax,
pub grouping_syntax: GroupingSyntax,
pub utility_syntax: UtilitySyntax,
pub transaction_syntax: TransactionSyntax,
pub show_syntax: ShowSyntax,
pub maintenance_syntax: MaintenanceSyntax,
pub access_control_syntax: AccessControlSyntax,
pub type_name_syntax: TypeNameSyntax,
pub target_spelling: TargetSpelling,
}Expand description
Small, typed dialect data consumed by parser and renderer code.
§Preset permissiveness spectrum
The shipped presets run from the strict standard to a parse-anything union; a
caller picks by how much non-standard SQL it must accept. The squonk crate’s
BuiltinDialect::ALL is the authoritative selectable list — this doc groups those
presets by how they are held honest:
ANSI— the strict SQL:2016 standard baseline: the principled neutral default, accepting only standard surface.POSTGRES/MYSQL/SQLITE/DUCKDB— one real dialect’s surface, strict in its own idiom (each gated behind its cargo feature). These, withANSI, are the oracle-compared presets: each is held to its real engine by a differential accept/reject oracle, so over-acceptance is a measured, gated zero.LENIENT— the permissive “parse anything” catch-all: the documented maximal union tooling reaches for on SQL of unknown origin (gated behind thelenientfeature).- The conservative, no-oracle presets —
BIGQUERY,HIVE,CLICKHOUSE,DATABRICKS,MSSQL,SNOWFLAKE,REDSHIFT(each behind its cargo feature) — derive fromANSIand enable only the surface that already has a modelled, tested parser gate and documentary evidence (theirONs are evidence-cited, not oracle-proven). This workspace ships no oracle for these engines, so their over-acceptance cannot be measured; conservatism is the honesty bar, and they are deliberately excluded from the oracle conformance sets — unsupported syntax is a clean reject routed to a follow-up ticket, never a silent over-accept. Each preset’s module doc spells out exactly what it adds overANSI.
There is deliberately no permissive “generic” preset (a vibe-union is
banned): ANSI is the generic/standard baseline, and LENIENT is the
honest, spelled-out permissive end. This differs from datafusion-sqlparser-rs,
whose GenericDialect is a permissive catch-all — the equivalent here is
LENIENT, not the standard baseline. The runtime name "generic" aliases ANSI;
see BuiltinDialect::from_name in the squonk crate for the migration mapping.
§Shared byte-trigger ownership: #
A single-meaning byte folds into one meaning-enum (the ^ axis is
caret_operator: exactly one of exponent / bitwise-XOR / none
per dialect). The # byte is not such a byte, and this is why its claimants stay
separate flags on their own sub-structs rather than a single HashMeaning enum: # is
a shared lead byte whose readings coexist in one dialect, partitioned by scan
phase and follow byte, not mutually exclusive. PostgreSQL enables bare-# XOR and
the #>/#>>/#- jsonb operators at once; a single-valued enum could not represent
both. Its five claimants, in resolution order:
#line comment (CommentSyntax::line_comment_hash, MySQL) — consumed as trivia before tokenizing, so when on it shadows every reading below.#+identifier-start word (abyte_classestable marking#CLASS_IDENTIFIER_START, T-SQL#temp) — the identifier scan precedes the operator/positional arms, so it wins on an identifier follow byte.#+digit positional column (ExpressionSyntax::positional_column, DuckDB#1).#+>/-jsonb path operators (OperatorSyntax::jsonb_operators, PostgreSQL) — maximal-munched ahead of a bare#, so disjoint from the readings below by follow byte; reaches the operator scanner only when#is routed there by claimant 5.- bare
#bitwise-XOR operator (hash_bitwise_xor, PostgreSQL) — the fallthrough when no earlier partition claims the byte.
Claimants 3/4/5 partition by follow byte and coexist freely; the genuine collisions
are only where a claimant is silently shadowed — the trivia phase (1 vs 2/3/5) and the
scan-order overlap (positional 3 vs bare-XOR 5). Those are the tracked pairwise
LexicalConflicts (HashCommentVersusHashIdentifier,
HashXorOperatorVersusHashComment,
HashXorOperatorVersusPositionalColumn,
HashCommentVersusPositionalColumn),
asserted absent on every shipped preset. That registry — one flag per behaviour, plus a
conflict entry per silently-shadowing pair — is the correct model for a coexisting-lead
byte; a HashMeaning meaning-enum would falsely impose mutual exclusion.
Fields§
§identifier_casing: CasingIdentity fold for unquoted identifiers; exact text remains interned.
identifier_quotes: &'static [IdentifierQuote]Identifier quote styles the dialect accepts (one or more; symmetric or asymmetric). The tokenizer matches an opening delimiter against this set.
default_null_ordering: NullOrderingDialect default when NULLS FIRST/NULLS LAST is omitted.
reserved_column_name: KeywordSetKeywords rejected as an unquoted column/table name or ColId alias
(PostgreSQL type_func_name ∪ reserved). Per-position reservation
(prod-keyword-position-reserved-sets): a keyword’s admissibility depends on
the grammatical position, so the single reserved set is replaced by four.
reserved_function_name: KeywordSetKeywords rejected as a function name (PostgreSQL reserved).
reserved_type_name: KeywordSetKeywords rejected as a (user-defined) type name (PostgreSQL
col_name ∪ reserved).
reserved_bare_alias: KeywordSetKeywords rejected as a bare column alias — one written without AS
(PostgreSQL AS_LABEL). AS-introduced aliases (ColLabel) admit every
keyword, so they need no reject set.
reserved_as_label: KeywordSetKeywords rejected in ColLabel position — an AS-introduced alias
(SELECT 1 AS <label>) and a dotted-name continuation part (schema.<part>,
x.<part>). PostgreSQL admits every keyword there (SELECT a AS select is
valid), so its set is KeywordSet::EMPTY; the same holds for every
PostgreSQL-family preset. SQLite draws no ColId/ColLabel split — a reserved
word is rejected in every name position uniformly — so it reuses its single
reserved set here, making SELECT 1 AS delete / SELECT x.update /
FROM schema.case the parse errors SQLite reports (engine-measured via rusqlite).
catalog_qualified_names: boolWhether a relation (table / index / view) name admits a catalog qualifier —
the third dotted part, catalog.schema.table. On for ANSI/PostgreSQL/MySQL/
DuckDB/Lenient, which cap a relation at three parts (a fourth is rejected). Off
for SQLite, whose relation names are schema.table at most (a database is the
schema namespace), so a three-part a.b.c in table/index position is the syntax
error SQLite reports (engine-measured via rusqlite). Column references reach one
part deeper through composite-field selection — a different grammar position —
and are never bounded by this flag.
byte_classes: ByteClassesByte classes used by tokenizer dispatch.
binding_powers: BindingPowerTableBinary and prefix operator binding powers used by parser and renderer.
set_operation_powers: SetOperationBindingPowerTableSet-operation binding powers used by parser and renderer.
string_literals: StringLiteralSyntaxString literal syntax extensions accepted by the tokenizer/parser.
numeric_literals: NumericLiteralSyntaxNumeric literal syntax extensions accepted by the tokenizer.
parameters: ParameterSyntaxPrepared-statement parameter placeholder forms accepted by the tokenizer.
session_variables: SessionVariableSyntaxMySQL session-variable forms (@name user variables, @@[scope.]name system
variables) accepted by the tokenizer.
identifier_syntax: IdentifierSyntaxUnquoted-identifier character policy (the dialect-variable $) accepted by the
tokenizer.
table_expressions: TableExpressionSyntaxTable-expression syntax forms accepted by the parser.
join_syntax: JoinSyntaxJoin-operator and recursive-query relation-composition syntax, gathered from
table_expressions.
table_factor_syntax: TableFactorSyntaxTable-factor FROM-item forms beyond a plain named table, gathered from
table_expressions.
expression_syntax: ExpressionSyntaxExpression postfix and constructor forms (typecast, subscript, COLLATE, AT TIME
ZONE, array/row constructors, field selection, typed literals) accepted by the
parser. The operator spellings and call-tail forms are separate dimensions —
see operator_syntax and call_syntax.
operator_syntax: OperatorSyntaxInfix/prefix operator forms (OPERATOR(…), @>/<@, ->/->>, ==, general
IS, <=>, the DuckDB lambda, the bitwise family, quantified comparisons)
accepted by the parser.
call_syntax: CallSyntaxFunction-call forms accepted by the parser (named arguments, cast/convert shape,
UTC_*/COLUMNS(…)/EXTRACT(… FROM …) special calls, …).
Aggregate tails (SEPARATOR/WITHIN GROUP/FILTER/OVER eligibility) live in
aggregate_call_syntax; keyword string specials live
in string_func_forms.
string_func_forms: StringFuncFormsKeyword string/scalar special-form syntax — the flags whose sole AST product
is a StringFunc.
aggregate_call_syntax: AggregateCallSyntaxAggregate/window function-call syntax — the in-parenthesis and post-) tails,
the argument-shape/arity restrictions, and the OVER-eligibility gate.
predicate_syntax: PredicateSyntaxPattern-match predicate forms (LIKE/ILIKE/SIMILAR TO) accepted by the
parser. LIKE is SQL core (on everywhere); ILIKE/SIMILAR TO are gated.
pipe_operator: PipeOperatorWhat the || operator token means: string concatenation or logical OR.
double_ampersand: DoubleAmpersandWhat the && operator token means: logical AND, or not an operator.
keyword_operators: KeywordOperatorsWhich dialect’s keyword infix operators are recognized (MySQL’s
DIV/MOD/XOR/RLIKE/REGEXP, SQLite’s GLOB/MATCH/REGEXP, or none) —
each variant names one dialect’s exact set; see KeywordOperators.
caret_operator: CaretOperatorWhat the ^ operator token means: arithmetic exponentiation, bitwise XOR, or no
infix meaning. The ^ byte always lexes; this is the sole owner of its infix
reading — the former split across an exponent_operator bool and a Caret-XOR
spelling is folded here, so the “both power and XOR” state is unrepresentable. See
CaretOperator.
hash_bitwise_xor: boolWhether a bare # lexes and parses as the bitwise-XOR operator
(BinaryOperator::BitwiseXor under the Hash
spelling, PostgreSQL). A different byte from caret_operator’s
^: PostgreSQL spells XOR #, MySQL spells it ^, and neither accepts the other’s
spelling. Also gates the tokenizer — # reaches the operator scanner only under this
flag — so it is one of the #-trigger claimants tracked in LexicalConflict
(against a # line comment and DuckDB’s #n positional column). Off for every
shipped dialect but PostgreSQL.
comment_syntax: CommentSyntaxDialect comment syntax extensions accepted by the tokenizer.
mutation_syntax: MutationSyntaxMutation-statement (INSERT/UPDATE/DELETE) syntax forms accepted by the
parser (RETURNING, ON CONFLICT).
statement_ddl_gates: StatementDdlGatesWhole-statement DDL dispatch gates (non-TABLE CREATE/DROP object dispatch),
split from the retired SchemaChangeSyntax.
view_sequence_clause_syntax: ViewSequenceClauseSyntaxView/sequence clause syntax after a DDL statement head has been chosen —
temporary/recursive views, view options, matview targets, sequence CACHE.
create_table_clause_syntax: CreateTableClauseSyntaxCREATE TABLE table-level clause syntax (storage/CTAS/partitioning/inheritance/
persistence clauses), split from the retired SchemaChangeSyntax.
column_definition_syntax: ColumnDefinitionSyntaxCREATE TABLE column-definition syntax (generated/identity columns, SQLite column
attributes, DEFAULT/COLLATE/STORAGE clauses), split from SchemaChangeSyntax.
constraint_syntax: ConstraintSyntaxTable/column-constraint syntax (deferrable/named/bare constraints, EXCLUDE, the
NO INHERIT/NOT VALID markers, index parameters), split from SchemaChangeSyntax.
index_alter_syntax: IndexAlterSyntaxCREATE INDEX/ALTER TABLE/DROP syntax (index clauses, the extended ALTER
surface, drop behaviour, routine arg types), split from SchemaChangeSyntax.
existence_guards: ExistenceGuardsIF [NOT] EXISTS existence guards on DDL statements (DROP/ALTER IF EXISTS,
CREATE VIEW/CREATE DATABASE IF NOT EXISTS), gathered from the schema-change
surface into one per-site table.
select_syntax: SelectSyntaxSELECT-body syntax forms accepted by the parser (DISTINCT ON, QUALIFY,
projection aliases, set-op quantifiers, …). Row-limiting / locking / pipe tails
live in query_tail_syntax; GROUP BY/ORDER BY
modes live in grouping_syntax.
query_tail_syntax: QueryTailSyntaxQuery-tail syntax — the row-limiting/locking family and the trailing ClickHouse/pipe clauses parsed after the SELECT body.
grouping_syntax: GroupingSyntaxGROUP BY/ORDER BY grouping-and-ordering syntax (grouping sets, clause
modes, and quantifiers).
utility_syntax: UtilitySyntaxUtility-statement syntax forms the parser dispatches: the
PostgreSQL COPY/COMMENT ON and SQLite PRAGMA/ATTACH/DETACH
statement gates.
transaction_syntax: TransactionSyntaxTransaction-control (TCL) syntax — openers, completers, savepoints, mode lists,
and XA forms — split from utility_syntax.
show_syntax: ShowSyntaxSHOW/DESCRIBE introspection-statement syntax (the session SHOW reader, the typed
SHOW <object> listings, and DESCRIBE/SUMMARIZE), gathered from
utility_syntax.
maintenance_syntax: MaintenanceSyntaxPhysical-maintenance-statement syntax (VACUUM/REINDEX/ANALYZE/CHECKPOINT),
gathered from utility_syntax.
access_control_syntax: AccessControlSyntaxAccess-control-statement syntax (GRANT/REVOKE and the extended object grammar),
gathered from utility_syntax.
type_name_syntax: TypeNameSyntaxType-name vocabulary the parser recognizes beyond the shared standard set
(the MySQL TINYINT/ENUM/UNSIGNED/… surface).
target_spelling: TargetSpellingWhich dialect’s canonical surface spelling a RenderSpelling::TargetDialect
render emits for constructs whose spelling diverges across dialects (today the
type names). Read by the renderer in place of recognizing a preset by identity,
so PostgreSQL-vs-ANSI output spelling is pure dialect data, not a cfg-gated
FeatureSet::POSTGRES comparison.
Implementations§
Source§impl FeatureSet
impl FeatureSet
Source§impl FeatureSet
impl FeatureSet
Source§impl FeatureSet
impl FeatureSet
Sourcepub const CLICKHOUSE: Self
Available on crate feature clickhouse only.
pub const CLICKHOUSE: Self
clickhouse only.ClickHouse as ANSI-derived dialect data (see the module docs for the full derivation rationale and the conservatism bar).
Source§impl FeatureSet
impl FeatureSet
Sourcepub const DATABRICKS: Self
Available on crate feature databricks only.
pub const DATABRICKS: Self
databricks only.Databricks as ANSI-derived dialect data (see the module docs for the full derivation rationale and the conservatism bar).
Source§impl FeatureSet
impl FeatureSet
Source§impl FeatureSet
impl FeatureSet
Source§impl FeatureSet
impl FeatureSet
Sourcepub const LENIENT: Self
Available on crate feature lenient only.
pub const LENIENT: Self
lenient only.The optional permissive tooling union — see the module-level docs for the full inclusion list and every conflict-resolution rule.
This is the “parse anything” mode behind the lenient cargo feature, and the
honest counterpart to the ban on a “generic” union: it is precise, not a
vibe. It is a const like every other preset, so the Lenient dialect’s
features() hands back a 'static borrow and the parser’s field reads
const-fold under Parser<Lenient> — zero per-parse cost, same code path as
ANSI.
Source§impl FeatureSet
impl FeatureSet
Source§impl FeatureSet
impl FeatureSet
Sourcepub const MYSQL: Self
Available on crate feature mysql only.
pub const MYSQL: Self
mysql only.MySQL as dialect data: every parser/tokenizer choice below is read through
FeatureSet fields, not a dialect-identity branch.
Source§impl FeatureSet
impl FeatureSet
Source§impl FeatureSet
impl FeatureSet
Source§impl FeatureSet
impl FeatureSet
Source§impl FeatureSet
impl FeatureSet
Source§impl FeatureSet
impl FeatureSet
Source§impl FeatureSet
impl FeatureSet
Sourcepub const fn with(&self, delta: FeatureDelta) -> Self
pub const fn with(&self, delta: FeatureDelta) -> Self
Return a custom dialect data value by applying delta to this base.
Source§impl FeatureSet
impl FeatureSet
Sourcepub const fn lexical_conflict(&self) -> Option<LexicalConflict>
pub const fn lexical_conflict(&self) -> Option<LexicalConflict>
The first lexical conflict in this feature set, or None when it is
self-consistent.
A dialect is modelled as independent feature data, but a few features
contend for the same tokenizer trigger, and the tokenizer is context-free:
each trigger resolves to exactly one token kind by a fixed precedence. Enabling
two claimants of one trigger is not an error today — the precedence silently
keeps one and shadows the other (e.g. double_quoted_strings on top of a "
identifier quote makes "x" a string, never the identifier). This predicate
turns that implicit precedence into an explicit, testable property: every
shipped preset — and any custom FeatureDelta — should return None.
The contested triggers form a MECE partition: each LexicalConflict variant
governs one distinct trigger — ", [, :+identifier (the a[x:y] slice
bound / {a: b} collection separator), $+digit, # (whose claimants — a line
comment, the XOR operator, a #-led identifier byte class, and DuckDB’s #n
positional reference — pair up as comment-vs-identifier, XOR-vs-comment,
positional-vs-XOR, and positional-vs-comment, none of which both fire in a shipped
preset), @name, <@, ? (the jsonb key-existence operator vs the anonymous
placeholder), and @@ (the jsonb/text-search match operator vs the MySQL
system-variable sigil) — with no overlap, plus the byte-class
hygiene variants that keep a feature-claimed sigil byte ($, @, :) out of a
custom table’s identifier-start class. The set is exhaustive over the tokenizer’s
shared-trigger hazards. The other either/or features are already single-valued
by type — PipeOperator for || and DoubleAmpersand for && are enums,
not overlapping booleans, so an invalid combination is unrepresentable and needs
no runtime check. The remaining multi-meaning sigils are disambiguated by
lookahead, not by enabling rival features, so they are MECE by context: ::
(typecast) and a lone : before a non-identifier byte stay disjoint from :name
by their follow byte — only a : before a bare identifier (the a[x:y] slice
bound / {a: b} collection separator) contends,
which is the tracked variant above; @@ is disjoint from @name by its second
@ (its only contention is the jsonb-vs-system-variable trigger above), and the
@? operator is disjoint from every @ claimant by its second byte; the non-digit
$ forms and the _charset'…' introducer split by their own
follow-sets; /*! (a versioned-comment region under
CommentSyntax::versioned_comments) is disjoint from a plain /* block
comment by its third byte, so the two never contend for the /* trigger; and the
two U&-prefixed StringLiteralSyntax::unicode_strings surfaces — the U&'…'
string constant and the U&"…" delimited identifier — are disjoint from each
other by their third byte (' vs ") and from a plain U-led identifier by the
three-byte U&'/U&" lead (U is an ordinary identifier-start letter, so a bare
U&1 stays a U word, a & operator, and 1), so neither steals the other nor a
plain identifier and no variant is minted for them.
Grammar-level gates (MutationSyntax, StatementDdlGates, SelectSyntax,
TableExpressionSyntax, …) never contend for a trigger — each is introduced by
a disjoint keyword (or occupies a distinct clause position) with no ordering
contention, so enabling any combination resolves to one production. They have their
own, MECE-disjoint hazard instead: a dependency, where a refinement flag rides a
base flag and is inert without it. That family is the sibling
feature_dependencies registry; contention here stays
a purely lexical property covering only shared tokenizer triggers.
Sourcepub const fn is_lexically_consistent(&self) -> bool
pub const fn is_lexically_consistent(&self) -> bool
Whether this feature set has no lexical_conflict —
every shared tokenizer trigger has exactly one claimant.
Sourcepub const fn feature_dependencies(&self) -> Option<FeatureDependencyViolation>
pub const fn feature_dependencies(&self) -> Option<FeatureDependencyViolation>
The first grammar-dependency violation in this feature set — a refinement flag set
without the base flag it rides on — or None when every dependent flag has its
prerequisite.
The grammar sibling of lexical_conflict. Several flags
only refine a production another flag opens: the extra slice bound needs the
bracket subscript, the MERGE extensions need MERGE dispatch, the [FORCE] CHECKPOINT <db> operands need the bare CHECKPOINT statement, and so on. Each
documents the relationship in its field doc (“rides on” / “only reachable where” /
“inert without”); this predicate turns that prose into an explicit, testable
property.
The severity is inertness, not unsoundness: a dependent flag whose base is off is
simply unreachable — the parser never reaches the grammar position, so the flag has
no effect and no wrong parse results. That is why this is a debug/test-time property
(every shipped preset and any custom FeatureDelta should return None) rather
than a runtime reject, and why try_with — whose contract is the
lexical-soundness gate — deliberately does not fold it in.
MECE with lexical_conflict: every variant here is a pure
grammar dependency with no tokenizer trigger of its own, and no shared-trigger
hazard appears here. A flag that both rides a base grammar flag and claims a
tokenizer trigger belongs in each registry for its respective axis.
The predicate reads the whole FeatureSet, so a dependent flag may name a base on
a different syntax axis (a cross-axis dependency) as freely as a same-axis one; the
machinery does not restrict a dependency to one sub-struct. What it does require is
the inertness contract above — a registrable dependent must be fully inert when its
base is off. That requirement, not the axis, is what excludes the one measured
near-miss:
SessionVariableSyntax::variable_assignment— a two-facet flag. Its parser facet (the MySQLSETvariable-assignment grammar) is unreachable withoutShowSyntax::session_statements, which gates allSET/RESET/SHOWdispatch — a genuine cross-axis grammar dependency. But its lexer facet (:=munching to oneColonEqualsoperator token) fires independently of that gate, so the flag is not inert whensession_statementsis off: it still changes tokenization (measured —:=lexes to one token with the flag on vs two,:then=, with it off). A dependent that observably changes tokenization while its base is off violates the inertness contract and the “no tokenizer trigger of its own” MECE line, so registering it as a variant would falsely certify it safe-to-dangle.variable_assignmentis therefore a documented exemption, not a variant: its field doc names the independent lexer facet as the reason the flag is not fully inert, and its cross-axis parser dependency is recorded there rather than here.
Sourcepub const fn has_satisfied_feature_dependencies(&self) -> bool
pub const fn has_satisfied_feature_dependencies(&self) -> bool
Whether this feature set has no
feature_dependencies violation — every dependent
grammar flag has the base flag it rides on.
Sourcepub fn without_dangling_dependents(&self) -> FeatureSet
pub fn without_dangling_dependents(&self) -> FeatureSet
This feature set with every inert refinement flag cleared — the dependency
registry’s normal form, in which
has_satisfied_feature_dependencies
holds.
Each feature_dependencies violation is a refinement
flag enabled without the base it rides on; the registry’s own contract is that such
a flag is inert (the parser never reaches its grammar position), so turning it off
cannot change any parse. This walks the registry, clearing one dangling dependent
per step until none remain, and is therefore an outcome-preserving projection onto
the parser’s self-consistency precondition (the parse-entry debug_assert!) — the
tool a caller that assembles a FeatureDelta by toggling individual flags uses to
drop the inert leftovers before handing the set to the parser, rather than reasoning
out the dependency closure by hand.
This is the dependency sibling of the lexical try_with: where
try_with reports the lexical verdict as a value, this repairs the (benign)
dependency one. It deliberately does not touch a
lexical_conflict or a
grammar_conflict — those are soundness hazards with no
inert-and-safe reading to normalize away, so a set carrying one has no defined parse
and this returns it unchanged.
Sourcepub const fn grammar_conflict(&self) -> Option<GrammarConflict>
pub const fn grammar_conflict(&self) -> Option<GrammarConflict>
The first grammar-position mutual exclusion in this feature set — two features whose
grammars read the same token sequence at the same parser-position head with no
lookahead to tell them apart — or None when no such pair is enabled together.
The third self-consistency sibling, after
lexical_conflict (shared tokenizer triggers) and
feature_dependencies (a refinement flag without its
base). This one covers the class the other two cannot: two features whose grammars
claim the same head, where the tokenizer is innocent (each byte lexes to one fixed
token) and neither flag rides the other. The parser resolves the head by a fixed
branch order, so enabling both silently shadows one reading — a soundness hazard
like a lexical conflict but at the grammar layer, which is exactly why neither sibling
registry can catch it (the prefix_colon_alias
field doc first named this gap).
A collision is registrable here only when the contention has no defined resolution
and no shipped preset enables both. A preset that pairs two head-claimants with a
documented, deterministic resolution — DuckDB’s SUMMARIZE-vs-MySQL-DESCRIBE
dispatch order under Lenient, or the GROUP BY ALL lookahead split — is a
conflict-free permissive union, not a mutual exclusion, and gets no variant. Like
the siblings this is a debug/test-time property — every shipped preset and any custom
FeatureDelta should return None.
MECE with both siblings: every variant here is a pure parser-position contention —
no shared tokenizer trigger (that is a LexicalConflict) and no base-flag
dependency (that is a FeatureDependencyViolation).
Sourcepub const fn has_no_grammar_conflict(&self) -> bool
pub const fn has_no_grammar_conflict(&self) -> bool
Whether this feature set has no grammar_conflict — no two
features contend for the same parser-position head.
Sourcepub const fn try_with(
&self,
delta: FeatureDelta,
) -> Result<Self, LexicalConflict>
pub const fn try_with( &self, delta: FeatureDelta, ) -> Result<Self, LexicalConflict>
Apply delta to this base, returning the customized set only when it is
lexically consistent, or the first LexicalConflict it would introduce.
The checked counterpart to with: a builder that wants the
conflict verdict as a value uses try_with, while with stays
the documented-unchecked fast path the presets build on (its result feeds the
construction-time debug_assert! at the parse/tokenize entry seam). See
lexical_conflict for what the shared triggers are.
This is a lexical gate only — its contract is the tokenizer-soundness check, and
it does not verify the sibling feature_dependencies
property (a dependent grammar flag without its base is inert, not unsound, so it
need not block a try_with). A builder wanting both verdicts checks
feature_dependencies on the returned set.
Source§impl FeatureSet
impl FeatureSet
Sourcepub const fn as_of(version: StandardVersion) -> Self
pub const fn as_of(version: StandardVersion) -> Self
The ANSI/standard config baseline as of SQL edition version.
The M1 dialect-data surface (identifier quoting, casing, concatenation, set
operations, …) is invariant across feature-ID-era editions — every standard
feature we implement is SQL:1999 Core — so this returns FeatureSet::ANSI
for every edition today. It is the stable anchor consumers pin against; the
exhaustive match forces a decision here once edition-varying dialect data
is added. For the set of standard features available as of an edition
(which does vary), query standard_features_as_of.
Per-dialect release pinning (e.g. PostgreSQL 14 vs 16) is a distinct axis that needs multi-version dialect data; it arrives with the later milestones.
Sourcepub const fn byte_class(&self, byte: u8) -> u8
pub const fn byte_class(&self, byte: u8) -> u8
Return all lexical classes for byte under this dialect.
Sourcepub const fn has_byte_class(&self, byte: u8, mask: u8) -> bool
pub const fn has_byte_class(&self, byte: u8, mask: u8) -> bool
Return true if byte has any lexical class in mask under this dialect.
Sourcepub const fn binding_power(&self, op: &BinaryOperator) -> BindingPower
pub const fn binding_power(&self, op: &BinaryOperator) -> BindingPower
Return the binary binding power for op under this dialect.
Sourcepub const fn prefix_binding_power(&self, op: &UnaryOperator) -> u8
pub const fn prefix_binding_power(&self, op: &UnaryOperator) -> u8
Return the prefix binding power for op under this dialect.
Sourcepub const fn set_operation_binding_power(
&self,
op: &SetOperator,
) -> BindingPower
pub const fn set_operation_binding_power( &self, op: &SetOperator, ) -> BindingPower
Return the set-operation binding power for op under this dialect.
Sourcepub fn fold_unquoted_identifier<'a>(&self, identifier: &'a str) -> Cow<'a, str>
pub fn fold_unquoted_identifier<'a>(&self, identifier: &'a str) -> Cow<'a, str>
Fold an unquoted identifier according to this dialect’s identity rules.
Sourcepub const fn default_nulls_first(&self) -> bool
pub const fn default_nulls_first(&self) -> bool
Whether omitted NULLS FIRST/NULLS LAST sorts nulls first.
Trait Implementations§
Source§impl Clone for FeatureSet
impl Clone for FeatureSet
Source§fn clone(&self) -> FeatureSet
fn clone(&self) -> FeatureSet
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more