1use rudb_catalog::{Catalog, Entry, QualifiedName, same_name};
16use rudb_common::{
17 Error, Field, LogicalType, Result, Semantics, Session, ShowBehavior, Span, Value,
18};
19use rudb_functions::{
20 Columns, FILE_ROW_NUMBER, FunctionKind, Given, Resolved, TableFunction, csv_fields, csv_given,
21 files, is_file, is_pattern, kind_of, parquet_fields, resolve, resolve_pragma, resolve_table,
22};
23use rudb_parse::ast::{self, Ast, Distinct, LiteralKind, Nulls, Order, Quantifier, SetOp};
24use rudb_parse::{NONE, identifier_parts, parse_ast_with_case};
25use rudb_plan::{
26 ColumnBinding, Expr, ExprRef, JoinKind, Node, NodeRef, Plan, SetOpKind, SortKey, WindowBound,
27 WindowExclude, WindowFrame, WindowUnit,
28};
29
30use crate::expr::{describe, has_aggregate};
31use crate::parameters::Parameters;
32use crate::scope::{Scope, Visible};
33
34pub fn bind(ast: &Ast, catalog: &Catalog) -> Result<Plan> {
41 bind_with(ast, catalog, &Parameters::new(), &Session::new())
42}
43
44pub fn bind_with(
53 ast: &Ast,
54 catalog: &Catalog,
55 parameters: &Parameters,
56 session: &Session,
57) -> Result<Plan> {
58 let query = match ast.statements.as_slice() {
59 [ast::Statement::Query(query)] => *query,
60 [] => return Err(Error::binder("no statement to bind")),
61 [_] => return Err(Error::not_implemented("a statement that is not a query")),
64 _ => return Err(Error::not_implemented("a script of more than one statement")),
65 };
66 let mut binder = Binder::with(catalog, parameters, session);
67 let (root, _) = binder.bind_query(ast, query)?;
68 let mut plan = binder.into_plan();
69 plan.set_root(root);
70 plan.validate()?;
71 Ok(plan)
72}
73
74pub fn bind_sql(query: &str, catalog: &Catalog) -> Result<Plan> {
80 bind_sql_with(query, catalog, &Session::new())
81}
82
83pub fn bind_sql_with(query: &str, catalog: &Catalog, session: &Session) -> Result<Plan> {
89 let ast = parse_ast_with_case(query, session.semantics().identifier_case())?;
90 bind_with(&ast, catalog, &Parameters::new(), session)
91}
92
93#[derive(Debug)]
95pub(crate) struct Aggregation {
96 pub(crate) index: u32,
98 pub(crate) groups: Vec<ExprRef>,
100 pub(crate) aggregates: Vec<ExprRef>,
102}
103
104#[derive(Debug)]
112pub(crate) struct WindowRun {
113 index: u32,
115 partition: Vec<ExprRef>,
117 order: Vec<SortKey>,
119 frame: WindowFrame,
121 calls: Vec<ExprRef>,
123}
124
125pub(crate) struct WindowCall<'a> {
130 pub(crate) name: &'a str,
132 pub(crate) args: &'a [ast::ExprRef],
134 pub(crate) distinct: bool,
136 pub(crate) ignore_nulls: bool,
138 pub(crate) spec: ast::WindowRef,
140}
141
142struct WindowParts {
144 args: Vec<ExprRef>,
146 partition: Vec<ExprRef>,
148 order: Vec<SortKey>,
150 frame: WindowFrame,
152}
153
154#[derive(Debug)]
155pub(crate) struct PendingSubquery {
156 pub(crate) node: NodeRef,
157 pub(crate) kind: JoinKind,
158 pub(crate) conditions: Vec<ExprRef>,
159 pub(crate) dependent: bool,
160}
161
162#[derive(Debug)]
164pub(crate) struct Binder<'a> {
165 catalog: &'a Catalog,
166 pub(crate) parameters: &'a Parameters,
168 pub(crate) session: &'a Session,
170 pub(crate) semantics: Semantics,
172 plan: Plan,
173 next_index: u32,
174 pub(crate) current_span: Span,
176 pub(crate) aggregation: Option<Aggregation>,
178 pub(crate) in_aggregate: bool,
180 pub(crate) windows: Vec<WindowRun>,
182 pub(crate) in_window: bool,
184 pub(crate) scalar_subqueries: Vec<PendingSubquery>,
186 pub(crate) outer_scopes: Vec<Scope>,
187 pub(crate) correlations: Vec<Vec<ColumnBinding>>,
188 pub(crate) clause: &'static str,
190 expanding: Vec<String>,
192 started: Option<i64>,
194}
195
196impl<'a> Binder<'a> {
197 pub(crate) fn with(
198 catalog: &'a Catalog,
199 parameters: &'a Parameters,
200 session: &'a Session,
201 ) -> Self {
202 Self {
203 catalog,
204 parameters,
205 session,
206 semantics: session.semantics(),
207 plan: Plan::new(),
208 next_index: 0,
209 current_span: Span::new(0, 0),
210 aggregation: None,
211 in_aggregate: false,
212 windows: Vec::new(),
213 in_window: false,
214 scalar_subqueries: Vec::new(),
215 outer_scopes: Vec::new(),
216 correlations: Vec::new(),
217 clause: "SELECT clause",
218 expanding: Vec::new(),
219 started: None,
220 }
221 }
222
223 pub(crate) fn catalog(&self) -> &Catalog {
224 self.catalog
225 }
226
227 pub(crate) fn instant(&mut self) -> i64 {
234 *self.started.get_or_insert_with(crate::context::micros_now)
235 }
236
237 pub(crate) fn plan(&self) -> &Plan {
238 &self.plan
239 }
240
241 pub(crate) fn plan_mut(&mut self) -> &mut Plan {
242 &mut self.plan
243 }
244
245 pub(crate) fn add_expr(&mut self, expr: Expr, ty: LogicalType) -> ExprRef {
246 self.plan.add_expr_at(expr, ty, self.current_span)
247 }
248
249 pub(crate) fn add_constant(&mut self, value: Value) -> ExprRef {
250 let ty = value.logical_type();
251 let reference = self.plan.add_value(value);
252 self.plan.add_expr_at(Expr::Constant(reference), ty, self.current_span)
253 }
254
255 pub(crate) fn add_node(&mut self, node: Node) -> NodeRef {
256 self.plan.add_node_at(node, self.current_span)
257 }
258
259 pub(crate) fn into_plan(self) -> Plan {
260 self.plan
261 }
262
263 pub(crate) fn fresh_index(&mut self) -> u32 {
265 let index = self.next_index;
266 self.next_index += 1;
267 index
268 }
269
270 fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
272 let binding = ColumnBinding::new(index, position as u32);
273 self.plan.add_expr(Expr::Column(binding), ty)
274 }
275
276 fn attach_scalar_subqueries(&mut self, mut input: NodeRef) -> NodeRef {
278 let subqueries = std::mem::take(&mut self.scalar_subqueries);
279 for pending in subqueries {
280 let PendingSubquery { node: mut right, kind, conditions, dependent } = pending;
281 if kind == JoinKind::Single && !self.semantics.scalar_subquery_error_on_multiple_rows()
282 {
283 right = self.add_node(Node::Limit { input: right, count: Some(1), offset: 0 });
284 }
285 let conditions = self.plan.add_expr_list(&conditions);
286 input = if dependent {
287 self.add_node(Node::DependentJoin { left: input, right, kind, conditions })
288 } else {
289 self.add_node(Node::Join { left: input, right, kind, conditions })
290 };
291 }
292 input
293 }
294
295 pub(crate) fn bind_query(
298 &mut self,
299 ast: &Ast,
300 query: ast::QueryRef,
301 ) -> Result<(NodeRef, Scope)> {
302 let span = ast.query_span(query);
303 let outer = std::mem::replace(&mut self.current_span, span);
304 let result =
305 self.bind_query_inner(ast, query).map_err(|error| error.with_fallback_span(span));
306 self.current_span = outer;
307 result
308 }
309
310 fn bind_query_inner(&mut self, ast: &Ast, query: ast::QueryRef) -> Result<(NodeRef, Scope)> {
311 let written = ast.query(query);
312 match written.body {
313 ast::QueryBody::Select(select) => self.bind_select(ast, select, &written),
314 ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
315 if by_name {
316 return Err(Error::not_implemented("UNION BY NAME"));
317 }
318 self.bind_set_op(ast, &written, op, quantifier, left, right)
319 }
320 ast::QueryBody::Values(rows) => self.bind_values(ast, &written, rows),
321 ast::QueryBody::Describe(inner) => self.bind_describe(ast, &written, inner),
322 ast::QueryBody::Show { name, relation } => {
323 self.bind_show(ast, &written, name, relation)
324 }
325 }
326 }
327
328 fn bind_show(
330 &mut self,
331 ast: &Ast,
332 query: &ast::Query,
333 name: ast::Slice,
334 relation: ast::QueryRef,
335 ) -> Result<(NodeRef, Scope)> {
336 let text = ast.name_text(name);
337 let parts: Vec<&str> = ast.name(name).collect();
338 let table_exists = self.catalog.resolve(&parts).is_ok();
339 let as_table = match self.semantics.show_behavior() {
340 ShowBehavior::Auto => table_exists,
341 ShowBehavior::Setting => false,
342 ShowBehavior::Table => true,
343 };
344 if as_table {
345 return self.bind_describe(ast, query, relation);
346 }
347 let Some((_, value)) =
348 self.session.iter().find(|(name, _)| name.eq_ignore_ascii_case(&text))
349 else {
350 return Err(Error::catalog(format!("Setting with name \"{text}\" does not exist")));
351 };
352 let field = Field::new(text, LogicalType::Varchar);
353 let expr = self.plan.add_constant(Value::Varchar(value.to_string()));
354 let row = self.plan.add_expr_list(&[expr]);
355 let rows = self.plan.add_rows(&[row]);
356 let columns = self.plan.add_fields(std::slice::from_ref(&field));
357 let index = self.fresh_index();
358 let node = self.add_node(Node::Values { index, columns, rows });
359 let mut scope = Scope::empty();
360 scope.push(Visible {
361 table: String::new(),
362 name: field.name,
363 binding: ColumnBinding::new(index, 0),
364 ty: LogicalType::Varchar,
365 not_null: false,
366 });
367 Ok((node, scope))
368 }
369
370 fn bind_describe(
386 &mut self,
387 ast: &Ast,
388 query: &ast::Query,
389 inner: ast::QueryRef,
390 ) -> Result<(NodeRef, Scope)> {
391 let (_, described) = self.bind_query(ast, inner)?;
392 let fields: Vec<Field> = ["column_name", "column_type", "null", "key", "default", "extra"]
393 .iter()
394 .map(|name| Field::new(*name, LogicalType::Varchar))
395 .collect();
396 let mut slices = Vec::with_capacity(described.columns.len());
397 for column in described.columns.clone() {
398 let written = [
401 column.name.clone(),
402 column.ty.to_string(),
403 if column.not_null { "NO" } else { "YES" }.to_owned(),
404 ];
405 let mut items: Vec<ExprRef> = written
406 .into_iter()
407 .map(|text| self.plan.add_constant(Value::Varchar(text)))
408 .collect();
409 for _ in 0..3 {
410 let empty = self.plan.add_constant(Value::Null);
411 items.push(self.cast_to(empty, &LogicalType::Varchar));
412 }
413 slices.push(self.plan.add_expr_list(&items));
414 }
415 let rows = self.plan.add_rows(&slices);
416 let columns = self.plan.add_fields(&fields);
417 let index = self.fresh_index();
418 let mut node = self.add_node(Node::Values { index, columns, rows });
419 let mut scope = Scope::empty();
420 for (at, field) in fields.iter().enumerate() {
421 scope.push(Visible {
422 table: String::new(),
423 name: field.name.clone(),
424 binding: ColumnBinding::new(index, at as u32),
425 ty: field.ty.clone(),
426 not_null: false,
427 });
428 }
429 let keys = self.sort_keys(ast, query, &scope, &[])?;
430 if !keys.is_empty() {
431 let keys = self.plan.add_sort_keys(&keys);
432 node = self.add_node(Node::Sort { input: node, keys });
433 }
434 node = self.apply_limit(ast, query, node)?;
435 Ok((node, scope))
436 }
437
438 fn passes_through(&self, expr: ExprRef, input: &Scope) -> bool {
444 let Expr::Column(binding) = *self.plan.expr(expr) else { return false };
445 input.columns.iter().any(|column| column.binding == binding && column.not_null)
446 }
447
448 fn bind_values(
455 &mut self,
456 ast: &Ast,
457 query: &ast::Query,
458 rows: ast::Slice,
459 ) -> Result<(NodeRef, Scope)> {
460 let written = ast.rows(rows).to_vec();
461 let Some(first) = written.first() else {
462 return Err(Error::binder("VALUES needs at least one row"));
463 };
464 let width = first.len as usize;
465 for (at, row) in written.iter().enumerate() {
466 if row.len as usize != width {
467 return Err(Error::binder(format!(
468 "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
469 at + 1,
470 row.len
471 )));
472 }
473 }
474 let empty = Scope::empty();
476 let previous = std::mem::replace(&mut self.clause, "VALUES clause");
477 let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
478 for row in &written {
479 let mut items = Vec::with_capacity(width);
480 for &expr in ast.expr_list(*row) {
481 items.push(self.bind_expr(ast, expr, &empty)?);
482 }
483 bound.push(items);
484 }
485 self.clause = previous;
486 let mut types = Vec::with_capacity(width);
487 for at in 0..width {
488 let mut ty = self.plan.expr_type(bound[0][at]).clone();
489 for row in &bound[1..] {
490 let other = self.plan.expr_type(row[at]).clone();
491 ty = ty.promote(&other).ok_or_else(|| {
492 Error::binder(format!(
493 "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
494 at + 1
495 ))
496 })?;
497 }
498 types.push(ty);
499 }
500 let mut slices = Vec::with_capacity(bound.len());
501 for row in &bound {
502 let items: Vec<ExprRef> = row
503 .iter()
504 .zip(&types)
505 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
506 .collect::<Result<_>>()?;
507 slices.push(self.plan.add_expr_list(&items));
508 }
509 let rows = self.plan.add_rows(&slices);
510 let fields: Vec<Field> = types
511 .iter()
512 .enumerate()
513 .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
514 .collect();
515 let columns = self.plan.add_fields(&fields);
516 let index = self.fresh_index();
517 let mut node = self.add_node(Node::Values { index, columns, rows });
518 let mut scope = Scope::empty();
519 for (at, field) in fields.iter().enumerate() {
520 scope.push(Visible {
521 table: String::new(),
522 name: field.name.clone(),
523 binding: ColumnBinding::new(index, at as u32),
524 ty: field.ty.clone(),
525 not_null: false,
526 });
527 }
528 let keys = self.sort_keys(ast, query, &scope, &[])?;
529 if !keys.is_empty() {
530 let keys = self.plan.add_sort_keys(&keys);
531 node = self.add_node(Node::Sort { input: node, keys });
532 }
533 node = self.apply_limit(ast, query, node)?;
534 Ok((node, scope))
535 }
536
537 fn bind_set_op(
538 &mut self,
539 ast: &Ast,
540 query: &ast::Query,
541 op: SetOp,
542 quantifier: Quantifier,
543 left: ast::QueryRef,
544 right: ast::QueryRef,
545 ) -> Result<(NodeRef, Scope)> {
546 let (left_node, left_scope) = self.bind_query(ast, left)?;
547 let (right_node, right_scope) = self.bind_query(ast, right)?;
548 if left_scope.len() != right_scope.len() {
549 return Err(Error::binder(format!(
550 "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
551 left_scope.len(),
552 right_scope.len()
553 )));
554 }
555 let mut types = Vec::with_capacity(left_scope.len());
557 for (left, right) in left_scope.columns.iter().zip(&right_scope.columns) {
558 let common = left.ty.promote(&right.ty).ok_or_else(|| {
559 Error::binder(format!(
560 "Cannot combine a column of type {} with a column of type {} in a set operation",
561 left.ty, right.ty
562 ))
563 })?;
564 types.push(common);
565 }
566 let left_node = self.conform(left_node, &left_scope, &types)?;
567 let right_node = self.conform(right_node, &right_scope, &types)?;
568 let index = self.fresh_index();
569 let kind = match op {
570 SetOp::Union => SetOpKind::Union,
571 SetOp::Except => SetOpKind::Except,
572 SetOp::Intersect => SetOpKind::Intersect,
573 };
574 let all = quantifier == Quantifier::All;
577 let mut node =
578 self.add_node(Node::SetOp { left: left_node, right: right_node, kind, all, index });
579 let mut scope = Scope::empty();
580 for (at, (column, ty)) in left_scope.columns.iter().zip(&types).enumerate() {
581 scope.push(Visible {
582 table: String::new(),
583 name: column.name.clone(),
584 binding: ColumnBinding::new(index, at as u32),
585 ty: ty.clone(),
586 not_null: false,
589 });
590 }
591 let keys = self.sort_keys(ast, query, &scope, &[])?;
595 if !keys.is_empty() {
596 let keys = self.plan.add_sort_keys(&keys);
597 node = self.add_node(Node::Sort { input: node, keys });
598 }
599 node = self.apply_limit(ast, query, node)?;
600 Ok((node, scope))
601 }
602
603 fn conform(&mut self, node: NodeRef, scope: &Scope, types: &[LogicalType]) -> Result<NodeRef> {
605 if scope.columns.iter().zip(types).all(|(column, ty)| &column.ty == ty) {
606 return Ok(node);
607 }
608 let index = self.fresh_index();
609 let mut exprs = Vec::with_capacity(types.len());
610 let mut names = Vec::with_capacity(types.len());
611 for (column, ty) in scope.columns.iter().zip(types) {
612 let expr = self.plan.add_expr(Expr::Column(column.binding), column.ty.clone());
613 exprs.push(self.checked_cast_to(expr, ty, false)?);
614 names.push(self.plan.intern(&column.name));
615 }
616 let exprs = self.plan.add_expr_list(&exprs);
617 let names = self.plan.add_name_list(&names);
618 Ok(self.add_node(Node::Project { input: node, index, exprs, names }))
619 }
620
621 fn bind_select(
624 &mut self,
625 ast: &Ast,
626 select: ast::SelectRef,
627 query: &ast::Query,
628 ) -> Result<(NodeRef, Scope)> {
629 let written = ast.select(select);
630 let outer_windows = std::mem::take(&mut self.windows);
634 let (mut node, input) = self.bind_from(ast, written.from)?;
635 node = self.attach_scalar_subqueries(node);
636
637 if written.filter != NONE {
638 self.clause = "WHERE clause";
639 let predicate = self.bind_expr(ast, written.filter, &input)?;
640 let predicate = self.as_boolean(predicate, "WHERE")?;
641 node = self.attach_scalar_subqueries(node);
642 node = self.add_node(Node::Filter { input: node, predicate });
643 }
644
645 let targets = ast.target_list(written.targets).to_vec();
646 if targets.is_empty() {
647 return Err(Error::binder("a SELECT needs at least one expression to select"));
648 }
649
650 let group_items = self.group_items(ast, &written, &targets)?;
651 let aggregating = !group_items.is_empty()
652 || written.having != NONE
653 || targets.iter().any(|target| has_aggregate(ast, target.expr));
654 if aggregating {
655 self.clause = "GROUP BY clause";
656 let mut groups = Vec::with_capacity(group_items.len());
657 for item in &group_items {
658 groups.push(self.bind_expr(ast, *item, &input)?);
659 }
660 let index = self.fresh_index();
661 self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
662 }
663
664 self.clause = "SELECT clause";
665 let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input)?;
666 let visible = exprs.len();
667
668 let mut having = None;
669 if written.having != NONE {
670 self.clause = "HAVING clause";
671 let predicate = self.bind_expr(ast, written.having, &input)?;
672 let predicate = self.over_aggregate(predicate, &input)?;
673 having = Some(self.as_boolean(predicate, "HAVING")?);
674 }
675
676 let project = self.fresh_index();
679 let mut output = Scope::empty();
680 for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
681 output.push(Visible {
682 table: String::new(),
683 name: name.clone(),
684 binding: ColumnBinding::new(project, at as u32),
685 ty: self.plan.expr_type(*expr).clone(),
686 not_null: self.passes_through(*expr, &input),
687 });
688 }
689
690 self.clause = "ORDER BY clause";
691 let mut extra = Vec::new();
692 let keys = self.select_sort_keys(
693 ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra,
694 )?;
695 if !extra.is_empty() && written.distinct != Distinct::No {
696 return Err(Error::binder(
697 "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
698 ));
699 }
700 let on = self.distinct_on(ast, written.distinct, &output)?;
701
702 node = self.attach_scalar_subqueries(node);
703
704 if let Some(aggregation) = self.aggregation.take() {
705 let index = aggregation.index;
706 let groups = self.plan.add_expr_list(&aggregation.groups);
707 let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
708 node = self.add_node(Node::Aggregate { input: node, index, groups, aggregates });
709 }
710 if let Some(predicate) = having {
711 node = self.add_node(Node::Filter { input: node, predicate });
712 }
713
714 for run in std::mem::replace(&mut self.windows, outer_windows) {
718 let partition = self.plan.add_expr_list(&run.partition);
719 let order = self.plan.add_sort_keys(&run.order);
720 let expressions = self.plan.add_expr_list(&run.calls);
721 node = self.add_node(Node::Window {
722 input: node,
723 index: run.index,
724 partition,
725 order,
726 frame: run.frame,
727 expressions,
728 });
729 }
730
731 let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
732 let exprs_slice = self.plan.add_expr_list(&exprs);
733 let names_slice = self.plan.add_name_list(&interned);
734 node = self.add_node(Node::Project {
735 input: node,
736 index: project,
737 exprs: exprs_slice,
738 names: names_slice,
739 });
740
741 if written.distinct != Distinct::No {
742 let on = self.plan.add_expr_list(&on);
743 node = self.add_node(Node::Distinct { input: node, on });
744 }
745 if !keys.is_empty() {
746 let keys = self.plan.add_sort_keys(&keys);
747 node = self.add_node(Node::Sort { input: node, keys });
748 }
749 node = self.apply_limit(ast, query, node)?;
750
751 if extra.is_empty() {
752 output.columns.truncate(visible);
753 return Ok((node, output));
754 }
755 let index = self.fresh_index();
758 let mut kept = Vec::with_capacity(visible);
759 let mut kept_names = Vec::with_capacity(visible);
760 let mut scope = Scope::empty();
761 for (at, name) in names.iter().enumerate().take(visible) {
762 let ty = output.columns[at].ty.clone();
763 kept.push(self.column(project, at, ty.clone()));
764 kept_names.push(self.plan.intern(name));
765 scope.push(Visible {
766 table: String::new(),
767 name: name.clone(),
768 binding: ColumnBinding::new(index, at as u32),
769 ty,
770 not_null: output.columns[at].not_null,
771 });
772 }
773 let exprs = self.plan.add_expr_list(&kept);
774 let names = self.plan.add_name_list(&kept_names);
775 node = self.add_node(Node::Project { input: node, index, exprs, names });
776 Ok((node, scope))
777 }
778
779 fn bind_targets(
781 &mut self,
782 ast: &Ast,
783 targets: &[ast::Target],
784 input: &Scope,
785 ) -> Result<(Vec<ExprRef>, Vec<String>)> {
786 let mut exprs = Vec::with_capacity(targets.len());
787 let mut names = Vec::with_capacity(targets.len());
788 for target in targets {
789 if let ast::Expr::Star { qualifier, replacements } = ast.expr(target.expr) {
790 let table = ast.name(qualifier).last().map(str::to_string);
791 let expanded: Vec<Visible> =
792 input.star(table.as_deref())?.into_iter().cloned().collect();
793 let replacements = ast.target_list(replacements).to_vec();
794 let mut used = vec![false; replacements.len()];
795 for column in expanded {
796 let found = replacements.iter().zip(&mut used).find(|(replacement, _)| {
797 same_name(ast.string(replacement.alias), &column.name)
798 });
799 let (expr, name) = match found {
804 Some((replacement, used)) => {
805 *used = true;
806 let expr = self.bind_expr(ast, replacement.expr, input)?;
807 (expr, ast.string(replacement.alias).to_string())
808 }
809 None => (
810 self.plan.add_expr(Expr::Column(column.binding), column.ty),
811 column.name,
812 ),
813 };
814 exprs.push(self.over_aggregate(expr, input)?);
815 names.push(name);
816 }
817 if let Some((replacement, _)) =
821 replacements.iter().zip(&used).find(|(_, used)| !**used)
822 {
823 return Err(missing_replacement(ast.string(replacement.alias), input));
824 }
825 continue;
826 }
827 let expr = self.bind_expr(ast, target.expr, input)?;
828 exprs.push(self.over_aggregate(expr, input)?);
829 names.push(if target.alias == NONE {
830 self.output_name(ast, target.expr, input)
831 } else {
832 ast.string(target.alias).to_string()
833 });
834 }
835 Ok((exprs, names))
836 }
837
838 fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
844 if let ast::Expr::Column { name } = ast.expr(target) {
845 let parts: Vec<&str> = ast.name(name).collect();
846 if let Ok(found) = input.resolve(&parts) {
847 return found.name.clone();
848 }
849 }
850 describe(ast, target, self.semantics)
851 }
852
853 fn group_items(
855 &self,
856 ast: &Ast,
857 select: &ast::Select,
858 targets: &[ast::Target],
859 ) -> Result<Vec<ast::ExprRef>> {
860 if select.group_by_all {
861 return Ok(targets
864 .iter()
865 .filter(|target| !has_aggregate(ast, target.expr))
866 .map(|target| target.expr)
867 .collect());
868 }
869 let mut items = Vec::new();
870 for &item in ast.expr_list(select.group_by) {
871 items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
872 }
873 Ok(items)
874 }
875
876 fn output_reference(
878 &self,
879 ast: &Ast,
880 item: ast::ExprRef,
881 targets: &[ast::Target],
882 clause: &str,
883 ) -> Result<Option<ast::ExprRef>> {
884 match ast.expr(item) {
885 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
886 let written = ast.string(text);
887 let position: usize = written.parse().map_err(|_| {
888 Error::binder(format!("{clause} term {written} is not a column"))
889 })?;
890 if position == 0 || position > targets.len() {
891 return Err(Error::binder(format!(
892 "{clause} term out of range - should be between 1 and {}",
893 targets.len()
894 )));
895 }
896 Ok(Some(targets[position - 1].expr))
897 }
898 ast::Expr::Column { name } => {
899 let parts: Vec<&str> = ast.name(name).collect();
900 let [written] = parts.as_slice() else { return Ok(None) };
901 let mut found = None;
902 for target in targets {
903 if target.alias != NONE && same_name(ast.string(target.alias), written) {
904 if found.is_some() {
905 return Ok(None);
906 }
907 found = Some(target.expr);
908 }
909 }
910 Ok(found)
911 }
912 _ => Ok(None),
913 }
914 }
915
916 #[allow(clippy::too_many_arguments)]
920 fn select_sort_keys(
921 &mut self,
922 ast: &Ast,
923 query: &ast::Query,
924 input: &Scope,
925 output: &Scope,
926 project: u32,
927 exprs: &mut Vec<ExprRef>,
928 names: &mut Vec<String>,
929 extra: &mut Vec<usize>,
930 ) -> Result<Vec<SortKey>> {
931 if query.order_by_all {
932 return Ok(self.every_column(output));
933 }
934 let items = ast.order_list(query.order_by).to_vec();
935 let mut keys = Vec::with_capacity(items.len());
936 for item in items {
937 self.check_order_literal(ast, item.expr)?;
938 let position = match self.output_position(ast, item.expr, output)? {
939 Some(position) => position,
940 None => {
941 let bound = self.bind_expr(ast, item.expr, input)?;
942 let bound = self.over_aggregate(bound, input)?;
943 match exprs.iter().position(|&held| self.same_expr(held, bound)) {
944 Some(position) => position,
945 None => {
946 exprs.push(bound);
947 names.push(describe(ast, item.expr, self.semantics));
948 extra.push(exprs.len() - 1);
949 exprs.len() - 1
950 }
951 }
952 }
953 };
954 let ty = self.plan.expr_type(exprs[position]).clone();
955 let expr = self.column(project, position, ty);
956 keys.push(self.sort_key(expr, item));
957 }
958 Ok(keys)
959 }
960
961 fn sort_keys(
963 &mut self,
964 ast: &Ast,
965 query: &ast::Query,
966 output: &Scope,
967 targets: &[ast::Target],
968 ) -> Result<Vec<SortKey>> {
969 if query.order_by_all {
970 return Ok(self.every_column(output));
971 }
972 let items = ast.order_list(query.order_by).to_vec();
973 let mut keys = Vec::with_capacity(items.len());
974 for item in items {
975 self.check_order_literal(ast, item.expr)?;
976 let expr = match self.output_position(ast, item.expr, output)? {
977 Some(position) => {
978 let column = &output.columns[position];
979 let (binding, ty) = (column.binding, column.ty.clone());
980 self.plan.add_expr(Expr::Column(binding), ty)
981 }
982 None => {
983 let _ = targets;
984 self.bind_expr(ast, item.expr, output)?
985 }
986 };
987 keys.push(self.sort_key(expr, item));
988 }
989 Ok(keys)
990 }
991
992 fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
993 let columns: Vec<(ColumnBinding, LogicalType)> =
994 output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
995 columns
996 .into_iter()
997 .map(|(binding, ty)| {
998 let expr = self.plan.add_expr(Expr::Column(binding), ty);
999 let descending = self.semantics.default_descending();
1000 SortKey { expr, descending, nulls_first: self.semantics.nulls_first(descending) }
1001 })
1002 .collect()
1003 }
1004
1005 fn sort_key(&self, expr: ExprRef, item: ast::OrderItem) -> SortKey {
1007 let descending = match item.order {
1008 Order::Unstated => self.semantics.default_descending(),
1009 Order::Ascending => false,
1010 Order::Descending => true,
1011 };
1012 let nulls_first = match item.nulls {
1013 Nulls::First => true,
1014 Nulls::Last => false,
1015 Nulls::Unstated => self.semantics.nulls_first(descending),
1016 };
1017 SortKey { expr, descending, nulls_first }
1018 }
1019
1020 fn output_position(
1022 &self,
1023 ast: &Ast,
1024 item: ast::ExprRef,
1025 output: &Scope,
1026 ) -> Result<Option<usize>> {
1027 match ast.expr(item) {
1028 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
1029 let written = ast.string(text);
1030 if written.contains(['.', 'e', 'E']) {
1031 return Ok(None);
1032 }
1033 let position: usize = written.parse().map_err(|_| {
1034 Error::binder(format!("ORDER BY term {written} is not a column"))
1035 })?;
1036 if position == 0 || position > output.len() {
1037 return Err(Error::binder(format!(
1038 "ORDER BY term out of range - should be between 1 and {}",
1039 output.len()
1040 )));
1041 }
1042 Ok(Some(position - 1))
1043 }
1044 ast::Expr::Column { name } => {
1045 let parts: Vec<&str> = ast.name(name).collect();
1046 let [written] = parts.as_slice() else { return Ok(None) };
1047 Ok(output.position_of(None, written))
1048 }
1049 _ => Ok(None),
1050 }
1051 }
1052
1053 fn check_order_literal(&self, ast: &Ast, item: ast::ExprRef) -> Result<()> {
1055 if !self.semantics.order_by_non_integer_literal()
1056 && matches!(
1057 ast.expr(item),
1058 ast::Expr::Literal { kind, text }
1059 if kind != LiteralKind::Number
1060 || ast.string(text).contains(['.', 'e', 'E'])
1061 )
1062 {
1063 return Err(Error::binder(
1064 "ORDER BY non-integer literal has no effect.\n* SET order_by_non_integer_literal=true to allow this behavior.",
1065 ));
1066 }
1067 Ok(())
1068 }
1069
1070 fn distinct_on(
1072 &mut self,
1073 ast: &Ast,
1074 distinct: Distinct,
1075 output: &Scope,
1076 ) -> Result<Vec<ExprRef>> {
1077 let Distinct::On(items) = distinct else {
1078 return Ok(Vec::new());
1079 };
1080 let items = ast.expr_list(items).to_vec();
1081 let mut on = Vec::with_capacity(items.len());
1082 for item in items {
1083 let Some(position) = self.output_position(ast, item, output)? else {
1084 return Err(Error::not_implemented(
1085 "DISTINCT ON an expression that is not in the select list",
1086 ));
1087 };
1088 let column = &output.columns[position];
1089 let (binding, ty) = (column.binding, column.ty.clone());
1090 on.push(self.plan.add_expr(Expr::Column(binding), ty));
1091 }
1092 Ok(on)
1093 }
1094
1095 fn apply_limit(&mut self, ast: &Ast, query: &ast::Query, input: NodeRef) -> Result<NodeRef> {
1096 if query.limit_percent {
1097 return Err(Error::not_implemented("LIMIT with a percentage"));
1098 }
1099 let count = self.constant_count(ast, query.limit, "LIMIT")?;
1100 let offset = self.constant_count(ast, query.offset, "OFFSET")?.unwrap_or(0);
1101 if count.is_none() && offset == 0 {
1102 return Ok(input);
1103 }
1104 Ok(self.add_node(Node::Limit { input, count, offset }))
1105 }
1106
1107 fn constant_count(
1109 &mut self,
1110 ast: &Ast,
1111 written: ast::ExprRef,
1112 clause: &str,
1113 ) -> Result<Option<u64>> {
1114 if written == NONE {
1115 return Ok(None);
1116 }
1117 self.clause = "LIMIT clause";
1118 let scope = Scope::empty();
1119 let bound = self.bind_expr(ast, written, &scope)?;
1120 let Expr::Constant(value) = *self.plan.expr(bound) else {
1121 return Err(Error::not_implemented(format!("a {clause} that is not a constant")));
1122 };
1123 let count = match self.plan.value(value) {
1124 Value::Null => return Ok(None),
1125 Value::TinyInt(count) => i128::from(*count),
1126 Value::SmallInt(count) => i128::from(*count),
1127 Value::Integer(count) => i128::from(*count),
1128 Value::BigInt(count) => i128::from(*count),
1129 Value::HugeInt(count) => *count,
1130 other => {
1131 return Err(Error::binder(format!(
1132 "{clause} takes a whole number of rows, not a value of type {}",
1133 other.logical_type()
1134 )));
1135 }
1136 };
1137 u64::try_from(count)
1138 .map(Some)
1139 .map_err(|_| Error::binder(format!("{clause} must not be negative")))
1140 }
1141
1142 fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
1145 let sources = ast.source_list(from).to_vec();
1146 let Some((first, rest)) = sources.split_first() else {
1147 return Ok((self.add_node(Node::Dummy), Scope::empty()));
1150 };
1151 let (mut node, mut scope) = self.bind_source(ast, *first)?;
1152 for source in rest {
1153 let (right, right_scope) = self.bind_source(ast, *source)?;
1154 node = self.add_node(Node::CrossProduct { left: node, right });
1155 scope = scope.concat(right_scope);
1156 }
1157 Ok((node, scope))
1158 }
1159
1160 fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
1161 match ast.source(source) {
1162 ast::Source::Table { name, alias, columns } => {
1163 self.bind_table(ast, name, alias, columns)
1164 }
1165 ast::Source::Function { name, args, alias, columns, pragma } => {
1166 self.bind_table_function(ast, name, args, alias, columns, pragma)
1167 }
1168 ast::Source::Subquery { query, alias, columns } => {
1169 let (node, mut scope) = self.bind_query(ast, query)?;
1170 let label = if alias == NONE {
1171 "unnamed_subquery".to_string()
1172 } else {
1173 ast.string(alias).to_string()
1174 };
1175 scope.relabel(&label);
1176 if !columns.is_empty() {
1177 let names: Vec<&str> = ast.name(columns).collect();
1178 scope.rename(&names, &label)?;
1179 }
1180 Ok((node, scope))
1181 }
1182 ast::Source::Values { rows, alias, columns } => {
1183 let bare = ast::Query::bare(ast::QueryBody::Values(rows));
1184 let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
1185 let label =
1186 if alias == NONE { String::new() } else { ast.string(alias).to_string() };
1187 scope.relabel(&label);
1188 if !columns.is_empty() {
1189 let names: Vec<&str> = ast.name(columns).collect();
1190 scope.rename(&names, &label)?;
1191 }
1192 Ok((node, scope))
1193 }
1194 ast::Source::Join { left, right, kind, natural, on, using } => {
1195 self.bind_join(ast, left, right, kind, natural, on, using)
1196 }
1197 }
1198 }
1199
1200 fn bind_table(
1201 &mut self,
1202 ast: &Ast,
1203 name: ast::Slice,
1204 alias: ast::StrRef,
1205 columns: ast::Slice,
1206 ) -> Result<(NodeRef, Scope)> {
1207 let parts: Vec<&str> = ast.name(name).collect();
1208 let catalog = self.catalog;
1209 let resolved = match catalog.resolve(&parts) {
1212 Ok(resolved) => resolved,
1213 Err(missing) => {
1214 return self.bind_replacement_scan(ast, &parts, alias, columns, missing);
1215 }
1216 };
1217 if catalog.entry(&resolved)? == Entry::View {
1218 return self.bind_view(ast, &resolved, alias, columns);
1219 }
1220 let table = catalog.table(&resolved)?;
1221 let fields: Vec<Field> = table.columns().to_vec();
1222 let label =
1223 if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
1224 let index = self.fresh_index();
1225 let mut scope = Scope::empty();
1226 for (at, field) in fields.iter().enumerate() {
1227 scope.push(Visible {
1228 table: label.clone(),
1229 name: field.name.clone(),
1230 binding: ColumnBinding::new(index, at as u32),
1231 ty: field.ty.clone(),
1232 not_null: field.not_null,
1233 });
1234 }
1235 if !columns.is_empty() {
1236 let names: Vec<&str> = ast.name(columns).collect();
1237 scope.rename(&names, &label)?;
1238 }
1239 let catalog_name = self.plan.intern(&resolved.catalog);
1240 let schema = self.plan.intern(&resolved.schema);
1241 let table_name = self.plan.intern(&resolved.table);
1242 let alias = self.plan.intern(&label);
1243 let columns = self.plan.add_fields(&fields);
1244 let node = self.add_node(Node::Get {
1245 catalog: catalog_name,
1246 schema,
1247 table: table_name,
1248 alias,
1249 index,
1250 columns,
1251 });
1252 Ok((node, scope))
1253 }
1254
1255 fn bind_view(
1267 &mut self,
1268 ast: &Ast,
1269 name: &QualifiedName,
1270 alias: ast::StrRef,
1271 columns: ast::Slice,
1272 ) -> Result<(NodeRef, Scope)> {
1273 let view = self.catalog.view(name)?;
1274 let full = name.to_string();
1275 if self.expanding.contains(&full) {
1276 return Err(Error::binder(format!(
1280 "infinite recursion detected: attempting to recursively bind view \"\"{}\"\"",
1281 name.table
1282 )));
1283 }
1284 let body = parse_ast_with_case(view.sql(), self.semantics.identifier_case())?;
1285 let query = match body.statements.as_slice() {
1286 [ast::Statement::Query(query)] => *query,
1287 _ => return Err(Error::binder(format!("view \"{}\" is not a query", name.table))),
1290 };
1291 self.expanding.push(full);
1292 let bound = self.bind_query(&body, query);
1293 self.expanding.pop();
1294 let (node, mut scope) = bound?;
1295
1296 let aliases: Vec<&str> = view.aliases().iter().map(String::as_str).collect();
1297 if !aliases.is_empty() {
1298 scope.rename(&aliases, "unnamed_subquery")?;
1299 }
1300 view.remember(scope.fields());
1307 let label = if alias == NONE { name.table.clone() } else { ast.string(alias).to_string() };
1308 scope.relabel(&label);
1309 if !columns.is_empty() {
1310 let names: Vec<&str> = ast.name(columns).collect();
1311 scope.rename(&names, &label)?;
1312 }
1313 Ok((node, scope))
1314 }
1315
1316 fn bind_table_function(
1324 &mut self,
1325 ast: &Ast,
1326 name: ast::Slice,
1327 args: ast::Slice,
1328 alias: ast::StrRef,
1329 columns: ast::Slice,
1330 pragma: bool,
1331 ) -> Result<(NodeRef, Scope)> {
1332 let parts: Vec<&str> = ast.name(name).collect();
1333 let function_name = *parts.last().unwrap_or(&"");
1337 if let Some(schema) = parts.iter().rev().nth(1) {
1338 if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
1339 return Err(Error::catalog(format!(
1340 "Table Function with name {} does not exist!",
1341 parts.join(".")
1342 )));
1343 }
1344 }
1345 let Some(called) = TableFunction::lookup(function_name) else {
1349 if pragma {
1350 if args.is_empty() && self.catalog.resolve(&parts).is_ok() {
1356 return self.bind_table(ast, name, alias, columns);
1357 }
1358 let spelled = function_name.strip_prefix("pragma_").unwrap_or(function_name);
1359 return Err(Error::catalog(format!(
1360 "Pragma Function with name {spelled} does not exist!"
1361 )));
1362 }
1363 return Err(Error::catalog(format!(
1364 "Table Function with name {function_name} does not exist!"
1365 )));
1366 };
1367 let written = ast.target_list(args).to_vec();
1368 let empty = Scope::empty();
1369 let previous = std::mem::replace(&mut self.clause, "table function arguments");
1370 let mut bound = Vec::new();
1371 let mut written_options = Vec::new();
1372 for argument in written {
1373 let expr = self.bind_expr(ast, argument.expr, &empty)?;
1374 if argument.alias == NONE {
1375 bound.push(expr);
1376 } else {
1377 let name = ast.string(argument.alias).to_string();
1378 let (parameter, value) = self.named_argument(called, &name, expr)?;
1379 written_options.push((parameter, value, expr));
1380 }
1381 }
1382 self.clause = previous;
1383 let options = Options::of(&written_options)?;
1384
1385 let given: Vec<LogicalType> =
1388 bound.iter().map(|&expr| self.plan.expr_type(expr).clone()).collect();
1389 let resolved = if pragma {
1390 resolve_pragma(function_name, &given)?
1391 } else {
1392 resolve_table(function_name, &given)?
1393 };
1394 let mut cast: Vec<ExprRef> = bound
1395 .iter()
1396 .zip(&resolved.arguments)
1397 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
1398 .collect::<Result<_>>()?;
1399
1400 if resolved.function.takes_a_name() {
1401 let Columns::Fixed(fields) = resolved.columns else {
1402 return Err(Error::internal("a pragma that resolved to a file"));
1403 };
1404 let [argument] = cast[..] else {
1405 return Err(Error::internal("a pragma that resolved to more than one name"));
1406 };
1407 return self.bind_pragma(ast, resolved.function, &fields, argument, alias, columns);
1408 }
1409 let fields = match resolved.columns {
1410 Columns::Fixed(fields) => fields,
1411 columns => {
1412 let paths = self.file_paths(cast[0], resolved.function.name())?;
1417 let first = paths.first().map_or("", String::as_str);
1418 let mut fields = match columns {
1419 Columns::Csv => csv_fields(&paths, options.given)?,
1422 _ => parquet_fields(first)?,
1423 };
1424 if options.all_varchar {
1425 for field in &mut fields {
1430 field.ty = LogicalType::Varchar;
1431 }
1432 }
1433 if options.binary_as_string {
1434 for field in &mut fields {
1439 if field.ty == LogicalType::Blob {
1440 field.ty = LogicalType::Varchar;
1441 }
1442 }
1443 }
1444 if options.file_row_number {
1445 if fields.iter().any(|field| field.name == FILE_ROW_NUMBER) {
1451 return Err(Error::binder(format!(
1452 "Duplicate column name \"{FILE_ROW_NUMBER}\": the file already has a \
1453 column of that name, so file_row_number cannot add one"
1454 )));
1455 }
1456 fields.push(Field::required(FILE_ROW_NUMBER.to_string(), LogicalType::BigInt));
1457 }
1458 cast = paths.iter().map(|path| self.path_constant(path)).collect();
1459 fields
1460 }
1461 };
1462 let label = if alias == NONE {
1463 resolved.function.name().to_string()
1464 } else {
1465 ast.string(alias).to_string()
1466 };
1467 let names: Vec<&str> = ast.name(columns).collect();
1468 self.table_function_source(
1469 resolved.function,
1470 &cast,
1471 &written_options,
1472 fields,
1473 &label,
1474 &names,
1475 )
1476 }
1477
1478 fn bind_pragma(
1491 &mut self,
1492 ast: &Ast,
1493 function: TableFunction,
1494 fields: &[Field],
1495 argument: ExprRef,
1496 alias: ast::StrRef,
1497 columns: ast::Slice,
1498 ) -> Result<(NodeRef, Scope)> {
1499 let written = self.pragma_name(argument, function)?;
1500 let parts = identifier_parts(&written);
1501 let spelled: Vec<&str> = parts.iter().map(String::as_str).collect();
1502 let name = self.catalog.resolve(&spelled)?;
1503 let described = self.described(ast, &name)?;
1504 let mut rows = Vec::with_capacity(described.len());
1505 for (at, field) in described.iter().enumerate() {
1506 let items = if matches!(function, TableFunction::PragmaShow) {
1507 self.describing(field)
1508 } else {
1509 self.table_info(at, field)
1510 };
1511 rows.push(self.plan.add_expr_list(&items));
1512 }
1513 let rows = self.plan.add_rows(&rows);
1514 let held = self.plan.add_fields(fields);
1515 let index = self.fresh_index();
1516 let node = self.add_node(Node::Values { index, columns: held, rows });
1517 let label =
1518 if alias == NONE { function.name().to_string() } else { ast.string(alias).to_string() };
1519 let mut scope = Scope::empty();
1520 for (at, field) in fields.iter().enumerate() {
1521 scope.push(Visible {
1522 table: label.clone(),
1523 name: field.name.clone(),
1524 binding: ColumnBinding::new(index, at as u32),
1525 ty: field.ty.clone(),
1526 not_null: false,
1527 });
1528 }
1529 if !columns.is_empty() {
1530 let names: Vec<&str> = ast.name(columns).collect();
1531 scope.rename(&names, &label)?;
1532 }
1533 Ok((node, scope))
1534 }
1535
1536 fn pragma_name(&self, argument: ExprRef, function: TableFunction) -> Result<String> {
1546 let Expr::Constant(reference) = *self.plan.expr(argument) else {
1547 return Err(Error::not_implemented(format!(
1548 "{}() given a name that is not a constant",
1549 function.name()
1550 )));
1551 };
1552 match self.plan.value(reference) {
1553 Value::Varchar(name) => Ok(name.clone()),
1554 Value::Null => Ok("NULL".to_string()),
1555 other => {
1556 Err(Error::internal(format!("a pragma name bound as VARCHAR arrived as {other}")))
1557 }
1558 }
1559 }
1560
1561 fn described(&mut self, ast: &Ast, name: &QualifiedName) -> Result<Vec<Field>> {
1572 if self.catalog.entry(name)? == Entry::Table {
1573 return Ok(self.catalog.table(name)?.columns().to_vec());
1574 }
1575 let (_, scope) = self.bind_view(ast, name, NONE, ast::Slice::default())?;
1576 Ok(scope.fields())
1577 }
1578
1579 fn describing(&mut self, field: &Field) -> Vec<ExprRef> {
1581 let written = [
1582 field.name.clone(),
1583 field.ty.to_string(),
1584 if field.not_null { "NO" } else { "YES" }.to_owned(),
1585 ];
1586 let mut items: Vec<ExprRef> =
1587 written.into_iter().map(|text| self.plan.add_constant(Value::Varchar(text))).collect();
1588 for _ in 0..3 {
1589 let empty = self.plan.add_constant(Value::Null);
1590 items.push(self.cast_to(empty, &LogicalType::Varchar));
1591 }
1592 items
1593 }
1594
1595 fn table_info(&mut self, at: usize, field: &Field) -> Vec<ExprRef> {
1601 let cid = self.plan.add_constant(Value::Integer(i32::try_from(at).unwrap_or(i32::MAX)));
1602 let name = self.plan.add_constant(Value::Varchar(field.name.clone()));
1603 let ty = self.plan.add_constant(Value::Varchar(field.ty.to_string()));
1604 let not_null = self.plan.add_constant(Value::Boolean(field.not_null));
1605 let default = self.plan.add_constant(Value::Null);
1606 let default = self.cast_to(default, &LogicalType::Varchar);
1607 let key = self.plan.add_constant(Value::Boolean(false));
1608 vec![cid, name, ty, not_null, default, key]
1609 }
1610
1611 fn named_argument(
1625 &mut self,
1626 function: TableFunction,
1627 name: &str,
1628 expr: ExprRef,
1629 ) -> Result<(&'static str, Value)> {
1630 let known = function
1631 .parameters()
1632 .iter()
1633 .find(|(parameter, _)| parameter.eq_ignore_ascii_case(name));
1634 let Some((parameter, wanted)) = known else {
1635 let candidates: Vec<String> = function
1636 .parameters()
1637 .iter()
1638 .map(|(parameter, ty)| format!(" {parameter} {ty}"))
1639 .collect();
1640 return Err(Error::binder(format!(
1641 "Invalid named parameter \"{name}\" for function {}\nCandidates:\n{}\n",
1642 function.name(),
1643 candidates.join("\n")
1644 )));
1645 };
1646 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1647 return Err(Error::not_implemented(format!(
1648 "the named parameter {parameter} with a value that is not a constant"
1649 )));
1650 };
1651 let value = self.plan.value(reference).clone();
1652 if value == Value::Null {
1653 return Err(Error::binder(null_parameter(function, parameter)));
1654 }
1655 let given = self.plan.expr_type(expr).clone();
1656 if given != *wanted {
1657 return Err(Error::not_implemented(format!(
1658 "the named parameter {parameter} given a {given} where a {wanted} was wanted"
1659 )));
1660 }
1661 Ok((parameter, value))
1662 }
1663
1664 fn bind_replacement_scan(
1675 &mut self,
1676 ast: &Ast,
1677 parts: &[&str],
1678 alias: ast::StrRef,
1679 columns: ast::Slice,
1680 missing: Error,
1681 ) -> Result<(NodeRef, Scope)> {
1682 let [path] = parts else { return Err(missing) };
1683 let path = *path;
1684 let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
1685 let Some(function) = Self::reader_for(extension) else {
1686 if is_file(path) {
1687 return Err(Error::binder(format!(
1692 "No extension found that is capable of reading the file \"{path}\"\n* If this \
1693 file is a supported file format you can explicitly use the reader functions, \
1694 such as read_csv, read_json or read_parquet"
1695 )));
1696 }
1697 return Err(missing);
1698 };
1699 let paths = files(path)?;
1704 let first = paths.first().map_or("", String::as_str);
1705 let fields = match function {
1706 TableFunction::ReadParquet => parquet_fields(first)?,
1707 _ => csv_fields(&paths, Given::default())?,
1708 };
1709 let label = if alias == NONE {
1715 if is_pattern(path) {
1716 path.to_string()
1717 } else {
1718 let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
1719 file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
1720 }
1721 } else {
1722 ast.string(alias).to_string()
1723 };
1724 let arguments: Vec<ExprRef> = paths.iter().map(|path| self.path_constant(path)).collect();
1725 let names: Vec<&str> = ast.name(columns).collect();
1726 self.table_function_source(function, &arguments, &[], fields, &label, &names)
1727 }
1728
1729 fn path_constant(&mut self, path: &str) -> ExprRef {
1731 let value = self.plan.add_value(Value::Varchar(path.to_string()));
1732 self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar)
1733 }
1734
1735 fn reader_for(extension: &str) -> Option<TableFunction> {
1742 if extension.eq_ignore_ascii_case("parquet") {
1743 return Some(TableFunction::ReadParquet);
1744 }
1745 if extension.eq_ignore_ascii_case("csv") || extension.eq_ignore_ascii_case("tsv") {
1746 return Some(TableFunction::ReadCsv);
1747 }
1748 None
1749 }
1750
1751 fn table_function_source(
1756 &mut self,
1757 function: TableFunction,
1758 args: &[ExprRef],
1759 written: &[(&'static str, Value, ExprRef)],
1760 fields: Vec<Field>,
1761 label: &str,
1762 names: &[&str],
1763 ) -> Result<(NodeRef, Scope)> {
1764 let index = self.fresh_index();
1765 let mut scope = Scope::empty();
1766 for (at, field) in fields.iter().enumerate() {
1767 scope.push(Visible {
1768 table: label.to_string(),
1769 name: field.name.clone(),
1770 binding: ColumnBinding::new(index, at as u32),
1771 ty: field.ty.clone(),
1772 not_null: false,
1775 });
1776 }
1777 if !names.is_empty() {
1778 scope.rename(names, label)?;
1779 }
1780 let function = self.plan.intern(function.name());
1781 let args = self.plan.add_expr_list(args);
1782 let named: Vec<u32> =
1783 written.iter().map(|(parameter, _, _)| self.plan.intern(parameter)).collect();
1784 let settings: Vec<ExprRef> = written.iter().map(|(_, _, expr)| *expr).collect();
1785 let options = self.plan.add_name_list(&named);
1786 let settings = self.plan.add_expr_list(&settings);
1787 let columns = self.plan.add_fields(&fields);
1788 let node = self.add_node(Node::TableFunction {
1789 index,
1790 function,
1791 args,
1792 options,
1793 settings,
1794 columns,
1795 });
1796 Ok((node, scope))
1797 }
1798
1799 fn file_paths(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1806 let mut paths = Vec::new();
1807 for pattern in self.file_patterns(expr, name)? {
1808 paths.extend(files(&pattern)?);
1809 }
1810 Ok(paths)
1811 }
1812
1813 fn file_patterns(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1825 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1826 return Err(Error::not_implemented(
1827 "a table function file name that is not a constant",
1828 ));
1829 };
1830 match self.plan.value(reference) {
1831 Value::Varchar(path) => Ok(vec![path.clone()]),
1832 Value::Null => Err(Error::parser(format!("{name} cannot take NULL list as parameter"))),
1834 Value::List { values, .. } => values
1835 .iter()
1836 .map(|value| match value {
1837 Value::Varchar(path) => Ok(path.clone()),
1838 _ => Err(Error::parser(format!(
1839 "{name} reader cannot take NULL input as parameter"
1840 ))),
1841 })
1842 .collect(),
1843 other => {
1844 Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
1845 }
1846 }
1847 }
1848
1849 #[allow(clippy::too_many_arguments)]
1850 fn bind_join(
1851 &mut self,
1852 ast: &Ast,
1853 left: ast::SourceRef,
1854 right: ast::SourceRef,
1855 kind: ast::JoinKind,
1856 natural: bool,
1857 on: ast::ExprRef,
1858 using: ast::Slice,
1859 ) -> Result<(NodeRef, Scope)> {
1860 let (left_node, left_scope) = self.bind_source(ast, left)?;
1861 let (right_node, right_scope) = self.bind_source(ast, right)?;
1862 let split = left_scope.len();
1863 let mut scope = left_scope.concat(right_scope);
1864
1865 let merged: Vec<String> = if natural {
1868 let mut names = Vec::new();
1869 for (at, column) in scope.columns.iter().enumerate().take(split) {
1870 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
1871 && !names.iter().any(|held: &String| same_name(held, &column.name))
1872 {
1873 let _ = at;
1874 names.push(column.name.clone());
1875 }
1876 }
1877 names
1878 } else {
1879 let mut names: Vec<String> = Vec::new();
1885 for name in ast.name(using) {
1886 if !names.iter().any(|held| same_name(held, name)) {
1887 names.push(name.to_string());
1888 }
1889 }
1890 names
1891 };
1892
1893 let mut conditions = Vec::new();
1894 let mut dropped = Vec::new();
1895 for name in &merged {
1896 let left_at = scope.columns[..split]
1897 .iter()
1898 .position(|column| same_name(&column.name, name))
1899 .ok_or_else(|| {
1900 Error::binder(format!(
1901 "column \"{name}\" specified in USING clause does not exist in left table"
1902 ))
1903 })?;
1904 let right_at = scope.columns[split..]
1905 .iter()
1906 .position(|column| same_name(&column.name, name))
1907 .map(|at| at + split)
1908 .ok_or_else(|| {
1909 Error::binder(format!(
1910 "column \"{name}\" specified in USING clause does not exist in right table"
1911 ))
1912 })?;
1913 let left_column = &scope.columns[left_at];
1914 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
1915 let right_column = &scope.columns[right_at];
1916 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
1917 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
1918 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
1919 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
1920 dropped.push(right_at);
1921 }
1922 dropped.sort_unstable();
1925 for at in dropped.into_iter().rev() {
1926 scope.remove(at);
1927 }
1928
1929 if on != NONE {
1930 if !merged.is_empty() {
1931 return Err(Error::binder("a join cannot have both ON and USING"));
1932 }
1933 self.clause = "JOIN condition";
1934 let predicate = self.bind_expr(ast, on, &scope)?;
1935 conditions.push(self.as_boolean(predicate, "JOIN")?);
1936 }
1937
1938 if kind == ast::JoinKind::Cross {
1939 if !conditions.is_empty() {
1940 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
1941 }
1942 let node = self.add_node(Node::CrossProduct { left: left_node, right: right_node });
1943 return Ok((node, scope));
1944 }
1945 if conditions.is_empty() && kind == ast::JoinKind::Inner {
1946 let node = self.add_node(Node::CrossProduct { left: left_node, right: right_node });
1947 return Ok((node, scope));
1948 }
1949 let kind = match kind {
1950 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
1951 ast::JoinKind::Left => JoinKind::Left,
1952 ast::JoinKind::Right => JoinKind::Right,
1953 ast::JoinKind::Full => JoinKind::Full,
1954 ast::JoinKind::Semi => JoinKind::Semi,
1955 ast::JoinKind::Anti => JoinKind::Anti,
1956 ast::JoinKind::Positional => JoinKind::Positional,
1957 };
1958 let conditions = self.plan.add_expr_list(&conditions);
1959 let node =
1960 self.add_node(Node::Join { left: left_node, right: right_node, kind, conditions });
1961 Ok((node, scope))
1962 }
1963
1964 pub(crate) fn bind_aggregate(
1968 &mut self,
1969 ast: &Ast,
1970 name: &str,
1971 args: &[ast::ExprRef],
1972 distinct: bool,
1973 scope: &Scope,
1974 ) -> Result<ExprRef> {
1975 if self.in_aggregate {
1976 return Err(Error::binder(format!(
1977 "aggregate function calls cannot be nested, and {name}() is inside one"
1978 )));
1979 }
1980 if self.aggregation.is_none() {
1981 return Err(Error::binder(format!(
1982 "aggregate function calls cannot be used in the {}",
1983 self.clause
1984 )));
1985 }
1986 self.in_aggregate = true;
1987 let mut bound = Vec::with_capacity(args.len());
1988 let mut failure = None;
1989 for &arg in args {
1990 match self.bind_expr(ast, arg, scope) {
1991 Ok(expr) => bound.push(expr),
1992 Err(error) => {
1993 failure = Some(error);
1994 break;
1995 }
1996 }
1997 }
1998 self.in_aggregate = false;
1999 if let Some(error) = failure {
2000 return Err(error);
2001 }
2002
2003 let types: Vec<LogicalType> =
2004 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
2005 let resolved = resolve(name, &types)?;
2006 let mut cast = Vec::with_capacity(bound.len());
2007 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
2008 cast.push(self.checked_cast_to(*arg, wanted, false)?);
2009 }
2010 let args = self.plan.add_expr_list(&cast);
2011 let name = self.plan.intern(resolved.name);
2012 let ty = resolved.returns;
2013 let call =
2014 self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter: None }, ty.clone());
2015
2016 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
2019 let existing = existing.unwrap_or_default();
2020 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
2021 Some(at) => at,
2022 None => {
2023 let aggregation = self.aggregation.as_mut().expect("checked above");
2024 aggregation.aggregates.push(call);
2025 aggregation.aggregates.len() - 1
2026 }
2027 };
2028 let aggregation = self.aggregation.as_ref().expect("checked above");
2029 let (index, groups) = (aggregation.index, aggregation.groups.len());
2030 Ok(self.column(index, groups + at, ty))
2031 }
2032
2033 pub(crate) fn bind_window(
2041 &mut self,
2042 ast: &Ast,
2043 written: &WindowCall<'_>,
2044 scope: &Scope,
2045 ) -> Result<ExprRef> {
2046 let WindowCall { name, args, distinct, ignore_nulls, spec } = *written;
2047 if self.in_aggregate {
2048 return Err(Error::binder(
2049 "aggregate function calls cannot contain window function calls",
2050 ));
2051 }
2052 if self.in_window {
2053 return Err(Error::binder("window function calls cannot be nested"));
2054 }
2055 let clause = if self.clause == "JOIN condition" { "WHERE clause" } else { self.clause };
2059 if clause != "SELECT clause" && clause != "ORDER BY clause" {
2060 return Err(Error::binder(format!("{clause} cannot contain window functions!")));
2061 }
2062
2063 let starred = args.iter().any(|&arg| {
2067 matches!(ast.expr(arg), ast::Expr::Star { qualifier, replacements }
2068 if qualifier.is_empty() && replacements.is_empty())
2069 });
2070 let (name, args): (&str, &[ast::ExprRef]) = if starred {
2071 if !same_name(name, "count") || args.len() != 1 {
2072 return Err(Error::binder(format!("* is not allowed in {name}()")));
2073 }
2074 ("count_star", &[])
2075 } else if same_name(name, "count") && args.is_empty() {
2076 ("count_star", &[])
2079 } else {
2080 (name, args)
2081 };
2082
2083 let held = ast.window(spec);
2084 self.in_window = true;
2085 let parts = self.window_parts(ast, args, held, scope);
2086 self.in_window = false;
2087 let parts = parts?;
2088 let offsets = [parts.frame.start, parts.frame.end]
2091 .iter()
2092 .any(|end| matches!(end, WindowBound::Preceding(_) | WindowBound::Following(_)));
2093 if parts.frame.unit == WindowUnit::Range && offsets && parts.order.len() != 1 {
2094 return Err(Error::binder("RANGE frames must have only one ORDER BY expression"));
2095 }
2096
2097 let types: Vec<LogicalType> =
2098 parts.args.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
2099 let resolved = window_signature(name, &types)?;
2100 if resolved.name == "fill" {
2103 let keys: Vec<LogicalType> =
2104 parts.order.iter().map(|key| self.plan.expr_type(key.expr).clone()).collect();
2105 refuse_fill(&types[0], &keys, distinct, ignore_nulls)?;
2106 }
2107 if distinct && kind_of(resolved.name) == Some(FunctionKind::Window) {
2111 return Err(Error::binder(format!(
2112 "DISTINCT is not implemented for the window function \"\"{name}\"\""
2113 )));
2114 }
2115 let mut cast = Vec::with_capacity(parts.args.len());
2116 for (arg, wanted) in parts.args.iter().zip(&resolved.arguments) {
2117 cast.push(self.checked_cast_to(*arg, wanted, false)?);
2118 }
2119 let args = self.plan.add_expr_list(&cast);
2120 let name = self.plan.intern(resolved.name);
2121 let ty = resolved.returns;
2122 let call = self.plan.add_expr(
2123 Expr::Window { name, args, distinct, filter: None, ignore_nulls },
2124 ty.clone(),
2125 );
2126
2127 let at = self.window_run(parts.partition, parts.order, parts.frame, call);
2128 let index = self.windows.last().expect("the run was just filed").index;
2129 Ok(self.column(index, at, ty))
2130 }
2131
2132 fn window_run(
2139 &mut self,
2140 partition: Vec<ExprRef>,
2141 order: Vec<SortKey>,
2142 frame: WindowFrame,
2143 call: ExprRef,
2144 ) -> usize {
2145 let matches = self.windows.last().is_some_and(|run| {
2146 run.frame == frame
2147 && run.partition.len() == partition.len()
2148 && run.order.len() == order.len()
2149 && run.partition.iter().zip(&partition).all(|(&l, &r)| self.same_expr(l, r))
2150 && run.order.iter().zip(&order).all(|(l, r)| {
2151 l.descending == r.descending
2152 && l.nulls_first == r.nulls_first
2153 && self.same_expr(l.expr, r.expr)
2154 })
2155 });
2156 if !matches {
2157 let index = self.fresh_index();
2158 self.windows.push(WindowRun { index, partition, order, frame, calls: Vec::new() });
2159 }
2160 let calls = self.windows.last().expect("a run is open").calls.clone();
2163 if let Some(at) = calls.iter().position(|&held| self.same_expr(held, call)) {
2164 return at;
2165 }
2166 let run = self.windows.last_mut().expect("a run is open");
2167 run.calls.push(call);
2168 run.calls.len() - 1
2169 }
2170
2171 fn window_parts(
2177 &mut self,
2178 ast: &Ast,
2179 args: &[ast::ExprRef],
2180 held: ast::WindowSpec,
2181 scope: &Scope,
2182 ) -> Result<WindowParts> {
2183 let mut bound = Vec::with_capacity(args.len());
2184 for &arg in args {
2185 let expr = self.bind_expr(ast, arg, scope)?;
2186 bound.push(self.over_aggregate(expr, scope)?);
2187 }
2188 let mut partition = Vec::new();
2189 for &key in ast.expr_list(held.partition) {
2190 let expr = self.bind_expr(ast, key, scope)?;
2191 partition.push(self.over_aggregate(expr, scope)?);
2192 }
2193 let mut order = Vec::new();
2194 for item in ast.order_list(held.order).to_vec() {
2195 let expr = self.bind_expr(ast, item.expr, scope)?;
2196 let expr = self.over_aggregate(expr, scope)?;
2197 order.push(self.sort_key(expr, item));
2198 }
2199 let frame = WindowFrame {
2200 unit: match held.unit {
2201 ast::WindowUnit::Rows => WindowUnit::Rows,
2202 ast::WindowUnit::Range => WindowUnit::Range,
2203 ast::WindowUnit::Groups => WindowUnit::Groups,
2204 },
2205 start: self.window_bound(ast, held.start, scope)?,
2206 end: self.window_bound(ast, held.end, scope)?,
2207 exclude: match held.exclude {
2208 ast::WindowExclude::NoOthers => WindowExclude::NoOthers,
2209 ast::WindowExclude::CurrentRow => WindowExclude::CurrentRow,
2210 ast::WindowExclude::Group => WindowExclude::Group,
2211 ast::WindowExclude::Ties => WindowExclude::Ties,
2212 },
2213 };
2214 Ok(WindowParts { args: bound, partition, order, frame })
2215 }
2216
2217 fn window_bound(
2219 &mut self,
2220 ast: &Ast,
2221 bound: ast::WindowBound,
2222 scope: &Scope,
2223 ) -> Result<WindowBound> {
2224 let offset = |binder: &mut Self, written| {
2225 let expr = binder.bind_expr(ast, written, scope)?;
2226 binder.over_aggregate(expr, scope)
2227 };
2228 Ok(match bound {
2229 ast::WindowBound::UnboundedPreceding => WindowBound::UnboundedPreceding,
2230 ast::WindowBound::CurrentRow => WindowBound::CurrentRow,
2231 ast::WindowBound::UnboundedFollowing => WindowBound::UnboundedFollowing,
2232 ast::WindowBound::Preceding(written) => WindowBound::Preceding(offset(self, written)?),
2233 ast::WindowBound::Following(written) => WindowBound::Following(offset(self, written)?),
2234 })
2235 }
2236
2237 fn is_window_output(&self, binding: ColumnBinding) -> bool {
2239 self.windows.iter().any(|run| run.index == binding.table)
2240 }
2241
2242 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
2248 let Some(aggregation) = self.aggregation.as_ref() else {
2249 return Ok(expr);
2250 };
2251 let index = aggregation.index;
2252 let groups = aggregation.groups.clone();
2253 for (at, group) in groups.iter().enumerate() {
2254 if self.same_expr(expr, *group) {
2255 let ty = self.plan.expr_type(*group).clone();
2256 return Ok(self.column(index, at, ty));
2257 }
2258 }
2259 let ty = self.plan.expr_type(expr).clone();
2260 match self.plan.expr(expr).clone() {
2261 Expr::Column(binding) if binding.table == index => Ok(expr),
2262 Expr::Column(binding) if self.is_window_output(binding) => Ok(expr),
2267 Expr::Column(binding) => {
2268 let name =
2269 scope.columns.iter().find(|column| column.binding == binding).map_or_else(
2270 || "a column".to_string(),
2271 |column| format!("\"{}\"", column.name),
2272 );
2273 Err(Error::binder(format!(
2274 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
2275 )))
2276 }
2277 Expr::Constant(_) | Expr::Aggregate { .. } | Expr::Window { .. } => Ok(expr),
2278 Expr::Cast { input, try_cast } => {
2279 let input = self.over_aggregate(input, scope)?;
2280 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
2281 }
2282 Expr::Compare { op, left, right } => {
2283 let left = self.over_aggregate(left, scope)?;
2284 let right = self.over_aggregate(right, scope)?;
2285 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
2286 }
2287 Expr::Conjunction { op, children } => {
2288 let written = self.plan.expr_list(children).to_vec();
2289 let mut rewritten = Vec::with_capacity(written.len());
2290 for child in written {
2291 rewritten.push(self.over_aggregate(child, scope)?);
2292 }
2293 let children = self.plan.add_expr_list(&rewritten);
2294 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
2295 }
2296 Expr::Function { name, args } => {
2297 let written = self.plan.expr_list(args).to_vec();
2298 let mut rewritten = Vec::with_capacity(written.len());
2299 for arg in written {
2300 rewritten.push(self.over_aggregate(arg, scope)?);
2301 }
2302 let args = self.plan.add_expr_list(&rewritten);
2303 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
2304 }
2305 Expr::Case { arms, otherwise } => {
2306 let written = self.plan.arm_list(arms).to_vec();
2307 let mut rewritten = Vec::with_capacity(written.len());
2308 for arm in written {
2309 let when = self.over_aggregate(arm.when, scope)?;
2310 let then = self.over_aggregate(arm.then, scope)?;
2311 rewritten.push(rudb_plan::Arm { when, then });
2312 }
2313 let otherwise = match otherwise {
2314 Some(expr) => Some(self.over_aggregate(expr, scope)?),
2315 None => None,
2316 };
2317 let arms = self.plan.add_arms(&rewritten);
2318 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
2319 }
2320 }
2321 }
2322
2323 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
2325 same_expr(&self.plan, left, right)
2326 }
2327}
2328
2329#[derive(Debug, Default)]
2339struct Options {
2340 binary_as_string: bool,
2343 all_varchar: bool,
2345 file_row_number: bool,
2350 given: Given,
2352}
2353
2354impl Options {
2355 fn of(written: &[(&'static str, Value, ExprRef)]) -> Result<Self> {
2362 let mut options = Self::default();
2363 for (parameter, value, _) in written {
2364 match (*parameter, value) {
2365 ("binary_as_string", Value::Boolean(on)) => options.binary_as_string = *on,
2366 ("all_varchar", Value::Boolean(on)) => options.all_varchar = *on,
2367 ("file_row_number", Value::Boolean(on)) => options.file_row_number = *on,
2368 _ => {}
2369 }
2370 }
2371 let named: Vec<(&str, Value)> =
2372 written.iter().map(|(parameter, value, _)| (*parameter, value.clone())).collect();
2373 options.given = csv_given(&named)?;
2374 Ok(options)
2375 }
2376}
2377
2378fn null_parameter(function: TableFunction, parameter: &str) -> String {
2387 match parameter {
2388 "header" => format!("\"{parameter}\" expects a non-null boolean value (e.g. TRUE or 1)"),
2389 "all_varchar" => format!("{} \"{parameter}\" cannot be NULL", function.name()),
2390 _ => format!("Cannot use NULL as argument to \"{parameter}\""),
2391 }
2392}
2393
2394fn missing_replacement(name: &str, input: &Scope) -> Error {
2399 Error::binder(format!(
2400 "Column \"{name}\" in REPLACE list not found in FROM clause{}",
2401 input.candidates()
2402 ))
2403}
2404
2405fn subtractable(ty: &LogicalType, ordering: bool) -> bool {
2414 if ty.is_numeric() {
2415 return true;
2416 }
2417 match ty {
2418 LogicalType::Date
2419 | LogicalType::Time
2420 | LogicalType::Timestamp
2421 | LogicalType::TimestampS
2422 | LogicalType::TimestampMs
2423 | LogicalType::TimestampNs
2424 | LogicalType::TimestampTz => true,
2425 LogicalType::TimeTz => ordering,
2426 _ => false,
2427 }
2428}
2429
2430fn refuse_fill(
2439 argument: &LogicalType,
2440 order: &[LogicalType],
2441 distinct: bool,
2442 ignore_nulls: bool,
2443) -> Result<()> {
2444 if !subtractable(argument, false) {
2445 return Err(Error::binder("FILL argument must support subtraction"));
2446 }
2447 let [key] = order else {
2448 return Err(Error::binder("FILL functions must have only one ORDER BY expression"));
2449 };
2450 if !subtractable(key, true) {
2451 return Err(Error::binder("FILL ordering must support subtraction"));
2452 }
2453 if distinct {
2454 return Err(Error::binder(
2455 "DISTINCT is not implemented for the window function \"\"fill\"\"",
2456 ));
2457 }
2458 if ignore_nulls {
2459 return Err(Error::binder(
2460 "RESPECT/IGNORE NULLS is not supported for the window function \"fill\"",
2461 ));
2462 }
2463 Ok(())
2464}
2465
2466fn window_signature(name: &str, types: &[LogicalType]) -> Result<Resolved> {
2473 match kind_of(name) {
2474 Some(FunctionKind::Aggregate | FunctionKind::Window) => resolve(name, types),
2475 Some(FunctionKind::Scalar) => {
2476 Err(Error::catalog(format!("{name} is not an aggregate function")))
2477 }
2478 None => Err(Error::catalog(format!("Aggregate Function with name {name} does not exist!"))),
2479 }
2480}
2481
2482fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
2484 if left == right {
2485 return true;
2486 }
2487 if plan.expr_type(left) != plan.expr_type(right) {
2488 return false;
2489 }
2490 let lists = |left, right| {
2491 let left: &[ExprRef] = plan.expr_list(left);
2492 let right: &[ExprRef] = plan.expr_list(right);
2493 left.len() == right.len()
2494 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
2495 };
2496 match (plan.expr(left), plan.expr(right)) {
2497 (Expr::Column(left), Expr::Column(right)) => left == right,
2498 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
2499 (
2500 Expr::Cast { input: left, try_cast: left_try },
2501 Expr::Cast { input: right, try_cast: right_try },
2502 ) => left_try == right_try && same_expr(plan, *left, *right),
2503 (
2504 Expr::Compare { op: left_op, left: left_a, right: left_b },
2505 Expr::Compare { op: right_op, left: right_a, right: right_b },
2506 ) => {
2507 left_op == right_op
2508 && same_expr(plan, *left_a, *right_a)
2509 && same_expr(plan, *left_b, *right_b)
2510 }
2511 (
2512 Expr::Conjunction { op: left_op, children: left_children },
2513 Expr::Conjunction { op: right_op, children: right_children },
2514 ) => left_op == right_op && lists(*left_children, *right_children),
2515 (
2516 Expr::Function { name: left_name, args: left_args },
2517 Expr::Function { name: right_name, args: right_args },
2518 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
2519 (
2520 Expr::Aggregate {
2521 name: left_name,
2522 args: left_args,
2523 distinct: left_distinct,
2524 filter: left_filter,
2525 },
2526 Expr::Aggregate {
2527 name: right_name,
2528 args: right_args,
2529 distinct: right_distinct,
2530 filter: right_filter,
2531 },
2532 ) => {
2533 plan.string(*left_name) == plan.string(*right_name)
2534 && left_distinct == right_distinct
2535 && match (left_filter, right_filter) {
2536 (None, None) => true,
2537 (Some(left), Some(right)) => same_expr(plan, *left, *right),
2538 _ => false,
2539 }
2540 && lists(*left_args, *right_args)
2541 }
2542 (
2546 Expr::Window {
2547 name: left_name,
2548 args: left_args,
2549 distinct: left_distinct,
2550 filter: left_filter,
2551 ignore_nulls: left_nulls,
2552 },
2553 Expr::Window {
2554 name: right_name,
2555 args: right_args,
2556 distinct: right_distinct,
2557 filter: right_filter,
2558 ignore_nulls: right_nulls,
2559 },
2560 ) => {
2561 plan.string(*left_name) == plan.string(*right_name)
2562 && left_distinct == right_distinct
2563 && left_nulls == right_nulls
2564 && match (left_filter, right_filter) {
2565 (None, None) => true,
2566 (Some(left), Some(right)) => same_expr(plan, *left, *right),
2567 _ => false,
2568 }
2569 && lists(*left_args, *right_args)
2570 }
2571 (
2572 Expr::Case { arms: left_arms, otherwise: left_otherwise },
2573 Expr::Case { arms: right_arms, otherwise: right_otherwise },
2574 ) => {
2575 let left_arms = plan.arm_list(*left_arms);
2576 let right_arms = plan.arm_list(*right_arms);
2577 left_arms.len() == right_arms.len()
2578 && left_arms.iter().zip(right_arms).all(|(left, right)| {
2579 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
2580 })
2581 && match (left_otherwise, right_otherwise) {
2582 (None, None) => true,
2583 (Some(left), Some(right)) => same_expr(plan, *left, *right),
2584 _ => false,
2585 }
2586 }
2587 _ => false,
2588 }
2589}