#[non_exhaustive]pub enum FeatureDependencyViolation {
Show 24 variants
KeyLockStrengthsWithoutLockingClauses,
StackedLockingClausesWithoutLockingClauses,
UnnestWithOffsetWithoutUnnest,
SliceStepWithoutSubscript,
MultidimArrayLiteralsWithoutArrayConstructor,
QuantifiedComparisonListsWithoutQuantifiedComparisons,
QuantifiedArbitraryOperatorWithoutQuantifiedComparisons,
LambdaExpressionsWithoutJsonArrowOperators,
CteBeforeMergeWithoutMerge,
MergeWhenNotMatchedByWithoutMerge,
MergeInsertDefaultValuesWithoutMerge,
MergeInsertOverridingWithoutMerge,
AlterExistenceGuardsWithoutAlterTableExtended,
AlterColumnSetDataTypeWithoutAlterTableExtended,
CheckpointDatabaseWithoutCheckpoint,
AnalyzeColumnsWithoutAnalyze,
LoadBareNameWithoutLoadExtension,
CallBareNameWithoutCall,
DetachIfExistsWithoutAttach,
UseQualifiedNameWithoutUseStatement,
UseStringLiteralNameWithoutUseStatement,
AccessControlExtendedObjectsWithoutAccessControl,
AccountGrantsWithoutAccessControl,
PrepareTypedParametersWithoutPreparedStatements,
}Expand description
A grammar-flag dependency left unsatisfied — a refinement feature enabled without the
base feature it rides on — surfaced by FeatureSet::feature_dependencies.
The grammar sibling of LexicalConflict, and MECE-disjoint from it: every variant
here is a pure grammar dependency (a flag inert without its base), never a shared
tokenizer trigger. Unlike a lexical conflict, an unsatisfied dependency is not a
soundness bug — the dependent flag is simply unreachable — so the registry is a
test/debug-time property, not a runtime reject.
Each variant is named <Dependent>Without<Base> and its doc names both the dependent
flag and the base flag it requires.
§Adding a dependent flag?
A flag that only refines a production another flag opens (a further clause, operand, guard, or bound reachable only once the base grammar is admitted) must be registered here before it lands — the “every preset is clean” claim is hand-maintained:
- Identify the base flag whose grammar position the new flag extends (the field doc’s “rides on” / “only reachable where” / “inert without” sentence names it).
- Add a
<Dependent>Without<Base>variant, a guard infeature_dependencies, and a per-variant detection test. - Point the field’s prose sentence at the new variant so the doc and the registry stay in lock-step.
If the flag instead claims its own tokenizer trigger, that hazard is a
LexicalConflict, not a dependency — keep the two registries MECE.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
KeyLockStrengthsWithoutLockingClauses
QueryTailSyntax::key_lock_strengths (the FOR NO KEY UPDATE / FOR KEY SHARE
strengths) refines the strength keyword after FOR, so it requires
QueryTailSyntax::locking_clauses. Without the base gate the FOR clause is never
read, so the strength refinement is unreachable.
StackedLockingClausesWithoutLockingClauses
QueryTailSyntax::stacked_locking_clauses (multiple FOR UPDATE/FOR SHARE clauses
on one query) repeats the shared locking clause, so it requires
QueryTailSyntax::locking_clauses. Without the base gate no locking clause is read,
so there is nothing to stack.
UnnestWithOffsetWithoutUnnest
TableFactorSyntax::unnest_with_offset (the BigQuery WITH OFFSET tail) sits
on an UNNEST table factor, so it requires TableFactorSyntax::unnest.
Without the base gate UNNEST( is left to the named-table path and the tail is
never reached.
SliceStepWithoutSubscript
ExpressionSyntax::slice_step (the third base[lower:upper:step] bound) is
reachable only once the bracket subscript has opened, so it requires
ExpressionSyntax::subscript. Without the base gate [ is never read as a
subscript and the extra bound is unreachable.
MultidimArrayLiteralsWithoutArrayConstructor
ExpressionSyntax::multidim_array_literals (the bare-bracket sub-row) is only a
value inside an ARRAY[…] constructor, so it requires
ExpressionSyntax::array_constructor. Without the base gate there is no
array-constructor element position for the sub-row to occupy.
QuantifiedComparisonListsWithoutQuantifiedComparisons
OperatorSyntax::quantified_comparison_lists (the scalar list/array operand of a
quantified comparison) rides the base quantifier reading, so it requires
OperatorSyntax::quantified_comparisons. Without the base gate ANY/ALL/SOME
is not read as a quantifier and the list operand is unreachable.
QuantifiedArbitraryOperatorWithoutQuantifiedComparisons
OperatorSyntax::quantified_arbitrary_operator (extending the quantifier past the
comparison operators) rides the base quantifier reading, so it requires
OperatorSyntax::quantified_comparisons. Without the base gate the quantifier is
unread and the arbitrary-operator extension is unreachable.
LambdaExpressionsWithoutJsonArrowOperators
OperatorSyntax::lambda_expressions (the DuckDB x -> body lambda) is a
grammar-position reading of the -> lexeme, which is munched only under
OperatorSyntax::json_arrow_operators, so it is inert without it. Without the base
gate no -> token is produced and the lambda reading never fires.
CteBeforeMergeWithoutMerge
MutationSyntax::cte_before_merge (a leading WITH before MERGE) is only
reachable where MutationSyntax::merge dispatches MERGE. Without the base gate
the MERGE after the CTE list is never dispatched.
MergeWhenNotMatchedByWithoutMerge
MutationSyntax::merge_when_not_matched_by (the WHEN NOT MATCHED BY SOURCE | TARGET arms) is only reachable where MutationSyntax::merge dispatches
MERGE. Without the base gate the MERGE statement is never parsed.
MergeInsertDefaultValuesWithoutMerge
MutationSyntax::merge_insert_default_values (the INSERT DEFAULT VALUES merge
action) is only reachable where MutationSyntax::merge dispatches MERGE. Without
the base gate the MERGE statement is never parsed.
MergeInsertOverridingWithoutMerge
MutationSyntax::merge_insert_overriding (the OVERRIDING {SYSTEM | USER} VALUE
merge-insert override) is only reachable where MutationSyntax::merge dispatches
MERGE. Without the base gate the MERGE statement is never parsed.
AlterExistenceGuardsWithoutAlterTableExtended
IndexAlterSyntax::alter_existence_guards (the IF [NOT] EXISTS guards inside
ALTER TABLE) is parsed only on the extended ALTER TABLE path, so it requires
IndexAlterSyntax::alter_table_extended. Without the base gate the non-extended
path parses no guard.
AlterColumnSetDataTypeWithoutAlterTableExtended
IndexAlterSyntax::alter_column_set_data_type (the ALTER COLUMN SET DATA TYPE
/ SET/DROP NOT NULL actions) is reached only on the extended ALTER TABLE path,
so it requires IndexAlterSyntax::alter_table_extended. Without the base gate the
ALTER COLUMN action is never reached.
CheckpointDatabaseWithoutCheckpoint
MaintenanceSyntax::checkpoint_database (the DuckDB [FORCE] CHECKPOINT <database>
operands) rides the base CHECKPOINT statement, so it requires
MaintenanceSyntax::checkpoint. Without the base gate CHECKPOINT is not dispatched
and the operands are unreachable.
AnalyzeColumnsWithoutAnalyze
MaintenanceSyntax::analyze_columns (the DuckDB ANALYZE <table> (<cols>) column
list) rides the base ANALYZE statement, so it requires
MaintenanceSyntax::analyze. Without the base gate ANALYZE is not dispatched and
the column list is unreachable.
LoadBareNameWithoutLoadExtension
UtilitySyntax::load_bare_name (the DuckDB bare-identifier LOAD <name> argument)
rides the base LOAD statement, so it requires UtilitySyntax::load_extension.
Without the base gate LOAD is not dispatched and the bare-name argument is
unreachable.
CallBareNameWithoutCall
UtilitySyntax::call_bare_name (MySQL’s bare CALL <name> form, no parenthesized
argument list) rides the base CALL statement, so it requires
UtilitySyntax::call. Without the base gate CALL is not dispatched and the
bare-name form is unreachable.
DetachIfExistsWithoutAttach
UtilitySyntax::detach_if_exists (the DETACH DATABASE IF EXISTS guard) rides the
base ATTACH/DETACH statement, so it requires UtilitySyntax::attach. Without
the base gate DETACH is not dispatched and the guard is unreachable.
UseQualifiedNameWithoutUseStatement
UtilitySyntax::use_qualified_name (DuckDB’s dotted USE <catalog> . <schema>
name, widening the accepted USE name arity from one to two parts) refines the name
grammar of the base USE statement, so it requires UtilitySyntax::use_statement.
Without the base gate the leading USE is not dispatched, so the parser never reaches
the arity check the flag widens and the flag is inert.
UseStringLiteralNameWithoutUseStatement
UtilitySyntax::use_string_literal_name (DuckDB’s USE 'n' / E'n' / $$n$$
single-part string-literal target) refines the name grammar of the base USE
statement, so it requires UtilitySyntax::use_statement. Without the base gate the
leading USE is not dispatched and the flag is inert.
AccessControlExtendedObjectsWithoutAccessControl
AccessControlSyntax::access_control_extended_objects (the extended GRANT/REVOKE
object and prefix grammar) builds on the base GRANT/REVOKE statements, so it
requires AccessControlSyntax::access_control. Without the base gate the access-control
statements are not dispatched and the extended forms are unreachable.
AccountGrantsWithoutAccessControl
AccessControlSyntax::access_control_account_grants (the MySQL account-based
GRANT/REVOKE grammar) is a route of the base GRANT/REVOKE statements, so it
requires AccessControlSyntax::access_control. Without the base gate the access-control
statements are not dispatched and the account-based grammar is unreachable.
PrepareTypedParametersWithoutPreparedStatements
UtilitySyntax::prepare_typed_parameters (the PostgreSQL PREPARE name(<type>, …) parenthesized parameter-type list) widens the name position of the
base PREPARE grammar, so it requires UtilitySyntax::prepared_statements.
Without the base gate PREPARE is not dispatched and the type list is unreachable.
Trait Implementations§
Source§impl Clone for FeatureDependencyViolation
impl Clone for FeatureDependencyViolation
Source§fn clone(&self) -> FeatureDependencyViolation
fn clone(&self) -> FeatureDependencyViolation
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more