1use std::sync::Arc;
16
17use rudb_catalog::{Catalog, Entry, QualifiedName, same_name};
18use rudb_common::bounds::Zones;
19use rudb_common::{
20 Error, Field, LogicalType, Result, Semantics, Session, ShowBehavior, Span, Stat, Value,
21};
22use rudb_functions::{
23 Columns, FILE_ROW_NUMBER, FunctionKind, Given, Resolved, TableFunction, csv_fields, csv_given,
24 files, is_file, is_pattern, kind_of, parquet_footers, resolve, resolve_pragma, resolve_table,
25};
26use rudb_kernels::cast_value;
27use rudb_parse::ast::{self, Ast, Distinct, LiteralKind, Nulls, Order, Quantifier, SetOp};
28use rudb_parse::{NONE, identifier_parts, parse_ast_with_case};
29use rudb_plan::{
30 BuildSide, ColumnBinding, ConjunctionOp, Expr, ExprRef, JoinKind, Node, NodeRef, Plan,
31 SetOpKind, SortKey, WindowBound, WindowExclude, WindowFrame, WindowUnit,
32};
33
34use crate::expr::{describe, has_aggregate};
35use crate::fold;
36use crate::parameters::Parameters;
37use crate::scope::{Scope, Visible};
38
39pub fn bind(ast: &Ast, catalog: &Catalog) -> Result<Plan> {
46 bind_with(ast, catalog, &Parameters::new(), &Session::new())
47}
48
49pub fn bind_with(
58 ast: &Ast,
59 catalog: &Catalog,
60 parameters: &Parameters,
61 session: &Session,
62) -> Result<Plan> {
63 let query = match ast.statements.as_slice() {
64 [ast::Statement::Query(query)] => *query,
65 [] => return Err(Error::binder("no statement to bind")),
66 [_] => return Err(Error::not_implemented("a statement that is not a query")),
69 _ => return Err(Error::not_implemented("a script of more than one statement")),
70 };
71 let mut binder = Binder::with(catalog, parameters, session);
72 let (root, _) = binder.bind_query(ast, query)?;
73 let mut plan = binder.into_plan();
74 plan.set_root(root);
75 plan.validate()?;
76 Ok(plan)
77}
78
79pub fn bind_sql(query: &str, catalog: &Catalog) -> Result<Plan> {
85 bind_sql_with(query, catalog, &Session::new())
86}
87
88pub fn bind_sql_with(query: &str, catalog: &Catalog, session: &Session) -> Result<Plan> {
94 let ast = parse_ast_with_case(query, session.semantics().identifier_case())?;
95 bind_with(&ast, catalog, &Parameters::new(), session)
96}
97
98#[derive(Debug)]
100pub(crate) struct Aggregation {
101 pub(crate) index: u32,
103 pub(crate) groups: Vec<ExprRef>,
105 pub(crate) aggregates: Vec<ExprRef>,
107}
108
109#[derive(Debug)]
117pub(crate) struct WindowRun {
118 index: u32,
120 partition: Vec<ExprRef>,
122 order: Vec<SortKey>,
124 frame: WindowFrame,
126 calls: Vec<ExprRef>,
128}
129
130pub(crate) struct WindowCall<'a> {
135 pub(crate) name: &'a str,
137 pub(crate) args: &'a [ast::ExprRef],
139 pub(crate) distinct: bool,
141 pub(crate) filter: ast::ExprRef,
143 pub(crate) ignore_nulls: bool,
145 pub(crate) spec: ast::WindowRef,
147}
148
149struct WindowParts {
151 args: Vec<ExprRef>,
153 partition: Vec<ExprRef>,
155 order: Vec<SortKey>,
157 frame: WindowFrame,
159}
160
161#[derive(Debug)]
168struct Read {
169 fields: Vec<Field>,
171 rows: Stat<u64>,
173 distincts: Vec<(String, Stat<u64>)>,
175 zones: Option<Arc<dyn Zones>>,
177}
178
179impl Read {
180 fn uncounted(fields: Vec<Field>) -> Self {
182 Self { fields, rows: Stat::Unknown, distincts: Vec::new(), zones: None }
183 }
184}
185
186#[derive(Debug)]
188struct Materialized {
189 written: u32,
191 cte: u32,
193 name: String,
195 fields: Vec<Field>,
197}
198
199#[derive(Debug)]
200pub(crate) struct PendingSubquery {
201 pub(crate) node: NodeRef,
202 pub(crate) kind: JoinKind,
203 pub(crate) conditions: Vec<ExprRef>,
204 pub(crate) dependent: bool,
205 pub(crate) reads: Vec<ColumnBinding>,
211 pub(crate) index: u32,
217 pub(crate) inside_aggregate: bool,
224}
225
226#[derive(Debug, Clone, Copy, PartialEq, Eq)]
228enum Side {
229 Left,
230 Right,
231}
232
233#[derive(Debug)]
235pub(crate) struct Binder<'a> {
236 catalog: &'a Catalog,
237 pub(crate) parameters: &'a Parameters,
239 pub(crate) session: &'a Session,
241 pub(crate) semantics: Semantics,
243 plan: Plan,
244 next_index: u32,
245 pub(crate) current_span: Span,
247 pub(crate) aggregation: Option<Aggregation>,
249 pub(crate) in_aggregate: bool,
251 pub(crate) in_filter: bool,
253 pub(crate) windows: Vec<WindowRun>,
255 pub(crate) in_window: bool,
257 pub(crate) scalar_subqueries: Vec<PendingSubquery>,
259 pub(crate) joined_above: Vec<u32>,
265 pub(crate) outer_scopes: Vec<Scope>,
266 pub(crate) lateral_scopes: Vec<usize>,
273 pub(crate) correlations: Vec<Vec<ColumnBinding>>,
274 pub(crate) clause: &'static str,
276 expanding: Vec<String>,
278 materialized: Vec<Materialized>,
284 next_cte: u32,
286 started: Option<i64>,
288}
289
290impl<'a> Binder<'a> {
291 pub(crate) fn with(
292 catalog: &'a Catalog,
293 parameters: &'a Parameters,
294 session: &'a Session,
295 ) -> Self {
296 Self {
297 catalog,
298 parameters,
299 session,
300 semantics: session.semantics(),
301 plan: Plan::new(),
302 next_index: 0,
303 current_span: Span::new(0, 0),
304 aggregation: None,
305 in_aggregate: false,
306 in_filter: false,
307 windows: Vec::new(),
308 in_window: false,
309 scalar_subqueries: Vec::new(),
310 joined_above: Vec::new(),
311 outer_scopes: Vec::new(),
312 lateral_scopes: Vec::new(),
313 correlations: Vec::new(),
314 clause: "SELECT clause",
315 expanding: Vec::new(),
316 materialized: Vec::new(),
317 next_cte: 0,
318 started: None,
319 }
320 }
321
322 pub(crate) fn catalog(&self) -> &Catalog {
323 self.catalog
324 }
325
326 pub(crate) fn instant(&mut self) -> i64 {
333 *self.started.get_or_insert_with(crate::context::micros_now)
334 }
335
336 pub(crate) fn plan(&self) -> &Plan {
337 &self.plan
338 }
339
340 pub(crate) fn plan_mut(&mut self) -> &mut Plan {
341 &mut self.plan
342 }
343
344 pub(crate) fn add_expr(&mut self, expr: Expr, ty: LogicalType) -> ExprRef {
345 self.plan.add_expr_at(expr, ty, self.current_span)
346 }
347
348 pub(crate) fn add_constant(&mut self, value: Value) -> ExprRef {
349 let ty = value.logical_type();
350 let reference = self.plan.add_value(value);
351 self.plan.add_expr_at(Expr::Constant(reference), ty, self.current_span)
352 }
353
354 pub(crate) fn add_node(&mut self, node: Node) -> NodeRef {
355 self.plan.add_node_at(node, self.current_span)
356 }
357
358 pub(crate) fn into_plan(self) -> Plan {
359 self.plan
360 }
361
362 pub(crate) fn fresh_index(&mut self) -> u32 {
364 let index = self.next_index;
365 self.next_index += 1;
366 index
367 }
368
369 fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
371 let binding = ColumnBinding::new(index, position as u32);
372 self.plan.add_expr(Expr::Column(binding), ty)
373 }
374
375 fn attach_scalar_subqueries(&mut self, mut input: NodeRef) -> NodeRef {
377 let subqueries = std::mem::take(&mut self.scalar_subqueries);
378 for pending in subqueries {
379 input = self.attach_subquery(input, pending);
380 }
381 input
382 }
383
384 fn attach_subquery(&mut self, input: NodeRef, pending: PendingSubquery) -> NodeRef {
391 let PendingSubquery {
392 node: mut right,
393 kind,
394 conditions,
395 dependent,
396 reads: _,
397 index: _,
398 inside_aggregate: _,
399 } = pending;
400 if kind == JoinKind::Single && !self.semantics.scalar_subquery_error_on_multiple_rows() {
401 right = self.add_node(Node::Limit { input: right, count: Some(1), offset: 0 });
402 }
403 let conditions = self.plan.add_expr_list(&conditions);
404 if dependent {
405 self.add_node(Node::DependentJoin { left: input, right, kind, conditions })
406 } else {
407 self.add_node(Node::Join {
408 left: input,
409 right,
410 kind,
411 conditions,
412 build: BuildSide::default(),
413 })
414 }
415 }
416
417 pub(crate) fn bind_query(
420 &mut self,
421 ast: &Ast,
422 query: ast::QueryRef,
423 ) -> Result<(NodeRef, Scope)> {
424 let span = ast.query_span(query);
425 let outer = std::mem::replace(&mut self.current_span, span);
426 let result =
427 self.bind_query_inner(ast, query).map_err(|error| error.with_fallback_span(span));
428 self.current_span = outer;
429 result
430 }
431
432 fn bind_query_inner(&mut self, ast: &Ast, query: ast::QueryRef) -> Result<(NodeRef, Scope)> {
433 let written = ast.query(query);
434 if written.ctes.is_empty() {
435 return self.bind_body(ast, &written);
436 }
437 let depth = self.materialized.len();
441 let result = self.bind_materialized(ast, &written);
442 self.materialized.truncate(depth);
443 result
444 }
445
446 fn bind_materialized(&mut self, ast: &Ast, written: &ast::Query) -> Result<(NodeRef, Scope)> {
452 let depth = self.materialized.len();
453 let held = ast.cte_list(written.ctes).to_vec();
454 let mut definitions = Vec::with_capacity(held.len());
455 for &index in &held {
456 definitions.push(self.bind_definition(ast, index)?);
457 }
458 let (mut node, scope) = self.bind_body(ast, written)?;
459 for (at, definition) in definitions.into_iter().enumerate().rev() {
460 let entry = &self.materialized[depth + at];
461 let cte = entry.cte;
462 let name = entry.name.clone();
463 let fields = entry.fields.clone();
464 let name = self.plan.intern(&name);
465 let columns = self.plan.add_fields(&fields);
466 node =
467 self.add_node(Node::MaterializedCte { definition, body: node, name, cte, columns });
468 }
469 Ok((node, scope))
470 }
471
472 fn bind_definition(&mut self, ast: &Ast, index: u32) -> Result<NodeRef> {
482 let held = ast.cte(index);
483 let name = ast.string(held.name).to_string();
484 let (node, mut scope) = self.bind_query(ast, held.query)?;
485 if !held.columns.is_empty() {
486 let names: Vec<&str> = ast.name(held.columns).collect();
487 scope.rename_prefix(&names);
488 }
489 let table = self.fresh_index();
490 let mut exprs = Vec::with_capacity(scope.len());
491 let mut names = Vec::with_capacity(scope.len());
492 for column in &scope.columns {
493 exprs.push(self.plan.add_expr(Expr::Column(column.binding), column.ty.clone()));
494 names.push(self.plan.intern(&column.name));
495 }
496 let exprs = self.plan.add_expr_list(&exprs);
497 let names = self.plan.add_name_list(&names);
498 let node = self.add_node(Node::Project { input: node, index: table, exprs, names });
499 let cte = self.next_cte;
500 self.next_cte += 1;
501 self.materialized.push(Materialized { written: index, cte, name, fields: scope.fields() });
502 Ok(node)
503 }
504
505 fn bind_body(&mut self, ast: &Ast, written: &ast::Query) -> Result<(NodeRef, Scope)> {
506 match written.body {
507 ast::QueryBody::Select(select) => self.bind_select(ast, select, written),
508 ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
509 let operator = Operator { op, quantifier, by_name };
510 self.bind_set_op(ast, written, operator, left, right)
511 }
512 ast::QueryBody::Values(rows) => self.bind_values(ast, written, rows),
513 ast::QueryBody::Describe(inner) => self.bind_describe(ast, written, inner),
514 ast::QueryBody::Show { name, relation } => self.bind_show(ast, written, name, relation),
515 }
516 }
517
518 fn bind_show(
520 &mut self,
521 ast: &Ast,
522 query: &ast::Query,
523 name: ast::Slice,
524 relation: ast::QueryRef,
525 ) -> Result<(NodeRef, Scope)> {
526 let text = ast.name_text(name);
527 let parts: Vec<&str> = ast.name(name).collect();
528 let table_exists = self.catalog.resolve(&parts).is_ok();
529 let as_table = match self.semantics.show_behavior() {
530 ShowBehavior::Auto => table_exists,
531 ShowBehavior::Setting => false,
532 ShowBehavior::Table => true,
533 };
534 if as_table {
535 return self.bind_describe(ast, query, relation);
536 }
537 let Some((_, value)) =
538 self.session.iter().find(|(name, _)| name.eq_ignore_ascii_case(&text))
539 else {
540 return Err(Error::catalog(format!("Setting with name \"{text}\" does not exist")));
541 };
542 let field = Field::new(text, LogicalType::Varchar);
543 let expr = self.plan.add_constant(Value::Varchar(value.to_string()));
544 let row = self.plan.add_expr_list(&[expr]);
545 let rows = self.plan.add_rows(&[row]);
546 let columns = self.plan.add_fields(std::slice::from_ref(&field));
547 let index = self.fresh_index();
548 let node = self.add_node(Node::Values { index, columns, rows });
549 let mut scope = Scope::empty();
550 scope.push(Visible {
551 table: String::new(),
552 name: field.name,
553 binding: ColumnBinding::new(index, 0),
554 ty: LogicalType::Varchar,
555 not_null: false,
556 });
557 Ok((node, scope))
558 }
559
560 fn bind_describe(
576 &mut self,
577 ast: &Ast,
578 query: &ast::Query,
579 inner: ast::QueryRef,
580 ) -> Result<(NodeRef, Scope)> {
581 let (_, described) = self.bind_query(ast, inner)?;
582 let fields: Vec<Field> = ["column_name", "column_type", "null", "key", "default", "extra"]
583 .iter()
584 .map(|name| Field::new(*name, LogicalType::Varchar))
585 .collect();
586 let mut slices = Vec::with_capacity(described.columns.len());
587 for column in described.columns.clone() {
588 let written = [
591 column.name.clone(),
592 column.ty.to_string(),
593 if column.not_null { "NO" } else { "YES" }.to_owned(),
594 ];
595 let mut items: Vec<ExprRef> = written
596 .into_iter()
597 .map(|text| self.plan.add_constant(Value::Varchar(text)))
598 .collect();
599 for _ in 0..3 {
600 let empty = self.plan.add_constant(Value::Null);
601 items.push(self.cast_to(empty, &LogicalType::Varchar));
602 }
603 slices.push(self.plan.add_expr_list(&items));
604 }
605 let rows = self.plan.add_rows(&slices);
606 let columns = self.plan.add_fields(&fields);
607 let index = self.fresh_index();
608 let mut node = self.add_node(Node::Values { index, columns, rows });
609 let mut scope = Scope::empty();
610 for (at, field) in fields.iter().enumerate() {
611 scope.push(Visible {
612 table: String::new(),
613 name: field.name.clone(),
614 binding: ColumnBinding::new(index, at as u32),
615 ty: field.ty.clone(),
616 not_null: false,
617 });
618 }
619 let keys = self.sort_keys(ast, query, &scope, &[])?;
620 if !keys.is_empty() {
621 let keys = self.plan.add_sort_keys(&keys);
622 node = self.add_node(Node::Sort { input: node, keys });
623 }
624 node = self.apply_limit(ast, query, node)?;
625 Ok((node, scope))
626 }
627
628 fn passes_through(&self, expr: ExprRef, input: &Scope) -> bool {
634 let Expr::Column(binding) = *self.plan.expr(expr) else { return false };
635 input.columns.iter().any(|column| column.binding == binding && column.not_null)
636 }
637
638 fn bind_values(
645 &mut self,
646 ast: &Ast,
647 query: &ast::Query,
648 rows: ast::Slice,
649 ) -> Result<(NodeRef, Scope)> {
650 let written = ast.rows(rows).to_vec();
651 let Some(first) = written.first() else {
652 return Err(Error::binder("VALUES needs at least one row"));
653 };
654 let width = first.len as usize;
655 for (at, row) in written.iter().enumerate() {
656 if row.len as usize != width {
657 return Err(Error::binder(format!(
658 "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
659 at + 1,
660 row.len
661 )));
662 }
663 }
664 let empty = Scope::empty();
666 let previous = std::mem::replace(&mut self.clause, "VALUES clause");
667 let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
668 for row in &written {
669 let mut items = Vec::with_capacity(width);
670 for &expr in ast.expr_list(*row) {
671 items.push(self.bind_expr(ast, expr, &empty)?);
672 }
673 bound.push(items);
674 }
675 self.clause = previous;
676 let mut types = Vec::with_capacity(width);
677 for at in 0..width {
678 let mut ty = self.plan.expr_type(bound[0][at]).clone();
679 for row in &bound[1..] {
680 let other = self.plan.expr_type(row[at]).clone();
681 ty = ty.promote(&other).ok_or_else(|| {
682 Error::binder(format!(
683 "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
684 at + 1
685 ))
686 })?;
687 }
688 types.push(ty);
689 }
690 let mut slices = Vec::with_capacity(bound.len());
691 for row in &bound {
692 let items: Vec<ExprRef> = row
693 .iter()
694 .zip(&types)
695 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
696 .collect::<Result<_>>()?;
697 slices.push(self.plan.add_expr_list(&items));
698 }
699 let rows = self.plan.add_rows(&slices);
700 let fields: Vec<Field> = types
701 .iter()
702 .enumerate()
703 .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
704 .collect();
705 let columns = self.plan.add_fields(&fields);
706 let index = self.fresh_index();
707 let mut node = self.add_node(Node::Values { index, columns, rows });
708 let mut scope = Scope::empty();
709 for (at, field) in fields.iter().enumerate() {
710 scope.push(Visible {
711 table: String::new(),
712 name: field.name.clone(),
713 binding: ColumnBinding::new(index, at as u32),
714 ty: field.ty.clone(),
715 not_null: false,
716 });
717 }
718 let keys = self.sort_keys(ast, query, &scope, &[])?;
719 if !keys.is_empty() {
720 let keys = self.plan.add_sort_keys(&keys);
721 node = self.add_node(Node::Sort { input: node, keys });
722 }
723 node = self.apply_limit(ast, query, node)?;
724 Ok((node, scope))
725 }
726
727 fn bind_set_op(
728 &mut self,
729 ast: &Ast,
730 query: &ast::Query,
731 operator: Operator,
732 left: ast::QueryRef,
733 right: ast::QueryRef,
734 ) -> Result<(NodeRef, Scope)> {
735 let (left_node, left_scope) = self.bind_query(ast, left)?;
736 let (right_node, right_scope) = self.bind_query(ast, right)?;
737 let merged = if operator.by_name {
738 match_by_name(&left_scope, &right_scope)?
739 } else {
740 match_by_position(&left_scope, &right_scope)?
741 };
742 let left_node = self.conform(left_node, &left_scope, &merged, |column| column.left)?;
743 let right_node = self.conform(right_node, &right_scope, &merged, |column| column.right)?;
744 let index = self.fresh_index();
745 let kind = match operator.op {
746 SetOp::Union => SetOpKind::Union,
747 SetOp::Except => SetOpKind::Except,
748 SetOp::Intersect => SetOpKind::Intersect,
749 };
750 let all = operator.quantifier == Quantifier::All;
753 let mut node =
754 self.add_node(Node::SetOp { left: left_node, right: right_node, kind, all, index });
755 let mut scope = Scope::empty();
756 for (at, column) in merged.iter().enumerate() {
757 scope.push(Visible {
758 table: String::new(),
759 name: column.name.clone(),
760 binding: ColumnBinding::new(index, at as u32),
761 ty: column.ty.clone(),
762 not_null: false,
765 });
766 }
767 let keys = self.sort_keys(ast, query, &scope, &[])?;
771 if !keys.is_empty() {
772 let keys = self.plan.add_sort_keys(&keys);
773 node = self.add_node(Node::Sort { input: node, keys });
774 }
775 node = self.apply_limit(ast, query, node)?;
776 Ok((node, scope))
777 }
778
779 fn conform(
785 &mut self,
786 node: NodeRef,
787 scope: &Scope,
788 merged: &[Merged],
789 pick: impl Fn(&Merged) -> Option<usize>,
790 ) -> Result<NodeRef> {
791 let unchanged = merged.len() == scope.len()
792 && merged
793 .iter()
794 .enumerate()
795 .all(|(at, column)| pick(column) == Some(at) && column.ty == scope.columns[at].ty);
796 if unchanged {
797 return Ok(node);
798 }
799 let index = self.fresh_index();
800 let mut exprs = Vec::with_capacity(merged.len());
801 let mut names = Vec::with_capacity(merged.len());
802 for column in merged {
803 let expr = match pick(column) {
804 Some(at) => {
805 let held = &scope.columns[at];
806 self.plan.add_expr(Expr::Column(held.binding), held.ty.clone())
807 }
808 None => self.plan.add_constant(Value::Null),
809 };
810 exprs.push(self.checked_cast_to(expr, &column.ty, false)?);
811 names.push(self.plan.intern(&column.name));
812 }
813 let exprs = self.plan.add_expr_list(&exprs);
814 let names = self.plan.add_name_list(&names);
815 Ok(self.add_node(Node::Project { input: node, index, exprs, names }))
816 }
817
818 fn bind_select(
821 &mut self,
822 ast: &Ast,
823 select: ast::SelectRef,
824 query: &ast::Query,
825 ) -> Result<(NodeRef, Scope)> {
826 let written = ast.select(select);
827 let outer_windows = std::mem::take(&mut self.windows);
831 let outer_joined_above = std::mem::take(&mut self.joined_above);
836 let (mut node, input) = self.bind_from(ast, written.from)?;
837 node = self.attach_scalar_subqueries(node);
838
839 if written.filter != NONE {
840 self.clause = "WHERE clause";
841 let predicate = self.bind_expr(ast, written.filter, &input)?;
842 let predicate = self.as_boolean(predicate, "WHERE")?;
843 node = self.attach_scalar_subqueries(node);
844 node = self.add_node(Node::Filter { input: node, predicate });
845 }
846
847 let targets = ast.target_list(written.targets).to_vec();
848 if targets.is_empty() {
849 return Err(Error::binder("a SELECT needs at least one expression to select"));
850 }
851
852 let group_items = self.group_items(ast, &written, &targets)?;
853 let aggregating = !group_items.is_empty()
854 || written.having != NONE
855 || targets.iter().any(|target| has_aggregate(ast, target.expr));
856 if aggregating {
857 self.clause = "GROUP BY clause";
858 let mut groups = Vec::with_capacity(group_items.len());
859 for item in &group_items {
860 groups.push(self.bind_expr(ast, *item, &input)?);
861 }
862 let index = self.fresh_index();
863 self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
864 }
865
866 let mut above = Vec::new();
873
874 self.clause = "SELECT clause";
875 let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input, &mut above)?;
876 let visible = exprs.len();
877
878 let mut having = None;
879 if written.having != NONE {
880 self.clause = "HAVING clause";
881 let before = self.scalar_subqueries.len();
882 let predicate = self.bind_expr(ast, written.having, &input)?;
883 self.lift_over_aggregate(before, &mut above, &input)?;
884 let predicate = self.over_aggregate(predicate, &input)?;
885 having = Some(self.as_boolean(predicate, "HAVING")?);
886 }
887
888 let project = self.fresh_index();
891 let mut output = Scope::empty();
892 for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
893 output.push(Visible {
894 table: String::new(),
895 name: name.clone(),
896 binding: ColumnBinding::new(project, at as u32),
897 ty: self.plan.expr_type(*expr).clone(),
898 not_null: self.passes_through(*expr, &input),
899 });
900 }
901
902 self.clause = "ORDER BY clause";
903 let mut extra = Vec::new();
904 let keys = self.select_sort_keys(
905 ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra, &mut above,
906 )?;
907 self.joined_above = outer_joined_above;
908 if !extra.is_empty() && written.distinct != Distinct::No {
909 return Err(Error::binder(
910 "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
911 ));
912 }
913 let on = self.distinct_on(ast, written.distinct, &output)?;
914
915 node = self.attach_scalar_subqueries(node);
916
917 if let Some(aggregation) = self.aggregation.take() {
918 let index = aggregation.index;
919 let groups = self.plan.add_expr_list(&aggregation.groups);
920 let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
921 node = self.add_node(Node::Aggregate { input: node, index, groups, aggregates });
922 }
923 if !above.is_empty() {
924 debug_assert!(self.scalar_subqueries.is_empty(), "a query is waiting to be joined");
925 self.scalar_subqueries = above;
926 node = self.attach_scalar_subqueries(node);
927 }
928 if let Some(predicate) = having {
929 node = self.add_node(Node::Filter { input: node, predicate });
930 }
931
932 for run in std::mem::replace(&mut self.windows, outer_windows) {
936 let partition = self.plan.add_expr_list(&run.partition);
937 let order = self.plan.add_sort_keys(&run.order);
938 let expressions = self.plan.add_expr_list(&run.calls);
939 node = self.add_node(Node::Window {
940 input: node,
941 index: run.index,
942 partition,
943 order,
944 frame: run.frame,
945 expressions,
946 });
947 }
948
949 let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
950 let exprs_slice = self.plan.add_expr_list(&exprs);
951 let names_slice = self.plan.add_name_list(&interned);
952 node = self.add_node(Node::Project {
953 input: node,
954 index: project,
955 exprs: exprs_slice,
956 names: names_slice,
957 });
958
959 if written.distinct != Distinct::No {
960 let on = self.plan.add_expr_list(&on);
961 node = self.add_node(Node::Distinct { input: node, on });
962 }
963 if !keys.is_empty() {
964 let keys = self.plan.add_sort_keys(&keys);
965 node = self.add_node(Node::Sort { input: node, keys });
966 }
967 node = self.apply_limit(ast, query, node)?;
968
969 if extra.is_empty() {
970 output.columns.truncate(visible);
971 return Ok((node, output));
972 }
973 let index = self.fresh_index();
976 let mut kept = Vec::with_capacity(visible);
977 let mut kept_names = Vec::with_capacity(visible);
978 let mut scope = Scope::empty();
979 for (at, name) in names.iter().enumerate().take(visible) {
980 let ty = output.columns[at].ty.clone();
981 kept.push(self.column(project, at, ty.clone()));
982 kept_names.push(self.plan.intern(name));
983 scope.push(Visible {
984 table: String::new(),
985 name: name.clone(),
986 binding: ColumnBinding::new(index, at as u32),
987 ty,
988 not_null: output.columns[at].not_null,
989 });
990 }
991 let exprs = self.plan.add_expr_list(&kept);
992 let names = self.plan.add_name_list(&kept_names);
993 node = self.add_node(Node::Project { input: node, index, exprs, names });
994 Ok((node, scope))
995 }
996
997 fn lift_over_aggregate(
1015 &mut self,
1016 before: usize,
1017 above: &mut Vec<PendingSubquery>,
1018 scope: &Scope,
1019 ) -> Result<()> {
1020 if self.aggregation.is_none() {
1021 return Ok(());
1022 }
1023 let mut lifted = Vec::new();
1024 for pending in self.scalar_subqueries.split_off(before) {
1025 if pending.dependent || pending.inside_aggregate {
1026 self.scalar_subqueries.push(pending);
1027 } else {
1028 self.joined_above.push(pending.index);
1029 lifted.push(pending);
1030 }
1031 }
1032 for pending in &mut lifted {
1037 let conditions = std::mem::take(&mut pending.conditions);
1038 let mut over = Vec::with_capacity(conditions.len());
1039 for condition in conditions {
1040 over.push(self.over_aggregate(condition, scope)?);
1041 }
1042 pending.conditions = over;
1043 }
1044 above.append(&mut lifted);
1045 Ok(())
1046 }
1047
1048 fn bind_targets(
1049 &mut self,
1050 ast: &Ast,
1051 targets: &[ast::Target],
1052 input: &Scope,
1053 above: &mut Vec<PendingSubquery>,
1054 ) -> Result<(Vec<ExprRef>, Vec<String>)> {
1055 let mut exprs = Vec::with_capacity(targets.len());
1056 let mut names = Vec::with_capacity(targets.len());
1057 for target in targets {
1058 if let ast::Expr::Star { qualifier, replacements } = ast.expr(target.expr) {
1059 let table = ast.name(qualifier).last().map(str::to_string);
1060 let expanded: Vec<Visible> =
1061 input.star(table.as_deref())?.into_iter().cloned().collect();
1062 let replacements = ast.target_list(replacements).to_vec();
1063 let mut used = vec![false; replacements.len()];
1064 for column in expanded {
1065 let found = replacements.iter().zip(&mut used).find(|(replacement, _)| {
1066 same_name(ast.string(replacement.alias), &column.name)
1067 });
1068 let before = self.scalar_subqueries.len();
1073 let (expr, name) = match found {
1074 Some((replacement, used)) => {
1075 *used = true;
1076 let expr = self.bind_expr(ast, replacement.expr, input)?;
1077 (expr, ast.string(replacement.alias).to_string())
1078 }
1079 None => (
1080 self.plan.add_expr(Expr::Column(column.binding), column.ty),
1081 column.name,
1082 ),
1083 };
1084 self.lift_over_aggregate(before, above, input)?;
1085 exprs.push(self.over_aggregate(expr, input)?);
1086 names.push(name);
1087 }
1088 if let Some((replacement, _)) =
1092 replacements.iter().zip(&used).find(|(_, used)| !**used)
1093 {
1094 return Err(missing_replacement(ast.string(replacement.alias), input));
1095 }
1096 continue;
1097 }
1098 let before = self.scalar_subqueries.len();
1099 let expr = self.bind_expr(ast, target.expr, input)?;
1100 self.lift_over_aggregate(before, above, input)?;
1101 exprs.push(self.over_aggregate(expr, input)?);
1102 names.push(if target.alias == NONE {
1103 self.output_name(ast, target.expr, input)
1104 } else {
1105 ast.string(target.alias).to_string()
1106 });
1107 }
1108 Ok((exprs, names))
1109 }
1110
1111 fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
1117 if let ast::Expr::Column { name } = ast.expr(target) {
1118 let parts: Vec<&str> = ast.name(name).collect();
1119 if let Ok(found) = input.resolve(&parts) {
1120 return found.name.clone();
1121 }
1122 }
1123 describe(ast, target, self.semantics)
1124 }
1125
1126 fn group_items(
1128 &self,
1129 ast: &Ast,
1130 select: &ast::Select,
1131 targets: &[ast::Target],
1132 ) -> Result<Vec<ast::ExprRef>> {
1133 if select.group_by_all {
1134 return Ok(targets
1137 .iter()
1138 .filter(|target| !has_aggregate(ast, target.expr))
1139 .map(|target| target.expr)
1140 .collect());
1141 }
1142 let mut items = Vec::new();
1143 for &item in ast.expr_list(select.group_by) {
1144 items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
1145 }
1146 Ok(items)
1147 }
1148
1149 fn output_reference(
1151 &self,
1152 ast: &Ast,
1153 item: ast::ExprRef,
1154 targets: &[ast::Target],
1155 clause: &str,
1156 ) -> Result<Option<ast::ExprRef>> {
1157 match ast.expr(item) {
1158 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
1159 let written = ast.string(text);
1160 let position: usize = written.parse().map_err(|_| {
1161 Error::binder(format!("{clause} term {written} is not a column"))
1162 })?;
1163 if position == 0 || position > targets.len() {
1164 return Err(Error::binder(format!(
1165 "{clause} term out of range - should be between 1 and {}",
1166 targets.len()
1167 )));
1168 }
1169 Ok(Some(targets[position - 1].expr))
1170 }
1171 ast::Expr::Column { name } => {
1172 let parts: Vec<&str> = ast.name(name).collect();
1173 let [written] = parts.as_slice() else { return Ok(None) };
1174 let mut found = None;
1175 for target in targets {
1176 if target.alias != NONE && same_name(ast.string(target.alias), written) {
1177 if found.is_some() {
1178 return Ok(None);
1179 }
1180 found = Some(target.expr);
1181 }
1182 }
1183 Ok(found)
1184 }
1185 _ => Ok(None),
1186 }
1187 }
1188
1189 #[allow(clippy::too_many_arguments)]
1193 fn select_sort_keys(
1194 &mut self,
1195 ast: &Ast,
1196 query: &ast::Query,
1197 input: &Scope,
1198 output: &Scope,
1199 project: u32,
1200 exprs: &mut Vec<ExprRef>,
1201 names: &mut Vec<String>,
1202 extra: &mut Vec<usize>,
1203 above: &mut Vec<PendingSubquery>,
1204 ) -> Result<Vec<SortKey>> {
1205 if query.order_by_all {
1206 return Ok(self.every_column(output));
1207 }
1208 let items = ast.order_list(query.order_by).to_vec();
1209 let mut keys = Vec::with_capacity(items.len());
1210 for item in items {
1211 self.check_order_literal(ast, item.expr)?;
1212 let position = match self.output_position(ast, item.expr, output)? {
1213 Some(position) => position,
1214 None => {
1215 let before = self.scalar_subqueries.len();
1216 let bound = self.bind_expr(ast, item.expr, input)?;
1217 self.lift_over_aggregate(before, above, input)?;
1218 let bound = self.over_aggregate(bound, input)?;
1219 match exprs.iter().position(|&held| self.same_expr(held, bound)) {
1220 Some(position) => position,
1221 None => {
1222 exprs.push(bound);
1223 names.push(describe(ast, item.expr, self.semantics));
1224 extra.push(exprs.len() - 1);
1225 exprs.len() - 1
1226 }
1227 }
1228 }
1229 };
1230 let ty = self.plan.expr_type(exprs[position]).clone();
1231 let expr = self.column(project, position, ty);
1232 keys.push(self.sort_key(expr, item));
1233 }
1234 Ok(keys)
1235 }
1236
1237 fn sort_keys(
1239 &mut self,
1240 ast: &Ast,
1241 query: &ast::Query,
1242 output: &Scope,
1243 targets: &[ast::Target],
1244 ) -> Result<Vec<SortKey>> {
1245 if query.order_by_all {
1246 return Ok(self.every_column(output));
1247 }
1248 let items = ast.order_list(query.order_by).to_vec();
1249 let mut keys = Vec::with_capacity(items.len());
1250 for item in items {
1251 self.check_order_literal(ast, item.expr)?;
1252 let expr = match self.output_position(ast, item.expr, output)? {
1253 Some(position) => {
1254 let column = &output.columns[position];
1255 let (binding, ty) = (column.binding, column.ty.clone());
1256 self.plan.add_expr(Expr::Column(binding), ty)
1257 }
1258 None => {
1259 let _ = targets;
1260 self.bind_expr(ast, item.expr, output)?
1261 }
1262 };
1263 keys.push(self.sort_key(expr, item));
1264 }
1265 Ok(keys)
1266 }
1267
1268 fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
1269 let columns: Vec<(ColumnBinding, LogicalType)> =
1270 output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
1271 columns
1272 .into_iter()
1273 .map(|(binding, ty)| {
1274 let expr = self.plan.add_expr(Expr::Column(binding), ty);
1275 let descending = self.semantics.default_descending();
1276 SortKey { expr, descending, nulls_first: self.semantics.nulls_first(descending) }
1277 })
1278 .collect()
1279 }
1280
1281 fn sort_key(&self, expr: ExprRef, item: ast::OrderItem) -> SortKey {
1283 let descending = match item.order {
1284 Order::Unstated => self.semantics.default_descending(),
1285 Order::Ascending => false,
1286 Order::Descending => true,
1287 };
1288 let nulls_first = match item.nulls {
1289 Nulls::First => true,
1290 Nulls::Last => false,
1291 Nulls::Unstated => self.semantics.nulls_first(descending),
1292 };
1293 SortKey { expr, descending, nulls_first }
1294 }
1295
1296 fn output_position(
1298 &self,
1299 ast: &Ast,
1300 item: ast::ExprRef,
1301 output: &Scope,
1302 ) -> Result<Option<usize>> {
1303 match ast.expr(item) {
1304 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
1305 let written = ast.string(text);
1306 if written.contains(['.', 'e', 'E']) {
1307 return Ok(None);
1308 }
1309 let position: usize = written.parse().map_err(|_| {
1310 Error::binder(format!("ORDER BY term {written} is not a column"))
1311 })?;
1312 if position == 0 || position > output.len() {
1313 return Err(Error::binder(format!(
1314 "ORDER BY term out of range - should be between 1 and {}",
1315 output.len()
1316 )));
1317 }
1318 Ok(Some(position - 1))
1319 }
1320 ast::Expr::Column { name } => {
1321 let parts: Vec<&str> = ast.name(name).collect();
1322 let [written] = parts.as_slice() else { return Ok(None) };
1323 Ok(output.position_of(None, written))
1324 }
1325 _ => Ok(None),
1326 }
1327 }
1328
1329 fn check_order_literal(&self, ast: &Ast, item: ast::ExprRef) -> Result<()> {
1331 if !self.semantics.order_by_non_integer_literal()
1332 && matches!(
1333 ast.expr(item),
1334 ast::Expr::Literal { kind, text }
1335 if kind != LiteralKind::Number
1336 || ast.string(text).contains(['.', 'e', 'E'])
1337 )
1338 {
1339 return Err(Error::binder(
1340 "ORDER BY non-integer literal has no effect.\n* SET order_by_non_integer_literal=true to allow this behavior.",
1341 ));
1342 }
1343 Ok(())
1344 }
1345
1346 fn distinct_on(
1348 &mut self,
1349 ast: &Ast,
1350 distinct: Distinct,
1351 output: &Scope,
1352 ) -> Result<Vec<ExprRef>> {
1353 let Distinct::On(items) = distinct else {
1354 return Ok(Vec::new());
1355 };
1356 let items = ast.expr_list(items).to_vec();
1357 let mut on = Vec::with_capacity(items.len());
1358 for item in items {
1359 let Some(position) = self.output_position(ast, item, output)? else {
1360 return Err(Error::not_implemented(
1361 "DISTINCT ON an expression that is not in the select list",
1362 ));
1363 };
1364 let column = &output.columns[position];
1365 let (binding, ty) = (column.binding, column.ty.clone());
1366 on.push(self.plan.add_expr(Expr::Column(binding), ty));
1367 }
1368 Ok(on)
1369 }
1370
1371 fn apply_limit(&mut self, ast: &Ast, query: &ast::Query, input: NodeRef) -> Result<NodeRef> {
1372 if query.limit_percent {
1373 let percent = self.constant_percent(ast, query.limit)?;
1374 let offset = self.constant_count(ast, query.offset, "OFFSET")?.unwrap_or(0);
1375 return Ok(match percent {
1376 Some(percent) => self.add_node(Node::LimitPercent { input, percent, offset }),
1377 None => self.limited(input, None, offset),
1380 });
1381 }
1382 let count = self.constant_count(ast, query.limit, "LIMIT")?;
1383 let offset = self.constant_count(ast, query.offset, "OFFSET")?.unwrap_or(0);
1384 Ok(self.limited(input, count, offset))
1385 }
1386
1387 fn limited(&mut self, input: NodeRef, count: Option<u64>, offset: u64) -> NodeRef {
1390 if count.is_none() && offset == 0 {
1391 return input;
1392 }
1393 self.add_node(Node::Limit { input, count, offset })
1394 }
1395
1396 fn constant_percent(&mut self, ast: &Ast, written: ast::ExprRef) -> Result<Option<f64>> {
1407 if written == NONE {
1408 return Ok(None);
1409 }
1410 self.clause = "LIMIT clause";
1411 let scope = Scope::empty();
1412 let bound = self.bind_expr(ast, written, &scope)?;
1413 let Some(value) = fold::value_of(&self.plan, bound)? else {
1414 return Err(Error::not_implemented("a LIMIT holding a subquery"));
1415 };
1416 if value.is_null() {
1417 return Ok(None);
1418 }
1419 let cast = cast_value(&value, &LogicalType::Double, false)?;
1420 let Value::Double(percent) = cast else {
1421 return Err(Error::binder(format!(
1422 "LIMIT takes a percentage, not a value of type {}",
1423 value.logical_type()
1424 )));
1425 };
1426 if !(0.0..=100.0).contains(&percent) {
1427 return Err(Error::out_of_range(
1428 "Limit percent out of range, should be between 0% and 100%",
1429 ));
1430 }
1431 Ok(Some(percent))
1432 }
1433
1434 fn constant_count(
1448 &mut self,
1449 ast: &Ast,
1450 written: ast::ExprRef,
1451 clause: &str,
1452 ) -> Result<Option<u64>> {
1453 if written == NONE {
1454 return Ok(None);
1455 }
1456 self.clause = "LIMIT clause";
1457 let scope = Scope::empty();
1458 let bound = self.bind_expr(ast, written, &scope)?;
1459 let Some(value) = fold::value_of(&self.plan, bound)? else {
1460 return Err(Error::not_implemented(format!("a {clause} holding a subquery")));
1461 };
1462 if value.is_null() {
1465 return Ok(None);
1466 }
1467 let count = cast_value(&value, &LogicalType::BigInt, false)?.as_i64().ok_or_else(|| {
1468 Error::binder(format!(
1469 "{clause} takes a whole number of rows, not a value of type {}",
1470 value.logical_type()
1471 ))
1472 })?;
1473 u64::try_from(count).map(Some).map_err(|_| Error::binder("LIMIT/OFFSET cannot be negative"))
1476 }
1477
1478 fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
1481 let sources = ast.source_list(from).to_vec();
1482 let Some((first, rest)) = sources.split_first() else {
1483 return Ok((self.add_node(Node::Dummy), Scope::empty()));
1486 };
1487 let (mut node, mut scope) = self.bind_source(ast, *first)?;
1488 for source in rest {
1489 let (right, right_scope, correlations) = self.bind_lateral(ast, *source, &scope)?;
1490 node = if correlations.is_empty() {
1491 self.add_node(Node::CrossProduct { left: node, right })
1492 } else {
1493 let conditions = self.plan.add_expr_list(&[]);
1494 self.add_node(Node::DependentJoin {
1495 left: node,
1496 right,
1497 kind: JoinKind::Inner,
1498 conditions,
1499 })
1500 };
1501 scope = scope.concat(right_scope);
1502 }
1503 Ok((node, scope))
1504 }
1505
1506 fn bind_lateral(
1518 &mut self,
1519 ast: &Ast,
1520 source: ast::SourceRef,
1521 left: &Scope,
1522 ) -> Result<(NodeRef, Scope, Vec<ColumnBinding>)> {
1523 self.lateral_scopes.push(self.outer_scopes.len());
1524 self.outer_scopes.push(left.clone());
1525 self.correlations.push(Vec::new());
1526 let bound = self.bind_source(ast, source);
1527 let read = self.correlations.pop().expect("correlation frame");
1528 self.outer_scopes.pop();
1529 self.lateral_scopes.pop();
1530 let (node, scope) = bound?;
1531
1532 let mut here = Vec::new();
1533 for binding in read {
1534 if left.columns.iter().any(|column| column.binding == binding) {
1535 here.push(binding);
1536 } else if let Some(enclosing) = self.correlations.last_mut() {
1537 if !enclosing.contains(&binding) {
1538 enclosing.push(binding);
1539 }
1540 }
1541 }
1542 Ok((node, scope, here))
1552 }
1553
1554 fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
1555 match ast.source(source) {
1556 ast::Source::Table { name, alias, columns } => {
1557 self.bind_table(ast, name, alias, columns)
1558 }
1559 ast::Source::Function { name, args, alias, columns, pragma } => {
1560 self.bind_table_function(ast, name, args, alias, columns, pragma)
1561 }
1562 ast::Source::Subquery { query, alias, columns } => {
1563 let (node, mut scope) = self.bind_query(ast, query)?;
1564 let label = if alias == NONE {
1565 "unnamed_subquery".to_string()
1566 } else {
1567 ast.string(alias).to_string()
1568 };
1569 scope.relabel(&label);
1570 if !columns.is_empty() {
1571 let names: Vec<&str> = ast.name(columns).collect();
1572 scope.rename(&names, &label)?;
1573 }
1574 Ok((node, scope))
1575 }
1576 ast::Source::Values { rows, alias, columns } => {
1577 let bare = ast::Query::bare(ast::QueryBody::Values(rows));
1578 let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
1579 let label =
1580 if alias == NONE { String::new() } else { ast.string(alias).to_string() };
1581 scope.relabel(&label);
1582 if !columns.is_empty() {
1583 let names: Vec<&str> = ast.name(columns).collect();
1584 scope.rename(&names, &label)?;
1585 }
1586 Ok((node, scope))
1587 }
1588 ast::Source::Cte { cte, alias, columns } => {
1589 self.bind_cte_scan(ast, cte, alias, columns)
1590 }
1591 ast::Source::Join { left, right, kind, natural, on, using } => {
1592 self.bind_join(ast, left, right, kind, natural, on, using)
1593 }
1594 }
1595 }
1596
1597 fn bind_cte_scan(
1604 &mut self,
1605 ast: &Ast,
1606 written: u32,
1607 alias: ast::StrRef,
1608 columns: ast::Slice,
1609 ) -> Result<(NodeRef, Scope)> {
1610 let Some(held) = self.materialized.iter().rev().find(|held| held.written == written) else {
1611 let name = ast.string(ast.cte(written).name);
1612 return Err(Error::binder(format!("Table with name {name} does not exist!")));
1613 };
1614 let cte = held.cte;
1615 let fields = held.fields.clone();
1616 let text = held.name.clone();
1617 let label = if alias == NONE { text.clone() } else { ast.string(alias).to_string() };
1618 let name = self.plan.intern(&text);
1619 let index = self.fresh_index();
1620 let mut scope = Scope::empty();
1621 for (at, field) in fields.iter().enumerate() {
1622 scope.push(Visible {
1623 table: label.clone(),
1624 name: field.name.clone(),
1625 binding: ColumnBinding::new(index, at as u32),
1626 ty: field.ty.clone(),
1627 not_null: field.not_null,
1628 });
1629 }
1630 if !columns.is_empty() {
1631 let names: Vec<&str> = ast.name(columns).collect();
1632 scope.rename(&names, &label)?;
1633 }
1634 let columns = self.plan.add_fields(&fields);
1635 let node = self.add_node(Node::CteScan { index, cte, name, columns });
1636 Ok((node, scope))
1637 }
1638
1639 fn bind_table(
1640 &mut self,
1641 ast: &Ast,
1642 name: ast::Slice,
1643 alias: ast::StrRef,
1644 columns: ast::Slice,
1645 ) -> Result<(NodeRef, Scope)> {
1646 let parts: Vec<&str> = ast.name(name).collect();
1647 let catalog = self.catalog;
1648 let resolved = match catalog.resolve(&parts) {
1651 Ok(resolved) => resolved,
1652 Err(missing) => {
1653 return self.bind_replacement_scan(ast, &parts, alias, columns, missing);
1654 }
1655 };
1656 if catalog.entry(&resolved)? == Entry::View {
1657 return self.bind_view(ast, &resolved, alias, columns);
1658 }
1659 let table = catalog.table(&resolved)?;
1660 let fields: Vec<Field> = table.columns().to_vec();
1661 let label =
1662 if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
1663 let index = self.fresh_index();
1664 let mut scope = Scope::empty();
1665 for (at, field) in fields.iter().enumerate() {
1666 scope.push(Visible {
1667 table: label.clone(),
1668 name: field.name.clone(),
1669 binding: ColumnBinding::new(index, at as u32),
1670 ty: field.ty.clone(),
1671 not_null: field.not_null,
1672 });
1673 }
1674 if !columns.is_empty() {
1675 let names: Vec<&str> = ast.name(columns).collect();
1676 scope.rename(&names, &label)?;
1677 }
1678 let catalog_name = self.plan.intern(&resolved.catalog);
1679 let schema = self.plan.intern(&resolved.schema);
1680 let table_name = self.plan.intern(&resolved.table);
1681 let alias = self.plan.intern(&label);
1682 let columns = self.plan.add_fields(&fields);
1683 let node = self.add_node(Node::Get {
1684 catalog: catalog_name,
1685 schema,
1686 table: table_name,
1687 alias,
1688 index,
1689 columns,
1690 });
1691 Ok((node, scope))
1692 }
1693
1694 fn bind_view(
1706 &mut self,
1707 ast: &Ast,
1708 name: &QualifiedName,
1709 alias: ast::StrRef,
1710 columns: ast::Slice,
1711 ) -> Result<(NodeRef, Scope)> {
1712 let view = self.catalog.view(name)?;
1713 let full = name.to_string();
1714 if self.expanding.contains(&full) {
1715 return Err(Error::binder(format!(
1719 "infinite recursion detected: attempting to recursively bind view \"\"{}\"\"",
1720 name.table
1721 )));
1722 }
1723 let body = parse_ast_with_case(view.sql(), self.semantics.identifier_case())?;
1724 let query = match body.statements.as_slice() {
1725 [ast::Statement::Query(query)] => *query,
1726 _ => return Err(Error::binder(format!("view \"{}\" is not a query", name.table))),
1729 };
1730 self.expanding.push(full);
1731 let bound = self.bind_query(&body, query);
1732 self.expanding.pop();
1733 let (node, mut scope) = bound?;
1734
1735 let aliases: Vec<&str> = view.aliases().iter().map(String::as_str).collect();
1736 if !aliases.is_empty() {
1737 scope.rename(&aliases, "unnamed_subquery")?;
1738 }
1739 view.remember(scope.fields());
1746 let label = if alias == NONE { name.table.clone() } else { ast.string(alias).to_string() };
1747 scope.relabel(&label);
1748 if !columns.is_empty() {
1749 let names: Vec<&str> = ast.name(columns).collect();
1750 scope.rename(&names, &label)?;
1751 }
1752 Ok((node, scope))
1753 }
1754
1755 fn bind_table_function(
1763 &mut self,
1764 ast: &Ast,
1765 name: ast::Slice,
1766 args: ast::Slice,
1767 alias: ast::StrRef,
1768 columns: ast::Slice,
1769 pragma: bool,
1770 ) -> Result<(NodeRef, Scope)> {
1771 let parts: Vec<&str> = ast.name(name).collect();
1772 let function_name = *parts.last().unwrap_or(&"");
1776 if let Some(schema) = parts.iter().rev().nth(1) {
1777 if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
1778 return Err(Error::catalog(format!(
1779 "Table Function with name {} does not exist!",
1780 parts.join(".")
1781 )));
1782 }
1783 }
1784 let Some(called) = TableFunction::lookup(function_name) else {
1788 if pragma {
1789 if args.is_empty() && self.catalog.resolve(&parts).is_ok() {
1795 return self.bind_table(ast, name, alias, columns);
1796 }
1797 let spelled = function_name.strip_prefix("pragma_").unwrap_or(function_name);
1798 return Err(Error::catalog(format!(
1799 "Pragma Function with name {spelled} does not exist!"
1800 )));
1801 }
1802 return Err(Error::catalog(format!(
1803 "Table Function with name {function_name} does not exist!"
1804 )));
1805 };
1806 let written = ast.target_list(args).to_vec();
1807 let empty = Scope::empty();
1808 let previous = std::mem::replace(&mut self.clause, "table function arguments");
1809 let mut bound = Vec::new();
1810 let mut written_options = Vec::new();
1811 for argument in written {
1812 let expr = self.bind_expr(ast, argument.expr, &empty)?;
1813 if argument.alias == NONE {
1814 bound.push(expr);
1815 } else {
1816 let name = ast.string(argument.alias).to_string();
1817 let (parameter, value) = self.named_argument(called, &name, expr)?;
1818 written_options.push((parameter, value, expr));
1819 }
1820 }
1821 self.clause = previous;
1822 let options = Options::of(&written_options)?;
1823
1824 let given: Vec<LogicalType> =
1827 bound.iter().map(|&expr| self.plan.expr_type(expr).clone()).collect();
1828 let resolved = if pragma {
1829 resolve_pragma(function_name, &given)?
1830 } else {
1831 resolve_table(function_name, &given)?
1832 };
1833 let mut cast: Vec<ExprRef> = bound
1834 .iter()
1835 .zip(&resolved.arguments)
1836 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
1837 .collect::<Result<_>>()?;
1838
1839 if resolved.function.takes_a_name() {
1840 let Columns::Fixed(fields) = resolved.columns else {
1841 return Err(Error::internal("a pragma that resolved to a file"));
1842 };
1843 let [argument] = cast[..] else {
1844 return Err(Error::internal("a pragma that resolved to more than one name"));
1845 };
1846 return self.bind_pragma(ast, resolved.function, &fields, argument, alias, columns);
1847 }
1848 let mut measured = Stat::Unknown;
1851 let mut counted: Vec<(String, Stat<u64>)> = Vec::new();
1852 let mut bounded: Option<Arc<dyn Zones>> = None;
1853 let fields = match resolved.columns {
1854 Columns::Fixed(fields) => fields,
1855 columns => {
1856 let paths = self.file_paths(cast[0], resolved.function.name())?;
1861 let mut fields = match columns {
1862 Columns::Csv => csv_fields(&paths, options.given)?,
1865 _ => {
1866 let footers = parquet_footers(&paths)?;
1867 measured = footers.rows;
1868 counted = footers.distincts;
1869 bounded = footers.zones;
1870 footers.fields
1871 }
1872 };
1873 if options.all_varchar {
1874 for field in &mut fields {
1879 field.ty = LogicalType::Varchar;
1880 }
1881 }
1882 if options.binary_as_string {
1883 for field in &mut fields {
1888 if field.ty == LogicalType::Blob {
1889 field.ty = LogicalType::Varchar;
1890 }
1891 }
1892 }
1893 if options.file_row_number {
1894 if fields.iter().any(|field| field.name == FILE_ROW_NUMBER) {
1900 return Err(Error::binder(format!(
1901 "Duplicate column name \"{FILE_ROW_NUMBER}\": the file already has a \
1902 column of that name, so file_row_number cannot add one"
1903 )));
1904 }
1905 fields.push(Field::required(FILE_ROW_NUMBER.to_string(), LogicalType::BigInt));
1906 }
1907 cast = paths.iter().map(|path| self.path_constant(path)).collect();
1908 fields
1909 }
1910 };
1911 let label = if alias == NONE {
1912 resolved.function.name().to_string()
1913 } else {
1914 ast.string(alias).to_string()
1915 };
1916 let names: Vec<&str> = ast.name(columns).collect();
1917 self.table_function_source(
1918 resolved.function,
1919 &cast,
1920 &written_options,
1921 Read { fields, rows: measured, distincts: counted, zones: bounded },
1922 &label,
1923 &names,
1924 )
1925 }
1926
1927 fn bind_pragma(
1940 &mut self,
1941 ast: &Ast,
1942 function: TableFunction,
1943 fields: &[Field],
1944 argument: ExprRef,
1945 alias: ast::StrRef,
1946 columns: ast::Slice,
1947 ) -> Result<(NodeRef, Scope)> {
1948 let written = self.pragma_name(argument, function)?;
1949 let parts = identifier_parts(&written);
1950 let spelled: Vec<&str> = parts.iter().map(String::as_str).collect();
1951 let name = self.catalog.resolve(&spelled)?;
1952 let described = self.described(ast, &name)?;
1953 let mut rows = Vec::with_capacity(described.len());
1954 for (at, field) in described.iter().enumerate() {
1955 let items = if matches!(function, TableFunction::PragmaShow) {
1956 self.describing(field)
1957 } else {
1958 self.table_info(at, field)
1959 };
1960 rows.push(self.plan.add_expr_list(&items));
1961 }
1962 let rows = self.plan.add_rows(&rows);
1963 let held = self.plan.add_fields(fields);
1964 let index = self.fresh_index();
1965 let node = self.add_node(Node::Values { index, columns: held, rows });
1966 let label =
1967 if alias == NONE { function.name().to_string() } else { ast.string(alias).to_string() };
1968 let mut scope = Scope::empty();
1969 for (at, field) in fields.iter().enumerate() {
1970 scope.push(Visible {
1971 table: label.clone(),
1972 name: field.name.clone(),
1973 binding: ColumnBinding::new(index, at as u32),
1974 ty: field.ty.clone(),
1975 not_null: false,
1976 });
1977 }
1978 if !columns.is_empty() {
1979 let names: Vec<&str> = ast.name(columns).collect();
1980 scope.rename(&names, &label)?;
1981 }
1982 Ok((node, scope))
1983 }
1984
1985 fn pragma_name(&self, argument: ExprRef, function: TableFunction) -> Result<String> {
1995 let Expr::Constant(reference) = *self.plan.expr(argument) else {
1996 return Err(Error::not_implemented(format!(
1997 "{}() given a name that is not a constant",
1998 function.name()
1999 )));
2000 };
2001 match self.plan.value(reference) {
2002 Value::Varchar(name) => Ok(name.clone()),
2003 Value::Null => Ok("NULL".to_string()),
2004 other => {
2005 Err(Error::internal(format!("a pragma name bound as VARCHAR arrived as {other}")))
2006 }
2007 }
2008 }
2009
2010 fn described(&mut self, ast: &Ast, name: &QualifiedName) -> Result<Vec<Field>> {
2021 if self.catalog.entry(name)? == Entry::Table {
2022 return Ok(self.catalog.table(name)?.columns().to_vec());
2023 }
2024 let (_, scope) = self.bind_view(ast, name, NONE, ast::Slice::default())?;
2025 Ok(scope.fields())
2026 }
2027
2028 fn describing(&mut self, field: &Field) -> Vec<ExprRef> {
2030 let written = [
2031 field.name.clone(),
2032 field.ty.to_string(),
2033 if field.not_null { "NO" } else { "YES" }.to_owned(),
2034 ];
2035 let mut items: Vec<ExprRef> =
2036 written.into_iter().map(|text| self.plan.add_constant(Value::Varchar(text))).collect();
2037 for _ in 0..3 {
2038 let empty = self.plan.add_constant(Value::Null);
2039 items.push(self.cast_to(empty, &LogicalType::Varchar));
2040 }
2041 items
2042 }
2043
2044 fn table_info(&mut self, at: usize, field: &Field) -> Vec<ExprRef> {
2050 let cid = self.plan.add_constant(Value::Integer(i32::try_from(at).unwrap_or(i32::MAX)));
2051 let name = self.plan.add_constant(Value::Varchar(field.name.clone()));
2052 let ty = self.plan.add_constant(Value::Varchar(field.ty.to_string()));
2053 let not_null = self.plan.add_constant(Value::Boolean(field.not_null));
2054 let default = self.plan.add_constant(Value::Null);
2055 let default = self.cast_to(default, &LogicalType::Varchar);
2056 let key = self.plan.add_constant(Value::Boolean(false));
2057 vec![cid, name, ty, not_null, default, key]
2058 }
2059
2060 fn named_argument(
2074 &mut self,
2075 function: TableFunction,
2076 name: &str,
2077 expr: ExprRef,
2078 ) -> Result<(&'static str, Value)> {
2079 let known = function
2080 .parameters()
2081 .iter()
2082 .find(|(parameter, _)| parameter.eq_ignore_ascii_case(name));
2083 let Some((parameter, wanted)) = known else {
2084 let candidates: Vec<String> = function
2085 .parameters()
2086 .iter()
2087 .map(|(parameter, ty)| format!(" {parameter} {ty}"))
2088 .collect();
2089 return Err(Error::binder(format!(
2090 "Invalid named parameter \"{name}\" for function {}\nCandidates:\n{}\n",
2091 function.name(),
2092 candidates.join("\n")
2093 )));
2094 };
2095 let Expr::Constant(reference) = *self.plan.expr(expr) else {
2096 return Err(Error::not_implemented(format!(
2097 "the named parameter {parameter} with a value that is not a constant"
2098 )));
2099 };
2100 let value = self.plan.value(reference).clone();
2101 if value == Value::Null {
2102 return Err(Error::binder(null_parameter(function, parameter)));
2103 }
2104 let given = self.plan.expr_type(expr).clone();
2105 if given != *wanted {
2106 return Err(Error::not_implemented(format!(
2107 "the named parameter {parameter} given a {given} where a {wanted} was wanted"
2108 )));
2109 }
2110 Ok((parameter, value))
2111 }
2112
2113 fn bind_replacement_scan(
2124 &mut self,
2125 ast: &Ast,
2126 parts: &[&str],
2127 alias: ast::StrRef,
2128 columns: ast::Slice,
2129 missing: Error,
2130 ) -> Result<(NodeRef, Scope)> {
2131 let [path] = parts else { return Err(missing) };
2132 let path = *path;
2133 let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
2134 let Some(function) = Self::reader_for(extension) else {
2135 if is_file(path) {
2136 return Err(Error::binder(format!(
2141 "No extension found that is capable of reading the file \"{path}\"\n* If this \
2142 file is a supported file format you can explicitly use the reader functions, \
2143 such as read_csv, read_json or read_parquet"
2144 )));
2145 }
2146 return Err(missing);
2147 };
2148 let paths = files(path)?;
2153 let read = match function {
2154 TableFunction::ReadParquet => {
2155 let footers = parquet_footers(&paths)?;
2156 Read {
2157 fields: footers.fields,
2158 rows: footers.rows,
2159 distincts: footers.distincts,
2160 zones: footers.zones,
2161 }
2162 }
2163 _ => Read::uncounted(csv_fields(&paths, Given::default())?),
2164 };
2165 let label = if alias == NONE {
2171 if is_pattern(path) {
2172 path.to_string()
2173 } else {
2174 let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
2175 file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
2176 }
2177 } else {
2178 ast.string(alias).to_string()
2179 };
2180 let arguments: Vec<ExprRef> = paths.iter().map(|path| self.path_constant(path)).collect();
2181 let names: Vec<&str> = ast.name(columns).collect();
2182 self.table_function_source(function, &arguments, &[], read, &label, &names)
2183 }
2184
2185 fn path_constant(&mut self, path: &str) -> ExprRef {
2187 let value = self.plan.add_value(Value::Varchar(path.to_string()));
2188 self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar)
2189 }
2190
2191 fn reader_for(extension: &str) -> Option<TableFunction> {
2198 if extension.eq_ignore_ascii_case("parquet") {
2199 return Some(TableFunction::ReadParquet);
2200 }
2201 if extension.eq_ignore_ascii_case("csv") || extension.eq_ignore_ascii_case("tsv") {
2202 return Some(TableFunction::ReadCsv);
2203 }
2204 None
2205 }
2206
2207 fn table_function_source(
2217 &mut self,
2218 function: TableFunction,
2219 args: &[ExprRef],
2220 written: &[(&'static str, Value, ExprRef)],
2221 read: Read,
2222 label: &str,
2223 names: &[&str],
2224 ) -> Result<(NodeRef, Scope)> {
2225 let Read { fields, rows, distincts, zones } = read;
2226 let index = self.fresh_index();
2227 if rows.is_known() {
2232 self.plan.measure(index, rows);
2233 }
2234 for (column, distinct) in distincts {
2235 self.plan.measure_distinct(index, &column, distinct);
2236 }
2237 if let Some(zones) = zones {
2238 self.plan.set_zones(index, zones);
2239 }
2240 let mut scope = Scope::empty();
2241 for (at, field) in fields.iter().enumerate() {
2242 scope.push(Visible {
2243 table: label.to_string(),
2244 name: field.name.clone(),
2245 binding: ColumnBinding::new(index, at as u32),
2246 ty: field.ty.clone(),
2247 not_null: false,
2250 });
2251 }
2252 if !names.is_empty() {
2253 scope.rename(names, label)?;
2254 }
2255 let function = self.plan.intern(function.name());
2256 let args = self.plan.add_expr_list(args);
2257 let named: Vec<u32> =
2258 written.iter().map(|(parameter, _, _)| self.plan.intern(parameter)).collect();
2259 let settings: Vec<ExprRef> = written.iter().map(|(_, _, expr)| *expr).collect();
2260 let options = self.plan.add_name_list(&named);
2261 let settings = self.plan.add_expr_list(&settings);
2262 let columns = self.plan.add_fields(&fields);
2263 let node = self.add_node(Node::TableFunction {
2264 index,
2265 function,
2266 args,
2267 options,
2268 settings,
2269 columns,
2270 });
2271 Ok((node, scope))
2272 }
2273
2274 fn file_paths(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
2281 let mut paths = Vec::new();
2282 for pattern in self.file_patterns(expr, name)? {
2283 paths.extend(files(&pattern)?);
2284 }
2285 Ok(paths)
2286 }
2287
2288 fn file_patterns(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
2300 let Expr::Constant(reference) = *self.plan.expr(expr) else {
2301 return Err(Error::not_implemented(
2302 "a table function file name that is not a constant",
2303 ));
2304 };
2305 match self.plan.value(reference) {
2306 Value::Varchar(path) => Ok(vec![path.clone()]),
2307 Value::Null => Err(Error::parser(format!("{name} cannot take NULL list as parameter"))),
2309 Value::List { values, .. } => values
2310 .iter()
2311 .map(|value| match value {
2312 Value::Varchar(path) => Ok(path.clone()),
2313 _ => Err(Error::parser(format!(
2314 "{name} reader cannot take NULL input as parameter"
2315 ))),
2316 })
2317 .collect(),
2318 other => {
2319 Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
2320 }
2321 }
2322 }
2323
2324 fn side_of(
2342 &self,
2343 pending: &PendingSubquery,
2344 left_tables: &[u32],
2345 right_tables: &[u32],
2346 ) -> Option<Side> {
2347 let mut needs_left = false;
2348 let mut needs_right = false;
2349 let mut note = |binding: ColumnBinding| {
2350 needs_left |= left_tables.contains(&binding.table);
2351 needs_right |= right_tables.contains(&binding.table);
2352 };
2353 for &binding in &pending.reads {
2354 note(binding);
2355 }
2356 for &condition in &pending.conditions {
2361 self.plan.read_columns(condition, &mut |_, binding| note(binding));
2362 }
2363 match (needs_left, needs_right) {
2364 (true, true) => None,
2365 (_, true) => Some(Side::Right),
2366 _ => Some(Side::Left),
2367 }
2368 }
2369
2370 #[allow(clippy::too_many_arguments)]
2391 fn bind_pair_dependent_join(
2392 &mut self,
2393 kind: ast::JoinKind,
2394 independent: bool,
2395 left: NodeRef,
2396 right: NodeRef,
2397 pair: Vec<PendingSubquery>,
2398 conditions: Vec<ExprRef>,
2399 scope: Scope,
2400 ) -> Result<(NodeRef, Scope)> {
2401 if kind != ast::JoinKind::Inner {
2402 return Err(Error::not_implemented(
2403 "a subquery that reads both sides of that join, written in the condition of a join \
2404 that is not an inner join"
2405 .to_string(),
2406 ));
2407 }
2408 if !independent {
2411 return Err(Error::not_implemented(
2412 "a subquery that reads both sides of that join, written in the condition of a join \
2413 whose right side is lateral"
2414 .to_string(),
2415 ));
2416 }
2417 let mut node = self.add_node(Node::CrossProduct { left, right });
2418 for pending in pair {
2419 node = self.attach_subquery(node, pending);
2420 }
2421 let mut conditions = conditions.into_iter();
2425 let mut predicate = conditions.next().expect("a join condition was bound");
2426 for next in conditions {
2427 let children = self.plan.add_expr_list(&[predicate, next]);
2428 let conjunction = Expr::Conjunction { op: ConjunctionOp::And, children };
2429 predicate = self.plan.add_expr(conjunction, LogicalType::Boolean);
2430 }
2431 let node = self.add_node(Node::Filter { input: node, predicate });
2432 Ok((node, scope))
2433 }
2434
2435 #[allow(clippy::too_many_arguments)]
2436 fn bind_join(
2437 &mut self,
2438 ast: &Ast,
2439 left: ast::SourceRef,
2440 right: ast::SourceRef,
2441 kind: ast::JoinKind,
2442 natural: bool,
2443 on: ast::ExprRef,
2444 using: ast::Slice,
2445 ) -> Result<(NodeRef, Scope)> {
2446 let (left_node, left_scope) = self.bind_source(ast, left)?;
2447 let (right_node, right_scope, correlated) = self.bind_lateral(ast, right, &left_scope)?;
2448 if !correlated.is_empty()
2452 && !matches!(kind, ast::JoinKind::Inner | ast::JoinKind::Cross | ast::JoinKind::Left)
2453 {
2454 return Err(Error::binder(
2455 "The combining JOIN type must be INNER or LEFT for a LATERAL reference",
2456 ));
2457 }
2458 let split = left_scope.len();
2459 let left_tables: Vec<u32> =
2465 left_scope.columns.iter().map(|column| column.binding.table).collect();
2466 let right_tables: Vec<u32> =
2467 right_scope.columns.iter().map(|column| column.binding.table).collect();
2468 let mut scope = left_scope.concat(right_scope);
2469
2470 let merged: Vec<String> = if natural {
2473 let mut names = Vec::new();
2474 for (at, column) in scope.columns.iter().enumerate().take(split) {
2475 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
2476 && !names.iter().any(|held: &String| same_name(held, &column.name))
2477 {
2478 let _ = at;
2479 names.push(column.name.clone());
2480 }
2481 }
2482 names
2483 } else {
2484 let mut names: Vec<String> = Vec::new();
2490 for name in ast.name(using) {
2491 if !names.iter().any(|held| same_name(held, name)) {
2492 names.push(name.to_string());
2493 }
2494 }
2495 names
2496 };
2497
2498 let mut conditions = Vec::new();
2499 let mut dropped = Vec::new();
2500 for name in &merged {
2501 let left_at = scope.columns[..split]
2502 .iter()
2503 .position(|column| same_name(&column.name, name))
2504 .ok_or_else(|| {
2505 Error::binder(format!(
2506 "column \"{name}\" specified in USING clause does not exist in left table"
2507 ))
2508 })?;
2509 let right_at = scope.columns[split..]
2510 .iter()
2511 .position(|column| same_name(&column.name, name))
2512 .map(|at| at + split)
2513 .ok_or_else(|| {
2514 Error::binder(format!(
2515 "column \"{name}\" specified in USING clause does not exist in right table"
2516 ))
2517 })?;
2518 let left_column = &scope.columns[left_at];
2519 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
2520 let right_column = &scope.columns[right_at];
2521 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
2522 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
2523 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
2524 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
2525 dropped.push(right_at);
2526 }
2527 dropped.sort_unstable();
2530 for at in dropped.into_iter().rev() {
2531 scope.remove(at);
2532 }
2533
2534 let mut left_node = left_node;
2535 let mut right_node = right_node;
2536 let mut pair = Vec::new();
2537 if on != NONE {
2538 if !merged.is_empty() {
2539 return Err(Error::binder("a join cannot have both ON and USING"));
2540 }
2541 self.clause = "JOIN condition";
2542 let waiting = self.scalar_subqueries.len();
2543 let predicate = self.bind_expr(ast, on, &scope)?;
2544 conditions.push(self.as_boolean(predicate, "JOIN")?);
2545 for pending in self.scalar_subqueries.split_off(waiting) {
2546 match self.side_of(&pending, &left_tables, &right_tables) {
2547 Some(Side::Right) => right_node = self.attach_subquery(right_node, pending),
2548 Some(Side::Left) => left_node = self.attach_subquery(left_node, pending),
2549 None => pair.push(pending),
2550 }
2551 }
2552 }
2553
2554 if kind == ast::JoinKind::Cross && !conditions.is_empty() {
2555 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
2556 }
2557 if !pair.is_empty() {
2558 return self.bind_pair_dependent_join(
2559 kind,
2560 correlated.is_empty(),
2561 left_node,
2562 right_node,
2563 pair,
2564 conditions,
2565 scope,
2566 );
2567 }
2568 if correlated.is_empty()
2572 && conditions.is_empty()
2573 && matches!(kind, ast::JoinKind::Cross | ast::JoinKind::Inner)
2574 {
2575 let node = self.add_node(Node::CrossProduct { left: left_node, right: right_node });
2576 return Ok((node, scope));
2577 }
2578 if matches!(kind, ast::JoinKind::Semi | ast::JoinKind::Anti) {
2587 scope.truncate(split);
2588 }
2589 let kind = match kind {
2590 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
2591 ast::JoinKind::Left => JoinKind::Left,
2592 ast::JoinKind::Right => JoinKind::Right,
2593 ast::JoinKind::Full => JoinKind::Full,
2594 ast::JoinKind::Semi => JoinKind::Semi,
2595 ast::JoinKind::Anti => JoinKind::Anti,
2596 ast::JoinKind::Positional => JoinKind::Positional,
2597 };
2598 let conditions = self.plan.add_expr_list(&conditions);
2599 let node = if correlated.is_empty() {
2600 self.add_node(Node::Join {
2601 left: left_node,
2602 right: right_node,
2603 kind,
2604 conditions,
2605 build: BuildSide::default(),
2606 })
2607 } else {
2608 self.add_node(Node::DependentJoin {
2609 left: left_node,
2610 right: right_node,
2611 kind,
2612 conditions,
2613 })
2614 };
2615 Ok((node, scope))
2616 }
2617
2618 fn bind_filter(
2626 &mut self,
2627 ast: &Ast,
2628 filter: ast::ExprRef,
2629 scope: &Scope,
2630 ) -> Result<Option<ExprRef>> {
2631 if filter == NONE {
2632 return Ok(None);
2633 }
2634 let bound = self.bind_expr(ast, filter, scope)?;
2635 Ok(Some(self.checked_cast_to(bound, &LogicalType::Boolean, false)?))
2636 }
2637
2638 pub(crate) fn bind_aggregate(
2640 &mut self,
2641 ast: &Ast,
2642 name: &str,
2643 args: &[ast::ExprRef],
2644 distinct: bool,
2645 filter: ast::ExprRef,
2646 scope: &Scope,
2647 ) -> Result<ExprRef> {
2648 if self.in_filter {
2649 return Err(Error::binder("aggregate functions are not allowed in FILTER"));
2650 }
2651 if self.in_aggregate {
2652 return Err(Error::binder(format!(
2653 "aggregate function calls cannot be nested, and {name}() is inside one"
2654 )));
2655 }
2656 if self.aggregation.is_none() {
2657 return Err(Error::binder(format!(
2658 "aggregate function calls cannot be used in the {}",
2659 self.clause
2660 )));
2661 }
2662 self.in_aggregate = true;
2667 self.in_filter = true;
2668 let filter = self.bind_filter(ast, filter, scope);
2669 self.in_filter = false;
2670 self.in_aggregate = false;
2671 let filter = filter?;
2672
2673 self.in_aggregate = true;
2674 let mut bound = Vec::with_capacity(args.len());
2675 let mut failure = None;
2676 for &arg in args {
2677 match self.bind_expr(ast, arg, scope) {
2678 Ok(expr) => bound.push(expr),
2679 Err(error) => {
2680 failure = Some(error);
2681 break;
2682 }
2683 }
2684 }
2685 self.in_aggregate = false;
2686 if let Some(error) = failure {
2687 return Err(error);
2688 }
2689
2690 let types: Vec<LogicalType> =
2691 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
2692 let resolved = resolve(name, &types)?;
2693 let mut cast = Vec::with_capacity(bound.len());
2694 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
2695 cast.push(self.checked_cast_to(*arg, wanted, false)?);
2696 }
2697 let args = self.plan.add_expr_list(&cast);
2698 let name = self.plan.intern(resolved.name);
2699 let ty = resolved.returns;
2700 let call = self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter }, ty.clone());
2701
2702 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
2705 let existing = existing.unwrap_or_default();
2706 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
2707 Some(at) => at,
2708 None => {
2709 let aggregation = self.aggregation.as_mut().expect("checked above");
2710 aggregation.aggregates.push(call);
2711 aggregation.aggregates.len() - 1
2712 }
2713 };
2714 let aggregation = self.aggregation.as_ref().expect("checked above");
2715 let (index, groups) = (aggregation.index, aggregation.groups.len());
2716 Ok(self.column(index, groups + at, ty))
2717 }
2718
2719 pub(crate) fn bind_window(
2727 &mut self,
2728 ast: &Ast,
2729 written: &WindowCall<'_>,
2730 scope: &Scope,
2731 ) -> Result<ExprRef> {
2732 let WindowCall { name, args, distinct, filter, ignore_nulls, spec } = *written;
2733 if self.in_aggregate {
2734 return Err(Error::binder(
2735 "aggregate function calls cannot contain window function calls",
2736 ));
2737 }
2738 if self.in_window {
2739 return Err(Error::binder("window function calls cannot be nested"));
2740 }
2741 let clause = if self.clause == "JOIN condition" { "WHERE clause" } else { self.clause };
2745 if clause != "SELECT clause" && clause != "ORDER BY clause" {
2746 return Err(Error::binder(format!("{clause} cannot contain window functions!")));
2747 }
2748
2749 let starred = args.iter().any(|&arg| {
2753 matches!(ast.expr(arg), ast::Expr::Star { qualifier, replacements }
2754 if qualifier.is_empty() && replacements.is_empty())
2755 });
2756 let (name, args): (&str, &[ast::ExprRef]) = if starred {
2757 if !same_name(name, "count") || args.len() != 1 {
2758 return Err(Error::binder(format!("* is not allowed in {name}()")));
2759 }
2760 ("count_star", &[])
2761 } else if same_name(name, "count") && args.is_empty() {
2762 ("count_star", &[])
2765 } else {
2766 (name, args)
2767 };
2768
2769 let held = ast.window(spec);
2770 self.in_window = true;
2771 let parts = self.window_parts(ast, args, held, scope);
2772 let filter = if parts.is_ok() { self.bind_filter(ast, filter, scope) } else { Ok(None) };
2777 self.in_window = false;
2778 let parts = parts?;
2779 let filter = filter?;
2780 let offsets = [parts.frame.start, parts.frame.end]
2783 .iter()
2784 .any(|end| matches!(end, WindowBound::Preceding(_) | WindowBound::Following(_)));
2785 if parts.frame.unit == WindowUnit::Range && offsets && parts.order.len() != 1 {
2786 return Err(Error::binder("RANGE frames must have only one ORDER BY expression"));
2787 }
2788
2789 let types: Vec<LogicalType> =
2790 parts.args.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
2791 let resolved = window_signature(name, &types)?;
2792 if resolved.name == "fill" {
2795 let keys: Vec<LogicalType> =
2796 parts.order.iter().map(|key| self.plan.expr_type(key.expr).clone()).collect();
2797 refuse_fill(&types[0], &keys, distinct, ignore_nulls)?;
2798 }
2799 if distinct && kind_of(resolved.name) == Some(FunctionKind::Window) {
2803 return Err(Error::binder(format!(
2804 "DISTINCT is not implemented for the window function \"\"{name}\"\""
2805 )));
2806 }
2807 if filter.is_some() && kind_of(resolved.name) == Some(FunctionKind::Window) {
2810 return Err(Error::binder(format!(
2811 "FILTER is not implemented for the window function \"\"{name}\"\""
2812 )));
2813 }
2814 let mut cast = Vec::with_capacity(parts.args.len());
2815 for (arg, wanted) in parts.args.iter().zip(&resolved.arguments) {
2816 cast.push(self.checked_cast_to(*arg, wanted, false)?);
2817 }
2818 let args = self.plan.add_expr_list(&cast);
2819 let name = self.plan.intern(resolved.name);
2820 let ty = resolved.returns;
2821 let call = self
2822 .plan
2823 .add_expr(Expr::Window { name, args, distinct, filter, ignore_nulls }, ty.clone());
2824
2825 let at = self.window_run(parts.partition, parts.order, parts.frame, call);
2826 let index = self.windows.last().expect("the run was just filed").index;
2827 Ok(self.column(index, at, ty))
2828 }
2829
2830 fn window_run(
2837 &mut self,
2838 partition: Vec<ExprRef>,
2839 order: Vec<SortKey>,
2840 frame: WindowFrame,
2841 call: ExprRef,
2842 ) -> usize {
2843 let matches = self.windows.last().is_some_and(|run| {
2844 run.frame == frame
2845 && run.partition.len() == partition.len()
2846 && run.order.len() == order.len()
2847 && run.partition.iter().zip(&partition).all(|(&l, &r)| self.same_expr(l, r))
2848 && run.order.iter().zip(&order).all(|(l, r)| {
2849 l.descending == r.descending
2850 && l.nulls_first == r.nulls_first
2851 && self.same_expr(l.expr, r.expr)
2852 })
2853 });
2854 if !matches {
2855 let index = self.fresh_index();
2856 self.windows.push(WindowRun { index, partition, order, frame, calls: Vec::new() });
2857 }
2858 let calls = self.windows.last().expect("a run is open").calls.clone();
2861 if let Some(at) = calls.iter().position(|&held| self.same_expr(held, call)) {
2862 return at;
2863 }
2864 let run = self.windows.last_mut().expect("a run is open");
2865 run.calls.push(call);
2866 run.calls.len() - 1
2867 }
2868
2869 fn window_parts(
2875 &mut self,
2876 ast: &Ast,
2877 args: &[ast::ExprRef],
2878 held: ast::WindowSpec,
2879 scope: &Scope,
2880 ) -> Result<WindowParts> {
2881 let mut bound = Vec::with_capacity(args.len());
2882 for &arg in args {
2883 let expr = self.bind_expr(ast, arg, scope)?;
2884 bound.push(self.over_aggregate(expr, scope)?);
2885 }
2886 let mut partition = Vec::new();
2887 for &key in ast.expr_list(held.partition) {
2888 let expr = self.bind_expr(ast, key, scope)?;
2889 partition.push(self.over_aggregate(expr, scope)?);
2890 }
2891 let mut order = Vec::new();
2892 for item in ast.order_list(held.order).to_vec() {
2893 let expr = self.bind_expr(ast, item.expr, scope)?;
2894 let expr = self.over_aggregate(expr, scope)?;
2895 order.push(self.sort_key(expr, item));
2896 }
2897 let frame = WindowFrame {
2898 unit: match held.unit {
2899 ast::WindowUnit::Rows => WindowUnit::Rows,
2900 ast::WindowUnit::Range => WindowUnit::Range,
2901 ast::WindowUnit::Groups => WindowUnit::Groups,
2902 },
2903 start: self.window_bound(ast, held.start, scope)?,
2904 end: self.window_bound(ast, held.end, scope)?,
2905 exclude: match held.exclude {
2906 ast::WindowExclude::NoOthers => WindowExclude::NoOthers,
2907 ast::WindowExclude::CurrentRow => WindowExclude::CurrentRow,
2908 ast::WindowExclude::Group => WindowExclude::Group,
2909 ast::WindowExclude::Ties => WindowExclude::Ties,
2910 },
2911 };
2912 Ok(WindowParts { args: bound, partition, order, frame })
2913 }
2914
2915 fn window_bound(
2917 &mut self,
2918 ast: &Ast,
2919 bound: ast::WindowBound,
2920 scope: &Scope,
2921 ) -> Result<WindowBound> {
2922 let offset = |binder: &mut Self, written| {
2923 let expr = binder.bind_expr(ast, written, scope)?;
2924 binder.over_aggregate(expr, scope)
2925 };
2926 Ok(match bound {
2927 ast::WindowBound::UnboundedPreceding => WindowBound::UnboundedPreceding,
2928 ast::WindowBound::CurrentRow => WindowBound::CurrentRow,
2929 ast::WindowBound::UnboundedFollowing => WindowBound::UnboundedFollowing,
2930 ast::WindowBound::Preceding(written) => WindowBound::Preceding(offset(self, written)?),
2931 ast::WindowBound::Following(written) => WindowBound::Following(offset(self, written)?),
2932 })
2933 }
2934
2935 fn is_pending_subquery(&self, binding: ColumnBinding) -> bool {
2937 self.scalar_subqueries.iter().any(|pending| pending.index == binding.table)
2938 }
2939
2940 fn is_window_output(&self, binding: ColumnBinding) -> bool {
2942 self.windows.iter().any(|run| run.index == binding.table)
2943 }
2944
2945 fn is_correlation(&self, binding: ColumnBinding) -> bool {
2951 self.correlations.last().is_some_and(|frame| frame.contains(&binding))
2952 }
2953
2954 fn name_of(&self, binding: ColumnBinding, scope: &Scope) -> String {
2960 std::iter::once(scope)
2961 .chain(self.outer_scopes.iter().rev())
2962 .flat_map(|visible| visible.columns.iter())
2963 .find(|column| column.binding == binding)
2964 .map_or_else(|| "a column".to_string(), |column| format!("\"{}\"", column.name))
2965 }
2966
2967 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
2973 let Some(aggregation) = self.aggregation.as_ref() else {
2974 return Ok(expr);
2975 };
2976 let index = aggregation.index;
2977 let groups = aggregation.groups.clone();
2978 for (at, group) in groups.iter().enumerate() {
2979 if self.same_expr(expr, *group) {
2980 let ty = self.plan.expr_type(*group).clone();
2981 return Ok(self.column(index, at, ty));
2982 }
2983 }
2984 let ty = self.plan.expr_type(expr).clone();
2985 match self.plan.expr(expr).clone() {
2986 Expr::Column(binding) if binding.table == index => Ok(expr),
2987 Expr::Column(binding) if self.is_window_output(binding) => Ok(expr),
2992 Expr::Column(binding) if self.joined_above.contains(&binding.table) => Ok(expr),
2997 Expr::Column(binding) if self.is_correlation(binding) => Ok(expr),
3003 Expr::Column(binding) if self.is_pending_subquery(binding) => Err(Error::binder(
3012 "a correlated subquery over a grouped query is not supported here yet",
3013 )),
3014 Expr::Column(binding) => {
3015 let name = self.name_of(binding, scope);
3016 Err(Error::binder(format!(
3017 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
3018 )))
3019 }
3020 Expr::Constant(_) | Expr::Aggregate { .. } | Expr::Window { .. } => Ok(expr),
3021 Expr::Cast { input, try_cast } => {
3022 let input = self.over_aggregate(input, scope)?;
3023 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
3024 }
3025 Expr::Compare { op, left, right } => {
3026 let left = self.over_aggregate(left, scope)?;
3027 let right = self.over_aggregate(right, scope)?;
3028 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
3029 }
3030 Expr::Conjunction { op, children } => {
3031 let written = self.plan.expr_list(children).to_vec();
3032 let mut rewritten = Vec::with_capacity(written.len());
3033 for child in written {
3034 rewritten.push(self.over_aggregate(child, scope)?);
3035 }
3036 let children = self.plan.add_expr_list(&rewritten);
3037 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
3038 }
3039 Expr::Function { name, args } => {
3040 let written = self.plan.expr_list(args).to_vec();
3041 let mut rewritten = Vec::with_capacity(written.len());
3042 for arg in written {
3043 rewritten.push(self.over_aggregate(arg, scope)?);
3044 }
3045 let args = self.plan.add_expr_list(&rewritten);
3046 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
3047 }
3048 Expr::Case { arms, otherwise } => {
3049 let written = self.plan.arm_list(arms).to_vec();
3050 let mut rewritten = Vec::with_capacity(written.len());
3051 for arm in written {
3052 let when = self.over_aggregate(arm.when, scope)?;
3053 let then = self.over_aggregate(arm.then, scope)?;
3054 rewritten.push(rudb_plan::Arm { when, then });
3055 }
3056 let otherwise = match otherwise {
3057 Some(expr) => Some(self.over_aggregate(expr, scope)?),
3058 None => None,
3059 };
3060 let arms = self.plan.add_arms(&rewritten);
3061 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
3062 }
3063 }
3064 }
3065
3066 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
3068 same_expr(&self.plan, left, right)
3069 }
3070}
3071
3072#[derive(Debug, Default)]
3082struct Options {
3083 binary_as_string: bool,
3086 all_varchar: bool,
3088 file_row_number: bool,
3093 given: Given,
3095}
3096
3097impl Options {
3098 fn of(written: &[(&'static str, Value, ExprRef)]) -> Result<Self> {
3105 let mut options = Self::default();
3106 for (parameter, value, _) in written {
3107 match (*parameter, value) {
3108 ("binary_as_string", Value::Boolean(on)) => options.binary_as_string = *on,
3109 ("all_varchar", Value::Boolean(on)) => options.all_varchar = *on,
3110 ("file_row_number", Value::Boolean(on)) => options.file_row_number = *on,
3111 _ => {}
3112 }
3113 }
3114 let named: Vec<(&str, Value)> =
3115 written.iter().map(|(parameter, value, _)| (*parameter, value.clone())).collect();
3116 options.given = csv_given(&named)?;
3117 Ok(options)
3118 }
3119}
3120
3121#[derive(Clone, Copy)]
3123struct Operator {
3124 op: SetOp,
3126 quantifier: Quantifier,
3128 by_name: bool,
3130}
3131
3132struct Merged {
3134 name: String,
3136 ty: LogicalType,
3138 left: Option<usize>,
3140 right: Option<usize>,
3142}
3143
3144fn match_by_position(left: &Scope, right: &Scope) -> Result<Vec<Merged>> {
3148 if left.len() != right.len() {
3149 return Err(Error::binder(format!(
3150 "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
3151 left.len(),
3152 right.len()
3153 )));
3154 }
3155 let mut merged = Vec::with_capacity(left.len());
3156 for (at, (held, other)) in left.columns.iter().zip(&right.columns).enumerate() {
3157 merged.push(Merged {
3158 name: held.name.clone(),
3159 ty: meet(&held.ty, &other.ty)?,
3160 left: Some(at),
3161 right: Some(at),
3162 });
3163 }
3164 Ok(merged)
3165}
3166
3167fn match_by_name(left: &Scope, right: &Scope) -> Result<Vec<Merged>> {
3175 named_once(left)?;
3176 named_once(right)?;
3177 let mut merged = Vec::with_capacity(left.len() + right.len());
3178 for (at, held) in left.columns.iter().enumerate() {
3179 let other = right.columns.iter().position(|column| same_name(&column.name, &held.name));
3180 let ty = match other {
3181 Some(other) => meet(&held.ty, &right.columns[other].ty)?,
3182 None => held.ty.clone(),
3183 };
3184 merged.push(Merged { name: held.name.clone(), ty, left: Some(at), right: other });
3185 }
3186 for (at, held) in right.columns.iter().enumerate() {
3187 if left.columns.iter().any(|column| same_name(&column.name, &held.name)) {
3188 continue;
3189 }
3190 merged.push(Merged {
3191 name: held.name.clone(),
3192 ty: held.ty.clone(),
3193 left: None,
3194 right: Some(at),
3195 });
3196 }
3197 Ok(merged)
3198}
3199
3200fn named_once(scope: &Scope) -> Result<()> {
3206 for (at, held) in scope.columns.iter().enumerate() {
3207 if scope.columns[..at].iter().any(|column| same_name(&column.name, &held.name)) {
3208 return Err(Error::binder(format!(
3209 "UNION (ALL) BY NAME operation doesn't support duplicate names in the SELECT list - the name \"\"{}\"\" occurs multiple times",
3210 held.name
3211 )));
3212 }
3213 }
3214 Ok(())
3215}
3216
3217fn meet(left: &LogicalType, right: &LogicalType) -> Result<LogicalType> {
3219 left.promote(right).ok_or_else(|| {
3220 Error::binder(format!(
3221 "Cannot combine a column of type {left} with a column of type {right} in a set operation"
3222 ))
3223 })
3224}
3225
3226fn null_parameter(function: TableFunction, parameter: &str) -> String {
3235 match parameter {
3236 "header" => format!("\"{parameter}\" expects a non-null boolean value (e.g. TRUE or 1)"),
3237 "all_varchar" => format!("{} \"{parameter}\" cannot be NULL", function.name()),
3238 _ => format!("Cannot use NULL as argument to \"{parameter}\""),
3239 }
3240}
3241
3242fn missing_replacement(name: &str, input: &Scope) -> Error {
3247 Error::binder(format!(
3248 "Column \"{name}\" in REPLACE list not found in FROM clause{}",
3249 input.candidates()
3250 ))
3251}
3252
3253fn subtractable(ty: &LogicalType, ordering: bool) -> bool {
3262 if ty.is_numeric() {
3263 return true;
3264 }
3265 match ty {
3266 LogicalType::Date
3267 | LogicalType::Time
3268 | LogicalType::Timestamp
3269 | LogicalType::TimestampS
3270 | LogicalType::TimestampMs
3271 | LogicalType::TimestampNs
3272 | LogicalType::TimestampTz => true,
3273 LogicalType::TimeTz => ordering,
3274 _ => false,
3275 }
3276}
3277
3278fn refuse_fill(
3287 argument: &LogicalType,
3288 order: &[LogicalType],
3289 distinct: bool,
3290 ignore_nulls: bool,
3291) -> Result<()> {
3292 if !subtractable(argument, false) {
3293 return Err(Error::binder("FILL argument must support subtraction"));
3294 }
3295 let [key] = order else {
3296 return Err(Error::binder("FILL functions must have only one ORDER BY expression"));
3297 };
3298 if !subtractable(key, true) {
3299 return Err(Error::binder("FILL ordering must support subtraction"));
3300 }
3301 if distinct {
3302 return Err(Error::binder(
3303 "DISTINCT is not implemented for the window function \"\"fill\"\"",
3304 ));
3305 }
3306 if ignore_nulls {
3307 return Err(Error::binder(
3308 "RESPECT/IGNORE NULLS is not supported for the window function \"fill\"",
3309 ));
3310 }
3311 Ok(())
3312}
3313
3314fn window_signature(name: &str, types: &[LogicalType]) -> Result<Resolved> {
3321 match kind_of(name) {
3322 Some(FunctionKind::Aggregate | FunctionKind::Window) => resolve(name, types),
3323 Some(FunctionKind::Scalar) => {
3324 Err(Error::catalog(format!("{name} is not an aggregate function")))
3325 }
3326 None => Err(Error::catalog(format!("Aggregate Function with name {name} does not exist!"))),
3327 }
3328}
3329
3330fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
3332 if left == right {
3333 return true;
3334 }
3335 if plan.expr_type(left) != plan.expr_type(right) {
3336 return false;
3337 }
3338 let lists = |left, right| {
3339 let left: &[ExprRef] = plan.expr_list(left);
3340 let right: &[ExprRef] = plan.expr_list(right);
3341 left.len() == right.len()
3342 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
3343 };
3344 match (plan.expr(left), plan.expr(right)) {
3345 (Expr::Column(left), Expr::Column(right)) => left == right,
3346 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
3347 (
3348 Expr::Cast { input: left, try_cast: left_try },
3349 Expr::Cast { input: right, try_cast: right_try },
3350 ) => left_try == right_try && same_expr(plan, *left, *right),
3351 (
3352 Expr::Compare { op: left_op, left: left_a, right: left_b },
3353 Expr::Compare { op: right_op, left: right_a, right: right_b },
3354 ) => {
3355 left_op == right_op
3356 && same_expr(plan, *left_a, *right_a)
3357 && same_expr(plan, *left_b, *right_b)
3358 }
3359 (
3360 Expr::Conjunction { op: left_op, children: left_children },
3361 Expr::Conjunction { op: right_op, children: right_children },
3362 ) => left_op == right_op && lists(*left_children, *right_children),
3363 (
3364 Expr::Function { name: left_name, args: left_args },
3365 Expr::Function { name: right_name, args: right_args },
3366 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
3367 (
3368 Expr::Aggregate {
3369 name: left_name,
3370 args: left_args,
3371 distinct: left_distinct,
3372 filter: left_filter,
3373 },
3374 Expr::Aggregate {
3375 name: right_name,
3376 args: right_args,
3377 distinct: right_distinct,
3378 filter: right_filter,
3379 },
3380 ) => {
3381 plan.string(*left_name) == plan.string(*right_name)
3382 && left_distinct == right_distinct
3383 && match (left_filter, right_filter) {
3384 (None, None) => true,
3385 (Some(left), Some(right)) => same_expr(plan, *left, *right),
3386 _ => false,
3387 }
3388 && lists(*left_args, *right_args)
3389 }
3390 (
3394 Expr::Window {
3395 name: left_name,
3396 args: left_args,
3397 distinct: left_distinct,
3398 filter: left_filter,
3399 ignore_nulls: left_nulls,
3400 },
3401 Expr::Window {
3402 name: right_name,
3403 args: right_args,
3404 distinct: right_distinct,
3405 filter: right_filter,
3406 ignore_nulls: right_nulls,
3407 },
3408 ) => {
3409 plan.string(*left_name) == plan.string(*right_name)
3410 && left_distinct == right_distinct
3411 && left_nulls == right_nulls
3412 && match (left_filter, right_filter) {
3413 (None, None) => true,
3414 (Some(left), Some(right)) => same_expr(plan, *left, *right),
3415 _ => false,
3416 }
3417 && lists(*left_args, *right_args)
3418 }
3419 (
3420 Expr::Case { arms: left_arms, otherwise: left_otherwise },
3421 Expr::Case { arms: right_arms, otherwise: right_otherwise },
3422 ) => {
3423 let left_arms = plan.arm_list(*left_arms);
3424 let right_arms = plan.arm_list(*right_arms);
3425 left_arms.len() == right_arms.len()
3426 && left_arms.iter().zip(right_arms).all(|(left, right)| {
3427 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
3428 })
3429 && match (left_otherwise, right_otherwise) {
3430 (None, None) => true,
3431 (Some(left), Some(right)) => same_expr(plan, *left, *right),
3432 _ => false,
3433 }
3434 }
3435 _ => false,
3436 }
3437}