1use rudb_catalog::{Catalog, Entry, QualifiedName, same_name};
16use rudb_common::{Error, Field, LogicalType, Result, Session, Value};
17use rudb_functions::{
18 Columns, FILE_ROW_NUMBER, Given, TableFunction, csv_fields, csv_given, files, is_file,
19 is_pattern, parquet_fields, resolve, resolve_table,
20};
21use rudb_parse::ast::{self, Ast, Distinct, LiteralKind, Nulls, Order, Quantifier, SetOp};
22use rudb_parse::{NONE, parse_ast};
23use rudb_plan::{ColumnBinding, Expr, ExprRef, JoinKind, Node, NodeRef, Plan, SetOpKind, SortKey};
24
25use crate::expr::{describe, has_aggregate};
26use crate::parameters::Parameters;
27use crate::scope::{Scope, Visible};
28
29pub fn bind(ast: &Ast, catalog: &Catalog) -> Result<Plan> {
36 bind_with(ast, catalog, &Parameters::new(), &Session::new())
37}
38
39pub fn bind_with(
48 ast: &Ast,
49 catalog: &Catalog,
50 parameters: &Parameters,
51 session: &Session,
52) -> Result<Plan> {
53 let query = match ast.statements.as_slice() {
54 [ast::Statement::Query(query)] => *query,
55 [] => return Err(Error::binder("no statement to bind")),
56 [_] => return Err(Error::not_implemented("a statement that is not a query")),
59 _ => return Err(Error::not_implemented("a script of more than one statement")),
60 };
61 let mut binder = Binder::with(catalog, parameters, session);
62 let (root, _) = binder.bind_query(ast, query)?;
63 let mut plan = binder.into_plan();
64 plan.set_root(root);
65 plan.validate()?;
66 Ok(plan)
67}
68
69pub fn bind_sql(query: &str, catalog: &Catalog) -> Result<Plan> {
75 bind_sql_with(query, catalog, &Session::new())
76}
77
78pub fn bind_sql_with(query: &str, catalog: &Catalog, session: &Session) -> Result<Plan> {
84 let ast = parse_ast(query)?;
85 bind_with(&ast, catalog, &Parameters::new(), session)
86}
87
88#[derive(Debug)]
90pub(crate) struct Aggregation {
91 pub(crate) index: u32,
93 pub(crate) groups: Vec<ExprRef>,
95 pub(crate) aggregates: Vec<ExprRef>,
97}
98
99#[derive(Debug)]
101pub(crate) struct Binder<'a> {
102 catalog: &'a Catalog,
103 pub(crate) parameters: &'a Parameters,
105 pub(crate) session: &'a Session,
107 plan: Plan,
108 next_index: u32,
109 pub(crate) aggregation: Option<Aggregation>,
111 pub(crate) in_aggregate: bool,
113 pub(crate) clause: &'static str,
115 expanding: Vec<String>,
117}
118
119impl<'a> Binder<'a> {
120 pub(crate) fn with(
121 catalog: &'a Catalog,
122 parameters: &'a Parameters,
123 session: &'a Session,
124 ) -> Self {
125 Self {
126 catalog,
127 parameters,
128 session,
129 plan: Plan::new(),
130 next_index: 0,
131 aggregation: None,
132 in_aggregate: false,
133 clause: "SELECT clause",
134 expanding: Vec::new(),
135 }
136 }
137
138 pub(crate) fn plan(&self) -> &Plan {
139 &self.plan
140 }
141
142 pub(crate) fn plan_mut(&mut self) -> &mut Plan {
143 &mut self.plan
144 }
145
146 pub(crate) fn into_plan(self) -> Plan {
147 self.plan
148 }
149
150 pub(crate) fn fresh_index(&mut self) -> u32 {
152 let index = self.next_index;
153 self.next_index += 1;
154 index
155 }
156
157 fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
159 let binding = ColumnBinding::new(index, position as u32);
160 self.plan.add_expr(Expr::Column(binding), ty)
161 }
162
163 pub(crate) fn bind_query(
166 &mut self,
167 ast: &Ast,
168 query: ast::QueryRef,
169 ) -> Result<(NodeRef, Scope)> {
170 let written = ast.query(query);
171 match written.body {
172 ast::QueryBody::Select(select) => self.bind_select(ast, select, &written),
173 ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
174 if by_name {
175 return Err(Error::not_implemented("UNION BY NAME"));
176 }
177 self.bind_set_op(ast, &written, op, quantifier, left, right)
178 }
179 ast::QueryBody::Values(rows) => self.bind_values(ast, &written, rows),
180 ast::QueryBody::Describe(inner) => self.bind_describe(ast, &written, inner),
181 }
182 }
183
184 fn bind_describe(
200 &mut self,
201 ast: &Ast,
202 query: &ast::Query,
203 inner: ast::QueryRef,
204 ) -> Result<(NodeRef, Scope)> {
205 let (_, described) = self.bind_query(ast, inner)?;
206 let fields: Vec<Field> = ["column_name", "column_type", "null", "key", "default", "extra"]
207 .iter()
208 .map(|name| Field::new(*name, LogicalType::Varchar))
209 .collect();
210 let mut slices = Vec::with_capacity(described.columns.len());
211 for column in described.columns.clone() {
212 let written = [
215 column.name.clone(),
216 column.ty.to_string(),
217 if column.not_null { "NO" } else { "YES" }.to_owned(),
218 ];
219 let mut items: Vec<ExprRef> = written
220 .into_iter()
221 .map(|text| self.plan.add_constant(Value::Varchar(text)))
222 .collect();
223 for _ in 0..3 {
224 let empty = self.plan.add_constant(Value::Null);
225 items.push(self.cast_to(empty, &LogicalType::Varchar));
226 }
227 slices.push(self.plan.add_expr_list(&items));
228 }
229 let rows = self.plan.add_rows(&slices);
230 let columns = self.plan.add_fields(&fields);
231 let index = self.fresh_index();
232 let mut node = self.plan.add_node(Node::Values { index, columns, rows });
233 let mut scope = Scope::empty();
234 for (at, field) in fields.iter().enumerate() {
235 scope.push(Visible {
236 table: String::new(),
237 name: field.name.clone(),
238 binding: ColumnBinding::new(index, at as u32),
239 ty: field.ty.clone(),
240 not_null: false,
241 });
242 }
243 let keys = self.sort_keys(ast, query, &scope, &[])?;
244 if !keys.is_empty() {
245 let keys = self.plan.add_sort_keys(&keys);
246 node = self.plan.add_node(Node::Sort { input: node, keys });
247 }
248 node = self.apply_limit(ast, query, node)?;
249 Ok((node, scope))
250 }
251
252 fn passes_through(&self, expr: ExprRef, input: &Scope) -> bool {
258 let Expr::Column(binding) = *self.plan.expr(expr) else { return false };
259 input.columns.iter().any(|column| column.binding == binding && column.not_null)
260 }
261
262 fn bind_values(
269 &mut self,
270 ast: &Ast,
271 query: &ast::Query,
272 rows: ast::Slice,
273 ) -> Result<(NodeRef, Scope)> {
274 let written = ast.rows(rows).to_vec();
275 let Some(first) = written.first() else {
276 return Err(Error::binder("VALUES needs at least one row"));
277 };
278 let width = first.len as usize;
279 for (at, row) in written.iter().enumerate() {
280 if row.len as usize != width {
281 return Err(Error::binder(format!(
282 "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
283 at + 1,
284 row.len
285 )));
286 }
287 }
288 let empty = Scope::empty();
290 let previous = std::mem::replace(&mut self.clause, "VALUES clause");
291 let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
292 for row in &written {
293 let mut items = Vec::with_capacity(width);
294 for &expr in ast.expr_list(*row) {
295 items.push(self.bind_expr(ast, expr, &empty)?);
296 }
297 bound.push(items);
298 }
299 self.clause = previous;
300 let mut types = Vec::with_capacity(width);
301 for at in 0..width {
302 let mut ty = self.plan.expr_type(bound[0][at]).clone();
303 for row in &bound[1..] {
304 let other = self.plan.expr_type(row[at]).clone();
305 ty = ty.promote(&other).ok_or_else(|| {
306 Error::binder(format!(
307 "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
308 at + 1
309 ))
310 })?;
311 }
312 types.push(ty);
313 }
314 let mut slices = Vec::with_capacity(bound.len());
315 for row in &bound {
316 let items: Vec<ExprRef> =
317 row.iter().zip(&types).map(|(&expr, ty)| self.cast_to(expr, ty)).collect();
318 slices.push(self.plan.add_expr_list(&items));
319 }
320 let rows = self.plan.add_rows(&slices);
321 let fields: Vec<Field> = types
322 .iter()
323 .enumerate()
324 .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
325 .collect();
326 let columns = self.plan.add_fields(&fields);
327 let index = self.fresh_index();
328 let mut node = self.plan.add_node(Node::Values { index, columns, rows });
329 let mut scope = Scope::empty();
330 for (at, field) in fields.iter().enumerate() {
331 scope.push(Visible {
332 table: String::new(),
333 name: field.name.clone(),
334 binding: ColumnBinding::new(index, at as u32),
335 ty: field.ty.clone(),
336 not_null: false,
337 });
338 }
339 let keys = self.sort_keys(ast, query, &scope, &[])?;
340 if !keys.is_empty() {
341 let keys = self.plan.add_sort_keys(&keys);
342 node = self.plan.add_node(Node::Sort { input: node, keys });
343 }
344 node = self.apply_limit(ast, query, node)?;
345 Ok((node, scope))
346 }
347
348 fn bind_set_op(
349 &mut self,
350 ast: &Ast,
351 query: &ast::Query,
352 op: SetOp,
353 quantifier: Quantifier,
354 left: ast::QueryRef,
355 right: ast::QueryRef,
356 ) -> Result<(NodeRef, Scope)> {
357 let (left_node, left_scope) = self.bind_query(ast, left)?;
358 let (right_node, right_scope) = self.bind_query(ast, right)?;
359 if left_scope.len() != right_scope.len() {
360 return Err(Error::binder(format!(
361 "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
362 left_scope.len(),
363 right_scope.len()
364 )));
365 }
366 let mut types = Vec::with_capacity(left_scope.len());
368 for (left, right) in left_scope.columns.iter().zip(&right_scope.columns) {
369 let common = left.ty.promote(&right.ty).ok_or_else(|| {
370 Error::binder(format!(
371 "Cannot combine a column of type {} with a column of type {} in a set operation",
372 left.ty, right.ty
373 ))
374 })?;
375 types.push(common);
376 }
377 let left_node = self.conform(left_node, &left_scope, &types);
378 let right_node = self.conform(right_node, &right_scope, &types);
379 let index = self.fresh_index();
380 let kind = match op {
381 SetOp::Union => SetOpKind::Union,
382 SetOp::Except => SetOpKind::Except,
383 SetOp::Intersect => SetOpKind::Intersect,
384 };
385 let all = quantifier == Quantifier::All;
388 let mut node = self.plan.add_node(Node::SetOp {
389 left: left_node,
390 right: right_node,
391 kind,
392 all,
393 index,
394 });
395 let mut scope = Scope::empty();
396 for (at, (column, ty)) in left_scope.columns.iter().zip(&types).enumerate() {
397 scope.push(Visible {
398 table: String::new(),
399 name: column.name.clone(),
400 binding: ColumnBinding::new(index, at as u32),
401 ty: ty.clone(),
402 not_null: false,
405 });
406 }
407 let keys = self.sort_keys(ast, query, &scope, &[])?;
411 if !keys.is_empty() {
412 let keys = self.plan.add_sort_keys(&keys);
413 node = self.plan.add_node(Node::Sort { input: node, keys });
414 }
415 node = self.apply_limit(ast, query, node)?;
416 Ok((node, scope))
417 }
418
419 fn conform(&mut self, node: NodeRef, scope: &Scope, types: &[LogicalType]) -> NodeRef {
421 if scope.columns.iter().zip(types).all(|(column, ty)| &column.ty == ty) {
422 return node;
423 }
424 let index = self.fresh_index();
425 let mut exprs = Vec::with_capacity(types.len());
426 let mut names = Vec::with_capacity(types.len());
427 for (column, ty) in scope.columns.iter().zip(types) {
428 let expr = self.plan.add_expr(Expr::Column(column.binding), column.ty.clone());
429 exprs.push(self.cast_to(expr, ty));
430 names.push(self.plan.intern(&column.name));
431 }
432 let exprs = self.plan.add_expr_list(&exprs);
433 let names = self.plan.add_name_list(&names);
434 self.plan.add_node(Node::Project { input: node, index, exprs, names })
435 }
436
437 fn bind_select(
440 &mut self,
441 ast: &Ast,
442 select: ast::SelectRef,
443 query: &ast::Query,
444 ) -> Result<(NodeRef, Scope)> {
445 let written = ast.select(select);
446 let (mut node, input) = self.bind_from(ast, written.from)?;
447
448 if written.filter != NONE {
449 self.clause = "WHERE clause";
450 let predicate = self.bind_expr(ast, written.filter, &input)?;
451 let predicate = self.as_boolean(predicate, "WHERE")?;
452 node = self.plan.add_node(Node::Filter { input: node, predicate });
453 }
454
455 let targets = ast.target_list(written.targets).to_vec();
456 if targets.is_empty() {
457 return Err(Error::binder("a SELECT needs at least one expression to select"));
458 }
459
460 let group_items = self.group_items(ast, &written, &targets)?;
461 let aggregating = !group_items.is_empty()
462 || written.having != NONE
463 || targets.iter().any(|target| has_aggregate(ast, target.expr));
464 if aggregating {
465 self.clause = "GROUP BY clause";
466 let mut groups = Vec::with_capacity(group_items.len());
467 for item in &group_items {
468 groups.push(self.bind_expr(ast, *item, &input)?);
469 }
470 let index = self.fresh_index();
471 self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
472 }
473
474 self.clause = "SELECT clause";
475 let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input)?;
476 let visible = exprs.len();
477
478 let mut having = None;
479 if written.having != NONE {
480 self.clause = "HAVING clause";
481 let predicate = self.bind_expr(ast, written.having, &input)?;
482 let predicate = self.over_aggregate(predicate, &input)?;
483 having = Some(self.as_boolean(predicate, "HAVING")?);
484 }
485
486 let project = self.fresh_index();
489 let mut output = Scope::empty();
490 for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
491 output.push(Visible {
492 table: String::new(),
493 name: name.clone(),
494 binding: ColumnBinding::new(project, at as u32),
495 ty: self.plan.expr_type(*expr).clone(),
496 not_null: self.passes_through(*expr, &input),
497 });
498 }
499
500 self.clause = "ORDER BY clause";
501 let mut extra = Vec::new();
502 let keys = self.select_sort_keys(
503 ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra,
504 )?;
505 if !extra.is_empty() && written.distinct != Distinct::No {
506 return Err(Error::binder(
507 "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
508 ));
509 }
510 let on = self.distinct_on(ast, written.distinct, &output)?;
511
512 if let Some(aggregation) = self.aggregation.take() {
513 let index = aggregation.index;
514 let groups = self.plan.add_expr_list(&aggregation.groups);
515 let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
516 node = self.plan.add_node(Node::Aggregate { input: node, index, groups, aggregates });
517 }
518 if let Some(predicate) = having {
519 node = self.plan.add_node(Node::Filter { input: node, predicate });
520 }
521
522 let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
523 let exprs_slice = self.plan.add_expr_list(&exprs);
524 let names_slice = self.plan.add_name_list(&interned);
525 node = self.plan.add_node(Node::Project {
526 input: node,
527 index: project,
528 exprs: exprs_slice,
529 names: names_slice,
530 });
531
532 if written.distinct != Distinct::No {
533 let on = self.plan.add_expr_list(&on);
534 node = self.plan.add_node(Node::Distinct { input: node, on });
535 }
536 if !keys.is_empty() {
537 let keys = self.plan.add_sort_keys(&keys);
538 node = self.plan.add_node(Node::Sort { input: node, keys });
539 }
540 node = self.apply_limit(ast, query, node)?;
541
542 if extra.is_empty() {
543 output.columns.truncate(visible);
544 return Ok((node, output));
545 }
546 let index = self.fresh_index();
549 let mut kept = Vec::with_capacity(visible);
550 let mut kept_names = Vec::with_capacity(visible);
551 let mut scope = Scope::empty();
552 for (at, name) in names.iter().enumerate().take(visible) {
553 let ty = output.columns[at].ty.clone();
554 kept.push(self.column(project, at, ty.clone()));
555 kept_names.push(self.plan.intern(name));
556 scope.push(Visible {
557 table: String::new(),
558 name: name.clone(),
559 binding: ColumnBinding::new(index, at as u32),
560 ty,
561 not_null: output.columns[at].not_null,
562 });
563 }
564 let exprs = self.plan.add_expr_list(&kept);
565 let names = self.plan.add_name_list(&kept_names);
566 node = self.plan.add_node(Node::Project { input: node, index, exprs, names });
567 Ok((node, scope))
568 }
569
570 fn bind_targets(
572 &mut self,
573 ast: &Ast,
574 targets: &[ast::Target],
575 input: &Scope,
576 ) -> Result<(Vec<ExprRef>, Vec<String>)> {
577 let mut exprs = Vec::with_capacity(targets.len());
578 let mut names = Vec::with_capacity(targets.len());
579 for target in targets {
580 if let ast::Expr::Star { qualifier, replacements } = ast.expr(target.expr) {
581 let table = ast.name(qualifier).last().map(str::to_string);
582 let expanded: Vec<Visible> =
583 input.star(table.as_deref())?.into_iter().cloned().collect();
584 let replacements = ast.target_list(replacements).to_vec();
585 let mut used = vec![false; replacements.len()];
586 for column in expanded {
587 let found = replacements.iter().zip(&mut used).find(|(replacement, _)| {
588 same_name(ast.string(replacement.alias), &column.name)
589 });
590 let (expr, name) = match found {
595 Some((replacement, used)) => {
596 *used = true;
597 let expr = self.bind_expr(ast, replacement.expr, input)?;
598 (expr, ast.string(replacement.alias).to_string())
599 }
600 None => (
601 self.plan.add_expr(Expr::Column(column.binding), column.ty),
602 column.name,
603 ),
604 };
605 exprs.push(self.over_aggregate(expr, input)?);
606 names.push(name);
607 }
608 if let Some((replacement, _)) =
612 replacements.iter().zip(&used).find(|(_, used)| !**used)
613 {
614 return Err(missing_replacement(ast.string(replacement.alias), input));
615 }
616 continue;
617 }
618 let expr = self.bind_expr(ast, target.expr, input)?;
619 exprs.push(self.over_aggregate(expr, input)?);
620 names.push(if target.alias == NONE {
621 self.output_name(ast, target.expr, input)
622 } else {
623 ast.string(target.alias).to_string()
624 });
625 }
626 Ok((exprs, names))
627 }
628
629 fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
635 if let ast::Expr::Column { name } = ast.expr(target) {
636 let parts: Vec<&str> = ast.name(name).collect();
637 if let Ok(found) = input.resolve(&parts) {
638 return found.name.clone();
639 }
640 }
641 describe(ast, target)
642 }
643
644 fn group_items(
646 &self,
647 ast: &Ast,
648 select: &ast::Select,
649 targets: &[ast::Target],
650 ) -> Result<Vec<ast::ExprRef>> {
651 if select.group_by_all {
652 return Ok(targets
655 .iter()
656 .filter(|target| !has_aggregate(ast, target.expr))
657 .map(|target| target.expr)
658 .collect());
659 }
660 let mut items = Vec::new();
661 for &item in ast.expr_list(select.group_by) {
662 items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
663 }
664 Ok(items)
665 }
666
667 fn output_reference(
669 &self,
670 ast: &Ast,
671 item: ast::ExprRef,
672 targets: &[ast::Target],
673 clause: &str,
674 ) -> Result<Option<ast::ExprRef>> {
675 match ast.expr(item) {
676 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
677 let written = ast.string(text);
678 let position: usize = written.parse().map_err(|_| {
679 Error::binder(format!("{clause} term {written} is not a column"))
680 })?;
681 if position == 0 || position > targets.len() {
682 return Err(Error::binder(format!(
683 "{clause} term out of range - should be between 1 and {}",
684 targets.len()
685 )));
686 }
687 Ok(Some(targets[position - 1].expr))
688 }
689 ast::Expr::Column { name } => {
690 let parts: Vec<&str> = ast.name(name).collect();
691 let [written] = parts.as_slice() else { return Ok(None) };
692 let mut found = None;
693 for target in targets {
694 if target.alias != NONE && same_name(ast.string(target.alias), written) {
695 if found.is_some() {
696 return Ok(None);
697 }
698 found = Some(target.expr);
699 }
700 }
701 Ok(found)
702 }
703 _ => Ok(None),
704 }
705 }
706
707 #[allow(clippy::too_many_arguments)]
711 fn select_sort_keys(
712 &mut self,
713 ast: &Ast,
714 query: &ast::Query,
715 input: &Scope,
716 output: &Scope,
717 project: u32,
718 exprs: &mut Vec<ExprRef>,
719 names: &mut Vec<String>,
720 extra: &mut Vec<usize>,
721 ) -> Result<Vec<SortKey>> {
722 if query.order_by_all {
723 return Ok(self.every_column(output));
724 }
725 let items = ast.order_list(query.order_by).to_vec();
726 let mut keys = Vec::with_capacity(items.len());
727 for item in items {
728 let position = match self.output_position(ast, item.expr, output)? {
729 Some(position) => position,
730 None => {
731 let bound = self.bind_expr(ast, item.expr, input)?;
732 let bound = self.over_aggregate(bound, input)?;
733 match exprs.iter().position(|&held| self.same_expr(held, bound)) {
734 Some(position) => position,
735 None => {
736 exprs.push(bound);
737 names.push(describe(ast, item.expr));
738 extra.push(exprs.len() - 1);
739 exprs.len() - 1
740 }
741 }
742 }
743 };
744 let ty = self.plan.expr_type(exprs[position]).clone();
745 let expr = self.column(project, position, ty);
746 keys.push(sort_key(expr, item));
747 }
748 Ok(keys)
749 }
750
751 fn sort_keys(
753 &mut self,
754 ast: &Ast,
755 query: &ast::Query,
756 output: &Scope,
757 targets: &[ast::Target],
758 ) -> Result<Vec<SortKey>> {
759 if query.order_by_all {
760 return Ok(self.every_column(output));
761 }
762 let items = ast.order_list(query.order_by).to_vec();
763 let mut keys = Vec::with_capacity(items.len());
764 for item in items {
765 let expr = match self.output_position(ast, item.expr, output)? {
766 Some(position) => {
767 let column = &output.columns[position];
768 let (binding, ty) = (column.binding, column.ty.clone());
769 self.plan.add_expr(Expr::Column(binding), ty)
770 }
771 None => {
772 let _ = targets;
773 self.bind_expr(ast, item.expr, output)?
774 }
775 };
776 keys.push(sort_key(expr, item));
777 }
778 Ok(keys)
779 }
780
781 fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
782 let columns: Vec<(ColumnBinding, LogicalType)> =
783 output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
784 columns
785 .into_iter()
786 .map(|(binding, ty)| {
787 let expr = self.plan.add_expr(Expr::Column(binding), ty);
788 SortKey { expr, descending: false, nulls_first: false }
789 })
790 .collect()
791 }
792
793 fn output_position(
795 &self,
796 ast: &Ast,
797 item: ast::ExprRef,
798 output: &Scope,
799 ) -> Result<Option<usize>> {
800 match ast.expr(item) {
801 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
802 let written = ast.string(text);
803 if written.contains(['.', 'e', 'E']) {
804 return Ok(None);
805 }
806 let position: usize = written.parse().map_err(|_| {
807 Error::binder(format!("ORDER BY term {written} is not a column"))
808 })?;
809 if position == 0 || position > output.len() {
810 return Err(Error::binder(format!(
811 "ORDER BY term out of range - should be between 1 and {}",
812 output.len()
813 )));
814 }
815 Ok(Some(position - 1))
816 }
817 ast::Expr::Column { name } => {
818 let parts: Vec<&str> = ast.name(name).collect();
819 let [written] = parts.as_slice() else { return Ok(None) };
820 Ok(output.position_of(None, written))
821 }
822 _ => Ok(None),
823 }
824 }
825
826 fn distinct_on(
828 &mut self,
829 ast: &Ast,
830 distinct: Distinct,
831 output: &Scope,
832 ) -> Result<Vec<ExprRef>> {
833 let Distinct::On(items) = distinct else {
834 return Ok(Vec::new());
835 };
836 let items = ast.expr_list(items).to_vec();
837 let mut on = Vec::with_capacity(items.len());
838 for item in items {
839 let Some(position) = self.output_position(ast, item, output)? else {
840 return Err(Error::not_implemented(
841 "DISTINCT ON an expression that is not in the select list",
842 ));
843 };
844 let column = &output.columns[position];
845 let (binding, ty) = (column.binding, column.ty.clone());
846 on.push(self.plan.add_expr(Expr::Column(binding), ty));
847 }
848 Ok(on)
849 }
850
851 fn apply_limit(&mut self, ast: &Ast, query: &ast::Query, input: NodeRef) -> Result<NodeRef> {
852 if query.limit_percent {
853 return Err(Error::not_implemented("LIMIT with a percentage"));
854 }
855 let count = self.constant_count(ast, query.limit, "LIMIT")?;
856 let offset = self.constant_count(ast, query.offset, "OFFSET")?.unwrap_or(0);
857 if count.is_none() && offset == 0 {
858 return Ok(input);
859 }
860 Ok(self.plan.add_node(Node::Limit { input, count, offset }))
861 }
862
863 fn constant_count(
865 &mut self,
866 ast: &Ast,
867 written: ast::ExprRef,
868 clause: &str,
869 ) -> Result<Option<u64>> {
870 if written == NONE {
871 return Ok(None);
872 }
873 self.clause = "LIMIT clause";
874 let scope = Scope::empty();
875 let bound = self.bind_expr(ast, written, &scope)?;
876 let Expr::Constant(value) = *self.plan.expr(bound) else {
877 return Err(Error::not_implemented(format!("a {clause} that is not a constant")));
878 };
879 let count = match self.plan.value(value) {
880 Value::Null => return Ok(None),
881 Value::TinyInt(count) => i128::from(*count),
882 Value::SmallInt(count) => i128::from(*count),
883 Value::Integer(count) => i128::from(*count),
884 Value::BigInt(count) => i128::from(*count),
885 Value::HugeInt(count) => *count,
886 other => {
887 return Err(Error::binder(format!(
888 "{clause} takes a whole number of rows, not a value of type {}",
889 other.logical_type()
890 )));
891 }
892 };
893 u64::try_from(count)
894 .map(Some)
895 .map_err(|_| Error::binder(format!("{clause} must not be negative")))
896 }
897
898 fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
901 let sources = ast.source_list(from).to_vec();
902 let Some((first, rest)) = sources.split_first() else {
903 return Ok((self.plan.add_node(Node::Dummy), Scope::empty()));
906 };
907 let (mut node, mut scope) = self.bind_source(ast, *first)?;
908 for source in rest {
909 let (right, right_scope) = self.bind_source(ast, *source)?;
910 node = self.plan.add_node(Node::CrossProduct { left: node, right });
911 scope = scope.concat(right_scope);
912 }
913 Ok((node, scope))
914 }
915
916 fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
917 match ast.source(source) {
918 ast::Source::Table { name, alias, columns } => {
919 self.bind_table(ast, name, alias, columns)
920 }
921 ast::Source::Function { name, args, alias, columns } => {
922 self.bind_table_function(ast, name, args, alias, columns)
923 }
924 ast::Source::Subquery { query, alias, columns } => {
925 let (node, mut scope) = self.bind_query(ast, query)?;
926 let label = if alias == NONE {
927 "unnamed_subquery".to_string()
928 } else {
929 ast.string(alias).to_string()
930 };
931 scope.relabel(&label);
932 if !columns.is_empty() {
933 let names: Vec<&str> = ast.name(columns).collect();
934 scope.rename(&names, &label)?;
935 }
936 Ok((node, scope))
937 }
938 ast::Source::Values { rows, alias, columns } => {
939 let bare = ast::Query::bare(ast::QueryBody::Values(rows));
940 let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
941 let label =
942 if alias == NONE { String::new() } else { ast.string(alias).to_string() };
943 scope.relabel(&label);
944 if !columns.is_empty() {
945 let names: Vec<&str> = ast.name(columns).collect();
946 scope.rename(&names, &label)?;
947 }
948 Ok((node, scope))
949 }
950 ast::Source::Join { left, right, kind, natural, on, using } => {
951 self.bind_join(ast, left, right, kind, natural, on, using)
952 }
953 }
954 }
955
956 fn bind_table(
957 &mut self,
958 ast: &Ast,
959 name: ast::Slice,
960 alias: ast::StrRef,
961 columns: ast::Slice,
962 ) -> Result<(NodeRef, Scope)> {
963 let parts: Vec<&str> = ast.name(name).collect();
964 let catalog = self.catalog;
965 let resolved = match catalog.resolve(&parts) {
968 Ok(resolved) => resolved,
969 Err(missing) => {
970 return self.bind_replacement_scan(ast, &parts, alias, columns, missing);
971 }
972 };
973 if catalog.entry(&resolved)? == Entry::View {
974 return self.bind_view(ast, &resolved, alias, columns);
975 }
976 let table = catalog.table(&resolved)?;
977 let fields: Vec<Field> = table.columns().to_vec();
978 let label =
979 if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
980 let index = self.fresh_index();
981 let mut scope = Scope::empty();
982 for (at, field) in fields.iter().enumerate() {
983 scope.push(Visible {
984 table: label.clone(),
985 name: field.name.clone(),
986 binding: ColumnBinding::new(index, at as u32),
987 ty: field.ty.clone(),
988 not_null: field.not_null,
989 });
990 }
991 if !columns.is_empty() {
992 let names: Vec<&str> = ast.name(columns).collect();
993 scope.rename(&names, &label)?;
994 }
995 let catalog_name = self.plan.intern(&resolved.catalog);
996 let schema = self.plan.intern(&resolved.schema);
997 let table_name = self.plan.intern(&resolved.table);
998 let alias = self.plan.intern(&label);
999 let columns = self.plan.add_fields(&fields);
1000 let node = self.plan.add_node(Node::Get {
1001 catalog: catalog_name,
1002 schema,
1003 table: table_name,
1004 alias,
1005 index,
1006 columns,
1007 });
1008 Ok((node, scope))
1009 }
1010
1011 fn bind_view(
1023 &mut self,
1024 ast: &Ast,
1025 name: &QualifiedName,
1026 alias: ast::StrRef,
1027 columns: ast::Slice,
1028 ) -> Result<(NodeRef, Scope)> {
1029 let view = self.catalog.view(name)?;
1030 let full = name.to_string();
1031 if self.expanding.contains(&full) {
1032 return Err(Error::binder(format!(
1036 "infinite recursion detected: attempting to recursively bind view \"\"{}\"\"",
1037 name.table
1038 )));
1039 }
1040 let body = parse_ast(view.sql())?;
1041 let query = match body.statements.as_slice() {
1042 [ast::Statement::Query(query)] => *query,
1043 _ => return Err(Error::binder(format!("view \"{}\" is not a query", name.table))),
1046 };
1047 self.expanding.push(full);
1048 let bound = self.bind_query(&body, query);
1049 self.expanding.pop();
1050 let (node, mut scope) = bound?;
1051
1052 let aliases: Vec<&str> = view.aliases().iter().map(String::as_str).collect();
1053 if !aliases.is_empty() {
1054 scope.rename(&aliases, "unnamed_subquery")?;
1055 }
1056 let label = if alias == NONE { name.table.clone() } else { ast.string(alias).to_string() };
1057 scope.relabel(&label);
1058 if !columns.is_empty() {
1059 let names: Vec<&str> = ast.name(columns).collect();
1060 scope.rename(&names, &label)?;
1061 }
1062 Ok((node, scope))
1063 }
1064
1065 fn bind_table_function(
1073 &mut self,
1074 ast: &Ast,
1075 name: ast::Slice,
1076 args: ast::Slice,
1077 alias: ast::StrRef,
1078 columns: ast::Slice,
1079 ) -> Result<(NodeRef, Scope)> {
1080 let parts: Vec<&str> = ast.name(name).collect();
1081 let function_name = *parts.last().unwrap_or(&"");
1085 if let Some(schema) = parts.iter().rev().nth(1) {
1086 if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
1087 return Err(Error::catalog(format!(
1088 "Table Function with name {} does not exist!",
1089 parts.join(".")
1090 )));
1091 }
1092 }
1093 let Some(called) = TableFunction::lookup(function_name) else {
1097 return Err(Error::catalog(format!(
1098 "Table Function with name {function_name} does not exist!"
1099 )));
1100 };
1101 let written = ast.target_list(args).to_vec();
1102 let empty = Scope::empty();
1103 let previous = std::mem::replace(&mut self.clause, "table function arguments");
1104 let mut bound = Vec::new();
1105 let mut written_options = Vec::new();
1106 for argument in written {
1107 let expr = self.bind_expr(ast, argument.expr, &empty)?;
1108 if argument.alias == NONE {
1109 bound.push(expr);
1110 } else {
1111 let name = ast.string(argument.alias).to_string();
1112 let (parameter, value) = self.named_argument(called, &name, expr)?;
1113 written_options.push((parameter, value, expr));
1114 }
1115 }
1116 self.clause = previous;
1117 let options = Options::of(&written_options)?;
1118
1119 let given: Vec<LogicalType> =
1122 bound.iter().map(|&expr| self.plan.expr_type(expr).clone()).collect();
1123 let resolved = resolve_table(function_name, &given)?;
1124 let mut cast: Vec<ExprRef> = bound
1125 .iter()
1126 .zip(&resolved.arguments)
1127 .map(|(&expr, ty)| self.cast_to(expr, ty))
1128 .collect();
1129
1130 let fields = match resolved.columns {
1131 Columns::Fixed(fields) => fields,
1132 columns => {
1133 let paths = self.file_paths(cast[0], resolved.function.name())?;
1138 let first = paths.first().map_or("", String::as_str);
1139 let mut fields = match columns {
1140 Columns::Csv => csv_fields(&paths, options.given)?,
1143 _ => parquet_fields(first)?,
1144 };
1145 if options.all_varchar {
1146 for field in &mut fields {
1151 field.ty = LogicalType::Varchar;
1152 }
1153 }
1154 if options.binary_as_string {
1155 for field in &mut fields {
1160 if field.ty == LogicalType::Blob {
1161 field.ty = LogicalType::Varchar;
1162 }
1163 }
1164 }
1165 if options.file_row_number {
1166 if fields.iter().any(|field| field.name == FILE_ROW_NUMBER) {
1172 return Err(Error::binder(format!(
1173 "Duplicate column name \"{FILE_ROW_NUMBER}\": the file already has a \
1174 column of that name, so file_row_number cannot add one"
1175 )));
1176 }
1177 fields.push(Field::required(FILE_ROW_NUMBER.to_string(), LogicalType::BigInt));
1178 }
1179 cast = paths.iter().map(|path| self.path_constant(path)).collect();
1180 fields
1181 }
1182 };
1183 let label = if alias == NONE {
1184 resolved.function.name().to_string()
1185 } else {
1186 ast.string(alias).to_string()
1187 };
1188 let names: Vec<&str> = ast.name(columns).collect();
1189 self.table_function_source(
1190 resolved.function,
1191 &cast,
1192 &written_options,
1193 fields,
1194 &label,
1195 &names,
1196 )
1197 }
1198
1199 fn named_argument(
1213 &mut self,
1214 function: TableFunction,
1215 name: &str,
1216 expr: ExprRef,
1217 ) -> Result<(&'static str, Value)> {
1218 let known = function
1219 .parameters()
1220 .iter()
1221 .find(|(parameter, _)| parameter.eq_ignore_ascii_case(name));
1222 let Some((parameter, wanted)) = known else {
1223 let candidates: Vec<String> = function
1224 .parameters()
1225 .iter()
1226 .map(|(parameter, ty)| format!(" {parameter} {ty}"))
1227 .collect();
1228 return Err(Error::binder(format!(
1229 "Invalid named parameter \"{name}\" for function {}\nCandidates:\n{}\n",
1230 function.name(),
1231 candidates.join("\n")
1232 )));
1233 };
1234 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1235 return Err(Error::not_implemented(format!(
1236 "the named parameter {parameter} with a value that is not a constant"
1237 )));
1238 };
1239 let value = self.plan.value(reference).clone();
1240 if value == Value::Null {
1241 return Err(Error::binder(null_parameter(function, parameter)));
1242 }
1243 let given = self.plan.expr_type(expr).clone();
1244 if given != *wanted {
1245 return Err(Error::not_implemented(format!(
1246 "the named parameter {parameter} given a {given} where a {wanted} was wanted"
1247 )));
1248 }
1249 Ok((parameter, value))
1250 }
1251
1252 fn bind_replacement_scan(
1263 &mut self,
1264 ast: &Ast,
1265 parts: &[&str],
1266 alias: ast::StrRef,
1267 columns: ast::Slice,
1268 missing: Error,
1269 ) -> Result<(NodeRef, Scope)> {
1270 let [path] = parts else { return Err(missing) };
1271 let path = *path;
1272 let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
1273 let Some(function) = Self::reader_for(extension) else {
1274 if is_file(path) {
1275 return Err(Error::binder(format!(
1280 "No extension found that is capable of reading the file \"{path}\"\n* If this \
1281 file is a supported file format you can explicitly use the reader functions, \
1282 such as read_csv, read_json or read_parquet"
1283 )));
1284 }
1285 return Err(missing);
1286 };
1287 let paths = files(path)?;
1292 let first = paths.first().map_or("", String::as_str);
1293 let fields = match function {
1294 TableFunction::ReadParquet => parquet_fields(first)?,
1295 _ => csv_fields(&paths, Given::default())?,
1296 };
1297 let label = if alias == NONE {
1303 if is_pattern(path) {
1304 path.to_string()
1305 } else {
1306 let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
1307 file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
1308 }
1309 } else {
1310 ast.string(alias).to_string()
1311 };
1312 let arguments: Vec<ExprRef> = paths.iter().map(|path| self.path_constant(path)).collect();
1313 let names: Vec<&str> = ast.name(columns).collect();
1314 self.table_function_source(function, &arguments, &[], fields, &label, &names)
1315 }
1316
1317 fn path_constant(&mut self, path: &str) -> ExprRef {
1319 let value = self.plan.add_value(Value::Varchar(path.to_string()));
1320 self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar)
1321 }
1322
1323 fn reader_for(extension: &str) -> Option<TableFunction> {
1330 if extension.eq_ignore_ascii_case("parquet") {
1331 return Some(TableFunction::ReadParquet);
1332 }
1333 if extension.eq_ignore_ascii_case("csv") || extension.eq_ignore_ascii_case("tsv") {
1334 return Some(TableFunction::ReadCsv);
1335 }
1336 None
1337 }
1338
1339 fn table_function_source(
1344 &mut self,
1345 function: TableFunction,
1346 args: &[ExprRef],
1347 written: &[(&'static str, Value, ExprRef)],
1348 fields: Vec<Field>,
1349 label: &str,
1350 names: &[&str],
1351 ) -> Result<(NodeRef, Scope)> {
1352 let index = self.fresh_index();
1353 let mut scope = Scope::empty();
1354 for (at, field) in fields.iter().enumerate() {
1355 scope.push(Visible {
1356 table: label.to_string(),
1357 name: field.name.clone(),
1358 binding: ColumnBinding::new(index, at as u32),
1359 ty: field.ty.clone(),
1360 not_null: false,
1363 });
1364 }
1365 if !names.is_empty() {
1366 scope.rename(names, label)?;
1367 }
1368 let function = self.plan.intern(function.name());
1369 let args = self.plan.add_expr_list(args);
1370 let named: Vec<u32> =
1371 written.iter().map(|(parameter, _, _)| self.plan.intern(parameter)).collect();
1372 let settings: Vec<ExprRef> = written.iter().map(|(_, _, expr)| *expr).collect();
1373 let options = self.plan.add_name_list(&named);
1374 let settings = self.plan.add_expr_list(&settings);
1375 let columns = self.plan.add_fields(&fields);
1376 let node = self.plan.add_node(Node::TableFunction {
1377 index,
1378 function,
1379 args,
1380 options,
1381 settings,
1382 columns,
1383 });
1384 Ok((node, scope))
1385 }
1386
1387 fn file_paths(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1394 let mut paths = Vec::new();
1395 for pattern in self.file_patterns(expr, name)? {
1396 paths.extend(files(&pattern)?);
1397 }
1398 Ok(paths)
1399 }
1400
1401 fn file_patterns(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1413 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1414 return Err(Error::not_implemented(
1415 "a table function file name that is not a constant",
1416 ));
1417 };
1418 match self.plan.value(reference) {
1419 Value::Varchar(path) => Ok(vec![path.clone()]),
1420 Value::Null => Err(Error::parser(format!("{name} cannot take NULL list as parameter"))),
1422 Value::List { values, .. } => values
1423 .iter()
1424 .map(|value| match value {
1425 Value::Varchar(path) => Ok(path.clone()),
1426 _ => Err(Error::parser(format!(
1427 "{name} reader cannot take NULL input as parameter"
1428 ))),
1429 })
1430 .collect(),
1431 other => {
1432 Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
1433 }
1434 }
1435 }
1436
1437 #[allow(clippy::too_many_arguments)]
1438 fn bind_join(
1439 &mut self,
1440 ast: &Ast,
1441 left: ast::SourceRef,
1442 right: ast::SourceRef,
1443 kind: ast::JoinKind,
1444 natural: bool,
1445 on: ast::ExprRef,
1446 using: ast::Slice,
1447 ) -> Result<(NodeRef, Scope)> {
1448 let (left_node, left_scope) = self.bind_source(ast, left)?;
1449 let (right_node, right_scope) = self.bind_source(ast, right)?;
1450 let split = left_scope.len();
1451 let mut scope = left_scope.concat(right_scope);
1452
1453 let merged: Vec<String> = if natural {
1456 let mut names = Vec::new();
1457 for (at, column) in scope.columns.iter().enumerate().take(split) {
1458 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
1459 && !names.iter().any(|held: &String| same_name(held, &column.name))
1460 {
1461 let _ = at;
1462 names.push(column.name.clone());
1463 }
1464 }
1465 names
1466 } else {
1467 let mut names: Vec<String> = Vec::new();
1473 for name in ast.name(using) {
1474 if !names.iter().any(|held| same_name(held, name)) {
1475 names.push(name.to_string());
1476 }
1477 }
1478 names
1479 };
1480
1481 let mut conditions = Vec::new();
1482 let mut dropped = Vec::new();
1483 for name in &merged {
1484 let left_at = scope.columns[..split]
1485 .iter()
1486 .position(|column| same_name(&column.name, name))
1487 .ok_or_else(|| {
1488 Error::binder(format!(
1489 "column \"{name}\" specified in USING clause does not exist in left table"
1490 ))
1491 })?;
1492 let right_at = scope.columns[split..]
1493 .iter()
1494 .position(|column| same_name(&column.name, name))
1495 .map(|at| at + split)
1496 .ok_or_else(|| {
1497 Error::binder(format!(
1498 "column \"{name}\" specified in USING clause does not exist in right table"
1499 ))
1500 })?;
1501 let left_column = &scope.columns[left_at];
1502 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
1503 let right_column = &scope.columns[right_at];
1504 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
1505 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
1506 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
1507 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
1508 dropped.push(right_at);
1509 }
1510 dropped.sort_unstable();
1513 for at in dropped.into_iter().rev() {
1514 scope.remove(at);
1515 }
1516
1517 if on != NONE {
1518 if !merged.is_empty() {
1519 return Err(Error::binder("a join cannot have both ON and USING"));
1520 }
1521 self.clause = "JOIN condition";
1522 let predicate = self.bind_expr(ast, on, &scope)?;
1523 conditions.push(self.as_boolean(predicate, "JOIN")?);
1524 }
1525
1526 if kind == ast::JoinKind::Cross {
1527 if !conditions.is_empty() {
1528 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
1529 }
1530 let node =
1531 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1532 return Ok((node, scope));
1533 }
1534 if conditions.is_empty() && kind == ast::JoinKind::Inner {
1535 let node =
1536 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1537 return Ok((node, scope));
1538 }
1539 let kind = match kind {
1540 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
1541 ast::JoinKind::Left => JoinKind::Left,
1542 ast::JoinKind::Right => JoinKind::Right,
1543 ast::JoinKind::Full => JoinKind::Full,
1544 ast::JoinKind::Semi => JoinKind::Semi,
1545 ast::JoinKind::Anti => JoinKind::Anti,
1546 ast::JoinKind::Positional => JoinKind::Positional,
1547 };
1548 let conditions = self.plan.add_expr_list(&conditions);
1549 let node =
1550 self.plan.add_node(Node::Join { left: left_node, right: right_node, kind, conditions });
1551 Ok((node, scope))
1552 }
1553
1554 pub(crate) fn bind_aggregate(
1558 &mut self,
1559 ast: &Ast,
1560 name: &str,
1561 args: &[ast::ExprRef],
1562 distinct: bool,
1563 scope: &Scope,
1564 ) -> Result<ExprRef> {
1565 if self.in_aggregate {
1566 return Err(Error::binder(format!(
1567 "aggregate function calls cannot be nested, and {name}() is inside one"
1568 )));
1569 }
1570 if self.aggregation.is_none() {
1571 return Err(Error::binder(format!(
1572 "aggregate function calls cannot be used in the {}",
1573 self.clause
1574 )));
1575 }
1576 self.in_aggregate = true;
1577 let mut bound = Vec::with_capacity(args.len());
1578 let mut failure = None;
1579 for &arg in args {
1580 match self.bind_expr(ast, arg, scope) {
1581 Ok(expr) => bound.push(expr),
1582 Err(error) => {
1583 failure = Some(error);
1584 break;
1585 }
1586 }
1587 }
1588 self.in_aggregate = false;
1589 if let Some(error) = failure {
1590 return Err(error);
1591 }
1592
1593 let types: Vec<LogicalType> =
1594 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
1595 let resolved = resolve(name, &types)?;
1596 let mut cast = Vec::with_capacity(bound.len());
1597 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
1598 cast.push(self.cast_to(*arg, wanted));
1599 }
1600 let args = self.plan.add_expr_list(&cast);
1601 let name = self.plan.intern(resolved.name);
1602 let ty = resolved.returns;
1603 let call =
1604 self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter: None }, ty.clone());
1605
1606 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
1609 let existing = existing.unwrap_or_default();
1610 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
1611 Some(at) => at,
1612 None => {
1613 let aggregation = self.aggregation.as_mut().expect("checked above");
1614 aggregation.aggregates.push(call);
1615 aggregation.aggregates.len() - 1
1616 }
1617 };
1618 let aggregation = self.aggregation.as_ref().expect("checked above");
1619 let (index, groups) = (aggregation.index, aggregation.groups.len());
1620 Ok(self.column(index, groups + at, ty))
1621 }
1622
1623 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
1629 let Some(aggregation) = self.aggregation.as_ref() else {
1630 return Ok(expr);
1631 };
1632 let index = aggregation.index;
1633 let groups = aggregation.groups.clone();
1634 for (at, group) in groups.iter().enumerate() {
1635 if self.same_expr(expr, *group) {
1636 let ty = self.plan.expr_type(*group).clone();
1637 return Ok(self.column(index, at, ty));
1638 }
1639 }
1640 let ty = self.plan.expr_type(expr).clone();
1641 match self.plan.expr(expr).clone() {
1642 Expr::Column(binding) if binding.table == index => Ok(expr),
1643 Expr::Column(binding) => {
1644 let name =
1645 scope.columns.iter().find(|column| column.binding == binding).map_or_else(
1646 || "a column".to_string(),
1647 |column| format!("\"{}\"", column.name),
1648 );
1649 Err(Error::binder(format!(
1650 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
1651 )))
1652 }
1653 Expr::Constant(_) | Expr::Aggregate { .. } => Ok(expr),
1654 Expr::Cast { input, try_cast } => {
1655 let input = self.over_aggregate(input, scope)?;
1656 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
1657 }
1658 Expr::Compare { op, left, right } => {
1659 let left = self.over_aggregate(left, scope)?;
1660 let right = self.over_aggregate(right, scope)?;
1661 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
1662 }
1663 Expr::Conjunction { op, children } => {
1664 let written = self.plan.expr_list(children).to_vec();
1665 let mut rewritten = Vec::with_capacity(written.len());
1666 for child in written {
1667 rewritten.push(self.over_aggregate(child, scope)?);
1668 }
1669 let children = self.plan.add_expr_list(&rewritten);
1670 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
1671 }
1672 Expr::Function { name, args } => {
1673 let written = self.plan.expr_list(args).to_vec();
1674 let mut rewritten = Vec::with_capacity(written.len());
1675 for arg in written {
1676 rewritten.push(self.over_aggregate(arg, scope)?);
1677 }
1678 let args = self.plan.add_expr_list(&rewritten);
1679 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
1680 }
1681 Expr::Case { arms, otherwise } => {
1682 let written = self.plan.arm_list(arms).to_vec();
1683 let mut rewritten = Vec::with_capacity(written.len());
1684 for arm in written {
1685 let when = self.over_aggregate(arm.when, scope)?;
1686 let then = self.over_aggregate(arm.then, scope)?;
1687 rewritten.push(rudb_plan::Arm { when, then });
1688 }
1689 let otherwise = match otherwise {
1690 Some(expr) => Some(self.over_aggregate(expr, scope)?),
1691 None => None,
1692 };
1693 let arms = self.plan.add_arms(&rewritten);
1694 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
1695 }
1696 }
1697 }
1698
1699 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
1701 same_expr(&self.plan, left, right)
1702 }
1703}
1704
1705#[derive(Debug, Default)]
1715struct Options {
1716 binary_as_string: bool,
1719 all_varchar: bool,
1721 file_row_number: bool,
1726 given: Given,
1728}
1729
1730impl Options {
1731 fn of(written: &[(&'static str, Value, ExprRef)]) -> Result<Self> {
1738 let mut options = Self::default();
1739 for (parameter, value, _) in written {
1740 match (*parameter, value) {
1741 ("binary_as_string", Value::Boolean(on)) => options.binary_as_string = *on,
1742 ("all_varchar", Value::Boolean(on)) => options.all_varchar = *on,
1743 ("file_row_number", Value::Boolean(on)) => options.file_row_number = *on,
1744 _ => {}
1745 }
1746 }
1747 let named: Vec<(&str, Value)> =
1748 written.iter().map(|(parameter, value, _)| (*parameter, value.clone())).collect();
1749 options.given = csv_given(&named)?;
1750 Ok(options)
1751 }
1752}
1753
1754fn null_parameter(function: TableFunction, parameter: &str) -> String {
1763 match parameter {
1764 "header" => format!("\"{parameter}\" expects a non-null boolean value (e.g. TRUE or 1)"),
1765 "all_varchar" => format!("{} \"{parameter}\" cannot be NULL", function.name()),
1766 _ => format!("Cannot use NULL as argument to \"{parameter}\""),
1767 }
1768}
1769
1770fn missing_replacement(name: &str, input: &Scope) -> Error {
1775 Error::binder(format!(
1776 "Column \"{name}\" in REPLACE list not found in FROM clause{}",
1777 input.candidates()
1778 ))
1779}
1780
1781fn sort_key(expr: ExprRef, item: ast::OrderItem) -> SortKey {
1787 let descending = item.order == Order::Descending;
1788 let nulls_first = match item.nulls {
1789 Nulls::First => true,
1790 Nulls::Last => false,
1791 Nulls::Unstated => descending,
1792 };
1793 SortKey { expr, descending, nulls_first }
1794}
1795
1796fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
1798 if left == right {
1799 return true;
1800 }
1801 if plan.expr_type(left) != plan.expr_type(right) {
1802 return false;
1803 }
1804 let lists = |left, right| {
1805 let left: &[ExprRef] = plan.expr_list(left);
1806 let right: &[ExprRef] = plan.expr_list(right);
1807 left.len() == right.len()
1808 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
1809 };
1810 match (plan.expr(left), plan.expr(right)) {
1811 (Expr::Column(left), Expr::Column(right)) => left == right,
1812 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
1813 (
1814 Expr::Cast { input: left, try_cast: left_try },
1815 Expr::Cast { input: right, try_cast: right_try },
1816 ) => left_try == right_try && same_expr(plan, *left, *right),
1817 (
1818 Expr::Compare { op: left_op, left: left_a, right: left_b },
1819 Expr::Compare { op: right_op, left: right_a, right: right_b },
1820 ) => {
1821 left_op == right_op
1822 && same_expr(plan, *left_a, *right_a)
1823 && same_expr(plan, *left_b, *right_b)
1824 }
1825 (
1826 Expr::Conjunction { op: left_op, children: left_children },
1827 Expr::Conjunction { op: right_op, children: right_children },
1828 ) => left_op == right_op && lists(*left_children, *right_children),
1829 (
1830 Expr::Function { name: left_name, args: left_args },
1831 Expr::Function { name: right_name, args: right_args },
1832 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
1833 (
1834 Expr::Aggregate {
1835 name: left_name,
1836 args: left_args,
1837 distinct: left_distinct,
1838 filter: left_filter,
1839 },
1840 Expr::Aggregate {
1841 name: right_name,
1842 args: right_args,
1843 distinct: right_distinct,
1844 filter: right_filter,
1845 },
1846 ) => {
1847 plan.string(*left_name) == plan.string(*right_name)
1848 && left_distinct == right_distinct
1849 && match (left_filter, right_filter) {
1850 (None, None) => true,
1851 (Some(left), Some(right)) => same_expr(plan, *left, *right),
1852 _ => false,
1853 }
1854 && lists(*left_args, *right_args)
1855 }
1856 (
1857 Expr::Case { arms: left_arms, otherwise: left_otherwise },
1858 Expr::Case { arms: right_arms, otherwise: right_otherwise },
1859 ) => {
1860 let left_arms = plan.arm_list(*left_arms);
1861 let right_arms = plan.arm_list(*right_arms);
1862 left_arms.len() == right_arms.len()
1863 && left_arms.iter().zip(right_arms).all(|(left, right)| {
1864 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
1865 })
1866 && match (left_otherwise, right_otherwise) {
1867 (None, None) => true,
1868 (Some(left), Some(right)) => same_expr(plan, *left, *right),
1869 _ => false,
1870 }
1871 }
1872 _ => false,
1873 }
1874}