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, row_count};
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 Bound, 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) order: ast::Slice,
148 pub(crate) spec: ast::WindowRef,
150}
151
152struct WindowParts {
154 args: Vec<ExprRef>,
156 partition: Vec<ExprRef>,
158 order: Vec<SortKey>,
160 inner: Vec<SortKey>,
163 frame: WindowFrame,
165}
166
167#[derive(Debug)]
174struct Read {
175 fields: Vec<Field>,
177 rows: Stat<u64>,
179 distincts: Vec<(String, Stat<u64>)>,
181 zones: Option<Arc<dyn Zones>>,
183}
184
185impl Read {
186 fn uncounted(fields: Vec<Field>) -> Self {
188 Self { fields, rows: Stat::Unknown, distincts: Vec::new(), zones: None }
189 }
190}
191
192#[derive(Debug)]
194struct Materialized {
195 written: u32,
197 cte: u32,
199 name: String,
201 fields: Vec<Field>,
203}
204
205#[derive(Debug)]
206pub(crate) struct PendingSubquery {
207 pub(crate) node: NodeRef,
208 pub(crate) kind: JoinKind,
209 pub(crate) conditions: Vec<ExprRef>,
210 pub(crate) dependent: bool,
211 pub(crate) reads: Vec<ColumnBinding>,
217 pub(crate) index: u32,
223 pub(crate) inside_aggregate: bool,
230}
231
232#[derive(Debug, Clone, Copy, PartialEq, Eq)]
234enum Side {
235 Left,
236 Right,
237}
238
239#[derive(Debug)]
241pub(crate) struct Binder<'a> {
242 catalog: &'a Catalog,
243 pub(crate) parameters: &'a Parameters,
245 pub(crate) session: &'a Session,
247 pub(crate) semantics: Semantics,
249 plan: Plan,
250 next_index: u32,
251 pub(crate) current_span: Span,
253 pub(crate) aggregation: Option<Aggregation>,
255 pub(crate) in_aggregate: bool,
257 pub(crate) in_filter: bool,
259 pub(crate) windows: Vec<WindowRun>,
261 pub(crate) in_window: bool,
263 pub(crate) scalar_subqueries: Vec<PendingSubquery>,
265 pub(crate) joined_above: Vec<u32>,
271 pub(crate) outer_scopes: Vec<Scope>,
272 pub(crate) lateral_scopes: Vec<usize>,
279 pub(crate) correlations: Vec<Vec<ColumnBinding>>,
280 pub(crate) clause: &'static str,
282 expanding: Vec<String>,
284 materialized: Vec<Materialized>,
290 next_cte: u32,
292 started: Option<i64>,
294}
295
296impl<'a> Binder<'a> {
297 pub(crate) fn with(
298 catalog: &'a Catalog,
299 parameters: &'a Parameters,
300 session: &'a Session,
301 ) -> Self {
302 Self {
303 catalog,
304 parameters,
305 session,
306 semantics: session.semantics(),
307 plan: Plan::new(),
308 next_index: 0,
309 current_span: Span::new(0, 0),
310 aggregation: None,
311 in_aggregate: false,
312 in_filter: false,
313 windows: Vec::new(),
314 in_window: false,
315 scalar_subqueries: Vec::new(),
316 joined_above: Vec::new(),
317 outer_scopes: Vec::new(),
318 lateral_scopes: Vec::new(),
319 correlations: Vec::new(),
320 clause: "SELECT clause",
321 expanding: Vec::new(),
322 materialized: Vec::new(),
323 next_cte: 0,
324 started: None,
325 }
326 }
327
328 pub(crate) fn catalog(&self) -> &Catalog {
329 self.catalog
330 }
331
332 pub(crate) fn instant(&mut self) -> i64 {
339 *self.started.get_or_insert_with(crate::context::micros_now)
340 }
341
342 pub(crate) fn plan(&self) -> &Plan {
343 &self.plan
344 }
345
346 pub(crate) fn plan_mut(&mut self) -> &mut Plan {
347 &mut self.plan
348 }
349
350 pub(crate) fn add_expr(&mut self, expr: Expr, ty: LogicalType) -> ExprRef {
351 self.plan.add_expr_at(expr, ty, self.current_span)
352 }
353
354 pub(crate) fn add_constant(&mut self, value: Value) -> ExprRef {
355 let ty = value.logical_type();
356 let reference = self.plan.add_value(value);
357 self.plan.add_expr_at(Expr::Constant(reference), ty, self.current_span)
358 }
359
360 pub(crate) fn add_node(&mut self, node: Node) -> NodeRef {
361 self.plan.add_node_at(node, self.current_span)
362 }
363
364 pub(crate) fn into_plan(self) -> Plan {
365 self.plan
366 }
367
368 pub(crate) fn fresh_index(&mut self) -> u32 {
370 let index = self.next_index;
371 self.next_index += 1;
372 index
373 }
374
375 fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
377 let binding = ColumnBinding::new(index, position as u32);
378 self.plan.add_expr(Expr::Column(binding), ty)
379 }
380
381 fn attach_scalar_subqueries(&mut self, mut input: NodeRef) -> NodeRef {
383 let subqueries = std::mem::take(&mut self.scalar_subqueries);
384 for pending in subqueries {
385 input = self.attach_subquery(input, pending);
386 }
387 input
388 }
389
390 fn attach_subquery(&mut self, input: NodeRef, pending: PendingSubquery) -> NodeRef {
397 let PendingSubquery {
398 node: mut right,
399 kind,
400 conditions,
401 dependent,
402 reads: _,
403 index: _,
404 inside_aggregate: _,
405 } = pending;
406 if kind == JoinKind::Single && !self.semantics.scalar_subquery_error_on_multiple_rows() {
407 right = self.add_node(Node::Limit {
408 input: right,
409 count: Bound::Rows(1),
410 offset: Bound::Rows(0),
411 });
412 }
413 let conditions = self.plan.add_expr_list(&conditions);
414 if dependent {
415 self.add_node(Node::DependentJoin { left: input, right, kind, conditions })
416 } else {
417 self.add_node(Node::Join {
418 left: input,
419 right,
420 kind,
421 conditions,
422 build: BuildSide::default(),
423 })
424 }
425 }
426
427 pub(crate) fn bind_query(
430 &mut self,
431 ast: &Ast,
432 query: ast::QueryRef,
433 ) -> Result<(NodeRef, Scope)> {
434 let span = ast.query_span(query);
435 let outer = std::mem::replace(&mut self.current_span, span);
436 let result =
437 self.bind_query_inner(ast, query).map_err(|error| error.with_fallback_span(span));
438 self.current_span = outer;
439 result
440 }
441
442 fn bind_query_inner(&mut self, ast: &Ast, query: ast::QueryRef) -> Result<(NodeRef, Scope)> {
443 let written = ast.query(query);
444 if written.ctes.is_empty() {
445 return self.bind_body(ast, &written);
446 }
447 let depth = self.materialized.len();
451 let result = self.bind_materialized(ast, &written);
452 self.materialized.truncate(depth);
453 result
454 }
455
456 fn bind_materialized(&mut self, ast: &Ast, written: &ast::Query) -> Result<(NodeRef, Scope)> {
462 let depth = self.materialized.len();
463 let held = ast.cte_list(written.ctes).to_vec();
464 let mut definitions = Vec::with_capacity(held.len());
465 for &index in &held {
466 definitions.push(self.bind_definition(ast, index)?);
467 }
468 let (mut node, scope) = self.bind_body(ast, written)?;
469 for (at, definition) in definitions.into_iter().enumerate().rev() {
470 let entry = &self.materialized[depth + at];
471 let cte = entry.cte;
472 let name = entry.name.clone();
473 let fields = entry.fields.clone();
474 let name = self.plan.intern(&name);
475 let columns = self.plan.add_fields(&fields);
476 node =
477 self.add_node(Node::MaterializedCte { definition, body: node, name, cte, columns });
478 }
479 Ok((node, scope))
480 }
481
482 fn bind_definition(&mut self, ast: &Ast, index: u32) -> Result<NodeRef> {
492 let held = ast.cte(index);
493 let name = ast.string(held.name).to_string();
494 let (node, mut scope) = self.bind_query(ast, held.query)?;
495 if !held.columns.is_empty() {
496 let names: Vec<&str> = ast.name(held.columns).collect();
497 scope.rename_prefix(&names);
498 }
499 let table = self.fresh_index();
500 let mut exprs = Vec::with_capacity(scope.len());
501 let mut names = Vec::with_capacity(scope.len());
502 for column in &scope.columns {
503 exprs.push(self.plan.add_expr(Expr::Column(column.binding), column.ty.clone()));
504 names.push(self.plan.intern(&column.name));
505 }
506 let exprs = self.plan.add_expr_list(&exprs);
507 let names = self.plan.add_name_list(&names);
508 let node = self.add_node(Node::Project { input: node, index: table, exprs, names });
509 let cte = self.next_cte;
510 self.next_cte += 1;
511 self.materialized.push(Materialized { written: index, cte, name, fields: scope.fields() });
512 Ok(node)
513 }
514
515 fn bind_body(&mut self, ast: &Ast, written: &ast::Query) -> Result<(NodeRef, Scope)> {
516 match written.body {
517 ast::QueryBody::Select(select) => self.bind_select(ast, select, written),
518 ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
519 let operator = Operator { op, quantifier, by_name };
520 self.bind_set_op(ast, written, operator, left, right)
521 }
522 ast::QueryBody::Values(rows) => self.bind_values(ast, written, rows),
523 ast::QueryBody::Describe(inner) => self.bind_describe(ast, written, inner),
524 ast::QueryBody::Show { name, relation } => self.bind_show(ast, written, name, relation),
525 }
526 }
527
528 fn bind_show(
530 &mut self,
531 ast: &Ast,
532 query: &ast::Query,
533 name: ast::Slice,
534 relation: ast::QueryRef,
535 ) -> Result<(NodeRef, Scope)> {
536 let text = ast.name_text(name);
537 let parts: Vec<&str> = ast.name(name).collect();
538 let table_exists = self.catalog.resolve(&parts).is_ok();
539 let as_table = match self.semantics.show_behavior() {
540 ShowBehavior::Auto => table_exists,
541 ShowBehavior::Setting => false,
542 ShowBehavior::Table => true,
543 };
544 if as_table {
545 return self.bind_describe(ast, query, relation);
546 }
547 let Some((_, value)) =
548 self.session.iter().find(|(name, _)| name.eq_ignore_ascii_case(&text))
549 else {
550 return Err(Error::catalog(format!("Setting with name \"{text}\" does not exist")));
551 };
552 let field = Field::new(text, LogicalType::Varchar);
553 let expr = self.plan.add_constant(Value::Varchar(value.to_string()));
554 let row = self.plan.add_expr_list(&[expr]);
555 let rows = self.plan.add_rows(&[row]);
556 let columns = self.plan.add_fields(std::slice::from_ref(&field));
557 let index = self.fresh_index();
558 let node = self.add_node(Node::Values { index, columns, rows });
559 let mut scope = Scope::empty();
560 scope.push(Visible {
561 table: String::new(),
562 name: field.name,
563 binding: ColumnBinding::new(index, 0),
564 ty: LogicalType::Varchar,
565 not_null: false,
566 });
567 Ok((node, scope))
568 }
569
570 fn bind_describe(
586 &mut self,
587 ast: &Ast,
588 query: &ast::Query,
589 inner: ast::QueryRef,
590 ) -> Result<(NodeRef, Scope)> {
591 let (_, described) = self.bind_query(ast, inner)?;
592 let fields: Vec<Field> = ["column_name", "column_type", "null", "key", "default", "extra"]
593 .iter()
594 .map(|name| Field::new(*name, LogicalType::Varchar))
595 .collect();
596 let mut slices = Vec::with_capacity(described.columns.len());
597 for column in described.columns.clone() {
598 let written = [
601 column.name.clone(),
602 column.ty.to_string(),
603 if column.not_null { "NO" } else { "YES" }.to_owned(),
604 ];
605 let mut items: Vec<ExprRef> = written
606 .into_iter()
607 .map(|text| self.plan.add_constant(Value::Varchar(text)))
608 .collect();
609 for _ in 0..3 {
610 let empty = self.plan.add_constant(Value::Null);
611 items.push(self.cast_to(empty, &LogicalType::Varchar));
612 }
613 slices.push(self.plan.add_expr_list(&items));
614 }
615 let rows = self.plan.add_rows(&slices);
616 let columns = self.plan.add_fields(&fields);
617 let index = self.fresh_index();
618 let mut node = self.add_node(Node::Values { index, columns, rows });
619 let mut scope = Scope::empty();
620 for (at, field) in fields.iter().enumerate() {
621 scope.push(Visible {
622 table: String::new(),
623 name: field.name.clone(),
624 binding: ColumnBinding::new(index, at as u32),
625 ty: field.ty.clone(),
626 not_null: false,
627 });
628 }
629 let keys = self.sort_keys(ast, query, &scope, &[])?;
630 if !keys.is_empty() {
631 let keys = self.plan.add_sort_keys(&keys);
632 node = self.add_node(Node::Sort { input: node, keys });
633 }
634 node = self.apply_limit(ast, query, node, &mut scope)?;
635 Ok((node, scope))
636 }
637
638 fn passes_through(&self, expr: ExprRef, input: &Scope) -> bool {
644 let Expr::Column(binding) = *self.plan.expr(expr) else { return false };
645 input.columns.iter().any(|column| column.binding == binding && column.not_null)
646 }
647
648 fn bind_values(
655 &mut self,
656 ast: &Ast,
657 query: &ast::Query,
658 rows: ast::Slice,
659 ) -> Result<(NodeRef, Scope)> {
660 let written = ast.rows(rows).to_vec();
661 let Some(first) = written.first() else {
662 return Err(Error::binder("VALUES needs at least one row"));
663 };
664 let width = first.len as usize;
665 for (at, row) in written.iter().enumerate() {
666 if row.len as usize != width {
667 return Err(Error::binder(format!(
668 "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
669 at + 1,
670 row.len
671 )));
672 }
673 }
674 let empty = Scope::empty();
676 let previous = std::mem::replace(&mut self.clause, "VALUES clause");
677 let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
678 for row in &written {
679 let mut items = Vec::with_capacity(width);
680 for &expr in ast.expr_list(*row) {
681 items.push(self.bind_expr(ast, expr, &empty)?);
682 }
683 bound.push(items);
684 }
685 self.clause = previous;
686 let mut types = Vec::with_capacity(width);
687 for at in 0..width {
688 let mut ty = self.plan.expr_type(bound[0][at]).clone();
689 for row in &bound[1..] {
690 let other = self.plan.expr_type(row[at]).clone();
691 ty = ty.promote(&other).ok_or_else(|| {
692 Error::binder(format!(
693 "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
694 at + 1
695 ))
696 })?;
697 }
698 types.push(ty);
699 }
700 let mut slices = Vec::with_capacity(bound.len());
701 for row in &bound {
702 let items: Vec<ExprRef> = row
703 .iter()
704 .zip(&types)
705 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
706 .collect::<Result<_>>()?;
707 slices.push(self.plan.add_expr_list(&items));
708 }
709 let rows = self.plan.add_rows(&slices);
710 let fields: Vec<Field> = types
711 .iter()
712 .enumerate()
713 .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
714 .collect();
715 let columns = self.plan.add_fields(&fields);
716 let index = self.fresh_index();
717 let mut node = self.add_node(Node::Values { index, columns, rows });
718 let mut scope = Scope::empty();
719 for (at, field) in fields.iter().enumerate() {
720 scope.push(Visible {
721 table: String::new(),
722 name: field.name.clone(),
723 binding: ColumnBinding::new(index, at as u32),
724 ty: field.ty.clone(),
725 not_null: false,
726 });
727 }
728 let keys = self.sort_keys(ast, query, &scope, &[])?;
729 if !keys.is_empty() {
730 let keys = self.plan.add_sort_keys(&keys);
731 node = self.add_node(Node::Sort { input: node, keys });
732 }
733 node = self.apply_limit(ast, query, node, &mut scope)?;
734 Ok((node, scope))
735 }
736
737 fn bind_set_op(
738 &mut self,
739 ast: &Ast,
740 query: &ast::Query,
741 operator: Operator,
742 left: ast::QueryRef,
743 right: ast::QueryRef,
744 ) -> Result<(NodeRef, Scope)> {
745 let (left_node, left_scope) = self.bind_query(ast, left)?;
746 let (right_node, right_scope) = self.bind_query(ast, right)?;
747 let merged = if operator.by_name {
748 match_by_name(&left_scope, &right_scope)?
749 } else {
750 match_by_position(&left_scope, &right_scope)?
751 };
752 let left_node = self.conform(left_node, &left_scope, &merged, |column| column.left)?;
753 let right_node = self.conform(right_node, &right_scope, &merged, |column| column.right)?;
754 let index = self.fresh_index();
755 let kind = match operator.op {
756 SetOp::Union => SetOpKind::Union,
757 SetOp::Except => SetOpKind::Except,
758 SetOp::Intersect => SetOpKind::Intersect,
759 };
760 let all = operator.quantifier == Quantifier::All;
763 let mut node =
764 self.add_node(Node::SetOp { left: left_node, right: right_node, kind, all, index });
765 let mut scope = Scope::empty();
766 for (at, column) in merged.iter().enumerate() {
767 scope.push(Visible {
768 table: String::new(),
769 name: column.name.clone(),
770 binding: ColumnBinding::new(index, at as u32),
771 ty: column.ty.clone(),
772 not_null: false,
775 });
776 }
777 let keys = self.sort_keys(ast, query, &scope, &[])?;
781 if !keys.is_empty() {
782 let keys = self.plan.add_sort_keys(&keys);
783 node = self.add_node(Node::Sort { input: node, keys });
784 }
785 node = self.apply_limit(ast, query, node, &mut scope)?;
786 Ok((node, scope))
787 }
788
789 fn conform(
795 &mut self,
796 node: NodeRef,
797 scope: &Scope,
798 merged: &[Merged],
799 pick: impl Fn(&Merged) -> Option<usize>,
800 ) -> Result<NodeRef> {
801 let unchanged = merged.len() == scope.len()
802 && merged
803 .iter()
804 .enumerate()
805 .all(|(at, column)| pick(column) == Some(at) && column.ty == scope.columns[at].ty);
806 if unchanged {
807 return Ok(node);
808 }
809 let index = self.fresh_index();
810 let mut exprs = Vec::with_capacity(merged.len());
811 let mut names = Vec::with_capacity(merged.len());
812 for column in merged {
813 let expr = match pick(column) {
814 Some(at) => {
815 let held = &scope.columns[at];
816 self.plan.add_expr(Expr::Column(held.binding), held.ty.clone())
817 }
818 None => self.plan.add_constant(Value::Null),
819 };
820 exprs.push(self.checked_cast_to(expr, &column.ty, false)?);
821 names.push(self.plan.intern(&column.name));
822 }
823 let exprs = self.plan.add_expr_list(&exprs);
824 let names = self.plan.add_name_list(&names);
825 Ok(self.add_node(Node::Project { input: node, index, exprs, names }))
826 }
827
828 fn bind_select(
831 &mut self,
832 ast: &Ast,
833 select: ast::SelectRef,
834 query: &ast::Query,
835 ) -> Result<(NodeRef, Scope)> {
836 let written = ast.select(select);
837 let outer_windows = std::mem::take(&mut self.windows);
841 let outer_joined_above = std::mem::take(&mut self.joined_above);
846 let (mut node, input) = self.bind_from(ast, written.from)?;
847 node = self.attach_scalar_subqueries(node);
848
849 if written.filter != NONE {
850 self.clause = "WHERE clause";
851 let predicate = self.bind_expr(ast, written.filter, &input)?;
852 let predicate = self.as_boolean(predicate, "WHERE")?;
853 node = self.attach_scalar_subqueries(node);
854 node = self.add_node(Node::Filter { input: node, predicate });
855 }
856
857 let targets = ast.target_list(written.targets).to_vec();
858 if targets.is_empty() {
859 return Err(Error::binder("a SELECT needs at least one expression to select"));
860 }
861
862 let group_items = self.group_items(ast, &written, &targets)?;
863 let aggregating = !group_items.is_empty()
864 || written.having != NONE
865 || targets.iter().any(|target| has_aggregate(ast, target.expr));
866 if aggregating {
867 self.clause = "GROUP BY clause";
868 let mut groups = Vec::with_capacity(group_items.len());
869 for item in &group_items {
870 groups.push(self.bind_expr(ast, *item, &input)?);
871 }
872 let index = self.fresh_index();
873 self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
874 }
875
876 let mut above = Vec::new();
883
884 self.clause = "SELECT clause";
885 let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input, &mut above)?;
886 let visible = exprs.len();
887
888 let mut having = None;
889 if written.having != NONE {
890 self.clause = "HAVING clause";
891 let before = self.scalar_subqueries.len();
892 let predicate = self.bind_expr(ast, written.having, &input)?;
893 self.lift_over_aggregate(before, &mut above, &input)?;
894 let predicate = self.over_aggregate(predicate, &input)?;
895 having = Some(self.as_boolean(predicate, "HAVING")?);
896 }
897
898 let project = self.fresh_index();
901 let mut output = Scope::empty();
902 for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
903 output.push(Visible {
904 table: String::new(),
905 name: name.clone(),
906 binding: ColumnBinding::new(project, at as u32),
907 ty: self.plan.expr_type(*expr).clone(),
908 not_null: self.passes_through(*expr, &input),
909 });
910 }
911
912 self.clause = "ORDER BY clause";
913 let mut extra = Vec::new();
914 let keys = self.select_sort_keys(
915 ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra, &mut above,
916 )?;
917 self.joined_above = outer_joined_above;
918 if !extra.is_empty() && written.distinct != Distinct::No {
919 return Err(Error::binder(
920 "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
921 ));
922 }
923 let on = self.distinct_on(ast, written.distinct, &output)?;
924
925 node = self.attach_scalar_subqueries(node);
926
927 if let Some(aggregation) = self.aggregation.take() {
928 let index = aggregation.index;
929 let groups = self.plan.add_expr_list(&aggregation.groups);
930 let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
931 node = self.add_node(Node::Aggregate { input: node, index, groups, aggregates });
932 }
933 if !above.is_empty() {
934 debug_assert!(self.scalar_subqueries.is_empty(), "a query is waiting to be joined");
935 self.scalar_subqueries = above;
936 node = self.attach_scalar_subqueries(node);
937 }
938 if let Some(predicate) = having {
939 node = self.add_node(Node::Filter { input: node, predicate });
940 }
941
942 for run in std::mem::replace(&mut self.windows, outer_windows) {
946 let partition = self.plan.add_expr_list(&run.partition);
947 let order = self.plan.add_sort_keys(&run.order);
948 let expressions = self.plan.add_expr_list(&run.calls);
949 node = self.add_node(Node::Window {
950 input: node,
951 index: run.index,
952 partition,
953 order,
954 frame: run.frame,
955 expressions,
956 });
957 }
958
959 let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
960 let exprs_slice = self.plan.add_expr_list(&exprs);
961 let names_slice = self.plan.add_name_list(&interned);
962 node = self.add_node(Node::Project {
963 input: node,
964 index: project,
965 exprs: exprs_slice,
966 names: names_slice,
967 });
968
969 if written.distinct != Distinct::No {
970 let on = self.plan.add_expr_list(&on);
971 node = self.add_node(Node::Distinct { input: node, on });
972 }
973 if !keys.is_empty() {
974 let keys = self.plan.add_sort_keys(&keys);
975 node = self.add_node(Node::Sort { input: node, keys });
976 }
977 node = self.apply_limit(ast, query, node, &mut output)?;
978
979 if extra.is_empty() {
980 output.columns.truncate(visible);
981 return Ok((node, output));
982 }
983 let index = self.fresh_index();
986 let mut kept = Vec::with_capacity(visible);
987 let mut kept_names = Vec::with_capacity(visible);
988 let mut scope = Scope::empty();
989 for (at, name) in names.iter().enumerate().take(visible) {
990 let ty = output.columns[at].ty.clone();
991 let binding = output.columns[at].binding;
995 kept.push(self.plan.add_expr(Expr::Column(binding), ty.clone()));
996 kept_names.push(self.plan.intern(name));
997 scope.push(Visible {
998 table: String::new(),
999 name: name.clone(),
1000 binding: ColumnBinding::new(index, at as u32),
1001 ty,
1002 not_null: output.columns[at].not_null,
1003 });
1004 }
1005 let exprs = self.plan.add_expr_list(&kept);
1006 let names = self.plan.add_name_list(&kept_names);
1007 node = self.add_node(Node::Project { input: node, index, exprs, names });
1008 Ok((node, scope))
1009 }
1010
1011 fn lift_over_aggregate(
1029 &mut self,
1030 before: usize,
1031 above: &mut Vec<PendingSubquery>,
1032 scope: &Scope,
1033 ) -> Result<()> {
1034 if self.aggregation.is_none() {
1035 return Ok(());
1036 }
1037 let mut lifted = Vec::new();
1038 for pending in self.scalar_subqueries.split_off(before) {
1039 if pending.dependent || pending.inside_aggregate {
1040 self.scalar_subqueries.push(pending);
1041 } else {
1042 self.joined_above.push(pending.index);
1043 lifted.push(pending);
1044 }
1045 }
1046 for pending in &mut lifted {
1051 let conditions = std::mem::take(&mut pending.conditions);
1052 let mut over = Vec::with_capacity(conditions.len());
1053 for condition in conditions {
1054 over.push(self.over_aggregate(condition, scope)?);
1055 }
1056 pending.conditions = over;
1057 }
1058 above.append(&mut lifted);
1059 Ok(())
1060 }
1061
1062 fn bind_targets(
1063 &mut self,
1064 ast: &Ast,
1065 targets: &[ast::Target],
1066 input: &Scope,
1067 above: &mut Vec<PendingSubquery>,
1068 ) -> Result<(Vec<ExprRef>, Vec<String>)> {
1069 let mut exprs = Vec::with_capacity(targets.len());
1070 let mut names = Vec::with_capacity(targets.len());
1071 for target in targets {
1072 if let ast::Expr::Star { qualifier, replacements } = ast.expr(target.expr) {
1073 let table = ast.name(qualifier).last().map(str::to_string);
1074 let expanded: Vec<Visible> =
1075 input.star(table.as_deref())?.into_iter().cloned().collect();
1076 let replacements = ast.target_list(replacements).to_vec();
1077 let mut used = vec![false; replacements.len()];
1078 for column in expanded {
1079 let found = replacements.iter().zip(&mut used).find(|(replacement, _)| {
1080 same_name(ast.string(replacement.alias), &column.name)
1081 });
1082 let before = self.scalar_subqueries.len();
1087 let (expr, name) = match found {
1088 Some((replacement, used)) => {
1089 *used = true;
1090 let expr = self.bind_expr(ast, replacement.expr, input)?;
1091 (expr, ast.string(replacement.alias).to_string())
1092 }
1093 None => (
1094 self.plan.add_expr(Expr::Column(column.binding), column.ty),
1095 column.name,
1096 ),
1097 };
1098 self.lift_over_aggregate(before, above, input)?;
1099 exprs.push(self.over_aggregate(expr, input)?);
1100 names.push(name);
1101 }
1102 if let Some((replacement, _)) =
1106 replacements.iter().zip(&used).find(|(_, used)| !**used)
1107 {
1108 return Err(missing_replacement(ast.string(replacement.alias), input));
1109 }
1110 continue;
1111 }
1112 let before = self.scalar_subqueries.len();
1113 let expr = self.bind_expr(ast, target.expr, input)?;
1114 self.lift_over_aggregate(before, above, input)?;
1115 exprs.push(self.over_aggregate(expr, input)?);
1116 names.push(if target.alias == NONE {
1117 self.output_name(ast, target.expr, input)
1118 } else {
1119 ast.string(target.alias).to_string()
1120 });
1121 }
1122 Ok((exprs, names))
1123 }
1124
1125 fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
1131 if let ast::Expr::Column { name } = ast.expr(target) {
1132 let parts: Vec<&str> = ast.name(name).collect();
1133 if let Ok(found) = input.resolve(&parts) {
1134 return found.name.clone();
1135 }
1136 }
1137 describe(ast, target, self.semantics)
1138 }
1139
1140 fn group_items(
1142 &self,
1143 ast: &Ast,
1144 select: &ast::Select,
1145 targets: &[ast::Target],
1146 ) -> Result<Vec<ast::ExprRef>> {
1147 if select.group_by_all {
1148 return Ok(targets
1151 .iter()
1152 .filter(|target| !has_aggregate(ast, target.expr))
1153 .map(|target| target.expr)
1154 .collect());
1155 }
1156 let mut items = Vec::new();
1157 for &item in ast.expr_list(select.group_by) {
1158 items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
1159 }
1160 Ok(items)
1161 }
1162
1163 fn output_reference(
1165 &self,
1166 ast: &Ast,
1167 item: ast::ExprRef,
1168 targets: &[ast::Target],
1169 clause: &str,
1170 ) -> Result<Option<ast::ExprRef>> {
1171 match ast.expr(item) {
1172 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
1173 let written = ast.string(text);
1174 let position: usize = written.parse().map_err(|_| {
1175 Error::binder(format!("{clause} term {written} is not a column"))
1176 })?;
1177 if position == 0 || position > targets.len() {
1178 return Err(Error::binder(format!(
1179 "{clause} term out of range - should be between 1 and {}",
1180 targets.len()
1181 )));
1182 }
1183 Ok(Some(targets[position - 1].expr))
1184 }
1185 ast::Expr::Column { name } => {
1186 let parts: Vec<&str> = ast.name(name).collect();
1187 let [written] = parts.as_slice() else { return Ok(None) };
1188 let mut found = None;
1189 for target in targets {
1190 if target.alias != NONE && same_name(ast.string(target.alias), written) {
1191 if found.is_some() {
1192 return Ok(None);
1193 }
1194 found = Some(target.expr);
1195 }
1196 }
1197 Ok(found)
1198 }
1199 _ => Ok(None),
1200 }
1201 }
1202
1203 #[allow(clippy::too_many_arguments)]
1207 fn select_sort_keys(
1208 &mut self,
1209 ast: &Ast,
1210 query: &ast::Query,
1211 input: &Scope,
1212 output: &Scope,
1213 project: u32,
1214 exprs: &mut Vec<ExprRef>,
1215 names: &mut Vec<String>,
1216 extra: &mut Vec<usize>,
1217 above: &mut Vec<PendingSubquery>,
1218 ) -> Result<Vec<SortKey>> {
1219 if query.order_by_all {
1220 return Ok(self.every_column(output));
1221 }
1222 let items = ast.order_list(query.order_by).to_vec();
1223 let mut keys = Vec::with_capacity(items.len());
1224 for item in items {
1225 self.check_order_literal(ast, item.expr)?;
1226 let position = match self.output_position(ast, item.expr, output)? {
1227 Some(position) => position,
1228 None => {
1229 let before = self.scalar_subqueries.len();
1230 let bound = self.bind_expr(ast, item.expr, input)?;
1231 self.lift_over_aggregate(before, above, input)?;
1232 let bound = self.over_aggregate(bound, input)?;
1233 match exprs.iter().position(|&held| self.same_expr(held, bound)) {
1234 Some(position) => position,
1235 None => {
1236 exprs.push(bound);
1237 names.push(describe(ast, item.expr, self.semantics));
1238 extra.push(exprs.len() - 1);
1239 exprs.len() - 1
1240 }
1241 }
1242 }
1243 };
1244 let ty = self.plan.expr_type(exprs[position]).clone();
1245 let expr = self.column(project, position, ty);
1246 keys.push(self.sort_key(expr, item));
1247 }
1248 Ok(keys)
1249 }
1250
1251 fn sort_keys(
1253 &mut self,
1254 ast: &Ast,
1255 query: &ast::Query,
1256 output: &Scope,
1257 targets: &[ast::Target],
1258 ) -> Result<Vec<SortKey>> {
1259 if query.order_by_all {
1260 return Ok(self.every_column(output));
1261 }
1262 let items = ast.order_list(query.order_by).to_vec();
1263 let mut keys = Vec::with_capacity(items.len());
1264 for item in items {
1265 self.check_order_literal(ast, item.expr)?;
1266 let expr = match self.output_position(ast, item.expr, output)? {
1267 Some(position) => {
1268 let column = &output.columns[position];
1269 let (binding, ty) = (column.binding, column.ty.clone());
1270 self.plan.add_expr(Expr::Column(binding), ty)
1271 }
1272 None => {
1273 let _ = targets;
1274 self.bind_expr(ast, item.expr, output)?
1275 }
1276 };
1277 keys.push(self.sort_key(expr, item));
1278 }
1279 Ok(keys)
1280 }
1281
1282 fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
1283 let columns: Vec<(ColumnBinding, LogicalType)> =
1284 output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
1285 columns
1286 .into_iter()
1287 .map(|(binding, ty)| {
1288 let expr = self.plan.add_expr(Expr::Column(binding), ty);
1289 let descending = self.semantics.default_descending();
1290 SortKey { expr, descending, nulls_first: self.semantics.nulls_first(descending) }
1291 })
1292 .collect()
1293 }
1294
1295 fn sort_key(&self, expr: ExprRef, item: ast::OrderItem) -> SortKey {
1297 let descending = match item.order {
1298 Order::Unstated => self.semantics.default_descending(),
1299 Order::Ascending => false,
1300 Order::Descending => true,
1301 };
1302 let nulls_first = match item.nulls {
1303 Nulls::First => true,
1304 Nulls::Last => false,
1305 Nulls::Unstated => self.semantics.nulls_first(descending),
1306 };
1307 SortKey { expr, descending, nulls_first }
1308 }
1309
1310 fn output_position(
1312 &self,
1313 ast: &Ast,
1314 item: ast::ExprRef,
1315 output: &Scope,
1316 ) -> Result<Option<usize>> {
1317 match ast.expr(item) {
1318 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
1319 let written = ast.string(text);
1320 if written.contains(['.', 'e', 'E']) {
1321 return Ok(None);
1322 }
1323 let position: usize = written.parse().map_err(|_| {
1324 Error::binder(format!("ORDER BY term {written} is not a column"))
1325 })?;
1326 if position == 0 || position > output.len() {
1327 return Err(Error::binder(format!(
1328 "ORDER BY term out of range - should be between 1 and {}",
1329 output.len()
1330 )));
1331 }
1332 Ok(Some(position - 1))
1333 }
1334 ast::Expr::Column { name } => {
1335 let parts: Vec<&str> = ast.name(name).collect();
1336 let [written] = parts.as_slice() else { return Ok(None) };
1337 Ok(output.position_of(None, written))
1338 }
1339 _ => Ok(None),
1340 }
1341 }
1342
1343 fn check_order_literal(&self, ast: &Ast, item: ast::ExprRef) -> Result<()> {
1345 if !self.semantics.order_by_non_integer_literal()
1346 && matches!(
1347 ast.expr(item),
1348 ast::Expr::Literal { kind, text }
1349 if kind != LiteralKind::Number
1350 || ast.string(text).contains(['.', 'e', 'E'])
1351 )
1352 {
1353 return Err(Error::binder(
1354 "ORDER BY non-integer literal has no effect.\n* SET order_by_non_integer_literal=true to allow this behavior.",
1355 ));
1356 }
1357 Ok(())
1358 }
1359
1360 fn distinct_on(
1362 &mut self,
1363 ast: &Ast,
1364 distinct: Distinct,
1365 output: &Scope,
1366 ) -> Result<Vec<ExprRef>> {
1367 let Distinct::On(items) = distinct else {
1368 return Ok(Vec::new());
1369 };
1370 let items = ast.expr_list(items).to_vec();
1371 let mut on = Vec::with_capacity(items.len());
1372 for item in items {
1373 let Some(position) = self.output_position(ast, item, output)? else {
1374 return Err(Error::not_implemented(
1375 "DISTINCT ON an expression that is not in the select list",
1376 ));
1377 };
1378 let column = &output.columns[position];
1379 let (binding, ty) = (column.binding, column.ty.clone());
1380 on.push(self.plan.add_expr(Expr::Column(binding), ty));
1381 }
1382 Ok(on)
1383 }
1384
1385 fn apply_limit(
1392 &mut self,
1393 ast: &Ast,
1394 query: &ast::Query,
1395 input: NodeRef,
1396 scope: &mut Scope,
1397 ) -> Result<NodeRef> {
1398 let waiting = self.scalar_subqueries.len();
1399 if query.limit_percent {
1400 let percent = self.constant_percent(ast, query.limit)?;
1401 let offset = self.count_bound(ast, query.offset, "OFFSET")?;
1402 let offset = self.settled(offset, "OFFSET")?;
1403 return Ok(match percent {
1404 Some(percent) => self.add_node(Node::LimitPercent { input, percent, offset }),
1405 None => self.limited(input, Bound::All, Bound::Rows(offset)),
1408 });
1409 }
1410 let count = self.count_bound(ast, query.limit, "LIMIT")?;
1411 let offset = match self.count_bound(ast, query.offset, "OFFSET")? {
1414 Bound::All => Bound::Rows(0),
1415 named => named,
1416 };
1417 let joined = self.scalar_subqueries.split_off(waiting);
1418 if joined.is_empty() {
1419 return Ok(self.limited(input, count, offset));
1420 }
1421 let mut input = input;
1422 for pending in joined {
1423 input = self.attach_subquery(input, pending);
1424 }
1425 let limit = self.add_node(Node::Limit { input, count, offset });
1426 Ok(self.reproject(limit, scope))
1427 }
1428
1429 fn limited(&mut self, input: NodeRef, count: Bound, offset: Bound) -> NodeRef {
1432 if count == Bound::All && offset == Bound::Rows(0) {
1433 return input;
1434 }
1435 self.add_node(Node::Limit { input, count, offset })
1436 }
1437
1438 fn settled(&self, bound: Bound, clause: &str) -> Result<u64> {
1444 match bound {
1445 Bound::Rows(rows) => Ok(rows),
1446 Bound::All => Ok(0),
1447 Bound::Read(_) => Err(Error::not_implemented(format!(
1448 "{clause} holding a subquery beside a LIMIT written as a percentage"
1449 ))),
1450 }
1451 }
1452
1453 fn reproject(&mut self, node: NodeRef, scope: &mut Scope) -> NodeRef {
1459 let index = self.fresh_index();
1460 let mut exprs = Vec::with_capacity(scope.columns.len());
1461 let mut names = Vec::with_capacity(scope.columns.len());
1462 for column in &scope.columns {
1463 exprs.push(self.plan.add_expr(Expr::Column(column.binding), column.ty.clone()));
1464 names.push(self.plan.intern(&column.name));
1465 }
1466 for (at, column) in scope.columns.iter_mut().enumerate() {
1467 column.binding = ColumnBinding::new(index, at as u32);
1468 }
1469 let exprs = self.plan.add_expr_list(&exprs);
1470 let names = self.plan.add_name_list(&names);
1471 self.add_node(Node::Project { input: node, index, exprs, names })
1472 }
1473
1474 fn constant_percent(&mut self, ast: &Ast, written: ast::ExprRef) -> Result<Option<f64>> {
1485 if written == NONE {
1486 return Ok(None);
1487 }
1488 self.clause = "LIMIT clause";
1489 let scope = Scope::empty();
1490 let bound = self.bind_expr(ast, written, &scope)?;
1491 let Some(value) = fold::value_of(&self.plan, bound)? else {
1492 return Err(Error::not_implemented("a LIMIT holding a subquery"));
1493 };
1494 if value.is_null() {
1495 return Ok(None);
1496 }
1497 let cast = cast_value(&value, &LogicalType::Double, false)?;
1498 let Value::Double(percent) = cast else {
1499 return Err(Error::binder(format!(
1500 "LIMIT takes a percentage, not a value of type {}",
1501 value.logical_type()
1502 )));
1503 };
1504 if !(0.0..=100.0).contains(&percent) {
1505 return Err(Error::out_of_range(
1506 "Limit percent out of range, should be between 0% and 100%",
1507 ));
1508 }
1509 Ok(Some(percent))
1510 }
1511
1512 fn count_bound(&mut self, ast: &Ast, written: ast::ExprRef, clause: &str) -> Result<Bound> {
1531 if written == NONE {
1532 return Ok(Bound::All);
1533 }
1534 self.clause = "LIMIT clause";
1535 let scope = Scope::empty();
1536 let bound = self.bind_expr(ast, written, &scope)?;
1537 let Some(value) = fold::value_of(&self.plan, bound)? else {
1538 return Ok(Bound::Read(bound));
1539 };
1540 if value.is_null() {
1543 return Ok(Bound::All);
1544 }
1545 row_count(&value, clause).map(Bound::Rows)
1546 }
1547
1548 fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
1551 let sources = ast.source_list(from).to_vec();
1552 let Some((first, rest)) = sources.split_first() else {
1553 return Ok((self.add_node(Node::Dummy), Scope::empty()));
1556 };
1557 let (mut node, mut scope) = self.bind_source(ast, *first)?;
1558 for source in rest {
1559 let (right, right_scope, correlations) = self.bind_lateral(ast, *source, &scope)?;
1560 node = if correlations.is_empty() {
1561 self.add_node(Node::CrossProduct { left: node, right })
1562 } else {
1563 let conditions = self.plan.add_expr_list(&[]);
1564 self.add_node(Node::DependentJoin {
1565 left: node,
1566 right,
1567 kind: JoinKind::Inner,
1568 conditions,
1569 })
1570 };
1571 scope = scope.concat(right_scope);
1572 }
1573 Ok((node, scope))
1574 }
1575
1576 fn bind_lateral(
1588 &mut self,
1589 ast: &Ast,
1590 source: ast::SourceRef,
1591 left: &Scope,
1592 ) -> Result<(NodeRef, Scope, Vec<ColumnBinding>)> {
1593 self.lateral_scopes.push(self.outer_scopes.len());
1594 self.outer_scopes.push(left.clone());
1595 self.correlations.push(Vec::new());
1596 let bound = self.bind_source(ast, source);
1597 let read = self.correlations.pop().expect("correlation frame");
1598 self.outer_scopes.pop();
1599 self.lateral_scopes.pop();
1600 let (node, scope) = bound?;
1601
1602 let mut here = Vec::new();
1603 for binding in read {
1604 if left.columns.iter().any(|column| column.binding == binding) {
1605 here.push(binding);
1606 } else if let Some(enclosing) = self.correlations.last_mut() {
1607 if !enclosing.contains(&binding) {
1608 enclosing.push(binding);
1609 }
1610 }
1611 }
1612 Ok((node, scope, here))
1622 }
1623
1624 fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
1625 match ast.source(source) {
1626 ast::Source::Table { name, alias, columns } => {
1627 self.bind_table(ast, name, alias, columns)
1628 }
1629 ast::Source::Function { name, args, alias, columns, pragma } => {
1630 self.bind_table_function(ast, name, args, alias, columns, pragma)
1631 }
1632 ast::Source::Subquery { query, alias, columns } => {
1633 let (node, mut scope) = self.bind_query(ast, query)?;
1634 let label = if alias == NONE {
1635 "unnamed_subquery".to_string()
1636 } else {
1637 ast.string(alias).to_string()
1638 };
1639 scope.relabel(&label);
1640 if !columns.is_empty() {
1641 let names: Vec<&str> = ast.name(columns).collect();
1642 scope.rename(&names, &label)?;
1643 }
1644 Ok((node, scope))
1645 }
1646 ast::Source::Values { rows, alias, columns } => {
1647 let bare = ast::Query::bare(ast::QueryBody::Values(rows));
1648 let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
1649 let label =
1650 if alias == NONE { String::new() } else { ast.string(alias).to_string() };
1651 scope.relabel(&label);
1652 if !columns.is_empty() {
1653 let names: Vec<&str> = ast.name(columns).collect();
1654 scope.rename(&names, &label)?;
1655 }
1656 Ok((node, scope))
1657 }
1658 ast::Source::Cte { cte, alias, columns } => {
1659 self.bind_cte_scan(ast, cte, alias, columns)
1660 }
1661 ast::Source::Join { left, right, kind, natural, on, using } => {
1662 self.bind_join(ast, left, right, kind, natural, on, using)
1663 }
1664 }
1665 }
1666
1667 fn bind_cte_scan(
1674 &mut self,
1675 ast: &Ast,
1676 written: u32,
1677 alias: ast::StrRef,
1678 columns: ast::Slice,
1679 ) -> Result<(NodeRef, Scope)> {
1680 let Some(held) = self.materialized.iter().rev().find(|held| held.written == written) else {
1681 let name = ast.string(ast.cte(written).name);
1682 return Err(Error::binder(format!("Table with name {name} does not exist!")));
1683 };
1684 let cte = held.cte;
1685 let fields = held.fields.clone();
1686 let text = held.name.clone();
1687 let label = if alias == NONE { text.clone() } else { ast.string(alias).to_string() };
1688 let name = self.plan.intern(&text);
1689 let index = self.fresh_index();
1690 let mut scope = Scope::empty();
1691 for (at, field) in fields.iter().enumerate() {
1692 scope.push(Visible {
1693 table: label.clone(),
1694 name: field.name.clone(),
1695 binding: ColumnBinding::new(index, at as u32),
1696 ty: field.ty.clone(),
1697 not_null: field.not_null,
1698 });
1699 }
1700 if !columns.is_empty() {
1701 let names: Vec<&str> = ast.name(columns).collect();
1702 scope.rename(&names, &label)?;
1703 }
1704 let columns = self.plan.add_fields(&fields);
1705 let node = self.add_node(Node::CteScan { index, cte, name, columns });
1706 Ok((node, scope))
1707 }
1708
1709 fn bind_table(
1710 &mut self,
1711 ast: &Ast,
1712 name: ast::Slice,
1713 alias: ast::StrRef,
1714 columns: ast::Slice,
1715 ) -> Result<(NodeRef, Scope)> {
1716 let parts: Vec<&str> = ast.name(name).collect();
1717 let catalog = self.catalog;
1718 let resolved = match catalog.resolve(&parts) {
1721 Ok(resolved) => resolved,
1722 Err(missing) => {
1723 return self.bind_replacement_scan(ast, &parts, alias, columns, missing);
1724 }
1725 };
1726 if catalog.entry(&resolved)? == Entry::View {
1727 return self.bind_view(ast, &resolved, alias, columns);
1728 }
1729 let table = catalog.table(&resolved)?;
1730 let fields: Vec<Field> = table.columns().to_vec();
1731 let label =
1732 if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
1733 let index = self.fresh_index();
1734 let mut scope = Scope::empty();
1735 for (at, field) in fields.iter().enumerate() {
1736 scope.push(Visible {
1737 table: label.clone(),
1738 name: field.name.clone(),
1739 binding: ColumnBinding::new(index, at as u32),
1740 ty: field.ty.clone(),
1741 not_null: field.not_null,
1742 });
1743 }
1744 if !columns.is_empty() {
1745 let names: Vec<&str> = ast.name(columns).collect();
1746 scope.rename(&names, &label)?;
1747 }
1748 let catalog_name = self.plan.intern(&resolved.catalog);
1749 let schema = self.plan.intern(&resolved.schema);
1750 let table_name = self.plan.intern(&resolved.table);
1751 let alias = self.plan.intern(&label);
1752 let columns = self.plan.add_fields(&fields);
1753 if let Some(zones) = table.rows().zones() {
1758 self.plan.set_zones(index, zones);
1759 }
1760 if let Some(frequencies) = table.frequencies() {
1761 self.plan.set_frequencies(index, frequencies);
1762 }
1763 for (column, distinct) in table.distincts() {
1764 self.plan.measure_distinct(index, &column, distinct);
1765 }
1766 let node = self.add_node(Node::Get {
1767 catalog: catalog_name,
1768 schema,
1769 table: table_name,
1770 alias,
1771 index,
1772 columns,
1773 });
1774 Ok((node, scope))
1775 }
1776
1777 fn bind_view(
1789 &mut self,
1790 ast: &Ast,
1791 name: &QualifiedName,
1792 alias: ast::StrRef,
1793 columns: ast::Slice,
1794 ) -> Result<(NodeRef, Scope)> {
1795 let view = self.catalog.view(name)?;
1796 let full = name.to_string();
1797 if self.expanding.contains(&full) {
1798 return Err(Error::binder(format!(
1802 "infinite recursion detected: attempting to recursively bind view \"\"{}\"\"",
1803 name.table
1804 )));
1805 }
1806 let body = parse_ast_with_case(view.sql(), self.semantics.identifier_case())?;
1807 let query = match body.statements.as_slice() {
1808 [ast::Statement::Query(query)] => *query,
1809 _ => return Err(Error::binder(format!("view \"{}\" is not a query", name.table))),
1812 };
1813 self.expanding.push(full);
1814 let bound = self.bind_query(&body, query);
1815 self.expanding.pop();
1816 let (node, mut scope) = bound?;
1817
1818 let aliases: Vec<&str> = view.aliases().iter().map(String::as_str).collect();
1819 if !aliases.is_empty() {
1820 scope.rename(&aliases, "unnamed_subquery")?;
1821 }
1822 view.remember(scope.fields());
1829 let label = if alias == NONE { name.table.clone() } else { ast.string(alias).to_string() };
1830 scope.relabel(&label);
1831 if !columns.is_empty() {
1832 let names: Vec<&str> = ast.name(columns).collect();
1833 scope.rename(&names, &label)?;
1834 }
1835 Ok((node, scope))
1836 }
1837
1838 fn bind_table_function(
1846 &mut self,
1847 ast: &Ast,
1848 name: ast::Slice,
1849 args: ast::Slice,
1850 alias: ast::StrRef,
1851 columns: ast::Slice,
1852 pragma: bool,
1853 ) -> Result<(NodeRef, Scope)> {
1854 let parts: Vec<&str> = ast.name(name).collect();
1855 let function_name = *parts.last().unwrap_or(&"");
1859 if let Some(schema) = parts.iter().rev().nth(1) {
1860 if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
1861 return Err(Error::catalog(format!(
1862 "Table Function with name {} does not exist!",
1863 parts.join(".")
1864 )));
1865 }
1866 }
1867 let Some(called) = TableFunction::lookup(function_name) else {
1871 if pragma {
1872 if args.is_empty() && self.catalog.resolve(&parts).is_ok() {
1878 return self.bind_table(ast, name, alias, columns);
1879 }
1880 let spelled = function_name.strip_prefix("pragma_").unwrap_or(function_name);
1881 return Err(Error::catalog(format!(
1882 "Pragma Function with name {spelled} does not exist!"
1883 )));
1884 }
1885 return Err(Error::catalog(format!(
1886 "Table Function with name {function_name} does not exist!"
1887 )));
1888 };
1889 let written = ast.target_list(args).to_vec();
1890 let empty = Scope::empty();
1891 let previous = std::mem::replace(&mut self.clause, "table function arguments");
1892 let mut bound = Vec::new();
1893 let mut written_options = Vec::new();
1894 for argument in written {
1895 let expr = self.bind_expr(ast, argument.expr, &empty)?;
1896 if argument.alias == NONE {
1897 bound.push(expr);
1898 } else {
1899 let name = ast.string(argument.alias).to_string();
1900 let (parameter, value) = self.named_argument(called, &name, expr)?;
1901 written_options.push((parameter, value, expr));
1902 }
1903 }
1904 self.clause = previous;
1905 let options = Options::of(&written_options)?;
1906
1907 let given: Vec<LogicalType> =
1910 bound.iter().map(|&expr| self.plan.expr_type(expr).clone()).collect();
1911 let resolved = if pragma {
1912 resolve_pragma(function_name, &given)?
1913 } else {
1914 resolve_table(function_name, &given)?
1915 };
1916 let mut cast: Vec<ExprRef> = bound
1917 .iter()
1918 .zip(&resolved.arguments)
1919 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
1920 .collect::<Result<_>>()?;
1921
1922 if resolved.function.takes_a_name() {
1923 let Columns::Fixed(fields) = resolved.columns else {
1924 return Err(Error::internal("a pragma that resolved to a file"));
1925 };
1926 let [argument] = cast[..] else {
1927 return Err(Error::internal("a pragma that resolved to more than one name"));
1928 };
1929 return self.bind_pragma(ast, resolved.function, &fields, argument, alias, columns);
1930 }
1931 let mut measured = Stat::Unknown;
1934 let mut counted: Vec<(String, Stat<u64>)> = Vec::new();
1935 let mut bounded: Option<Arc<dyn Zones>> = None;
1936 let fields = match resolved.columns {
1937 Columns::Fixed(fields) => fields,
1938 columns => {
1939 let paths = self.file_paths(cast[0], resolved.function.name())?;
1944 let mut fields = match columns {
1945 Columns::Csv => csv_fields(&paths, options.given)?,
1948 _ => {
1949 let footers = parquet_footers(&paths)?;
1950 measured = footers.rows;
1951 counted = footers.distincts;
1952 bounded = footers.zones;
1953 footers.fields
1954 }
1955 };
1956 if options.all_varchar {
1957 for field in &mut fields {
1962 field.ty = LogicalType::Varchar;
1963 }
1964 }
1965 if options.binary_as_string {
1966 for field in &mut fields {
1971 if field.ty == LogicalType::Blob {
1972 field.ty = LogicalType::Varchar;
1973 }
1974 }
1975 }
1976 if options.file_row_number {
1977 if fields.iter().any(|field| field.name == FILE_ROW_NUMBER) {
1983 return Err(Error::binder(format!(
1984 "Duplicate column name \"{FILE_ROW_NUMBER}\": the file already has a \
1985 column of that name, so file_row_number cannot add one"
1986 )));
1987 }
1988 fields.push(Field::required(FILE_ROW_NUMBER.to_string(), LogicalType::BigInt));
1989 }
1990 cast = paths.iter().map(|path| self.path_constant(path)).collect();
1991 fields
1992 }
1993 };
1994 let label = if alias == NONE {
1995 resolved.function.name().to_string()
1996 } else {
1997 ast.string(alias).to_string()
1998 };
1999 let names: Vec<&str> = ast.name(columns).collect();
2000 self.table_function_source(
2001 resolved.function,
2002 &cast,
2003 &written_options,
2004 Read { fields, rows: measured, distincts: counted, zones: bounded },
2005 &label,
2006 &names,
2007 )
2008 }
2009
2010 fn bind_pragma(
2023 &mut self,
2024 ast: &Ast,
2025 function: TableFunction,
2026 fields: &[Field],
2027 argument: ExprRef,
2028 alias: ast::StrRef,
2029 columns: ast::Slice,
2030 ) -> Result<(NodeRef, Scope)> {
2031 let written = self.pragma_name(argument, function)?;
2032 let parts = identifier_parts(&written);
2033 let spelled: Vec<&str> = parts.iter().map(String::as_str).collect();
2034 let name = self.catalog.resolve(&spelled)?;
2035 let described = self.described(ast, &name)?;
2036 let mut rows = Vec::with_capacity(described.len());
2037 for (at, field) in described.iter().enumerate() {
2038 let items = if matches!(function, TableFunction::PragmaShow) {
2039 self.describing(field)
2040 } else {
2041 self.table_info(at, field)
2042 };
2043 rows.push(self.plan.add_expr_list(&items));
2044 }
2045 let rows = self.plan.add_rows(&rows);
2046 let held = self.plan.add_fields(fields);
2047 let index = self.fresh_index();
2048 let node = self.add_node(Node::Values { index, columns: held, rows });
2049 let label =
2050 if alias == NONE { function.name().to_string() } else { ast.string(alias).to_string() };
2051 let mut scope = Scope::empty();
2052 for (at, field) in fields.iter().enumerate() {
2053 scope.push(Visible {
2054 table: label.clone(),
2055 name: field.name.clone(),
2056 binding: ColumnBinding::new(index, at as u32),
2057 ty: field.ty.clone(),
2058 not_null: false,
2059 });
2060 }
2061 if !columns.is_empty() {
2062 let names: Vec<&str> = ast.name(columns).collect();
2063 scope.rename(&names, &label)?;
2064 }
2065 Ok((node, scope))
2066 }
2067
2068 fn pragma_name(&self, argument: ExprRef, function: TableFunction) -> Result<String> {
2078 let Expr::Constant(reference) = *self.plan.expr(argument) else {
2079 return Err(Error::not_implemented(format!(
2080 "{}() given a name that is not a constant",
2081 function.name()
2082 )));
2083 };
2084 match self.plan.value(reference) {
2085 Value::Varchar(name) => Ok(name.clone()),
2086 Value::Null => Ok("NULL".to_string()),
2087 other => {
2088 Err(Error::internal(format!("a pragma name bound as VARCHAR arrived as {other}")))
2089 }
2090 }
2091 }
2092
2093 fn described(&mut self, ast: &Ast, name: &QualifiedName) -> Result<Vec<Field>> {
2104 if self.catalog.entry(name)? == Entry::Table {
2105 return Ok(self.catalog.table(name)?.columns().to_vec());
2106 }
2107 let (_, scope) = self.bind_view(ast, name, NONE, ast::Slice::default())?;
2108 Ok(scope.fields())
2109 }
2110
2111 fn describing(&mut self, field: &Field) -> Vec<ExprRef> {
2113 let written = [
2114 field.name.clone(),
2115 field.ty.to_string(),
2116 if field.not_null { "NO" } else { "YES" }.to_owned(),
2117 ];
2118 let mut items: Vec<ExprRef> =
2119 written.into_iter().map(|text| self.plan.add_constant(Value::Varchar(text))).collect();
2120 for _ in 0..3 {
2121 let empty = self.plan.add_constant(Value::Null);
2122 items.push(self.cast_to(empty, &LogicalType::Varchar));
2123 }
2124 items
2125 }
2126
2127 fn table_info(&mut self, at: usize, field: &Field) -> Vec<ExprRef> {
2133 let cid = self.plan.add_constant(Value::Integer(i32::try_from(at).unwrap_or(i32::MAX)));
2134 let name = self.plan.add_constant(Value::Varchar(field.name.clone()));
2135 let ty = self.plan.add_constant(Value::Varchar(field.ty.to_string()));
2136 let not_null = self.plan.add_constant(Value::Boolean(field.not_null));
2137 let default = self.plan.add_constant(Value::Null);
2138 let default = self.cast_to(default, &LogicalType::Varchar);
2139 let key = self.plan.add_constant(Value::Boolean(false));
2140 vec![cid, name, ty, not_null, default, key]
2141 }
2142
2143 fn named_argument(
2157 &mut self,
2158 function: TableFunction,
2159 name: &str,
2160 expr: ExprRef,
2161 ) -> Result<(&'static str, Value)> {
2162 let known = function
2163 .parameters()
2164 .iter()
2165 .find(|(parameter, _)| parameter.eq_ignore_ascii_case(name));
2166 let Some((parameter, wanted)) = known else {
2167 let candidates: Vec<String> = function
2168 .parameters()
2169 .iter()
2170 .map(|(parameter, ty)| format!(" {parameter} {ty}"))
2171 .collect();
2172 return Err(Error::binder(format!(
2173 "Invalid named parameter \"{name}\" for function {}\nCandidates:\n{}\n",
2174 function.name(),
2175 candidates.join("\n")
2176 )));
2177 };
2178 let Expr::Constant(reference) = *self.plan.expr(expr) else {
2179 return Err(Error::not_implemented(format!(
2180 "the named parameter {parameter} with a value that is not a constant"
2181 )));
2182 };
2183 let value = self.plan.value(reference).clone();
2184 if value == Value::Null {
2185 return Err(Error::binder(null_parameter(function, parameter)));
2186 }
2187 let given = self.plan.expr_type(expr).clone();
2188 if given != *wanted {
2189 return Err(Error::not_implemented(format!(
2190 "the named parameter {parameter} given a {given} where a {wanted} was wanted"
2191 )));
2192 }
2193 Ok((parameter, value))
2194 }
2195
2196 fn bind_replacement_scan(
2207 &mut self,
2208 ast: &Ast,
2209 parts: &[&str],
2210 alias: ast::StrRef,
2211 columns: ast::Slice,
2212 missing: Error,
2213 ) -> Result<(NodeRef, Scope)> {
2214 let [path] = parts else { return Err(missing) };
2215 let path = *path;
2216 let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
2217 let Some(function) = Self::reader_for(extension) else {
2218 if is_file(path) {
2219 return Err(Error::binder(format!(
2224 "No extension found that is capable of reading the file \"{path}\"\n* If this \
2225 file is a supported file format you can explicitly use the reader functions, \
2226 such as read_csv, read_json or read_parquet"
2227 )));
2228 }
2229 return Err(missing);
2230 };
2231 let paths = files(path)?;
2236 let read = match function {
2237 TableFunction::ReadParquet => {
2238 let footers = parquet_footers(&paths)?;
2239 Read {
2240 fields: footers.fields,
2241 rows: footers.rows,
2242 distincts: footers.distincts,
2243 zones: footers.zones,
2244 }
2245 }
2246 _ => Read::uncounted(csv_fields(&paths, Given::default())?),
2247 };
2248 let label = if alias == NONE {
2254 if is_pattern(path) {
2255 path.to_string()
2256 } else {
2257 let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
2258 file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
2259 }
2260 } else {
2261 ast.string(alias).to_string()
2262 };
2263 let arguments: Vec<ExprRef> = paths.iter().map(|path| self.path_constant(path)).collect();
2264 let names: Vec<&str> = ast.name(columns).collect();
2265 self.table_function_source(function, &arguments, &[], read, &label, &names)
2266 }
2267
2268 fn path_constant(&mut self, path: &str) -> ExprRef {
2270 let value = self.plan.add_value(Value::Varchar(path.to_string()));
2271 self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar)
2272 }
2273
2274 fn reader_for(extension: &str) -> Option<TableFunction> {
2281 if extension.eq_ignore_ascii_case("parquet") {
2282 return Some(TableFunction::ReadParquet);
2283 }
2284 if extension.eq_ignore_ascii_case("csv") || extension.eq_ignore_ascii_case("tsv") {
2285 return Some(TableFunction::ReadCsv);
2286 }
2287 None
2288 }
2289
2290 fn table_function_source(
2300 &mut self,
2301 function: TableFunction,
2302 args: &[ExprRef],
2303 written: &[(&'static str, Value, ExprRef)],
2304 read: Read,
2305 label: &str,
2306 names: &[&str],
2307 ) -> Result<(NodeRef, Scope)> {
2308 let Read { fields, rows, distincts, zones } = read;
2309 let index = self.fresh_index();
2310 if rows.is_known() {
2315 self.plan.measure(index, rows);
2316 }
2317 for (column, distinct) in distincts {
2318 self.plan.measure_distinct(index, &column, distinct);
2319 }
2320 if let Some(zones) = zones {
2321 self.plan.set_zones(index, zones);
2322 }
2323 let mut scope = Scope::empty();
2324 for (at, field) in fields.iter().enumerate() {
2325 scope.push(Visible {
2326 table: label.to_string(),
2327 name: field.name.clone(),
2328 binding: ColumnBinding::new(index, at as u32),
2329 ty: field.ty.clone(),
2330 not_null: false,
2333 });
2334 }
2335 if !names.is_empty() {
2336 scope.rename(names, label)?;
2337 }
2338 let function = self.plan.intern(function.name());
2339 let args = self.plan.add_expr_list(args);
2340 let named: Vec<u32> =
2341 written.iter().map(|(parameter, _, _)| self.plan.intern(parameter)).collect();
2342 let settings: Vec<ExprRef> = written.iter().map(|(_, _, expr)| *expr).collect();
2343 let options = self.plan.add_name_list(&named);
2344 let settings = self.plan.add_expr_list(&settings);
2345 let columns = self.plan.add_fields(&fields);
2346 let node = self.add_node(Node::TableFunction {
2347 index,
2348 function,
2349 args,
2350 options,
2351 settings,
2352 columns,
2353 });
2354 Ok((node, scope))
2355 }
2356
2357 fn file_paths(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
2364 let mut paths = Vec::new();
2365 for pattern in self.file_patterns(expr, name)? {
2366 paths.extend(files(&pattern)?);
2367 }
2368 Ok(paths)
2369 }
2370
2371 fn file_patterns(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
2383 let Expr::Constant(reference) = *self.plan.expr(expr) else {
2384 return Err(Error::not_implemented(
2385 "a table function file name that is not a constant",
2386 ));
2387 };
2388 match self.plan.value(reference) {
2389 Value::Varchar(path) => Ok(vec![path.clone()]),
2390 Value::Null => Err(Error::parser(format!("{name} cannot take NULL list as parameter"))),
2392 Value::List { values, .. } => values
2393 .iter()
2394 .map(|value| match value {
2395 Value::Varchar(path) => Ok(path.clone()),
2396 _ => Err(Error::parser(format!(
2397 "{name} reader cannot take NULL input as parameter"
2398 ))),
2399 })
2400 .collect(),
2401 other => {
2402 Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
2403 }
2404 }
2405 }
2406
2407 fn side_of(
2425 &self,
2426 pending: &PendingSubquery,
2427 left_tables: &[u32],
2428 right_tables: &[u32],
2429 ) -> Option<Side> {
2430 let mut needs_left = false;
2431 let mut needs_right = false;
2432 let mut note = |binding: ColumnBinding| {
2433 needs_left |= left_tables.contains(&binding.table);
2434 needs_right |= right_tables.contains(&binding.table);
2435 };
2436 for &binding in &pending.reads {
2437 note(binding);
2438 }
2439 for &condition in &pending.conditions {
2444 self.plan.read_columns(condition, &mut |_, binding| note(binding));
2445 }
2446 match (needs_left, needs_right) {
2447 (true, true) => None,
2448 (_, true) => Some(Side::Right),
2449 _ => Some(Side::Left),
2450 }
2451 }
2452
2453 #[allow(clippy::too_many_arguments)]
2474 fn bind_pair_dependent_join(
2475 &mut self,
2476 kind: ast::JoinKind,
2477 independent: bool,
2478 left: NodeRef,
2479 right: NodeRef,
2480 pair: Vec<PendingSubquery>,
2481 conditions: Vec<ExprRef>,
2482 scope: Scope,
2483 ) -> Result<(NodeRef, Scope)> {
2484 if kind != ast::JoinKind::Inner {
2485 return Err(Error::not_implemented(
2486 "a subquery that reads both sides of that join, written in the condition of a join \
2487 that is not an inner join"
2488 .to_string(),
2489 ));
2490 }
2491 if !independent {
2494 return Err(Error::not_implemented(
2495 "a subquery that reads both sides of that join, written in the condition of a join \
2496 whose right side is lateral"
2497 .to_string(),
2498 ));
2499 }
2500 let mut node = self.add_node(Node::CrossProduct { left, right });
2501 for pending in pair {
2502 node = self.attach_subquery(node, pending);
2503 }
2504 let mut conditions = conditions.into_iter();
2508 let mut predicate = conditions.next().expect("a join condition was bound");
2509 for next in conditions {
2510 let children = self.plan.add_expr_list(&[predicate, next]);
2511 let conjunction = Expr::Conjunction { op: ConjunctionOp::And, children };
2512 predicate = self.plan.add_expr(conjunction, LogicalType::Boolean);
2513 }
2514 let node = self.add_node(Node::Filter { input: node, predicate });
2515 Ok((node, scope))
2516 }
2517
2518 #[allow(clippy::too_many_arguments)]
2519 fn bind_join(
2520 &mut self,
2521 ast: &Ast,
2522 left: ast::SourceRef,
2523 right: ast::SourceRef,
2524 kind: ast::JoinKind,
2525 natural: bool,
2526 on: ast::ExprRef,
2527 using: ast::Slice,
2528 ) -> Result<(NodeRef, Scope)> {
2529 let (left_node, left_scope) = self.bind_source(ast, left)?;
2530 let (right_node, right_scope, correlated) = self.bind_lateral(ast, right, &left_scope)?;
2531 if !correlated.is_empty()
2535 && !matches!(kind, ast::JoinKind::Inner | ast::JoinKind::Cross | ast::JoinKind::Left)
2536 {
2537 return Err(Error::binder(
2538 "The combining JOIN type must be INNER or LEFT for a LATERAL reference",
2539 ));
2540 }
2541 let split = left_scope.len();
2542 let left_tables: Vec<u32> =
2548 left_scope.columns.iter().map(|column| column.binding.table).collect();
2549 let right_tables: Vec<u32> =
2550 right_scope.columns.iter().map(|column| column.binding.table).collect();
2551 let mut scope = left_scope.concat(right_scope);
2552
2553 let merged: Vec<String> = if natural {
2556 let mut names = Vec::new();
2557 for (at, column) in scope.columns.iter().enumerate().take(split) {
2558 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
2559 && !names.iter().any(|held: &String| same_name(held, &column.name))
2560 {
2561 let _ = at;
2562 names.push(column.name.clone());
2563 }
2564 }
2565 names
2566 } else {
2567 let mut names: Vec<String> = Vec::new();
2573 for name in ast.name(using) {
2574 if !names.iter().any(|held| same_name(held, name)) {
2575 names.push(name.to_string());
2576 }
2577 }
2578 names
2579 };
2580
2581 let mut conditions = Vec::new();
2582 let mut dropped = Vec::new();
2583 for name in &merged {
2584 let left_at = scope.columns[..split]
2585 .iter()
2586 .position(|column| same_name(&column.name, name))
2587 .ok_or_else(|| {
2588 Error::binder(format!(
2589 "column \"{name}\" specified in USING clause does not exist in left table"
2590 ))
2591 })?;
2592 let right_at = scope.columns[split..]
2593 .iter()
2594 .position(|column| same_name(&column.name, name))
2595 .map(|at| at + split)
2596 .ok_or_else(|| {
2597 Error::binder(format!(
2598 "column \"{name}\" specified in USING clause does not exist in right table"
2599 ))
2600 })?;
2601 let left_column = &scope.columns[left_at];
2602 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
2603 let right_column = &scope.columns[right_at];
2604 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
2605 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
2606 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
2607 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
2608 dropped.push(right_at);
2609 }
2610 dropped.sort_unstable();
2613 for at in dropped.into_iter().rev() {
2614 scope.remove(at);
2615 }
2616
2617 let mut left_node = left_node;
2618 let mut right_node = right_node;
2619 let mut pair = Vec::new();
2620 if on != NONE {
2621 if !merged.is_empty() {
2622 return Err(Error::binder("a join cannot have both ON and USING"));
2623 }
2624 self.clause = "JOIN condition";
2625 let waiting = self.scalar_subqueries.len();
2626 let predicate = self.bind_expr(ast, on, &scope)?;
2627 conditions.push(self.as_boolean(predicate, "JOIN")?);
2628 for pending in self.scalar_subqueries.split_off(waiting) {
2629 match self.side_of(&pending, &left_tables, &right_tables) {
2630 Some(Side::Right) => right_node = self.attach_subquery(right_node, pending),
2631 Some(Side::Left) => left_node = self.attach_subquery(left_node, pending),
2632 None => pair.push(pending),
2633 }
2634 }
2635 }
2636
2637 if kind == ast::JoinKind::Cross && !conditions.is_empty() {
2638 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
2639 }
2640 if !pair.is_empty() {
2641 return self.bind_pair_dependent_join(
2642 kind,
2643 correlated.is_empty(),
2644 left_node,
2645 right_node,
2646 pair,
2647 conditions,
2648 scope,
2649 );
2650 }
2651 if correlated.is_empty()
2655 && conditions.is_empty()
2656 && matches!(kind, ast::JoinKind::Cross | ast::JoinKind::Inner)
2657 {
2658 let node = self.add_node(Node::CrossProduct { left: left_node, right: right_node });
2659 return Ok((node, scope));
2660 }
2661 if matches!(kind, ast::JoinKind::Semi | ast::JoinKind::Anti) {
2670 scope.truncate(split);
2671 }
2672 let kind = match kind {
2673 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
2674 ast::JoinKind::Left => JoinKind::Left,
2675 ast::JoinKind::Right => JoinKind::Right,
2676 ast::JoinKind::Full => JoinKind::Full,
2677 ast::JoinKind::Semi => JoinKind::Semi,
2678 ast::JoinKind::Anti => JoinKind::Anti,
2679 ast::JoinKind::Positional => JoinKind::Positional,
2680 };
2681 let conditions = self.plan.add_expr_list(&conditions);
2682 let node = if correlated.is_empty() {
2683 self.add_node(Node::Join {
2684 left: left_node,
2685 right: right_node,
2686 kind,
2687 conditions,
2688 build: BuildSide::default(),
2689 })
2690 } else {
2691 self.add_node(Node::DependentJoin {
2692 left: left_node,
2693 right: right_node,
2694 kind,
2695 conditions,
2696 })
2697 };
2698 Ok((node, scope))
2699 }
2700
2701 fn bind_filter(
2709 &mut self,
2710 ast: &Ast,
2711 filter: ast::ExprRef,
2712 scope: &Scope,
2713 ) -> Result<Option<ExprRef>> {
2714 if filter == NONE {
2715 return Ok(None);
2716 }
2717 let bound = self.bind_expr(ast, filter, scope)?;
2718 Ok(Some(self.checked_cast_to(bound, &LogicalType::Boolean, false)?))
2719 }
2720
2721 pub(crate) fn bind_aggregate(
2723 &mut self,
2724 ast: &Ast,
2725 name: &str,
2726 args: &[ast::ExprRef],
2727 distinct: bool,
2728 filter: ast::ExprRef,
2729 scope: &Scope,
2730 ) -> Result<ExprRef> {
2731 if self.in_filter {
2732 return Err(Error::binder("aggregate functions are not allowed in FILTER"));
2733 }
2734 if self.in_aggregate {
2735 return Err(Error::binder(format!(
2736 "aggregate function calls cannot be nested, and {name}() is inside one"
2737 )));
2738 }
2739 if self.aggregation.is_none() {
2740 return Err(Error::binder(format!(
2741 "aggregate function calls cannot be used in the {}",
2742 self.clause
2743 )));
2744 }
2745 self.in_aggregate = true;
2750 self.in_filter = true;
2751 let filter = self.bind_filter(ast, filter, scope);
2752 self.in_filter = false;
2753 self.in_aggregate = false;
2754 let filter = filter?;
2755
2756 self.in_aggregate = true;
2757 let mut bound = Vec::with_capacity(args.len());
2758 let mut failure = None;
2759 for &arg in args {
2760 match self.bind_expr(ast, arg, scope) {
2761 Ok(expr) => bound.push(expr),
2762 Err(error) => {
2763 failure = Some(error);
2764 break;
2765 }
2766 }
2767 }
2768 self.in_aggregate = false;
2769 if let Some(error) = failure {
2770 return Err(error);
2771 }
2772
2773 let types: Vec<LogicalType> =
2774 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
2775 let resolved = resolve(name, &types)?;
2776 let mut cast = Vec::with_capacity(bound.len());
2777 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
2778 cast.push(self.checked_cast_to(*arg, wanted, false)?);
2779 }
2780 let args = self.plan.add_expr_list(&cast);
2781 let name = self.plan.intern(resolved.name);
2782 let ty = resolved.returns;
2783 let call = self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter }, ty.clone());
2784
2785 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
2788 let existing = existing.unwrap_or_default();
2789 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
2790 Some(at) => at,
2791 None => {
2792 let aggregation = self.aggregation.as_mut().expect("checked above");
2793 aggregation.aggregates.push(call);
2794 aggregation.aggregates.len() - 1
2795 }
2796 };
2797 let aggregation = self.aggregation.as_ref().expect("checked above");
2798 let (index, groups) = (aggregation.index, aggregation.groups.len());
2799 Ok(self.column(index, groups + at, ty))
2800 }
2801
2802 pub(crate) fn bind_window(
2810 &mut self,
2811 ast: &Ast,
2812 written: &WindowCall<'_>,
2813 scope: &Scope,
2814 ) -> Result<ExprRef> {
2815 let WindowCall { name, args, distinct, filter, ignore_nulls, spec, .. } = *written;
2816 if self.in_aggregate {
2817 return Err(Error::binder(
2818 "aggregate function calls cannot contain window function calls",
2819 ));
2820 }
2821 if self.in_window {
2822 return Err(Error::binder("window function calls cannot be nested"));
2823 }
2824 let clause = if self.clause == "JOIN condition" { "WHERE clause" } else { self.clause };
2828 if clause != "SELECT clause" && clause != "ORDER BY clause" {
2829 return Err(Error::binder(format!("{clause} cannot contain window functions!")));
2830 }
2831
2832 let starred = args.iter().any(|&arg| {
2836 matches!(ast.expr(arg), ast::Expr::Star { qualifier, replacements }
2837 if qualifier.is_empty() && replacements.is_empty())
2838 });
2839 let (name, args): (&str, &[ast::ExprRef]) = if starred {
2840 if !same_name(name, "count") || args.len() != 1 {
2841 return Err(Error::binder(format!("* is not allowed in {name}()")));
2842 }
2843 ("count_star", &[])
2844 } else if same_name(name, "count") && args.is_empty() {
2845 ("count_star", &[])
2848 } else {
2849 (name, args)
2850 };
2851
2852 let held = ast.window(spec);
2853 self.in_window = true;
2854 let parts = self.window_parts(ast, written, args, held, scope);
2855 let filter = if parts.is_ok() { self.bind_filter(ast, filter, scope) } else { Ok(None) };
2860 self.in_window = false;
2861 let parts = parts?;
2862 let filter = filter?;
2863 let offsets = [parts.frame.start, parts.frame.end]
2866 .iter()
2867 .any(|end| matches!(end, WindowBound::Preceding(_) | WindowBound::Following(_)));
2868 if parts.frame.unit == WindowUnit::Range && offsets && parts.order.len() != 1 {
2869 return Err(Error::binder("RANGE frames must have only one ORDER BY expression"));
2870 }
2871
2872 let types: Vec<LogicalType> =
2873 parts.args.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
2874 let resolved = window_signature(name, &types)?;
2875 if resolved.name == "fill" {
2878 let keys: Vec<LogicalType> =
2879 parts.order.iter().map(|key| self.plan.expr_type(key.expr).clone()).collect();
2880 refuse_fill(&types[0], &keys, distinct, ignore_nulls)?;
2881 }
2882 if distinct && kind_of(resolved.name) == Some(FunctionKind::Window) {
2886 return Err(Error::binder(format!(
2887 "DISTINCT is not implemented for the window function \"\"{name}\"\""
2888 )));
2889 }
2890 if filter.is_some() && kind_of(resolved.name) == Some(FunctionKind::Window) {
2893 return Err(Error::binder(format!(
2894 "FILTER is not implemented for the window function \"\"{name}\"\""
2895 )));
2896 }
2897 if !parts.inner.is_empty() && kind_of(resolved.name) == Some(FunctionKind::Window) {
2905 let counts = matches!(resolved.name, "first_value" | "last_value" | "nth_value");
2906 if !counts {
2907 if parts.frame.exclude != WindowExclude::NoOthers {
2908 return Err(Error::binder(format!(
2909 "EXCLUDE is not supported for the window function \"\"{}\"\"",
2910 resolved.name
2911 )));
2912 }
2913 return Err(Error::not_implemented(format!(
2914 "ORDER BY inside the arguments of the window function \"{}\"",
2915 resolved.name
2916 )));
2917 }
2918 }
2919 let mut cast = Vec::with_capacity(parts.args.len());
2920 for (arg, wanted) in parts.args.iter().zip(&resolved.arguments) {
2921 cast.push(self.checked_cast_to(*arg, wanted, false)?);
2922 }
2923 let args = self.plan.add_expr_list(&cast);
2924 let order = self.plan.add_sort_keys(&parts.inner);
2925 let name = self.plan.intern(resolved.name);
2926 let ty = resolved.returns;
2927 let call = self.plan.add_expr(
2928 Expr::Window { name, args, distinct, filter, ignore_nulls, order },
2929 ty.clone(),
2930 );
2931
2932 let at = self.window_run(parts.partition, parts.order, parts.frame, call);
2933 let index = self.windows.last().expect("the run was just filed").index;
2934 Ok(self.column(index, at, ty))
2935 }
2936
2937 fn window_run(
2944 &mut self,
2945 partition: Vec<ExprRef>,
2946 order: Vec<SortKey>,
2947 frame: WindowFrame,
2948 call: ExprRef,
2949 ) -> usize {
2950 let matches = self.windows.last().is_some_and(|run| {
2951 run.frame == frame
2952 && run.partition.len() == partition.len()
2953 && run.order.len() == order.len()
2954 && run.partition.iter().zip(&partition).all(|(&l, &r)| self.same_expr(l, r))
2955 && run.order.iter().zip(&order).all(|(l, r)| {
2956 l.descending == r.descending
2957 && l.nulls_first == r.nulls_first
2958 && self.same_expr(l.expr, r.expr)
2959 })
2960 });
2961 if !matches {
2962 let index = self.fresh_index();
2963 self.windows.push(WindowRun { index, partition, order, frame, calls: Vec::new() });
2964 }
2965 let calls = self.windows.last().expect("a run is open").calls.clone();
2968 if let Some(at) = calls.iter().position(|&held| self.same_expr(held, call)) {
2969 return at;
2970 }
2971 let run = self.windows.last_mut().expect("a run is open");
2972 run.calls.push(call);
2973 run.calls.len() - 1
2974 }
2975
2976 fn window_parts(
2982 &mut self,
2983 ast: &Ast,
2984 written: &WindowCall<'_>,
2985 args: &[ast::ExprRef],
2986 held: ast::WindowSpec,
2987 scope: &Scope,
2988 ) -> Result<WindowParts> {
2989 let mut bound = Vec::with_capacity(args.len());
2990 for &arg in args {
2991 let expr = self.bind_expr(ast, arg, scope)?;
2992 bound.push(self.over_aggregate(expr, scope)?);
2993 }
2994 let mut inner = Vec::new();
2998 for item in ast.order_list(written.order).to_vec() {
2999 let expr = self.bind_expr(ast, item.expr, scope)?;
3000 let expr = self.over_aggregate(expr, scope)?;
3001 inner.push(self.sort_key(expr, item));
3002 }
3003 let mut partition = Vec::new();
3004 for &key in ast.expr_list(held.partition) {
3005 let expr = self.bind_expr(ast, key, scope)?;
3006 partition.push(self.over_aggregate(expr, scope)?);
3007 }
3008 let mut order = Vec::new();
3009 for item in ast.order_list(held.order).to_vec() {
3010 let expr = self.bind_expr(ast, item.expr, scope)?;
3011 let expr = self.over_aggregate(expr, scope)?;
3012 order.push(self.sort_key(expr, item));
3013 }
3014 let frame = WindowFrame {
3015 unit: match held.unit {
3016 ast::WindowUnit::Rows => WindowUnit::Rows,
3017 ast::WindowUnit::Range => WindowUnit::Range,
3018 ast::WindowUnit::Groups => WindowUnit::Groups,
3019 },
3020 start: self.window_bound(ast, held.start, scope)?,
3021 end: self.window_bound(ast, held.end, scope)?,
3022 exclude: match held.exclude {
3023 ast::WindowExclude::NoOthers => WindowExclude::NoOthers,
3024 ast::WindowExclude::CurrentRow => WindowExclude::CurrentRow,
3025 ast::WindowExclude::Group => WindowExclude::Group,
3026 ast::WindowExclude::Ties => WindowExclude::Ties,
3027 },
3028 };
3029 Ok(WindowParts { args: bound, partition, order, inner, frame })
3030 }
3031
3032 fn window_bound(
3034 &mut self,
3035 ast: &Ast,
3036 bound: ast::WindowBound,
3037 scope: &Scope,
3038 ) -> Result<WindowBound> {
3039 let offset = |binder: &mut Self, written| {
3040 let expr = binder.bind_expr(ast, written, scope)?;
3041 binder.over_aggregate(expr, scope)
3042 };
3043 Ok(match bound {
3044 ast::WindowBound::UnboundedPreceding => WindowBound::UnboundedPreceding,
3045 ast::WindowBound::CurrentRow => WindowBound::CurrentRow,
3046 ast::WindowBound::UnboundedFollowing => WindowBound::UnboundedFollowing,
3047 ast::WindowBound::Preceding(written) => WindowBound::Preceding(offset(self, written)?),
3048 ast::WindowBound::Following(written) => WindowBound::Following(offset(self, written)?),
3049 })
3050 }
3051
3052 fn is_pending_subquery(&self, binding: ColumnBinding) -> bool {
3054 self.scalar_subqueries.iter().any(|pending| pending.index == binding.table)
3055 }
3056
3057 fn is_window_output(&self, binding: ColumnBinding) -> bool {
3059 self.windows.iter().any(|run| run.index == binding.table)
3060 }
3061
3062 fn is_correlation(&self, binding: ColumnBinding) -> bool {
3068 self.correlations.last().is_some_and(|frame| frame.contains(&binding))
3069 }
3070
3071 fn name_of(&self, binding: ColumnBinding, scope: &Scope) -> String {
3077 std::iter::once(scope)
3078 .chain(self.outer_scopes.iter().rev())
3079 .flat_map(|visible| visible.columns.iter())
3080 .find(|column| column.binding == binding)
3081 .map_or_else(|| "a column".to_string(), |column| format!("\"{}\"", column.name))
3082 }
3083
3084 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
3090 let Some(aggregation) = self.aggregation.as_ref() else {
3091 return Ok(expr);
3092 };
3093 let index = aggregation.index;
3094 let groups = aggregation.groups.clone();
3095 for (at, group) in groups.iter().enumerate() {
3096 if self.same_expr(expr, *group) {
3097 let ty = self.plan.expr_type(*group).clone();
3098 return Ok(self.column(index, at, ty));
3099 }
3100 }
3101 let ty = self.plan.expr_type(expr).clone();
3102 match self.plan.expr(expr).clone() {
3103 Expr::Column(binding) if binding.table == index => Ok(expr),
3104 Expr::Column(binding) if self.is_window_output(binding) => Ok(expr),
3109 Expr::Column(binding) if self.joined_above.contains(&binding.table) => Ok(expr),
3114 Expr::Column(binding) if self.is_correlation(binding) => Ok(expr),
3120 Expr::Column(binding) if self.is_pending_subquery(binding) => Err(Error::binder(
3129 "a correlated subquery over a grouped query is not supported here yet",
3130 )),
3131 Expr::Column(binding) => {
3132 let name = self.name_of(binding, scope);
3133 Err(Error::binder(format!(
3134 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
3135 )))
3136 }
3137 Expr::Constant(_) | Expr::Aggregate { .. } | Expr::Window { .. } => Ok(expr),
3138 Expr::Cast { input, try_cast } => {
3139 let input = self.over_aggregate(input, scope)?;
3140 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
3141 }
3142 Expr::Compare { op, left, right } => {
3143 let left = self.over_aggregate(left, scope)?;
3144 let right = self.over_aggregate(right, scope)?;
3145 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
3146 }
3147 Expr::Conjunction { op, children } => {
3148 let written = self.plan.expr_list(children).to_vec();
3149 let mut rewritten = Vec::with_capacity(written.len());
3150 for child in written {
3151 rewritten.push(self.over_aggregate(child, scope)?);
3152 }
3153 let children = self.plan.add_expr_list(&rewritten);
3154 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
3155 }
3156 Expr::Function { name, args } => {
3157 let written = self.plan.expr_list(args).to_vec();
3158 let mut rewritten = Vec::with_capacity(written.len());
3159 for arg in written {
3160 rewritten.push(self.over_aggregate(arg, scope)?);
3161 }
3162 let args = self.plan.add_expr_list(&rewritten);
3163 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
3164 }
3165 Expr::Case { arms, otherwise } => {
3166 let written = self.plan.arm_list(arms).to_vec();
3167 let mut rewritten = Vec::with_capacity(written.len());
3168 for arm in written {
3169 let when = self.over_aggregate(arm.when, scope)?;
3170 let then = self.over_aggregate(arm.then, scope)?;
3171 rewritten.push(rudb_plan::Arm { when, then });
3172 }
3173 let otherwise = match otherwise {
3174 Some(expr) => Some(self.over_aggregate(expr, scope)?),
3175 None => None,
3176 };
3177 let arms = self.plan.add_arms(&rewritten);
3178 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
3179 }
3180 }
3181 }
3182
3183 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
3185 same_expr(&self.plan, left, right)
3186 }
3187}
3188
3189#[derive(Debug, Default)]
3199struct Options {
3200 binary_as_string: bool,
3203 all_varchar: bool,
3205 file_row_number: bool,
3210 given: Given,
3212}
3213
3214impl Options {
3215 fn of(written: &[(&'static str, Value, ExprRef)]) -> Result<Self> {
3222 let mut options = Self::default();
3223 for (parameter, value, _) in written {
3224 match (*parameter, value) {
3225 ("binary_as_string", Value::Boolean(on)) => options.binary_as_string = *on,
3226 ("all_varchar", Value::Boolean(on)) => options.all_varchar = *on,
3227 ("file_row_number", Value::Boolean(on)) => options.file_row_number = *on,
3228 _ => {}
3229 }
3230 }
3231 let named: Vec<(&str, Value)> =
3232 written.iter().map(|(parameter, value, _)| (*parameter, value.clone())).collect();
3233 options.given = csv_given(&named)?;
3234 Ok(options)
3235 }
3236}
3237
3238#[derive(Clone, Copy)]
3240struct Operator {
3241 op: SetOp,
3243 quantifier: Quantifier,
3245 by_name: bool,
3247}
3248
3249struct Merged {
3251 name: String,
3253 ty: LogicalType,
3255 left: Option<usize>,
3257 right: Option<usize>,
3259}
3260
3261fn match_by_position(left: &Scope, right: &Scope) -> Result<Vec<Merged>> {
3265 if left.len() != right.len() {
3266 return Err(Error::binder(format!(
3267 "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
3268 left.len(),
3269 right.len()
3270 )));
3271 }
3272 let mut merged = Vec::with_capacity(left.len());
3273 for (at, (held, other)) in left.columns.iter().zip(&right.columns).enumerate() {
3274 merged.push(Merged {
3275 name: held.name.clone(),
3276 ty: meet(&held.ty, &other.ty)?,
3277 left: Some(at),
3278 right: Some(at),
3279 });
3280 }
3281 Ok(merged)
3282}
3283
3284fn match_by_name(left: &Scope, right: &Scope) -> Result<Vec<Merged>> {
3292 named_once(left)?;
3293 named_once(right)?;
3294 let mut merged = Vec::with_capacity(left.len() + right.len());
3295 for (at, held) in left.columns.iter().enumerate() {
3296 let other = right.columns.iter().position(|column| same_name(&column.name, &held.name));
3297 let ty = match other {
3298 Some(other) => meet(&held.ty, &right.columns[other].ty)?,
3299 None => held.ty.clone(),
3300 };
3301 merged.push(Merged { name: held.name.clone(), ty, left: Some(at), right: other });
3302 }
3303 for (at, held) in right.columns.iter().enumerate() {
3304 if left.columns.iter().any(|column| same_name(&column.name, &held.name)) {
3305 continue;
3306 }
3307 merged.push(Merged {
3308 name: held.name.clone(),
3309 ty: held.ty.clone(),
3310 left: None,
3311 right: Some(at),
3312 });
3313 }
3314 Ok(merged)
3315}
3316
3317fn named_once(scope: &Scope) -> Result<()> {
3323 for (at, held) in scope.columns.iter().enumerate() {
3324 if scope.columns[..at].iter().any(|column| same_name(&column.name, &held.name)) {
3325 return Err(Error::binder(format!(
3326 "UNION (ALL) BY NAME operation doesn't support duplicate names in the SELECT list - the name \"\"{}\"\" occurs multiple times",
3327 held.name
3328 )));
3329 }
3330 }
3331 Ok(())
3332}
3333
3334fn meet(left: &LogicalType, right: &LogicalType) -> Result<LogicalType> {
3336 left.promote(right).ok_or_else(|| {
3337 Error::binder(format!(
3338 "Cannot combine a column of type {left} with a column of type {right} in a set operation"
3339 ))
3340 })
3341}
3342
3343fn null_parameter(function: TableFunction, parameter: &str) -> String {
3352 match parameter {
3353 "header" => format!("\"{parameter}\" expects a non-null boolean value (e.g. TRUE or 1)"),
3354 "all_varchar" => format!("{} \"{parameter}\" cannot be NULL", function.name()),
3355 _ => format!("Cannot use NULL as argument to \"{parameter}\""),
3356 }
3357}
3358
3359fn missing_replacement(name: &str, input: &Scope) -> Error {
3364 Error::binder(format!(
3365 "Column \"{name}\" in REPLACE list not found in FROM clause{}",
3366 input.candidates()
3367 ))
3368}
3369
3370fn subtractable(ty: &LogicalType, ordering: bool) -> bool {
3379 if ty.is_numeric() {
3380 return true;
3381 }
3382 match ty {
3383 LogicalType::Date
3384 | LogicalType::Time
3385 | LogicalType::Timestamp
3386 | LogicalType::TimestampS
3387 | LogicalType::TimestampMs
3388 | LogicalType::TimestampNs
3389 | LogicalType::TimestampTz => true,
3390 LogicalType::TimeTz => ordering,
3391 _ => false,
3392 }
3393}
3394
3395fn refuse_fill(
3404 argument: &LogicalType,
3405 order: &[LogicalType],
3406 distinct: bool,
3407 ignore_nulls: bool,
3408) -> Result<()> {
3409 if !subtractable(argument, false) {
3410 return Err(Error::binder("FILL argument must support subtraction"));
3411 }
3412 let [key] = order else {
3413 return Err(Error::binder("FILL functions must have only one ORDER BY expression"));
3414 };
3415 if !subtractable(key, true) {
3416 return Err(Error::binder("FILL ordering must support subtraction"));
3417 }
3418 if distinct {
3419 return Err(Error::binder(
3420 "DISTINCT is not implemented for the window function \"\"fill\"\"",
3421 ));
3422 }
3423 if ignore_nulls {
3424 return Err(Error::binder(
3425 "RESPECT/IGNORE NULLS is not supported for the window function \"fill\"",
3426 ));
3427 }
3428 Ok(())
3429}
3430
3431fn window_signature(name: &str, types: &[LogicalType]) -> Result<Resolved> {
3438 match kind_of(name) {
3439 Some(FunctionKind::Aggregate | FunctionKind::Window) => resolve(name, types),
3440 Some(FunctionKind::Scalar) => {
3441 Err(Error::catalog(format!("{name} is not an aggregate function")))
3442 }
3443 None => Err(Error::catalog(format!("Aggregate Function with name {name} does not exist!"))),
3444 }
3445}
3446
3447fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
3449 if left == right {
3450 return true;
3451 }
3452 if plan.expr_type(left) != plan.expr_type(right) {
3453 return false;
3454 }
3455 let lists = |left, right| {
3456 let left: &[ExprRef] = plan.expr_list(left);
3457 let right: &[ExprRef] = plan.expr_list(right);
3458 left.len() == right.len()
3459 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
3460 };
3461 match (plan.expr(left), plan.expr(right)) {
3462 (Expr::Column(left), Expr::Column(right)) => left == right,
3463 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
3464 (
3465 Expr::Cast { input: left, try_cast: left_try },
3466 Expr::Cast { input: right, try_cast: right_try },
3467 ) => left_try == right_try && same_expr(plan, *left, *right),
3468 (
3469 Expr::Compare { op: left_op, left: left_a, right: left_b },
3470 Expr::Compare { op: right_op, left: right_a, right: right_b },
3471 ) => {
3472 left_op == right_op
3473 && same_expr(plan, *left_a, *right_a)
3474 && same_expr(plan, *left_b, *right_b)
3475 }
3476 (
3477 Expr::Conjunction { op: left_op, children: left_children },
3478 Expr::Conjunction { op: right_op, children: right_children },
3479 ) => left_op == right_op && lists(*left_children, *right_children),
3480 (
3481 Expr::Function { name: left_name, args: left_args },
3482 Expr::Function { name: right_name, args: right_args },
3483 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
3484 (
3485 Expr::Aggregate {
3486 name: left_name,
3487 args: left_args,
3488 distinct: left_distinct,
3489 filter: left_filter,
3490 },
3491 Expr::Aggregate {
3492 name: right_name,
3493 args: right_args,
3494 distinct: right_distinct,
3495 filter: right_filter,
3496 },
3497 ) => {
3498 plan.string(*left_name) == plan.string(*right_name)
3499 && left_distinct == right_distinct
3500 && match (left_filter, right_filter) {
3501 (None, None) => true,
3502 (Some(left), Some(right)) => same_expr(plan, *left, *right),
3503 _ => false,
3504 }
3505 && lists(*left_args, *right_args)
3506 }
3507 (
3511 Expr::Window {
3512 name: left_name,
3513 args: left_args,
3514 distinct: left_distinct,
3515 filter: left_filter,
3516 ignore_nulls: left_nulls,
3517 order: left_order,
3518 },
3519 Expr::Window {
3520 name: right_name,
3521 args: right_args,
3522 distinct: right_distinct,
3523 filter: right_filter,
3524 ignore_nulls: right_nulls,
3525 order: right_order,
3526 },
3527 ) => {
3528 let left_keys = plan.sort_key_list(*left_order);
3531 let right_keys = plan.sort_key_list(*right_order);
3532 plan.string(*left_name) == plan.string(*right_name)
3533 && left_distinct == right_distinct
3534 && left_nulls == right_nulls
3535 && left_keys.len() == right_keys.len()
3536 && left_keys.iter().zip(right_keys).all(|(left, right)| {
3537 left.descending == right.descending
3538 && left.nulls_first == right.nulls_first
3539 && same_expr(plan, left.expr, right.expr)
3540 })
3541 && match (left_filter, right_filter) {
3542 (None, None) => true,
3543 (Some(left), Some(right)) => same_expr(plan, *left, *right),
3544 _ => false,
3545 }
3546 && lists(*left_args, *right_args)
3547 }
3548 (
3549 Expr::Case { arms: left_arms, otherwise: left_otherwise },
3550 Expr::Case { arms: right_arms, otherwise: right_otherwise },
3551 ) => {
3552 let left_arms = plan.arm_list(*left_arms);
3553 let right_arms = plan.arm_list(*right_arms);
3554 left_arms.len() == right_arms.len()
3555 && left_arms.iter().zip(right_arms).all(|(left, right)| {
3556 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
3557 })
3558 && match (left_otherwise, right_otherwise) {
3559 (None, None) => true,
3560 (Some(left), Some(right)) => same_expr(plan, *left, *right),
3561 _ => false,
3562 }
3563 }
3564 _ => false,
3565 }
3566}