Skip to main content

FeatureSet

Struct FeatureSet 

Source
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, with ANSI, 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 the lenient feature).
  • The conservative, no-oracle presets — BIGQUERY, HIVE, CLICKHOUSE, DATABRICKS, MSSQL, SNOWFLAKE, REDSHIFT (each behind its cargo feature) — derive from ANSI and enable only the surface that already has a modelled, tested parser gate and documentary evidence (their ONs 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 over ANSI.

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:

  1. # line comment (CommentSyntax::line_comment_hash, MySQL) — consumed as trivia before tokenizing, so when on it shadows every reading below.
  2. #+identifier-start word (a byte_classes table marking # CLASS_IDENTIFIER_START, T-SQL #temp) — the identifier scan precedes the operator/positional arms, so it wins on an identifier follow byte.
  3. #+digit positional column (ExpressionSyntax::positional_column, DuckDB #1).
  4. #+>/- 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.
  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: Casing

Identity 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: NullOrdering

Dialect default when NULLS FIRST/NULLS LAST is omitted.

§reserved_column_name: KeywordSet

Keywords 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: KeywordSet

Keywords rejected as a function name (PostgreSQL reserved).

§reserved_type_name: KeywordSet

Keywords rejected as a (user-defined) type name (PostgreSQL col_name ∪ reserved).

§reserved_bare_alias: KeywordSet

Keywords 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: KeywordSet

Keywords 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: bool

Whether 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: ByteClasses

Byte classes used by tokenizer dispatch.

§binding_powers: BindingPowerTable

Binary and prefix operator binding powers used by parser and renderer.

§set_operation_powers: SetOperationBindingPowerTable

Set-operation binding powers used by parser and renderer.

§string_literals: StringLiteralSyntax

String literal syntax extensions accepted by the tokenizer/parser.

§numeric_literals: NumericLiteralSyntax

Numeric literal syntax extensions accepted by the tokenizer.

§parameters: ParameterSyntax

Prepared-statement parameter placeholder forms accepted by the tokenizer.

§session_variables: SessionVariableSyntax

MySQL session-variable forms (@name user variables, @@[scope.]name system variables) accepted by the tokenizer.

§identifier_syntax: IdentifierSyntax

Unquoted-identifier character policy (the dialect-variable $) accepted by the tokenizer.

§table_expressions: TableExpressionSyntax

Table-expression syntax forms accepted by the parser.

§join_syntax: JoinSyntax

Join-operator and recursive-query relation-composition syntax, gathered from table_expressions.

§table_factor_syntax: TableFactorSyntax

Table-factor FROM-item forms beyond a plain named table, gathered from table_expressions.

§expression_syntax: ExpressionSyntax

Expression 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: OperatorSyntax

Infix/prefix operator forms (OPERATOR(…), @>/<@, ->/->>, ==, general IS, <=>, the DuckDB lambda, the bitwise family, quantified comparisons) accepted by the parser.

§call_syntax: CallSyntax

Function-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: StringFuncForms

Keyword string/scalar special-form syntax — the flags whose sole AST product is a StringFunc.

§aggregate_call_syntax: AggregateCallSyntax

Aggregate/window function-call syntax — the in-parenthesis and post-) tails, the argument-shape/arity restrictions, and the OVER-eligibility gate.

§predicate_syntax: PredicateSyntax

Pattern-match predicate forms (LIKE/ILIKE/SIMILAR TO) accepted by the parser. LIKE is SQL core (on everywhere); ILIKE/SIMILAR TO are gated.

§pipe_operator: PipeOperator

What the || operator token means: string concatenation or logical OR.

§double_ampersand: DoubleAmpersand

What the && operator token means: logical AND, or not an operator.

§keyword_operators: KeywordOperators

Which 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: CaretOperator

What 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: bool

Whether 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: CommentSyntax

Dialect comment syntax extensions accepted by the tokenizer.

§mutation_syntax: MutationSyntax

Mutation-statement (INSERT/UPDATE/DELETE) syntax forms accepted by the parser (RETURNING, ON CONFLICT).

§statement_ddl_gates: StatementDdlGates

Whole-statement DDL dispatch gates (non-TABLE CREATE/DROP object dispatch), split from the retired SchemaChangeSyntax.

§view_sequence_clause_syntax: ViewSequenceClauseSyntax

View/sequence clause syntax after a DDL statement head has been chosen — temporary/recursive views, view options, matview targets, sequence CACHE.

§create_table_clause_syntax: CreateTableClauseSyntax

CREATE TABLE table-level clause syntax (storage/CTAS/partitioning/inheritance/ persistence clauses), split from the retired SchemaChangeSyntax.

§column_definition_syntax: ColumnDefinitionSyntax

CREATE TABLE column-definition syntax (generated/identity columns, SQLite column attributes, DEFAULT/COLLATE/STORAGE clauses), split from SchemaChangeSyntax.

§constraint_syntax: ConstraintSyntax

Table/column-constraint syntax (deferrable/named/bare constraints, EXCLUDE, the NO INHERIT/NOT VALID markers, index parameters), split from SchemaChangeSyntax.

§index_alter_syntax: IndexAlterSyntax

CREATE INDEX/ALTER TABLE/DROP syntax (index clauses, the extended ALTER surface, drop behaviour, routine arg types), split from SchemaChangeSyntax.

§existence_guards: ExistenceGuards

IF [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: SelectSyntax

SELECT-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: QueryTailSyntax

Query-tail syntax — the row-limiting/locking family and the trailing ClickHouse/pipe clauses parsed after the SELECT body.

§grouping_syntax: GroupingSyntax

GROUP BY/ORDER BY grouping-and-ordering syntax (grouping sets, clause modes, and quantifiers).

§utility_syntax: UtilitySyntax

Utility-statement syntax forms the parser dispatches: the PostgreSQL COPY/COMMENT ON and SQLite PRAGMA/ATTACH/DETACH statement gates.

§transaction_syntax: TransactionSyntax

Transaction-control (TCL) syntax — openers, completers, savepoints, mode lists, and XA forms — split from utility_syntax.

§show_syntax: ShowSyntax

SHOW/DESCRIBE introspection-statement syntax (the session SHOW reader, the typed SHOW <object> listings, and DESCRIBE/SUMMARIZE), gathered from utility_syntax.

§maintenance_syntax: MaintenanceSyntax

Physical-maintenance-statement syntax (VACUUM/REINDEX/ANALYZE/CHECKPOINT), gathered from utility_syntax.

§access_control_syntax: AccessControlSyntax

Access-control-statement syntax (GRANT/REVOKE and the extended object grammar), gathered from utility_syntax.

§type_name_syntax: TypeNameSyntax

Type-name vocabulary the parser recognizes beyond the shared standard set (the MySQL TINYINT/ENUM/UNSIGNED/… surface).

§target_spelling: TargetSpelling

Which 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

Source

pub const ANSI: Self

The generic/standard dialect data.

Source§

impl FeatureSet

Source

pub const BIGQUERY: Self

Available on crate feature bigquery only.

BigQuery / ZetaSQL as ANSI-derived dialect data (see the module docs for the full derivation rationale and the conservatism bar).

Source§

impl FeatureSet

Source

pub const CLICKHOUSE: Self

Available on crate feature clickhouse only.

ClickHouse as ANSI-derived dialect data (see the module docs for the full derivation rationale and the conservatism bar).

Source§

impl FeatureSet

Source

pub const DATABRICKS: Self

Available on crate feature databricks only.

Databricks as ANSI-derived dialect data (see the module docs for the full derivation rationale and the conservatism bar).

Source§

impl FeatureSet

Source

pub const DUCKDB: Self

Available on crate feature duckdb only.

DuckDB as PostgreSQL-derived dialect data.

Source§

impl FeatureSet

Source

pub const HIVE: Self

Available on crate feature hive only.

Hive / HiveQL as ANSI-derived dialect data (see the module docs for the full derivation rationale and the conservatism bar).

Source§

impl FeatureSet

Source

pub const LENIENT: Self

Available on crate feature 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

Source

pub const MSSQL: Self

Available on crate feature mssql only.

MSSQL / T-SQL as ANSI-derived dialect data (see the module docs for the full derivation rationale and the conservatism bar).

Source§

impl FeatureSet

Source

pub const MYSQL: Self

Available on crate feature mysql only.

MySQL as dialect data: every parser/tokenizer choice below is read through FeatureSet fields, not a dialect-identity branch.

Source§

impl FeatureSet

Source

pub const POSTGRES: Self

Available on crate feature postgres only.

PostgreSQL as dialect data.

Source§

impl FeatureSet

Source

pub const QUILTDB: Self

Available on crate feature quiltdb only.

The complete QuiltDB feature set.

Source§

impl FeatureSet

Source

pub const REDSHIFT: Self

Available on crate feature redshift only.

Amazon Redshift as ANSI-derived dialect data (see the module docs for the full derivation rationale — including why a PostgreSQL-8 fork still derives from ANSI, not POSTGRES — and the conservatism bar).

Source§

impl FeatureSet

Source

pub const SNOWFLAKE: Self

Available on crate feature snowflake only.

Snowflake as ANSI-derived dialect data (see the module docs for the full derivation rationale and the conservatism bar).

Source§

impl FeatureSet

Source

pub const SQLITE: Self

Available on crate feature sqlite only.

SQLite as dialect data, including the position-aware reserved sets that its %fallback keyword model requires.

Source§

impl FeatureSet

Source

pub const fn with(&self, delta: FeatureDelta) -> Self

Return a custom dialect data value by applying delta to this base.

Source§

impl FeatureSet

Source

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 typePipeOperator 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.

Source

pub const fn is_lexically_consistent(&self) -> bool

Whether this feature set has no lexical_conflict — every shared tokenizer trigger has exactly one claimant.

Source

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 MySQL SET variable-assignment grammar) is unreachable without ShowSyntax::session_statements, which gates all SET/RESET/SHOW dispatch — a genuine cross-axis grammar dependency. But its lexer facet (:= munching to one ColonEquals operator token) fires independently of that gate, so the flag is not inert when session_statements is 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_assignment is 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.
Source

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.

Source

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.

Source

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).

Source

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.

Source

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

Source

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.

Source

pub const fn byte_class(&self, byte: u8) -> u8

Return all lexical classes for byte under this dialect.

Source

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.

Source

pub const fn binding_power(&self, op: &BinaryOperator) -> BindingPower

Return the binary binding power for op under this dialect.

Source

pub const fn prefix_binding_power(&self, op: &UnaryOperator) -> u8

Return the prefix binding power for op under this dialect.

Source

pub const fn set_operation_binding_power( &self, op: &SetOperator, ) -> BindingPower

Return the set-operation binding power for op under this dialect.

Source

pub fn fold_unquoted_identifier<'a>(&self, identifier: &'a str) -> Cow<'a, str>

Fold an unquoted identifier according to this dialect’s identity rules.

Source

pub const fn default_nulls_first(&self) -> bool

Whether omitted NULLS FIRST/NULLS LAST sorts nulls first.

Trait Implementations§

Source§

impl Clone for FeatureSet

Source§

fn clone(&self) -> FeatureSet

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for FeatureSet

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for FeatureSet

Source§

impl PartialEq for FeatureSet

Source§

fn eq(&self, other: &FeatureSet) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for FeatureSet

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.