1use super::{
68 AccessControlSyntax, AggregateCallSyntax, CallSyntax, CaretOperator, Casing,
69 ColumnDefinitionSyntax, CommentSyntax, ConstraintSyntax, CreateTableClauseSyntax,
70 DoubleAmpersand, ExistenceGuards, ExpressionSyntax, FeatureSet, GroupingSyntax,
71 IdentifierQuote, IdentifierSyntax, IndexAlterSyntax, JoinSyntax, Keyword, KeywordOperators,
72 KeywordSet, MaintenanceSyntax, MutationSyntax, NullOrdering, NumericLiteralSyntax,
73 OperatorSyntax, ParameterSyntax, PipeOperator, PredicateSyntax, QueryTailSyntax,
74 RESERVED_BARE_ALIAS, RESERVED_COLUMN_NAME, RESERVED_FUNCTION_NAME, RESERVED_TYPE_NAME,
75 STANDARD_BYTE_CLASSES, SelectSyntax, SessionVariableSyntax, ShowSyntax, StatementDdlGates,
76 StringFuncForms, StringLiteralSyntax, TableExpressionSyntax, TableFactorSyntax, TargetSpelling,
77 TransactionSyntax, TypeNameSyntax, UtilitySyntax, ViewSequenceClauseSyntax,
78};
79use crate::precedence::{STANDARD_BINDING_POWERS, STANDARD_SET_OPERATION_BINDING_POWERS};
80
81pub const DATABRICKS_IDENTIFIER_QUOTES: &[IdentifierQuote] = &[
87 IdentifierQuote::Symmetric('"'),
88 IdentifierQuote::Symmetric('`'),
89];
90
91pub const DATABRICKS_QUALIFY_RESERVATION: KeywordSet =
99 KeywordSet::from_keywords(&[Keyword::Qualify]);
100
101pub const DATABRICKS_RESERVED_COLUMN_NAME: KeywordSet =
103 RESERVED_COLUMN_NAME.union(DATABRICKS_QUALIFY_RESERVATION);
104
105pub const DATABRICKS_RESERVED_FUNCTION_NAME: KeywordSet =
107 RESERVED_FUNCTION_NAME.union(DATABRICKS_QUALIFY_RESERVATION);
108
109pub const DATABRICKS_RESERVED_TYPE_NAME: KeywordSet =
111 RESERVED_TYPE_NAME.union(DATABRICKS_QUALIFY_RESERVATION);
112
113pub const DATABRICKS_RESERVED_BARE_ALIAS: KeywordSet =
115 RESERVED_BARE_ALIAS.union(DATABRICKS_QUALIFY_RESERVATION);
116
117impl SelectSyntax {
118 pub const DATABRICKS: Self = Self {
124 qualify: true,
125 lateral_view_clause: true,
130 distinct_on: false,
131 select_into: false,
132 empty_target_list: false,
133 alias_string_literals: false,
134 bare_alias_string_literals: false,
135 union_by_name: false,
136 wildcard_modifiers: false,
137 wildcard_replace: false,
138 intersect_all: true,
139 except_all: true,
140 qualified_wildcard_alias: false,
141 from_first: false,
142 explicit_table: true,
143 parenthesized_query_operands: true,
144 values_rows_require_equal_arity: false,
145 values_row_constructor: true,
146 as_alias_rejects_reserved: false,
147 trailing_comma: false,
148 prefix_colon_alias: false,
149 connect_by_clause: false,
150 };
151}
152
153impl QueryTailSyntax {
154 pub const DATABRICKS: Self = Self {
156 fetch_first: true,
157 limit_offset_comma: false,
158 locking_clauses: false,
159 key_lock_strengths: false,
160 stacked_locking_clauses: false,
161 using_sample: false,
162 leading_offset: true,
163 limit_expressions: true,
164 limit_percent: false,
165 with_ties_requires_order_by: false,
166 pipe_syntax: false,
167 limit_by_clause: false,
168 settings_clause: false,
169 format_clause: false,
170 for_xml_json_clause: false,
171 };
172}
173
174impl GroupingSyntax {
175 pub const DATABRICKS: Self = Self {
177 group_by_all: true,
178 group_by_set_quantifier: false,
179 order_by_all: true,
180 grouping_sets: true,
181 with_rollup: false,
182 order_by_using: false,
183 };
184}
185
186impl ExpressionSyntax {
187 pub const DATABRICKS: Self = Self {
191 semi_structured_access: true,
192 typecast_operator: false,
193 subscript: false,
194 slice_step: false,
195 collate: false,
196 at_time_zone: false,
197 array_constructor: false,
198 multidim_array_literals: false,
199 collection_literals: false,
200 row_constructor: false,
201 struct_constructor: false,
202 field_selection: false,
203 field_wildcard: false,
204 typed_string_literals: true,
205 typed_interval_literal: true,
206 relaxed_interval_syntax: false,
207 mysql_interval_operator: false,
208 positional_column: false,
209 lambda_keyword: false,
210 };
211}
212
213impl TableExpressionSyntax {
214 pub const DATABRICKS: Self = Self {
220 table_version: true,
222 only: false,
223 table_sample: false,
224 parenthesized_joins: true,
225 table_alias_column_lists: true,
226 join_using_alias: false,
227 index_hints: false,
228 table_hints: false,
229 partition_selection: false,
230 base_table_alias_column_lists: true,
231 string_literal_aliases: false,
232 aliased_parenthesized_join: true,
233 bare_table_alias_is_bare_label: false,
234 table_json_path: false,
235 indexed_by: false,
236 prefix_colon_alias: false,
237 };
238}
239
240impl JoinSyntax {
241 pub const DATABRICKS: Self = Self {
243 sided_semi_anti_join: true,
244 stacked_join_qualifiers: true,
245 full_outer_join: true,
246 natural_cross_join: false,
247 straight_join: false,
248 asof_join: false,
249 positional_join: false,
250 semi_anti_join: false,
251 apply_join: false,
252 recursive_search_cycle: false,
253 recursive_union_rejects_order_limit: false,
254 recursive_using_key: false,
255 };
256}
257
258impl TableFactorSyntax {
259 pub const DATABRICKS: Self = Self {
261 lateral: false,
262 table_functions: false,
263 rows_from: false,
264 unnest: false,
265 unnest_with_offset: false,
266 table_function_ordinality: false,
267 special_function_table_source: true,
268 pivot: false,
269 unpivot: false,
270 show_ref: false,
271 from_values: false,
272 json_table: false,
273 xml_table: false,
274 table_expr_factor: false,
275 pivot_value_sources: false,
276 match_recognize: false,
277 open_json: false,
278 };
279}
280
281impl UtilitySyntax {
282 pub const DATABRICKS: Self = Self {
289 copy: false,
290 copy_into: false,
291 stage_references: false,
292 comment_on: false,
293 comment_if_exists: false,
294 pragma: false,
295 attach: false,
296 kill: false,
297 handler_statements: false,
298 plugin_component_statements: false,
299 shutdown: false,
300 restart: false,
301 clone: false,
302 import_table: false,
303 help_statement: false,
304 binlog: false,
305 key_cache_statements: false,
306 use_statement: false,
307 use_qualified_name: false,
308 use_string_literal_name: false,
309 prepared_statements: false,
310 prepare_typed_parameters: false,
311 prepared_statements_from: false,
312 call: false,
313 call_bare_name: false,
314 load_extension: false,
315 load_bare_name: false,
316 load_data: false,
317 reset_scope: false,
318 detach_if_exists: false,
319 do_statement: false,
320 do_expression_list: false,
321 lock_tables: false,
322 lock_instance: false,
323 rename_statement: false,
324 signal_diagnostics: false,
325 export_import_database: false,
326 update_extensions: false,
327 flush: false,
328 purge_binary_logs: false,
329 replication_statements: false,
330 };
331}
332impl TransactionSyntax {
333 pub const DATABRICKS: Self = Self {
335 start_transaction: true,
336 start_transaction_block_optional: false,
337 transaction_work_keyword: true,
338 begin_transaction_keyword: true,
339 commit_transaction_keyword: true,
340 rollback_transaction_keyword: true,
341 transaction_name: false,
342 begin_transaction_modes: true,
343 transaction_savepoints: true,
344 set_transaction: true,
345 transaction_isolation_mode: true,
346 transaction_access_mode: true,
347 transaction_deferrable_mode: true,
348 start_transaction_isolation_mode: true,
349 start_transaction_deferrable_mode: true,
350 start_transaction_consistent_snapshot: false,
351 transaction_multiple_modes: true,
352 transaction_modes_require_commas: false,
353 transaction_modes_reject_duplicates: false,
354 abort_transaction_alias: false,
355 end_transaction_alias: false,
356 transaction_release: false,
357 transaction_chain: true,
358 release_savepoint_keyword_optional: true,
359 begin_transaction_mode: false,
360 xa_transactions: false,
361 };
362}
363
364impl ShowSyntax {
365 pub const DATABRICKS: Self = Self {
367 show_functions: true,
368 describe: false,
369 describe_summarize: false,
370 session_statements: true,
371 set_value_reserved_words: super::RESERVED_SET_VALUE_WORDS,
372 set_value_on_keyword: true,
373 set_value_null_keyword: false,
374 show_tables: false,
375 show_columns: false,
376 show_create_table: false,
377 show_routine_status: false,
378 show_verbose: false,
379 show_admin: false,
380 };
381}
382
383impl MaintenanceSyntax {
384 pub const DATABRICKS: Self = Self {
386 vacuum: false,
387 vacuum_analyze: false,
388 reindex: false,
389 analyze: false,
390 analyze_columns: false,
391 checkpoint: false,
392 checkpoint_database: false,
393 table_maintenance: false,
394 };
395}
396
397impl AccessControlSyntax {
398 pub const DATABRICKS: Self = Self {
400 alter_role_rename: false,
401 access_control: true,
402 access_control_extended_objects: true,
403 user_role_management: false,
404 access_control_account_grants: false,
405 };
406}
407
408impl FeatureSet {
409 pub const DATABRICKS: Self = Self {
412 identifier_casing: Casing::Preserve,
416 identifier_quotes: DATABRICKS_IDENTIFIER_QUOTES,
418 default_null_ordering: NullOrdering::NullsLast,
419 reserved_column_name: DATABRICKS_RESERVED_COLUMN_NAME,
423 reserved_function_name: DATABRICKS_RESERVED_FUNCTION_NAME,
424 reserved_type_name: DATABRICKS_RESERVED_TYPE_NAME,
425 reserved_bare_alias: DATABRICKS_RESERVED_BARE_ALIAS,
426 reserved_as_label: KeywordSet::EMPTY,
427 catalog_qualified_names: true,
428 byte_classes: STANDARD_BYTE_CLASSES,
429 binding_powers: STANDARD_BINDING_POWERS,
430 set_operation_powers: STANDARD_SET_OPERATION_BINDING_POWERS,
431 string_literals: StringLiteralSyntax::ANSI,
437 numeric_literals: NumericLiteralSyntax::ANSI,
438 parameters: ParameterSyntax::ANSI,
439 session_variables: SessionVariableSyntax::ANSI,
440 identifier_syntax: IdentifierSyntax::ANSI,
441 table_expressions: TableExpressionSyntax::DATABRICKS,
443 join_syntax: JoinSyntax::DATABRICKS,
444 table_factor_syntax: TableFactorSyntax::DATABRICKS,
445 expression_syntax: ExpressionSyntax::DATABRICKS,
447 operator_syntax: OperatorSyntax::ANSI,
448 call_syntax: CallSyntax::ANSI,
449 string_func_forms: StringFuncForms::ANSI,
450 aggregate_call_syntax: AggregateCallSyntax::ANSI,
451 predicate_syntax: PredicateSyntax::ANSI,
452 pipe_operator: PipeOperator::StringConcat,
453 double_ampersand: DoubleAmpersand::Unsupported,
454 keyword_operators: KeywordOperators::Unsupported,
455 caret_operator: CaretOperator::Unsupported,
456 hash_bitwise_xor: false,
457 comment_syntax: CommentSyntax::ANSI,
458 mutation_syntax: MutationSyntax::ANSI,
459 statement_ddl_gates: StatementDdlGates::ANSI,
460 view_sequence_clause_syntax: ViewSequenceClauseSyntax::ANSI,
461 create_table_clause_syntax: CreateTableClauseSyntax::ANSI,
462 column_definition_syntax: ColumnDefinitionSyntax::ANSI,
463 constraint_syntax: ConstraintSyntax::ANSI,
464 index_alter_syntax: IndexAlterSyntax::ANSI,
465 existence_guards: ExistenceGuards::ANSI,
466 select_syntax: SelectSyntax::DATABRICKS,
468 query_tail_syntax: QueryTailSyntax::DATABRICKS,
469 grouping_syntax: GroupingSyntax::DATABRICKS,
470 utility_syntax: UtilitySyntax::DATABRICKS,
473 transaction_syntax: TransactionSyntax::DATABRICKS,
474 show_syntax: ShowSyntax::DATABRICKS,
475 maintenance_syntax: MaintenanceSyntax::DATABRICKS,
476 access_control_syntax: AccessControlSyntax::DATABRICKS,
477 type_name_syntax: TypeNameSyntax::ANSI,
478 target_spelling: TargetSpelling::Ansi,
482 };
483}
484
485pub const DATABRICKS: FeatureSet = FeatureSet::DATABRICKS;
487
488const _: () = assert!(FeatureSet::DATABRICKS.is_lexically_consistent());
497const _: () = assert!(FeatureSet::DATABRICKS.has_satisfied_feature_dependencies());
501const _: () = assert!(FeatureSet::DATABRICKS.has_no_grammar_conflict());
502
503#[cfg(test)]
504mod tests {
505 use super::*;
506
507 #[test]
508 fn databricks_is_ansi_plus_the_six_gates_and_two_lexical_facts() {
509 let ansi = FeatureSet::ANSI;
516 let dbx = FeatureSet::DATABRICKS;
517
518 assert_eq!(dbx.identifier_casing, Casing::Preserve);
520 assert_ne!(dbx.identifier_casing, ansi.identifier_casing);
521 assert_eq!(dbx.identifier_quotes, DATABRICKS_IDENTIFIER_QUOTES);
522 assert_ne!(dbx.identifier_quotes, ansi.identifier_quotes);
523 assert!(!dbx.string_literals.double_quoted_strings);
526 assert!(!dbx.parameters.named_colon);
528
529 assert_eq!(dbx.select_syntax, SelectSyntax::DATABRICKS);
531 assert_ne!(dbx.select_syntax, ansi.select_syntax);
532 assert_eq!(dbx.expression_syntax, ExpressionSyntax::DATABRICKS);
533 assert_ne!(dbx.expression_syntax, ansi.expression_syntax);
534 assert_eq!(dbx.table_expressions, TableExpressionSyntax::DATABRICKS);
535 assert_eq!(dbx.join_syntax, JoinSyntax::DATABRICKS);
536 assert_ne!(dbx.join_syntax, ansi.join_syntax);
537 assert_eq!(dbx.utility_syntax, UtilitySyntax::DATABRICKS);
540 assert_eq!(dbx.show_syntax, ShowSyntax::DATABRICKS);
541 assert_ne!(dbx.show_syntax, ansi.show_syntax);
542 assert!(dbx.show_syntax.show_functions);
543 assert_eq!(
544 ShowSyntax {
545 show_functions: false,
546 ..dbx.show_syntax
547 },
548 ansi.show_syntax,
549 );
550
551 assert_eq!(dbx.reserved_column_name, DATABRICKS_RESERVED_COLUMN_NAME);
553 assert_ne!(dbx.reserved_column_name, ansi.reserved_column_name);
554 assert_eq!(
555 dbx.reserved_function_name,
556 DATABRICKS_RESERVED_FUNCTION_NAME
557 );
558 assert_eq!(dbx.reserved_type_name, DATABRICKS_RESERVED_TYPE_NAME);
559 assert_eq!(dbx.reserved_bare_alias, DATABRICKS_RESERVED_BARE_ALIAS);
560 assert_eq!(
562 dbx.reserved_column_name
563 .difference(DATABRICKS_QUALIFY_RESERVATION),
564 ansi.reserved_column_name,
565 );
566 assert!(dbx.reserved_column_name.contains(Keyword::Qualify));
567 assert!(dbx.reserved_bare_alias.contains(Keyword::Qualify));
568 assert_eq!(dbx.reserved_as_label, KeywordSet::EMPTY);
570
571 assert_eq!(dbx.string_literals, ansi.string_literals);
573 assert_eq!(dbx.numeric_literals, ansi.numeric_literals);
574 assert_eq!(dbx.parameters, ansi.parameters);
575 assert_eq!(dbx.session_variables, ansi.session_variables);
576 assert_eq!(dbx.identifier_syntax, ansi.identifier_syntax);
577 assert_eq!(dbx.operator_syntax, ansi.operator_syntax);
578 assert_eq!(dbx.call_syntax, ansi.call_syntax);
579 assert_eq!(dbx.predicate_syntax, ansi.predicate_syntax);
580 assert_eq!(dbx.mutation_syntax, ansi.mutation_syntax);
581 assert_eq!(dbx.statement_ddl_gates, ansi.statement_ddl_gates);
582 assert_eq!(
583 dbx.create_table_clause_syntax,
584 ansi.create_table_clause_syntax
585 );
586 assert_eq!(dbx.column_definition_syntax, ansi.column_definition_syntax);
587 assert_eq!(dbx.constraint_syntax, ansi.constraint_syntax);
588 assert_eq!(dbx.index_alter_syntax, ansi.index_alter_syntax);
589 assert_eq!(dbx.existence_guards, ansi.existence_guards);
590 assert_eq!(dbx.type_name_syntax, ansi.type_name_syntax);
591 assert_eq!(dbx.byte_classes, ansi.byte_classes);
592 assert_eq!(dbx.binding_powers, ansi.binding_powers);
593 assert_eq!(dbx.target_spelling, ansi.target_spelling);
594 assert_eq!(dbx.default_null_ordering, ansi.default_null_ordering);
595 }
596
597 #[test]
598 fn databricks_enables_exactly_the_six_staged_gates() {
599 let ansi = FeatureSet::ANSI;
604 let dbx = FeatureSet::DATABRICKS;
605
606 assert!(dbx.join_syntax.sided_semi_anti_join);
607 assert!(!ansi.join_syntax.sided_semi_anti_join);
608 assert!(!dbx.join_syntax.semi_anti_join);
610 assert!(dbx.expression_syntax.semi_structured_access);
611 assert!(!ansi.expression_syntax.semi_structured_access);
612 assert!(dbx.select_syntax.qualify && !ansi.select_syntax.qualify);
613 assert!(dbx.grouping_syntax.group_by_all && !ansi.grouping_syntax.group_by_all);
614 assert!(dbx.grouping_syntax.order_by_all && !ansi.grouping_syntax.order_by_all);
616 assert!(dbx.select_syntax.lateral_view_clause && !ansi.select_syntax.lateral_view_clause);
619 assert!(!dbx.table_factor_syntax.lateral);
620
621 assert_eq!(
622 SelectSyntax {
623 qualify: false,
624 lateral_view_clause: false,
625 ..dbx.select_syntax
626 },
627 ansi.select_syntax,
628 );
629 assert_eq!(
630 GroupingSyntax {
631 group_by_all: false,
632 order_by_all: false,
633 ..dbx.grouping_syntax
634 },
635 ansi.grouping_syntax,
636 );
637 assert_eq!(
638 ExpressionSyntax {
639 semi_structured_access: false,
640 ..dbx.expression_syntax
641 },
642 ansi.expression_syntax,
643 );
644 assert_eq!(
645 JoinSyntax {
646 sided_semi_anti_join: false,
647 ..dbx.join_syntax
648 },
649 ansi.join_syntax,
650 );
651 }
652
653 #[test]
654 fn databricks_is_lexically_consistent_and_dependency_clean() {
655 let dbx = FeatureSet::DATABRICKS;
660 assert_eq!(dbx.lexical_conflict(), None);
661 assert!(dbx.is_lexically_consistent());
662 assert_eq!(dbx.feature_dependencies(), None);
663 assert!(dbx.has_satisfied_feature_dependencies());
664 assert_eq!(dbx.grammar_conflict(), None);
665 assert!(dbx.has_no_grammar_conflict());
666 }
667 #[test]
668 fn databricks_closed_delta_axes_match_documented_set() {
669 crate::dialect::closed_delta::assert_closed_delta(
670 &FeatureSet::ANSI,
671 &FeatureSet::DATABRICKS,
672 &[
673 "identifier_casing",
674 "identifier_quotes",
675 "reserved_column_name",
676 "reserved_function_name",
677 "reserved_type_name",
678 "reserved_bare_alias",
679 "table_expressions",
680 "join_syntax",
681 "expression_syntax",
682 "select_syntax",
683 "grouping_syntax",
684 "show_syntax",
685 ],
686 );
687 }
688}