1use std::collections::HashMap;
21
22use rudb_common::{Error, IdentifierCase, Result, Span, Value};
23
24use crate::ast::{
25 Ast, BinaryOp, CaseArm, ColumnDef, CreateTable, CreateView, Cte, Distinct, DropTable, Expr,
26 ExprRef, Insert, JoinKind, LiteralKind, Nulls, Order, OrderItem, Quantifier, Query, QueryBody,
27 QueryRef, Scope, Select, SelectRef, SetOp, Setting, Slice, Source, SourceRef, Statement,
28 StrRef, Target, UnaryOp, WindowBound, WindowExclude, WindowRef, WindowSpec, WindowUnit,
29};
30use crate::generated::rules::PROGRAM;
31use crate::matcher::{NONE, Tree, parse_tokens};
32use crate::token::{Kind, Token};
33use crate::tokenize::tokenize;
34
35pub fn parse_ast(query: &str) -> Result<Ast> {
41 parse_ast_with_case(query, IdentifierCase::Preserve)
42}
43
44pub fn parse_ast_with_case(query: &str, identifier_case: IdentifierCase) -> Result<Ast> {
46 let tokens = tokenize(query)?;
47 let tree = parse_tokens(query, &tokens, PROGRAM, true)?;
48 transform_with_case(query, &tokens, &tree, identifier_case)
49}
50
51pub fn transform(query: &str, tokens: &[Token], tree: &Tree) -> Result<Ast> {
53 transform_with_case(query, tokens, tree, IdentifierCase::Preserve)
54}
55
56pub fn transform_with_case(
58 query: &str,
59 tokens: &[Token],
60 tree: &Tree,
61 identifier_case: IdentifierCase,
62) -> Result<Ast> {
63 let mut transform = Transform {
64 query,
65 tokens,
66 tree,
67 ast: Ast::default(),
68 interned: HashMap::new(),
69 anonymous: 0,
70 identifier_case,
71 current_span: Span::new(0, 0),
72 ctes: Vec::new(),
73 named_windows: Vec::new(),
74 query_depth: 0,
75 };
76 transform.program(tree.root())?;
77 Ok(transform.ast)
78}
79
80fn is_statement(name: &str) -> bool {
93 let folded = name.to_ascii_lowercase();
94 folded.starts_with("enable_")
95 || folded.starts_with("disable_")
96 || folded == "force_checkpoint"
97 || folded == "verify_parallelism"
98}
99
100struct Transform<'a> {
101 query: &'a str,
102 tokens: &'a [Token],
103 tree: &'a Tree,
104 ast: Ast,
105 interned: HashMap<String, StrRef>,
106 anonymous: u32,
108 identifier_case: IdentifierCase,
109 current_span: Span,
110 ctes: Vec<(StrRef, Held, Slice)>,
118 named_windows: Vec<(StrRef, WindowRef, bool)>,
125 query_depth: usize,
132}
133
134#[derive(Debug, Clone, Copy)]
136enum Held {
137 Inline(QueryRef),
139 Once(u32),
141}
142
143impl<'a> Transform<'a> {
144 fn text(&self, node: u32) -> &'a str {
148 self.tree.text(node, self.query, self.tokens)
149 }
150
151 fn span(&self, node: u32) -> Span {
153 let parsed = self.tree.node(node);
154 if parsed.start >= parsed.end {
155 let at = self
156 .tokens
157 .get(parsed.start as usize)
158 .map_or(self.query.len() as u32, |token| token.start);
159 return Span::new(at, at);
160 }
161 let first = self.tokens[parsed.start as usize];
162 let last = self.tokens[parsed.end as usize - 1];
163 Span::new(first.start, last.end)
164 }
165
166 fn name(&self, node: u32) -> &'static str {
168 self.tree.name(node)
169 }
170
171 fn kids(&self, node: u32) -> impl Iterator<Item = u32> + use<'a> {
177 let tree = self.tree;
178 tree.children(node)
179 }
180
181 fn count(&self, node: u32) -> usize {
183 self.kids(node).count()
184 }
185
186 fn nth(&self, node: u32, n: usize) -> u32 {
188 self.kids(node).nth(n).unwrap_or(NONE)
189 }
190
191 fn first(&self, node: u32) -> u32 {
193 self.nth(node, 0)
194 }
195
196 fn find(&self, node: u32, name: &str) -> u32 {
203 self.kids(node).find(|&kid| self.name(kid) == name).unwrap_or(NONE)
204 }
205
206 fn descendant(&self, node: u32, name: &str) -> u32 {
208 if self.name(node) == name {
209 return node;
210 }
211 self.kids(node)
212 .map(|kid| self.descendant(kid, name))
213 .find(|&found| found != NONE)
214 .unwrap_or(NONE)
215 }
216
217 fn contains(&self, node: u32, name: &str) -> bool {
219 self.name(node) == name || self.kids(node).any(|kid| self.contains(kid, name))
220 }
221
222 fn leaves(&self, node: u32, out: &mut Vec<u32>) {
229 let mut any = false;
230 for kid in self.kids(node) {
231 any = true;
232 self.leaves(kid, &mut *out);
233 }
234 if !any {
235 out.push(node);
236 }
237 }
238
239 fn intern(&mut self, text: &str) -> StrRef {
243 if let Some(&index) = self.interned.get(text) {
244 return index;
245 }
246 let index = u32::try_from(self.ast.strings.len())
247 .map_err(|_| Error::internal("more than four billion strings in one query"))
248 .unwrap_or(NONE);
249 self.ast.strings.push(text.to_string());
250 self.interned.insert(text.to_string(), index);
251 index
252 }
253
254 fn push(&mut self, expr: Expr) -> ExprRef {
256 let index = self.ast.exprs.len() as u32;
257 self.ast.exprs.push(expr);
258 self.ast.expr_spans.push(self.current_span);
259 index
260 }
261
262 fn push_source(&mut self, source: Source) -> SourceRef {
264 let index = self.ast.sources.len() as u32;
265 self.ast.sources.push(source);
266 index
267 }
268
269 fn push_query(&mut self, query: Query) -> QueryRef {
271 let index = self.ast.queries.len() as u32;
272 self.ast.queries.push(query);
273 self.ast.query_spans.push(self.current_span);
274 index
275 }
276
277 fn push_select(&mut self, select: Select) -> SelectRef {
279 let index = self.ast.selects.len() as u32;
280 self.ast.selects.push(select);
281 index
282 }
283
284 fn push_window(&mut self, spec: WindowSpec) -> WindowRef {
286 let index = self.ast.windows.len() as u32;
287 self.ast.windows.push(spec);
288 index
289 }
290
291 fn order_slice(&mut self, items: Vec<OrderItem>) -> Slice {
293 let start = self.ast.order_items.len() as u32;
294 self.ast.order_items.extend(items);
295 Slice { start, len: self.ast.order_items.len() as u32 - start }
296 }
297
298 fn expr_slice(&mut self, items: Vec<ExprRef>) -> Slice {
300 let start = self.ast.expr_lists.len() as u32;
301 self.ast.expr_lists.extend(items);
302 Slice { start, len: self.ast.expr_lists.len() as u32 - start }
303 }
304
305 fn part_slice(&mut self, items: Vec<StrRef>) -> Slice {
307 let start = self.ast.parts.len() as u32;
308 self.ast.parts.extend(items);
309 Slice { start, len: self.ast.parts.len() as u32 - start }
310 }
311
312 fn cte_slice(&mut self, items: Vec<u32>) -> Slice {
314 let start = self.ast.cte_lists.len() as u32;
315 self.ast.cte_lists.extend(items);
316 Slice { start, len: self.ast.cte_lists.len() as u32 - start }
317 }
318
319 fn column_def_slice(&mut self, items: Vec<ColumnDef>) -> Slice {
321 let start = self.ast.column_defs.len() as u32;
322 self.ast.column_defs.extend(items);
323 Slice { start, len: self.ast.column_defs.len() as u32 - start }
324 }
325
326 fn target_slice(&mut self, items: Vec<Target>) -> Slice {
328 let start = self.ast.targets.len() as u32;
329 self.ast.targets.extend(items);
330 Slice { start, len: self.ast.targets.len() as u32 - start }
331 }
332
333 fn name_list_slice(&mut self, items: Vec<Slice>) -> Slice {
335 let start = self.ast.name_lists.len() as u32;
336 self.ast.name_lists.extend(items);
337 Slice { start, len: self.ast.name_lists.len() as u32 - start }
338 }
339
340 fn unsupported<T>(&self, node: u32) -> Result<T> {
345 let text = self.text(node);
346 let text = if text.chars().count() > 60 {
347 let cut = text.char_indices().nth(60).map_or(text.len(), |(at, _)| at);
348 format!("{}...", &text[..cut])
349 } else {
350 text.to_string()
351 };
352 Err(Error::not_implemented(format!(
353 "{text} is not supported yet, the grammar rule is {}",
354 self.name(node)
355 )))
356 }
357
358 fn identifier(&mut self, node: u32) -> StrRef {
362 let mut leaves = Vec::new();
363 self.leaves(node, &mut leaves);
364 let text = leaves.last().map_or("", |&leaf| self.text(leaf));
365 let text = self.fold_identifier(text.strip_suffix('.').unwrap_or(text));
366 self.intern(&text)
367 }
368
369 fn bare_name(&self, node: u32) -> Option<String> {
375 let mut leaves = Vec::new();
376 self.leaves(node, &mut leaves);
377 let mut parts = leaves
378 .iter()
379 .map(|&leaf| self.text(leaf))
380 .filter(|text| !text.is_empty() && *text != "*");
381 let only = parts.next()?;
382 if parts.next().is_some() {
383 return None;
384 }
385 Some(self.fold_identifier(only.strip_suffix('.').unwrap_or(only)))
386 }
387
388 fn name_parts(&mut self, node: u32) -> Slice {
390 let mut leaves = Vec::new();
391 self.leaves(node, &mut leaves);
392 let mut parts = Vec::with_capacity(leaves.len());
393 for leaf in leaves {
394 let text = self.text(leaf);
395 if text.is_empty() || text == "*" {
398 continue;
399 }
400 let text = self.fold_identifier(text.strip_suffix('.').unwrap_or(text));
401 let interned = self.intern(&text);
402 parts.push(interned);
403 }
404 self.part_slice(parts)
405 }
406
407 fn fold_identifier(&self, text: &str) -> String {
408 if text.starts_with(['"', '\'']) {
409 return unquote(text);
410 }
411 match self.identifier_case {
412 IdentifierCase::Preserve => text.to_string(),
413 IdentifierCase::Lower => text.to_ascii_lowercase(),
414 IdentifierCase::Upper => text.to_ascii_uppercase(),
415 }
416 }
417
418 fn program(&mut self, node: u32) -> Result<()> {
422 for top in self.kids(node) {
423 let Some(statement) = self.kids(top).find(|&kid| self.name(kid) == "Statement") else {
428 continue;
429 };
430 let statement = self.statement(statement)?;
431 self.ast.statements.push(statement);
432 }
433 Ok(())
434 }
435
436 fn statement(&mut self, node: u32) -> Result<Statement> {
438 let inner = self.first(node);
439 match self.name(inner) {
440 "SelectStatement" => {
441 let query = self.query(self.first(inner))?;
442 Ok(Statement::Query(query))
443 }
444 "CreateStatement" => self.create_statement(inner),
445 "DropStatement" => self.drop_statement(inner),
446 "InsertStatement" => self.insert_statement(inner),
447 "SetStatement" => self.set_statement(inner),
448 "ResetStatement" => self.reset_statement(inner),
449 "PragmaStatement" => self.pragma_statement(inner),
450 "ExplainStatement" => self.explain_statement(inner),
451 "CheckpointStatement" => Ok(Statement::Checkpoint),
452 _ => self.unsupported(inner),
453 }
454 }
455
456 fn explain_statement(&mut self, node: u32) -> Result<Statement> {
477 let mut analyze = self.find(node, "AnalyzeKeyword") != NONE;
478 let mut statistics = false;
479 let list = self.find(node, "ExplainOptionList");
480 if list != NONE {
481 for option in self.kids(list).filter(|&kid| self.name(kid) == "ExplainOption") {
482 let name = self.text(self.find(option, "ExplainOptionName"));
483 match name.to_ascii_lowercase().as_str() {
484 "analyze" => analyze = true,
485 "logical" => {}
486 "statistics" => statistics = true,
487 lowered => {
488 return Err(Error::not_implemented(format!(
489 "Unimplemented explain type: {lowered}"
490 )));
491 }
492 }
493 if self.count(option) != 1 {
498 return self.unsupported(option);
499 }
500 }
501 }
502 let inner = self.first(self.find(node, "ExplainableStatements"));
503 if self.name(inner) != "ExplainSelectStatement" {
504 return self.unsupported(inner);
505 }
506 let query = self.query(self.find(inner, "SelectStatementInternal"))?;
507 Ok(Statement::Explain { query, analyze, statistics })
508 }
509
510 fn set_statement(&mut self, node: u32) -> Result<Statement> {
517 let inner = self.first(self.find(node, "SetAssignmentOrTimeZone"));
518 if self.name(inner) == "SetTimeZone" {
519 return self.set_time_zone(inner);
520 }
521 if self.name(inner) != "StandardAssignment" {
522 return self.unsupported(inner);
523 }
524 let (name, scope) = self.setting_name(self.find(inner, "SetVariableOrSetting"))?;
525 let assignment = self.find(inner, "SetAssignment");
526 let list = self.find(assignment, "VariableList");
527 let kids: Vec<u32> = self.kids(list).collect();
528 if kids.len() == 1 && self.contains(list, "DefaultExpression") {
529 let index = self.ast.settings.len() as u32;
530 self.ast.settings.push(Setting { name, scope, value: NONE, pragma: false });
531 return Ok(Statement::Reset(index));
532 }
533 let mut values = Vec::new();
534 for kid in kids {
535 values.push(self.expr(kid)?);
536 }
537 let [value] = values[..] else {
541 return self.unsupported(list);
542 };
543 let index = self.ast.settings.len() as u32;
544 self.ast.settings.push(Setting { name, scope, value, pragma: false });
545 Ok(Statement::Set(index))
546 }
547
548 fn set_time_zone(&mut self, node: u32) -> Result<Statement> {
550 let zone = self.first(self.find(node, "ZoneValue"));
551 let name = self.intern("TimeZone");
552 if matches!(self.name(zone), "ZoneDefault" | "ZoneLocal") {
553 let index = self.ast.settings.len() as u32;
554 self.ast.settings.push(Setting {
555 name,
556 scope: Scope::Unwritten,
557 value: NONE,
558 pragma: false,
559 });
560 return Ok(Statement::Reset(index));
561 }
562 let text = match self.name(zone) {
563 "ZoneStringLiteral" => self.string_value(self.find(zone, "StringLiteral"))?,
564 "ZoneIdentifier" => {
565 let identifier = self.find(zone, "Identifier");
566 let identifier = self.identifier(identifier);
567 self.ast.string(identifier).to_string()
568 }
569 _ => return self.unsupported(zone),
570 };
571 let text = self.intern(&text);
572 let value = self.push(Expr::Literal { kind: LiteralKind::String, text });
573 let index = self.ast.settings.len() as u32;
574 self.ast.settings.push(Setting { name, scope: Scope::Unwritten, value, pragma: false });
575 Ok(Statement::Set(index))
576 }
577
578 fn reset_statement(&mut self, node: u32) -> Result<Statement> {
580 let (name, scope) = self.setting_name(self.find(node, "SetVariableOrSetting"))?;
581 let index = self.ast.settings.len() as u32;
582 self.ast.settings.push(Setting { name, scope, value: NONE, pragma: false });
583 Ok(Statement::Reset(index))
584 }
585
586 fn pragma_statement(&mut self, node: u32) -> Result<Statement> {
599 let inner = self.first(self.find(node, "PragmaAssignOrFunction"));
600 match self.name(inner) {
601 "PragmaAssign" => self.pragma_assign(inner),
602 "PragmaFunction" => self.pragma_function(inner),
603 _ => self.unsupported(inner),
604 }
605 }
606
607 fn pragma_assign(&mut self, node: u32) -> Result<Statement> {
609 let name = self.identifier(self.find(node, "SettingName"));
610 let list = self.find(node, "VariableList");
611 let mut values = Vec::new();
612 for kid in self.kids(list) {
613 values.push(self.expr(kid)?);
614 }
615 let [value] = values[..] else {
618 return self.unsupported(list);
619 };
620 let index = self.ast.settings.len() as u32;
621 self.ast.settings.push(Setting { name, scope: Scope::Unwritten, value, pragma: false });
622 Ok(Statement::Set(index))
623 }
624
625 fn pragma_function(&mut self, node: u32) -> Result<Statement> {
641 let interned = self.identifier(self.find(node, "PragmaName"));
642 let written = self.ast.string(interned).to_string();
643 let parameters = self.find(node, "PragmaParameters");
646 if parameters == NONE && is_statement(&written) {
647 let index = self.ast.settings.len() as u32;
648 self.ast.settings.push(Setting {
649 name: interned,
650 scope: Scope::Unwritten,
651 value: NONE,
652 pragma: true,
653 });
654 return Ok(Statement::Set(index));
655 }
656 let part = self.intern(&format!("pragma_{written}"));
657 let name = self.part_slice(vec![part]);
658 let mut args = Vec::new();
659 if parameters != NONE {
660 for kid in self.kids(parameters) {
661 let expr = self.expr(kid)?;
662 args.push(Target { expr: self.quoted(expr), alias: NONE });
663 }
664 }
665 let args = self.target_slice(args);
666 let source = self.push_source(Source::Function {
667 name,
668 args,
669 alias: NONE,
670 columns: Slice::default(),
671 pragma: true,
672 });
673 Ok(Statement::Query(self.star_over(source)))
674 }
675
676 fn quoted(&mut self, expr: ExprRef) -> ExprRef {
683 let Expr::Column { name } = self.ast.exprs[expr as usize] else {
684 return expr;
685 };
686 let written: Vec<&str> = self.ast.name(name).collect();
687 let joined = written.join(".");
688 let text = self.intern(&joined);
689 self.push(Expr::Literal { kind: LiteralKind::String, text })
690 }
691
692 fn setting_name(&mut self, node: u32) -> Result<(StrRef, Scope)> {
698 let inner = self.first(node);
699 if self.name(inner) != "SetSetting" {
700 return self.unsupported(inner);
701 }
702 let written = self.find(inner, "SettingScope");
703 let scope = if written == NONE {
704 Scope::Unwritten
705 } else {
706 match self.name(self.first(written)) {
707 "GlobalScope" => Scope::Global,
708 "SessionScope" => Scope::Session,
709 "LocalScope" => Scope::Local,
710 _ => return self.unsupported(written),
711 }
712 };
713 Ok((self.identifier(self.find(inner, "SettingName")), scope))
714 }
715
716 fn create_statement(&mut self, node: u32) -> Result<Statement> {
722 let or_replace = self.find(node, "OrReplace") != NONE;
723 let temporary = self.find(node, "Temporary") != NONE;
724 let variation = self.find(node, "CreateStatementVariation");
725 let inner = self.first(variation);
726 if or_replace && self.find(inner, "IfNotExists") != NONE {
730 return Err(Error::parser(
731 "Cannot specify both OR REPLACE and IF NOT EXISTS within single create statement",
732 ));
733 }
734 match self.name(inner) {
735 "CreateTableStmt" => self.create_table_statement(inner, or_replace, temporary),
736 "CreateViewStmt" => self.create_view_statement(inner, or_replace, temporary),
737 _ => self.unsupported(inner),
738 }
739 }
740
741 fn create_table_statement(
743 &mut self,
744 inner: u32,
745 or_replace: bool,
746 temporary: bool,
747 ) -> Result<Statement> {
748 let name = self.name_parts(self.find(inner, "QualifiedName"));
749 let if_not_exists = self.find(inner, "IfNotExists") != NONE;
750 let definition = self.find(inner, "CreateTableDefinition");
751 let body = self.first(definition);
752 let (columns, query) = match self.name(body) {
753 "CreateColumnList" => (self.column_list(body)?, NONE),
754 "CreateTableAs" => self.create_table_as(body)?,
755 _ => return self.unsupported(body),
756 };
757 let index = self.ast.create_tables.len() as u32;
758 self.ast.create_tables.push(CreateTable {
759 name,
760 columns,
761 query,
762 if_not_exists,
763 or_replace,
764 temporary,
765 });
766 Ok(Statement::CreateTable(index))
767 }
768
769 fn create_view_statement(
776 &mut self,
777 inner: u32,
778 or_replace: bool,
779 temporary: bool,
780 ) -> Result<Statement> {
781 for kid in self.kids(inner) {
782 if matches!(self.name(kid), "CreateSecure" | "CreateRecursive" | "WithList") {
786 return self.unsupported(kid);
787 }
788 }
789 let name = self.name_parts(self.find(inner, "QualifiedName"));
790 let if_not_exists = self.find(inner, "IfNotExists") != NONE;
791 let list = self.find(inner, "InsertColumnList");
792 let columns = if list == NONE {
793 Slice::default()
794 } else {
795 let mut parts = Vec::new();
796 for kid in self.kids(self.find(list, "ColumnList")) {
797 parts.push(self.identifier(kid));
798 }
799 self.part_slice(parts)
800 };
801 let body = self.find(inner, "SelectStatementInternal");
802 let sql = self.text(body).to_string();
803 let sql = self.intern(&sql);
804 let query = self.query(body)?;
805 let index = self.ast.create_views.len() as u32;
806 self.ast.create_views.push(CreateView {
807 name,
808 columns,
809 query,
810 sql,
811 if_not_exists,
812 or_replace,
813 temporary,
814 });
815 Ok(Statement::CreateView(index))
816 }
817
818 fn column_list(&mut self, node: u32) -> Result<Slice> {
820 for kid in self.kids(node) {
821 if matches!(self.name(kid), "PartitionOptions" | "SortedOptions" | "WithList") {
822 return self.unsupported(kid);
823 }
824 }
825 let list = self.find(node, "CreateTableColumnList");
826 if list == NONE {
827 return Ok(Slice::default());
830 }
831 let mut defs = Vec::new();
832 for element in self.kids(list) {
833 let inner = self.first(element);
834 if self.name(inner) != "CreateTableColumnDefinition" {
835 return self.unsupported(inner);
839 }
840 defs.push(self.column_definition(self.first(inner))?);
841 }
842 Ok(self.column_def_slice(defs))
843 }
844
845 fn column_definition(&mut self, node: u32) -> Result<ColumnDef> {
848 let name = self.identifier(self.find(node, "DottedIdentifier"));
849 let type_node = self.find(node, "Type");
850 let ty = if type_node == NONE {
851 NONE
852 } else {
853 let text = self.text(type_node).to_string();
854 self.intern(&text)
855 };
856 if self.find(node, "GeneratedColumn") != NONE {
857 return self.unsupported(self.find(node, "GeneratedColumn"));
858 }
859 let mut not_null = false;
860 for kid in self.kids(node) {
861 if self.name(kid) != "ColumnConstraint" {
862 continue;
863 }
864 let constraint = self.first(kid);
865 match self.name(constraint) {
866 "NotNullConstraint" => {
867 not_null = self.name(self.first(constraint)) == "NotNullColumnConstraint";
868 }
869 _ => return self.unsupported(constraint),
870 }
871 }
872 Ok(ColumnDef { name, ty, not_null })
873 }
874
875 fn create_table_as(&mut self, node: u32) -> Result<(Slice, QueryRef)> {
881 for kid in self.kids(node) {
882 if matches!(
883 self.name(kid),
884 "PartitionOptions" | "SortedOptions" | "WithList" | "WithData"
885 ) {
886 return self.unsupported(kid);
887 }
888 }
889 let names = self.find(node, "IdentifierList");
890 let columns = if names == NONE {
891 Slice::default()
892 } else {
893 let mut defs = Vec::new();
894 for kid in self.kids(names) {
895 let name = self.identifier(kid);
896 defs.push(ColumnDef { name, ty: NONE, not_null: false });
897 }
898 self.column_def_slice(defs)
899 };
900 let statement = self.find(node, "Statement");
901 let inner = self.first(statement);
902 if self.name(inner) != "SelectStatement" {
903 return self.unsupported(inner);
904 }
905 let query = self.query(self.first(inner))?;
906 Ok((columns, query))
907 }
908
909 fn drop_statement(&mut self, node: u32) -> Result<Statement> {
915 if self.find(node, "DropBehavior") != NONE {
916 return self.unsupported(self.find(node, "DropBehavior"));
917 }
918 let entries = self.find(node, "DropEntries");
919 let inner = self.first(entries);
920 if self.name(inner) != "DropTable" {
921 return self.unsupported(inner);
922 }
923 let kind = self.find(inner, "TableOrView");
924 let view = match self.name(self.first(kind)) {
925 "CommentTable" => false,
926 "CommentView" => true,
927 _ => return self.unsupported(kind),
928 };
929 let if_exists = self.find(inner, "IfExists") != NONE;
930 let mut names = Vec::new();
931 for kid in self.kids(inner) {
932 if self.name(kid) == "BaseTableName" {
933 names.push(self.name_parts(kid));
934 }
935 }
936 let names = self.name_list_slice(names);
937 let index = self.ast.drop_tables.len() as u32;
938 self.ast.drop_tables.push(DropTable { names, if_exists, view });
939 Ok(Statement::DropTable(index))
940 }
941
942 fn insert_statement(&mut self, node: u32) -> Result<Statement> {
949 for kid in self.kids(node) {
950 if matches!(
951 self.name(kid),
952 "InsertTarget" | "InsertColumnList" | "InsertValues" | "WithClause"
953 ) {
954 continue;
955 }
956 return self.unsupported(kid);
957 }
958 if self.find(node, "WithClause") != NONE {
959 return self.unsupported(self.find(node, "WithClause"));
960 }
961 let name = self.name_parts(self.find(self.find(node, "InsertTarget"), "BaseTableName"));
962 let list = self.find(node, "InsertColumnList");
963 let columns = if list == NONE {
964 Slice::default()
965 } else {
966 let mut parts = Vec::new();
967 for kid in self.kids(self.find(list, "ColumnList")) {
968 parts.push(self.identifier(kid));
969 }
970 self.part_slice(parts)
971 };
972 let values = self.find(node, "InsertValues");
973 let inner = self.first(values);
974 if self.name(inner) != "SelectInsertValues" {
975 return self.unsupported(inner);
976 }
977 let source = self.query(self.find(inner, "SelectStatementInternal"))?;
978 let index = self.ast.inserts.len() as u32;
979 self.ast.inserts.push(Insert { name, columns, source });
980 Ok(Statement::Insert(index))
981 }
982
983 fn query(&mut self, node: u32) -> Result<QueryRef> {
985 let span = self.span(node);
986 let outer = std::mem::replace(&mut self.current_span, span);
987 self.query_depth += 1;
992 let result = self.query_inner(node);
993 self.query_depth -= 1;
994 self.current_span = outer;
995 result
996 }
997
998 fn query_inner(&mut self, node: u32) -> Result<QueryRef> {
999 let mark = self.ctes.len();
1000 let mut once = Vec::new();
1001 let with = self.find(node, "WithClause");
1002 if with != NONE {
1003 if self.find(with, "Recursive") != NONE {
1004 return self.unsupported(self.find(with, "Recursive"));
1005 }
1006 let written: Vec<u32> =
1007 self.kids(with).filter(|&kid| self.name(kid) == "WithStatement").collect();
1008 for (at, &statement) in written.iter().enumerate() {
1009 let word = self.find(statement, "Materialized");
1025 let asked =
1026 word != NONE && !self.text(word).eq_ignore_ascii_case("NOT MATERIALIZED");
1027 let refused = word != NONE && !asked;
1028 let name = self.identifier(self.first(statement));
1029 let materialized =
1030 asked || (!refused && self.worth_holding(node, &written[..=at], name));
1031 let list = self.find(statement, "InsertColumnList");
1032 let columns = if list == NONE {
1033 Slice::default()
1034 } else {
1035 let mut names = Vec::new();
1036 for kid in self.kids(self.find(list, "ColumnList")) {
1037 names.push(self.identifier(kid));
1038 }
1039 self.part_slice(names)
1040 };
1041 let body = self.find(statement, "CTEBody");
1042 let select = self.first(body);
1043 if self.name(select) != "CTESelectBody" {
1044 return self.unsupported(body);
1045 }
1046 let query = self.query(self.first(select))?;
1047 if materialized {
1048 let index = self.ast.ctes.len() as u32;
1049 self.ast.ctes.push(Cte { name, query, columns });
1050 once.push(index);
1051 self.ctes.push((name, Held::Once(index), columns));
1052 } else {
1053 self.ctes.push((name, Held::Inline(query), columns));
1054 }
1055 }
1056 }
1057 let chain = self.find(node, "SelectSetOpChain");
1058 if chain == NONE {
1059 return self.unsupported(node);
1060 }
1061 let query = self.set_op_chain(chain)?;
1062 let modifiers = self.find(node, "ResultModifiers");
1063 if modifiers != NONE {
1064 self.result_modifiers(query, modifiers)?;
1065 }
1066 if !once.is_empty() {
1067 let slice = self.cte_slice(once);
1068 self.ast.queries[query as usize].ctes = slice;
1069 }
1070 self.ctes.truncate(mark);
1071 Ok(query)
1072 }
1073
1074 fn worth_holding(&self, query: u32, held: &[u32], name: StrRef) -> bool {
1094 if self.query_depth != 1 {
1095 return false;
1096 }
1097 let name = self.ast.string(name);
1098 if self.redefines(query, name, held) {
1103 return false;
1104 }
1105 let mut seen = 0;
1106 self.counts_reads(query, name, held, &mut seen);
1107 seen > 1
1108 }
1109
1110 fn counts_reads(&self, at: u32, name: &str, held: &[u32], seen: &mut usize) {
1112 if held.contains(&at) {
1113 return;
1114 }
1115 if self.name(at) == "BaseTableName"
1116 && self.bare_name(at).is_some_and(|read| read.eq_ignore_ascii_case(name))
1117 {
1118 *seen += 1;
1119 }
1120 for kid in self.kids(at) {
1121 self.counts_reads(kid, name, held, seen);
1122 }
1123 }
1124
1125 fn redefines(&self, at: u32, name: &str, held: &[u32]) -> bool {
1127 if held.contains(&at) {
1128 return false;
1129 }
1130 if self.name(at) == "WithStatement"
1131 && self
1132 .bare_name(self.first(at))
1133 .is_some_and(|written| written.eq_ignore_ascii_case(name))
1134 {
1135 return true;
1136 }
1137 self.kids(at).any(|kid| self.redefines(kid, name, held))
1138 }
1139
1140 fn set_op_chain(&mut self, node: u32) -> Result<QueryRef> {
1142 let mut kids = self.kids(node);
1143 let head = kids.next().unwrap_or(NONE);
1144 let mut left = self.intersect_chain(head)?;
1145 for tail in kids {
1146 let clause = self.first(tail);
1148 let (op, quantifier, by_name) = self.setop_clause(clause)?;
1149 let right = self.intersect_chain(self.nth(tail, 1))?;
1150 left = self.push_query(Query::bare(QueryBody::SetOp {
1151 op,
1152 quantifier,
1153 by_name,
1154 left,
1155 right,
1156 }));
1157 }
1158 Ok(left)
1159 }
1160
1161 fn intersect_chain(&mut self, node: u32) -> Result<QueryRef> {
1163 let mut kids = self.kids(node);
1164 let head = kids.next().unwrap_or(NONE);
1165 let mut left = self.select_atom(head)?;
1166 for tail in kids {
1167 let clause = self.first(tail);
1169 let quantifier = self.quantifier(self.find(clause, "DistinctOrAll"));
1170 let right = self.select_atom(self.nth(tail, 1))?;
1171 left = self.push_query(Query::bare(QueryBody::SetOp {
1172 op: SetOp::Intersect,
1173 quantifier,
1174 by_name: false,
1175 left,
1176 right,
1177 }));
1178 }
1179 Ok(left)
1180 }
1181
1182 fn setop_clause(&mut self, node: u32) -> Result<(SetOp, Quantifier, bool)> {
1184 let kind = self.find(node, "SetopType");
1185 let op = match self.name(self.first(kind)) {
1186 "SetopUnion" => SetOp::Union,
1187 "SetopExcept" => SetOp::Except,
1188 _ => return self.unsupported(kind),
1189 };
1190 let quantifier = self.quantifier(self.find(node, "DistinctOrAll"));
1191 let by_name = self.find(node, "ByName") != NONE;
1192 if by_name && op == SetOp::Except {
1197 return Err(Error::parser("Invalid combination of EXCEPT and BY NAME"));
1198 }
1199 Ok((op, quantifier, by_name))
1200 }
1201
1202 fn quantifier(&self, node: u32) -> Quantifier {
1204 if node == NONE {
1205 return Quantifier::Unstated;
1206 }
1207 match self.name(self.first(node)) {
1208 "DistinctKeyword" => Quantifier::Distinct,
1209 "AllKeyword" => Quantifier::All,
1210 _ => Quantifier::Unstated,
1211 }
1212 }
1213
1214 fn select_atom(&mut self, node: u32) -> Result<QueryRef> {
1216 let inner = self.first(node);
1217 match self.name(inner) {
1218 "SelectParens" => self.query(self.first(inner)),
1221 "SelectStatementType" => {
1222 let kind = self.first(inner);
1223 match self.name(kind) {
1224 "OptionalParensSimpleSelect" => {
1225 let select = self.simple_select(self.unwrap_parens(kind))?;
1226 Ok(self.push_query(Query::bare(QueryBody::Select(select))))
1227 }
1228 "ValuesClause" => {
1229 let rows = self.values_clause(kind)?;
1230 Ok(self.push_query(Query::bare(QueryBody::Values(rows))))
1231 }
1232 "DescribeStatement" => self.describe_statement(kind),
1233 _ => self.unsupported(kind),
1234 }
1235 }
1236 _ => self.unsupported(inner),
1237 }
1238 }
1239
1240 fn describe_statement(&mut self, node: u32) -> Result<QueryRef> {
1253 let inner = self.first(node);
1254 match self.name(inner) {
1255 "DescribeSelect" => {
1256 self.describe_and_not_summarize(inner)?;
1257 let query = self.query(self.find(inner, "SelectStatementInternal"))?;
1258 Ok(self.push_query(Query::bare(QueryBody::Describe(query))))
1259 }
1260 "DescribeByName" => {
1261 self.describe_and_not_summarize(inner)?;
1262 let target = self.find(inner, "DescribeTarget");
1263 if target == NONE {
1264 return self.unsupported(inner);
1265 }
1266 let name = self.name_parts(target);
1267 if let Some(query) = self.special_form(name) {
1268 return Ok(query);
1269 }
1270 let source = self.describe_target(target)?;
1271 let query = self.star_over(source);
1272 Ok(self.push_query(Query::bare(QueryBody::Describe(query))))
1273 }
1274 "ShowAllTables" => Ok(self.pragma_query("pragma_show_tables_expanded")),
1275 "ShowByName" => {
1276 let target = self.find(inner, "ShowTarget");
1277 if target == NONE {
1278 return self.unsupported(inner);
1279 }
1280 let name = self.name_parts(target);
1281 if let Some(query) = self.special_form(name) {
1282 return Ok(query);
1283 }
1284 let source = self.push_source(Source::Table {
1285 name,
1286 alias: NONE,
1287 columns: Slice::default(),
1288 });
1289 let relation = self.star_over(source);
1290 Ok(self.push_query(Query::bare(QueryBody::Show { name, relation })))
1291 }
1292 _ => self.unsupported(inner),
1293 }
1294 }
1295
1296 fn special_form(&mut self, name: Slice) -> Option<QueryRef> {
1303 if name.len != 1 {
1304 return None;
1305 }
1306 let written = self.ast.name_text(name);
1307 let pragma = match written.to_ascii_lowercase().as_str() {
1308 "tables" => "pragma_show_tables",
1309 "databases" => "pragma_show_databases",
1310 _ => return None,
1311 };
1312 Some(self.pragma_query(pragma))
1313 }
1314
1315 fn pragma_query(&mut self, pragma: &str) -> QueryRef {
1320 let part = self.intern(pragma);
1321 let name = self.part_slice(vec![part]);
1322 let args = self.target_slice(Vec::new());
1323 let source = self.push_source(Source::Function {
1324 name,
1325 args,
1326 alias: NONE,
1327 columns: Slice::default(),
1328 pragma: true,
1329 });
1330 self.star_over(source)
1331 }
1332
1333 fn describe_and_not_summarize(&mut self, node: u32) -> Result<()> {
1335 let word = self.find(node, "DescribeOrSummarize");
1336 if word == NONE || self.name(self.first(word)) != "DescribeRule" {
1337 return self.unsupported(if word == NONE { node } else { word });
1338 }
1339 Ok(())
1340 }
1341
1342 fn describe_target(&mut self, node: u32) -> Result<SourceRef> {
1348 let inner = self.first(node);
1349 let name = match self.name(inner) {
1350 "DescribeBaseTableName" => self.name_parts(self.find(inner, "BaseTableName")),
1351 "DescribeStringLiteral" => {
1352 let text = self.string_value(self.find(inner, "StringLiteral"))?;
1353 let part = self.intern(&text);
1354 self.part_slice(vec![part])
1355 }
1356 _ => return self.unsupported(inner),
1357 };
1358 Ok(self.push_source(Source::Table { name, alias: NONE, columns: Slice::default() }))
1359 }
1360
1361 fn star_over(&mut self, source: SourceRef) -> QueryRef {
1363 let star =
1364 self.push(Expr::Star { qualifier: Slice::default(), replacements: Slice::default() });
1365 let targets = self.target_slice(vec![Target { expr: star, alias: NONE }]);
1366 let start = self.ast.source_lists.len() as u32;
1367 self.ast.source_lists.push(source);
1368 let from = Slice { start, len: 1 };
1369 let select = self.push_select(Select { targets, from, ..Select::empty() });
1370 self.push_query(Query::bare(QueryBody::Select(select)))
1371 }
1372
1373 fn values_clause(&mut self, node: u32) -> Result<Slice> {
1379 let mut rows = Vec::new();
1380 for kid in self.kids(node) {
1381 if self.name(kid) != "ValuesExpressions" {
1382 continue;
1383 }
1384 let mut items = Vec::new();
1385 for expr in self.kids(kid) {
1386 items.push(self.expr(expr)?);
1387 }
1388 let slice = self.expr_slice(items);
1389 rows.push(slice);
1390 }
1391 let start = self.ast.rows.len() as u32;
1392 self.ast.rows.extend(rows);
1393 Ok(Slice { start, len: self.ast.rows.len() as u32 - start })
1394 }
1395
1396 fn unwrap_parens(&self, node: u32) -> u32 {
1398 let mut node = self.first(node);
1399 while self.name(node) == "SimpleSelectParens" {
1400 node = self.first(node);
1401 }
1402 node
1403 }
1404
1405 fn result_modifiers(&mut self, query: QueryRef, node: u32) -> Result<()> {
1407 let order = self.find(node, "OrderByClause");
1408 if order != NONE {
1409 let (items, all) = self.order_by(order)?;
1410 self.ast.queries[query as usize].order_by = self.order_slice(items);
1411 self.ast.queries[query as usize].order_by_all = all;
1412 }
1413 let limit = self.find(node, "LimitOffset");
1414 if limit != NONE {
1415 self.limit_offset(query, self.first(limit))?;
1416 }
1417 Ok(())
1418 }
1419
1420 fn limit_offset(&mut self, query: QueryRef, node: u32) -> Result<()> {
1422 match self.name(node) {
1423 "LimitOffsetClause" | "OffsetLimitClause" => {
1424 let limit = self.find(node, "LimitClause");
1425 if limit != NONE {
1426 self.limit(query, limit)?;
1427 }
1428 let offset = self.find(node, "OffsetClause");
1429 if offset != NONE {
1430 self.offset(query, offset)?;
1431 }
1432 Ok(())
1433 }
1434 _ => self.unsupported(node),
1435 }
1436 }
1437
1438 fn limit(&mut self, query: QueryRef, node: u32) -> Result<()> {
1440 let value = self.first(node);
1441 let inner = self.first(value);
1442 match self.name(inner) {
1443 "LimitAll" => Ok(()),
1445 "LimitExpression" => {
1449 let expr = self.expr(self.first(inner))?;
1450 self.ast.queries[query as usize].limit = expr;
1451 self.ast.queries[query as usize].limit_percent = self.text(inner).ends_with('%');
1452 Ok(())
1453 }
1454 "LimitLiteralPercent" => {
1455 let expr = self.expr(self.first(inner))?;
1456 self.ast.queries[query as usize].limit = expr;
1457 self.ast.queries[query as usize].limit_percent = true;
1458 Ok(())
1459 }
1460 _ => self.unsupported(inner),
1461 }
1462 }
1463
1464 fn offset(&mut self, query: QueryRef, node: u32) -> Result<()> {
1466 let value = self.first(node);
1467 let expr = self.expr(self.first(value))?;
1468 self.ast.queries[query as usize].offset = expr;
1469 Ok(())
1470 }
1471
1472 fn simple_select(&mut self, node: u32) -> Result<SelectRef> {
1475 for name in ["QualifyClause", "SampleClause"] {
1476 let clause = self.find(node, name);
1477 if clause != NONE {
1478 return self.unsupported(clause);
1479 }
1480 }
1481 let mark = self.named_windows.len();
1484 let windows = self.find(node, "WindowClause");
1485 if windows != NONE {
1486 self.window_clause(windows)?;
1487 }
1488 let mut select = Select::empty();
1489 self.select_from(&mut select, self.first(node))?;
1490 let filter = self.find(node, "WhereClause");
1491 if filter != NONE {
1492 select.filter = self.expr(self.first(filter))?;
1493 }
1494 let group = self.find(node, "GroupByClause");
1495 if group != NONE {
1496 self.group_by(&mut select, self.first(group))?;
1497 }
1498 let having = self.find(node, "HavingClause");
1499 if having != NONE {
1500 select.having = self.expr(self.first(having))?;
1501 }
1502 self.named_windows.truncate(mark);
1503 Ok(self.push_select(select))
1504 }
1505
1506 fn select_from(&mut self, select: &mut Select, node: u32) -> Result<()> {
1509 let clause = self.first(node);
1510 let targets = self.find(clause, "SelectClause");
1511 let from = self.find(clause, "FromClause");
1512 if from != NONE {
1513 select.from = self.sources(from)?;
1514 }
1515 if targets == NONE {
1516 let star = self
1520 .push(Expr::Star { qualifier: Slice::default(), replacements: Slice::default() });
1521 let start = self.ast.targets.len() as u32;
1522 self.ast.targets.push(Target { expr: star, alias: NONE });
1523 select.targets = Slice { start, len: 1 };
1524 return Ok(());
1525 }
1526 self.select_clause(select, targets)
1527 }
1528
1529 fn select_clause(&mut self, select: &mut Select, node: u32) -> Result<()> {
1531 let distinct = self.find(node, "DistinctClause");
1532 if distinct != NONE {
1533 let inner = self.first(distinct);
1534 select.distinct = match self.name(inner) {
1535 "DistinctAll" => Distinct::No,
1537 "DistinctOn" => {
1538 let on = self.find(inner, "DistinctOnTargets");
1539 if on == NONE {
1540 Distinct::Yes
1541 } else {
1542 let mut items = Vec::new();
1543 for kid in self.kids(on) {
1544 items.push(self.expr(kid)?);
1545 }
1546 Distinct::On(self.expr_slice(items))
1547 }
1548 }
1549 _ => return self.unsupported(inner),
1550 };
1551 }
1552 let list = self.find(node, "TargetList");
1553 if list == NONE {
1554 return Ok(());
1555 }
1556 let mut targets = Vec::new();
1557 for kid in self.kids(list) {
1558 targets.push(self.target(kid)?);
1559 }
1560 select.targets = self.target_slice(targets);
1561 Ok(())
1562 }
1563
1564 fn target(&mut self, node: u32) -> Result<Target> {
1566 let inner = self.first(node);
1567 match self.name(inner) {
1568 "ColIdExpression" => {
1570 let alias = self.identifier(self.first(inner));
1571 let expr = self.expr(self.nth(inner, 1))?;
1572 Ok(Target { expr, alias })
1573 }
1574 "ExpressionAsCollabel" => {
1575 let expr = self.expr(self.first(inner))?;
1576 let alias = self.identifier(self.nth(inner, 1));
1577 Ok(Target { expr, alias })
1578 }
1579 "ExpressionOptIdentifier" => {
1580 let expr = self.expr(self.first(inner))?;
1581 let alias =
1582 if self.count(inner) > 1 { self.identifier(self.nth(inner, 1)) } else { NONE };
1583 Ok(Target { expr, alias })
1584 }
1585 _ => self.unsupported(inner),
1586 }
1587 }
1588
1589 fn group_by(&mut self, select: &mut Select, node: u32) -> Result<()> {
1591 let inner = self.first(node);
1592 match self.name(inner) {
1593 "GroupByAll" => {
1594 select.group_by_all = true;
1595 Ok(())
1596 }
1597 "GroupByList" => {
1598 let mut items = Vec::new();
1599 for kid in self.kids(inner) {
1600 let expression = self.first(kid);
1603 if self.name(expression) != "GroupByBaseExpression" {
1604 return self.unsupported(expression);
1605 }
1606 items.push(self.expr(self.first(expression))?);
1607 }
1608 select.group_by = self.expr_slice(items);
1609 Ok(())
1610 }
1611 _ => self.unsupported(inner),
1612 }
1613 }
1614
1615 fn order_by(&mut self, node: u32) -> Result<(Vec<OrderItem>, bool)> {
1618 let inner = self.first(self.first(node));
1619 match self.name(inner) {
1620 "OrderByAll" => {
1621 let (order, nulls) = self.sort_options(inner);
1622 Ok((vec![OrderItem { expr: NONE, order, nulls }], true))
1623 }
1624 "OrderByExpressionList" => {
1625 let mut items = Vec::new();
1626 for kid in self.kids(inner) {
1627 let expr = self.expr(self.first(kid))?;
1629 let (order, nulls) = self.sort_options(kid);
1630 items.push(OrderItem { expr, order, nulls });
1631 }
1632 Ok((items, false))
1633 }
1634 _ => self.unsupported(inner),
1635 }
1636 }
1637
1638 fn sort_options(&self, node: u32) -> (Order, Nulls) {
1640 let direction = self.find(node, "DescOrAsc");
1641 let order = if direction == NONE {
1642 Order::Unstated
1643 } else if self.name(self.first(direction)) == "DescendingOrder" {
1644 Order::Descending
1645 } else {
1646 Order::Ascending
1647 };
1648 let placement = self.find(node, "NullsFirstOrLast");
1649 let nulls = if placement == NONE {
1650 Nulls::Unstated
1651 } else if self.name(self.first(placement)) == "NullsFirst" {
1652 Nulls::First
1653 } else {
1654 Nulls::Last
1655 };
1656 (order, nulls)
1657 }
1658
1659 fn sources(&mut self, node: u32) -> Result<Slice> {
1663 let mut items = Vec::new();
1664 for kid in self.kids(node) {
1665 items.push(self.table_ref(kid)?);
1666 }
1667 let start = self.ast.source_lists.len() as u32;
1668 self.ast.source_lists.extend(items);
1669 Ok(Slice { start, len: self.ast.source_lists.len() as u32 - start })
1670 }
1671
1672 fn table_ref(&mut self, node: u32) -> Result<SourceRef> {
1674 let mut kids = self.kids(node);
1675 let head = kids.next().unwrap_or(NONE);
1676 let mut left = self.inner_table_ref(head)?;
1677 for tail in kids {
1678 let clause = self.first(tail);
1679 if self.name(clause) != "JoinClause" {
1680 return self.unsupported(clause);
1681 }
1682 left = self.join(left, self.first(clause))?;
1683 }
1684 Ok(left)
1685 }
1686
1687 fn inner_table_ref(&mut self, node: u32) -> Result<SourceRef> {
1689 let inner = if self.name(node) == "InnerTableRef" { self.first(node) } else { node };
1690 match self.name(inner) {
1691 "BaseTableRef" => {
1692 if self.find(inner, "TableAliasColon") != NONE {
1693 return self.unsupported(inner);
1694 }
1695 for name in ["AtClause", "SampleClause"] {
1696 let clause = self.find(inner, name);
1697 if clause != NONE {
1698 return self.unsupported(clause);
1699 }
1700 }
1701 let name = self.name_parts(self.find(inner, "BaseTableName"));
1702 let (alias, columns) = self.table_alias(self.find(inner, "TableAlias"));
1703 if name.len == 1 {
1704 let part = self.ast.parts[name.start as usize];
1705 if let Some(&(_, held, declared)) =
1706 self.ctes.iter().rev().find(|&&(cte, _, _)| {
1707 self.ast.string(cte).eq_ignore_ascii_case(self.ast.string(part))
1708 })
1709 {
1710 match held {
1711 Held::Inline(query) => {
1712 let alias = if alias == NONE { part } else { alias };
1713 let columns = if columns.is_empty() { declared } else { columns };
1714 return Ok(self.push_source(Source::Subquery {
1715 query,
1716 alias,
1717 columns,
1718 }));
1719 }
1720 Held::Once(cte) => {
1724 return Ok(self.push_source(Source::Cte { cte, alias, columns }));
1725 }
1726 }
1727 }
1728 }
1729 Ok(self.push_source(Source::Table { name, alias, columns }))
1730 }
1731 "TableSubquery" => {
1735 if self.find(inner, "TableAliasColon") != NONE {
1736 return self.unsupported(inner);
1737 }
1738 let reference = self.find(inner, "SubqueryReference");
1740 let query = self.query(self.first(reference))?;
1741 let (alias, columns) = self.table_alias(self.find(inner, "TableAlias"));
1742 Ok(self.push_source(Source::Subquery { query, alias, columns }))
1743 }
1744 "TableFunction" => {
1750 let form = self.first(inner);
1751 for name in ["TableAliasColon", "WithOrdinality", "SampleClause"] {
1752 let clause = self.find(form, name);
1753 if clause != NONE {
1754 return self.unsupported(clause);
1755 }
1756 }
1757 let name = self.name_parts(self.find(form, "QualifiedTableFunction"));
1758 let mut args = Vec::new();
1759 let list = self.find(form, "TableFunctionArguments");
1762 for kid in self.kids(list) {
1763 args.push(self.table_argument(kid)?);
1764 }
1765 let args = self.target_slice(args);
1766 let (alias, columns) = self.table_alias(self.find(form, "TableAlias"));
1767 Ok(self.push_source(Source::Function { name, args, alias, columns, pragma: false }))
1768 }
1769 "ValuesRef" => {
1770 if self.find(inner, "TableAliasColon") != NONE {
1771 return self.unsupported(inner);
1772 }
1773 let rows = self.values_clause(self.find(inner, "ValuesClause"))?;
1774 let (alias, columns) = self.table_alias(self.find(inner, "TableAlias"));
1775 Ok(self.push_source(Source::Values { rows, alias, columns }))
1776 }
1777 "ParensTableRef" => {
1778 if self.find(inner, "TableAliasColon") != NONE
1779 || self.find(inner, "SampleClause") != NONE
1780 || self.find(inner, "TableAlias") != NONE
1781 {
1782 return self.unsupported(inner);
1783 }
1784 self.table_ref(self.find(inner, "TableRef"))
1785 }
1786 _ => self.unsupported(inner),
1787 }
1788 }
1789
1790 fn table_alias(&mut self, node: u32) -> (StrRef, Slice) {
1792 if node == NONE {
1793 return (NONE, Slice::default());
1794 }
1795 let inner = self.first(node);
1796 let alias = self.identifier(self.first(inner));
1797 let list = self.find(inner, "ColumnAliases");
1798 if list == NONE {
1799 return (alias, Slice::default());
1800 }
1801 let mut columns = Vec::new();
1802 for kid in self.kids(list) {
1803 let name = self.identifier(kid);
1804 columns.push(name);
1805 }
1806 (alias, self.part_slice(columns))
1807 }
1808
1809 fn join(&mut self, left: SourceRef, node: u32) -> Result<SourceRef> {
1811 match self.name(node) {
1812 "RegularJoinClause" => {
1814 if self.find(node, "Asof") != NONE {
1815 return self.unsupported(node);
1816 }
1817 let kind = self.join_type(self.find(node, "JoinType"));
1818 let right = self.table_ref(self.find(node, "TableRef"))?;
1819 let (on, using) = self.join_qualifier(self.find(node, "JoinQualifier"))?;
1820 Ok(self.push_source(Source::Join { left, right, kind, natural: false, on, using }))
1821 }
1822 "JoinWithoutOnClause" => {
1825 let prefix = self.first(self.find(node, "JoinPrefix"));
1826 let (kind, natural) = match self.name(prefix) {
1827 "CrossJoinPrefix" => (JoinKind::Cross, false),
1828 "PositionalJoinPrefix" => (JoinKind::Positional, false),
1829 "NaturalJoinPrefix" => (self.join_type(self.find(prefix, "JoinType")), true),
1830 _ => return self.unsupported(prefix),
1831 };
1832 let right = self.inner_table_ref(self.find(node, "InnerTableRef"))?;
1833 Ok(self.push_source(Source::Join {
1834 left,
1835 right,
1836 kind,
1837 natural,
1838 on: NONE,
1839 using: Slice::default(),
1840 }))
1841 }
1842 _ => self.unsupported(node),
1843 }
1844 }
1845
1846 fn join_type(&self, node: u32) -> JoinKind {
1849 if node == NONE {
1850 return JoinKind::Inner;
1851 }
1852 match self.name(self.first(node)) {
1853 "FullJoin" => JoinKind::Full,
1854 "LeftJoin" => JoinKind::Left,
1855 "RightJoin" => JoinKind::Right,
1856 "SemiJoin" => JoinKind::Semi,
1857 "AntiJoin" => JoinKind::Anti,
1858 _ => JoinKind::Inner,
1859 }
1860 }
1861
1862 fn join_qualifier(&mut self, node: u32) -> Result<(ExprRef, Slice)> {
1864 let inner = self.first(node);
1865 match self.name(inner) {
1866 "OnClause" => Ok((self.expr(self.first(inner))?, Slice::default())),
1867 "UsingClause" => {
1868 let mut columns = Vec::new();
1869 for kid in self.kids(inner) {
1870 let name = self.identifier(kid);
1871 columns.push(name);
1872 }
1873 Ok((NONE, self.part_slice(columns)))
1874 }
1875 _ => self.unsupported(inner),
1876 }
1877 }
1878
1879 fn expr(&mut self, node: u32) -> Result<ExprRef> {
1897 let span = self.span(node);
1898 let outer = std::mem::replace(&mut self.current_span, span);
1899 let result = self.expr_inner(node);
1900 self.current_span = outer;
1901 result
1902 }
1903
1904 fn expr_inner(&mut self, node: u32) -> Result<ExprRef> {
1905 let mut node = node;
1906 loop {
1907 let count = self.count(node);
1908 let name = self.name(node);
1909 match name {
1910 "LogicalOrExpression" if count > 1 => return self.logical(node, BinaryOp::Or),
1911 "LogicalAndExpression" if count > 1 => return self.logical(node, BinaryOp::And),
1912 "LogicalNotExpression" if count > 1 => return self.logical_not(node),
1913 "IsExpression" if count > 1 => return self.is_expression(node),
1914 "BetweenInLikeExpression" if count > 1 => return self.between_in_like(node),
1915 "PrefixExpression" if count > 1 => return self.prefix(node),
1916 "BaseExpression" if count > 1 => return self.indirection(node),
1917 "LambdaArrowExpression"
1918 | "IsDistinctFromExpression"
1919 | "ComparisonExpression"
1920 | "OtherOperatorExpression"
1921 | "BitwiseExpression"
1922 | "AdditiveExpression"
1923 | "MultiplicativeExpression"
1924 | "ExponentiationExpression"
1925 | "CollateExpression"
1926 | "AtTimeZoneExpression"
1927 if count > 1 =>
1928 {
1929 return self.tail_chain(node);
1930 }
1931 "ColumnReference" => {
1932 let name = self.name_parts(node);
1933 return Ok(self.push(Expr::Column { name }));
1934 }
1935 "StarExpression" => return self.star(node),
1936 "NumberLiteral" => {
1937 let text = self.text(node).to_string();
1938 let text = self.intern(&text);
1939 return Ok(self.push(Expr::Literal { kind: LiteralKind::Number, text }));
1940 }
1941 "StringLiteral" => return self.string_literal(node),
1942 "NullLiteral" | "TrueLiteral" | "FalseLiteral" => {
1943 let kind = match name {
1944 "NullLiteral" => LiteralKind::Null,
1945 "TrueLiteral" => LiteralKind::True,
1946 _ => LiteralKind::False,
1947 };
1948 return Ok(self.push(Expr::Literal { kind, text: NONE }));
1949 }
1950 "FunctionExpression" => return self.function(node),
1951 "CoalesceExpression" => return self.coalesce(node),
1952 "NullIfExpression" => return self.null_if(node),
1953 "SubstringExpression" => return self.substring(node),
1954 "PositionExpression" => return self.position(node),
1955 "TrimExpression" => return self.trim(node),
1956 "OverlayExpression" => return self.overlay(node),
1957 "ExtractExpression" => return self.extract(node),
1958 "CastExpression" => return self.cast(node),
1959 "TypeLiteral" => return self.typed_literal(node),
1960 "IntervalLiteral" => return self.interval_literal(node),
1961 "CaseExpression" => return self.case(node),
1962 "ParenthesisExpression" => return self.row(node),
1963 "ParensExpression" if count == 1 => node = self.first(node),
1969 "BoundedListExpression" => return self.list(node),
1970 "QuestionMarkNumberedParameter"
1971 | "AnonymousParameter"
1972 | "NumberedParameter"
1973 | "ColLabelParameter" => return self.parameter(node),
1974 "SubqueryExpression" => return self.subquery(node),
1975 _ if count == 1 && self.text(self.first(node)) == self.text(node) => {
1976 node = self.first(node);
1977 }
1978 _ => return self.unsupported(node),
1979 }
1980 }
1981 }
1982
1983 fn tail_chain(&mut self, node: u32) -> Result<ExprRef> {
1985 let mut kids = self.kids(node);
1986 let head = kids.next().unwrap_or(NONE);
1987 let mut left = self.expr(head)?;
1988 for tail in kids {
1989 let operator = self.first(tail);
1990 let operand = self.kids(tail).last().unwrap_or(NONE);
1994 if self.count(tail) > 2 {
1995 return self.unsupported(tail);
1996 }
1997 if self.contains(operator, "AnyAllParsedOperator") {
1998 let any_op = self.descendant(operator, "AnyOp");
1999 let op = self.binary_op(any_op)?;
2000 let reference = self.descendant(operand, "SubqueryReference");
2001 if reference == NONE {
2002 return self.unsupported(operand);
2003 }
2004 let query = self.query(self.first(reference))?;
2005 let all = self.contains(operator, "SubqueryAll");
2006 left = self.push(Expr::QuantifiedSubquery { operand: left, op, query, all });
2007 continue;
2008 }
2009 let op = self.binary_op(operator)?;
2010 let right = self.expr(operand)?;
2011 left = self.push(Expr::Binary { op, left, right });
2012 }
2013 Ok(left)
2014 }
2015
2016 fn binary_op(&mut self, node: u32) -> Result<BinaryOp> {
2018 let mut leaf = node;
2024 while self.count(leaf) == 1 {
2025 leaf = self.first(leaf);
2026 }
2027 let text = self.text(node);
2028 let upper = text.to_ascii_uppercase();
2029 let op = match upper.as_str() {
2030 "OR" => BinaryOp::Or,
2031 "AND" => BinaryOp::And,
2032 "=" | "==" => BinaryOp::Eq,
2033 "!=" | "<>" => BinaryOp::NotEq,
2034 "<" => BinaryOp::Lt,
2035 ">" => BinaryOp::Gt,
2036 "<=" => BinaryOp::LtEq,
2037 ">=" => BinaryOp::GtEq,
2038 "+" => BinaryOp::Add,
2039 "-" => BinaryOp::Subtract,
2040 "*" => BinaryOp::Multiply,
2041 "/" => BinaryOp::Divide,
2042 "//" => BinaryOp::IntegerDivide,
2043 "%" => BinaryOp::Modulo,
2044 "^" | "**" => BinaryOp::Power,
2045 "&" => BinaryOp::BitAnd,
2046 "|" => BinaryOp::BitOr,
2047 "<<" => BinaryOp::ShiftLeft,
2048 ">>" => BinaryOp::ShiftRight,
2049 "||" => BinaryOp::Concat,
2050 "COLLATE" => BinaryOp::Collate,
2051 "->" => BinaryOp::Arrow,
2052 "->>" => BinaryOp::LongArrow,
2053 "@>" => BinaryOp::Contains,
2054 "<@" => BinaryOp::ContainedBy,
2055 "&&" => BinaryOp::Overlaps,
2056 "^@" => BinaryOp::StartsWith,
2057 "<<=" => BinaryOp::InetContainedByOrEq,
2058 ">>=" => BinaryOp::InetContainsOrEq,
2059 _ if self.name(leaf) == "AtTimeZoneOperator" => BinaryOp::AtTimeZone,
2060 _ if self.name(leaf) == "IsDistinctFromOp" => {
2063 if upper.split_whitespace().any(|word| word == "NOT") {
2064 BinaryOp::IsNotDistinctFrom
2065 } else {
2066 BinaryOp::IsDistinctFrom
2067 }
2068 }
2069 _ if self.name(leaf) == "OperatorLiteral" => {
2076 let interned = self.intern(text);
2077 BinaryOp::Named(interned)
2078 }
2079 _ => return self.unsupported(node),
2080 };
2081 Ok(op)
2082 }
2083
2084 fn logical(&mut self, node: u32, op: BinaryOp) -> Result<ExprRef> {
2089 let mut kids = self.kids(node);
2090 let head = kids.next().unwrap_or(NONE);
2091 let mut left = self.expr(head)?;
2092 for tail in kids {
2093 let right = self.expr(self.first(tail))?;
2094 left = self.push(Expr::Binary { op, left, right });
2095 }
2096 Ok(left)
2097 }
2098
2099 fn logical_not(&mut self, node: u32) -> Result<ExprRef> {
2104 let negations = self.count(self.first(node));
2105 let mut expr = self.expr(self.nth(node, 1))?;
2106 for _ in 0..negations {
2107 expr = self.push(Expr::Unary { op: UnaryOp::Not, operand: expr });
2108 }
2109 Ok(expr)
2110 }
2111
2112 fn is_expression(&mut self, node: u32) -> Result<ExprRef> {
2114 let mut kids = self.kids(node);
2115 let head = kids.next().unwrap_or(NONE);
2116 let mut expr = self.expr(head)?;
2117 for test in kids {
2118 let inner = self.first(test);
2119 let negated = self.text(inner).to_ascii_uppercase().contains("NOT");
2120 let op = match self.name(inner) {
2121 "NotNull" => UnaryOp::IsNotNull,
2122 "IsNull" => UnaryOp::IsNull,
2123 "IsLiteral" => match self.name(self.first(self.first(inner))) {
2126 "NullLiteral" if negated => UnaryOp::IsNotNull,
2127 "NullLiteral" => UnaryOp::IsNull,
2128 "TrueLiteral" if negated => UnaryOp::IsNotTrue,
2129 "TrueLiteral" => UnaryOp::IsTrue,
2130 "FalseLiteral" if negated => UnaryOp::IsNotFalse,
2131 "FalseLiteral" => UnaryOp::IsFalse,
2132 "UnknownLiteral" if negated => UnaryOp::IsNotUnknown,
2133 "UnknownLiteral" => UnaryOp::IsUnknown,
2134 _ => return self.unsupported(inner),
2135 },
2136 _ => return self.unsupported(inner),
2137 };
2138 expr = self.push(Expr::Unary { op, operand: expr });
2139 }
2140 Ok(expr)
2141 }
2142
2143 fn between_in_like(&mut self, node: u32) -> Result<ExprRef> {
2145 let operand = self.expr(self.first(node))?;
2146 let op = self.nth(node, 1);
2149 let negated = self.text(op).to_ascii_uppercase().starts_with("NOT");
2150 let inner = self.first(self.first(op));
2151 match self.name(inner) {
2152 "BetweenClause" => {
2154 let low = self.expr(self.first(inner))?;
2155 let high = self.expr(self.nth(inner, 1))?;
2156 Ok(self.push(Expr::Between { operand, low, high, negated }))
2157 }
2158 "InClause" => {
2160 let expression = self.first(self.first(inner));
2161 match self.name(expression) {
2162 "InExpressionList" => {
2163 let mut items = Vec::new();
2164 for kid in self.kids(expression) {
2165 items.push(self.expr(kid)?);
2166 }
2167 let list = self.expr_slice(items);
2168 Ok(self.push(Expr::In { operand, list, negated }))
2169 }
2170 "InSelectStatement" => {
2171 let query = self.query(self.first(expression))?;
2172 Ok(self.push(Expr::InSubquery { operand, query, negated }))
2173 }
2174 _ => self.unsupported(expression),
2175 }
2176 }
2177 "LikeClause" => {
2179 if self.find(inner, "EscapeClause") != NONE {
2180 return self.unsupported(inner);
2181 }
2182 let variation = self.name(self.first(self.first(inner)));
2183 let op = match (variation, negated) {
2184 ("LikeToken", false) | ("NotLikeOp", true) => BinaryOp::Like,
2185 ("LikeToken", true) | ("NotLikeOp", false) => BinaryOp::NotLike,
2186 ("ILikeToken", false) | ("NotILikeOp", true) => BinaryOp::ILike,
2187 ("ILikeToken", true) | ("NotILikeOp", false) => BinaryOp::NotILike,
2188 ("GlobToken", _) => BinaryOp::Glob,
2191 ("RegexMatchToken", _) => BinaryOp::Regex,
2192 ("SimilarToToken", false) => BinaryOp::SimilarTo,
2193 ("SimilarToToken", true) => BinaryOp::NotSimilarTo,
2194 ("NotSimilarToOp", false) => BinaryOp::NotRegex,
2195 ("NotSimilarToOp", true) => BinaryOp::Regex,
2196 ("RegexInsensitiveMatchToken", false)
2197 | ("NotRegexInsensitiveMatchOp", true) => BinaryOp::RegexInsensitive,
2198 ("RegexInsensitiveMatchToken", true)
2199 | ("NotRegexInsensitiveMatchOp", false) => BinaryOp::NotRegexInsensitive,
2200 _ => return self.unsupported(inner),
2201 };
2202 let right = self.expr(self.nth(inner, 1))?;
2203 let expr = self.push(Expr::Binary { op, left: operand, right });
2204 if negated && matches!(op, BinaryOp::Glob | BinaryOp::Regex) {
2207 return Ok(self.push(Expr::Unary { op: UnaryOp::Not, operand: expr }));
2208 }
2209 Ok(expr)
2210 }
2211 _ => self.unsupported(inner),
2212 }
2213 }
2214
2215 fn prefix(&mut self, node: u32) -> Result<ExprRef> {
2217 let kids: Vec<u32> = self.kids(node).collect();
2218 let mut expr = self.expr(kids[kids.len() - 1])?;
2219 for &operator in kids[..kids.len() - 1].iter().rev() {
2220 let op = match self.name(self.first(operator)) {
2221 "MinusPrefixOperator" => UnaryOp::Negate,
2222 "PlusPrefixOperator" => UnaryOp::Plus,
2223 "TildePrefixOperator" => UnaryOp::BitNot,
2224 _ => return self.unsupported(operator),
2225 };
2226 expr = self.push(Expr::Unary { op, operand: expr });
2227 }
2228 Ok(expr)
2229 }
2230
2231 fn indirection(&mut self, node: u32) -> Result<ExprRef> {
2233 let mut expr = self.expr(self.first(node))?;
2234 for step in self.kids(self.nth(node, 1)) {
2235 let inner = self.first(step);
2236 expr = match self.name(inner) {
2237 "CastOperator" => {
2239 let text = self.text(self.first(inner)).to_string();
2240 let ty = self.intern(&text);
2241 self.push(Expr::Cast { operand: expr, ty, try_cast: false })
2242 }
2243 "DotOperator" => {
2244 let dot = self.first(inner);
2245 match self.name(dot) {
2246 "DotColumnOperator" => {
2251 let field = self.identifier(self.first(dot));
2252 let text = self.ast.string(field).to_string();
2253 let literal = self.intern(&text);
2254 let key = self
2255 .push(Expr::Literal { kind: LiteralKind::String, text: literal });
2256 let name = self.function_name("struct_extract");
2257 let args = self.expr_slice(vec![expr, key]);
2258 self.push(Expr::Function { name, args, distinct: false, filter: NONE })
2259 }
2260 "DotMethodOperator" => {
2262 let method = self.first(dot);
2263 let text = self.text(self.first(method)).to_string();
2264 let text = unquote(&text);
2265 let name = self.function_name(&text);
2266 let mut args = vec![expr];
2267 let list = self.find(method, "MethodExpressionArguments");
2268 if list != NONE {
2269 let inner = self.first(list);
2270 let arguments = self.find(inner, "MethodFunctionArguments");
2271 if arguments != NONE {
2272 for kid in self.kids(arguments) {
2273 args.push(self.argument(kid)?);
2274 }
2275 }
2276 }
2277 let args = self.expr_slice(args);
2278 self.push(Expr::Function { name, args, distinct: false, filter: NONE })
2279 }
2280 _ => return self.unsupported(dot),
2281 }
2282 }
2283 "SliceExpression" => self.subscript(inner, expr)?,
2288 "PostfixOperator" => {
2290 self.push(Expr::Unary { op: UnaryOp::Factorial, operand: expr })
2291 }
2292 _ => return self.unsupported(inner),
2293 };
2294 }
2295 Ok(expr)
2296 }
2297
2298 fn subscript(&mut self, node: u32, target: ExprRef) -> Result<ExprRef> {
2317 let bound = self.first(node);
2318 let (mut begin, mut end, mut step) = (NONE, NONE, NONE);
2319 for kid in self.kids(bound) {
2320 match self.name(kid) {
2321 "EndSliceBound" => end = kid,
2322 "StepSliceBound" => step = kid,
2323 _ => begin = kid,
2324 }
2325 }
2326 if end == NONE && step == NONE {
2327 if begin == NONE {
2328 return Err(Error::parser("Empty subscript '[]' is not allowed"));
2329 }
2330 let index = self.expr(begin)?;
2331 let name = self.function_name("array_extract");
2332 let args = self.expr_slice(vec![target, index]);
2333 return Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }));
2334 }
2335 let first = if begin == NONE { self.literal_number("1") } else { self.expr(begin)? };
2336 let value = if end == NONE { NONE } else { self.find(end, "EndSliceValue") };
2339 let written = if value == NONE { NONE } else { self.first(value) };
2340 let last = if written == NONE || self.name(written) == "EndSliceMinus" {
2341 self.literal_number("-1")
2342 } else {
2343 self.expr(written)?
2344 };
2345 let mut args = vec![target, first, last];
2346 if step != NONE {
2347 let by = self.first(step);
2348 args.push(if by == NONE {
2349 self.push(Expr::List { items: Slice::default() })
2350 } else {
2351 self.expr(by)?
2352 });
2353 }
2354 let name = self.function_name("array_slice");
2355 let args = self.expr_slice(args);
2356 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2357 }
2358
2359 fn literal_number(&mut self, digits: &str) -> ExprRef {
2361 let text = self.intern(digits);
2362 self.push(Expr::Literal { kind: LiteralKind::Number, text })
2363 }
2364
2365 fn function_name(&mut self, name: &str) -> Slice {
2367 let interned = self.intern(name);
2368 self.part_slice(vec![interned])
2369 }
2370
2371 fn star(&mut self, node: u32) -> Result<ExprRef> {
2373 for name in ["ExcludeList", "RenameList"] {
2374 let list = self.find(node, name);
2375 if list != NONE {
2376 return self.unsupported(list);
2377 }
2378 }
2379 let replace = self.find(node, "ReplaceList");
2380 let replacements =
2381 if replace == NONE { Slice::default() } else { self.replacements(replace)? };
2382 let qualifier = self.find(node, "StarQualifierList");
2383 let qualifier =
2384 if qualifier == NONE { Slice::default() } else { self.name_parts(qualifier) };
2385 Ok(self.push(Expr::Star { qualifier, replacements }))
2386 }
2387
2388 fn replacements(&mut self, node: u32) -> Result<Slice> {
2395 let entries = self.first(self.first(node));
2398 let listed: Vec<u32> =
2399 self.kids(entries).filter(|&kid| self.name(kid) == "ReplaceEntry").collect();
2400 let mut replacements = Vec::with_capacity(listed.len());
2401 for entry in listed {
2402 let expr = self.expr(self.first(entry))?;
2403 let alias = self.identifier(self.nth(entry, 1));
2404 let written = self.ast.string(alias).to_string();
2405 if replacements
2406 .iter()
2407 .any(|held: &Target| self.ast.string(held.alias).eq_ignore_ascii_case(&written))
2408 {
2409 return Err(Error::parser(format!(
2410 "Duplicate entry \"{written}\" in REPLACE list"
2411 )));
2412 }
2413 replacements.push(Target { expr, alias });
2414 }
2415 Ok(self.target_slice(replacements))
2416 }
2417
2418 fn function(&mut self, node: u32) -> Result<ExprRef> {
2421 for name in ["WithinGroupClause", "ExportClause"] {
2422 let clause = self.find(node, name);
2423 if clause != NONE {
2424 return self.unsupported(clause);
2425 }
2426 }
2427 let clause = self.find(node, "FilterClause");
2431 let written =
2432 if clause == NONE { NONE } else { self.descendant(clause, "FilterClauseContents") };
2433 let filter = if written == NONE {
2434 NONE
2435 } else {
2436 let predicate = self.kids(written).last().unwrap_or(NONE);
2437 self.expr(predicate)?
2438 };
2439 let over = self.find(node, "OverClause");
2440 let name = self.name_parts(self.first(node));
2441 let list = self.first(self.nth(node, 1));
2445 let inside = self.find(list, "OrderByClause");
2450 if inside != NONE && over == NONE {
2451 return self.unsupported(inside);
2452 }
2453 let inner = if inside == NONE {
2454 Slice { start: 0, len: 0 }
2455 } else {
2456 let (items, all) = self.order_by(inside)?;
2460 if all {
2461 return self.unsupported(inside);
2462 }
2463 self.order_slice(items)
2464 };
2465 let nulls = self.find(list, "IgnoreOrRespectNulls");
2468 if nulls != NONE && over == NONE {
2469 return Err(Error::parser(
2470 "RESPECT/IGNORE NULLS is not supported for non-window functions",
2471 ));
2472 }
2473 let ignore_nulls = nulls != NONE && self.name(self.first(nulls)) == "IgnoreNulls";
2474 let distinct = self.quantifier(self.find(list, "DistinctOrAll")) == Quantifier::Distinct;
2475 let mut args = Vec::new();
2476 let arguments = self.find(list, "FunctionArgumentList");
2477 if arguments != NONE {
2478 for kid in self.kids(arguments) {
2479 args.push(self.argument(kid)?);
2480 }
2481 }
2482 if over != NONE {
2487 let args = self.expr_slice(args);
2488 let spec = self.over(over)?;
2489 return Ok(self.push(Expr::Window {
2490 name,
2491 args,
2492 distinct,
2493 filter,
2494 ignore_nulls,
2495 order: inner,
2496 spec,
2497 }));
2498 }
2499 if self.ast.name(name).last().is_some_and(|part| part.eq_ignore_ascii_case("ifnull")) {
2505 if args.len() != 2 {
2506 return Err(Error::parser("Wrong number of arguments to IFNULL."));
2507 }
2508 let args = self.expr_slice(args);
2509 let name = self.function_name("coalesce");
2510 return Ok(self.push(Expr::Function { name, args, distinct, filter }));
2511 }
2512 let args = self.expr_slice(args);
2513 Ok(self.push(Expr::Function { name, args, distinct, filter }))
2514 }
2515
2516 fn window_clause(&mut self, node: u32) -> Result<()> {
2524 for kid in self.kids(node) {
2525 if self.name(kid) != "WindowDefinition" {
2526 continue;
2527 }
2528 let name = self.identifier(self.first(kid));
2529 let definition = self.find(kid, "WindowFrameDefinition");
2530 if definition == NONE {
2531 return self.unsupported(kid);
2532 }
2533 let (spec, framed) = self.window_definition(definition)?;
2534 let spec = self.push_window(spec);
2535 self.named_windows.push((name, spec, framed));
2536 }
2537 Ok(())
2538 }
2539
2540 fn over(&mut self, node: u32) -> Result<WindowRef> {
2549 let mut frame = self.first(node);
2550 if self.name(frame) == "WindowFrame" {
2551 frame = self.first(frame);
2552 }
2553 match self.name(frame) {
2554 "ParensIdentifier" | "IdentifierWindowFrame" => {
2555 let name = self.identifier(self.first(frame));
2556 let (spec, _) = self.named_window(name)?;
2557 Ok(spec)
2558 }
2559 "WindowFrameDefinition" => {
2560 let (spec, _) = self.window_definition(frame)?;
2561 Ok(self.push_window(spec))
2562 }
2563 _ => self.unsupported(frame),
2564 }
2565 }
2566
2567 fn named_window(&self, name: StrRef) -> Result<(WindowRef, bool)> {
2569 let written = self.ast.string(name);
2570 let found = self
2571 .named_windows
2572 .iter()
2573 .rev()
2574 .find(|&&(defined, _, _)| self.ast.string(defined).eq_ignore_ascii_case(written));
2575 match found {
2576 Some(&(_, spec, framed)) => Ok((spec, framed)),
2577 None => Err(Error::parser(format!("window \"\"{written}\"\" does not exist"))),
2581 }
2582 }
2583
2584 fn window_definition(&mut self, node: u32) -> Result<(WindowSpec, bool)> {
2591 let held = self.first(self.first(node));
2592 let (base, contents) = match self.name(held) {
2593 "WindowFrameNameContents" => {
2594 (self.find(held, "BaseWindowName"), self.find(held, "WindowFrameContents"))
2595 }
2596 "WindowFrameContents" => (NONE, held),
2597 _ => return self.unsupported(held),
2598 };
2599 if contents == NONE {
2600 return self.unsupported(node);
2601 }
2602 let partition = self.find(contents, "WindowPartition");
2603 let order = self.find(contents, "OrderByClause");
2604 let frame = self.find(contents, "FrameClause");
2605 let mut spec = WindowSpec::empty();
2606 if base != NONE {
2607 let name = self.identifier(self.first(base));
2608 let written = self.ast.string(name).to_string();
2609 let (found, framed) = self.named_window(name)?;
2610 if framed {
2614 return Err(Error::parser(format!(
2615 "cannot copy window \"{written}\" because it has a frame clause"
2616 )));
2617 }
2618 spec = self.ast.window(found);
2619 if partition != NONE && !spec.partition.is_empty() {
2620 return Err(Error::parser(format!(
2621 "Cannot override PARTITION BY clause of window \"{written}\""
2622 )));
2623 }
2624 if order != NONE && !spec.order.is_empty() {
2625 return Err(Error::parser(format!(
2626 "Cannot override ORDER BY clause of window \"{written}\""
2627 )));
2628 }
2629 }
2630 if partition != NONE {
2631 let mut items = Vec::new();
2632 for kid in self.kids(partition) {
2633 items.push(self.expr(kid)?);
2634 }
2635 spec.partition = self.expr_slice(items);
2636 }
2637 if order != NONE {
2638 let (items, all) = self.order_by(order)?;
2639 if all {
2640 return self.unsupported(order);
2641 }
2642 spec.order = self.order_slice(items);
2643 }
2644 if frame != NONE {
2645 self.frame_clause(&mut spec, frame)?;
2646 }
2647 Ok((spec, frame != NONE))
2648 }
2649
2650 fn frame_clause(&mut self, spec: &mut WindowSpec, node: u32) -> Result<()> {
2658 let framing = self.first(self.find(node, "Framing"));
2659 spec.unit = match self.name(framing) {
2660 "RowsFraming" => WindowUnit::Rows,
2661 "RangeFraming" => WindowUnit::Range,
2662 "GroupsFraming" => WindowUnit::Groups,
2663 _ => return self.unsupported(framing),
2664 };
2665 let extent = self.first(self.find(node, "FrameExtent"));
2666 match self.name(extent) {
2667 "SingleFrameExtent" => {
2670 spec.start = self.frame_bound(self.first(extent))?;
2671 spec.end = WindowBound::CurrentRow;
2672 }
2673 "BetweenFrameExtent" => {
2675 spec.start = self.frame_bound(self.first(extent))?;
2676 spec.end = self.frame_bound(self.nth(extent, 1))?;
2677 }
2678 _ => return self.unsupported(extent),
2679 }
2680 let exclude = self.find(node, "WindowExcludeClause");
2681 if exclude != NONE {
2682 let element = self.first(self.first(exclude));
2683 spec.exclude = match self.name(element) {
2684 "ExcludeCurrentRow" => WindowExclude::CurrentRow,
2685 "ExcludeGroup" => WindowExclude::Group,
2686 "ExcludeTies" => WindowExclude::Ties,
2687 "ExcludeNoOthers" => WindowExclude::NoOthers,
2688 _ => return self.unsupported(element),
2689 };
2690 }
2691 if spec.start == WindowBound::UnboundedPreceding
2692 && spec.end == WindowBound::UnboundedFollowing
2693 {
2694 spec.unit = WindowUnit::Rows;
2695 }
2696 Ok(())
2697 }
2698
2699 fn frame_bound(&mut self, node: u32) -> Result<WindowBound> {
2701 let inner = if self.name(node) == "FrameBound" { self.first(node) } else { node };
2702 match self.name(inner) {
2703 "FrameCurrentRow" => Ok(WindowBound::CurrentRow),
2704 "FrameUnbounded" => {
2706 if self.preceding(self.first(inner)) {
2707 Ok(WindowBound::UnboundedPreceding)
2708 } else {
2709 Ok(WindowBound::UnboundedFollowing)
2710 }
2711 }
2712 "FrameExpression" => {
2714 let offset = self.expr(self.first(inner))?;
2715 if self.preceding(self.nth(inner, 1)) {
2716 Ok(WindowBound::Preceding(offset))
2717 } else {
2718 Ok(WindowBound::Following(offset))
2719 }
2720 }
2721 _ => self.unsupported(inner),
2722 }
2723 }
2724
2725 fn preceding(&self, node: u32) -> bool {
2727 self.name(self.first(node)) == "PrecedingFrame"
2728 }
2729
2730 fn coalesce(&mut self, node: u32) -> Result<ExprRef> {
2741 let mut args = Vec::new();
2742 for kid in self.kids(node) {
2743 args.push(self.expr(kid)?);
2744 }
2745 let args = self.expr_slice(args);
2746 let name = self.function_name("coalesce");
2747 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2748 }
2749
2750 fn null_if(&mut self, node: u32) -> Result<ExprRef> {
2760 let arguments = self.find(node, "NullIfArguments");
2761 if arguments == NONE {
2762 return self.unsupported(node);
2763 }
2764 let mut args = Vec::new();
2765 for kid in self.kids(arguments) {
2766 args.push(self.expr(kid)?);
2767 }
2768 let args = self.expr_slice(args);
2769 let name = self.function_name("nullif");
2770 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2771 }
2772
2773 fn substring(&mut self, node: u32) -> Result<ExprRef> {
2782 let shape = self.first(self.first(node));
2783 let mut args = Vec::new();
2784 match self.name(shape) {
2785 "SubstringExpressionList" => {
2786 for kid in self.kids(shape) {
2787 args.push(self.expr(kid)?);
2788 }
2789 }
2790 "SubstringParameters" => {
2791 args.push(self.expr(self.first(shape))?);
2792 let bounds = self.first(self.nth(shape, 1));
2796 let from = self.find(bounds, "FromExpression");
2797 let start =
2798 if from == NONE { self.number("1") } else { self.expr(self.first(from))? };
2799 args.push(start);
2800 let count = self.find(bounds, "ForExpression");
2801 if count != NONE {
2802 args.push(self.expr(self.first(count))?);
2803 }
2804 }
2805 _ => return self.unsupported(shape),
2806 }
2807 let args = self.expr_slice(args);
2808 let name = self.function_name("substring");
2809 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2810 }
2811
2812 fn position(&mut self, node: u32) -> Result<ExprRef> {
2819 let arguments = self.first(node);
2820 if self.count(arguments) != 2 {
2821 return self.unsupported(arguments);
2822 }
2823 let needle = self.expr(self.first(arguments))?;
2824 let haystack = self.expr(self.nth(arguments, 1))?;
2825 let args = self.expr_slice(vec![haystack, needle]);
2826 let name = self.function_name("position");
2827 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2828 }
2829
2830 fn trim(&mut self, node: u32) -> Result<ExprRef> {
2839 let arguments = self.first(node);
2840 let direction = self.find(arguments, "TrimDirection");
2841 let name = match direction {
2842 NONE => "trim",
2843 held => match self.name(self.first(held)) {
2844 "TrimLeading" => "ltrim",
2845 "TrimTrailing" => "rtrim",
2846 _ => "trim",
2847 },
2848 };
2849 let mut args = Vec::new();
2850 for kid in self.kids(arguments) {
2851 if matches!(self.name(kid), "TrimDirection" | "TrimSource") {
2852 continue;
2853 }
2854 args.push(self.expr(kid)?);
2855 }
2856 let source = self.find(arguments, "TrimSource");
2859 if source != NONE && self.count(source) == 1 {
2860 args.push(self.expr(self.first(source))?);
2861 }
2862 let args = self.expr_slice(args);
2863 let name = self.function_name(name);
2864 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2865 }
2866
2867 fn overlay(&mut self, node: u32) -> Result<ExprRef> {
2875 let shape = self.first(self.first(node));
2876 if !matches!(self.name(shape), "OverlayParameters" | "OverlayExpressionList") {
2877 return self.unsupported(shape);
2878 }
2879 let mut args = Vec::new();
2880 for kid in self.kids(shape) {
2881 let kid = match self.name(kid) {
2882 "FromExpression" | "ForExpression" => self.first(kid),
2883 _ => kid,
2884 };
2885 args.push(self.expr(kid)?);
2886 }
2887 let args = self.expr_slice(args);
2888 let name = self.function_name("overlay");
2889 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2890 }
2891
2892 fn number(&mut self, text: &str) -> ExprRef {
2894 let text = self.intern(text);
2895 self.push(Expr::Literal { kind: LiteralKind::Number, text })
2896 }
2897
2898 fn extract(&mut self, node: u32) -> Result<ExprRef> {
2907 let arguments = self.find(node, "ExtractArguments");
2908 if arguments == NONE {
2909 return self.unsupported(node);
2910 }
2911 let argument = self.first(self.first(arguments));
2912 let part = match self.name(argument) {
2913 "ExtractStringArgument" => self.string_value(argument)?,
2914 "ExtractDatePartArgument" => date_part(self.text(argument)),
2919 "ExtractIdentifierArgument" => self.text(argument).to_string(),
2922 _ => return self.unsupported(argument),
2923 };
2924 let text = self.intern(&part);
2925 let part = self.push(Expr::Literal { kind: LiteralKind::String, text });
2926 let operand = self.expr(self.nth(arguments, 1))?;
2927 let name = self.function_name("date_part");
2928 let args = self.expr_slice(vec![part, operand]);
2929 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2930 }
2931
2932 fn argument(&mut self, node: u32) -> Result<ExprRef> {
2934 let inner = self.first(node);
2935 match self.name(inner) {
2936 "PositionalFunctionArgument" => self.expr(self.first(inner)),
2937 _ => self.unsupported(inner),
2938 }
2939 }
2940
2941 fn table_argument(&mut self, node: u32) -> Result<Target> {
2956 let inner = self.first(node);
2957 if self.name(inner) == "NamedFunctionArgument" {
2958 let named = self.first(inner);
2959 if self.count(named) != 3 {
2960 return self.unsupported(named);
2963 }
2964 let alias = self.identifier(self.first(named));
2965 let expr = self.expr(self.nth(named, 2))?;
2966 return Ok(Target { expr, alias });
2967 }
2968 let expr = self.expr(self.first(inner))?;
2969 if let Expr::Binary { op: BinaryOp::Eq, left, right } = self.ast.expr(expr) {
2970 if let Expr::Column { name } = self.ast.expr(left) {
2971 if name.len == 1 {
2972 let alias = self.ast.parts[name.start as usize];
2973 return Ok(Target { expr: right, alias });
2974 }
2975 }
2976 }
2977 Ok(Target { expr, alias: NONE })
2978 }
2979
2980 fn cast(&mut self, node: u32) -> Result<ExprRef> {
2982 let try_cast = self.name(self.first(self.first(node))) == "TryCastKeyword";
2983 let arguments = self.nth(node, 1);
2985 let operand = self.expr(self.first(arguments))?;
2986 let text = self.text(self.nth(arguments, 1)).to_string();
2987 let ty = self.intern(&text);
2988 Ok(self.push(Expr::Cast { operand, ty, try_cast }))
2989 }
2990
2991 fn typed_literal(&mut self, node: u32) -> Result<ExprRef> {
3001 let text = self.text(self.first(node)).to_string();
3002 let ty = self.intern(&text);
3003 let operand = self.expr(self.nth(node, 1))?;
3004 Ok(self.push(Expr::Cast { operand, ty, try_cast: false }))
3005 }
3006
3007 fn interval_literal(&mut self, node: u32) -> Result<ExprRef> {
3025 let parameter = self.find(node, "IntervalParameter");
3026 if parameter == NONE {
3027 return self.unsupported(node);
3028 }
3029 let operand = self.expr(self.first(parameter))?;
3030 let unit = self.find(node, "Interval");
3031 if unit == NONE {
3032 let ty = self.intern("INTERVAL");
3033 return Ok(self.push(Expr::Cast { operand, ty, try_cast: false }));
3034 }
3035 let spelling = self.name(self.first(unit));
3036 if spelling == "IntervalToInterval" {
3040 let pair = self.name(self.first(self.first(unit)));
3041 return Err(Error::parser(format!("{} is not supported", worded(pair))));
3042 }
3043 let Some(&(_, function, width)) = UNITS.iter().find(|(rule, _, _)| *rule == spelling)
3044 else {
3045 return self.unsupported(unit);
3046 };
3047 let double = self.intern("DOUBLE");
3048 let mut count = self.push(Expr::Cast { operand, ty: double, try_cast: false });
3049 if let Some(width) = width {
3050 let name = self.function_name("trunc");
3051 let args = self.expr_slice(vec![count]);
3052 let whole = self.push(Expr::Function { name, args, distinct: false, filter: NONE });
3053 let ty = self.intern(width);
3054 count = self.push(Expr::Cast { operand: whole, ty, try_cast: false });
3055 }
3056 let name = self.function_name(function);
3057 let args = self.expr_slice(vec![count]);
3058 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
3059 }
3060
3061 fn case(&mut self, node: u32) -> Result<ExprRef> {
3063 let mut operand = NONE;
3064 let mut arms = Vec::new();
3065 let mut otherwise = NONE;
3066 for kid in self.kids(node) {
3067 match self.name(kid) {
3068 "CaseWhenThen" => {
3070 let when = self.expr(self.first(kid))?;
3071 let then = self.expr(self.nth(kid, 1))?;
3072 arms.push(CaseArm { when, then });
3073 }
3074 "CaseElse" => otherwise = self.expr(self.first(kid))?,
3076 _ => operand = self.expr(kid)?,
3078 }
3079 }
3080 let start = self.ast.case_arms.len() as u32;
3081 self.ast.case_arms.extend(arms);
3082 let arms = Slice { start, len: self.ast.case_arms.len() as u32 - start };
3083 Ok(self.push(Expr::Case { operand, arms, otherwise }))
3084 }
3085
3086 fn row(&mut self, node: u32) -> Result<ExprRef> {
3091 let mut items = Vec::new();
3092 for kid in self.kids(node) {
3093 items.push(self.expr(kid)?);
3094 }
3095 if items.len() == 1 {
3096 return Ok(items[0]);
3097 }
3098 let items = self.expr_slice(items);
3099 Ok(self.push(Expr::Row { items }))
3100 }
3101
3102 fn parameter(&mut self, node: u32) -> Result<ExprRef> {
3109 let written = self.text(node).trim();
3110 let written = written.trim_start_matches(['?', '$']).trim();
3111 let name = if written.is_empty() {
3112 self.anonymous += 1;
3113 self.anonymous.to_string()
3114 } else {
3115 written.to_string()
3116 };
3117 let name = self.intern(&name);
3118 Ok(self.push(Expr::Parameter { name }))
3119 }
3120
3121 fn list(&mut self, node: u32) -> Result<ExprRef> {
3126 let mut items = Vec::new();
3127 for kid in self.kids(node) {
3128 items.push(self.expr(kid)?);
3129 }
3130 let items = self.expr_slice(items);
3131 Ok(self.push(Expr::List { items }))
3132 }
3133
3134 fn subquery(&mut self, node: u32) -> Result<ExprRef> {
3136 let negated = self.find(node, "SubqueryNot") != NONE;
3137 let exists = self.find(node, "SubqueryExists") != NONE;
3138 let reference = self.find(node, "SubqueryReference");
3139 let query = self.query(self.first(reference))?;
3140 Ok(if exists {
3141 self.push(Expr::Exists { query, negated })
3142 } else if negated {
3143 return self.unsupported(node);
3144 } else {
3145 self.push(Expr::Subquery { query })
3146 })
3147 }
3148
3149 fn string_value(&self, node: u32) -> Result<String> {
3155 let span = self.tree.node(node);
3156 let mut value = String::new();
3157 for token in &self.tokens[span.start as usize..span.end as usize] {
3158 if token.kind == Kind::String {
3159 value.push_str(&string_token(token.text(self.query))?);
3160 }
3161 }
3162 Ok(value)
3163 }
3164
3165 fn first_string(&self, node: u32) -> &'a str {
3171 let span = self.tree.node(node);
3172 self.tokens[span.start as usize..span.end as usize]
3173 .iter()
3174 .find(|token| token.kind == Kind::String)
3175 .map_or("", |token| token.text(self.query))
3176 }
3177
3178 fn string_literal(&mut self, node: u32) -> Result<ExprRef> {
3187 let token = self.first_string(node);
3188 let prefix = match token.as_bytes() {
3189 [prefix, b'\'', ..] => *prefix,
3190 _ => 0,
3191 };
3192 if matches!(prefix, b'X' | b'x') {
3193 if let Some(body) = token.get(1..).and_then(quoted_body) {
3194 let text = blob_text(body.as_bytes())?;
3195 let text = self.intern(&text);
3196 return Ok(self.push(Expr::Literal { kind: LiteralKind::Blob, text }));
3197 }
3198 }
3199 let value = self.string_value(node)?;
3200 let text = self.intern(&value);
3201 let literal = self.push(Expr::Literal { kind: LiteralKind::String, text });
3202 if matches!(prefix, b'N' | b'n') {
3203 let ty = self.intern("VARCHAR");
3204 return Ok(self.push(Expr::Cast { operand: literal, ty, try_cast: false }));
3205 }
3206 Ok(literal)
3207 }
3208}
3209
3210const UNITS: &[(&str, &str, Option<&str>)] = &[
3218 ("YearKeyword", "to_years", Some("INTEGER")),
3219 ("MonthKeyword", "to_months", Some("INTEGER")),
3220 ("QuarterKeyword", "to_quarters", Some("INTEGER")),
3221 ("DecadeKeyword", "to_decades", Some("INTEGER")),
3222 ("CenturyKeyword", "to_centuries", Some("INTEGER")),
3223 ("MillenniumKeyword", "to_millennia", Some("INTEGER")),
3224 ("DayKeyword", "to_days", Some("INTEGER")),
3225 ("WeekKeyword", "to_weeks", Some("INTEGER")),
3226 ("HourKeyword", "to_hours", Some("BIGINT")),
3227 ("MinuteKeyword", "to_minutes", Some("BIGINT")),
3228 ("MicrosecondKeyword", "to_microseconds", Some("BIGINT")),
3229 ("SecondKeyword", "to_seconds", None),
3230 ("MillisecondKeyword", "to_milliseconds", None),
3231];
3232
3233fn date_part(written: &str) -> String {
3244 const PARTS: &[(&str, &str)] = &[
3245 ("YEAR", "YEAR"),
3246 ("YEARS", "YEAR"),
3247 ("MONTH", "MONTH"),
3248 ("MONTHS", "MONTH"),
3249 ("DAY", "DAY"),
3250 ("DAYS", "DAY"),
3251 ("HOUR", "HOUR"),
3252 ("HOURS", "HOUR"),
3253 ("MINUTE", "MINUTE"),
3254 ("MINUTES", "MINUTE"),
3255 ("SECOND", "SECOND"),
3256 ("SECONDS", "SECOND"),
3257 ("MILLISECOND", "MILLISECONDS"),
3258 ("MILLISECONDS", "MILLISECONDS"),
3259 ("MICROSECOND", "MICROSECONDS"),
3260 ("MICROSECONDS", "MICROSECONDS"),
3261 ("WEEK", "WEEK"),
3262 ("WEEKS", "WEEK"),
3263 ("QUARTER", "QUARTER"),
3264 ("QUARTERS", "QUARTER"),
3265 ("DECADE", "DECADE"),
3266 ("DECADES", "DECADE"),
3267 ("CENTURY", "CENTURY"),
3268 ("CENTURIES", "CENTURY"),
3269 ("MILLENNIUM", "MILLENNIUM"),
3270 ("MILLENNIA", "MILLENNIUM"),
3271 ];
3272 PARTS
3273 .iter()
3274 .find(|(spelling, _)| spelling.eq_ignore_ascii_case(written))
3275 .map_or_else(|| written.to_string(), |(_, name)| (*name).to_string())
3276}
3277
3278fn worded(rule: &str) -> String {
3280 let mut out = String::new();
3281 for character in rule.chars() {
3282 if character.is_ascii_uppercase() && !out.is_empty() {
3283 out.push(' ');
3284 }
3285 out.push(character.to_ascii_uppercase());
3286 }
3287 out
3288}
3289
3290fn string_token(text: &str) -> Result<String> {
3297 if let Some(body) = dollar_body(text) {
3298 return Ok(body.to_string());
3299 }
3300 if let Some(body) = quoted_body(text) {
3301 return Ok(body.replace("''", "'"));
3302 }
3303 let Some(body) = text.get(1..).and_then(quoted_body) else {
3304 return Ok(text.to_string());
3305 };
3306 match text.as_bytes()[0] {
3307 b'E' | b'e' => escaped(body),
3308 b'N' | b'n' => Ok(body.replace("''", "'")),
3310 b'B' | b'b' => Ok(format!("b{}", body.replace("''", "'"))),
3314 _ => Err(Error::not_implemented(format!("the string literal {text} is not supported yet"))),
3317 }
3318}
3319
3320fn blob_text(body: &[u8]) -> Result<String> {
3332 if body.len() % 2 != 0 {
3333 return Err(Error::parser("Hex string literal must have an even number of hex digits"));
3334 }
3335 let digit = |byte: u8| (byte as char).to_digit(16).map(|digit| digit as u8);
3336 let bytes: Option<Vec<u8>> =
3337 body.chunks(2).map(|pair| Some(digit(pair[0])? * 16 + digit(pair[1])?)).collect();
3338 match bytes {
3339 Some(bytes) => Ok(Value::Blob(bytes).to_string()),
3340 None => {
3341 Ok(body.chunks(2).map(|pair| format!("\\x{}", String::from_utf8_lossy(pair))).collect())
3342 }
3343 }
3344}
3345
3346fn quoted_body(text: &str) -> Option<&str> {
3351 text.strip_prefix('\'').filter(|rest| !rest.is_empty()).and_then(|rest| rest.strip_suffix('\''))
3352}
3353
3354fn escaped(body: &str) -> Result<String> {
3367 let bytes = body.as_bytes();
3368 let mut out = Vec::with_capacity(bytes.len());
3369 let mut at = 0;
3370 while at < bytes.len() {
3371 let byte = bytes[at];
3372 at += 1;
3373 if byte == b'\'' && bytes.get(at) == Some(&b'\'') {
3374 out.push(b'\'');
3375 at += 1;
3376 continue;
3377 }
3378 if byte != b'\\' || at == bytes.len() {
3379 out.push(byte);
3380 continue;
3381 }
3382 let escape = bytes[at];
3383 at += 1;
3384 match escape {
3385 b'n' => out.push(b'\n'),
3386 b't' => out.push(b'\t'),
3387 b'r' => out.push(b'\r'),
3388 b'b' => out.push(0x08),
3389 b'f' => out.push(0x0c),
3390 b'x' => match digits(bytes, &mut at, 16, 2) {
3391 Some(value) => out.push(value as u8),
3392 None => out.push(b'x'),
3393 },
3394 b'0'..=b'7' => {
3395 at -= 1;
3396 let value = digits(bytes, &mut at, 8, 3).unwrap_or(0);
3397 out.push(value as u8);
3398 }
3399 b'u' => match four_hex(bytes, at).and_then(char::from_u32).filter(|c| *c != '\0') {
3400 Some(c) => {
3401 at += 4;
3402 out.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes());
3403 }
3404 None => out.push(b'u'),
3405 },
3406 other => out.push(other),
3407 }
3408 }
3409 if out.contains(&0) {
3410 return Err(Error::parser("Null character not permitted in escape string literal"));
3411 }
3412 String::from_utf8(out).map_err(|error| {
3413 Error::parser(format!(
3414 "Invalid UTF-8 in escape string literal at byte offset {}: byte mismatch",
3415 error.utf8_error().valid_up_to()
3416 ))
3417 })
3418}
3419
3420fn digits(bytes: &[u8], at: &mut usize, radix: u32, most: usize) -> Option<u32> {
3425 let mut value = None;
3426 for _ in 0..most {
3427 let Some(digit) = bytes.get(*at).and_then(|byte| (*byte as char).to_digit(radix)) else {
3428 break;
3429 };
3430 value = Some(value.unwrap_or(0) * radix + digit);
3431 *at += 1;
3432 }
3433 value
3434}
3435
3436fn four_hex(bytes: &[u8], at: usize) -> Option<u32> {
3442 let digits = bytes.get(at..at + 4)?;
3443 if !digits.iter().all(u8::is_ascii_hexdigit) {
3444 return None;
3445 }
3446 u32::from_str_radix(std::str::from_utf8(digits).ok()?, 16).ok()
3447}
3448
3449fn dollar_body(text: &str) -> Option<&str> {
3458 let rest = text.strip_prefix('$')?;
3459 let close = rest.find('$')?;
3460 let (tag, body) = (&rest[..close], &rest[close + 1..]);
3461 body.strip_suffix(&format!("${tag}$"))
3462}
3463
3464fn unquote(text: &str) -> String {
3474 if let Some(body) = text.strip_prefix('"').and_then(|rest| rest.strip_suffix('"')) {
3475 return body.replace("\"\"", "\"");
3476 }
3477 match text.strip_prefix('\'').and_then(|rest| rest.strip_suffix('\'')) {
3478 Some(body) => body.replace("''", "'"),
3479 None => text.to_string(),
3480 }
3481}
3482
3483#[cfg(test)]
3484mod tests {
3485 use super::*;
3486 use crate::corpus::CORPUS;
3487 use crate::matcher::parse;
3488
3489 fn show(ast: &Ast, expr: ExprRef) -> String {
3497 if expr == NONE {
3498 return "-".to_string();
3499 }
3500 fn shown_filter(ast: &Ast, filter: ExprRef) -> String {
3502 if filter == NONE { String::new() } else { format!(" FILTER [{}]", show(ast, filter)) }
3503 }
3504 fn keys(ast: &Ast, slice: Slice) -> String {
3506 ast.order_list(slice)
3507 .iter()
3508 .map(|item| format!("{} {:?} {:?}", show(ast, item.expr), item.order, item.nulls))
3509 .collect::<Vec<_>>()
3510 .join(", ")
3511 }
3512 let list = |slice: Slice| {
3513 ast.expr_list(slice).iter().map(|&item| show(ast, item)).collect::<Vec<_>>().join(", ")
3514 };
3515 match ast.expr(expr) {
3516 Expr::Star { qualifier, replacements } => {
3517 let star = if qualifier.is_empty() {
3518 "*".to_string()
3519 } else {
3520 format!("{}.*", ast.name_text(qualifier))
3521 };
3522 if replacements.is_empty() {
3523 return star;
3524 }
3525 let entries: Vec<String> = ast
3526 .target_list(replacements)
3527 .iter()
3528 .map(|target| {
3529 format!("{} AS {}", show(ast, target.expr), ast.string(target.alias))
3530 })
3531 .collect();
3532 format!("{star} REPLACE ({})", entries.join(", "))
3533 }
3534 Expr::Column { name } => ast.name_text(name),
3535 Expr::Literal { kind, text } => match kind {
3536 LiteralKind::Number => ast.string(text).to_string(),
3537 LiteralKind::String => format!("'{}'", ast.string(text)),
3538 LiteralKind::Blob => format!("'{}'::BLOB", ast.string(text)),
3539 other => format!("{other:?}").to_uppercase(),
3540 },
3541 Expr::Unary { op, operand } => format!("({op:?} {})", show(ast, operand)),
3542 Expr::Binary { op, left, right } => {
3543 let op = match op {
3544 BinaryOp::Named(name) => ast.string(name).to_string(),
3545 other => format!("{other:?}"),
3546 };
3547 format!("({} {op} {})", show(ast, left), show(ast, right))
3548 }
3549 Expr::Function { name, args, distinct, filter } => {
3550 let distinct = if distinct { "DISTINCT " } else { "" };
3551 let filter = shown_filter(ast, filter);
3552 format!("{}({distinct}{}){filter}", ast.name_text(name), list(args))
3553 }
3554 Expr::Window { name, args, distinct, filter, ignore_nulls, order: inner, spec } => {
3555 let distinct = if distinct { "DISTINCT " } else { "" };
3556 let filter = shown_filter(ast, filter);
3557 let nulls = if ignore_nulls { " IGNORE NULLS" } else { "" };
3558 let inner = keys(ast, inner);
3559 let inner = if inner.is_empty() { inner } else { format!(" ORDER BY {inner}") };
3560 let held = ast.window(spec);
3561 let order = keys(ast, held.order);
3562 let bound = |end: WindowBound| match end {
3563 WindowBound::Preceding(offset) => format!("Preceding({})", show(ast, offset)),
3564 WindowBound::Following(offset) => format!("Following({})", show(ast, offset)),
3565 other => format!("{other:?}"),
3566 };
3567 format!(
3568 "{}({distinct}{}{inner}{nulls}){filter} OVER [{}] [{order}] [{:?} {} {} {:?}]",
3569 ast.name_text(name),
3570 list(args),
3571 list(held.partition),
3572 held.unit,
3573 bound(held.start),
3574 bound(held.end),
3575 held.exclude
3576 )
3577 }
3578 Expr::Cast { operand, ty, try_cast } => {
3579 let word = if try_cast { "TRY_CAST" } else { "CAST" };
3580 format!("{word}({} AS {})", show(ast, operand), ast.string(ty))
3581 }
3582 Expr::Case { operand, arms, otherwise } => {
3583 let arms = ast
3584 .arm_list(arms)
3585 .iter()
3586 .map(|arm| format!("WHEN {} THEN {}", show(ast, arm.when), show(ast, arm.then)))
3587 .collect::<Vec<_>>()
3588 .join(" ");
3589 format!("CASE {} {arms} ELSE {} END", show(ast, operand), show(ast, otherwise))
3590 }
3591 Expr::Between { operand, low, high, negated } => {
3592 let not = if negated { "NOT " } else { "" };
3593 format!(
3594 "({not}{} BETWEEN {} AND {})",
3595 show(ast, operand),
3596 show(ast, low),
3597 show(ast, high)
3598 )
3599 }
3600 Expr::In { operand, list: items, negated } => {
3601 let not = if negated { "NOT " } else { "" };
3602 format!("({not}{} IN [{}])", show(ast, operand), list(items))
3603 }
3604 Expr::List { items } => format!("[{}]", list(items)),
3605 Expr::Parameter { name } => format!("${}", ast.string(name)),
3606 Expr::Row { items } => format!("ROW({})", list(items)),
3607 Expr::Subquery { query } => format!("({})", show_query(ast, query)),
3608 Expr::Exists { query, negated } => {
3609 let exists = format!("EXISTS ({})", show_query(ast, query));
3610 if negated { format!("NOT {exists}") } else { exists }
3611 }
3612 Expr::InSubquery { operand, query, negated } => {
3613 let written = format!("{} IN ({})", show(ast, operand), show_query(ast, query));
3614 if negated { format!("NOT {written}") } else { written }
3615 }
3616 Expr::QuantifiedSubquery { operand, op, query, all } => {
3617 let quantifier = if all { "ALL" } else { "ANY" };
3618 format!("{} {op:?} {quantifier} ({})", show(ast, operand), show_query(ast, query))
3619 }
3620 }
3621 }
3622
3623 fn show_source(ast: &Ast, source: SourceRef) -> String {
3625 let alias = |alias: StrRef| match alias {
3626 NONE => String::new(),
3627 other => format!(" AS {}", ast.string(other)),
3628 };
3629 match ast.source(source) {
3630 Source::Table { name, alias: name_alias, .. } => {
3631 format!("{}{}", ast.name_text(name), alias(name_alias))
3632 }
3633 Source::Function { name, args, alias: call_alias, .. } => {
3634 let args = ast
3635 .target_list(args)
3636 .iter()
3637 .map(|item| match item.alias {
3638 NONE => show(ast, item.expr),
3639 named => format!("{} := {}", ast.string(named), show(ast, item.expr)),
3640 })
3641 .collect::<Vec<_>>()
3642 .join(", ");
3643 format!("{}({args}){}", ast.name_text(name), alias(call_alias))
3644 }
3645 Source::Subquery { query, alias: query_alias, .. } => {
3646 format!("({}){}", show_query(ast, query), alias(query_alias))
3647 }
3648 Source::Cte { cte, alias: cte_alias, .. } => {
3649 format!("{}{}", ast.string(ast.cte(cte).name), alias(cte_alias))
3650 }
3651 Source::Values { rows, alias: values_alias, .. } => {
3652 format!("{}{}", show_rows(ast, rows), alias(values_alias))
3653 }
3654 Source::Join { left, right, kind, natural, on, using } => {
3655 let natural = if natural { "NATURAL " } else { "" };
3656 let on = if on == NONE { String::new() } else { format!(" ON {}", show(ast, on)) };
3657 let using = if using.is_empty() {
3658 String::new()
3659 } else {
3660 format!(" USING ({})", ast.name_text(using))
3661 };
3662 format!(
3663 "({} {natural}{kind:?} JOIN {}{on}{using})",
3664 show_source(ast, left),
3665 show_source(ast, right)
3666 )
3667 }
3668 }
3669 }
3670
3671 fn show_rows(ast: &Ast, rows: Slice) -> String {
3673 let rows = ast
3674 .rows(rows)
3675 .iter()
3676 .map(|&row| {
3677 let items = ast
3678 .expr_list(row)
3679 .iter()
3680 .map(|&item| show(ast, item))
3681 .collect::<Vec<_>>()
3682 .join(", ");
3683 format!("({items})")
3684 })
3685 .collect::<Vec<_>>()
3686 .join(", ");
3687 format!("VALUES {rows}")
3688 }
3689
3690 fn show_query(ast: &Ast, index: QueryRef) -> String {
3692 let query = ast.query(index);
3693 let list = |slice: Slice| {
3694 ast.expr_list(slice).iter().map(|&item| show(ast, item)).collect::<Vec<_>>().join(", ")
3695 };
3696 let mut out = String::new();
3697 for &index in ast.cte_list(query.ctes) {
3698 let cte = ast.cte(index);
3699 let columns = ast.name(cte.columns).collect::<Vec<_>>().join(", ");
3700 let columns = if columns.is_empty() { columns } else { format!("({columns})") };
3701 out += &format!(
3702 "WITH {}{columns} AS MATERIALIZED ({}) ",
3703 ast.string(cte.name),
3704 show_query(ast, cte.query)
3705 );
3706 }
3707 out += &match query.body {
3708 QueryBody::SetOp { op, quantifier, by_name, left, right } => {
3709 let by_name = if by_name { " BY NAME" } else { "" };
3710 format!(
3711 "({} {op:?} {quantifier:?}{by_name} {})",
3712 show_query(ast, left),
3713 show_query(ast, right)
3714 )
3715 }
3716 QueryBody::Select(index) => {
3717 let select = ast.select(index);
3718 let distinct = match select.distinct {
3719 Distinct::No => String::new(),
3720 Distinct::Yes => " DISTINCT".to_string(),
3721 Distinct::On(on) => format!(" DISTINCT ON ({})", list(on)),
3722 };
3723 let targets = ast
3724 .target_list(select.targets)
3725 .iter()
3726 .map(|target| match target.alias {
3727 NONE => show(ast, target.expr),
3728 alias => format!("{} AS {}", show(ast, target.expr), ast.string(alias)),
3729 })
3730 .collect::<Vec<_>>()
3731 .join(", ");
3732 let mut out = format!("SELECT{distinct} {targets}");
3733 if !select.from.is_empty() {
3734 let from = ast
3735 .source_list(select.from)
3736 .iter()
3737 .map(|&source| show_source(ast, source))
3738 .collect::<Vec<_>>()
3739 .join(", ");
3740 out += &format!(" FROM {from}");
3741 }
3742 if select.filter != NONE {
3743 out += &format!(" WHERE {}", show(ast, select.filter));
3744 }
3745 if select.group_by_all {
3746 out += " GROUP BY ALL";
3747 } else if !select.group_by.is_empty() {
3748 out += &format!(" GROUP BY {}", list(select.group_by));
3749 }
3750 if select.having != NONE {
3751 out += &format!(" HAVING {}", show(ast, select.having));
3752 }
3753 out
3754 }
3755 QueryBody::Values(rows) => show_rows(ast, rows),
3756 QueryBody::Describe(inner) => format!("DESCRIBE {}", show_query(ast, inner)),
3757 QueryBody::Show { name, .. } => format!("SHOW {}", ast.name_text(name)),
3758 };
3759 if query.order_by_all {
3760 out += " ORDER BY ALL";
3761 } else if !query.order_by.is_empty() {
3762 let items = ast
3763 .order_list(query.order_by)
3764 .iter()
3765 .map(|item| format!("{} {:?} {:?}", show(ast, item.expr), item.order, item.nulls))
3766 .collect::<Vec<_>>()
3767 .join(", ");
3768 out += &format!(" ORDER BY {items}");
3769 }
3770 if query.limit != NONE {
3771 let percent = if query.limit_percent { "%" } else { "" };
3772 out += &format!(" LIMIT {}{percent}", show(ast, query.limit));
3773 }
3774 if query.offset != NONE {
3775 out += &format!(" OFFSET {}", show(ast, query.offset));
3776 }
3777 out
3778 }
3779
3780 fn round(query: &str) -> String {
3782 let ast = parse_ast(query).unwrap_or_else(|error| panic!("{query}: {error}"));
3783 assert_eq!(ast.statements.len(), 1, "{query} is one statement");
3784 let Statement::Query(index) = ast.statements[0] else {
3785 panic!("{query} is not a query");
3786 };
3787 show_query(&ast, index)
3788 }
3789
3790 fn round_with_case(query: &str, case: IdentifierCase) -> String {
3791 let ast =
3792 parse_ast_with_case(query, case).unwrap_or_else(|error| panic!("{query}: {error}"));
3793 let Statement::Query(index) = ast.statements[0] else {
3794 panic!("{query} is not a query");
3795 };
3796 show_query(&ast, index)
3797 }
3798
3799 fn round_statement(query: &str) -> String {
3801 let ast = parse_ast(query).unwrap_or_else(|error| panic!("{query}: {error}"));
3802 assert_eq!(ast.statements.len(), 1, "{query} is one statement");
3803 match ast.statements[0] {
3804 Statement::Query(index) => show_query(&ast, index),
3805 Statement::CreateTable(index) => {
3806 let create = ast.create_table(index);
3807 let mut out = "CREATE".to_string();
3808 if create.or_replace {
3809 out += " OR REPLACE";
3810 }
3811 if create.temporary {
3812 out += " TEMPORARY";
3813 }
3814 out += " TABLE";
3815 if create.if_not_exists {
3816 out += " IF NOT EXISTS";
3817 }
3818 out += &format!(" {}", ast.name_text(create.name));
3819 let columns = ast
3820 .column_defs(create.columns)
3821 .iter()
3822 .map(|def| {
3823 let ty = match def.ty {
3824 NONE => String::new(),
3825 other => format!(" {}", ast.string(other)),
3826 };
3827 let null = if def.not_null { " NOT NULL" } else { "" };
3828 format!("{}{ty}{null}", ast.string(def.name))
3829 })
3830 .collect::<Vec<_>>()
3831 .join(", ");
3832 if !columns.is_empty() || create.query == NONE {
3833 out += &format!(" ({columns})");
3834 }
3835 if create.query != NONE {
3836 out += &format!(" AS {}", show_query(&ast, create.query));
3837 }
3838 out
3839 }
3840 Statement::CreateView(index) => {
3841 let create = ast.create_view(index);
3842 let mut out = "CREATE".to_string();
3843 if create.or_replace {
3844 out += " OR REPLACE";
3845 }
3846 if create.temporary {
3847 out += " TEMPORARY";
3848 }
3849 out += " VIEW";
3850 if create.if_not_exists {
3851 out += " IF NOT EXISTS";
3852 }
3853 out += &format!(" {}", ast.name_text(create.name));
3854 if !create.columns.is_empty() {
3855 let columns = ast.name(create.columns).collect::<Vec<_>>().join(", ");
3856 out += &format!(" ({columns})");
3857 }
3858 out + &format!(" AS {}", show_query(&ast, create.query))
3859 }
3860 Statement::DropTable(index) => {
3861 let drop = ast.drop_table(index);
3862 let mut out = if drop.view { "DROP VIEW" } else { "DROP TABLE" }.to_string();
3863 if drop.if_exists {
3864 out += " IF EXISTS";
3865 }
3866 let names = ast
3867 .name_list(drop.names)
3868 .iter()
3869 .map(|&name| ast.name_text(name))
3870 .collect::<Vec<_>>()
3871 .join(", ");
3872 out + &format!(" {names}")
3873 }
3874 Statement::Insert(index) => {
3875 let insert = ast.insert(index);
3876 let mut out = format!("INSERT INTO {}", ast.name_text(insert.name));
3877 if !insert.columns.is_empty() {
3878 let columns = ast.name(insert.columns).collect::<Vec<_>>().join(", ");
3879 out += &format!(" ({columns})");
3880 }
3881 out + &format!(" {}", show_query(&ast, insert.source))
3882 }
3883 Statement::Set(index) if ast.setting(index).pragma => {
3884 format!("PRAGMA {}", ast.string(ast.setting(index).name))
3885 }
3886 Statement::Set(index) => {
3887 let setting = ast.setting(index);
3888 let scope = match setting.scope.keyword() {
3889 "" => String::new(),
3890 word => format!(" {word}"),
3891 };
3892 format!("SET{scope} {} = {}", ast.string(setting.name), show(&ast, setting.value))
3893 }
3894 Statement::Reset(index) => {
3895 let setting = ast.setting(index);
3896 let scope = match setting.scope.keyword() {
3897 "" => String::new(),
3898 word => format!(" {word}"),
3899 };
3900 format!("RESET{scope} {}", ast.string(setting.name))
3901 }
3902 Statement::Checkpoint => "CHECKPOINT".to_string(),
3903 Statement::Explain { query, analyze, statistics } => {
3904 let analyze = if analyze { "ANALYZE " } else { "" };
3905 let statistics = if statistics { "(STATISTICS) " } else { "" };
3906 format!("EXPLAIN {analyze}{statistics}{}", show_query(&ast, query))
3907 }
3908 }
3909 }
3910
3911 #[test]
3912 fn expressions_and_queries_keep_their_source_ranges() {
3913 let sql = "SELECT 1 + 22";
3914 let ast = parse_ast(sql).expect("the query parses");
3915 let Statement::Query(query) = ast.statements[0] else { panic!("a query") };
3916 assert_eq!(ast.query_span(query), Span::new(0, sql.len() as u32));
3917 let twenty_two = ast
3918 .exprs
3919 .iter()
3920 .enumerate()
3921 .find_map(|(at, expr)| match *expr {
3922 Expr::Literal { kind: LiteralKind::Number, text } if ast.string(text) == "22" => {
3923 Some(at as u32)
3924 }
3925 _ => None,
3926 })
3927 .expect("the literal is in the arena");
3928 assert_eq!(ast.expr_span(twenty_two), Span::new(11, 13));
3929 }
3930
3931 #[test]
3932 fn an_explain_keeps_the_query_it_was_asked_about() {
3933 assert_eq!(
3934 round_statement("EXPLAIN SELECT a FROM t WHERE a > 1"),
3935 "EXPLAIN SELECT a FROM t WHERE (a Gt 1)"
3936 );
3937 assert_eq!(round_statement("explain select 1"), "EXPLAIN SELECT 1");
3938 assert_eq!(round_statement("explain analyze select 1"), "EXPLAIN ANALYZE SELECT 1");
3939 }
3940
3941 #[test]
3942 fn the_three_explain_options_this_answers_mean_what_their_names_say() {
3943 assert_eq!(round_statement("EXPLAIN (ANALYZE) SELECT 1"), "EXPLAIN ANALYZE SELECT 1");
3946 assert_eq!(
3947 round_statement("explain (analyze) select 1"),
3948 round_statement("explain analyze select 1")
3949 );
3950 assert_eq!(round_statement("EXPLAIN (LOGICAL) SELECT 1"), "EXPLAIN SELECT 1");
3952 assert_eq!(
3953 round_statement("EXPLAIN (STATISTICS) SELECT 1"),
3954 "EXPLAIN (STATISTICS) SELECT 1"
3955 );
3956 assert_eq!(
3957 round_statement("EXPLAIN (ANALYZE, STATISTICS) SELECT 1"),
3958 "EXPLAIN ANALYZE (STATISTICS) SELECT 1"
3959 );
3960 assert_eq!(
3961 round_statement("EXPLAIN ANALYZE (STATISTICS) SELECT 1"),
3962 "EXPLAIN ANALYZE (STATISTICS) SELECT 1"
3963 );
3964 }
3965
3966 #[test]
3967 fn the_parts_of_an_explain_that_are_not_the_query_are_refused_by_name() {
3968 for (query, named) in [
3972 ("EXPLAIN (FORMAT JSON) SELECT 1", "Unimplemented explain type: format"),
3973 ("EXPLAIN (NONSENSE) SELECT 1", "Unimplemented explain type: nonsense"),
3974 ("EXPLAIN (ANALYZE false) SELECT 1", "ExplainOption"),
3975 ("EXPLAIN INSERT INTO t VALUES (1)", "InsertStatement"),
3976 ("EXPLAIN CREATE TABLE u (a INTEGER)", "CreateStatement"),
3977 ] {
3978 let error = parse_ast(query).expect_err(query).to_string();
3979 assert!(error.contains(named), "{query}: {error}");
3980 }
3981 }
3982
3983 #[test]
3984 fn a_set_keeps_its_name_its_scope_and_its_value() {
3985 assert_eq!(round_statement("SET memory_limit = '1GB'"), "SET memory_limit = '1GB'");
3986 assert_eq!(round_statement("set threads=4"), "SET threads = 4");
3987 assert_eq!(round_statement("SET GLOBAL threads = 4"), "SET GLOBAL threads = 4");
3988 assert_eq!(round_statement("SET SESSION threads = 4"), "SET SESSION threads = 4");
3989 assert_eq!(round_statement("SET LOCAL threads = 4"), "SET LOCAL threads = 4");
3990 assert_eq!(round_statement("RESET memory_limit"), "RESET memory_limit");
3991 assert_eq!(round_statement("RESET GLOBAL memory_limit"), "RESET GLOBAL memory_limit");
3992 assert_eq!(
3993 round_statement("SET TIME ZONE 'Asia/Kathmandu'"),
3994 "SET TimeZone = 'Asia/Kathmandu'"
3995 );
3996 assert_eq!(round_statement("SET TIME ZONE UTC"), "SET TimeZone = 'UTC'");
3997 assert_eq!(round_statement("SET TIME ZONE DEFAULT"), "RESET TimeZone");
3998 assert_eq!(round_statement("SET TIME ZONE LOCAL"), "RESET TimeZone");
3999 }
4000
4001 #[test]
4002 fn the_two_other_things_the_word_set_starts_are_refused_rather_than_read_as_settings() {
4003 for statement in ["SET VARIABLE x = 1", "SET SCHEMA 'main'"] {
4007 let error = parse_ast(statement).expect_err(statement);
4008 assert_eq!(error.code().duckdb_name(), "Not implemented Error", "{statement}");
4009 }
4010 }
4011
4012 #[test]
4013 fn a_setting_written_with_a_list_of_values_is_refused_rather_than_taking_the_first() {
4014 let error = parse_ast("SET search_path = a, b").expect_err("a list of two");
4015 assert_eq!(error.code().duckdb_name(), "Not implemented Error");
4016 }
4017
4018 #[test]
4019 fn the_query_m0_has_to_run_transforms() {
4020 assert_eq!(round("SELECT * FROM t WHERE x > 5"), "SELECT * FROM t WHERE (x Gt 5)");
4021 }
4022
4023 #[test]
4024 fn a_replace_list_rides_on_the_star_it_changes() {
4025 assert_eq!(
4028 round("SELECT * REPLACE (a + 1 AS a) FROM t"),
4029 "SELECT * REPLACE ((a Add 1) AS a) FROM t"
4030 );
4031 assert_eq!(
4032 round("SELECT * REPLACE a + 1 AS a FROM t"),
4033 "SELECT * REPLACE ((a Add 1) AS a) FROM t"
4034 );
4035 assert_eq!(
4036 round("SELECT t.* REPLACE (make_date(a) AS a, b * 2 AS b) FROM t"),
4037 "SELECT t.* REPLACE (make_date(a) AS a, (b Multiply 2) AS b) FROM t"
4038 );
4039 }
4040
4041 #[test]
4042 fn one_column_cannot_be_replaced_twice() {
4043 let error = parse_ast("SELECT * REPLACE (a + 1 AS a, a + 2 AS A) FROM t").unwrap_err();
4046 assert_eq!(error.to_string(), "Parser Error: Duplicate entry \"A\" in REPLACE list");
4047 }
4048
4049 #[test]
4050 fn a_table_function_argument_can_have_a_name_written_in_front_of_it() {
4051 for spelling in
4054 ["binary_as_string := True", "binary_as_string => True", "binary_as_string = True"]
4055 {
4056 assert_eq!(
4057 round(&format!("SELECT * FROM read_parquet('f.parquet', {spelling})")),
4058 "SELECT * FROM read_parquet('f.parquet', binary_as_string := TRUE)",
4059 "{spelling}"
4060 );
4061 }
4062 }
4063
4064 #[test]
4065 fn an_equality_that_is_not_a_bare_name_stays_an_argument() {
4066 assert_eq!(round("SELECT * FROM f(t.a = 1)"), "SELECT * FROM f((t.a Eq 1))");
4069 assert_eq!(round("SELECT * FROM f(1 = 1)"), "SELECT * FROM f((1 Eq 1))");
4070 }
4071
4072 #[test]
4073 fn a_create_table_keeps_its_types_as_text() {
4074 assert_eq!(
4075 round_statement("CREATE TABLE t (a INTEGER, b VARCHAR NOT NULL)"),
4076 "CREATE TABLE t (a INTEGER, b VARCHAR NOT NULL)"
4077 );
4078 assert_eq!(
4082 round_statement("CREATE TABLE t (a DECIMAL(18, 3), b STRUCT(x INT))"),
4083 "CREATE TABLE t (a DECIMAL(18, 3), b STRUCT(x INT))"
4084 );
4085 }
4086
4087 #[test]
4088 fn the_modifiers_on_a_create_table_survive() {
4089 assert_eq!(
4090 round_statement("CREATE OR REPLACE TEMPORARY TABLE s.t (a INT)"),
4091 "CREATE OR REPLACE TEMPORARY TABLE s.t (a INT)"
4092 );
4093 assert_eq!(
4094 round_statement("CREATE TEMPORARY TABLE IF NOT EXISTS s.t (a INT)"),
4095 "CREATE TEMPORARY TABLE IF NOT EXISTS s.t (a INT)"
4096 );
4097 }
4098
4099 #[test]
4100 fn or_replace_and_if_not_exists_in_one_statement_is_refused_here_and_not_later() {
4101 for sql in [
4105 "CREATE OR REPLACE TABLE IF NOT EXISTS t (a INT)",
4106 "CREATE OR REPLACE VIEW IF NOT EXISTS v AS SELECT 1",
4107 ] {
4108 let error = parse_ast(sql).unwrap_err().to_string();
4109 assert_eq!(
4110 error,
4111 "Parser Error: Cannot specify both OR REPLACE and IF NOT EXISTS within single \
4112 create statement"
4113 );
4114 }
4115 }
4116
4117 #[test]
4118 fn a_create_table_as_carries_the_query_and_not_the_types() {
4119 assert_eq!(
4120 round_statement("CREATE TABLE t AS SELECT a FROM u"),
4121 "CREATE TABLE t AS SELECT a FROM u"
4122 );
4123 assert_eq!(
4126 round_statement("CREATE TABLE t (x, y) AS SELECT a, b FROM u"),
4127 "CREATE TABLE t (x, y) AS SELECT a, b FROM u"
4128 );
4129 }
4130
4131 #[test]
4132 fn a_create_view_carries_its_body_twice_over() {
4133 assert_eq!(
4134 round_statement("CREATE VIEW v AS SELECT a FROM u"),
4135 "CREATE VIEW v AS SELECT a FROM u"
4136 );
4137 assert_eq!(
4138 round_statement("CREATE OR REPLACE VIEW main.v (x, y) AS SELECT a, b FROM u"),
4139 "CREATE OR REPLACE VIEW main.v (x, y) AS SELECT a, b FROM u"
4140 );
4141 let ast = parse_ast("CREATE VIEW v (x) AS SELECT a FROM u WHERE a > 1").expect("parses");
4144 let Statement::CreateView(index) = ast.statements[0] else {
4145 panic!("not a create view");
4146 };
4147 assert_eq!(ast.string(ast.create_view(index).sql), "SELECT a FROM u WHERE a > 1");
4148 }
4149
4150 #[test]
4151 fn a_drop_view_is_not_a_drop_table() {
4152 assert_eq!(round_statement("DROP VIEW IF EXISTS a, b"), "DROP VIEW IF EXISTS a, b");
4153 assert_eq!(round_statement("DROP TABLE a"), "DROP TABLE a");
4154 }
4155
4156 #[test]
4157 fn a_drop_table_is_a_list_of_qualified_names() {
4158 assert_eq!(round_statement("DROP TABLE t"), "DROP TABLE t");
4159 assert_eq!(round_statement("DROP TABLE IF EXISTS a, b.c"), "DROP TABLE IF EXISTS a, b.c");
4160 }
4161
4162 #[test]
4163 fn dropping_something_that_is_neither_a_table_nor_a_view_is_refused() {
4164 let error = parse_ast("DROP MATERIALIZED VIEW v").unwrap_err().to_string();
4168 assert!(error.starts_with("Not implemented Error"), "{error}");
4169 }
4170
4171 #[test]
4172 fn both_spellings_of_insert_arrive_at_a_query() {
4173 assert_eq!(
4174 round_statement("INSERT INTO t VALUES (1, 'a'), (2, 'b')"),
4175 "INSERT INTO t VALUES (1, 'a'), (2, 'b')"
4176 );
4177 assert_eq!(
4178 round_statement("INSERT INTO t (a, b) SELECT x, y FROM u"),
4179 "INSERT INTO t (a, b) SELECT x, y FROM u"
4180 );
4181 }
4182
4183 #[test]
4184 fn an_insert_clause_that_changes_the_answer_is_refused() {
4185 for query in [
4186 "INSERT INTO t VALUES (1) RETURNING *",
4187 "INSERT OR REPLACE INTO t VALUES (1)",
4188 "INSERT INTO t BY NAME SELECT 1 AS a",
4189 "INSERT INTO t VALUES (1) ON CONFLICT DO NOTHING",
4190 "INSERT INTO t DEFAULT VALUES",
4191 ] {
4192 let error = parse_ast(query).unwrap_err().to_string();
4193 assert!(error.starts_with("Not implemented Error"), "{query} gave {error}");
4194 }
4195 }
4196
4197 #[test]
4198 fn a_column_constraint_that_is_not_not_null_is_refused() {
4199 for query in [
4203 "CREATE TABLE t (a INT PRIMARY KEY)",
4204 "CREATE TABLE t (a INT UNIQUE)",
4205 "CREATE TABLE t (a INT CHECK (a > 0))",
4206 "CREATE TABLE t (a INT DEFAULT 1)",
4207 "CREATE TABLE t (a INT REFERENCES u (b))",
4208 "CREATE TABLE t (a INT, PRIMARY KEY (a))",
4209 ] {
4210 let error = parse_ast(query).unwrap_err().to_string();
4211 assert!(error.starts_with("Not implemented Error"), "{query} gave {error}");
4212 }
4213 }
4214
4215 #[test]
4216 fn values_is_a_query_on_its_own_and_in_a_from() {
4217 assert_eq!(round("VALUES (1), (2)"), "VALUES (1), (2)");
4218 assert_eq!(
4222 round("SELECT * FROM (VALUES (1, 2), (3, 4)) t(a, b)"),
4223 "SELECT * FROM (VALUES (1, 2), (3, 4)) AS t"
4224 );
4225 assert_eq!(
4226 round("SELECT * FROM VALUES (1, 2), (3, 4) AS t(a, b)"),
4227 "SELECT * FROM VALUES (1, 2), (3, 4) AS t"
4228 );
4229 assert_eq!(round("VALUES (1), (2, 3)"), "VALUES (1), (2, 3)");
4232 }
4233
4234 #[test]
4235 fn non_recursive_ctes_inline_and_semantic_variants_are_explicit() {
4236 assert_eq!(
4237 round("WITH t AS (SELECT 1 AS x) SELECT x FROM t"),
4238 "SELECT x FROM (SELECT 1 AS x) AS t"
4239 );
4240 assert_eq!(
4241 round("WITH t(x) AS NOT MATERIALIZED (SELECT 1) SELECT x FROM t"),
4242 "SELECT x FROM (SELECT 1) AS t"
4243 );
4244 let query = "WITH RECURSIVE t(x) AS (SELECT 1) SELECT x FROM t";
4245 let error = parse_ast(query).expect_err("the unsupported CTE shape is refused");
4246 assert!(error.to_string().starts_with("Not implemented Error"), "{query}: {error}");
4247 }
4248
4249 #[test]
4256 fn a_plain_cte_read_twice_is_held_and_one_read_once_is_inlined() {
4257 assert_eq!(
4258 round("WITH t AS (SELECT 1 AS x) SELECT * FROM t a, t b"),
4259 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT * FROM t AS a, t AS b"
4260 );
4261 assert_eq!(
4262 round("WITH t AS (SELECT 1 AS x) SELECT x FROM t"),
4263 "SELECT x FROM (SELECT 1 AS x) AS t"
4264 );
4265 assert_eq!(
4266 round("WITH t AS NOT MATERIALIZED (SELECT 1 AS x) SELECT * FROM t a, t b"),
4267 "SELECT * FROM (SELECT 1 AS x) AS a, (SELECT 1 AS x) AS b"
4268 );
4269 assert_eq!(
4271 round("WITH t AS (SELECT 1 AS x), u AS (SELECT x FROM t) SELECT x FROM t"),
4272 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT x FROM t"
4273 );
4274 assert_eq!(
4276 round("WITH t AS (SELECT 1 AS x) SELECT * FROM t a, main.t b"),
4277 "SELECT * FROM (SELECT 1 AS x) AS a, main.t AS b"
4278 );
4279 }
4280
4281 #[test]
4288 fn a_cte_written_inside_a_subquery_is_inlined_however_often_it_is_read() {
4289 assert_eq!(
4290 round("SELECT * FROM (WITH t AS (SELECT 1 AS x) SELECT * FROM t a, t b) c"),
4291 "SELECT * FROM (SELECT * FROM (SELECT 1 AS x) AS a, (SELECT 1 AS x) AS b) AS c"
4292 );
4293 assert_eq!(
4294 round("WITH o AS (WITH i AS (SELECT 1 AS x) SELECT * FROM i a, i b) SELECT * FROM o"),
4295 "SELECT * FROM (SELECT * FROM (SELECT 1 AS x) AS a, (SELECT 1 AS x) AS b) AS o"
4296 );
4297 }
4298
4299 #[test]
4305 fn a_plain_cte_whose_name_is_written_again_further_in_is_inlined() {
4306 assert_eq!(
4307 round(
4308 "WITH t AS (SELECT 1 AS x) SELECT * FROM t a, \
4309 (WITH t AS (SELECT 2 AS x) SELECT x FROM t) b"
4310 ),
4311 "SELECT * FROM (SELECT 1 AS x) AS a, (SELECT x FROM (SELECT 2 AS x) AS t) AS b"
4312 );
4313 }
4314
4315 #[test]
4317 fn a_materialized_cte_stays_a_definition_and_its_references_stay_references() {
4318 assert_eq!(
4319 round("WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT x FROM t"),
4320 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT x FROM t"
4321 );
4322 assert_eq!(
4323 round("WITH t(y) AS MATERIALIZED (SELECT 1) SELECT y FROM t"),
4324 "WITH t(y) AS MATERIALIZED (SELECT 1) SELECT y FROM t"
4325 );
4326 assert_eq!(
4329 round("WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT * FROM t a, t b"),
4330 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT * FROM t AS a, t AS b"
4331 );
4332 assert_eq!(
4334 round(
4335 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT (WITH t AS (SELECT 2 AS x) \
4336 SELECT x FROM t) AS inner"
4337 ),
4338 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT (SELECT x FROM (SELECT 2 AS x) AS t) \
4339 AS inner"
4340 );
4341 assert_eq!(
4344 round(
4345 "WITH a AS MATERIALIZED (SELECT 1 AS x), b AS MATERIALIZED (SELECT x + 1 AS y \
4346 FROM a) SELECT y FROM b"
4347 ),
4348 "WITH a AS MATERIALIZED (SELECT 1 AS x) WITH b AS MATERIALIZED (SELECT (x Add 1) \
4349 AS y FROM a) SELECT y FROM b"
4350 );
4351 }
4352
4353 #[test]
4361 fn describe_rewrites_a_name_into_a_star_over_it() {
4362 assert_eq!(round("DESCRIBE SELECT 1 AS a"), "DESCRIBE SELECT 1 AS a");
4363 assert_eq!(round("DESCRIBE t"), "DESCRIBE SELECT * FROM t");
4364 assert_eq!(round("DESC t"), "DESCRIBE SELECT * FROM t");
4365 assert_eq!(round("DESCRIBE 'x.parquet'"), "DESCRIBE SELECT * FROM x.parquet");
4366 assert_eq!(
4368 round("SELECT column_name FROM (DESCRIBE SELECT 1 AS a)"),
4369 "SELECT column_name FROM (DESCRIBE SELECT 1 AS a)"
4370 );
4371 assert_eq!(round("DESCRIBE DESCRIBE SELECT 1 AS a"), "DESCRIBE DESCRIBE SELECT 1 AS a");
4372 }
4373
4374 #[test]
4381 fn summarize_is_refused_even_though_it_parses_as_a_describe() {
4382 for query in ["SUMMARIZE t", "SUMMARIZE SELECT 1"] {
4383 let error = parse_ast(query).expect_err("summarize is not implemented");
4384 let message = error.to_string();
4385 assert!(message.starts_with("Not implemented Error"), "{query} failed with {message}");
4386 }
4387 }
4388
4389 #[test]
4390 fn every_statement_in_the_corpus_gets_a_defined_answer() {
4391 let mut done = 0;
4396 for query in CORPUS {
4397 match parse_ast(query) {
4398 Ok(ast) => {
4399 assert_eq!(ast.statements.len(), 1, "{query}");
4400 done += 1;
4401 }
4402 Err(error) => {
4403 let message = error.to_string();
4404 assert!(
4405 message.starts_with("Not implemented Error"),
4406 "{query} failed with {message}, which is not a not-implemented error"
4407 );
4408 }
4409 }
4410 }
4411 assert!(done >= 31, "only {done} of the corpus transforms, which is fewer than it was");
4414 }
4415
4416 #[test]
4417 fn the_ast_is_far_smaller_than_the_parse_tree() {
4418 let query = CORPUS[4];
4419 let tree = parse(query).unwrap();
4420 let ast = parse_ast(query).unwrap();
4421 assert!(
4424 ast.node_count() * 20 < tree.arena_len(),
4425 "{} ast nodes against {} parse nodes",
4426 ast.node_count(),
4427 tree.arena_len()
4428 );
4429 }
4430
4431 #[test]
4432 fn precedence_comes_out_of_the_chain_and_into_the_tree() {
4433 assert_eq!(round("SELECT 1 + 2 * 3"), "SELECT (1 Add (2 Multiply 3))");
4434 assert_eq!(round("SELECT (1 + 2) * 3"), "SELECT ((1 Add 2) Multiply 3)");
4435 assert_eq!(round("SELECT 1 + 2 + 3"), "SELECT ((1 Add 2) Add 3)");
4436 assert_eq!(round("SELECT 1 - 2 - 3"), "SELECT ((1 Subtract 2) Subtract 3)");
4437 assert_eq!(
4438 round("SELECT a OR b AND c"),
4439 "SELECT (a Or (b And c))",
4440 "and binds tighter than or"
4441 );
4442 }
4443
4444 #[test]
4445 fn a_double_negation_is_two_nodes_and_not_none() {
4446 assert_eq!(round("SELECT NOT NOT a"), "SELECT (Not (Not a))");
4450 }
4451
4452 #[test]
4453 fn a_parenthesised_single_expression_is_not_a_row() {
4454 assert_eq!(round("SELECT (a)"), "SELECT a");
4455 assert_eq!(round("SELECT (a, b)"), "SELECT ROW(a, b)");
4456 }
4457
4458 #[test]
4459 fn a_bracketed_list_is_a_list_of_however_many_items_were_written() {
4460 assert_eq!(round("SELECT [a]"), "SELECT [a]");
4463 assert_eq!(round("SELECT [1, 2, 3]"), "SELECT [1, 2, 3]");
4464 assert_eq!(round("SELECT []"), "SELECT []");
4465 assert_eq!(round("SELECT ['a.parquet', 'b.parquet']"), "SELECT ['a.parquet', 'b.parquet']");
4466 }
4467
4468 #[test]
4469 fn a_parameter_carries_its_identifier_however_it_was_written() {
4470 assert_eq!(round("SELECT $1"), "SELECT $1");
4471 assert_eq!(round("SELECT ?1"), "SELECT $1");
4472 assert_eq!(round("SELECT $name"), "SELECT $name");
4473 assert_eq!(round("SELECT ? + $2"), "SELECT ($1 Add $2)");
4476 assert_eq!(round("SELECT ?, ?, ?"), "SELECT $1, $2, $3");
4477 }
4478
4479 #[test]
4480 fn the_parameters_of_a_statement_are_listed_once_each_in_written_order() {
4481 let ast = parse_ast("SELECT $b, $a, $b WHERE $a").expect("parses");
4482 assert_eq!(ast.parameters(), vec!["b", "a"]);
4483 assert!(parse_ast("SELECT 1").expect("parses").parameters().is_empty());
4484 }
4485
4486 #[test]
4487 fn the_three_ways_to_write_an_alias_all_arrive() {
4488 assert_eq!(round("SELECT a AS b"), "SELECT a AS b");
4489 assert_eq!(round("SELECT a b"), "SELECT a AS b");
4490 assert_eq!(round("SELECT b: a"), "SELECT a AS b");
4491 assert_eq!(round("SELECT a"), "SELECT a", "and no alias when none was written");
4492 }
4493
4494 #[test]
4495 fn a_from_with_no_select_selects_everything() {
4496 assert_eq!(round("FROM t"), "SELECT * FROM t");
4499 assert_eq!(round("FROM t SELECT a"), "SELECT a FROM t");
4500 }
4501
4502 #[test]
4503 fn joins_nest_to_the_left() {
4504 assert_eq!(
4505 round("SELECT * FROM a JOIN b ON a.i = b.i LEFT JOIN c USING (k)"),
4506 "SELECT * FROM ((a Inner JOIN b ON (a.i Eq b.i)) Left JOIN c USING (k))"
4507 );
4508 assert_eq!(
4509 round("SELECT * FROM a NATURAL JOIN b"),
4510 "SELECT * FROM (a NATURAL Inner JOIN b)"
4511 );
4512 assert_eq!(round("SELECT * FROM a CROSS JOIN b"), "SELECT * FROM (a Cross JOIN b)");
4513 assert_eq!(
4514 round("SELECT * FROM a POSITIONAL JOIN b"),
4515 "SELECT * FROM (a Positional JOIN b)"
4516 );
4517 assert_eq!(round("SELECT * FROM a, b"), "SELECT * FROM a, b", "a comma is not a join node");
4518 }
4519
4520 #[test]
4521 fn a_qualified_name_keeps_its_parts_however_it_was_spelled() {
4522 assert_eq!(round("SELECT a"), "SELECT a");
4526 assert_eq!(round("SELECT t.a"), "SELECT t.a");
4527 assert_eq!(round("SELECT s.t.a"), "SELECT s.t.a");
4528 assert_eq!(round("SELECT c.s.t.a"), "SELECT c.s.t.a");
4529 assert_eq!(round("SELECT * FROM s.t"), "SELECT * FROM s.t");
4530 }
4531
4532 #[test]
4533 fn a_star_can_be_qualified() {
4534 assert_eq!(round("SELECT *"), "SELECT *");
4535 assert_eq!(round("SELECT t.*"), "SELECT t.*");
4536 assert_eq!(round("SELECT s.t.*"), "SELECT s.t.*");
4537 }
4538
4539 #[test]
4540 fn a_quoted_identifier_keeps_its_case_and_loses_its_quotes() {
4541 let ast = parse_ast("SELECT \"Mixed Case\", \"a\"\"b\"").unwrap();
4545 assert_eq!(ast.strings[0], "Mixed Case");
4546 assert_eq!(ast.strings[1], "a\"b");
4547 }
4548
4549 #[test]
4550 fn a_string_literal_is_decoded_and_adjacent_ones_are_joined() {
4551 assert_eq!(round("SELECT 'it''s'"), "SELECT 'it's'");
4552 assert_eq!(round("SELECT 'a'\n'b'"), "SELECT 'ab'", "the standard's adjacency rule");
4553 }
4554
4555 #[test]
4557 fn a_dollar_quoted_string_loses_its_dollars_and_its_tag() {
4558 assert_eq!(round("SELECT $$dollar quoted$$"), "SELECT 'dollar quoted'");
4559 assert_eq!(round("SELECT $tag$body$tag$"), "SELECT 'body'");
4560 assert_eq!(round("SELECT $$$$"), "SELECT ''", "an empty tag and an empty body");
4561 assert_eq!(round("SELECT $tag$it''s $other$ fine$tag$"), "SELECT 'it''s $other$ fine'");
4564 assert_eq!(round("SELECT $$open"), "SELECT '$$open'");
4566 }
4567
4568 #[test]
4574 fn an_escape_string_resolves_its_backslashes() {
4575 assert_eq!(round("SELECT E'a\\nb'"), "SELECT 'a\nb'");
4576 assert_eq!(round("SELECT e'a\\tb'"), "SELECT 'a\tb'", "the prefix is a letter, not a name");
4577 assert_eq!(round("SELECT E'a\\rb'"), "SELECT 'a\rb'");
4578 assert_eq!(round("SELECT E'a\\bb'"), "SELECT 'a\u{8}b'");
4579 assert_eq!(round("SELECT E'a\\fb'"), "SELECT 'a\u{c}b'");
4580 assert_eq!(round("SELECT E'a\\\\b'"), "SELECT 'a\\b'");
4581 assert_eq!(round("SELECT E'a\\'b'"), "SELECT 'a'b'", "a quote, the same as ''");
4582 assert_eq!(round("SELECT E'a''b'"), "SELECT 'a'b'", "and '' still means a quote here");
4583 assert_eq!(round("SELECT E'a\\vb'"), "SELECT 'avb'");
4586 assert_eq!(round("SELECT E'a\\qb'"), "SELECT 'aqb'");
4587 }
4588
4589 #[test]
4591 fn a_numeric_escape_writes_the_byte_or_the_character_it_names() {
4592 assert_eq!(round("SELECT E'\\x41'"), "SELECT 'A'");
4593 assert_eq!(round("SELECT E'\\x4142'"), "SELECT 'A42'", "two digits at the most");
4594 assert_eq!(
4595 round("SELECT E'a\\x'"),
4596 "SELECT 'ax'",
4597 "and one at the least, or it is a letter"
4598 );
4599 assert_eq!(round("SELECT E'\\101'"), "SELECT 'A'");
4600 assert_eq!(round("SELECT E'\\1011'"), "SELECT 'A1'", "three digits at the most");
4601 assert_eq!(round("SELECT E'\\8'"), "SELECT '8'", "8 is not an octal digit");
4602 assert_eq!(round("SELECT E'\\xc3\\xa9'"), "SELECT 'é'");
4604 assert_eq!(round("SELECT E'\\u00e9'"), "SELECT 'é'");
4605 assert_eq!(round("SELECT E'a\\u41'"), "SELECT 'au41'", "four digits or it is a letter");
4606 assert_eq!(round("SELECT E'a\\uZZZZ'"), "SELECT 'auZZZZ'");
4607 assert_eq!(
4608 round("SELECT E'\\ud83d\\ude00'"),
4609 "SELECT 'ud83dude00'",
4610 "surrogates are not it"
4611 );
4612 }
4613
4614 #[test]
4616 fn an_escape_string_that_is_not_a_string_raises() {
4617 let error = parse_ast("SELECT E'a\\x00'").unwrap_err().to_string();
4618 assert_eq!(error, "Parser Error: Null character not permitted in escape string literal");
4619 let error = parse_ast("SELECT E'a\\377'").unwrap_err().to_string();
4620 assert_eq!(
4621 error,
4622 "Parser Error: Invalid UTF-8 in escape string literal at byte offset 1: byte mismatch",
4623 "the offset is where the bytes stop being a string, not where the escape was written"
4624 );
4625 }
4626
4627 #[test]
4629 fn the_other_string_prefixes_are_what_upstream_makes_of_them() {
4630 assert_eq!(round("SELECT N'abc'"), "SELECT CAST('abc' AS VARCHAR)");
4632 assert_eq!(round("SELECT n'abc'"), "SELECT CAST('abc' AS VARCHAR)");
4633 assert_eq!(round("SELECT B'101'"), "SELECT 'b101'");
4635 assert_eq!(round("SELECT b'abc'"), "SELECT 'babc'");
4636 assert_eq!(round("SELECT B''"), "SELECT 'b'", "an empty one is the letter on its own");
4637 }
4638
4639 #[test]
4645 fn a_hex_string_is_a_blob_and_not_a_string() {
4646 assert_eq!(round("SELECT x'4142'"), "SELECT 'AB'::BLOB");
4647 assert_eq!(round("SELECT X'4142'"), "SELECT 'AB'::BLOB");
4648 assert_eq!(round("SELECT x'ff41'"), "SELECT '\\xFFA'::BLOB", "a byte that does not print");
4649 assert_eq!(round("SELECT x''"), "SELECT ''::BLOB", "an empty one is an empty blob");
4650 assert_eq!(round("SELECT x'2741'"), "SELECT '\\x27A'::BLOB");
4653 assert_eq!(round("SELECT x'5c7834314141'"), "SELECT '\\x5Cx41AA'::BLOB");
4654 let error = parse_ast("SELECT x'4'").unwrap_err().to_string();
4657 assert_eq!(
4658 error,
4659 "Parser Error: Hex string literal must have an even number of hex digits"
4660 );
4661 assert_eq!(round("SELECT x'41zz'"), "SELECT '\\x41\\xzz'::BLOB");
4662 }
4663
4664 #[test]
4665 fn the_null_and_boolean_tests_are_postfix_unary_operators() {
4666 assert_eq!(round("SELECT x IS NULL"), "SELECT (IsNull x)");
4667 assert_eq!(round("SELECT x IS NOT NULL"), "SELECT (IsNotNull x)");
4668 assert_eq!(round("SELECT x ISNULL"), "SELECT (IsNull x)");
4669 assert_eq!(round("SELECT x NOTNULL"), "SELECT (IsNotNull x)");
4670 assert_eq!(round("SELECT x IS TRUE"), "SELECT (IsTrue x)");
4671 assert_eq!(round("SELECT x IS NOT FALSE"), "SELECT (IsNotFalse x)");
4672 assert_eq!(round("SELECT x IS DISTINCT FROM y"), "SELECT (x IsDistinctFrom y)");
4673 assert_eq!(round("SELECT x IS NOT DISTINCT FROM y"), "SELECT (x IsNotDistinctFrom y)");
4674 }
4675
4676 #[test]
4677 fn the_like_family_folds_its_negation_into_the_operator() {
4678 assert_eq!(round("SELECT x LIKE 'a'"), "SELECT (x Like 'a')");
4679 assert_eq!(round("SELECT x NOT LIKE 'a'"), "SELECT (x NotLike 'a')");
4680 assert_eq!(round("SELECT x ILIKE 'a'"), "SELECT (x ILike 'a')");
4681 assert_eq!(round("SELECT x ~~ 'a'"), "SELECT (x Like 'a')", "the operator spelling");
4682 assert_eq!(round("SELECT x !~~ 'a'"), "SELECT (x NotLike 'a')");
4683 assert_eq!(round("SELECT x SIMILAR TO 'a'"), "SELECT (x SimilarTo 'a')");
4684 assert_eq!(round("SELECT x NOT GLOB 'a'"), "SELECT (Not (x Glob 'a'))");
4686 }
4687
4688 #[test]
4689 fn between_and_in_carry_their_negation_as_a_flag() {
4690 assert_eq!(round("SELECT x BETWEEN 1 AND 2"), "SELECT (x BETWEEN 1 AND 2)");
4691 assert_eq!(round("SELECT x NOT BETWEEN 1 AND 2"), "SELECT (NOT x BETWEEN 1 AND 2)");
4692 assert_eq!(round("SELECT x IN (1, 2)"), "SELECT (x IN [1, 2])");
4693 assert_eq!(round("SELECT x NOT IN (1, 2)"), "SELECT (NOT x IN [1, 2])");
4694 }
4695
4696 #[test]
4697 fn both_spellings_of_a_cast_are_the_same_node() {
4698 assert_eq!(round("SELECT CAST(x AS BIGINT)"), "SELECT CAST(x AS BIGINT)");
4699 assert_eq!(round("SELECT x::BIGINT"), "SELECT CAST(x AS BIGINT)");
4700 assert_eq!(round("SELECT TRY_CAST(x AS BIGINT)"), "SELECT TRY_CAST(x AS BIGINT)");
4701 assert_eq!(
4702 round("SELECT x::DECIMAL(18, 3)"),
4703 "SELECT CAST(x AS DECIMAL(18, 3))",
4704 "the type is kept as text because parsing it is the type system's job"
4705 );
4706 }
4707
4708 #[test]
4709 fn a_typed_literal_is_a_third_spelling_of_the_same_cast() {
4710 assert_eq!(round("SELECT DATE '1995-09-01'"), "SELECT CAST('1995-09-01' AS DATE)");
4711 assert_eq!(
4712 round("SELECT date '1995-09-01'"),
4713 "SELECT CAST('1995-09-01' AS date)",
4714 "the type is kept as written, the same as it is in the other two spellings"
4715 );
4716 assert_eq!(
4717 round("SELECT TIMESTAMP '2020-01-01 03:04:05'"),
4718 "SELECT CAST('2020-01-01 03:04:05' AS TIMESTAMP)"
4719 );
4720 assert_eq!(
4721 round("SELECT DECIMAL(5, 2) '1.5'"),
4722 "SELECT CAST('1.5' AS DECIMAL(5, 2))",
4723 "any type the cast takes is a typed literal, parameters and all"
4724 );
4725 assert_eq!(
4726 round("SELECT VARCHAR 'hi' FROM t"),
4727 "SELECT CAST('hi' AS VARCHAR) FROM t",
4728 "including the ones where the cast has nothing to do"
4729 );
4730 }
4731
4732 #[test]
4733 fn a_case_keeps_its_arms_in_order() {
4734 assert_eq!(
4735 round("SELECT CASE WHEN a THEN 1 WHEN b THEN 2 ELSE 3 END"),
4736 "SELECT CASE - WHEN a THEN 1 WHEN b THEN 2 ELSE 3 END"
4737 );
4738 assert_eq!(
4739 round("SELECT CASE x WHEN 1 THEN 'a' END"),
4740 "SELECT CASE x WHEN 1 THEN 'a' ELSE - END",
4741 "a simple case keeps the operand and a missing else is not an implicit null yet"
4742 );
4743 }
4744
4745 #[test]
4746 fn a_field_access_and_a_method_call_are_ordinary_function_calls() {
4747 assert_eq!(round("SELECT (f(x)).y"), "SELECT struct_extract(f(x), 'y')");
4750 assert_eq!(round("SELECT a[1]"), "SELECT array_extract(a, 1)");
4751 }
4752
4753 #[test]
4755 fn a_range_gets_the_bounds_the_query_left_out() {
4756 assert_eq!(round("SELECT a[1:2]"), "SELECT array_slice(a, 1, 2)");
4757 assert_eq!(round("SELECT a[:2]"), "SELECT array_slice(a, 1, 2)");
4758 assert_eq!(round("SELECT a[2:]"), "SELECT array_slice(a, 2, -1)");
4759 assert_eq!(round("SELECT a[:]"), "SELECT array_slice(a, 1, -1)");
4760 assert_eq!(round("SELECT a[1:-]"), "SELECT array_slice(a, 1, -1)");
4762 assert_eq!(round("SELECT a[1:2:3]"), "SELECT array_slice(a, 1, 2, 3)");
4763 assert_eq!(round("SELECT a[1:2:]"), "SELECT array_slice(a, 1, 2, [])");
4766 }
4767
4768 #[test]
4770 fn an_empty_subscript_is_not_a_subscript() {
4771 let error = parse_ast("SELECT a[]").expect_err("an empty subscript");
4772 assert_eq!(error.message(), "Empty subscript '[]' is not allowed");
4773 }
4774
4775 #[test]
4778 fn a_keyword_is_not_stepped_through_on_the_way_to_its_one_argument() {
4779 for (sql, rule) in [
4780 ("SELECT row(1)", "RowExpression"),
4781 ("SELECT try(1)", "TryExpression"),
4782 ("SELECT unpack([1])", "UnpackExpression"),
4783 ("SELECT columns('a')", "ColumnsExpression"),
4784 ] {
4785 let error = parse_ast(sql).expect_err(sql);
4786 assert!(error.message().ends_with(rule), "{sql}: {error}");
4787 }
4788 assert_eq!(round("SELECT (1 + 2) * 3"), "SELECT ((1 Add 2) Multiply 3)");
4791 assert_eq!(round("SELECT -(7)"), "SELECT (Negate 7)");
4792 }
4793
4794 #[test]
4796 fn the_null_checks_are_calls_by_the_names_duckdb_prints() {
4797 assert_eq!(round("SELECT COALESCE(a, b, 1)"), "SELECT coalesce(a, b, 1)");
4800 assert_eq!(round("SELECT coalesce(a)"), "SELECT coalesce(a)");
4801 assert_eq!(round("SELECT NULLIF(a, 1)"), "SELECT nullif(a, 1)");
4802 assert_eq!(round("SELECT ifnull(a, 1)"), "SELECT coalesce(a, 1)");
4804 assert_eq!(round("SELECT main.ifnull(a, 1)"), "SELECT coalesce(a, 1)");
4805 let error = parse_ast("SELECT ifnull(a)").expect_err("one argument to ifnull");
4806 assert_eq!(error.message(), "Wrong number of arguments to IFNULL.");
4807 let error = parse_ast("SELECT ifnull(a, b, c)").expect_err("three arguments to ifnull");
4808 assert_eq!(error.message(), "Wrong number of arguments to IFNULL.");
4809 }
4810
4811 #[test]
4814 fn the_string_keywords_are_the_calls_duckdb_prints() {
4815 assert_eq!(round("SELECT substring(s, 2, 3)"), "SELECT substring(s, 2, 3)");
4816 assert_eq!(round("SELECT SUBSTRING(s FROM 2 FOR 3)"), "SELECT substring(s, 2, 3)");
4817 assert_eq!(round("SELECT substring(s FROM 2)"), "SELECT substring(s, 2)");
4818 assert_eq!(round("SELECT substring(s FOR 3)"), "SELECT substring(s, 1, 3)");
4820 assert_eq!(round("SELECT position('c' IN s)"), "SELECT position(s, 'c')");
4822 assert_eq!(round("SELECT trim(s)"), "SELECT trim(s)");
4823 assert_eq!(round("SELECT trim(BOTH 'x' FROM s)"), "SELECT trim(s, 'x')");
4824 assert_eq!(round("SELECT trim(BOTH FROM s)"), "SELECT trim(s)");
4825 assert_eq!(round("SELECT trim(s, 'xy')"), "SELECT trim(s, 'xy')");
4826 assert_eq!(round("SELECT trim(LEADING FROM s)"), "SELECT ltrim(s)");
4828 assert_eq!(round("SELECT trim(TRAILING FROM s)"), "SELECT rtrim(s)");
4829 assert_eq!(round("SELECT trim(LEADING 'x' FROM s)"), "SELECT ltrim(s, 'x')");
4830 assert_eq!(round("SELECT trim(TRAILING 'x' FROM s)"), "SELECT rtrim(s, 'x')");
4831 assert_eq!(
4832 round("SELECT overlay(s PLACING 'X' FROM 2 FOR 1)"),
4833 "SELECT overlay(s, 'X', 2, 1)"
4834 );
4835 assert_eq!(round("SELECT overlay(s PLACING 'X' FROM 2)"), "SELECT overlay(s, 'X', 2)");
4836 assert_eq!(round("SELECT overlay(s, 'X', 2, 1)"), "SELECT overlay(s, 'X', 2, 1)");
4837 }
4838
4839 #[test]
4840 fn an_aggregate_keeps_its_distinct() {
4841 assert_eq!(round("SELECT count(*)"), "SELECT count(*)");
4842 assert_eq!(round("SELECT count(DISTINCT x)"), "SELECT count(DISTINCT x)");
4843 assert_eq!(round("SELECT count(ALL x)"), "SELECT count(x)");
4844 assert_eq!(round("SELECT main.count(x)"), "SELECT main.count(x)");
4845 }
4846
4847 #[test]
4848 fn a_call_keeps_the_filter_it_was_written_with_and_the_word_where_is_optional() {
4849 assert_eq!(round("SELECT sum(x) FILTER (WHERE y > 1)"), "SELECT sum(x) FILTER [(y Gt 1)]");
4853 assert_eq!(round("SELECT sum(x) FILTER (y > 1)"), "SELECT sum(x) FILTER [(y Gt 1)]");
4854 assert_eq!(round("SELECT count(*) FILTER (WHERE b)"), "SELECT count(*) FILTER [b]");
4855 assert_eq!(
4856 round("SELECT sum(DISTINCT x) FILTER (WHERE b)"),
4857 "SELECT sum(DISTINCT x) FILTER [b]"
4858 );
4859 assert_eq!(round("SELECT abs(x) FILTER (WHERE b)"), "SELECT abs(x) FILTER [b]");
4860 }
4861
4862 #[test]
4864 fn a_window_call_carries_its_filter_in_front_of_its_over() {
4865 assert_eq!(
4866 round("SELECT sum(x) FILTER (WHERE b) OVER ()"),
4867 "SELECT sum(x) FILTER [b] OVER [] [] [Range UnboundedPreceding CurrentRow NoOthers]"
4868 );
4869 }
4870
4871 #[test]
4872 fn the_modifiers_hang_off_the_query_and_not_off_the_select() {
4873 assert_eq!(
4877 round("SELECT 1 UNION ALL SELECT 2 ORDER BY 1"),
4878 "(SELECT 1 Union All SELECT 2) ORDER BY 1 Unstated Unstated"
4879 );
4880 assert_eq!(
4881 round("SELECT a FROM t UNION SELECT b FROM u EXCEPT SELECT c FROM v"),
4882 "((SELECT a FROM t Union Unstated SELECT b FROM u) Except Unstated SELECT c FROM v)",
4883 "set operators are left associative"
4884 );
4885 assert_eq!(
4886 round("SELECT 1 UNION SELECT 2 INTERSECT SELECT 3"),
4887 "(SELECT 1 Union Unstated (SELECT 2 Intersect Unstated SELECT 3))",
4888 "and intersect binds tighter than the other two"
4889 );
4890 }
4891
4892 #[test]
4893 fn the_sort_and_limit_clauses_keep_what_was_written() {
4894 assert_eq!(
4895 round("SELECT a FROM t ORDER BY a"),
4896 "SELECT a FROM t ORDER BY a Unstated Unstated"
4897 );
4898 assert_eq!(
4899 round("SELECT a FROM t ORDER BY a DESC NULLS LAST"),
4900 "SELECT a FROM t ORDER BY a Descending Last"
4901 );
4902 assert_eq!(round("SELECT a FROM t ORDER BY ALL"), "SELECT a FROM t ORDER BY ALL");
4903 assert_eq!(round("SELECT a FROM t GROUP BY ALL"), "SELECT a FROM t GROUP BY ALL");
4904 assert_eq!(round("SELECT a FROM t LIMIT 10 OFFSET 5"), "SELECT a FROM t LIMIT 10 OFFSET 5");
4905 assert_eq!(round("SELECT a FROM t OFFSET 5 LIMIT 10"), "SELECT a FROM t LIMIT 10 OFFSET 5");
4906 assert_eq!(round("SELECT a FROM t LIMIT 10%"), "SELECT a FROM t LIMIT 10%");
4907 assert_eq!(round("SELECT a FROM t LIMIT ALL"), "SELECT a FROM t", "which is no limit");
4908 }
4909
4910 #[test]
4911 fn a_subquery_appears_in_both_places_it_can() {
4912 assert_eq!(
4913 round("SELECT * FROM (SELECT x FROM t) AS s"),
4914 "SELECT * FROM (SELECT x FROM t) AS s"
4915 );
4916 assert_eq!(round("SELECT (SELECT 1)"), "SELECT (SELECT 1)");
4917 }
4918
4919 #[test]
4920 fn distinct_on_keeps_its_expressions() {
4921 assert_eq!(round("SELECT DISTINCT a"), "SELECT DISTINCT a");
4922 assert_eq!(round("SELECT ALL a"), "SELECT a", "which is the default written out");
4923 assert_eq!(round("SELECT DISTINCT ON (a, b) a"), "SELECT DISTINCT ON (a, b) a");
4924 }
4925
4926 #[test]
4927 fn an_operator_the_dialect_does_not_name_is_kept_by_name() {
4928 assert_eq!(round("SELECT a <=> b"), "SELECT (a <=> b)");
4934 assert!(parse_ast("SELECT a foo b").is_err(), "a bare word is not an operator");
4935 }
4936
4937 #[test]
4938 fn a_script_is_a_list_of_statements() {
4939 let ast = parse_ast("SELECT 1; SELECT 2;").unwrap();
4940 assert_eq!(ast.statements.len(), 2);
4941 let Statement::Query(second) = ast.statements[1] else {
4945 panic!("the second statement is a query");
4946 };
4947 assert_eq!(show_query(&ast, second), "SELECT 2");
4948 }
4949
4950 #[test]
4951 fn an_unsupported_construct_names_itself_and_what_was_written() {
4952 let error = parse_ast("ALTER TABLE t ADD COLUMN a INTEGER").unwrap_err().to_string();
4953 assert!(error.starts_with("Not implemented Error"), "{error}");
4954 assert!(error.contains("ALTER TABLE t ADD COLUMN a INTEGER"), "{error}");
4955 assert!(error.contains("AlterStatement"), "{error}");
4956 }
4957
4958 #[test]
4959 fn a_long_construct_is_cut_short_in_the_message() {
4960 let query = format!("ALTER TABLE t ADD COLUMN {} INTEGER", "a".repeat(80));
4961 let error = parse_ast(&query).unwrap_err().to_string();
4962 assert!(error.contains("..."), "{error}");
4963 assert!(error.len() < 200, "{error}");
4964 }
4965
4966 #[test]
4967 fn the_transformer_never_panics_on_anything_the_matcher_accepts() {
4968 for query in [
4972 "SELECT",
4973 "FROM t SELECT",
4974 "SELECT * FROM t WHERE",
4975 "SELECT ()",
4976 "SELECT a FROM t GROUP BY ()",
4977 ] {
4978 let answer = parse_ast(query);
4979 if let Err(error) = answer {
4980 let message = error.to_string();
4981 assert!(
4982 message.starts_with("Not implemented Error")
4983 || message.starts_with("Parser Error"),
4984 "{query} failed with {message}"
4985 );
4986 }
4987 }
4988 }
4989
4990 #[test]
4991 fn a_file_name_in_a_from_clause_is_a_table_name_with_the_quotes_off() {
4992 assert_eq!(round("SELECT * FROM 'hits.parquet'"), "SELECT * FROM hits.parquet");
4996 assert_eq!(round("SELECT * FROM \"hits.parquet\""), "SELECT * FROM hits.parquet");
4997 assert_eq!(round("SELECT * FROM 'hits.parquet' AS h"), "SELECT * FROM hits.parquet AS h");
4998 assert_eq!(
4999 round_with_case("SELECT Mixed FROM 'NoSuch/Mixed/File.csv'", IdentifierCase::Lower),
5000 "SELECT mixed FROM NoSuch/Mixed/File.csv"
5001 );
5002 assert_eq!(
5003 round_with_case("SELECT Mixed FROM \"QuotedTable\"", IdentifierCase::Upper),
5004 "SELECT MIXED FROM QuotedTable"
5005 );
5006 }
5007
5008 #[test]
5009 fn a_function_call_in_a_from_clause_is_a_source_and_not_an_expression() {
5010 assert_eq!(round("SELECT * FROM range(3)"), "SELECT * FROM range(3)");
5011 assert_eq!(round("SELECT * FROM range(1, 10, 2)"), "SELECT * FROM range(1, 10, 2)");
5012 assert_eq!(round("SELECT * FROM main.range(3)"), "SELECT * FROM main.range(3)");
5013 assert_eq!(round("SELECT * FROM range(3) AS t"), "SELECT * FROM range(3) AS t");
5014 assert_eq!(round("SELECT * FROM some_function()"), "SELECT * FROM some_function()");
5017 assert_eq!(round("SELECT * FROM LATERAL range(3)"), "SELECT * FROM range(3)");
5020 assert_eq!(
5021 round("SELECT * FROM t, LATERAL (SELECT t.x) AS v"),
5022 "SELECT * FROM t, (SELECT t.x) AS v"
5023 );
5024 }
5025
5026 #[test]
5027 fn the_forms_of_a_table_function_this_does_not_cover_are_turned_away_by_name() {
5028 for query in ["SELECT * FROM range(3) WITH ORDINALITY", "SELECT * FROM t: range(3)"] {
5029 let error = parse_ast(query).unwrap_err().to_string();
5030 assert!(error.contains("grammar rule"), "{query} failed with {error}");
5031 }
5032 }
5033
5034 #[test]
5035 fn a_pragma_is_the_call_it_stands_for_by_the_time_it_leaves_here() {
5036 assert_eq!(round("PRAGMA version"), "SELECT * FROM pragma_version()");
5037 assert_eq!(round("PRAGMA database_size"), "SELECT * FROM pragma_database_size()");
5038 assert_eq!(round("PRAGMA VERSION"), "SELECT * FROM pragma_VERSION()");
5041 assert_eq!(round("PRAGMA table_info('t')"), "SELECT * FROM pragma_table_info('t')");
5042 }
5043
5044 #[test]
5045 fn a_pragma_that_is_a_statement_stays_one_rather_than_becoming_a_call() {
5046 assert_eq!(round_statement("PRAGMA disable_optimizer"), "PRAGMA disable_optimizer");
5049 assert_eq!(round_statement("PRAGMA enable_profiling"), "PRAGMA enable_profiling");
5050 assert_eq!(round_statement("PRAGMA force_checkpoint"), "PRAGMA force_checkpoint");
5051 assert_eq!(round_statement("PRAGMA verify_parallelism"), "PRAGMA verify_parallelism");
5052 assert_eq!(round_statement("PRAGMA enable_nothing_at_all"), "PRAGMA enable_nothing_at_all");
5055 assert_eq!(
5057 round("PRAGMA disable_optimizer('x')"),
5058 "SELECT * FROM pragma_disable_optimizer('x')"
5059 );
5060 }
5061
5062 #[test]
5063 fn a_bare_name_in_a_pragmas_parentheses_is_a_name_and_not_a_column() {
5064 assert_eq!(round("PRAGMA table_info(t)"), "SELECT * FROM pragma_table_info('t')");
5067 assert_eq!(round("PRAGMA table_info(main.t)"), "SELECT * FROM pragma_table_info('main.t')");
5068 assert_eq!(round("PRAGMA table_info(\"T\")"), "SELECT * FROM pragma_table_info('T')");
5069 assert_eq!(round("PRAGMA table_info(1)"), "SELECT * FROM pragma_table_info(1)");
5072 }
5073
5074 #[test]
5075 fn a_pragma_with_an_equals_sign_is_a_set_and_nothing_else() {
5076 assert_eq!(round_statement("PRAGMA memory_limit = '1GB'"), "SET memory_limit = '1GB'");
5077 assert_eq!(round_statement("PRAGMA threads = 4"), "SET threads = 4");
5078 }
5079
5080 #[test]
5081 fn a_pragma_with_empty_parentheses_does_not_parse_on_either_engine() {
5082 let error = parse_ast("PRAGMA version()").unwrap_err().to_string();
5085 assert!(error.contains("syntax error at or near \")\""), "{error}");
5086 }
5087
5088 #[test]
5089 fn a_window_call_carries_its_partition_its_order_and_its_frame() {
5090 assert_eq!(
5091 round("SELECT row_number() OVER () FROM t"),
5092 "SELECT row_number() OVER [] [] [Range UnboundedPreceding CurrentRow NoOthers] FROM t"
5093 );
5094 assert_eq!(
5095 round("SELECT sum(a) OVER (PARTITION BY b, c ORDER BY d DESC NULLS FIRST) FROM t"),
5096 "SELECT sum(a) OVER [b, c] [d Descending First] \
5097 [Range UnboundedPreceding CurrentRow NoOthers] FROM t"
5098 );
5099 assert_eq!(
5100 round(
5101 "SELECT sum(a) OVER (ORDER BY b GROUPS BETWEEN 1 PRECEDING AND 2 FOLLOWING EXCLUDE TIES) FROM t"
5102 ),
5103 "SELECT sum(a) OVER [] [b Unstated Unstated] \
5104 [Groups Preceding(1) Following(2) Ties] FROM t"
5105 );
5106 }
5107
5108 #[test]
5111 fn a_frame_with_both_ends_unbounded_is_counted_in_rows() {
5112 for unit in ["ROWS", "RANGE", "GROUPS"] {
5113 let query = format!(
5114 "SELECT sum(a) OVER (ORDER BY b {unit} BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t"
5115 );
5116 assert_eq!(
5117 round(&query),
5118 "SELECT sum(a) OVER [] [b Unstated Unstated] \
5119 [Rows UnboundedPreceding UnboundedFollowing NoOthers] FROM t"
5120 );
5121 }
5122 }
5123
5124 #[test]
5127 fn a_frame_written_with_one_bound_ends_at_the_current_row() {
5128 assert_eq!(
5129 round("SELECT sum(a) OVER (ORDER BY b ROWS UNBOUNDED PRECEDING) FROM t"),
5130 round(
5131 "SELECT sum(a) OVER (ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t"
5132 )
5133 );
5134 }
5135
5136 #[test]
5137 fn a_named_window_is_resolved_here_and_not_carried_any_further() {
5138 let inlined = round("SELECT sum(a) OVER (PARTITION BY b ORDER BY c) FROM t");
5139 assert_eq!(
5140 round("SELECT sum(a) OVER w FROM t WINDOW w AS (PARTITION BY b ORDER BY c)"),
5141 inlined
5142 );
5143 assert_eq!(
5144 round("SELECT sum(a) OVER (w) FROM t WINDOW w AS (PARTITION BY b ORDER BY c)"),
5145 inlined
5146 );
5147 assert_eq!(
5150 round("SELECT sum(a) OVER v FROM t WINDOW w AS (PARTITION BY b), v AS (w ORDER BY c)"),
5151 inlined
5152 );
5153 assert_eq!(
5154 round("SELECT sum(a) OVER (w ORDER BY c) FROM t WINDOW w AS (PARTITION BY b)"),
5155 inlined
5156 );
5157 assert_eq!(
5159 round("SELECT sum(a) OVER W FROM t WINDOW w AS (PARTITION BY b ORDER BY c)"),
5160 inlined
5161 );
5162 }
5163
5164 #[test]
5167 fn a_named_window_reaches_a_subquery_written_in_the_same_block() {
5168 let ast = parse_ast("SELECT (SELECT sum(b) OVER w FROM u) FROM t WINDOW w AS (ORDER BY b)");
5169 assert!(ast.is_ok(), "{:?}", ast.err());
5170 let error =
5172 parse_ast("SELECT 1 FROM t WINDOW w AS (ORDER BY b); SELECT sum(a) OVER w FROM u;")
5173 .unwrap_err()
5174 .to_string();
5175 assert!(error.contains("window \"\"w\"\" does not exist"), "{error}");
5176 }
5177
5178 #[test]
5181 fn the_four_complaints_about_a_named_window_are_upstreams() {
5182 let cases = [
5183 ("SELECT sum(a) OVER w FROM t", "window \"\"w\"\" does not exist"),
5184 (
5185 "SELECT sum(a) OVER (w PARTITION BY b) FROM t WINDOW w AS (PARTITION BY b)",
5186 "Cannot override PARTITION BY clause of window \"w\"",
5187 ),
5188 (
5189 "SELECT sum(a) OVER (w ORDER BY b) FROM t WINDOW w AS (ORDER BY b)",
5190 "Cannot override ORDER BY clause of window \"w\"",
5191 ),
5192 (
5193 "SELECT sum(a) OVER (w ROWS UNBOUNDED PRECEDING) FROM t WINDOW w AS (ORDER BY b ROWS UNBOUNDED PRECEDING)",
5194 "cannot copy window \"w\" because it has a frame clause",
5195 ),
5196 ];
5197 for (query, expected) in cases {
5198 let error = parse_ast(query).expect_err(query).to_string();
5199 assert!(error.contains(expected), "{query}: {error}");
5200 }
5201 }
5202
5203 #[test]
5206 fn the_modifiers_that_only_a_window_takes_are_turned_down_without_one() {
5207 let error = parse_ast("SELECT first_value(a IGNORE NULLS) FROM t").unwrap_err().to_string();
5208 assert!(
5209 error.contains("RESPECT/IGNORE NULLS is not supported for non-window functions"),
5210 "{error}"
5211 );
5212 let error = parse_ast("SELECT sum(a) OVER (ORDER BY b EXCLUDE TIES) FROM t")
5213 .unwrap_err()
5214 .to_string();
5215 assert!(error.contains("syntax error at or near \"EXCLUDE\""), "{error}");
5216 }
5217
5218 #[test]
5221 fn a_window_call_is_not_put_through_the_rewrites_a_plain_call_is() {
5222 assert_eq!(
5223 round("SELECT ifnull(1) OVER () FROM t"),
5224 "SELECT ifnull(1) OVER [] [] [Range UnboundedPreceding CurrentRow NoOthers] FROM t"
5225 );
5226 let error = parse_ast("SELECT ifnull(1) FROM t").unwrap_err().to_string();
5227 assert!(error.contains("Wrong number of arguments to IFNULL."), "{error}");
5228 }
5229
5230 #[test]
5231 fn interning_means_a_name_written_twice_is_stored_once() {
5232 let ast = parse_ast("SELECT a, a, a FROM t WHERE a = a").unwrap();
5233 assert_eq!(ast.strings.iter().filter(|text| *text == "a").count(), 1);
5234 }
5235}