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 if self.find(list, "OrderByClause") != NONE {
2446 return self.unsupported(self.find(list, "OrderByClause"));
2447 }
2448 let nulls = self.find(list, "IgnoreOrRespectNulls");
2451 if nulls != NONE && over == NONE {
2452 return Err(Error::parser(
2453 "RESPECT/IGNORE NULLS is not supported for non-window functions",
2454 ));
2455 }
2456 let ignore_nulls = nulls != NONE && self.name(self.first(nulls)) == "IgnoreNulls";
2457 let distinct = self.quantifier(self.find(list, "DistinctOrAll")) == Quantifier::Distinct;
2458 let mut args = Vec::new();
2459 let arguments = self.find(list, "FunctionArgumentList");
2460 if arguments != NONE {
2461 for kid in self.kids(arguments) {
2462 args.push(self.argument(kid)?);
2463 }
2464 }
2465 if over != NONE {
2470 let args = self.expr_slice(args);
2471 let spec = self.over(over)?;
2472 return Ok(self.push(Expr::Window {
2473 name,
2474 args,
2475 distinct,
2476 filter,
2477 ignore_nulls,
2478 spec,
2479 }));
2480 }
2481 if self.ast.name(name).last().is_some_and(|part| part.eq_ignore_ascii_case("ifnull")) {
2487 if args.len() != 2 {
2488 return Err(Error::parser("Wrong number of arguments to IFNULL."));
2489 }
2490 let args = self.expr_slice(args);
2491 let name = self.function_name("coalesce");
2492 return Ok(self.push(Expr::Function { name, args, distinct, filter }));
2493 }
2494 let args = self.expr_slice(args);
2495 Ok(self.push(Expr::Function { name, args, distinct, filter }))
2496 }
2497
2498 fn window_clause(&mut self, node: u32) -> Result<()> {
2506 for kid in self.kids(node) {
2507 if self.name(kid) != "WindowDefinition" {
2508 continue;
2509 }
2510 let name = self.identifier(self.first(kid));
2511 let definition = self.find(kid, "WindowFrameDefinition");
2512 if definition == NONE {
2513 return self.unsupported(kid);
2514 }
2515 let (spec, framed) = self.window_definition(definition)?;
2516 let spec = self.push_window(spec);
2517 self.named_windows.push((name, spec, framed));
2518 }
2519 Ok(())
2520 }
2521
2522 fn over(&mut self, node: u32) -> Result<WindowRef> {
2531 let mut frame = self.first(node);
2532 if self.name(frame) == "WindowFrame" {
2533 frame = self.first(frame);
2534 }
2535 match self.name(frame) {
2536 "ParensIdentifier" | "IdentifierWindowFrame" => {
2537 let name = self.identifier(self.first(frame));
2538 let (spec, _) = self.named_window(name)?;
2539 Ok(spec)
2540 }
2541 "WindowFrameDefinition" => {
2542 let (spec, _) = self.window_definition(frame)?;
2543 Ok(self.push_window(spec))
2544 }
2545 _ => self.unsupported(frame),
2546 }
2547 }
2548
2549 fn named_window(&self, name: StrRef) -> Result<(WindowRef, bool)> {
2551 let written = self.ast.string(name);
2552 let found = self
2553 .named_windows
2554 .iter()
2555 .rev()
2556 .find(|&&(defined, _, _)| self.ast.string(defined).eq_ignore_ascii_case(written));
2557 match found {
2558 Some(&(_, spec, framed)) => Ok((spec, framed)),
2559 None => Err(Error::parser(format!("window \"\"{written}\"\" does not exist"))),
2563 }
2564 }
2565
2566 fn window_definition(&mut self, node: u32) -> Result<(WindowSpec, bool)> {
2573 let held = self.first(self.first(node));
2574 let (base, contents) = match self.name(held) {
2575 "WindowFrameNameContents" => {
2576 (self.find(held, "BaseWindowName"), self.find(held, "WindowFrameContents"))
2577 }
2578 "WindowFrameContents" => (NONE, held),
2579 _ => return self.unsupported(held),
2580 };
2581 if contents == NONE {
2582 return self.unsupported(node);
2583 }
2584 let partition = self.find(contents, "WindowPartition");
2585 let order = self.find(contents, "OrderByClause");
2586 let frame = self.find(contents, "FrameClause");
2587 let mut spec = WindowSpec::empty();
2588 if base != NONE {
2589 let name = self.identifier(self.first(base));
2590 let written = self.ast.string(name).to_string();
2591 let (found, framed) = self.named_window(name)?;
2592 if framed {
2596 return Err(Error::parser(format!(
2597 "cannot copy window \"{written}\" because it has a frame clause"
2598 )));
2599 }
2600 spec = self.ast.window(found);
2601 if partition != NONE && !spec.partition.is_empty() {
2602 return Err(Error::parser(format!(
2603 "Cannot override PARTITION BY clause of window \"{written}\""
2604 )));
2605 }
2606 if order != NONE && !spec.order.is_empty() {
2607 return Err(Error::parser(format!(
2608 "Cannot override ORDER BY clause of window \"{written}\""
2609 )));
2610 }
2611 }
2612 if partition != NONE {
2613 let mut items = Vec::new();
2614 for kid in self.kids(partition) {
2615 items.push(self.expr(kid)?);
2616 }
2617 spec.partition = self.expr_slice(items);
2618 }
2619 if order != NONE {
2620 let (items, all) = self.order_by(order)?;
2621 if all {
2622 return self.unsupported(order);
2623 }
2624 spec.order = self.order_slice(items);
2625 }
2626 if frame != NONE {
2627 self.frame_clause(&mut spec, frame)?;
2628 }
2629 Ok((spec, frame != NONE))
2630 }
2631
2632 fn frame_clause(&mut self, spec: &mut WindowSpec, node: u32) -> Result<()> {
2640 let framing = self.first(self.find(node, "Framing"));
2641 spec.unit = match self.name(framing) {
2642 "RowsFraming" => WindowUnit::Rows,
2643 "RangeFraming" => WindowUnit::Range,
2644 "GroupsFraming" => WindowUnit::Groups,
2645 _ => return self.unsupported(framing),
2646 };
2647 let extent = self.first(self.find(node, "FrameExtent"));
2648 match self.name(extent) {
2649 "SingleFrameExtent" => {
2652 spec.start = self.frame_bound(self.first(extent))?;
2653 spec.end = WindowBound::CurrentRow;
2654 }
2655 "BetweenFrameExtent" => {
2657 spec.start = self.frame_bound(self.first(extent))?;
2658 spec.end = self.frame_bound(self.nth(extent, 1))?;
2659 }
2660 _ => return self.unsupported(extent),
2661 }
2662 let exclude = self.find(node, "WindowExcludeClause");
2663 if exclude != NONE {
2664 let element = self.first(self.first(exclude));
2665 spec.exclude = match self.name(element) {
2666 "ExcludeCurrentRow" => WindowExclude::CurrentRow,
2667 "ExcludeGroup" => WindowExclude::Group,
2668 "ExcludeTies" => WindowExclude::Ties,
2669 "ExcludeNoOthers" => WindowExclude::NoOthers,
2670 _ => return self.unsupported(element),
2671 };
2672 }
2673 if spec.start == WindowBound::UnboundedPreceding
2674 && spec.end == WindowBound::UnboundedFollowing
2675 {
2676 spec.unit = WindowUnit::Rows;
2677 }
2678 Ok(())
2679 }
2680
2681 fn frame_bound(&mut self, node: u32) -> Result<WindowBound> {
2683 let inner = if self.name(node) == "FrameBound" { self.first(node) } else { node };
2684 match self.name(inner) {
2685 "FrameCurrentRow" => Ok(WindowBound::CurrentRow),
2686 "FrameUnbounded" => {
2688 if self.preceding(self.first(inner)) {
2689 Ok(WindowBound::UnboundedPreceding)
2690 } else {
2691 Ok(WindowBound::UnboundedFollowing)
2692 }
2693 }
2694 "FrameExpression" => {
2696 let offset = self.expr(self.first(inner))?;
2697 if self.preceding(self.nth(inner, 1)) {
2698 Ok(WindowBound::Preceding(offset))
2699 } else {
2700 Ok(WindowBound::Following(offset))
2701 }
2702 }
2703 _ => self.unsupported(inner),
2704 }
2705 }
2706
2707 fn preceding(&self, node: u32) -> bool {
2709 self.name(self.first(node)) == "PrecedingFrame"
2710 }
2711
2712 fn coalesce(&mut self, node: u32) -> Result<ExprRef> {
2723 let mut args = Vec::new();
2724 for kid in self.kids(node) {
2725 args.push(self.expr(kid)?);
2726 }
2727 let args = self.expr_slice(args);
2728 let name = self.function_name("coalesce");
2729 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2730 }
2731
2732 fn null_if(&mut self, node: u32) -> Result<ExprRef> {
2742 let arguments = self.find(node, "NullIfArguments");
2743 if arguments == NONE {
2744 return self.unsupported(node);
2745 }
2746 let mut args = Vec::new();
2747 for kid in self.kids(arguments) {
2748 args.push(self.expr(kid)?);
2749 }
2750 let args = self.expr_slice(args);
2751 let name = self.function_name("nullif");
2752 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2753 }
2754
2755 fn substring(&mut self, node: u32) -> Result<ExprRef> {
2764 let shape = self.first(self.first(node));
2765 let mut args = Vec::new();
2766 match self.name(shape) {
2767 "SubstringExpressionList" => {
2768 for kid in self.kids(shape) {
2769 args.push(self.expr(kid)?);
2770 }
2771 }
2772 "SubstringParameters" => {
2773 args.push(self.expr(self.first(shape))?);
2774 let bounds = self.first(self.nth(shape, 1));
2778 let from = self.find(bounds, "FromExpression");
2779 let start =
2780 if from == NONE { self.number("1") } else { self.expr(self.first(from))? };
2781 args.push(start);
2782 let count = self.find(bounds, "ForExpression");
2783 if count != NONE {
2784 args.push(self.expr(self.first(count))?);
2785 }
2786 }
2787 _ => return self.unsupported(shape),
2788 }
2789 let args = self.expr_slice(args);
2790 let name = self.function_name("substring");
2791 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2792 }
2793
2794 fn position(&mut self, node: u32) -> Result<ExprRef> {
2801 let arguments = self.first(node);
2802 if self.count(arguments) != 2 {
2803 return self.unsupported(arguments);
2804 }
2805 let needle = self.expr(self.first(arguments))?;
2806 let haystack = self.expr(self.nth(arguments, 1))?;
2807 let args = self.expr_slice(vec![haystack, needle]);
2808 let name = self.function_name("position");
2809 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2810 }
2811
2812 fn trim(&mut self, node: u32) -> Result<ExprRef> {
2821 let arguments = self.first(node);
2822 let direction = self.find(arguments, "TrimDirection");
2823 let name = match direction {
2824 NONE => "trim",
2825 held => match self.name(self.first(held)) {
2826 "TrimLeading" => "ltrim",
2827 "TrimTrailing" => "rtrim",
2828 _ => "trim",
2829 },
2830 };
2831 let mut args = Vec::new();
2832 for kid in self.kids(arguments) {
2833 if matches!(self.name(kid), "TrimDirection" | "TrimSource") {
2834 continue;
2835 }
2836 args.push(self.expr(kid)?);
2837 }
2838 let source = self.find(arguments, "TrimSource");
2841 if source != NONE && self.count(source) == 1 {
2842 args.push(self.expr(self.first(source))?);
2843 }
2844 let args = self.expr_slice(args);
2845 let name = self.function_name(name);
2846 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2847 }
2848
2849 fn overlay(&mut self, node: u32) -> Result<ExprRef> {
2857 let shape = self.first(self.first(node));
2858 if !matches!(self.name(shape), "OverlayParameters" | "OverlayExpressionList") {
2859 return self.unsupported(shape);
2860 }
2861 let mut args = Vec::new();
2862 for kid in self.kids(shape) {
2863 let kid = match self.name(kid) {
2864 "FromExpression" | "ForExpression" => self.first(kid),
2865 _ => kid,
2866 };
2867 args.push(self.expr(kid)?);
2868 }
2869 let args = self.expr_slice(args);
2870 let name = self.function_name("overlay");
2871 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2872 }
2873
2874 fn number(&mut self, text: &str) -> ExprRef {
2876 let text = self.intern(text);
2877 self.push(Expr::Literal { kind: LiteralKind::Number, text })
2878 }
2879
2880 fn extract(&mut self, node: u32) -> Result<ExprRef> {
2889 let arguments = self.find(node, "ExtractArguments");
2890 if arguments == NONE {
2891 return self.unsupported(node);
2892 }
2893 let argument = self.first(self.first(arguments));
2894 let part = match self.name(argument) {
2895 "ExtractStringArgument" => self.string_value(argument)?,
2896 "ExtractDatePartArgument" => date_part(self.text(argument)),
2901 "ExtractIdentifierArgument" => self.text(argument).to_string(),
2904 _ => return self.unsupported(argument),
2905 };
2906 let text = self.intern(&part);
2907 let part = self.push(Expr::Literal { kind: LiteralKind::String, text });
2908 let operand = self.expr(self.nth(arguments, 1))?;
2909 let name = self.function_name("date_part");
2910 let args = self.expr_slice(vec![part, operand]);
2911 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
2912 }
2913
2914 fn argument(&mut self, node: u32) -> Result<ExprRef> {
2916 let inner = self.first(node);
2917 match self.name(inner) {
2918 "PositionalFunctionArgument" => self.expr(self.first(inner)),
2919 _ => self.unsupported(inner),
2920 }
2921 }
2922
2923 fn table_argument(&mut self, node: u32) -> Result<Target> {
2938 let inner = self.first(node);
2939 if self.name(inner) == "NamedFunctionArgument" {
2940 let named = self.first(inner);
2941 if self.count(named) != 3 {
2942 return self.unsupported(named);
2945 }
2946 let alias = self.identifier(self.first(named));
2947 let expr = self.expr(self.nth(named, 2))?;
2948 return Ok(Target { expr, alias });
2949 }
2950 let expr = self.expr(self.first(inner))?;
2951 if let Expr::Binary { op: BinaryOp::Eq, left, right } = self.ast.expr(expr) {
2952 if let Expr::Column { name } = self.ast.expr(left) {
2953 if name.len == 1 {
2954 let alias = self.ast.parts[name.start as usize];
2955 return Ok(Target { expr: right, alias });
2956 }
2957 }
2958 }
2959 Ok(Target { expr, alias: NONE })
2960 }
2961
2962 fn cast(&mut self, node: u32) -> Result<ExprRef> {
2964 let try_cast = self.name(self.first(self.first(node))) == "TryCastKeyword";
2965 let arguments = self.nth(node, 1);
2967 let operand = self.expr(self.first(arguments))?;
2968 let text = self.text(self.nth(arguments, 1)).to_string();
2969 let ty = self.intern(&text);
2970 Ok(self.push(Expr::Cast { operand, ty, try_cast }))
2971 }
2972
2973 fn typed_literal(&mut self, node: u32) -> Result<ExprRef> {
2983 let text = self.text(self.first(node)).to_string();
2984 let ty = self.intern(&text);
2985 let operand = self.expr(self.nth(node, 1))?;
2986 Ok(self.push(Expr::Cast { operand, ty, try_cast: false }))
2987 }
2988
2989 fn interval_literal(&mut self, node: u32) -> Result<ExprRef> {
3007 let parameter = self.find(node, "IntervalParameter");
3008 if parameter == NONE {
3009 return self.unsupported(node);
3010 }
3011 let operand = self.expr(self.first(parameter))?;
3012 let unit = self.find(node, "Interval");
3013 if unit == NONE {
3014 let ty = self.intern("INTERVAL");
3015 return Ok(self.push(Expr::Cast { operand, ty, try_cast: false }));
3016 }
3017 let spelling = self.name(self.first(unit));
3018 if spelling == "IntervalToInterval" {
3022 let pair = self.name(self.first(self.first(unit)));
3023 return Err(Error::parser(format!("{} is not supported", worded(pair))));
3024 }
3025 let Some(&(_, function, width)) = UNITS.iter().find(|(rule, _, _)| *rule == spelling)
3026 else {
3027 return self.unsupported(unit);
3028 };
3029 let double = self.intern("DOUBLE");
3030 let mut count = self.push(Expr::Cast { operand, ty: double, try_cast: false });
3031 if let Some(width) = width {
3032 let name = self.function_name("trunc");
3033 let args = self.expr_slice(vec![count]);
3034 let whole = self.push(Expr::Function { name, args, distinct: false, filter: NONE });
3035 let ty = self.intern(width);
3036 count = self.push(Expr::Cast { operand: whole, ty, try_cast: false });
3037 }
3038 let name = self.function_name(function);
3039 let args = self.expr_slice(vec![count]);
3040 Ok(self.push(Expr::Function { name, args, distinct: false, filter: NONE }))
3041 }
3042
3043 fn case(&mut self, node: u32) -> Result<ExprRef> {
3045 let mut operand = NONE;
3046 let mut arms = Vec::new();
3047 let mut otherwise = NONE;
3048 for kid in self.kids(node) {
3049 match self.name(kid) {
3050 "CaseWhenThen" => {
3052 let when = self.expr(self.first(kid))?;
3053 let then = self.expr(self.nth(kid, 1))?;
3054 arms.push(CaseArm { when, then });
3055 }
3056 "CaseElse" => otherwise = self.expr(self.first(kid))?,
3058 _ => operand = self.expr(kid)?,
3060 }
3061 }
3062 let start = self.ast.case_arms.len() as u32;
3063 self.ast.case_arms.extend(arms);
3064 let arms = Slice { start, len: self.ast.case_arms.len() as u32 - start };
3065 Ok(self.push(Expr::Case { operand, arms, otherwise }))
3066 }
3067
3068 fn row(&mut self, node: u32) -> Result<ExprRef> {
3073 let mut items = Vec::new();
3074 for kid in self.kids(node) {
3075 items.push(self.expr(kid)?);
3076 }
3077 if items.len() == 1 {
3078 return Ok(items[0]);
3079 }
3080 let items = self.expr_slice(items);
3081 Ok(self.push(Expr::Row { items }))
3082 }
3083
3084 fn parameter(&mut self, node: u32) -> Result<ExprRef> {
3091 let written = self.text(node).trim();
3092 let written = written.trim_start_matches(['?', '$']).trim();
3093 let name = if written.is_empty() {
3094 self.anonymous += 1;
3095 self.anonymous.to_string()
3096 } else {
3097 written.to_string()
3098 };
3099 let name = self.intern(&name);
3100 Ok(self.push(Expr::Parameter { name }))
3101 }
3102
3103 fn list(&mut self, node: u32) -> Result<ExprRef> {
3108 let mut items = Vec::new();
3109 for kid in self.kids(node) {
3110 items.push(self.expr(kid)?);
3111 }
3112 let items = self.expr_slice(items);
3113 Ok(self.push(Expr::List { items }))
3114 }
3115
3116 fn subquery(&mut self, node: u32) -> Result<ExprRef> {
3118 let negated = self.find(node, "SubqueryNot") != NONE;
3119 let exists = self.find(node, "SubqueryExists") != NONE;
3120 let reference = self.find(node, "SubqueryReference");
3121 let query = self.query(self.first(reference))?;
3122 Ok(if exists {
3123 self.push(Expr::Exists { query, negated })
3124 } else if negated {
3125 return self.unsupported(node);
3126 } else {
3127 self.push(Expr::Subquery { query })
3128 })
3129 }
3130
3131 fn string_value(&self, node: u32) -> Result<String> {
3137 let span = self.tree.node(node);
3138 let mut value = String::new();
3139 for token in &self.tokens[span.start as usize..span.end as usize] {
3140 if token.kind == Kind::String {
3141 value.push_str(&string_token(token.text(self.query))?);
3142 }
3143 }
3144 Ok(value)
3145 }
3146
3147 fn first_string(&self, node: u32) -> &'a str {
3153 let span = self.tree.node(node);
3154 self.tokens[span.start as usize..span.end as usize]
3155 .iter()
3156 .find(|token| token.kind == Kind::String)
3157 .map_or("", |token| token.text(self.query))
3158 }
3159
3160 fn string_literal(&mut self, node: u32) -> Result<ExprRef> {
3169 let token = self.first_string(node);
3170 let prefix = match token.as_bytes() {
3171 [prefix, b'\'', ..] => *prefix,
3172 _ => 0,
3173 };
3174 if matches!(prefix, b'X' | b'x') {
3175 if let Some(body) = token.get(1..).and_then(quoted_body) {
3176 let text = blob_text(body.as_bytes())?;
3177 let text = self.intern(&text);
3178 return Ok(self.push(Expr::Literal { kind: LiteralKind::Blob, text }));
3179 }
3180 }
3181 let value = self.string_value(node)?;
3182 let text = self.intern(&value);
3183 let literal = self.push(Expr::Literal { kind: LiteralKind::String, text });
3184 if matches!(prefix, b'N' | b'n') {
3185 let ty = self.intern("VARCHAR");
3186 return Ok(self.push(Expr::Cast { operand: literal, ty, try_cast: false }));
3187 }
3188 Ok(literal)
3189 }
3190}
3191
3192const UNITS: &[(&str, &str, Option<&str>)] = &[
3200 ("YearKeyword", "to_years", Some("INTEGER")),
3201 ("MonthKeyword", "to_months", Some("INTEGER")),
3202 ("QuarterKeyword", "to_quarters", Some("INTEGER")),
3203 ("DecadeKeyword", "to_decades", Some("INTEGER")),
3204 ("CenturyKeyword", "to_centuries", Some("INTEGER")),
3205 ("MillenniumKeyword", "to_millennia", Some("INTEGER")),
3206 ("DayKeyword", "to_days", Some("INTEGER")),
3207 ("WeekKeyword", "to_weeks", Some("INTEGER")),
3208 ("HourKeyword", "to_hours", Some("BIGINT")),
3209 ("MinuteKeyword", "to_minutes", Some("BIGINT")),
3210 ("MicrosecondKeyword", "to_microseconds", Some("BIGINT")),
3211 ("SecondKeyword", "to_seconds", None),
3212 ("MillisecondKeyword", "to_milliseconds", None),
3213];
3214
3215fn date_part(written: &str) -> String {
3226 const PARTS: &[(&str, &str)] = &[
3227 ("YEAR", "YEAR"),
3228 ("YEARS", "YEAR"),
3229 ("MONTH", "MONTH"),
3230 ("MONTHS", "MONTH"),
3231 ("DAY", "DAY"),
3232 ("DAYS", "DAY"),
3233 ("HOUR", "HOUR"),
3234 ("HOURS", "HOUR"),
3235 ("MINUTE", "MINUTE"),
3236 ("MINUTES", "MINUTE"),
3237 ("SECOND", "SECOND"),
3238 ("SECONDS", "SECOND"),
3239 ("MILLISECOND", "MILLISECONDS"),
3240 ("MILLISECONDS", "MILLISECONDS"),
3241 ("MICROSECOND", "MICROSECONDS"),
3242 ("MICROSECONDS", "MICROSECONDS"),
3243 ("WEEK", "WEEK"),
3244 ("WEEKS", "WEEK"),
3245 ("QUARTER", "QUARTER"),
3246 ("QUARTERS", "QUARTER"),
3247 ("DECADE", "DECADE"),
3248 ("DECADES", "DECADE"),
3249 ("CENTURY", "CENTURY"),
3250 ("CENTURIES", "CENTURY"),
3251 ("MILLENNIUM", "MILLENNIUM"),
3252 ("MILLENNIA", "MILLENNIUM"),
3253 ];
3254 PARTS
3255 .iter()
3256 .find(|(spelling, _)| spelling.eq_ignore_ascii_case(written))
3257 .map_or_else(|| written.to_string(), |(_, name)| (*name).to_string())
3258}
3259
3260fn worded(rule: &str) -> String {
3262 let mut out = String::new();
3263 for character in rule.chars() {
3264 if character.is_ascii_uppercase() && !out.is_empty() {
3265 out.push(' ');
3266 }
3267 out.push(character.to_ascii_uppercase());
3268 }
3269 out
3270}
3271
3272fn string_token(text: &str) -> Result<String> {
3279 if let Some(body) = dollar_body(text) {
3280 return Ok(body.to_string());
3281 }
3282 if let Some(body) = quoted_body(text) {
3283 return Ok(body.replace("''", "'"));
3284 }
3285 let Some(body) = text.get(1..).and_then(quoted_body) else {
3286 return Ok(text.to_string());
3287 };
3288 match text.as_bytes()[0] {
3289 b'E' | b'e' => escaped(body),
3290 b'N' | b'n' => Ok(body.replace("''", "'")),
3292 b'B' | b'b' => Ok(format!("b{}", body.replace("''", "'"))),
3296 _ => Err(Error::not_implemented(format!("the string literal {text} is not supported yet"))),
3299 }
3300}
3301
3302fn blob_text(body: &[u8]) -> Result<String> {
3314 if body.len() % 2 != 0 {
3315 return Err(Error::parser("Hex string literal must have an even number of hex digits"));
3316 }
3317 let digit = |byte: u8| (byte as char).to_digit(16).map(|digit| digit as u8);
3318 let bytes: Option<Vec<u8>> =
3319 body.chunks(2).map(|pair| Some(digit(pair[0])? * 16 + digit(pair[1])?)).collect();
3320 match bytes {
3321 Some(bytes) => Ok(Value::Blob(bytes).to_string()),
3322 None => {
3323 Ok(body.chunks(2).map(|pair| format!("\\x{}", String::from_utf8_lossy(pair))).collect())
3324 }
3325 }
3326}
3327
3328fn quoted_body(text: &str) -> Option<&str> {
3333 text.strip_prefix('\'').filter(|rest| !rest.is_empty()).and_then(|rest| rest.strip_suffix('\''))
3334}
3335
3336fn escaped(body: &str) -> Result<String> {
3349 let bytes = body.as_bytes();
3350 let mut out = Vec::with_capacity(bytes.len());
3351 let mut at = 0;
3352 while at < bytes.len() {
3353 let byte = bytes[at];
3354 at += 1;
3355 if byte == b'\'' && bytes.get(at) == Some(&b'\'') {
3356 out.push(b'\'');
3357 at += 1;
3358 continue;
3359 }
3360 if byte != b'\\' || at == bytes.len() {
3361 out.push(byte);
3362 continue;
3363 }
3364 let escape = bytes[at];
3365 at += 1;
3366 match escape {
3367 b'n' => out.push(b'\n'),
3368 b't' => out.push(b'\t'),
3369 b'r' => out.push(b'\r'),
3370 b'b' => out.push(0x08),
3371 b'f' => out.push(0x0c),
3372 b'x' => match digits(bytes, &mut at, 16, 2) {
3373 Some(value) => out.push(value as u8),
3374 None => out.push(b'x'),
3375 },
3376 b'0'..=b'7' => {
3377 at -= 1;
3378 let value = digits(bytes, &mut at, 8, 3).unwrap_or(0);
3379 out.push(value as u8);
3380 }
3381 b'u' => match four_hex(bytes, at).and_then(char::from_u32).filter(|c| *c != '\0') {
3382 Some(c) => {
3383 at += 4;
3384 out.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes());
3385 }
3386 None => out.push(b'u'),
3387 },
3388 other => out.push(other),
3389 }
3390 }
3391 if out.contains(&0) {
3392 return Err(Error::parser("Null character not permitted in escape string literal"));
3393 }
3394 String::from_utf8(out).map_err(|error| {
3395 Error::parser(format!(
3396 "Invalid UTF-8 in escape string literal at byte offset {}: byte mismatch",
3397 error.utf8_error().valid_up_to()
3398 ))
3399 })
3400}
3401
3402fn digits(bytes: &[u8], at: &mut usize, radix: u32, most: usize) -> Option<u32> {
3407 let mut value = None;
3408 for _ in 0..most {
3409 let Some(digit) = bytes.get(*at).and_then(|byte| (*byte as char).to_digit(radix)) else {
3410 break;
3411 };
3412 value = Some(value.unwrap_or(0) * radix + digit);
3413 *at += 1;
3414 }
3415 value
3416}
3417
3418fn four_hex(bytes: &[u8], at: usize) -> Option<u32> {
3424 let digits = bytes.get(at..at + 4)?;
3425 if !digits.iter().all(u8::is_ascii_hexdigit) {
3426 return None;
3427 }
3428 u32::from_str_radix(std::str::from_utf8(digits).ok()?, 16).ok()
3429}
3430
3431fn dollar_body(text: &str) -> Option<&str> {
3440 let rest = text.strip_prefix('$')?;
3441 let close = rest.find('$')?;
3442 let (tag, body) = (&rest[..close], &rest[close + 1..]);
3443 body.strip_suffix(&format!("${tag}$"))
3444}
3445
3446fn unquote(text: &str) -> String {
3456 if let Some(body) = text.strip_prefix('"').and_then(|rest| rest.strip_suffix('"')) {
3457 return body.replace("\"\"", "\"");
3458 }
3459 match text.strip_prefix('\'').and_then(|rest| rest.strip_suffix('\'')) {
3460 Some(body) => body.replace("''", "'"),
3461 None => text.to_string(),
3462 }
3463}
3464
3465#[cfg(test)]
3466mod tests {
3467 use super::*;
3468 use crate::corpus::CORPUS;
3469 use crate::matcher::parse;
3470
3471 fn show(ast: &Ast, expr: ExprRef) -> String {
3479 if expr == NONE {
3480 return "-".to_string();
3481 }
3482 fn shown_filter(ast: &Ast, filter: ExprRef) -> String {
3484 if filter == NONE { String::new() } else { format!(" FILTER [{}]", show(ast, filter)) }
3485 }
3486 let list = |slice: Slice| {
3487 ast.expr_list(slice).iter().map(|&item| show(ast, item)).collect::<Vec<_>>().join(", ")
3488 };
3489 match ast.expr(expr) {
3490 Expr::Star { qualifier, replacements } => {
3491 let star = if qualifier.is_empty() {
3492 "*".to_string()
3493 } else {
3494 format!("{}.*", ast.name_text(qualifier))
3495 };
3496 if replacements.is_empty() {
3497 return star;
3498 }
3499 let entries: Vec<String> = ast
3500 .target_list(replacements)
3501 .iter()
3502 .map(|target| {
3503 format!("{} AS {}", show(ast, target.expr), ast.string(target.alias))
3504 })
3505 .collect();
3506 format!("{star} REPLACE ({})", entries.join(", "))
3507 }
3508 Expr::Column { name } => ast.name_text(name),
3509 Expr::Literal { kind, text } => match kind {
3510 LiteralKind::Number => ast.string(text).to_string(),
3511 LiteralKind::String => format!("'{}'", ast.string(text)),
3512 LiteralKind::Blob => format!("'{}'::BLOB", ast.string(text)),
3513 other => format!("{other:?}").to_uppercase(),
3514 },
3515 Expr::Unary { op, operand } => format!("({op:?} {})", show(ast, operand)),
3516 Expr::Binary { op, left, right } => {
3517 let op = match op {
3518 BinaryOp::Named(name) => ast.string(name).to_string(),
3519 other => format!("{other:?}"),
3520 };
3521 format!("({} {op} {})", show(ast, left), show(ast, right))
3522 }
3523 Expr::Function { name, args, distinct, filter } => {
3524 let distinct = if distinct { "DISTINCT " } else { "" };
3525 let filter = shown_filter(ast, filter);
3526 format!("{}({distinct}{}){filter}", ast.name_text(name), list(args))
3527 }
3528 Expr::Window { name, args, distinct, filter, ignore_nulls, spec } => {
3529 let distinct = if distinct { "DISTINCT " } else { "" };
3530 let filter = shown_filter(ast, filter);
3531 let nulls = if ignore_nulls { " IGNORE NULLS" } else { "" };
3532 let held = ast.window(spec);
3533 let order = ast
3534 .order_list(held.order)
3535 .iter()
3536 .map(|item| {
3537 format!("{} {:?} {:?}", show(ast, item.expr), item.order, item.nulls)
3538 })
3539 .collect::<Vec<_>>()
3540 .join(", ");
3541 let bound = |end: WindowBound| match end {
3542 WindowBound::Preceding(offset) => format!("Preceding({})", show(ast, offset)),
3543 WindowBound::Following(offset) => format!("Following({})", show(ast, offset)),
3544 other => format!("{other:?}"),
3545 };
3546 format!(
3547 "{}({distinct}{}{nulls}){filter} OVER [{}] [{order}] [{:?} {} {} {:?}]",
3548 ast.name_text(name),
3549 list(args),
3550 list(held.partition),
3551 held.unit,
3552 bound(held.start),
3553 bound(held.end),
3554 held.exclude
3555 )
3556 }
3557 Expr::Cast { operand, ty, try_cast } => {
3558 let word = if try_cast { "TRY_CAST" } else { "CAST" };
3559 format!("{word}({} AS {})", show(ast, operand), ast.string(ty))
3560 }
3561 Expr::Case { operand, arms, otherwise } => {
3562 let arms = ast
3563 .arm_list(arms)
3564 .iter()
3565 .map(|arm| format!("WHEN {} THEN {}", show(ast, arm.when), show(ast, arm.then)))
3566 .collect::<Vec<_>>()
3567 .join(" ");
3568 format!("CASE {} {arms} ELSE {} END", show(ast, operand), show(ast, otherwise))
3569 }
3570 Expr::Between { operand, low, high, negated } => {
3571 let not = if negated { "NOT " } else { "" };
3572 format!(
3573 "({not}{} BETWEEN {} AND {})",
3574 show(ast, operand),
3575 show(ast, low),
3576 show(ast, high)
3577 )
3578 }
3579 Expr::In { operand, list: items, negated } => {
3580 let not = if negated { "NOT " } else { "" };
3581 format!("({not}{} IN [{}])", show(ast, operand), list(items))
3582 }
3583 Expr::List { items } => format!("[{}]", list(items)),
3584 Expr::Parameter { name } => format!("${}", ast.string(name)),
3585 Expr::Row { items } => format!("ROW({})", list(items)),
3586 Expr::Subquery { query } => format!("({})", show_query(ast, query)),
3587 Expr::Exists { query, negated } => {
3588 let exists = format!("EXISTS ({})", show_query(ast, query));
3589 if negated { format!("NOT {exists}") } else { exists }
3590 }
3591 Expr::InSubquery { operand, query, negated } => {
3592 let written = format!("{} IN ({})", show(ast, operand), show_query(ast, query));
3593 if negated { format!("NOT {written}") } else { written }
3594 }
3595 Expr::QuantifiedSubquery { operand, op, query, all } => {
3596 let quantifier = if all { "ALL" } else { "ANY" };
3597 format!("{} {op:?} {quantifier} ({})", show(ast, operand), show_query(ast, query))
3598 }
3599 }
3600 }
3601
3602 fn show_source(ast: &Ast, source: SourceRef) -> String {
3604 let alias = |alias: StrRef| match alias {
3605 NONE => String::new(),
3606 other => format!(" AS {}", ast.string(other)),
3607 };
3608 match ast.source(source) {
3609 Source::Table { name, alias: name_alias, .. } => {
3610 format!("{}{}", ast.name_text(name), alias(name_alias))
3611 }
3612 Source::Function { name, args, alias: call_alias, .. } => {
3613 let args = ast
3614 .target_list(args)
3615 .iter()
3616 .map(|item| match item.alias {
3617 NONE => show(ast, item.expr),
3618 named => format!("{} := {}", ast.string(named), show(ast, item.expr)),
3619 })
3620 .collect::<Vec<_>>()
3621 .join(", ");
3622 format!("{}({args}){}", ast.name_text(name), alias(call_alias))
3623 }
3624 Source::Subquery { query, alias: query_alias, .. } => {
3625 format!("({}){}", show_query(ast, query), alias(query_alias))
3626 }
3627 Source::Cte { cte, alias: cte_alias, .. } => {
3628 format!("{}{}", ast.string(ast.cte(cte).name), alias(cte_alias))
3629 }
3630 Source::Values { rows, alias: values_alias, .. } => {
3631 format!("{}{}", show_rows(ast, rows), alias(values_alias))
3632 }
3633 Source::Join { left, right, kind, natural, on, using } => {
3634 let natural = if natural { "NATURAL " } else { "" };
3635 let on = if on == NONE { String::new() } else { format!(" ON {}", show(ast, on)) };
3636 let using = if using.is_empty() {
3637 String::new()
3638 } else {
3639 format!(" USING ({})", ast.name_text(using))
3640 };
3641 format!(
3642 "({} {natural}{kind:?} JOIN {}{on}{using})",
3643 show_source(ast, left),
3644 show_source(ast, right)
3645 )
3646 }
3647 }
3648 }
3649
3650 fn show_rows(ast: &Ast, rows: Slice) -> String {
3652 let rows = ast
3653 .rows(rows)
3654 .iter()
3655 .map(|&row| {
3656 let items = ast
3657 .expr_list(row)
3658 .iter()
3659 .map(|&item| show(ast, item))
3660 .collect::<Vec<_>>()
3661 .join(", ");
3662 format!("({items})")
3663 })
3664 .collect::<Vec<_>>()
3665 .join(", ");
3666 format!("VALUES {rows}")
3667 }
3668
3669 fn show_query(ast: &Ast, index: QueryRef) -> String {
3671 let query = ast.query(index);
3672 let list = |slice: Slice| {
3673 ast.expr_list(slice).iter().map(|&item| show(ast, item)).collect::<Vec<_>>().join(", ")
3674 };
3675 let mut out = String::new();
3676 for &index in ast.cte_list(query.ctes) {
3677 let cte = ast.cte(index);
3678 let columns = ast.name(cte.columns).collect::<Vec<_>>().join(", ");
3679 let columns = if columns.is_empty() { columns } else { format!("({columns})") };
3680 out += &format!(
3681 "WITH {}{columns} AS MATERIALIZED ({}) ",
3682 ast.string(cte.name),
3683 show_query(ast, cte.query)
3684 );
3685 }
3686 out += &match query.body {
3687 QueryBody::SetOp { op, quantifier, by_name, left, right } => {
3688 let by_name = if by_name { " BY NAME" } else { "" };
3689 format!(
3690 "({} {op:?} {quantifier:?}{by_name} {})",
3691 show_query(ast, left),
3692 show_query(ast, right)
3693 )
3694 }
3695 QueryBody::Select(index) => {
3696 let select = ast.select(index);
3697 let distinct = match select.distinct {
3698 Distinct::No => String::new(),
3699 Distinct::Yes => " DISTINCT".to_string(),
3700 Distinct::On(on) => format!(" DISTINCT ON ({})", list(on)),
3701 };
3702 let targets = ast
3703 .target_list(select.targets)
3704 .iter()
3705 .map(|target| match target.alias {
3706 NONE => show(ast, target.expr),
3707 alias => format!("{} AS {}", show(ast, target.expr), ast.string(alias)),
3708 })
3709 .collect::<Vec<_>>()
3710 .join(", ");
3711 let mut out = format!("SELECT{distinct} {targets}");
3712 if !select.from.is_empty() {
3713 let from = ast
3714 .source_list(select.from)
3715 .iter()
3716 .map(|&source| show_source(ast, source))
3717 .collect::<Vec<_>>()
3718 .join(", ");
3719 out += &format!(" FROM {from}");
3720 }
3721 if select.filter != NONE {
3722 out += &format!(" WHERE {}", show(ast, select.filter));
3723 }
3724 if select.group_by_all {
3725 out += " GROUP BY ALL";
3726 } else if !select.group_by.is_empty() {
3727 out += &format!(" GROUP BY {}", list(select.group_by));
3728 }
3729 if select.having != NONE {
3730 out += &format!(" HAVING {}", show(ast, select.having));
3731 }
3732 out
3733 }
3734 QueryBody::Values(rows) => show_rows(ast, rows),
3735 QueryBody::Describe(inner) => format!("DESCRIBE {}", show_query(ast, inner)),
3736 QueryBody::Show { name, .. } => format!("SHOW {}", ast.name_text(name)),
3737 };
3738 if query.order_by_all {
3739 out += " ORDER BY ALL";
3740 } else if !query.order_by.is_empty() {
3741 let items = ast
3742 .order_list(query.order_by)
3743 .iter()
3744 .map(|item| format!("{} {:?} {:?}", show(ast, item.expr), item.order, item.nulls))
3745 .collect::<Vec<_>>()
3746 .join(", ");
3747 out += &format!(" ORDER BY {items}");
3748 }
3749 if query.limit != NONE {
3750 let percent = if query.limit_percent { "%" } else { "" };
3751 out += &format!(" LIMIT {}{percent}", show(ast, query.limit));
3752 }
3753 if query.offset != NONE {
3754 out += &format!(" OFFSET {}", show(ast, query.offset));
3755 }
3756 out
3757 }
3758
3759 fn round(query: &str) -> String {
3761 let ast = parse_ast(query).unwrap_or_else(|error| panic!("{query}: {error}"));
3762 assert_eq!(ast.statements.len(), 1, "{query} is one statement");
3763 let Statement::Query(index) = ast.statements[0] else {
3764 panic!("{query} is not a query");
3765 };
3766 show_query(&ast, index)
3767 }
3768
3769 fn round_with_case(query: &str, case: IdentifierCase) -> String {
3770 let ast =
3771 parse_ast_with_case(query, case).unwrap_or_else(|error| panic!("{query}: {error}"));
3772 let Statement::Query(index) = ast.statements[0] else {
3773 panic!("{query} is not a query");
3774 };
3775 show_query(&ast, index)
3776 }
3777
3778 fn round_statement(query: &str) -> String {
3780 let ast = parse_ast(query).unwrap_or_else(|error| panic!("{query}: {error}"));
3781 assert_eq!(ast.statements.len(), 1, "{query} is one statement");
3782 match ast.statements[0] {
3783 Statement::Query(index) => show_query(&ast, index),
3784 Statement::CreateTable(index) => {
3785 let create = ast.create_table(index);
3786 let mut out = "CREATE".to_string();
3787 if create.or_replace {
3788 out += " OR REPLACE";
3789 }
3790 if create.temporary {
3791 out += " TEMPORARY";
3792 }
3793 out += " TABLE";
3794 if create.if_not_exists {
3795 out += " IF NOT EXISTS";
3796 }
3797 out += &format!(" {}", ast.name_text(create.name));
3798 let columns = ast
3799 .column_defs(create.columns)
3800 .iter()
3801 .map(|def| {
3802 let ty = match def.ty {
3803 NONE => String::new(),
3804 other => format!(" {}", ast.string(other)),
3805 };
3806 let null = if def.not_null { " NOT NULL" } else { "" };
3807 format!("{}{ty}{null}", ast.string(def.name))
3808 })
3809 .collect::<Vec<_>>()
3810 .join(", ");
3811 if !columns.is_empty() || create.query == NONE {
3812 out += &format!(" ({columns})");
3813 }
3814 if create.query != NONE {
3815 out += &format!(" AS {}", show_query(&ast, create.query));
3816 }
3817 out
3818 }
3819 Statement::CreateView(index) => {
3820 let create = ast.create_view(index);
3821 let mut out = "CREATE".to_string();
3822 if create.or_replace {
3823 out += " OR REPLACE";
3824 }
3825 if create.temporary {
3826 out += " TEMPORARY";
3827 }
3828 out += " VIEW";
3829 if create.if_not_exists {
3830 out += " IF NOT EXISTS";
3831 }
3832 out += &format!(" {}", ast.name_text(create.name));
3833 if !create.columns.is_empty() {
3834 let columns = ast.name(create.columns).collect::<Vec<_>>().join(", ");
3835 out += &format!(" ({columns})");
3836 }
3837 out + &format!(" AS {}", show_query(&ast, create.query))
3838 }
3839 Statement::DropTable(index) => {
3840 let drop = ast.drop_table(index);
3841 let mut out = if drop.view { "DROP VIEW" } else { "DROP TABLE" }.to_string();
3842 if drop.if_exists {
3843 out += " IF EXISTS";
3844 }
3845 let names = ast
3846 .name_list(drop.names)
3847 .iter()
3848 .map(|&name| ast.name_text(name))
3849 .collect::<Vec<_>>()
3850 .join(", ");
3851 out + &format!(" {names}")
3852 }
3853 Statement::Insert(index) => {
3854 let insert = ast.insert(index);
3855 let mut out = format!("INSERT INTO {}", ast.name_text(insert.name));
3856 if !insert.columns.is_empty() {
3857 let columns = ast.name(insert.columns).collect::<Vec<_>>().join(", ");
3858 out += &format!(" ({columns})");
3859 }
3860 out + &format!(" {}", show_query(&ast, insert.source))
3861 }
3862 Statement::Set(index) if ast.setting(index).pragma => {
3863 format!("PRAGMA {}", ast.string(ast.setting(index).name))
3864 }
3865 Statement::Set(index) => {
3866 let setting = ast.setting(index);
3867 let scope = match setting.scope.keyword() {
3868 "" => String::new(),
3869 word => format!(" {word}"),
3870 };
3871 format!("SET{scope} {} = {}", ast.string(setting.name), show(&ast, setting.value))
3872 }
3873 Statement::Reset(index) => {
3874 let setting = ast.setting(index);
3875 let scope = match setting.scope.keyword() {
3876 "" => String::new(),
3877 word => format!(" {word}"),
3878 };
3879 format!("RESET{scope} {}", ast.string(setting.name))
3880 }
3881 Statement::Checkpoint => "CHECKPOINT".to_string(),
3882 Statement::Explain { query, analyze, statistics } => {
3883 let analyze = if analyze { "ANALYZE " } else { "" };
3884 let statistics = if statistics { "(STATISTICS) " } else { "" };
3885 format!("EXPLAIN {analyze}{statistics}{}", show_query(&ast, query))
3886 }
3887 }
3888 }
3889
3890 #[test]
3891 fn expressions_and_queries_keep_their_source_ranges() {
3892 let sql = "SELECT 1 + 22";
3893 let ast = parse_ast(sql).expect("the query parses");
3894 let Statement::Query(query) = ast.statements[0] else { panic!("a query") };
3895 assert_eq!(ast.query_span(query), Span::new(0, sql.len() as u32));
3896 let twenty_two = ast
3897 .exprs
3898 .iter()
3899 .enumerate()
3900 .find_map(|(at, expr)| match *expr {
3901 Expr::Literal { kind: LiteralKind::Number, text } if ast.string(text) == "22" => {
3902 Some(at as u32)
3903 }
3904 _ => None,
3905 })
3906 .expect("the literal is in the arena");
3907 assert_eq!(ast.expr_span(twenty_two), Span::new(11, 13));
3908 }
3909
3910 #[test]
3911 fn an_explain_keeps_the_query_it_was_asked_about() {
3912 assert_eq!(
3913 round_statement("EXPLAIN SELECT a FROM t WHERE a > 1"),
3914 "EXPLAIN SELECT a FROM t WHERE (a Gt 1)"
3915 );
3916 assert_eq!(round_statement("explain select 1"), "EXPLAIN SELECT 1");
3917 assert_eq!(round_statement("explain analyze select 1"), "EXPLAIN ANALYZE SELECT 1");
3918 }
3919
3920 #[test]
3921 fn the_three_explain_options_this_answers_mean_what_their_names_say() {
3922 assert_eq!(round_statement("EXPLAIN (ANALYZE) SELECT 1"), "EXPLAIN ANALYZE SELECT 1");
3925 assert_eq!(
3926 round_statement("explain (analyze) select 1"),
3927 round_statement("explain analyze select 1")
3928 );
3929 assert_eq!(round_statement("EXPLAIN (LOGICAL) SELECT 1"), "EXPLAIN SELECT 1");
3931 assert_eq!(
3932 round_statement("EXPLAIN (STATISTICS) SELECT 1"),
3933 "EXPLAIN (STATISTICS) SELECT 1"
3934 );
3935 assert_eq!(
3936 round_statement("EXPLAIN (ANALYZE, STATISTICS) SELECT 1"),
3937 "EXPLAIN ANALYZE (STATISTICS) SELECT 1"
3938 );
3939 assert_eq!(
3940 round_statement("EXPLAIN ANALYZE (STATISTICS) SELECT 1"),
3941 "EXPLAIN ANALYZE (STATISTICS) SELECT 1"
3942 );
3943 }
3944
3945 #[test]
3946 fn the_parts_of_an_explain_that_are_not_the_query_are_refused_by_name() {
3947 for (query, named) in [
3951 ("EXPLAIN (FORMAT JSON) SELECT 1", "Unimplemented explain type: format"),
3952 ("EXPLAIN (NONSENSE) SELECT 1", "Unimplemented explain type: nonsense"),
3953 ("EXPLAIN (ANALYZE false) SELECT 1", "ExplainOption"),
3954 ("EXPLAIN INSERT INTO t VALUES (1)", "InsertStatement"),
3955 ("EXPLAIN CREATE TABLE u (a INTEGER)", "CreateStatement"),
3956 ] {
3957 let error = parse_ast(query).expect_err(query).to_string();
3958 assert!(error.contains(named), "{query}: {error}");
3959 }
3960 }
3961
3962 #[test]
3963 fn a_set_keeps_its_name_its_scope_and_its_value() {
3964 assert_eq!(round_statement("SET memory_limit = '1GB'"), "SET memory_limit = '1GB'");
3965 assert_eq!(round_statement("set threads=4"), "SET threads = 4");
3966 assert_eq!(round_statement("SET GLOBAL threads = 4"), "SET GLOBAL threads = 4");
3967 assert_eq!(round_statement("SET SESSION threads = 4"), "SET SESSION threads = 4");
3968 assert_eq!(round_statement("SET LOCAL threads = 4"), "SET LOCAL threads = 4");
3969 assert_eq!(round_statement("RESET memory_limit"), "RESET memory_limit");
3970 assert_eq!(round_statement("RESET GLOBAL memory_limit"), "RESET GLOBAL memory_limit");
3971 assert_eq!(
3972 round_statement("SET TIME ZONE 'Asia/Kathmandu'"),
3973 "SET TimeZone = 'Asia/Kathmandu'"
3974 );
3975 assert_eq!(round_statement("SET TIME ZONE UTC"), "SET TimeZone = 'UTC'");
3976 assert_eq!(round_statement("SET TIME ZONE DEFAULT"), "RESET TimeZone");
3977 assert_eq!(round_statement("SET TIME ZONE LOCAL"), "RESET TimeZone");
3978 }
3979
3980 #[test]
3981 fn the_two_other_things_the_word_set_starts_are_refused_rather_than_read_as_settings() {
3982 for statement in ["SET VARIABLE x = 1", "SET SCHEMA 'main'"] {
3986 let error = parse_ast(statement).expect_err(statement);
3987 assert_eq!(error.code().duckdb_name(), "Not implemented Error", "{statement}");
3988 }
3989 }
3990
3991 #[test]
3992 fn a_setting_written_with_a_list_of_values_is_refused_rather_than_taking_the_first() {
3993 let error = parse_ast("SET search_path = a, b").expect_err("a list of two");
3994 assert_eq!(error.code().duckdb_name(), "Not implemented Error");
3995 }
3996
3997 #[test]
3998 fn the_query_m0_has_to_run_transforms() {
3999 assert_eq!(round("SELECT * FROM t WHERE x > 5"), "SELECT * FROM t WHERE (x Gt 5)");
4000 }
4001
4002 #[test]
4003 fn a_replace_list_rides_on_the_star_it_changes() {
4004 assert_eq!(
4007 round("SELECT * REPLACE (a + 1 AS a) FROM t"),
4008 "SELECT * REPLACE ((a Add 1) AS a) FROM t"
4009 );
4010 assert_eq!(
4011 round("SELECT * REPLACE a + 1 AS a FROM t"),
4012 "SELECT * REPLACE ((a Add 1) AS a) FROM t"
4013 );
4014 assert_eq!(
4015 round("SELECT t.* REPLACE (make_date(a) AS a, b * 2 AS b) FROM t"),
4016 "SELECT t.* REPLACE (make_date(a) AS a, (b Multiply 2) AS b) FROM t"
4017 );
4018 }
4019
4020 #[test]
4021 fn one_column_cannot_be_replaced_twice() {
4022 let error = parse_ast("SELECT * REPLACE (a + 1 AS a, a + 2 AS A) FROM t").unwrap_err();
4025 assert_eq!(error.to_string(), "Parser Error: Duplicate entry \"A\" in REPLACE list");
4026 }
4027
4028 #[test]
4029 fn a_table_function_argument_can_have_a_name_written_in_front_of_it() {
4030 for spelling in
4033 ["binary_as_string := True", "binary_as_string => True", "binary_as_string = True"]
4034 {
4035 assert_eq!(
4036 round(&format!("SELECT * FROM read_parquet('f.parquet', {spelling})")),
4037 "SELECT * FROM read_parquet('f.parquet', binary_as_string := TRUE)",
4038 "{spelling}"
4039 );
4040 }
4041 }
4042
4043 #[test]
4044 fn an_equality_that_is_not_a_bare_name_stays_an_argument() {
4045 assert_eq!(round("SELECT * FROM f(t.a = 1)"), "SELECT * FROM f((t.a Eq 1))");
4048 assert_eq!(round("SELECT * FROM f(1 = 1)"), "SELECT * FROM f((1 Eq 1))");
4049 }
4050
4051 #[test]
4052 fn a_create_table_keeps_its_types_as_text() {
4053 assert_eq!(
4054 round_statement("CREATE TABLE t (a INTEGER, b VARCHAR NOT NULL)"),
4055 "CREATE TABLE t (a INTEGER, b VARCHAR NOT NULL)"
4056 );
4057 assert_eq!(
4061 round_statement("CREATE TABLE t (a DECIMAL(18, 3), b STRUCT(x INT))"),
4062 "CREATE TABLE t (a DECIMAL(18, 3), b STRUCT(x INT))"
4063 );
4064 }
4065
4066 #[test]
4067 fn the_modifiers_on_a_create_table_survive() {
4068 assert_eq!(
4069 round_statement("CREATE OR REPLACE TEMPORARY TABLE s.t (a INT)"),
4070 "CREATE OR REPLACE TEMPORARY TABLE s.t (a INT)"
4071 );
4072 assert_eq!(
4073 round_statement("CREATE TEMPORARY TABLE IF NOT EXISTS s.t (a INT)"),
4074 "CREATE TEMPORARY TABLE IF NOT EXISTS s.t (a INT)"
4075 );
4076 }
4077
4078 #[test]
4079 fn or_replace_and_if_not_exists_in_one_statement_is_refused_here_and_not_later() {
4080 for sql in [
4084 "CREATE OR REPLACE TABLE IF NOT EXISTS t (a INT)",
4085 "CREATE OR REPLACE VIEW IF NOT EXISTS v AS SELECT 1",
4086 ] {
4087 let error = parse_ast(sql).unwrap_err().to_string();
4088 assert_eq!(
4089 error,
4090 "Parser Error: Cannot specify both OR REPLACE and IF NOT EXISTS within single \
4091 create statement"
4092 );
4093 }
4094 }
4095
4096 #[test]
4097 fn a_create_table_as_carries_the_query_and_not_the_types() {
4098 assert_eq!(
4099 round_statement("CREATE TABLE t AS SELECT a FROM u"),
4100 "CREATE TABLE t AS SELECT a FROM u"
4101 );
4102 assert_eq!(
4105 round_statement("CREATE TABLE t (x, y) AS SELECT a, b FROM u"),
4106 "CREATE TABLE t (x, y) AS SELECT a, b FROM u"
4107 );
4108 }
4109
4110 #[test]
4111 fn a_create_view_carries_its_body_twice_over() {
4112 assert_eq!(
4113 round_statement("CREATE VIEW v AS SELECT a FROM u"),
4114 "CREATE VIEW v AS SELECT a FROM u"
4115 );
4116 assert_eq!(
4117 round_statement("CREATE OR REPLACE VIEW main.v (x, y) AS SELECT a, b FROM u"),
4118 "CREATE OR REPLACE VIEW main.v (x, y) AS SELECT a, b FROM u"
4119 );
4120 let ast = parse_ast("CREATE VIEW v (x) AS SELECT a FROM u WHERE a > 1").expect("parses");
4123 let Statement::CreateView(index) = ast.statements[0] else {
4124 panic!("not a create view");
4125 };
4126 assert_eq!(ast.string(ast.create_view(index).sql), "SELECT a FROM u WHERE a > 1");
4127 }
4128
4129 #[test]
4130 fn a_drop_view_is_not_a_drop_table() {
4131 assert_eq!(round_statement("DROP VIEW IF EXISTS a, b"), "DROP VIEW IF EXISTS a, b");
4132 assert_eq!(round_statement("DROP TABLE a"), "DROP TABLE a");
4133 }
4134
4135 #[test]
4136 fn a_drop_table_is_a_list_of_qualified_names() {
4137 assert_eq!(round_statement("DROP TABLE t"), "DROP TABLE t");
4138 assert_eq!(round_statement("DROP TABLE IF EXISTS a, b.c"), "DROP TABLE IF EXISTS a, b.c");
4139 }
4140
4141 #[test]
4142 fn dropping_something_that_is_neither_a_table_nor_a_view_is_refused() {
4143 let error = parse_ast("DROP MATERIALIZED VIEW v").unwrap_err().to_string();
4147 assert!(error.starts_with("Not implemented Error"), "{error}");
4148 }
4149
4150 #[test]
4151 fn both_spellings_of_insert_arrive_at_a_query() {
4152 assert_eq!(
4153 round_statement("INSERT INTO t VALUES (1, 'a'), (2, 'b')"),
4154 "INSERT INTO t VALUES (1, 'a'), (2, 'b')"
4155 );
4156 assert_eq!(
4157 round_statement("INSERT INTO t (a, b) SELECT x, y FROM u"),
4158 "INSERT INTO t (a, b) SELECT x, y FROM u"
4159 );
4160 }
4161
4162 #[test]
4163 fn an_insert_clause_that_changes_the_answer_is_refused() {
4164 for query in [
4165 "INSERT INTO t VALUES (1) RETURNING *",
4166 "INSERT OR REPLACE INTO t VALUES (1)",
4167 "INSERT INTO t BY NAME SELECT 1 AS a",
4168 "INSERT INTO t VALUES (1) ON CONFLICT DO NOTHING",
4169 "INSERT INTO t DEFAULT VALUES",
4170 ] {
4171 let error = parse_ast(query).unwrap_err().to_string();
4172 assert!(error.starts_with("Not implemented Error"), "{query} gave {error}");
4173 }
4174 }
4175
4176 #[test]
4177 fn a_column_constraint_that_is_not_not_null_is_refused() {
4178 for query in [
4182 "CREATE TABLE t (a INT PRIMARY KEY)",
4183 "CREATE TABLE t (a INT UNIQUE)",
4184 "CREATE TABLE t (a INT CHECK (a > 0))",
4185 "CREATE TABLE t (a INT DEFAULT 1)",
4186 "CREATE TABLE t (a INT REFERENCES u (b))",
4187 "CREATE TABLE t (a INT, PRIMARY KEY (a))",
4188 ] {
4189 let error = parse_ast(query).unwrap_err().to_string();
4190 assert!(error.starts_with("Not implemented Error"), "{query} gave {error}");
4191 }
4192 }
4193
4194 #[test]
4195 fn values_is_a_query_on_its_own_and_in_a_from() {
4196 assert_eq!(round("VALUES (1), (2)"), "VALUES (1), (2)");
4197 assert_eq!(
4201 round("SELECT * FROM (VALUES (1, 2), (3, 4)) t(a, b)"),
4202 "SELECT * FROM (VALUES (1, 2), (3, 4)) AS t"
4203 );
4204 assert_eq!(
4205 round("SELECT * FROM VALUES (1, 2), (3, 4) AS t(a, b)"),
4206 "SELECT * FROM VALUES (1, 2), (3, 4) AS t"
4207 );
4208 assert_eq!(round("VALUES (1), (2, 3)"), "VALUES (1), (2, 3)");
4211 }
4212
4213 #[test]
4214 fn non_recursive_ctes_inline_and_semantic_variants_are_explicit() {
4215 assert_eq!(
4216 round("WITH t AS (SELECT 1 AS x) SELECT x FROM t"),
4217 "SELECT x FROM (SELECT 1 AS x) AS t"
4218 );
4219 assert_eq!(
4220 round("WITH t(x) AS NOT MATERIALIZED (SELECT 1) SELECT x FROM t"),
4221 "SELECT x FROM (SELECT 1) AS t"
4222 );
4223 let query = "WITH RECURSIVE t(x) AS (SELECT 1) SELECT x FROM t";
4224 let error = parse_ast(query).expect_err("the unsupported CTE shape is refused");
4225 assert!(error.to_string().starts_with("Not implemented Error"), "{query}: {error}");
4226 }
4227
4228 #[test]
4235 fn a_plain_cte_read_twice_is_held_and_one_read_once_is_inlined() {
4236 assert_eq!(
4237 round("WITH t AS (SELECT 1 AS x) SELECT * FROM t a, t b"),
4238 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT * FROM t AS a, t AS b"
4239 );
4240 assert_eq!(
4241 round("WITH t AS (SELECT 1 AS x) SELECT x FROM t"),
4242 "SELECT x FROM (SELECT 1 AS x) AS t"
4243 );
4244 assert_eq!(
4245 round("WITH t AS NOT MATERIALIZED (SELECT 1 AS x) SELECT * FROM t a, t b"),
4246 "SELECT * FROM (SELECT 1 AS x) AS a, (SELECT 1 AS x) AS b"
4247 );
4248 assert_eq!(
4250 round("WITH t AS (SELECT 1 AS x), u AS (SELECT x FROM t) SELECT x FROM t"),
4251 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT x FROM t"
4252 );
4253 assert_eq!(
4255 round("WITH t AS (SELECT 1 AS x) SELECT * FROM t a, main.t b"),
4256 "SELECT * FROM (SELECT 1 AS x) AS a, main.t AS b"
4257 );
4258 }
4259
4260 #[test]
4267 fn a_cte_written_inside_a_subquery_is_inlined_however_often_it_is_read() {
4268 assert_eq!(
4269 round("SELECT * FROM (WITH t AS (SELECT 1 AS x) SELECT * FROM t a, t b) c"),
4270 "SELECT * FROM (SELECT * FROM (SELECT 1 AS x) AS a, (SELECT 1 AS x) AS b) AS c"
4271 );
4272 assert_eq!(
4273 round("WITH o AS (WITH i AS (SELECT 1 AS x) SELECT * FROM i a, i b) SELECT * FROM o"),
4274 "SELECT * FROM (SELECT * FROM (SELECT 1 AS x) AS a, (SELECT 1 AS x) AS b) AS o"
4275 );
4276 }
4277
4278 #[test]
4284 fn a_plain_cte_whose_name_is_written_again_further_in_is_inlined() {
4285 assert_eq!(
4286 round(
4287 "WITH t AS (SELECT 1 AS x) SELECT * FROM t a, \
4288 (WITH t AS (SELECT 2 AS x) SELECT x FROM t) b"
4289 ),
4290 "SELECT * FROM (SELECT 1 AS x) AS a, (SELECT x FROM (SELECT 2 AS x) AS t) AS b"
4291 );
4292 }
4293
4294 #[test]
4296 fn a_materialized_cte_stays_a_definition_and_its_references_stay_references() {
4297 assert_eq!(
4298 round("WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT x FROM t"),
4299 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT x FROM t"
4300 );
4301 assert_eq!(
4302 round("WITH t(y) AS MATERIALIZED (SELECT 1) SELECT y FROM t"),
4303 "WITH t(y) AS MATERIALIZED (SELECT 1) SELECT y FROM t"
4304 );
4305 assert_eq!(
4308 round("WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT * FROM t a, t b"),
4309 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT * FROM t AS a, t AS b"
4310 );
4311 assert_eq!(
4313 round(
4314 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT (WITH t AS (SELECT 2 AS x) \
4315 SELECT x FROM t) AS inner"
4316 ),
4317 "WITH t AS MATERIALIZED (SELECT 1 AS x) SELECT (SELECT x FROM (SELECT 2 AS x) AS t) \
4318 AS inner"
4319 );
4320 assert_eq!(
4323 round(
4324 "WITH a AS MATERIALIZED (SELECT 1 AS x), b AS MATERIALIZED (SELECT x + 1 AS y \
4325 FROM a) SELECT y FROM b"
4326 ),
4327 "WITH a AS MATERIALIZED (SELECT 1 AS x) WITH b AS MATERIALIZED (SELECT (x Add 1) \
4328 AS y FROM a) SELECT y FROM b"
4329 );
4330 }
4331
4332 #[test]
4340 fn describe_rewrites_a_name_into_a_star_over_it() {
4341 assert_eq!(round("DESCRIBE SELECT 1 AS a"), "DESCRIBE SELECT 1 AS a");
4342 assert_eq!(round("DESCRIBE t"), "DESCRIBE SELECT * FROM t");
4343 assert_eq!(round("DESC t"), "DESCRIBE SELECT * FROM t");
4344 assert_eq!(round("DESCRIBE 'x.parquet'"), "DESCRIBE SELECT * FROM x.parquet");
4345 assert_eq!(
4347 round("SELECT column_name FROM (DESCRIBE SELECT 1 AS a)"),
4348 "SELECT column_name FROM (DESCRIBE SELECT 1 AS a)"
4349 );
4350 assert_eq!(round("DESCRIBE DESCRIBE SELECT 1 AS a"), "DESCRIBE DESCRIBE SELECT 1 AS a");
4351 }
4352
4353 #[test]
4360 fn summarize_is_refused_even_though_it_parses_as_a_describe() {
4361 for query in ["SUMMARIZE t", "SUMMARIZE SELECT 1"] {
4362 let error = parse_ast(query).expect_err("summarize is not implemented");
4363 let message = error.to_string();
4364 assert!(message.starts_with("Not implemented Error"), "{query} failed with {message}");
4365 }
4366 }
4367
4368 #[test]
4369 fn every_statement_in_the_corpus_gets_a_defined_answer() {
4370 let mut done = 0;
4375 for query in CORPUS {
4376 match parse_ast(query) {
4377 Ok(ast) => {
4378 assert_eq!(ast.statements.len(), 1, "{query}");
4379 done += 1;
4380 }
4381 Err(error) => {
4382 let message = error.to_string();
4383 assert!(
4384 message.starts_with("Not implemented Error"),
4385 "{query} failed with {message}, which is not a not-implemented error"
4386 );
4387 }
4388 }
4389 }
4390 assert!(done >= 31, "only {done} of the corpus transforms, which is fewer than it was");
4393 }
4394
4395 #[test]
4396 fn the_ast_is_far_smaller_than_the_parse_tree() {
4397 let query = CORPUS[4];
4398 let tree = parse(query).unwrap();
4399 let ast = parse_ast(query).unwrap();
4400 assert!(
4403 ast.node_count() * 20 < tree.arena_len(),
4404 "{} ast nodes against {} parse nodes",
4405 ast.node_count(),
4406 tree.arena_len()
4407 );
4408 }
4409
4410 #[test]
4411 fn precedence_comes_out_of_the_chain_and_into_the_tree() {
4412 assert_eq!(round("SELECT 1 + 2 * 3"), "SELECT (1 Add (2 Multiply 3))");
4413 assert_eq!(round("SELECT (1 + 2) * 3"), "SELECT ((1 Add 2) Multiply 3)");
4414 assert_eq!(round("SELECT 1 + 2 + 3"), "SELECT ((1 Add 2) Add 3)");
4415 assert_eq!(round("SELECT 1 - 2 - 3"), "SELECT ((1 Subtract 2) Subtract 3)");
4416 assert_eq!(
4417 round("SELECT a OR b AND c"),
4418 "SELECT (a Or (b And c))",
4419 "and binds tighter than or"
4420 );
4421 }
4422
4423 #[test]
4424 fn a_double_negation_is_two_nodes_and_not_none() {
4425 assert_eq!(round("SELECT NOT NOT a"), "SELECT (Not (Not a))");
4429 }
4430
4431 #[test]
4432 fn a_parenthesised_single_expression_is_not_a_row() {
4433 assert_eq!(round("SELECT (a)"), "SELECT a");
4434 assert_eq!(round("SELECT (a, b)"), "SELECT ROW(a, b)");
4435 }
4436
4437 #[test]
4438 fn a_bracketed_list_is_a_list_of_however_many_items_were_written() {
4439 assert_eq!(round("SELECT [a]"), "SELECT [a]");
4442 assert_eq!(round("SELECT [1, 2, 3]"), "SELECT [1, 2, 3]");
4443 assert_eq!(round("SELECT []"), "SELECT []");
4444 assert_eq!(round("SELECT ['a.parquet', 'b.parquet']"), "SELECT ['a.parquet', 'b.parquet']");
4445 }
4446
4447 #[test]
4448 fn a_parameter_carries_its_identifier_however_it_was_written() {
4449 assert_eq!(round("SELECT $1"), "SELECT $1");
4450 assert_eq!(round("SELECT ?1"), "SELECT $1");
4451 assert_eq!(round("SELECT $name"), "SELECT $name");
4452 assert_eq!(round("SELECT ? + $2"), "SELECT ($1 Add $2)");
4455 assert_eq!(round("SELECT ?, ?, ?"), "SELECT $1, $2, $3");
4456 }
4457
4458 #[test]
4459 fn the_parameters_of_a_statement_are_listed_once_each_in_written_order() {
4460 let ast = parse_ast("SELECT $b, $a, $b WHERE $a").expect("parses");
4461 assert_eq!(ast.parameters(), vec!["b", "a"]);
4462 assert!(parse_ast("SELECT 1").expect("parses").parameters().is_empty());
4463 }
4464
4465 #[test]
4466 fn the_three_ways_to_write_an_alias_all_arrive() {
4467 assert_eq!(round("SELECT a AS b"), "SELECT a AS b");
4468 assert_eq!(round("SELECT a b"), "SELECT a AS b");
4469 assert_eq!(round("SELECT b: a"), "SELECT a AS b");
4470 assert_eq!(round("SELECT a"), "SELECT a", "and no alias when none was written");
4471 }
4472
4473 #[test]
4474 fn a_from_with_no_select_selects_everything() {
4475 assert_eq!(round("FROM t"), "SELECT * FROM t");
4478 assert_eq!(round("FROM t SELECT a"), "SELECT a FROM t");
4479 }
4480
4481 #[test]
4482 fn joins_nest_to_the_left() {
4483 assert_eq!(
4484 round("SELECT * FROM a JOIN b ON a.i = b.i LEFT JOIN c USING (k)"),
4485 "SELECT * FROM ((a Inner JOIN b ON (a.i Eq b.i)) Left JOIN c USING (k))"
4486 );
4487 assert_eq!(
4488 round("SELECT * FROM a NATURAL JOIN b"),
4489 "SELECT * FROM (a NATURAL Inner JOIN b)"
4490 );
4491 assert_eq!(round("SELECT * FROM a CROSS JOIN b"), "SELECT * FROM (a Cross JOIN b)");
4492 assert_eq!(
4493 round("SELECT * FROM a POSITIONAL JOIN b"),
4494 "SELECT * FROM (a Positional JOIN b)"
4495 );
4496 assert_eq!(round("SELECT * FROM a, b"), "SELECT * FROM a, b", "a comma is not a join node");
4497 }
4498
4499 #[test]
4500 fn a_qualified_name_keeps_its_parts_however_it_was_spelled() {
4501 assert_eq!(round("SELECT a"), "SELECT a");
4505 assert_eq!(round("SELECT t.a"), "SELECT t.a");
4506 assert_eq!(round("SELECT s.t.a"), "SELECT s.t.a");
4507 assert_eq!(round("SELECT c.s.t.a"), "SELECT c.s.t.a");
4508 assert_eq!(round("SELECT * FROM s.t"), "SELECT * FROM s.t");
4509 }
4510
4511 #[test]
4512 fn a_star_can_be_qualified() {
4513 assert_eq!(round("SELECT *"), "SELECT *");
4514 assert_eq!(round("SELECT t.*"), "SELECT t.*");
4515 assert_eq!(round("SELECT s.t.*"), "SELECT s.t.*");
4516 }
4517
4518 #[test]
4519 fn a_quoted_identifier_keeps_its_case_and_loses_its_quotes() {
4520 let ast = parse_ast("SELECT \"Mixed Case\", \"a\"\"b\"").unwrap();
4524 assert_eq!(ast.strings[0], "Mixed Case");
4525 assert_eq!(ast.strings[1], "a\"b");
4526 }
4527
4528 #[test]
4529 fn a_string_literal_is_decoded_and_adjacent_ones_are_joined() {
4530 assert_eq!(round("SELECT 'it''s'"), "SELECT 'it's'");
4531 assert_eq!(round("SELECT 'a'\n'b'"), "SELECT 'ab'", "the standard's adjacency rule");
4532 }
4533
4534 #[test]
4536 fn a_dollar_quoted_string_loses_its_dollars_and_its_tag() {
4537 assert_eq!(round("SELECT $$dollar quoted$$"), "SELECT 'dollar quoted'");
4538 assert_eq!(round("SELECT $tag$body$tag$"), "SELECT 'body'");
4539 assert_eq!(round("SELECT $$$$"), "SELECT ''", "an empty tag and an empty body");
4540 assert_eq!(round("SELECT $tag$it''s $other$ fine$tag$"), "SELECT 'it''s $other$ fine'");
4543 assert_eq!(round("SELECT $$open"), "SELECT '$$open'");
4545 }
4546
4547 #[test]
4553 fn an_escape_string_resolves_its_backslashes() {
4554 assert_eq!(round("SELECT E'a\\nb'"), "SELECT 'a\nb'");
4555 assert_eq!(round("SELECT e'a\\tb'"), "SELECT 'a\tb'", "the prefix is a letter, not a name");
4556 assert_eq!(round("SELECT E'a\\rb'"), "SELECT 'a\rb'");
4557 assert_eq!(round("SELECT E'a\\bb'"), "SELECT 'a\u{8}b'");
4558 assert_eq!(round("SELECT E'a\\fb'"), "SELECT 'a\u{c}b'");
4559 assert_eq!(round("SELECT E'a\\\\b'"), "SELECT 'a\\b'");
4560 assert_eq!(round("SELECT E'a\\'b'"), "SELECT 'a'b'", "a quote, the same as ''");
4561 assert_eq!(round("SELECT E'a''b'"), "SELECT 'a'b'", "and '' still means a quote here");
4562 assert_eq!(round("SELECT E'a\\vb'"), "SELECT 'avb'");
4565 assert_eq!(round("SELECT E'a\\qb'"), "SELECT 'aqb'");
4566 }
4567
4568 #[test]
4570 fn a_numeric_escape_writes_the_byte_or_the_character_it_names() {
4571 assert_eq!(round("SELECT E'\\x41'"), "SELECT 'A'");
4572 assert_eq!(round("SELECT E'\\x4142'"), "SELECT 'A42'", "two digits at the most");
4573 assert_eq!(
4574 round("SELECT E'a\\x'"),
4575 "SELECT 'ax'",
4576 "and one at the least, or it is a letter"
4577 );
4578 assert_eq!(round("SELECT E'\\101'"), "SELECT 'A'");
4579 assert_eq!(round("SELECT E'\\1011'"), "SELECT 'A1'", "three digits at the most");
4580 assert_eq!(round("SELECT E'\\8'"), "SELECT '8'", "8 is not an octal digit");
4581 assert_eq!(round("SELECT E'\\xc3\\xa9'"), "SELECT 'é'");
4583 assert_eq!(round("SELECT E'\\u00e9'"), "SELECT 'é'");
4584 assert_eq!(round("SELECT E'a\\u41'"), "SELECT 'au41'", "four digits or it is a letter");
4585 assert_eq!(round("SELECT E'a\\uZZZZ'"), "SELECT 'auZZZZ'");
4586 assert_eq!(
4587 round("SELECT E'\\ud83d\\ude00'"),
4588 "SELECT 'ud83dude00'",
4589 "surrogates are not it"
4590 );
4591 }
4592
4593 #[test]
4595 fn an_escape_string_that_is_not_a_string_raises() {
4596 let error = parse_ast("SELECT E'a\\x00'").unwrap_err().to_string();
4597 assert_eq!(error, "Parser Error: Null character not permitted in escape string literal");
4598 let error = parse_ast("SELECT E'a\\377'").unwrap_err().to_string();
4599 assert_eq!(
4600 error,
4601 "Parser Error: Invalid UTF-8 in escape string literal at byte offset 1: byte mismatch",
4602 "the offset is where the bytes stop being a string, not where the escape was written"
4603 );
4604 }
4605
4606 #[test]
4608 fn the_other_string_prefixes_are_what_upstream_makes_of_them() {
4609 assert_eq!(round("SELECT N'abc'"), "SELECT CAST('abc' AS VARCHAR)");
4611 assert_eq!(round("SELECT n'abc'"), "SELECT CAST('abc' AS VARCHAR)");
4612 assert_eq!(round("SELECT B'101'"), "SELECT 'b101'");
4614 assert_eq!(round("SELECT b'abc'"), "SELECT 'babc'");
4615 assert_eq!(round("SELECT B''"), "SELECT 'b'", "an empty one is the letter on its own");
4616 }
4617
4618 #[test]
4624 fn a_hex_string_is_a_blob_and_not_a_string() {
4625 assert_eq!(round("SELECT x'4142'"), "SELECT 'AB'::BLOB");
4626 assert_eq!(round("SELECT X'4142'"), "SELECT 'AB'::BLOB");
4627 assert_eq!(round("SELECT x'ff41'"), "SELECT '\\xFFA'::BLOB", "a byte that does not print");
4628 assert_eq!(round("SELECT x''"), "SELECT ''::BLOB", "an empty one is an empty blob");
4629 assert_eq!(round("SELECT x'2741'"), "SELECT '\\x27A'::BLOB");
4632 assert_eq!(round("SELECT x'5c7834314141'"), "SELECT '\\x5Cx41AA'::BLOB");
4633 let error = parse_ast("SELECT x'4'").unwrap_err().to_string();
4636 assert_eq!(
4637 error,
4638 "Parser Error: Hex string literal must have an even number of hex digits"
4639 );
4640 assert_eq!(round("SELECT x'41zz'"), "SELECT '\\x41\\xzz'::BLOB");
4641 }
4642
4643 #[test]
4644 fn the_null_and_boolean_tests_are_postfix_unary_operators() {
4645 assert_eq!(round("SELECT x IS NULL"), "SELECT (IsNull x)");
4646 assert_eq!(round("SELECT x IS NOT NULL"), "SELECT (IsNotNull x)");
4647 assert_eq!(round("SELECT x ISNULL"), "SELECT (IsNull x)");
4648 assert_eq!(round("SELECT x NOTNULL"), "SELECT (IsNotNull x)");
4649 assert_eq!(round("SELECT x IS TRUE"), "SELECT (IsTrue x)");
4650 assert_eq!(round("SELECT x IS NOT FALSE"), "SELECT (IsNotFalse x)");
4651 assert_eq!(round("SELECT x IS DISTINCT FROM y"), "SELECT (x IsDistinctFrom y)");
4652 assert_eq!(round("SELECT x IS NOT DISTINCT FROM y"), "SELECT (x IsNotDistinctFrom y)");
4653 }
4654
4655 #[test]
4656 fn the_like_family_folds_its_negation_into_the_operator() {
4657 assert_eq!(round("SELECT x LIKE 'a'"), "SELECT (x Like 'a')");
4658 assert_eq!(round("SELECT x NOT LIKE 'a'"), "SELECT (x NotLike 'a')");
4659 assert_eq!(round("SELECT x ILIKE 'a'"), "SELECT (x ILike 'a')");
4660 assert_eq!(round("SELECT x ~~ 'a'"), "SELECT (x Like 'a')", "the operator spelling");
4661 assert_eq!(round("SELECT x !~~ 'a'"), "SELECT (x NotLike 'a')");
4662 assert_eq!(round("SELECT x SIMILAR TO 'a'"), "SELECT (x SimilarTo 'a')");
4663 assert_eq!(round("SELECT x NOT GLOB 'a'"), "SELECT (Not (x Glob 'a'))");
4665 }
4666
4667 #[test]
4668 fn between_and_in_carry_their_negation_as_a_flag() {
4669 assert_eq!(round("SELECT x BETWEEN 1 AND 2"), "SELECT (x BETWEEN 1 AND 2)");
4670 assert_eq!(round("SELECT x NOT BETWEEN 1 AND 2"), "SELECT (NOT x BETWEEN 1 AND 2)");
4671 assert_eq!(round("SELECT x IN (1, 2)"), "SELECT (x IN [1, 2])");
4672 assert_eq!(round("SELECT x NOT IN (1, 2)"), "SELECT (NOT x IN [1, 2])");
4673 }
4674
4675 #[test]
4676 fn both_spellings_of_a_cast_are_the_same_node() {
4677 assert_eq!(round("SELECT CAST(x AS BIGINT)"), "SELECT CAST(x AS BIGINT)");
4678 assert_eq!(round("SELECT x::BIGINT"), "SELECT CAST(x AS BIGINT)");
4679 assert_eq!(round("SELECT TRY_CAST(x AS BIGINT)"), "SELECT TRY_CAST(x AS BIGINT)");
4680 assert_eq!(
4681 round("SELECT x::DECIMAL(18, 3)"),
4682 "SELECT CAST(x AS DECIMAL(18, 3))",
4683 "the type is kept as text because parsing it is the type system's job"
4684 );
4685 }
4686
4687 #[test]
4688 fn a_typed_literal_is_a_third_spelling_of_the_same_cast() {
4689 assert_eq!(round("SELECT DATE '1995-09-01'"), "SELECT CAST('1995-09-01' AS DATE)");
4690 assert_eq!(
4691 round("SELECT date '1995-09-01'"),
4692 "SELECT CAST('1995-09-01' AS date)",
4693 "the type is kept as written, the same as it is in the other two spellings"
4694 );
4695 assert_eq!(
4696 round("SELECT TIMESTAMP '2020-01-01 03:04:05'"),
4697 "SELECT CAST('2020-01-01 03:04:05' AS TIMESTAMP)"
4698 );
4699 assert_eq!(
4700 round("SELECT DECIMAL(5, 2) '1.5'"),
4701 "SELECT CAST('1.5' AS DECIMAL(5, 2))",
4702 "any type the cast takes is a typed literal, parameters and all"
4703 );
4704 assert_eq!(
4705 round("SELECT VARCHAR 'hi' FROM t"),
4706 "SELECT CAST('hi' AS VARCHAR) FROM t",
4707 "including the ones where the cast has nothing to do"
4708 );
4709 }
4710
4711 #[test]
4712 fn a_case_keeps_its_arms_in_order() {
4713 assert_eq!(
4714 round("SELECT CASE WHEN a THEN 1 WHEN b THEN 2 ELSE 3 END"),
4715 "SELECT CASE - WHEN a THEN 1 WHEN b THEN 2 ELSE 3 END"
4716 );
4717 assert_eq!(
4718 round("SELECT CASE x WHEN 1 THEN 'a' END"),
4719 "SELECT CASE x WHEN 1 THEN 'a' ELSE - END",
4720 "a simple case keeps the operand and a missing else is not an implicit null yet"
4721 );
4722 }
4723
4724 #[test]
4725 fn a_field_access_and_a_method_call_are_ordinary_function_calls() {
4726 assert_eq!(round("SELECT (f(x)).y"), "SELECT struct_extract(f(x), 'y')");
4729 assert_eq!(round("SELECT a[1]"), "SELECT array_extract(a, 1)");
4730 }
4731
4732 #[test]
4734 fn a_range_gets_the_bounds_the_query_left_out() {
4735 assert_eq!(round("SELECT a[1:2]"), "SELECT array_slice(a, 1, 2)");
4736 assert_eq!(round("SELECT a[:2]"), "SELECT array_slice(a, 1, 2)");
4737 assert_eq!(round("SELECT a[2:]"), "SELECT array_slice(a, 2, -1)");
4738 assert_eq!(round("SELECT a[:]"), "SELECT array_slice(a, 1, -1)");
4739 assert_eq!(round("SELECT a[1:-]"), "SELECT array_slice(a, 1, -1)");
4741 assert_eq!(round("SELECT a[1:2:3]"), "SELECT array_slice(a, 1, 2, 3)");
4742 assert_eq!(round("SELECT a[1:2:]"), "SELECT array_slice(a, 1, 2, [])");
4745 }
4746
4747 #[test]
4749 fn an_empty_subscript_is_not_a_subscript() {
4750 let error = parse_ast("SELECT a[]").expect_err("an empty subscript");
4751 assert_eq!(error.message(), "Empty subscript '[]' is not allowed");
4752 }
4753
4754 #[test]
4757 fn a_keyword_is_not_stepped_through_on_the_way_to_its_one_argument() {
4758 for (sql, rule) in [
4759 ("SELECT row(1)", "RowExpression"),
4760 ("SELECT try(1)", "TryExpression"),
4761 ("SELECT unpack([1])", "UnpackExpression"),
4762 ("SELECT columns('a')", "ColumnsExpression"),
4763 ] {
4764 let error = parse_ast(sql).expect_err(sql);
4765 assert!(error.message().ends_with(rule), "{sql}: {error}");
4766 }
4767 assert_eq!(round("SELECT (1 + 2) * 3"), "SELECT ((1 Add 2) Multiply 3)");
4770 assert_eq!(round("SELECT -(7)"), "SELECT (Negate 7)");
4771 }
4772
4773 #[test]
4775 fn the_null_checks_are_calls_by_the_names_duckdb_prints() {
4776 assert_eq!(round("SELECT COALESCE(a, b, 1)"), "SELECT coalesce(a, b, 1)");
4779 assert_eq!(round("SELECT coalesce(a)"), "SELECT coalesce(a)");
4780 assert_eq!(round("SELECT NULLIF(a, 1)"), "SELECT nullif(a, 1)");
4781 assert_eq!(round("SELECT ifnull(a, 1)"), "SELECT coalesce(a, 1)");
4783 assert_eq!(round("SELECT main.ifnull(a, 1)"), "SELECT coalesce(a, 1)");
4784 let error = parse_ast("SELECT ifnull(a)").expect_err("one argument to ifnull");
4785 assert_eq!(error.message(), "Wrong number of arguments to IFNULL.");
4786 let error = parse_ast("SELECT ifnull(a, b, c)").expect_err("three arguments to ifnull");
4787 assert_eq!(error.message(), "Wrong number of arguments to IFNULL.");
4788 }
4789
4790 #[test]
4793 fn the_string_keywords_are_the_calls_duckdb_prints() {
4794 assert_eq!(round("SELECT substring(s, 2, 3)"), "SELECT substring(s, 2, 3)");
4795 assert_eq!(round("SELECT SUBSTRING(s FROM 2 FOR 3)"), "SELECT substring(s, 2, 3)");
4796 assert_eq!(round("SELECT substring(s FROM 2)"), "SELECT substring(s, 2)");
4797 assert_eq!(round("SELECT substring(s FOR 3)"), "SELECT substring(s, 1, 3)");
4799 assert_eq!(round("SELECT position('c' IN s)"), "SELECT position(s, 'c')");
4801 assert_eq!(round("SELECT trim(s)"), "SELECT trim(s)");
4802 assert_eq!(round("SELECT trim(BOTH 'x' FROM s)"), "SELECT trim(s, 'x')");
4803 assert_eq!(round("SELECT trim(BOTH FROM s)"), "SELECT trim(s)");
4804 assert_eq!(round("SELECT trim(s, 'xy')"), "SELECT trim(s, 'xy')");
4805 assert_eq!(round("SELECT trim(LEADING FROM s)"), "SELECT ltrim(s)");
4807 assert_eq!(round("SELECT trim(TRAILING FROM s)"), "SELECT rtrim(s)");
4808 assert_eq!(round("SELECT trim(LEADING 'x' FROM s)"), "SELECT ltrim(s, 'x')");
4809 assert_eq!(round("SELECT trim(TRAILING 'x' FROM s)"), "SELECT rtrim(s, 'x')");
4810 assert_eq!(
4811 round("SELECT overlay(s PLACING 'X' FROM 2 FOR 1)"),
4812 "SELECT overlay(s, 'X', 2, 1)"
4813 );
4814 assert_eq!(round("SELECT overlay(s PLACING 'X' FROM 2)"), "SELECT overlay(s, 'X', 2)");
4815 assert_eq!(round("SELECT overlay(s, 'X', 2, 1)"), "SELECT overlay(s, 'X', 2, 1)");
4816 }
4817
4818 #[test]
4819 fn an_aggregate_keeps_its_distinct() {
4820 assert_eq!(round("SELECT count(*)"), "SELECT count(*)");
4821 assert_eq!(round("SELECT count(DISTINCT x)"), "SELECT count(DISTINCT x)");
4822 assert_eq!(round("SELECT count(ALL x)"), "SELECT count(x)");
4823 assert_eq!(round("SELECT main.count(x)"), "SELECT main.count(x)");
4824 }
4825
4826 #[test]
4827 fn a_call_keeps_the_filter_it_was_written_with_and_the_word_where_is_optional() {
4828 assert_eq!(round("SELECT sum(x) FILTER (WHERE y > 1)"), "SELECT sum(x) FILTER [(y Gt 1)]");
4832 assert_eq!(round("SELECT sum(x) FILTER (y > 1)"), "SELECT sum(x) FILTER [(y Gt 1)]");
4833 assert_eq!(round("SELECT count(*) FILTER (WHERE b)"), "SELECT count(*) FILTER [b]");
4834 assert_eq!(
4835 round("SELECT sum(DISTINCT x) FILTER (WHERE b)"),
4836 "SELECT sum(DISTINCT x) FILTER [b]"
4837 );
4838 assert_eq!(round("SELECT abs(x) FILTER (WHERE b)"), "SELECT abs(x) FILTER [b]");
4839 }
4840
4841 #[test]
4843 fn a_window_call_carries_its_filter_in_front_of_its_over() {
4844 assert_eq!(
4845 round("SELECT sum(x) FILTER (WHERE b) OVER ()"),
4846 "SELECT sum(x) FILTER [b] OVER [] [] [Range UnboundedPreceding CurrentRow NoOthers]"
4847 );
4848 }
4849
4850 #[test]
4851 fn the_modifiers_hang_off_the_query_and_not_off_the_select() {
4852 assert_eq!(
4856 round("SELECT 1 UNION ALL SELECT 2 ORDER BY 1"),
4857 "(SELECT 1 Union All SELECT 2) ORDER BY 1 Unstated Unstated"
4858 );
4859 assert_eq!(
4860 round("SELECT a FROM t UNION SELECT b FROM u EXCEPT SELECT c FROM v"),
4861 "((SELECT a FROM t Union Unstated SELECT b FROM u) Except Unstated SELECT c FROM v)",
4862 "set operators are left associative"
4863 );
4864 assert_eq!(
4865 round("SELECT 1 UNION SELECT 2 INTERSECT SELECT 3"),
4866 "(SELECT 1 Union Unstated (SELECT 2 Intersect Unstated SELECT 3))",
4867 "and intersect binds tighter than the other two"
4868 );
4869 }
4870
4871 #[test]
4872 fn the_sort_and_limit_clauses_keep_what_was_written() {
4873 assert_eq!(
4874 round("SELECT a FROM t ORDER BY a"),
4875 "SELECT a FROM t ORDER BY a Unstated Unstated"
4876 );
4877 assert_eq!(
4878 round("SELECT a FROM t ORDER BY a DESC NULLS LAST"),
4879 "SELECT a FROM t ORDER BY a Descending Last"
4880 );
4881 assert_eq!(round("SELECT a FROM t ORDER BY ALL"), "SELECT a FROM t ORDER BY ALL");
4882 assert_eq!(round("SELECT a FROM t GROUP BY ALL"), "SELECT a FROM t GROUP BY ALL");
4883 assert_eq!(round("SELECT a FROM t LIMIT 10 OFFSET 5"), "SELECT a FROM t LIMIT 10 OFFSET 5");
4884 assert_eq!(round("SELECT a FROM t OFFSET 5 LIMIT 10"), "SELECT a FROM t LIMIT 10 OFFSET 5");
4885 assert_eq!(round("SELECT a FROM t LIMIT 10%"), "SELECT a FROM t LIMIT 10%");
4886 assert_eq!(round("SELECT a FROM t LIMIT ALL"), "SELECT a FROM t", "which is no limit");
4887 }
4888
4889 #[test]
4890 fn a_subquery_appears_in_both_places_it_can() {
4891 assert_eq!(
4892 round("SELECT * FROM (SELECT x FROM t) AS s"),
4893 "SELECT * FROM (SELECT x FROM t) AS s"
4894 );
4895 assert_eq!(round("SELECT (SELECT 1)"), "SELECT (SELECT 1)");
4896 }
4897
4898 #[test]
4899 fn distinct_on_keeps_its_expressions() {
4900 assert_eq!(round("SELECT DISTINCT a"), "SELECT DISTINCT a");
4901 assert_eq!(round("SELECT ALL a"), "SELECT a", "which is the default written out");
4902 assert_eq!(round("SELECT DISTINCT ON (a, b) a"), "SELECT DISTINCT ON (a, b) a");
4903 }
4904
4905 #[test]
4906 fn an_operator_the_dialect_does_not_name_is_kept_by_name() {
4907 assert_eq!(round("SELECT a <=> b"), "SELECT (a <=> b)");
4913 assert!(parse_ast("SELECT a foo b").is_err(), "a bare word is not an operator");
4914 }
4915
4916 #[test]
4917 fn a_script_is_a_list_of_statements() {
4918 let ast = parse_ast("SELECT 1; SELECT 2;").unwrap();
4919 assert_eq!(ast.statements.len(), 2);
4920 let Statement::Query(second) = ast.statements[1] else {
4924 panic!("the second statement is a query");
4925 };
4926 assert_eq!(show_query(&ast, second), "SELECT 2");
4927 }
4928
4929 #[test]
4930 fn an_unsupported_construct_names_itself_and_what_was_written() {
4931 let error = parse_ast("ALTER TABLE t ADD COLUMN a INTEGER").unwrap_err().to_string();
4932 assert!(error.starts_with("Not implemented Error"), "{error}");
4933 assert!(error.contains("ALTER TABLE t ADD COLUMN a INTEGER"), "{error}");
4934 assert!(error.contains("AlterStatement"), "{error}");
4935 }
4936
4937 #[test]
4938 fn a_long_construct_is_cut_short_in_the_message() {
4939 let query = format!("ALTER TABLE t ADD COLUMN {} INTEGER", "a".repeat(80));
4940 let error = parse_ast(&query).unwrap_err().to_string();
4941 assert!(error.contains("..."), "{error}");
4942 assert!(error.len() < 200, "{error}");
4943 }
4944
4945 #[test]
4946 fn the_transformer_never_panics_on_anything_the_matcher_accepts() {
4947 for query in [
4951 "SELECT",
4952 "FROM t SELECT",
4953 "SELECT * FROM t WHERE",
4954 "SELECT ()",
4955 "SELECT a FROM t GROUP BY ()",
4956 ] {
4957 let answer = parse_ast(query);
4958 if let Err(error) = answer {
4959 let message = error.to_string();
4960 assert!(
4961 message.starts_with("Not implemented Error")
4962 || message.starts_with("Parser Error"),
4963 "{query} failed with {message}"
4964 );
4965 }
4966 }
4967 }
4968
4969 #[test]
4970 fn a_file_name_in_a_from_clause_is_a_table_name_with_the_quotes_off() {
4971 assert_eq!(round("SELECT * FROM 'hits.parquet'"), "SELECT * FROM hits.parquet");
4975 assert_eq!(round("SELECT * FROM \"hits.parquet\""), "SELECT * FROM hits.parquet");
4976 assert_eq!(round("SELECT * FROM 'hits.parquet' AS h"), "SELECT * FROM hits.parquet AS h");
4977 assert_eq!(
4978 round_with_case("SELECT Mixed FROM 'NoSuch/Mixed/File.csv'", IdentifierCase::Lower),
4979 "SELECT mixed FROM NoSuch/Mixed/File.csv"
4980 );
4981 assert_eq!(
4982 round_with_case("SELECT Mixed FROM \"QuotedTable\"", IdentifierCase::Upper),
4983 "SELECT MIXED FROM QuotedTable"
4984 );
4985 }
4986
4987 #[test]
4988 fn a_function_call_in_a_from_clause_is_a_source_and_not_an_expression() {
4989 assert_eq!(round("SELECT * FROM range(3)"), "SELECT * FROM range(3)");
4990 assert_eq!(round("SELECT * FROM range(1, 10, 2)"), "SELECT * FROM range(1, 10, 2)");
4991 assert_eq!(round("SELECT * FROM main.range(3)"), "SELECT * FROM main.range(3)");
4992 assert_eq!(round("SELECT * FROM range(3) AS t"), "SELECT * FROM range(3) AS t");
4993 assert_eq!(round("SELECT * FROM some_function()"), "SELECT * FROM some_function()");
4996 assert_eq!(round("SELECT * FROM LATERAL range(3)"), "SELECT * FROM range(3)");
4999 assert_eq!(
5000 round("SELECT * FROM t, LATERAL (SELECT t.x) AS v"),
5001 "SELECT * FROM t, (SELECT t.x) AS v"
5002 );
5003 }
5004
5005 #[test]
5006 fn the_forms_of_a_table_function_this_does_not_cover_are_turned_away_by_name() {
5007 for query in ["SELECT * FROM range(3) WITH ORDINALITY", "SELECT * FROM t: range(3)"] {
5008 let error = parse_ast(query).unwrap_err().to_string();
5009 assert!(error.contains("grammar rule"), "{query} failed with {error}");
5010 }
5011 }
5012
5013 #[test]
5014 fn a_pragma_is_the_call_it_stands_for_by_the_time_it_leaves_here() {
5015 assert_eq!(round("PRAGMA version"), "SELECT * FROM pragma_version()");
5016 assert_eq!(round("PRAGMA database_size"), "SELECT * FROM pragma_database_size()");
5017 assert_eq!(round("PRAGMA VERSION"), "SELECT * FROM pragma_VERSION()");
5020 assert_eq!(round("PRAGMA table_info('t')"), "SELECT * FROM pragma_table_info('t')");
5021 }
5022
5023 #[test]
5024 fn a_pragma_that_is_a_statement_stays_one_rather_than_becoming_a_call() {
5025 assert_eq!(round_statement("PRAGMA disable_optimizer"), "PRAGMA disable_optimizer");
5028 assert_eq!(round_statement("PRAGMA enable_profiling"), "PRAGMA enable_profiling");
5029 assert_eq!(round_statement("PRAGMA force_checkpoint"), "PRAGMA force_checkpoint");
5030 assert_eq!(round_statement("PRAGMA verify_parallelism"), "PRAGMA verify_parallelism");
5031 assert_eq!(round_statement("PRAGMA enable_nothing_at_all"), "PRAGMA enable_nothing_at_all");
5034 assert_eq!(
5036 round("PRAGMA disable_optimizer('x')"),
5037 "SELECT * FROM pragma_disable_optimizer('x')"
5038 );
5039 }
5040
5041 #[test]
5042 fn a_bare_name_in_a_pragmas_parentheses_is_a_name_and_not_a_column() {
5043 assert_eq!(round("PRAGMA table_info(t)"), "SELECT * FROM pragma_table_info('t')");
5046 assert_eq!(round("PRAGMA table_info(main.t)"), "SELECT * FROM pragma_table_info('main.t')");
5047 assert_eq!(round("PRAGMA table_info(\"T\")"), "SELECT * FROM pragma_table_info('T')");
5048 assert_eq!(round("PRAGMA table_info(1)"), "SELECT * FROM pragma_table_info(1)");
5051 }
5052
5053 #[test]
5054 fn a_pragma_with_an_equals_sign_is_a_set_and_nothing_else() {
5055 assert_eq!(round_statement("PRAGMA memory_limit = '1GB'"), "SET memory_limit = '1GB'");
5056 assert_eq!(round_statement("PRAGMA threads = 4"), "SET threads = 4");
5057 }
5058
5059 #[test]
5060 fn a_pragma_with_empty_parentheses_does_not_parse_on_either_engine() {
5061 let error = parse_ast("PRAGMA version()").unwrap_err().to_string();
5064 assert!(error.contains("syntax error at or near \")\""), "{error}");
5065 }
5066
5067 #[test]
5068 fn a_window_call_carries_its_partition_its_order_and_its_frame() {
5069 assert_eq!(
5070 round("SELECT row_number() OVER () FROM t"),
5071 "SELECT row_number() OVER [] [] [Range UnboundedPreceding CurrentRow NoOthers] FROM t"
5072 );
5073 assert_eq!(
5074 round("SELECT sum(a) OVER (PARTITION BY b, c ORDER BY d DESC NULLS FIRST) FROM t"),
5075 "SELECT sum(a) OVER [b, c] [d Descending First] \
5076 [Range UnboundedPreceding CurrentRow NoOthers] FROM t"
5077 );
5078 assert_eq!(
5079 round(
5080 "SELECT sum(a) OVER (ORDER BY b GROUPS BETWEEN 1 PRECEDING AND 2 FOLLOWING EXCLUDE TIES) FROM t"
5081 ),
5082 "SELECT sum(a) OVER [] [b Unstated Unstated] \
5083 [Groups Preceding(1) Following(2) Ties] FROM t"
5084 );
5085 }
5086
5087 #[test]
5090 fn a_frame_with_both_ends_unbounded_is_counted_in_rows() {
5091 for unit in ["ROWS", "RANGE", "GROUPS"] {
5092 let query = format!(
5093 "SELECT sum(a) OVER (ORDER BY b {unit} BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t"
5094 );
5095 assert_eq!(
5096 round(&query),
5097 "SELECT sum(a) OVER [] [b Unstated Unstated] \
5098 [Rows UnboundedPreceding UnboundedFollowing NoOthers] FROM t"
5099 );
5100 }
5101 }
5102
5103 #[test]
5106 fn a_frame_written_with_one_bound_ends_at_the_current_row() {
5107 assert_eq!(
5108 round("SELECT sum(a) OVER (ORDER BY b ROWS UNBOUNDED PRECEDING) FROM t"),
5109 round(
5110 "SELECT sum(a) OVER (ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t"
5111 )
5112 );
5113 }
5114
5115 #[test]
5116 fn a_named_window_is_resolved_here_and_not_carried_any_further() {
5117 let inlined = round("SELECT sum(a) OVER (PARTITION BY b ORDER BY c) FROM t");
5118 assert_eq!(
5119 round("SELECT sum(a) OVER w FROM t WINDOW w AS (PARTITION BY b ORDER BY c)"),
5120 inlined
5121 );
5122 assert_eq!(
5123 round("SELECT sum(a) OVER (w) FROM t WINDOW w AS (PARTITION BY b ORDER BY c)"),
5124 inlined
5125 );
5126 assert_eq!(
5129 round("SELECT sum(a) OVER v FROM t WINDOW w AS (PARTITION BY b), v AS (w ORDER BY c)"),
5130 inlined
5131 );
5132 assert_eq!(
5133 round("SELECT sum(a) OVER (w ORDER BY c) FROM t WINDOW w AS (PARTITION BY b)"),
5134 inlined
5135 );
5136 assert_eq!(
5138 round("SELECT sum(a) OVER W FROM t WINDOW w AS (PARTITION BY b ORDER BY c)"),
5139 inlined
5140 );
5141 }
5142
5143 #[test]
5146 fn a_named_window_reaches_a_subquery_written_in_the_same_block() {
5147 let ast = parse_ast("SELECT (SELECT sum(b) OVER w FROM u) FROM t WINDOW w AS (ORDER BY b)");
5148 assert!(ast.is_ok(), "{:?}", ast.err());
5149 let error =
5151 parse_ast("SELECT 1 FROM t WINDOW w AS (ORDER BY b); SELECT sum(a) OVER w FROM u;")
5152 .unwrap_err()
5153 .to_string();
5154 assert!(error.contains("window \"\"w\"\" does not exist"), "{error}");
5155 }
5156
5157 #[test]
5160 fn the_four_complaints_about_a_named_window_are_upstreams() {
5161 let cases = [
5162 ("SELECT sum(a) OVER w FROM t", "window \"\"w\"\" does not exist"),
5163 (
5164 "SELECT sum(a) OVER (w PARTITION BY b) FROM t WINDOW w AS (PARTITION BY b)",
5165 "Cannot override PARTITION BY clause of window \"w\"",
5166 ),
5167 (
5168 "SELECT sum(a) OVER (w ORDER BY b) FROM t WINDOW w AS (ORDER BY b)",
5169 "Cannot override ORDER BY clause of window \"w\"",
5170 ),
5171 (
5172 "SELECT sum(a) OVER (w ROWS UNBOUNDED PRECEDING) FROM t WINDOW w AS (ORDER BY b ROWS UNBOUNDED PRECEDING)",
5173 "cannot copy window \"w\" because it has a frame clause",
5174 ),
5175 ];
5176 for (query, expected) in cases {
5177 let error = parse_ast(query).expect_err(query).to_string();
5178 assert!(error.contains(expected), "{query}: {error}");
5179 }
5180 }
5181
5182 #[test]
5185 fn the_modifiers_that_only_a_window_takes_are_turned_down_without_one() {
5186 let error = parse_ast("SELECT first_value(a IGNORE NULLS) FROM t").unwrap_err().to_string();
5187 assert!(
5188 error.contains("RESPECT/IGNORE NULLS is not supported for non-window functions"),
5189 "{error}"
5190 );
5191 let error = parse_ast("SELECT sum(a) OVER (ORDER BY b EXCLUDE TIES) FROM t")
5192 .unwrap_err()
5193 .to_string();
5194 assert!(error.contains("syntax error at or near \"EXCLUDE\""), "{error}");
5195 }
5196
5197 #[test]
5200 fn a_window_call_is_not_put_through_the_rewrites_a_plain_call_is() {
5201 assert_eq!(
5202 round("SELECT ifnull(1) OVER () FROM t"),
5203 "SELECT ifnull(1) OVER [] [] [Range UnboundedPreceding CurrentRow NoOthers] FROM t"
5204 );
5205 let error = parse_ast("SELECT ifnull(1) FROM t").unwrap_err().to_string();
5206 assert!(error.contains("Wrong number of arguments to IFNULL."), "{error}");
5207 }
5208
5209 #[test]
5210 fn interning_means_a_name_written_twice_is_stored_once() {
5211 let ast = parse_ast("SELECT a, a, a FROM t WHERE a = a").unwrap();
5212 assert_eq!(ast.strings.iter().filter(|text| *text == "a").count(), 1);
5213 }
5214}