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::{STANDARD_BINDING_POWERS, STANDARD_SET_OPERATION_BINDING_POWERS};
pub const CLICKHOUSE_IDENTIFIER_QUOTES: &[IdentifierQuote] = &[
IdentifierQuote::Symmetric('"'),
IdentifierQuote::Symmetric('`'),
];
impl SelectSyntax {
pub const CLICKHOUSE: Self = Self {
distinct_on: false,
select_into: false,
empty_target_list: false,
qualify: false,
alias_string_literals: false,
bare_alias_string_literals: false,
union_by_name: false,
wildcard_modifiers: false,
wildcard_replace: false,
intersect_all: true,
except_all: true,
qualified_wildcard_alias: false,
from_first: false,
explicit_table: true,
parenthesized_query_operands: true,
values_rows_require_equal_arity: false,
values_row_constructor: true,
as_alias_rejects_reserved: false,
trailing_comma: false,
prefix_colon_alias: false,
lateral_view_clause: false,
connect_by_clause: false,
};
}
impl QueryTailSyntax {
pub const CLICKHOUSE: Self = Self {
limit_by_clause: true,
settings_clause: true,
format_clause: true,
fetch_first: true,
limit_offset_comma: false,
locking_clauses: false,
key_lock_strengths: false,
stacked_locking_clauses: false,
using_sample: false,
leading_offset: true,
limit_expressions: true,
limit_percent: false,
with_ties_requires_order_by: false,
pipe_syntax: false,
for_xml_json_clause: false,
};
}
impl GroupingSyntax {
pub const CLICKHOUSE: Self = Self {
grouping_sets: true,
with_rollup: false,
order_by_using: false,
group_by_all: false,
group_by_set_quantifier: false,
order_by_all: false,
};
}
impl TypeNameSyntax {
pub const CLICKHOUSE: Self = Self {
nullable_type: true,
low_cardinality_type: true,
fixed_string_type: true,
datetime64_type: true,
nested_type: true,
bit_width_integer_names: true,
extended_scalar_type_names: false,
enum_type: false,
set_type: false,
numeric_modifiers: false,
integer_display_width: false,
composite_types: false,
varchar_requires_length: false,
zoned_temporal_types: true,
empty_type_parens: false,
character_set_annotation: false,
signed_type_modifier: false,
liberal_type_names: false,
string_type_modifiers: false,
angle_bracket_types: false,
};
}
impl FeatureSet {
pub const CLICKHOUSE: Self = Self {
identifier_casing: Casing::Preserve,
identifier_quotes: CLICKHOUSE_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::ANSI,
numeric_literals: NumericLiteralSyntax::ANSI,
parameters: ParameterSyntax::ANSI,
session_variables: SessionVariableSyntax::ANSI,
identifier_syntax: IdentifierSyntax::ANSI,
table_expressions: TableExpressionSyntax::ANSI,
join_syntax: JoinSyntax::ANSI,
table_factor_syntax: TableFactorSyntax::ANSI,
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,
view_sequence_clause_syntax: ViewSequenceClauseSyntax::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::CLICKHOUSE,
query_tail_syntax: QueryTailSyntax::CLICKHOUSE,
grouping_syntax: GroupingSyntax::CLICKHOUSE,
utility_syntax: UtilitySyntax::ANSI,
transaction_syntax: TransactionSyntax::ANSI,
show_syntax: ShowSyntax::ANSI,
maintenance_syntax: MaintenanceSyntax::ANSI,
access_control_syntax: AccessControlSyntax::ANSI,
type_name_syntax: TypeNameSyntax::CLICKHOUSE,
target_spelling: TargetSpelling::Ansi,
};
}
pub const CLICKHOUSE: FeatureSet = FeatureSet::CLICKHOUSE;
const _: () = assert!(FeatureSet::CLICKHOUSE.is_lexically_consistent());
const _: () = assert!(FeatureSet::CLICKHOUSE.has_satisfied_feature_dependencies());
const _: () = assert!(FeatureSet::CLICKHOUSE.has_no_grammar_conflict());
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn clickhouse_is_ansi_plus_the_nine_gates_and_two_lexical_facts() {
let ansi = FeatureSet::ANSI;
let ch = FeatureSet::CLICKHOUSE;
assert_eq!(ch.identifier_casing, Casing::Preserve);
assert_ne!(ch.identifier_casing, ansi.identifier_casing);
assert_eq!(ch.identifier_quotes, CLICKHOUSE_IDENTIFIER_QUOTES);
assert_ne!(ch.identifier_quotes, ansi.identifier_quotes);
assert!(!ch.string_literals.double_quoted_strings);
assert_eq!(ch.query_tail_syntax, QueryTailSyntax::CLICKHOUSE);
assert_ne!(ch.query_tail_syntax, ansi.query_tail_syntax);
assert_eq!(ch.type_name_syntax, TypeNameSyntax::CLICKHOUSE);
assert_ne!(ch.type_name_syntax, ansi.type_name_syntax);
assert_eq!(ch.string_literals, ansi.string_literals);
assert_eq!(ch.numeric_literals, ansi.numeric_literals);
assert_eq!(ch.parameters, ansi.parameters);
assert_eq!(ch.session_variables, ansi.session_variables);
assert_eq!(ch.identifier_syntax, ansi.identifier_syntax);
assert_eq!(ch.table_expressions, ansi.table_expressions);
assert_eq!(ch.expression_syntax, ansi.expression_syntax);
assert_eq!(ch.operator_syntax, ansi.operator_syntax);
assert_eq!(ch.call_syntax, ansi.call_syntax);
assert_eq!(ch.predicate_syntax, ansi.predicate_syntax);
assert_eq!(ch.mutation_syntax, ansi.mutation_syntax);
assert_eq!(ch.statement_ddl_gates, ansi.statement_ddl_gates);
assert_eq!(
ch.create_table_clause_syntax,
ansi.create_table_clause_syntax
);
assert_eq!(ch.column_definition_syntax, ansi.column_definition_syntax);
assert_eq!(ch.constraint_syntax, ansi.constraint_syntax);
assert_eq!(ch.index_alter_syntax, ansi.index_alter_syntax);
assert_eq!(ch.existence_guards, ansi.existence_guards);
assert_eq!(ch.utility_syntax, ansi.utility_syntax);
assert_eq!(ch.reserved_column_name, ansi.reserved_column_name);
assert_eq!(ch.reserved_function_name, ansi.reserved_function_name);
assert_eq!(ch.reserved_type_name, ansi.reserved_type_name);
assert_eq!(ch.reserved_bare_alias, ansi.reserved_bare_alias);
assert_eq!(ch.byte_classes, ansi.byte_classes);
assert_eq!(ch.binding_powers, ansi.binding_powers);
assert_eq!(ch.target_spelling, ansi.target_spelling);
}
#[test]
fn clickhouse_enables_exactly_the_nine_staged_gates() {
let ansi = FeatureSet::ANSI;
let ch = FeatureSet::CLICKHOUSE;
assert!(ch.query_tail_syntax.limit_by_clause && !ansi.query_tail_syntax.limit_by_clause);
assert!(ch.query_tail_syntax.settings_clause && !ansi.query_tail_syntax.settings_clause);
assert!(ch.query_tail_syntax.format_clause && !ansi.query_tail_syntax.format_clause);
assert!(ch.type_name_syntax.nullable_type && !ansi.type_name_syntax.nullable_type);
assert!(
ch.type_name_syntax.low_cardinality_type && !ansi.type_name_syntax.low_cardinality_type
);
assert!(ch.type_name_syntax.fixed_string_type && !ansi.type_name_syntax.fixed_string_type);
assert!(ch.type_name_syntax.datetime64_type && !ansi.type_name_syntax.datetime64_type);
assert!(ch.type_name_syntax.nested_type && !ansi.type_name_syntax.nested_type);
assert!(
ch.type_name_syntax.bit_width_integer_names
&& !ansi.type_name_syntax.bit_width_integer_names
);
assert_eq!(
QueryTailSyntax {
limit_by_clause: false,
settings_clause: false,
format_clause: false,
..ch.query_tail_syntax
},
ansi.query_tail_syntax,
);
assert_eq!(
TypeNameSyntax {
nullable_type: false,
low_cardinality_type: false,
fixed_string_type: false,
datetime64_type: false,
nested_type: false,
bit_width_integer_names: false,
..ch.type_name_syntax
},
ansi.type_name_syntax,
);
}
#[test]
fn clickhouse_is_lexically_consistent_and_dependency_clean() {
let ch = FeatureSet::CLICKHOUSE;
assert_eq!(ch.lexical_conflict(), None);
assert!(ch.is_lexically_consistent());
assert_eq!(ch.feature_dependencies(), None);
assert!(ch.has_satisfied_feature_dependencies());
assert_eq!(ch.grammar_conflict(), None);
assert!(ch.has_no_grammar_conflict());
}
#[test]
fn clickhouse_closed_delta_axes_match_documented_set() {
crate::dialect::closed_delta::assert_closed_delta(
&FeatureSet::ANSI,
&FeatureSet::CLICKHOUSE,
&[
"identifier_casing",
"identifier_quotes",
"query_tail_syntax",
"type_name_syntax",
],
);
}
}