use super::{
AccessControlSyntax, AggregateCallSyntax, CallSyntax, CaretOperator, Casing,
ColumnDefinitionSyntax, CommentSyntax, ConstraintSyntax, CreateTableClauseSyntax,
DoubleAmpersand, ExistenceGuards, ExpressionSyntax, FeatureSet, GroupingSyntax,
IdentifierQuote, IdentifierSyntax, IndexAlterSyntax, JoinSyntax, Keyword, 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 BIGQUERY_IDENTIFIER_QUOTES: &[IdentifierQuote] = &[IdentifierQuote::Symmetric('`')];
pub const BIGQUERY_PIVOT_RESERVATION: KeywordSet =
KeywordSet::from_keywords(&[Keyword::Pivot, Keyword::Unpivot]);
pub const BIGQUERY_RESERVED_COLUMN_NAME: KeywordSet =
RESERVED_COLUMN_NAME.union(BIGQUERY_PIVOT_RESERVATION);
impl StringLiteralSyntax {
pub const BIGQUERY: Self = Self {
double_quoted_strings: true,
escape_strings: false,
dollar_quoted_strings: false,
national_strings: false,
backslash_escapes: false,
unicode_strings: false,
bit_string_literals: false,
blob_literals: false,
charset_introducers: false,
same_line_adjacent_concat: false,
};
}
impl TableExpressionSyntax {
pub const BIGQUERY: Self = Self {
table_version: true,
only: false,
table_sample: false,
parenthesized_joins: true,
table_alias_column_lists: true,
join_using_alias: false,
index_hints: false,
table_hints: false,
partition_selection: false,
base_table_alias_column_lists: true,
string_literal_aliases: false,
aliased_parenthesized_join: true,
bare_table_alias_is_bare_label: false,
table_json_path: false,
indexed_by: false,
prefix_colon_alias: false,
};
}
impl JoinSyntax {
pub const BIGQUERY: Self = Self {
stacked_join_qualifiers: true,
full_outer_join: true,
natural_cross_join: false,
straight_join: false,
asof_join: false,
positional_join: false,
semi_anti_join: false,
sided_semi_anti_join: false,
apply_join: false,
recursive_search_cycle: false,
recursive_union_rejects_order_limit: false,
recursive_using_key: false,
};
}
impl ExpressionSyntax {
pub const BIGQUERY: Self = Self {
struct_constructor: true,
typecast_operator: false,
subscript: false,
slice_step: false,
collate: false,
at_time_zone: false,
semi_structured_access: false,
array_constructor: false,
multidim_array_literals: false,
collection_literals: false,
row_constructor: false,
field_selection: false,
field_wildcard: false,
typed_string_literals: true,
typed_interval_literal: true,
relaxed_interval_syntax: false,
mysql_interval_operator: false,
positional_column: false,
lambda_keyword: false,
};
}
impl TableFactorSyntax {
pub const BIGQUERY: Self = Self {
unnest: true,
unnest_with_offset: true,
pivot_value_sources: true,
lateral: false,
table_functions: false,
rows_from: false,
table_function_ordinality: false,
special_function_table_source: true,
pivot: false,
unpivot: false,
show_ref: false,
from_values: false,
json_table: false,
xml_table: false,
table_expr_factor: false,
match_recognize: false,
open_json: false,
};
}
impl TypeNameSyntax {
pub const BIGQUERY: Self = Self {
angle_bracket_types: 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,
nullable_type: false,
low_cardinality_type: false,
fixed_string_type: false,
datetime64_type: false,
nested_type: false,
bit_width_integer_names: false,
liberal_type_names: false,
string_type_modifiers: false,
};
}
impl FeatureSet {
pub const BIGQUERY: Self = Self {
identifier_casing: Casing::Lower,
identifier_quotes: BIGQUERY_IDENTIFIER_QUOTES,
default_null_ordering: NullOrdering::NullsLast,
reserved_column_name: BIGQUERY_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::BIGQUERY,
numeric_literals: NumericLiteralSyntax::ANSI,
parameters: ParameterSyntax::ANSI,
session_variables: SessionVariableSyntax::ANSI,
identifier_syntax: IdentifierSyntax::ANSI,
table_expressions: TableExpressionSyntax::BIGQUERY,
join_syntax: JoinSyntax::BIGQUERY,
table_factor_syntax: TableFactorSyntax::BIGQUERY,
expression_syntax: ExpressionSyntax::BIGQUERY,
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::ANSI,
query_tail_syntax: QueryTailSyntax::ANSI,
grouping_syntax: GroupingSyntax::ANSI,
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::BIGQUERY,
target_spelling: TargetSpelling::Ansi,
};
}
pub const BIGQUERY: FeatureSet = FeatureSet::BIGQUERY;
const _: () = assert!(FeatureSet::BIGQUERY.is_lexically_consistent());
const _: () = assert!(FeatureSet::BIGQUERY.has_satisfied_feature_dependencies());
const _: () = assert!(FeatureSet::BIGQUERY.has_no_grammar_conflict());
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bigquery_is_ansi_plus_the_gates_and_two_lexical_facts() {
let ansi = FeatureSet::ANSI;
let bq = FeatureSet::BIGQUERY;
assert_eq!(bq.identifier_casing, Casing::Lower);
assert_ne!(bq.identifier_casing, ansi.identifier_casing);
assert_eq!(bq.identifier_quotes, BIGQUERY_IDENTIFIER_QUOTES);
assert_ne!(bq.identifier_quotes, ansi.identifier_quotes);
assert!(bq.string_literals.double_quoted_strings);
assert!(!bq.identifier_quotes.iter().any(|quote| quote.open() == '"'));
assert!(bq.identifier_quotes.iter().any(|quote| quote.open() == '`'));
assert_eq!(bq.identifier_quotes.len(), 1);
assert_eq!(bq.string_literals, StringLiteralSyntax::BIGQUERY);
assert_ne!(bq.string_literals, ansi.string_literals);
assert_eq!(bq.table_expressions, TableExpressionSyntax::BIGQUERY);
assert_eq!(bq.table_factor_syntax, TableFactorSyntax::BIGQUERY);
assert_ne!(bq.table_factor_syntax, ansi.table_factor_syntax);
assert_eq!(bq.reserved_column_name, BIGQUERY_RESERVED_COLUMN_NAME);
assert_ne!(bq.reserved_column_name, ansi.reserved_column_name);
assert_eq!(
bq.reserved_column_name
.difference(BIGQUERY_PIVOT_RESERVATION),
ansi.reserved_column_name,
);
assert!(bq.reserved_column_name.contains(Keyword::Pivot));
assert!(bq.reserved_column_name.contains(Keyword::Unpivot));
assert_eq!(bq.reserved_function_name, ansi.reserved_function_name);
assert_eq!(bq.reserved_type_name, ansi.reserved_type_name);
assert_eq!(bq.reserved_bare_alias, ansi.reserved_bare_alias);
assert!(!bq.reserved_function_name.contains(Keyword::Pivot));
assert!(!bq.reserved_type_name.contains(Keyword::Pivot));
assert!(!bq.reserved_bare_alias.contains(Keyword::Pivot));
assert_eq!(bq.reserved_as_label, KeywordSet::EMPTY);
assert_eq!(bq.select_syntax, ansi.select_syntax);
assert!(!bq.query_tail_syntax.pipe_syntax);
assert_eq!(bq.numeric_literals, ansi.numeric_literals);
assert_eq!(bq.parameters, ansi.parameters);
assert_eq!(bq.expression_syntax, ExpressionSyntax::BIGQUERY);
assert!(bq.expression_syntax.struct_constructor);
assert!(!ansi.expression_syntax.struct_constructor);
assert_eq!(
ExpressionSyntax {
struct_constructor: false,
..bq.expression_syntax
},
ansi.expression_syntax
);
assert_eq!(bq.session_variables, ansi.session_variables);
assert_eq!(bq.identifier_syntax, ansi.identifier_syntax);
assert_eq!(bq.operator_syntax, ansi.operator_syntax);
assert_eq!(bq.call_syntax, ansi.call_syntax);
assert_eq!(bq.predicate_syntax, ansi.predicate_syntax);
assert_eq!(bq.mutation_syntax, ansi.mutation_syntax);
assert_eq!(bq.statement_ddl_gates, ansi.statement_ddl_gates);
assert_eq!(
bq.create_table_clause_syntax,
ansi.create_table_clause_syntax
);
assert_eq!(bq.column_definition_syntax, ansi.column_definition_syntax);
assert_eq!(bq.constraint_syntax, ansi.constraint_syntax);
assert_eq!(bq.index_alter_syntax, ansi.index_alter_syntax);
assert_eq!(bq.existence_guards, ansi.existence_guards);
assert_eq!(bq.utility_syntax, ansi.utility_syntax);
assert!(bq.type_name_syntax.angle_bracket_types);
assert!(!ansi.type_name_syntax.angle_bracket_types);
assert_eq!(
TypeNameSyntax {
angle_bracket_types: false,
..bq.type_name_syntax
},
ansi.type_name_syntax,
);
assert_eq!(bq.byte_classes, ansi.byte_classes);
assert_eq!(bq.binding_powers, ansi.binding_powers);
assert_eq!(bq.target_spelling, ansi.target_spelling);
assert_eq!(bq.default_null_ordering, ansi.default_null_ordering);
}
#[test]
fn bigquery_enables_exactly_the_unnest_gates_and_double_quote_string() {
let ansi = FeatureSet::ANSI;
let bq = FeatureSet::BIGQUERY;
assert!(bq.table_factor_syntax.unnest && !ansi.table_factor_syntax.unnest);
assert!(
bq.table_factor_syntax.unnest_with_offset
&& !ansi.table_factor_syntax.unnest_with_offset
);
assert!(
bq.string_literals.double_quoted_strings && !ansi.string_literals.double_quoted_strings
);
assert!(bq.identifier_quotes.iter().any(|quote| quote.open() == '`'));
assert!(
!ansi
.identifier_quotes
.iter()
.any(|quote| quote.open() == '`')
);
assert_eq!(
TableFactorSyntax {
unnest: false,
unnest_with_offset: false,
pivot_value_sources: false,
..bq.table_factor_syntax
},
ansi.table_factor_syntax,
);
assert_eq!(
StringLiteralSyntax {
double_quoted_strings: false,
..bq.string_literals
},
ansi.string_literals,
);
}
#[test]
fn bigquery_is_lexically_consistent_and_dependency_clean() {
let bq = FeatureSet::BIGQUERY;
assert_eq!(bq.lexical_conflict(), None);
assert!(bq.is_lexically_consistent());
assert_eq!(bq.feature_dependencies(), None);
assert!(bq.has_satisfied_feature_dependencies());
assert_eq!(bq.grammar_conflict(), None);
assert!(bq.has_no_grammar_conflict());
let broken = FeatureSet::BIGQUERY.with(
super::super::FeatureDelta::EMPTY.table_factor_syntax(TableFactorSyntax {
unnest: false,
..bq.table_factor_syntax
}),
);
assert_eq!(
broken.feature_dependencies(),
Some(super::super::FeatureDependencyViolation::UnnestWithOffsetWithoutUnnest),
);
}
#[test]
fn bigquery_closed_delta_axes_match_documented_set() {
crate::dialect::closed_delta::assert_closed_delta(
&FeatureSet::ANSI,
&FeatureSet::BIGQUERY,
&[
"identifier_casing",
"identifier_quotes",
"reserved_column_name",
"string_literals",
"table_expressions",
"table_factor_syntax",
"expression_syntax",
"type_name_syntax",
],
);
}
}