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, TypeNameSyntax,
UtilitySyntax,
};
use crate::precedence::{STANDARD_BINDING_POWERS, STANDARD_SET_OPERATION_BINDING_POWERS};
pub const MSSQL_IDENTIFIER_QUOTES: &[IdentifierQuote] = &[
IdentifierQuote::Symmetric('"'),
IdentifierQuote::Asymmetric {
open: '[',
close: ']',
},
];
impl StringLiteralSyntax {
pub const MSSQL: Self = Self {
national_strings: true,
..StringLiteralSyntax::ANSI
};
}
impl NumericLiteralSyntax {
pub const MSSQL: Self = Self {
money_literals: true,
..NumericLiteralSyntax::ANSI
};
}
impl ParameterSyntax {
pub const MSSQL: Self = Self {
named_at: true,
..ParameterSyntax::ANSI
};
}
impl TableExpressionSyntax {
pub const MSSQL: Self = Self {
table_hints: true,
table_version: true,
..TableExpressionSyntax::ANSI
};
}
impl JoinSyntax {
pub const MSSQL: Self = Self {
apply_join: true,
..JoinSyntax::ANSI
};
}
impl QueryTailSyntax {
pub const MSSQL: Self = Self {
for_xml_json_clause: true,
..QueryTailSyntax::ANSI
};
}
impl TableFactorSyntax {
pub const MSSQL: Self = Self {
open_json: true,
..TableFactorSyntax::ANSI
};
}
impl FeatureSet {
pub const MSSQL: Self = Self {
identifier_casing: Casing::Lower,
identifier_quotes: MSSQL_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: STANDARD_BINDING_POWERS,
set_operation_powers: STANDARD_SET_OPERATION_BINDING_POWERS,
string_literals: StringLiteralSyntax::MSSQL,
numeric_literals: NumericLiteralSyntax::MSSQL,
parameters: ParameterSyntax::MSSQL,
session_variables: SessionVariableSyntax::ANSI,
identifier_syntax: IdentifierSyntax::ANSI,
table_expressions: TableExpressionSyntax::MSSQL,
join_syntax: JoinSyntax::MSSQL,
table_factor_syntax: TableFactorSyntax::MSSQL,
expression_syntax: ExpressionSyntax::ANSI,
operator_syntax: OperatorSyntax::ANSI,
call_syntax: CallSyntax::ANSI,
string_func_forms: StringFuncForms::ANSI,
aggregate_call_syntax: AggregateCallSyntax::ANSI,
predicate_syntax: PredicateSyntax::ANSI,
pipe_operator: PipeOperator::StringConcat,
double_ampersand: DoubleAmpersand::Unsupported,
keyword_operators: KeywordOperators::Unsupported,
caret_operator: CaretOperator::Unsupported,
hash_bitwise_xor: false,
comment_syntax: CommentSyntax::ANSI,
mutation_syntax: MutationSyntax::ANSI,
statement_ddl_gates: StatementDdlGates::ANSI,
create_table_clause_syntax: CreateTableClauseSyntax::ANSI,
column_definition_syntax: ColumnDefinitionSyntax::ANSI,
constraint_syntax: ConstraintSyntax::ANSI,
index_alter_syntax: IndexAlterSyntax::ANSI,
existence_guards: ExistenceGuards::ANSI,
select_syntax: SelectSyntax::ANSI,
query_tail_syntax: QueryTailSyntax::MSSQL,
grouping_syntax: GroupingSyntax::ANSI,
utility_syntax: UtilitySyntax::ANSI,
show_syntax: ShowSyntax::ANSI,
maintenance_syntax: MaintenanceSyntax::ANSI,
access_control_syntax: AccessControlSyntax::ANSI,
type_name_syntax: TypeNameSyntax::ANSI,
target_spelling: TargetSpelling::Ansi,
};
}
pub const MSSQL: FeatureSet = FeatureSet::MSSQL;
const _: () = assert!(FeatureSet::MSSQL.is_lexically_consistent());
const _: () = assert!(FeatureSet::MSSQL.has_satisfied_feature_dependencies());
const _: () = assert!(FeatureSet::MSSQL.has_no_grammar_conflict());
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mssql_is_ansi_plus_the_six_gates_and_two_lexical_facts() {
let ansi = FeatureSet::ANSI;
let mssql = FeatureSet::MSSQL;
assert_eq!(mssql.identifier_casing, Casing::Lower);
assert_ne!(mssql.identifier_casing, ansi.identifier_casing);
assert_eq!(mssql.identifier_quotes, MSSQL_IDENTIFIER_QUOTES);
assert_ne!(mssql.identifier_quotes, ansi.identifier_quotes);
assert!(!mssql.string_literals.double_quoted_strings);
assert!(!mssql.session_variables.user_variables);
assert!(!mssql.parameters.positional_dollar);
assert!(
!mssql
.identifier_quotes
.iter()
.any(|quote| quote.open() == '`')
);
assert_eq!(mssql.string_literals, StringLiteralSyntax::MSSQL);
assert_ne!(mssql.string_literals, ansi.string_literals);
assert_eq!(mssql.numeric_literals, NumericLiteralSyntax::MSSQL);
assert_ne!(mssql.numeric_literals, ansi.numeric_literals);
assert_eq!(mssql.parameters, ParameterSyntax::MSSQL);
assert_ne!(mssql.parameters, ansi.parameters);
assert_eq!(mssql.table_expressions, TableExpressionSyntax::MSSQL);
assert_ne!(mssql.table_expressions, ansi.table_expressions);
assert_eq!(mssql.reserved_column_name, ansi.reserved_column_name);
assert_eq!(mssql.reserved_function_name, ansi.reserved_function_name);
assert_eq!(mssql.reserved_type_name, ansi.reserved_type_name);
assert_eq!(mssql.reserved_bare_alias, ansi.reserved_bare_alias);
assert_eq!(mssql.reserved_as_label, KeywordSet::EMPTY);
assert_eq!(mssql.select_syntax, ansi.select_syntax);
assert_eq!(mssql.expression_syntax, ansi.expression_syntax);
assert_eq!(mssql.session_variables, ansi.session_variables);
assert_eq!(mssql.identifier_syntax, ansi.identifier_syntax);
assert_eq!(mssql.operator_syntax, ansi.operator_syntax);
assert_eq!(mssql.call_syntax, ansi.call_syntax);
assert_eq!(mssql.predicate_syntax, ansi.predicate_syntax);
assert_eq!(mssql.mutation_syntax, ansi.mutation_syntax);
assert_eq!(mssql.statement_ddl_gates, ansi.statement_ddl_gates);
assert_eq!(
mssql.create_table_clause_syntax,
ansi.create_table_clause_syntax
);
assert_eq!(
mssql.column_definition_syntax,
ansi.column_definition_syntax
);
assert_eq!(mssql.constraint_syntax, ansi.constraint_syntax);
assert_eq!(mssql.index_alter_syntax, ansi.index_alter_syntax);
assert_eq!(mssql.existence_guards, ansi.existence_guards);
assert_eq!(mssql.utility_syntax, ansi.utility_syntax);
assert_eq!(mssql.type_name_syntax, ansi.type_name_syntax);
assert_eq!(mssql.byte_classes, ansi.byte_classes);
assert_eq!(mssql.binding_powers, ansi.binding_powers);
assert_eq!(mssql.target_spelling, ansi.target_spelling);
assert_eq!(mssql.default_null_ordering, ansi.default_null_ordering);
}
#[test]
fn mssql_enables_exactly_the_six_staged_gates() {
let ansi = FeatureSet::ANSI;
let mssql = FeatureSet::MSSQL;
assert!(mssql.join_syntax.apply_join);
assert!(!ansi.join_syntax.apply_join);
assert!(mssql.table_expressions.table_hints);
assert!(!ansi.table_expressions.table_hints);
assert!(mssql.parameters.named_at && !ansi.parameters.named_at);
assert!(mssql.string_literals.national_strings && !ansi.string_literals.national_strings);
assert!(mssql.numeric_literals.money_literals && !ansi.numeric_literals.money_literals);
assert!(
mssql
.identifier_quotes
.iter()
.any(|quote| quote.open() == '[')
);
assert!(
!ansi
.identifier_quotes
.iter()
.any(|quote| quote.open() == '[')
);
assert_eq!(
TableExpressionSyntax {
table_hints: false,
table_version: false,
..mssql.table_expressions
},
ansi.table_expressions,
);
assert_eq!(
JoinSyntax {
apply_join: false,
..mssql.join_syntax
},
ansi.join_syntax,
);
assert_eq!(
ParameterSyntax {
named_at: false,
..mssql.parameters
},
ansi.parameters,
);
assert_eq!(
StringLiteralSyntax {
national_strings: false,
..mssql.string_literals
},
ansi.string_literals,
);
assert_eq!(
NumericLiteralSyntax {
money_literals: false,
..mssql.numeric_literals
},
ansi.numeric_literals,
);
}
#[test]
fn mssql_is_lexically_consistent_and_dependency_clean() {
let mssql = FeatureSet::MSSQL;
assert_eq!(mssql.lexical_conflict(), None);
assert!(mssql.is_lexically_consistent());
assert_eq!(mssql.feature_dependencies(), None);
assert!(mssql.has_satisfied_feature_dependencies());
assert_eq!(mssql.grammar_conflict(), None);
assert!(mssql.has_no_grammar_conflict());
}
}