use super::{
AccessControlSyntax, AggregateCallSyntax, CallSyntax, CaretOperator, Casing,
ColumnDefinitionSyntax, CommentSyntax, ConstraintSyntax, CreateTableClauseSyntax,
DoubleAmpersand, ExistenceGuards, ExpressionSyntax, FeatureSet, GroupingSyntax,
IdentifierQuote, IdentifierSyntax, IndexAlterSyntax, JoinSyntax, KeywordOperators, KeywordSet,
MaintenanceSyntax, MutationSyntax, NullOrdering, NumericLiteralSyntax, OperatorSyntax,
ParameterSyntax, PipeOperator, PredicateSyntax, QueryTailSyntax, RESERVED_BARE_ALIAS,
RESERVED_COLUMN_NAME, RESERVED_FUNCTION_NAME, RESERVED_TYPE_NAME, STANDARD_BYTE_CLASSES,
SelectSyntax, SessionVariableSyntax, ShowSyntax, StatementDdlGates, StringFuncForms,
StringLiteralSyntax, TableExpressionSyntax, TableFactorSyntax, TargetSpelling,
TransactionSyntax, TypeNameSyntax, UtilitySyntax, ViewSequenceClauseSyntax,
};
use crate::precedence::{
Assoc, BindingPower, BindingPowerTable, IS_PREDICATE_BELOW_COMPARISON,
RANGE_PREDICATE_ABOVE_COMPARISON, STANDARD_SET_OPERATION_BINDING_POWERS,
};
pub const LENIENT_IDENTIFIER_QUOTES: &[IdentifierQuote] = &[
IdentifierQuote::Symmetric('"'),
IdentifierQuote::Symmetric('`'),
IdentifierQuote::Asymmetric {
open: '[',
close: ']',
},
];
impl CommentSyntax {
pub const LENIENT: Self = Self {
line_comment_hash: true,
line_comment_ends_at_carriage_return: false,
nested_block_comments: true,
versioned_comments: Some(u32::MAX),
unterminated_block_comment_at_eof: true,
};
}
impl StringLiteralSyntax {
pub const LENIENT: Self = Self {
escape_strings: true,
dollar_quoted_strings: true,
national_strings: true,
double_quoted_strings: false,
backslash_escapes: true,
unicode_strings: true,
bit_string_literals: true,
blob_literals: false,
charset_introducers: true,
same_line_adjacent_concat: true,
};
}
impl NumericLiteralSyntax {
pub const LENIENT: Self = Self {
hex_integers: true,
octal_integers: true,
binary_integers: true,
underscore_separators: true,
radix_leading_underscore: true,
money_literals: false,
reject_trailing_junk: false,
};
}
impl ParameterSyntax {
pub const LENIENT: Self = Self {
positional_dollar: true,
positional_dollar_large: true,
anonymous_question: true,
named_colon: true,
named_at: true,
named_dollar: false,
numbered_question: true,
};
}
impl SessionVariableSyntax {
pub const LENIENT: Self = Self {
user_variables: false,
system_variables: true,
variable_assignment: false,
};
}
impl IdentifierSyntax {
pub const LENIENT: Self = Self {
non_ascii: super::NonAsciiIdentifierSyntax::Any,
dollar_in_identifiers: true,
string_literal_identifiers: true,
string_literal_table_names: true,
empty_quoted_identifiers: true,
};
}
impl TableExpressionSyntax {
pub const LENIENT: Self = Self {
only: true,
table_sample: true,
parenthesized_joins: true,
table_alias_column_lists: true,
join_using_alias: true,
index_hints: true,
table_hints: true,
partition_selection: true,
base_table_alias_column_lists: true,
string_literal_aliases: true,
aliased_parenthesized_join: true,
bare_table_alias_is_bare_label: false,
table_version: true,
table_json_path: false,
indexed_by: false,
prefix_colon_alias: true,
};
}
impl JoinSyntax {
pub const LENIENT: Self = Self {
stacked_join_qualifiers: true,
full_outer_join: true,
natural_cross_join: true,
straight_join: true,
asof_join: true,
positional_join: true,
semi_anti_join: true,
sided_semi_anti_join: true,
apply_join: true,
recursive_search_cycle: true,
recursive_union_rejects_order_limit: false,
recursive_using_key: true,
};
}
impl TableFactorSyntax {
pub const LENIENT: Self = Self {
lateral: true,
table_functions: true,
rows_from: true,
unnest: true,
unnest_with_offset: false,
table_function_ordinality: true,
special_function_table_source: true,
pivot: true,
unpivot: true,
show_ref: true,
from_values: true,
json_table: true,
xml_table: true,
table_expr_factor: true,
pivot_value_sources: true,
match_recognize: true,
open_json: true,
};
}
impl ExpressionSyntax {
pub const LENIENT: Self = Self {
typecast_operator: true,
subscript: false,
slice_step: false,
collate: true,
at_time_zone: true,
semi_structured_access: false,
array_constructor: false,
multidim_array_literals: false,
collection_literals: false,
row_constructor: true,
struct_constructor: true,
field_selection: true,
field_wildcard: true,
typed_string_literals: true,
typed_interval_literal: true,
relaxed_interval_syntax: true,
mysql_interval_operator: true,
positional_column: false,
lambda_keyword: true,
};
}
impl OperatorSyntax {
pub const LENIENT: Self = Self {
operator_construct: true,
containment_operators: false,
json_arrow_operators: false,
jsonb_operators: false,
double_equals: true,
integer_divide_slash: true,
starts_with_operator: false,
is_general_equality: true,
truth_value_tests: true,
null_safe_equals: true,
lambda_expressions: false,
bitwise_operators: true,
quantified_comparisons: true,
quantified_comparison_lists: true,
quantified_arbitrary_operator: true,
custom_operators: false,
null_test_postfix: true,
postfix_operators: true,
};
}
impl CallSyntax {
pub const LENIENT: Self = Self {
named_argument: true,
utc_special_functions: true,
columns_expression: true,
extract_from_syntax: true,
try_cast: true,
restricted_cast_targets: false,
extract_string_field: true,
method_chaining: true,
sqljson_constructors_require_argument: false,
sqljson_expression_functions: true,
xml_expression_functions: true,
variadic_argument: true,
merge_action_function: true,
convert_function: true,
};
}
impl StringFuncForms {
pub const LENIENT: Self = Self {
substring_from_for: true,
substring_leading_for: true,
substring_similar: true,
substring_plain_call_requires_2_or_3_args: false,
substr_from_for: true,
position_in: true,
position_asymmetric_operands: false,
overlay_placing: true,
overlay_requires_placing: false,
trim_from: true,
trim_list_syntax: true,
collation_for_expression: true,
ceil_to_field: true,
floor_to_field: true,
match_against: true,
};
}
impl AggregateCallSyntax {
pub const LENIENT: Self = Self {
group_concat_separator: true,
within_group: true,
aggregate_filter: true,
filter_optional_where: true,
aggregate_args_require_adjacent_paren: false,
null_treatment: true,
aggregate_calls_reject_empty_arguments: false,
over_requires_windowable_function: false,
window_function_tail: false,
standalone_argument_order_by: true,
};
}
impl PredicateSyntax {
pub const LENIENT: Self = Self {
is_distinct_from: true,
like: true,
ilike: true,
similar_to: true,
overlaps_period_predicate: true,
unparenthesized_in_list: true,
pattern_match_quantifier: true,
between_symmetric: true,
is_normalized: true,
empty_in_list: true,
null_test_two_word_postfix: true,
};
}
impl MutationSyntax {
pub const LENIENT: Self = Self {
insert_ignore: true,
insert_overwrite: true,
returning: true,
on_conflict: true,
on_duplicate_key_update: true,
multi_column_assignment: true,
update_tuple_value_row_arity: false,
where_current_of: true,
merge: true,
replace_into: true,
insert_set: true,
update_delete_tails: true,
joined_update_delete: true,
or_conflict_action: true,
insert_column_matching: true,
delete_using: true,
update_from: true,
delete_using_target_alias: true,
cte_before_insert: true,
cte_before_merge: true,
data_modifying_ctes: true,
merge_when_not_matched_by: true,
merge_insert_default_values: true,
merge_insert_overriding: true,
merge_insert_multirow: true,
merge_update_set_star: true,
merge_insert_star_by_name: true,
merge_error_action: true,
update_set_qualified_column: true,
};
}
impl StatementDdlGates {
pub const LENIENT: Self = Self {
colocation_groups: true,
create_trigger: true,
create_macro: true,
create_secret: true,
create_type: true,
create_virtual_table: true,
create_sequence: true,
extension_ddl: true,
transform_ddl: true,
alter_system: true,
tablespace_ddl: true,
logfile_group_ddl: true,
schemas: true,
schema_elements: true,
databases: true,
drop_database: false,
materialized_views: true,
routines: true,
or_replace: true,
create_or_replace_table: true,
compound_statements: true,
alter_database: true,
alter_database_options: true,
server_definition: true,
alter_instance: true,
spatial_reference_system: true,
resource_group: true,
alter_sequence: true,
alter_object_set_schema: true,
};
}
impl ViewSequenceClauseSyntax {
pub const LENIENT: Self = Self {
materialized_view_to: true,
create_sequence_cache: true,
temporary_views: true,
recursive_views: true,
view_definition_options: true,
};
}
impl CreateTableClauseSyntax {
pub const LENIENT: Self = Self {
table_options: true,
without_rowid_table_option: true,
strict_table_option: true,
storage_parameters: true,
on_commit: true,
create_table_as_with_data: true,
create_table_as_execute: true,
declarative_partitioning: true,
table_inheritance: true,
like_source_table: true,
statement_level_table_like: true,
unlogged_tables: true,
table_access_method: true,
without_oids: true,
typed_tables: true,
};
}
impl ColumnDefinitionSyntax {
pub const LENIENT: Self = Self {
generated_column_shorthand: true,
column_conflict_resolution_clause: true,
typeless_column_definitions: true,
typeless_generated_columns: true,
joined_autoincrement_attribute: true,
inline_primary_key_ordering: true,
named_column_collate_constraint: true,
identity_columns: true,
compact_identity_columns: true,
default_expression_requires_parens: false,
column_default_requires_b_expr: false,
column_collation: true,
column_storage: true,
};
}
impl ConstraintSyntax {
pub const LENIENT: Self = Self {
deferrable_constraints: true,
named_inline_non_check_constraints: true,
bare_constraint_name: true,
exclusion_constraints: true,
constraint_no_inherit_not_valid: true,
index_constraint_parameters: true,
constraint_column_collate_order: true,
referential_action_cascade_set: true,
check_constraint_subqueries: true,
};
}
impl IndexAlterSyntax {
pub const LENIENT: Self = Self {
rename_constraint: true,
alter_table_set_options: true,
drop_primary_key: true,
alter_column_add_identity: true,
index_storage_parameters: true,
drop_behavior: true,
index_drop_on_table: false,
index_concurrently: true,
index_using_method: true,
partial_index: true,
index_if_not_exists: true,
index_nulls_order: true,
alter_table_extended: true,
alter_nested_column_paths: true,
alter_existence_guards: true,
alter_column_set_data_type: true,
routine_arg_types: true,
routine_arg_defaults: true,
routine_arg_modes: true,
routine_language_string: true,
alter_table_multiple_actions: true,
};
}
impl ExistenceGuards {
pub const LENIENT: Self = Self {
if_exists: true,
view_if_not_exists: true,
create_database_if_not_exists: true,
};
}
impl SelectSyntax {
pub const LENIENT: Self = Self {
distinct_on: true,
select_into: true,
empty_target_list: true,
qualify: true,
alias_string_literals: true,
bare_alias_string_literals: true,
union_by_name: true,
wildcard_modifiers: true,
wildcard_replace: true,
intersect_all: true,
except_all: true,
qualified_wildcard_alias: true,
from_first: true,
explicit_table: true,
parenthesized_query_operands: true,
values_rows_require_equal_arity: false,
values_row_constructor: true,
as_alias_rejects_reserved: false,
trailing_comma: true,
prefix_colon_alias: true,
lateral_view_clause: true,
connect_by_clause: true,
};
}
impl QueryTailSyntax {
pub const LENIENT: Self = Self {
fetch_first: true,
limit_offset_comma: true,
locking_clauses: true,
key_lock_strengths: true,
stacked_locking_clauses: true,
using_sample: true,
leading_offset: true,
limit_expressions: true,
limit_percent: true,
with_ties_requires_order_by: false,
pipe_syntax: false,
limit_by_clause: true,
settings_clause: true,
format_clause: true,
for_xml_json_clause: true,
};
}
impl GroupingSyntax {
pub const LENIENT: Self = Self {
grouping_sets: true,
with_rollup: true,
order_by_using: true,
group_by_all: true,
group_by_set_quantifier: true,
order_by_all: true,
};
}
impl UtilitySyntax {
pub const LENIENT: Self = Self {
copy: true,
copy_into: true,
stage_references: false,
comment_on: true,
comment_if_exists: true,
pragma: true,
attach: true,
kill: true,
handler_statements: true,
plugin_component_statements: true,
shutdown: true,
restart: true,
clone: true,
import_table: true,
help_statement: true,
binlog: true,
key_cache_statements: true,
use_statement: true,
use_qualified_name: true,
use_string_literal_name: true,
prepared_statements: true,
prepare_typed_parameters: true,
call: true,
call_bare_name: true,
load_extension: true,
load_bare_name: true,
load_data: true,
reset_scope: true,
detach_if_exists: true,
do_statement: true,
do_expression_list: false,
prepared_statements_from: false,
lock_tables: true,
lock_instance: true,
rename_statement: true,
signal_diagnostics: true,
export_import_database: true,
update_extensions: true,
flush: true,
purge_binary_logs: true,
replication_statements: true,
};
}
impl TransactionSyntax {
pub const LENIENT: Self = Self {
start_transaction: true,
start_transaction_block_optional: true,
transaction_work_keyword: true,
begin_transaction_keyword: true,
commit_transaction_keyword: true,
rollback_transaction_keyword: true,
transaction_name: true,
begin_transaction_modes: true,
transaction_savepoints: true,
set_transaction: true,
transaction_isolation_mode: true,
transaction_access_mode: true,
transaction_deferrable_mode: true,
start_transaction_isolation_mode: true,
start_transaction_deferrable_mode: true,
start_transaction_consistent_snapshot: true,
transaction_multiple_modes: true,
transaction_modes_require_commas: false,
transaction_modes_reject_duplicates: false,
abort_transaction_alias: true,
end_transaction_alias: true,
transaction_release: true,
transaction_chain: true,
release_savepoint_keyword_optional: true,
begin_transaction_mode: true,
xa_transactions: true,
};
}
impl ShowSyntax {
pub const LENIENT: Self = Self {
describe: true,
describe_summarize: true,
session_statements: true,
set_value_reserved_words: KeywordSet::EMPTY,
set_value_on_keyword: true,
set_value_null_keyword: true,
show_tables: true,
show_columns: true,
show_create_table: true,
show_functions: true,
show_routine_status: true,
show_verbose: true,
show_admin: true,
};
}
impl MaintenanceSyntax {
pub const LENIENT: Self = Self {
vacuum: true,
vacuum_analyze: true,
reindex: true,
analyze: true,
analyze_columns: true,
checkpoint: true,
checkpoint_database: true,
table_maintenance: true,
};
}
impl AccessControlSyntax {
pub const LENIENT: Self = Self {
alter_role_rename: true,
access_control: true,
access_control_extended_objects: true,
user_role_management: true,
access_control_account_grants: false,
};
}
impl TypeNameSyntax {
pub const LENIENT: Self = Self {
extended_scalar_type_names: true,
enum_type: true,
set_type: true,
numeric_modifiers: true,
integer_display_width: true,
composite_types: true,
varchar_requires_length: false,
zoned_temporal_types: true,
empty_type_parens: true,
character_set_annotation: true,
signed_type_modifier: true,
nullable_type: true,
low_cardinality_type: true,
fixed_string_type: true,
datetime64_type: true,
nested_type: true,
bit_width_integer_names: true,
liberal_type_names: true,
string_type_modifiers: false,
angle_bracket_types: true,
};
}
impl FeatureSet {
pub const LENIENT: Self = Self {
identifier_casing: Casing::Preserve,
identifier_quotes: LENIENT_IDENTIFIER_QUOTES,
default_null_ordering: NullOrdering::NullsLast,
reserved_column_name: RESERVED_COLUMN_NAME,
reserved_function_name: RESERVED_FUNCTION_NAME,
reserved_type_name: RESERVED_TYPE_NAME,
reserved_bare_alias: RESERVED_BARE_ALIAS,
reserved_as_label: KeywordSet::EMPTY,
catalog_qualified_names: true,
byte_classes: STANDARD_BYTE_CLASSES,
binding_powers: BindingPowerTable {
or: BindingPower {
left: 10,
right: 11,
assoc: Assoc::Left,
},
xor: BindingPower {
left: 15,
right: 16,
assoc: Assoc::Left,
},
and: BindingPower {
left: 20,
right: 21,
assoc: Assoc::Left,
},
comparison: BindingPower {
left: 40,
right: 41,
assoc: Assoc::NonAssoc,
},
range_predicate_override: Some(RANGE_PREDICATE_ABOVE_COMPARISON),
is_predicate_override: Some(IS_PREDICATE_BELOW_COMPARISON),
double_equals: BindingPower {
left: 40,
right: 41,
assoc: Assoc::NonAssoc,
},
additive: BindingPower {
left: 50,
right: 51,
assoc: Assoc::Left,
},
multiplicative: BindingPower {
left: 60,
right: 61,
assoc: Assoc::Left,
},
exponent: BindingPower {
left: 65,
right: 66,
assoc: Assoc::Left,
},
string_concat: BindingPower {
left: 45,
right: 46,
assoc: Assoc::Left,
},
any_operator: BindingPower {
left: 45,
right: 46,
assoc: Assoc::Left,
},
json_get: BindingPower {
left: 45,
right: 46,
assoc: Assoc::Left,
},
bitwise_or: BindingPower {
left: 45,
right: 46,
assoc: Assoc::Left,
},
bitwise_and: BindingPower {
left: 45,
right: 46,
assoc: Assoc::Left,
},
bitwise_shift: BindingPower {
left: 45,
right: 46,
assoc: Assoc::Left,
},
bitwise_xor: BindingPower {
left: 45,
right: 46,
assoc: Assoc::Left,
},
prefix_not: 30,
prefix_sign: 80,
prefix_bitwise_not: 46,
at_time_zone: BindingPower {
left: 70,
right: 71,
assoc: Assoc::Left,
},
collate: BindingPower {
left: 74,
right: 75,
assoc: Assoc::Left,
},
subscript: BindingPower {
left: 84,
right: 85,
assoc: Assoc::Left,
},
typecast: BindingPower {
left: 88,
right: 89,
assoc: Assoc::Left,
},
field_selection: BindingPower {
left: 92,
right: 93,
assoc: Assoc::Left,
},
},
set_operation_powers: STANDARD_SET_OPERATION_BINDING_POWERS,
string_literals: StringLiteralSyntax::LENIENT,
numeric_literals: NumericLiteralSyntax::LENIENT,
parameters: ParameterSyntax::LENIENT,
session_variables: SessionVariableSyntax::LENIENT,
identifier_syntax: IdentifierSyntax::LENIENT,
table_expressions: TableExpressionSyntax::LENIENT,
join_syntax: JoinSyntax::LENIENT,
table_factor_syntax: TableFactorSyntax::LENIENT,
expression_syntax: ExpressionSyntax::LENIENT,
operator_syntax: OperatorSyntax::LENIENT,
call_syntax: CallSyntax::LENIENT,
string_func_forms: StringFuncForms::LENIENT,
aggregate_call_syntax: AggregateCallSyntax::LENIENT,
predicate_syntax: PredicateSyntax::LENIENT,
pipe_operator: PipeOperator::StringConcat,
double_ampersand: DoubleAmpersand::LogicalAnd,
keyword_operators: KeywordOperators::MySql,
caret_operator: CaretOperator::BitwiseXor,
hash_bitwise_xor: false,
comment_syntax: CommentSyntax::LENIENT,
mutation_syntax: MutationSyntax::LENIENT,
statement_ddl_gates: StatementDdlGates::LENIENT,
view_sequence_clause_syntax: ViewSequenceClauseSyntax::LENIENT,
create_table_clause_syntax: CreateTableClauseSyntax::LENIENT,
column_definition_syntax: ColumnDefinitionSyntax::LENIENT,
constraint_syntax: ConstraintSyntax::LENIENT,
index_alter_syntax: IndexAlterSyntax::LENIENT,
existence_guards: ExistenceGuards::LENIENT,
select_syntax: SelectSyntax::LENIENT,
query_tail_syntax: QueryTailSyntax::LENIENT,
grouping_syntax: GroupingSyntax::LENIENT,
utility_syntax: UtilitySyntax::LENIENT,
transaction_syntax: TransactionSyntax::LENIENT,
show_syntax: ShowSyntax::LENIENT,
maintenance_syntax: MaintenanceSyntax::LENIENT,
access_control_syntax: AccessControlSyntax::LENIENT,
type_name_syntax: TypeNameSyntax::LENIENT,
target_spelling: TargetSpelling::Ansi,
};
}
pub const LENIENT: FeatureSet = FeatureSet::LENIENT;
const _: () = assert!(FeatureSet::LENIENT.is_lexically_consistent());
const _: () = assert!(FeatureSet::LENIENT.has_satisfied_feature_dependencies());
const _: () = assert!(FeatureSet::LENIENT.has_no_grammar_conflict());
#[cfg(test)]
mod tests {
use super::super::{
Casing, CommentSyntax, ExpressionSyntax, FeatureDelta, FeatureSet, IdentifierQuote,
LexicalConflict, NumericLiteralSyntax, OperatorSyntax, ParameterSyntax, PipeOperator,
SessionVariableSyntax, StringLiteralSyntax, TableExpressionSyntax,
};
#[test]
fn lenient_resolves_every_contested_trigger_to_one_claimant() {
assert_eq!(FeatureSet::LENIENT.lexical_conflict(), None);
assert!(FeatureSet::LENIENT.is_lexically_consistent());
}
#[test]
fn lenient_quotes_three_identifier_styles() {
let opens: Vec<char> = FeatureSet::LENIENT
.identifier_quotes
.iter()
.map(|quote| quote.open())
.collect();
assert_eq!(opens, ['"', '`', '[']);
assert_eq!(
FeatureSet::LENIENT.identifier_quotes[2],
IdentifierQuote::Asymmetric {
open: '[',
close: ']'
},
);
}
#[test]
fn conflict_resolution_fields_match_the_documented_rules() {
let lenient = FeatureSet::LENIENT;
assert!(!lenient.string_literals.double_quoted_strings);
assert!(!lenient.expression_syntax.subscript);
assert!(!lenient.expression_syntax.array_constructor);
assert!(!lenient.numeric_literals.money_literals);
assert!(lenient.parameters.positional_dollar);
assert_eq!(lenient.pipe_operator, PipeOperator::StringConcat);
assert_eq!(lenient.identifier_casing, Casing::Preserve);
}
#[test]
fn lenient_enables_copy_utility_statement() {
let lenient = FeatureSet::LENIENT.utility_syntax;
let ansi = FeatureSet::ANSI.utility_syntax;
assert!(lenient.copy);
assert!(!ansi.copy);
assert_ne!(lenient, ansi);
}
#[test]
fn lexical_conflict_detects_each_contested_trigger() {
let double_quote =
FeatureSet::LENIENT.with(FeatureDelta::EMPTY.string_literals(StringLiteralSyntax {
double_quoted_strings: true,
..StringLiteralSyntax::LENIENT
}));
assert_eq!(
double_quote.lexical_conflict(),
Some(LexicalConflict::DoubleQuoteStringVersusIdentifier),
);
let bracket =
FeatureSet::LENIENT.with(FeatureDelta::EMPTY.expression_syntax(ExpressionSyntax {
subscript: true,
..ExpressionSyntax::LENIENT
}));
assert_eq!(
bracket.lexical_conflict(),
Some(LexicalConflict::BracketIdentifierVersusArraySyntax),
);
let bracket_list =
FeatureSet::LENIENT.with(FeatureDelta::EMPTY.expression_syntax(ExpressionSyntax {
collection_literals: true,
..ExpressionSyntax::LENIENT
}));
assert_eq!(
bracket_list.lexical_conflict(),
Some(LexicalConflict::BracketIdentifierVersusArraySyntax),
);
let bracket_table_path = FeatureSet::LENIENT.with(FeatureDelta::EMPTY.table_expressions(
TableExpressionSyntax {
table_json_path: true,
..TableExpressionSyntax::LENIENT
},
));
assert_eq!(
bracket_table_path.lexical_conflict(),
Some(LexicalConflict::BracketIdentifierVersusArraySyntax),
);
let money =
FeatureSet::LENIENT.with(FeatureDelta::EMPTY.numeric_literals(NumericLiteralSyntax {
money_literals: true,
..NumericLiteralSyntax::LENIENT
}));
assert_eq!(
money.lexical_conflict(),
Some(LexicalConflict::MoneyVersusPositionalDollar),
);
let pg_param = FeatureSet::ANSI.with(FeatureDelta::EMPTY.parameters(ParameterSyntax {
positional_dollar: true,
..ParameterSyntax::ANSI
}));
assert_eq!(pg_param.lexical_conflict(), None);
let at_name = FeatureSet::LENIENT.with(FeatureDelta::EMPTY.session_variables(
SessionVariableSyntax {
user_variables: true,
..SessionVariableSyntax::LENIENT
},
));
assert_eq!(
at_name.lexical_conflict(),
Some(LexicalConflict::AtNameParameterVersusUserVariable),
);
let colon_slice =
FeatureSet::POSTGRES.with(FeatureDelta::EMPTY.parameters(ParameterSyntax {
named_colon: true,
..ParameterSyntax::POSTGRES
}));
assert_eq!(
colon_slice.lexical_conflict(),
Some(LexicalConflict::ColonParameterVersusSliceBound),
);
let colon_collection = FeatureSet::ANSI.with(
FeatureDelta::EMPTY
.parameters(ParameterSyntax {
named_colon: true,
..ParameterSyntax::ANSI
})
.expression_syntax(ExpressionSyntax {
collection_literals: true,
..ExpressionSyntax::ANSI
}),
);
assert_eq!(
colon_collection.lexical_conflict(),
Some(LexicalConflict::ColonParameterVersusSliceBound),
);
let containment_at =
FeatureSet::POSTGRES.with(FeatureDelta::EMPTY.parameters(ParameterSyntax {
named_at: true,
..ParameterSyntax::POSTGRES
}));
assert_eq!(
containment_at.lexical_conflict(),
Some(LexicalConflict::ContainmentOperatorVersusAtName),
);
let custom_at = FeatureSet::POSTGRES.with(
FeatureDelta::EMPTY
.operator_syntax(OperatorSyntax {
containment_operators: false,
..OperatorSyntax::POSTGRES
})
.parameters(ParameterSyntax {
named_at: true,
..ParameterSyntax::POSTGRES
}),
);
assert_eq!(
custom_at.lexical_conflict(),
Some(LexicalConflict::CustomOperatorVersusAtName),
);
let custom_sysvar = FeatureSet::POSTGRES.with(
FeatureDelta::EMPTY
.operator_syntax(OperatorSyntax {
jsonb_operators: false,
..OperatorSyntax::POSTGRES
})
.session_variables(SessionVariableSyntax {
system_variables: true,
..FeatureSet::POSTGRES.session_variables
}),
);
assert_eq!(
custom_sysvar.lexical_conflict(),
Some(LexicalConflict::CustomOperatorVersusSystemVariable),
);
assert_eq!(FeatureSet::LENIENT.lexical_conflict(), None);
let hash_xor_and_comment =
FeatureSet::POSTGRES.with(FeatureDelta::EMPTY.comment_syntax(CommentSyntax {
line_comment_hash: true,
..CommentSyntax::ANSI
}));
assert_eq!(
hash_xor_and_comment.lexical_conflict(),
Some(LexicalConflict::HashXorOperatorVersusHashComment),
);
let lenient_hash_xor = FeatureSet::LENIENT.with(FeatureDelta::EMPTY.hash_bitwise_xor(true));
assert_eq!(
lenient_hash_xor.lexical_conflict(),
Some(LexicalConflict::HashXorOperatorVersusHashComment),
);
}
}