1use rudb_catalog::{Catalog, Entry, QualifiedName, same_name};
16use rudb_common::{Error, Field, LogicalType, Result, 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())
37}
38
39pub fn bind_with(ast: &Ast, catalog: &Catalog, parameters: &Parameters) -> Result<Plan> {
45 let query = match ast.statements.as_slice() {
46 [ast::Statement::Query(query)] => *query,
47 [] => return Err(Error::binder("no statement to bind")),
48 [_] => return Err(Error::not_implemented("a statement that is not a query")),
51 _ => return Err(Error::not_implemented("a script of more than one statement")),
52 };
53 let mut binder = Binder::with(catalog, parameters);
54 let (root, _) = binder.bind_query(ast, query)?;
55 let mut plan = binder.into_plan();
56 plan.set_root(root);
57 plan.validate()?;
58 Ok(plan)
59}
60
61pub fn bind_sql(query: &str, catalog: &Catalog) -> Result<Plan> {
67 let ast = parse_ast(query)?;
68 bind(&ast, catalog)
69}
70
71#[derive(Debug)]
73pub(crate) struct Aggregation {
74 pub(crate) index: u32,
76 pub(crate) groups: Vec<ExprRef>,
78 pub(crate) aggregates: Vec<ExprRef>,
80}
81
82#[derive(Debug)]
84pub(crate) struct Binder<'a> {
85 catalog: &'a Catalog,
86 pub(crate) parameters: &'a Parameters,
88 plan: Plan,
89 next_index: u32,
90 pub(crate) aggregation: Option<Aggregation>,
92 pub(crate) in_aggregate: bool,
94 pub(crate) clause: &'static str,
96 expanding: Vec<String>,
98}
99
100impl<'a> Binder<'a> {
101 pub(crate) fn with(catalog: &'a Catalog, parameters: &'a Parameters) -> Self {
102 Self {
103 catalog,
104 parameters,
105 plan: Plan::new(),
106 next_index: 0,
107 aggregation: None,
108 in_aggregate: false,
109 clause: "SELECT clause",
110 expanding: Vec::new(),
111 }
112 }
113
114 pub(crate) fn plan(&self) -> &Plan {
115 &self.plan
116 }
117
118 pub(crate) fn plan_mut(&mut self) -> &mut Plan {
119 &mut self.plan
120 }
121
122 pub(crate) fn into_plan(self) -> Plan {
123 self.plan
124 }
125
126 pub(crate) fn fresh_index(&mut self) -> u32 {
128 let index = self.next_index;
129 self.next_index += 1;
130 index
131 }
132
133 fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
135 let binding = ColumnBinding::new(index, position as u32);
136 self.plan.add_expr(Expr::Column(binding), ty)
137 }
138
139 pub(crate) fn bind_query(
142 &mut self,
143 ast: &Ast,
144 query: ast::QueryRef,
145 ) -> Result<(NodeRef, Scope)> {
146 let written = ast.query(query);
147 match written.body {
148 ast::QueryBody::Select(select) => self.bind_select(ast, select, &written),
149 ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
150 if by_name {
151 return Err(Error::not_implemented("UNION BY NAME"));
152 }
153 self.bind_set_op(ast, &written, op, quantifier, left, right)
154 }
155 ast::QueryBody::Values(rows) => self.bind_values(ast, &written, rows),
156 ast::QueryBody::Describe(inner) => self.bind_describe(ast, &written, inner),
157 }
158 }
159
160 fn bind_describe(
176 &mut self,
177 ast: &Ast,
178 query: &ast::Query,
179 inner: ast::QueryRef,
180 ) -> Result<(NodeRef, Scope)> {
181 let (_, described) = self.bind_query(ast, inner)?;
182 let fields: Vec<Field> = ["column_name", "column_type", "null", "key", "default", "extra"]
183 .iter()
184 .map(|name| Field::new(*name, LogicalType::Varchar))
185 .collect();
186 let mut slices = Vec::with_capacity(described.columns.len());
187 for column in described.columns.clone() {
188 let written = [
191 column.name.clone(),
192 column.ty.to_string(),
193 if column.not_null { "NO" } else { "YES" }.to_owned(),
194 ];
195 let mut items: Vec<ExprRef> = written
196 .into_iter()
197 .map(|text| self.plan.add_constant(Value::Varchar(text)))
198 .collect();
199 for _ in 0..3 {
200 let empty = self.plan.add_constant(Value::Null);
201 items.push(self.cast_to(empty, &LogicalType::Varchar));
202 }
203 slices.push(self.plan.add_expr_list(&items));
204 }
205 let rows = self.plan.add_rows(&slices);
206 let columns = self.plan.add_fields(&fields);
207 let index = self.fresh_index();
208 let mut node = self.plan.add_node(Node::Values { index, columns, rows });
209 let mut scope = Scope::empty();
210 for (at, field) in fields.iter().enumerate() {
211 scope.push(Visible {
212 table: String::new(),
213 name: field.name.clone(),
214 binding: ColumnBinding::new(index, at as u32),
215 ty: field.ty.clone(),
216 not_null: false,
217 });
218 }
219 let keys = self.sort_keys(ast, query, &scope, &[])?;
220 if !keys.is_empty() {
221 let keys = self.plan.add_sort_keys(&keys);
222 node = self.plan.add_node(Node::Sort { input: node, keys });
223 }
224 node = self.apply_limit(ast, query, node)?;
225 Ok((node, scope))
226 }
227
228 fn passes_through(&self, expr: ExprRef, input: &Scope) -> bool {
234 let Expr::Column(binding) = *self.plan.expr(expr) else { return false };
235 input.columns.iter().any(|column| column.binding == binding && column.not_null)
236 }
237
238 fn bind_values(
245 &mut self,
246 ast: &Ast,
247 query: &ast::Query,
248 rows: ast::Slice,
249 ) -> Result<(NodeRef, Scope)> {
250 let written = ast.rows(rows).to_vec();
251 let Some(first) = written.first() else {
252 return Err(Error::binder("VALUES needs at least one row"));
253 };
254 let width = first.len as usize;
255 for (at, row) in written.iter().enumerate() {
256 if row.len as usize != width {
257 return Err(Error::binder(format!(
258 "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
259 at + 1,
260 row.len
261 )));
262 }
263 }
264 let empty = Scope::empty();
266 let previous = std::mem::replace(&mut self.clause, "VALUES clause");
267 let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
268 for row in &written {
269 let mut items = Vec::with_capacity(width);
270 for &expr in ast.expr_list(*row) {
271 items.push(self.bind_expr(ast, expr, &empty)?);
272 }
273 bound.push(items);
274 }
275 self.clause = previous;
276 let mut types = Vec::with_capacity(width);
277 for at in 0..width {
278 let mut ty = self.plan.expr_type(bound[0][at]).clone();
279 for row in &bound[1..] {
280 let other = self.plan.expr_type(row[at]).clone();
281 ty = ty.promote(&other).ok_or_else(|| {
282 Error::binder(format!(
283 "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
284 at + 1
285 ))
286 })?;
287 }
288 types.push(ty);
289 }
290 let mut slices = Vec::with_capacity(bound.len());
291 for row in &bound {
292 let items: Vec<ExprRef> =
293 row.iter().zip(&types).map(|(&expr, ty)| self.cast_to(expr, ty)).collect();
294 slices.push(self.plan.add_expr_list(&items));
295 }
296 let rows = self.plan.add_rows(&slices);
297 let fields: Vec<Field> = types
298 .iter()
299 .enumerate()
300 .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
301 .collect();
302 let columns = self.plan.add_fields(&fields);
303 let index = self.fresh_index();
304 let mut node = self.plan.add_node(Node::Values { index, columns, rows });
305 let mut scope = Scope::empty();
306 for (at, field) in fields.iter().enumerate() {
307 scope.push(Visible {
308 table: String::new(),
309 name: field.name.clone(),
310 binding: ColumnBinding::new(index, at as u32),
311 ty: field.ty.clone(),
312 not_null: false,
313 });
314 }
315 let keys = self.sort_keys(ast, query, &scope, &[])?;
316 if !keys.is_empty() {
317 let keys = self.plan.add_sort_keys(&keys);
318 node = self.plan.add_node(Node::Sort { input: node, keys });
319 }
320 node = self.apply_limit(ast, query, node)?;
321 Ok((node, scope))
322 }
323
324 fn bind_set_op(
325 &mut self,
326 ast: &Ast,
327 query: &ast::Query,
328 op: SetOp,
329 quantifier: Quantifier,
330 left: ast::QueryRef,
331 right: ast::QueryRef,
332 ) -> Result<(NodeRef, Scope)> {
333 let (left_node, left_scope) = self.bind_query(ast, left)?;
334 let (right_node, right_scope) = self.bind_query(ast, right)?;
335 if left_scope.len() != right_scope.len() {
336 return Err(Error::binder(format!(
337 "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
338 left_scope.len(),
339 right_scope.len()
340 )));
341 }
342 let mut types = Vec::with_capacity(left_scope.len());
344 for (left, right) in left_scope.columns.iter().zip(&right_scope.columns) {
345 let common = left.ty.promote(&right.ty).ok_or_else(|| {
346 Error::binder(format!(
347 "Cannot combine a column of type {} with a column of type {} in a set operation",
348 left.ty, right.ty
349 ))
350 })?;
351 types.push(common);
352 }
353 let left_node = self.conform(left_node, &left_scope, &types);
354 let right_node = self.conform(right_node, &right_scope, &types);
355 let index = self.fresh_index();
356 let kind = match op {
357 SetOp::Union => SetOpKind::Union,
358 SetOp::Except => SetOpKind::Except,
359 SetOp::Intersect => SetOpKind::Intersect,
360 };
361 let all = quantifier == Quantifier::All;
364 let mut node = self.plan.add_node(Node::SetOp {
365 left: left_node,
366 right: right_node,
367 kind,
368 all,
369 index,
370 });
371 let mut scope = Scope::empty();
372 for (at, (column, ty)) in left_scope.columns.iter().zip(&types).enumerate() {
373 scope.push(Visible {
374 table: String::new(),
375 name: column.name.clone(),
376 binding: ColumnBinding::new(index, at as u32),
377 ty: ty.clone(),
378 not_null: false,
381 });
382 }
383 let keys = self.sort_keys(ast, query, &scope, &[])?;
387 if !keys.is_empty() {
388 let keys = self.plan.add_sort_keys(&keys);
389 node = self.plan.add_node(Node::Sort { input: node, keys });
390 }
391 node = self.apply_limit(ast, query, node)?;
392 Ok((node, scope))
393 }
394
395 fn conform(&mut self, node: NodeRef, scope: &Scope, types: &[LogicalType]) -> NodeRef {
397 if scope.columns.iter().zip(types).all(|(column, ty)| &column.ty == ty) {
398 return node;
399 }
400 let index = self.fresh_index();
401 let mut exprs = Vec::with_capacity(types.len());
402 let mut names = Vec::with_capacity(types.len());
403 for (column, ty) in scope.columns.iter().zip(types) {
404 let expr = self.plan.add_expr(Expr::Column(column.binding), column.ty.clone());
405 exprs.push(self.cast_to(expr, ty));
406 names.push(self.plan.intern(&column.name));
407 }
408 let exprs = self.plan.add_expr_list(&exprs);
409 let names = self.plan.add_name_list(&names);
410 self.plan.add_node(Node::Project { input: node, index, exprs, names })
411 }
412
413 fn bind_select(
416 &mut self,
417 ast: &Ast,
418 select: ast::SelectRef,
419 query: &ast::Query,
420 ) -> Result<(NodeRef, Scope)> {
421 let written = ast.select(select);
422 let (mut node, input) = self.bind_from(ast, written.from)?;
423
424 if written.filter != NONE {
425 self.clause = "WHERE clause";
426 let predicate = self.bind_expr(ast, written.filter, &input)?;
427 let predicate = self.as_boolean(predicate, "WHERE")?;
428 node = self.plan.add_node(Node::Filter { input: node, predicate });
429 }
430
431 let targets = ast.target_list(written.targets).to_vec();
432 if targets.is_empty() {
433 return Err(Error::binder("a SELECT needs at least one expression to select"));
434 }
435
436 let group_items = self.group_items(ast, &written, &targets)?;
437 let aggregating = !group_items.is_empty()
438 || written.having != NONE
439 || targets.iter().any(|target| has_aggregate(ast, target.expr));
440 if aggregating {
441 self.clause = "GROUP BY clause";
442 let mut groups = Vec::with_capacity(group_items.len());
443 for item in &group_items {
444 groups.push(self.bind_expr(ast, *item, &input)?);
445 }
446 let index = self.fresh_index();
447 self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
448 }
449
450 self.clause = "SELECT clause";
451 let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input)?;
452 let visible = exprs.len();
453
454 let mut having = None;
455 if written.having != NONE {
456 self.clause = "HAVING clause";
457 let predicate = self.bind_expr(ast, written.having, &input)?;
458 let predicate = self.over_aggregate(predicate, &input)?;
459 having = Some(self.as_boolean(predicate, "HAVING")?);
460 }
461
462 let project = self.fresh_index();
465 let mut output = Scope::empty();
466 for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
467 output.push(Visible {
468 table: String::new(),
469 name: name.clone(),
470 binding: ColumnBinding::new(project, at as u32),
471 ty: self.plan.expr_type(*expr).clone(),
472 not_null: self.passes_through(*expr, &input),
473 });
474 }
475
476 self.clause = "ORDER BY clause";
477 let mut extra = Vec::new();
478 let keys = self.select_sort_keys(
479 ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra,
480 )?;
481 if !extra.is_empty() && written.distinct != Distinct::No {
482 return Err(Error::binder(
483 "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
484 ));
485 }
486 let on = self.distinct_on(ast, written.distinct, &output)?;
487
488 if let Some(aggregation) = self.aggregation.take() {
489 let index = aggregation.index;
490 let groups = self.plan.add_expr_list(&aggregation.groups);
491 let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
492 node = self.plan.add_node(Node::Aggregate { input: node, index, groups, aggregates });
493 }
494 if let Some(predicate) = having {
495 node = self.plan.add_node(Node::Filter { input: node, predicate });
496 }
497
498 let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
499 let exprs_slice = self.plan.add_expr_list(&exprs);
500 let names_slice = self.plan.add_name_list(&interned);
501 node = self.plan.add_node(Node::Project {
502 input: node,
503 index: project,
504 exprs: exprs_slice,
505 names: names_slice,
506 });
507
508 if written.distinct != Distinct::No {
509 let on = self.plan.add_expr_list(&on);
510 node = self.plan.add_node(Node::Distinct { input: node, on });
511 }
512 if !keys.is_empty() {
513 let keys = self.plan.add_sort_keys(&keys);
514 node = self.plan.add_node(Node::Sort { input: node, keys });
515 }
516 node = self.apply_limit(ast, query, node)?;
517
518 if extra.is_empty() {
519 output.columns.truncate(visible);
520 return Ok((node, output));
521 }
522 let index = self.fresh_index();
525 let mut kept = Vec::with_capacity(visible);
526 let mut kept_names = Vec::with_capacity(visible);
527 let mut scope = Scope::empty();
528 for (at, name) in names.iter().enumerate().take(visible) {
529 let ty = output.columns[at].ty.clone();
530 kept.push(self.column(project, at, ty.clone()));
531 kept_names.push(self.plan.intern(name));
532 scope.push(Visible {
533 table: String::new(),
534 name: name.clone(),
535 binding: ColumnBinding::new(index, at as u32),
536 ty,
537 not_null: output.columns[at].not_null,
538 });
539 }
540 let exprs = self.plan.add_expr_list(&kept);
541 let names = self.plan.add_name_list(&kept_names);
542 node = self.plan.add_node(Node::Project { input: node, index, exprs, names });
543 Ok((node, scope))
544 }
545
546 fn bind_targets(
548 &mut self,
549 ast: &Ast,
550 targets: &[ast::Target],
551 input: &Scope,
552 ) -> Result<(Vec<ExprRef>, Vec<String>)> {
553 let mut exprs = Vec::with_capacity(targets.len());
554 let mut names = Vec::with_capacity(targets.len());
555 for target in targets {
556 if let ast::Expr::Star { qualifier, replacements } = ast.expr(target.expr) {
557 let table = ast.name(qualifier).last().map(str::to_string);
558 let expanded: Vec<Visible> =
559 input.star(table.as_deref())?.into_iter().cloned().collect();
560 let replacements = ast.target_list(replacements).to_vec();
561 let mut used = vec![false; replacements.len()];
562 for column in expanded {
563 let found = replacements.iter().zip(&mut used).find(|(replacement, _)| {
564 same_name(ast.string(replacement.alias), &column.name)
565 });
566 let (expr, name) = match found {
571 Some((replacement, used)) => {
572 *used = true;
573 let expr = self.bind_expr(ast, replacement.expr, input)?;
574 (expr, ast.string(replacement.alias).to_string())
575 }
576 None => (
577 self.plan.add_expr(Expr::Column(column.binding), column.ty),
578 column.name,
579 ),
580 };
581 exprs.push(self.over_aggregate(expr, input)?);
582 names.push(name);
583 }
584 if let Some((replacement, _)) =
588 replacements.iter().zip(&used).find(|(_, used)| !**used)
589 {
590 return Err(missing_replacement(ast.string(replacement.alias), input));
591 }
592 continue;
593 }
594 let expr = self.bind_expr(ast, target.expr, input)?;
595 exprs.push(self.over_aggregate(expr, input)?);
596 names.push(if target.alias == NONE {
597 self.output_name(ast, target.expr, input)
598 } else {
599 ast.string(target.alias).to_string()
600 });
601 }
602 Ok((exprs, names))
603 }
604
605 fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
611 if let ast::Expr::Column { name } = ast.expr(target) {
612 let parts: Vec<&str> = ast.name(name).collect();
613 if let Ok(found) = input.resolve(&parts) {
614 return found.name.clone();
615 }
616 }
617 describe(ast, target)
618 }
619
620 fn group_items(
622 &self,
623 ast: &Ast,
624 select: &ast::Select,
625 targets: &[ast::Target],
626 ) -> Result<Vec<ast::ExprRef>> {
627 if select.group_by_all {
628 return Ok(targets
631 .iter()
632 .filter(|target| !has_aggregate(ast, target.expr))
633 .map(|target| target.expr)
634 .collect());
635 }
636 let mut items = Vec::new();
637 for &item in ast.expr_list(select.group_by) {
638 items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
639 }
640 Ok(items)
641 }
642
643 fn output_reference(
645 &self,
646 ast: &Ast,
647 item: ast::ExprRef,
648 targets: &[ast::Target],
649 clause: &str,
650 ) -> Result<Option<ast::ExprRef>> {
651 match ast.expr(item) {
652 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
653 let written = ast.string(text);
654 let position: usize = written.parse().map_err(|_| {
655 Error::binder(format!("{clause} term {written} is not a column"))
656 })?;
657 if position == 0 || position > targets.len() {
658 return Err(Error::binder(format!(
659 "{clause} term out of range - should be between 1 and {}",
660 targets.len()
661 )));
662 }
663 Ok(Some(targets[position - 1].expr))
664 }
665 ast::Expr::Column { name } => {
666 let parts: Vec<&str> = ast.name(name).collect();
667 let [written] = parts.as_slice() else { return Ok(None) };
668 let mut found = None;
669 for target in targets {
670 if target.alias != NONE && same_name(ast.string(target.alias), written) {
671 if found.is_some() {
672 return Ok(None);
673 }
674 found = Some(target.expr);
675 }
676 }
677 Ok(found)
678 }
679 _ => Ok(None),
680 }
681 }
682
683 #[allow(clippy::too_many_arguments)]
687 fn select_sort_keys(
688 &mut self,
689 ast: &Ast,
690 query: &ast::Query,
691 input: &Scope,
692 output: &Scope,
693 project: u32,
694 exprs: &mut Vec<ExprRef>,
695 names: &mut Vec<String>,
696 extra: &mut Vec<usize>,
697 ) -> Result<Vec<SortKey>> {
698 if query.order_by_all {
699 return Ok(self.every_column(output));
700 }
701 let items = ast.order_list(query.order_by).to_vec();
702 let mut keys = Vec::with_capacity(items.len());
703 for item in items {
704 let position = match self.output_position(ast, item.expr, output)? {
705 Some(position) => position,
706 None => {
707 let bound = self.bind_expr(ast, item.expr, input)?;
708 let bound = self.over_aggregate(bound, input)?;
709 match exprs.iter().position(|&held| self.same_expr(held, bound)) {
710 Some(position) => position,
711 None => {
712 exprs.push(bound);
713 names.push(describe(ast, item.expr));
714 extra.push(exprs.len() - 1);
715 exprs.len() - 1
716 }
717 }
718 }
719 };
720 let ty = self.plan.expr_type(exprs[position]).clone();
721 let expr = self.column(project, position, ty);
722 keys.push(sort_key(expr, item));
723 }
724 Ok(keys)
725 }
726
727 fn sort_keys(
729 &mut self,
730 ast: &Ast,
731 query: &ast::Query,
732 output: &Scope,
733 targets: &[ast::Target],
734 ) -> Result<Vec<SortKey>> {
735 if query.order_by_all {
736 return Ok(self.every_column(output));
737 }
738 let items = ast.order_list(query.order_by).to_vec();
739 let mut keys = Vec::with_capacity(items.len());
740 for item in items {
741 let expr = match self.output_position(ast, item.expr, output)? {
742 Some(position) => {
743 let column = &output.columns[position];
744 let (binding, ty) = (column.binding, column.ty.clone());
745 self.plan.add_expr(Expr::Column(binding), ty)
746 }
747 None => {
748 let _ = targets;
749 self.bind_expr(ast, item.expr, output)?
750 }
751 };
752 keys.push(sort_key(expr, item));
753 }
754 Ok(keys)
755 }
756
757 fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
758 let columns: Vec<(ColumnBinding, LogicalType)> =
759 output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
760 columns
761 .into_iter()
762 .map(|(binding, ty)| {
763 let expr = self.plan.add_expr(Expr::Column(binding), ty);
764 SortKey { expr, descending: false, nulls_first: false }
765 })
766 .collect()
767 }
768
769 fn output_position(
771 &self,
772 ast: &Ast,
773 item: ast::ExprRef,
774 output: &Scope,
775 ) -> Result<Option<usize>> {
776 match ast.expr(item) {
777 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
778 let written = ast.string(text);
779 if written.contains(['.', 'e', 'E']) {
780 return Ok(None);
781 }
782 let position: usize = written.parse().map_err(|_| {
783 Error::binder(format!("ORDER BY term {written} is not a column"))
784 })?;
785 if position == 0 || position > output.len() {
786 return Err(Error::binder(format!(
787 "ORDER BY term out of range - should be between 1 and {}",
788 output.len()
789 )));
790 }
791 Ok(Some(position - 1))
792 }
793 ast::Expr::Column { name } => {
794 let parts: Vec<&str> = ast.name(name).collect();
795 let [written] = parts.as_slice() else { return Ok(None) };
796 Ok(output.position_of(None, written))
797 }
798 _ => Ok(None),
799 }
800 }
801
802 fn distinct_on(
804 &mut self,
805 ast: &Ast,
806 distinct: Distinct,
807 output: &Scope,
808 ) -> Result<Vec<ExprRef>> {
809 let Distinct::On(items) = distinct else {
810 return Ok(Vec::new());
811 };
812 let items = ast.expr_list(items).to_vec();
813 let mut on = Vec::with_capacity(items.len());
814 for item in items {
815 let Some(position) = self.output_position(ast, item, output)? else {
816 return Err(Error::not_implemented(
817 "DISTINCT ON an expression that is not in the select list",
818 ));
819 };
820 let column = &output.columns[position];
821 let (binding, ty) = (column.binding, column.ty.clone());
822 on.push(self.plan.add_expr(Expr::Column(binding), ty));
823 }
824 Ok(on)
825 }
826
827 fn apply_limit(&mut self, ast: &Ast, query: &ast::Query, input: NodeRef) -> Result<NodeRef> {
828 if query.limit_percent {
829 return Err(Error::not_implemented("LIMIT with a percentage"));
830 }
831 let count = self.constant_count(ast, query.limit, "LIMIT")?;
832 let offset = self.constant_count(ast, query.offset, "OFFSET")?.unwrap_or(0);
833 if count.is_none() && offset == 0 {
834 return Ok(input);
835 }
836 Ok(self.plan.add_node(Node::Limit { input, count, offset }))
837 }
838
839 fn constant_count(
841 &mut self,
842 ast: &Ast,
843 written: ast::ExprRef,
844 clause: &str,
845 ) -> Result<Option<u64>> {
846 if written == NONE {
847 return Ok(None);
848 }
849 self.clause = "LIMIT clause";
850 let scope = Scope::empty();
851 let bound = self.bind_expr(ast, written, &scope)?;
852 let Expr::Constant(value) = *self.plan.expr(bound) else {
853 return Err(Error::not_implemented(format!("a {clause} that is not a constant")));
854 };
855 let count = match self.plan.value(value) {
856 Value::Null => return Ok(None),
857 Value::TinyInt(count) => i128::from(*count),
858 Value::SmallInt(count) => i128::from(*count),
859 Value::Integer(count) => i128::from(*count),
860 Value::BigInt(count) => i128::from(*count),
861 Value::HugeInt(count) => *count,
862 other => {
863 return Err(Error::binder(format!(
864 "{clause} takes a whole number of rows, not a value of type {}",
865 other.logical_type()
866 )));
867 }
868 };
869 u64::try_from(count)
870 .map(Some)
871 .map_err(|_| Error::binder(format!("{clause} must not be negative")))
872 }
873
874 fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
877 let sources = ast.source_list(from).to_vec();
878 let Some((first, rest)) = sources.split_first() else {
879 return Ok((self.plan.add_node(Node::Dummy), Scope::empty()));
882 };
883 let (mut node, mut scope) = self.bind_source(ast, *first)?;
884 for source in rest {
885 let (right, right_scope) = self.bind_source(ast, *source)?;
886 node = self.plan.add_node(Node::CrossProduct { left: node, right });
887 scope = scope.concat(right_scope);
888 }
889 Ok((node, scope))
890 }
891
892 fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
893 match ast.source(source) {
894 ast::Source::Table { name, alias, columns } => {
895 self.bind_table(ast, name, alias, columns)
896 }
897 ast::Source::Function { name, args, alias, columns } => {
898 self.bind_table_function(ast, name, args, alias, columns)
899 }
900 ast::Source::Subquery { query, alias, columns } => {
901 let (node, mut scope) = self.bind_query(ast, query)?;
902 let label = if alias == NONE {
903 "unnamed_subquery".to_string()
904 } else {
905 ast.string(alias).to_string()
906 };
907 scope.relabel(&label);
908 if !columns.is_empty() {
909 let names: Vec<&str> = ast.name(columns).collect();
910 scope.rename(&names, &label)?;
911 }
912 Ok((node, scope))
913 }
914 ast::Source::Values { rows, alias, columns } => {
915 let bare = ast::Query::bare(ast::QueryBody::Values(rows));
916 let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
917 let label =
918 if alias == NONE { String::new() } else { ast.string(alias).to_string() };
919 scope.relabel(&label);
920 if !columns.is_empty() {
921 let names: Vec<&str> = ast.name(columns).collect();
922 scope.rename(&names, &label)?;
923 }
924 Ok((node, scope))
925 }
926 ast::Source::Join { left, right, kind, natural, on, using } => {
927 self.bind_join(ast, left, right, kind, natural, on, using)
928 }
929 }
930 }
931
932 fn bind_table(
933 &mut self,
934 ast: &Ast,
935 name: ast::Slice,
936 alias: ast::StrRef,
937 columns: ast::Slice,
938 ) -> Result<(NodeRef, Scope)> {
939 let parts: Vec<&str> = ast.name(name).collect();
940 let catalog = self.catalog;
941 let resolved = match catalog.resolve(&parts) {
944 Ok(resolved) => resolved,
945 Err(missing) => {
946 return self.bind_replacement_scan(ast, &parts, alias, columns, missing);
947 }
948 };
949 if catalog.entry(&resolved)? == Entry::View {
950 return self.bind_view(ast, &resolved, alias, columns);
951 }
952 let table = catalog.table(&resolved)?;
953 let fields: Vec<Field> = table.columns().to_vec();
954 let label =
955 if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
956 let index = self.fresh_index();
957 let mut scope = Scope::empty();
958 for (at, field) in fields.iter().enumerate() {
959 scope.push(Visible {
960 table: label.clone(),
961 name: field.name.clone(),
962 binding: ColumnBinding::new(index, at as u32),
963 ty: field.ty.clone(),
964 not_null: field.not_null,
965 });
966 }
967 if !columns.is_empty() {
968 let names: Vec<&str> = ast.name(columns).collect();
969 scope.rename(&names, &label)?;
970 }
971 let catalog_name = self.plan.intern(&resolved.catalog);
972 let schema = self.plan.intern(&resolved.schema);
973 let table_name = self.plan.intern(&resolved.table);
974 let alias = self.plan.intern(&label);
975 let columns = self.plan.add_fields(&fields);
976 let node = self.plan.add_node(Node::Get {
977 catalog: catalog_name,
978 schema,
979 table: table_name,
980 alias,
981 index,
982 columns,
983 });
984 Ok((node, scope))
985 }
986
987 fn bind_view(
999 &mut self,
1000 ast: &Ast,
1001 name: &QualifiedName,
1002 alias: ast::StrRef,
1003 columns: ast::Slice,
1004 ) -> Result<(NodeRef, Scope)> {
1005 let view = self.catalog.view(name)?;
1006 let full = name.to_string();
1007 if self.expanding.contains(&full) {
1008 return Err(Error::binder(format!(
1012 "infinite recursion detected: attempting to recursively bind view \"\"{}\"\"",
1013 name.table
1014 )));
1015 }
1016 let body = parse_ast(view.sql())?;
1017 let query = match body.statements.as_slice() {
1018 [ast::Statement::Query(query)] => *query,
1019 _ => return Err(Error::binder(format!("view \"{}\" is not a query", name.table))),
1022 };
1023 self.expanding.push(full);
1024 let bound = self.bind_query(&body, query);
1025 self.expanding.pop();
1026 let (node, mut scope) = bound?;
1027
1028 let aliases: Vec<&str> = view.aliases().iter().map(String::as_str).collect();
1029 if !aliases.is_empty() {
1030 scope.rename(&aliases, "unnamed_subquery")?;
1031 }
1032 let label = if alias == NONE { name.table.clone() } else { ast.string(alias).to_string() };
1033 scope.relabel(&label);
1034 if !columns.is_empty() {
1035 let names: Vec<&str> = ast.name(columns).collect();
1036 scope.rename(&names, &label)?;
1037 }
1038 Ok((node, scope))
1039 }
1040
1041 fn bind_table_function(
1049 &mut self,
1050 ast: &Ast,
1051 name: ast::Slice,
1052 args: ast::Slice,
1053 alias: ast::StrRef,
1054 columns: ast::Slice,
1055 ) -> Result<(NodeRef, Scope)> {
1056 let parts: Vec<&str> = ast.name(name).collect();
1057 let function_name = *parts.last().unwrap_or(&"");
1061 if let Some(schema) = parts.iter().rev().nth(1) {
1062 if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
1063 return Err(Error::catalog(format!(
1064 "Table Function with name {} does not exist!",
1065 parts.join(".")
1066 )));
1067 }
1068 }
1069 let Some(called) = TableFunction::lookup(function_name) else {
1073 return Err(Error::catalog(format!(
1074 "Table Function with name {function_name} does not exist!"
1075 )));
1076 };
1077 let written = ast.target_list(args).to_vec();
1078 let empty = Scope::empty();
1079 let previous = std::mem::replace(&mut self.clause, "table function arguments");
1080 let mut bound = Vec::new();
1081 let mut written_options = Vec::new();
1082 for argument in written {
1083 let expr = self.bind_expr(ast, argument.expr, &empty)?;
1084 if argument.alias == NONE {
1085 bound.push(expr);
1086 } else {
1087 let name = ast.string(argument.alias).to_string();
1088 let (parameter, value) = self.named_argument(called, &name, expr)?;
1089 written_options.push((parameter, value, expr));
1090 }
1091 }
1092 self.clause = previous;
1093 let options = Options::of(&written_options)?;
1094
1095 let given: Vec<LogicalType> =
1098 bound.iter().map(|&expr| self.plan.expr_type(expr).clone()).collect();
1099 let resolved = resolve_table(function_name, &given)?;
1100 let mut cast: Vec<ExprRef> = bound
1101 .iter()
1102 .zip(&resolved.arguments)
1103 .map(|(&expr, ty)| self.cast_to(expr, ty))
1104 .collect();
1105
1106 let fields = match resolved.columns {
1107 Columns::Fixed(fields) => fields,
1108 columns => {
1109 let paths = self.file_paths(cast[0], resolved.function.name())?;
1114 let first = paths.first().map_or("", String::as_str);
1115 let mut fields = match columns {
1116 Columns::Csv => csv_fields(&paths, options.given)?,
1119 _ => parquet_fields(first)?,
1120 };
1121 if options.all_varchar {
1122 for field in &mut fields {
1127 field.ty = LogicalType::Varchar;
1128 }
1129 }
1130 if options.binary_as_string {
1131 for field in &mut fields {
1136 if field.ty == LogicalType::Blob {
1137 field.ty = LogicalType::Varchar;
1138 }
1139 }
1140 }
1141 if options.file_row_number {
1142 if fields.iter().any(|field| field.name == FILE_ROW_NUMBER) {
1148 return Err(Error::binder(format!(
1149 "Duplicate column name \"{FILE_ROW_NUMBER}\": the file already has a \
1150 column of that name, so file_row_number cannot add one"
1151 )));
1152 }
1153 fields.push(Field::required(FILE_ROW_NUMBER.to_string(), LogicalType::BigInt));
1154 }
1155 cast = paths.iter().map(|path| self.path_constant(path)).collect();
1156 fields
1157 }
1158 };
1159 let label = if alias == NONE {
1160 resolved.function.name().to_string()
1161 } else {
1162 ast.string(alias).to_string()
1163 };
1164 let names: Vec<&str> = ast.name(columns).collect();
1165 self.table_function_source(
1166 resolved.function,
1167 &cast,
1168 &written_options,
1169 fields,
1170 &label,
1171 &names,
1172 )
1173 }
1174
1175 fn named_argument(
1189 &mut self,
1190 function: TableFunction,
1191 name: &str,
1192 expr: ExprRef,
1193 ) -> Result<(&'static str, Value)> {
1194 let known = function
1195 .parameters()
1196 .iter()
1197 .find(|(parameter, _)| parameter.eq_ignore_ascii_case(name));
1198 let Some((parameter, wanted)) = known else {
1199 let candidates: Vec<String> = function
1200 .parameters()
1201 .iter()
1202 .map(|(parameter, ty)| format!(" {parameter} {ty}"))
1203 .collect();
1204 return Err(Error::binder(format!(
1205 "Invalid named parameter \"{name}\" for function {}\nCandidates:\n{}\n",
1206 function.name(),
1207 candidates.join("\n")
1208 )));
1209 };
1210 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1211 return Err(Error::not_implemented(format!(
1212 "the named parameter {parameter} with a value that is not a constant"
1213 )));
1214 };
1215 let value = self.plan.value(reference).clone();
1216 if value == Value::Null {
1217 return Err(Error::binder(null_parameter(function, parameter)));
1218 }
1219 let given = self.plan.expr_type(expr).clone();
1220 if given != *wanted {
1221 return Err(Error::not_implemented(format!(
1222 "the named parameter {parameter} given a {given} where a {wanted} was wanted"
1223 )));
1224 }
1225 Ok((parameter, value))
1226 }
1227
1228 fn bind_replacement_scan(
1239 &mut self,
1240 ast: &Ast,
1241 parts: &[&str],
1242 alias: ast::StrRef,
1243 columns: ast::Slice,
1244 missing: Error,
1245 ) -> Result<(NodeRef, Scope)> {
1246 let [path] = parts else { return Err(missing) };
1247 let path = *path;
1248 let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
1249 let Some(function) = Self::reader_for(extension) else {
1250 if is_file(path) {
1251 return Err(Error::binder(format!(
1256 "No extension found that is capable of reading the file \"{path}\"\n* If this \
1257 file is a supported file format you can explicitly use the reader functions, \
1258 such as read_csv, read_json or read_parquet"
1259 )));
1260 }
1261 return Err(missing);
1262 };
1263 let paths = files(path)?;
1268 let first = paths.first().map_or("", String::as_str);
1269 let fields = match function {
1270 TableFunction::ReadParquet => parquet_fields(first)?,
1271 _ => csv_fields(&paths, Given::default())?,
1272 };
1273 let label = if alias == NONE {
1279 if is_pattern(path) {
1280 path.to_string()
1281 } else {
1282 let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
1283 file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
1284 }
1285 } else {
1286 ast.string(alias).to_string()
1287 };
1288 let arguments: Vec<ExprRef> = paths.iter().map(|path| self.path_constant(path)).collect();
1289 let names: Vec<&str> = ast.name(columns).collect();
1290 self.table_function_source(function, &arguments, &[], fields, &label, &names)
1291 }
1292
1293 fn path_constant(&mut self, path: &str) -> ExprRef {
1295 let value = self.plan.add_value(Value::Varchar(path.to_string()));
1296 self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar)
1297 }
1298
1299 fn reader_for(extension: &str) -> Option<TableFunction> {
1306 if extension.eq_ignore_ascii_case("parquet") {
1307 return Some(TableFunction::ReadParquet);
1308 }
1309 if extension.eq_ignore_ascii_case("csv") || extension.eq_ignore_ascii_case("tsv") {
1310 return Some(TableFunction::ReadCsv);
1311 }
1312 None
1313 }
1314
1315 fn table_function_source(
1320 &mut self,
1321 function: TableFunction,
1322 args: &[ExprRef],
1323 written: &[(&'static str, Value, ExprRef)],
1324 fields: Vec<Field>,
1325 label: &str,
1326 names: &[&str],
1327 ) -> Result<(NodeRef, Scope)> {
1328 let index = self.fresh_index();
1329 let mut scope = Scope::empty();
1330 for (at, field) in fields.iter().enumerate() {
1331 scope.push(Visible {
1332 table: label.to_string(),
1333 name: field.name.clone(),
1334 binding: ColumnBinding::new(index, at as u32),
1335 ty: field.ty.clone(),
1336 not_null: false,
1339 });
1340 }
1341 if !names.is_empty() {
1342 scope.rename(names, label)?;
1343 }
1344 let function = self.plan.intern(function.name());
1345 let args = self.plan.add_expr_list(args);
1346 let named: Vec<u32> =
1347 written.iter().map(|(parameter, _, _)| self.plan.intern(parameter)).collect();
1348 let settings: Vec<ExprRef> = written.iter().map(|(_, _, expr)| *expr).collect();
1349 let options = self.plan.add_name_list(&named);
1350 let settings = self.plan.add_expr_list(&settings);
1351 let columns = self.plan.add_fields(&fields);
1352 let node = self.plan.add_node(Node::TableFunction {
1353 index,
1354 function,
1355 args,
1356 options,
1357 settings,
1358 columns,
1359 });
1360 Ok((node, scope))
1361 }
1362
1363 fn file_paths(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1370 let mut paths = Vec::new();
1371 for pattern in self.file_patterns(expr, name)? {
1372 paths.extend(files(&pattern)?);
1373 }
1374 Ok(paths)
1375 }
1376
1377 fn file_patterns(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1389 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1390 return Err(Error::not_implemented(
1391 "a table function file name that is not a constant",
1392 ));
1393 };
1394 match self.plan.value(reference) {
1395 Value::Varchar(path) => Ok(vec![path.clone()]),
1396 Value::Null => Err(Error::parser(format!("{name} cannot take NULL list as parameter"))),
1398 Value::List { values, .. } => values
1399 .iter()
1400 .map(|value| match value {
1401 Value::Varchar(path) => Ok(path.clone()),
1402 _ => Err(Error::parser(format!(
1403 "{name} reader cannot take NULL input as parameter"
1404 ))),
1405 })
1406 .collect(),
1407 other => {
1408 Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
1409 }
1410 }
1411 }
1412
1413 #[allow(clippy::too_many_arguments)]
1414 fn bind_join(
1415 &mut self,
1416 ast: &Ast,
1417 left: ast::SourceRef,
1418 right: ast::SourceRef,
1419 kind: ast::JoinKind,
1420 natural: bool,
1421 on: ast::ExprRef,
1422 using: ast::Slice,
1423 ) -> Result<(NodeRef, Scope)> {
1424 let (left_node, left_scope) = self.bind_source(ast, left)?;
1425 let (right_node, right_scope) = self.bind_source(ast, right)?;
1426 let split = left_scope.len();
1427 let mut scope = left_scope.concat(right_scope);
1428
1429 let merged: Vec<String> = if natural {
1432 let mut names = Vec::new();
1433 for (at, column) in scope.columns.iter().enumerate().take(split) {
1434 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
1435 && !names.iter().any(|held: &String| same_name(held, &column.name))
1436 {
1437 let _ = at;
1438 names.push(column.name.clone());
1439 }
1440 }
1441 names
1442 } else {
1443 ast.name(using).map(str::to_string).collect()
1444 };
1445
1446 let mut conditions = Vec::new();
1447 let mut dropped = Vec::new();
1448 for name in &merged {
1449 let left_at = scope.columns[..split]
1450 .iter()
1451 .position(|column| same_name(&column.name, name))
1452 .ok_or_else(|| {
1453 Error::binder(format!(
1454 "column \"{name}\" specified in USING clause does not exist in left table"
1455 ))
1456 })?;
1457 let right_at = scope.columns[split..]
1458 .iter()
1459 .position(|column| same_name(&column.name, name))
1460 .map(|at| at + split)
1461 .ok_or_else(|| {
1462 Error::binder(format!(
1463 "column \"{name}\" specified in USING clause does not exist in right table"
1464 ))
1465 })?;
1466 let left_column = &scope.columns[left_at];
1467 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
1468 let right_column = &scope.columns[right_at];
1469 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
1470 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
1471 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
1472 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
1473 dropped.push(right_at);
1474 }
1475 dropped.sort_unstable();
1478 for at in dropped.into_iter().rev() {
1479 scope.remove(at);
1480 }
1481
1482 if on != NONE {
1483 if !merged.is_empty() {
1484 return Err(Error::binder("a join cannot have both ON and USING"));
1485 }
1486 self.clause = "JOIN condition";
1487 let predicate = self.bind_expr(ast, on, &scope)?;
1488 conditions.push(self.as_boolean(predicate, "JOIN")?);
1489 }
1490
1491 if kind == ast::JoinKind::Cross {
1492 if !conditions.is_empty() {
1493 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
1494 }
1495 let node =
1496 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1497 return Ok((node, scope));
1498 }
1499 if conditions.is_empty() && kind == ast::JoinKind::Inner {
1500 let node =
1501 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1502 return Ok((node, scope));
1503 }
1504 let kind = match kind {
1505 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
1506 ast::JoinKind::Left => JoinKind::Left,
1507 ast::JoinKind::Right => JoinKind::Right,
1508 ast::JoinKind::Full => JoinKind::Full,
1509 ast::JoinKind::Semi => JoinKind::Semi,
1510 ast::JoinKind::Anti => JoinKind::Anti,
1511 ast::JoinKind::Positional => JoinKind::Positional,
1512 };
1513 let conditions = self.plan.add_expr_list(&conditions);
1514 let node =
1515 self.plan.add_node(Node::Join { left: left_node, right: right_node, kind, conditions });
1516 Ok((node, scope))
1517 }
1518
1519 pub(crate) fn bind_aggregate(
1523 &mut self,
1524 ast: &Ast,
1525 name: &str,
1526 args: &[ast::ExprRef],
1527 distinct: bool,
1528 scope: &Scope,
1529 ) -> Result<ExprRef> {
1530 if self.in_aggregate {
1531 return Err(Error::binder(format!(
1532 "aggregate function calls cannot be nested, and {name}() is inside one"
1533 )));
1534 }
1535 if self.aggregation.is_none() {
1536 return Err(Error::binder(format!(
1537 "aggregate function calls cannot be used in the {}",
1538 self.clause
1539 )));
1540 }
1541 self.in_aggregate = true;
1542 let mut bound = Vec::with_capacity(args.len());
1543 let mut failure = None;
1544 for &arg in args {
1545 match self.bind_expr(ast, arg, scope) {
1546 Ok(expr) => bound.push(expr),
1547 Err(error) => {
1548 failure = Some(error);
1549 break;
1550 }
1551 }
1552 }
1553 self.in_aggregate = false;
1554 if let Some(error) = failure {
1555 return Err(error);
1556 }
1557
1558 let types: Vec<LogicalType> =
1559 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
1560 let resolved = resolve(name, &types)?;
1561 let mut cast = Vec::with_capacity(bound.len());
1562 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
1563 cast.push(self.cast_to(*arg, wanted));
1564 }
1565 let args = self.plan.add_expr_list(&cast);
1566 let name = self.plan.intern(resolved.name);
1567 let ty = resolved.returns;
1568 let call =
1569 self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter: None }, ty.clone());
1570
1571 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
1574 let existing = existing.unwrap_or_default();
1575 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
1576 Some(at) => at,
1577 None => {
1578 let aggregation = self.aggregation.as_mut().expect("checked above");
1579 aggregation.aggregates.push(call);
1580 aggregation.aggregates.len() - 1
1581 }
1582 };
1583 let aggregation = self.aggregation.as_ref().expect("checked above");
1584 let (index, groups) = (aggregation.index, aggregation.groups.len());
1585 Ok(self.column(index, groups + at, ty))
1586 }
1587
1588 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
1594 let Some(aggregation) = self.aggregation.as_ref() else {
1595 return Ok(expr);
1596 };
1597 let index = aggregation.index;
1598 let groups = aggregation.groups.clone();
1599 for (at, group) in groups.iter().enumerate() {
1600 if self.same_expr(expr, *group) {
1601 let ty = self.plan.expr_type(*group).clone();
1602 return Ok(self.column(index, at, ty));
1603 }
1604 }
1605 let ty = self.plan.expr_type(expr).clone();
1606 match self.plan.expr(expr).clone() {
1607 Expr::Column(binding) if binding.table == index => Ok(expr),
1608 Expr::Column(binding) => {
1609 let name =
1610 scope.columns.iter().find(|column| column.binding == binding).map_or_else(
1611 || "a column".to_string(),
1612 |column| format!("\"{}\"", column.name),
1613 );
1614 Err(Error::binder(format!(
1615 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
1616 )))
1617 }
1618 Expr::Constant(_) | Expr::Aggregate { .. } => Ok(expr),
1619 Expr::Cast { input, try_cast } => {
1620 let input = self.over_aggregate(input, scope)?;
1621 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
1622 }
1623 Expr::Compare { op, left, right } => {
1624 let left = self.over_aggregate(left, scope)?;
1625 let right = self.over_aggregate(right, scope)?;
1626 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
1627 }
1628 Expr::Conjunction { op, children } => {
1629 let written = self.plan.expr_list(children).to_vec();
1630 let mut rewritten = Vec::with_capacity(written.len());
1631 for child in written {
1632 rewritten.push(self.over_aggregate(child, scope)?);
1633 }
1634 let children = self.plan.add_expr_list(&rewritten);
1635 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
1636 }
1637 Expr::Function { name, args } => {
1638 let written = self.plan.expr_list(args).to_vec();
1639 let mut rewritten = Vec::with_capacity(written.len());
1640 for arg in written {
1641 rewritten.push(self.over_aggregate(arg, scope)?);
1642 }
1643 let args = self.plan.add_expr_list(&rewritten);
1644 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
1645 }
1646 Expr::Case { arms, otherwise } => {
1647 let written = self.plan.arm_list(arms).to_vec();
1648 let mut rewritten = Vec::with_capacity(written.len());
1649 for arm in written {
1650 let when = self.over_aggregate(arm.when, scope)?;
1651 let then = self.over_aggregate(arm.then, scope)?;
1652 rewritten.push(rudb_plan::Arm { when, then });
1653 }
1654 let otherwise = match otherwise {
1655 Some(expr) => Some(self.over_aggregate(expr, scope)?),
1656 None => None,
1657 };
1658 let arms = self.plan.add_arms(&rewritten);
1659 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
1660 }
1661 }
1662 }
1663
1664 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
1666 same_expr(&self.plan, left, right)
1667 }
1668}
1669
1670#[derive(Debug, Default)]
1680struct Options {
1681 binary_as_string: bool,
1684 all_varchar: bool,
1686 file_row_number: bool,
1691 given: Given,
1693}
1694
1695impl Options {
1696 fn of(written: &[(&'static str, Value, ExprRef)]) -> Result<Self> {
1703 let mut options = Self::default();
1704 for (parameter, value, _) in written {
1705 match (*parameter, value) {
1706 ("binary_as_string", Value::Boolean(on)) => options.binary_as_string = *on,
1707 ("all_varchar", Value::Boolean(on)) => options.all_varchar = *on,
1708 ("file_row_number", Value::Boolean(on)) => options.file_row_number = *on,
1709 _ => {}
1710 }
1711 }
1712 let named: Vec<(&str, Value)> =
1713 written.iter().map(|(parameter, value, _)| (*parameter, value.clone())).collect();
1714 options.given = csv_given(&named)?;
1715 Ok(options)
1716 }
1717}
1718
1719fn null_parameter(function: TableFunction, parameter: &str) -> String {
1728 match parameter {
1729 "header" => format!("\"{parameter}\" expects a non-null boolean value (e.g. TRUE or 1)"),
1730 "all_varchar" => format!("{} \"{parameter}\" cannot be NULL", function.name()),
1731 _ => format!("Cannot use NULL as argument to \"{parameter}\""),
1732 }
1733}
1734
1735fn missing_replacement(name: &str, input: &Scope) -> Error {
1740 Error::binder(format!(
1741 "Column \"{name}\" in REPLACE list not found in FROM clause{}",
1742 input.candidates()
1743 ))
1744}
1745
1746fn sort_key(expr: ExprRef, item: ast::OrderItem) -> SortKey {
1752 let descending = item.order == Order::Descending;
1753 let nulls_first = match item.nulls {
1754 Nulls::First => true,
1755 Nulls::Last => false,
1756 Nulls::Unstated => descending,
1757 };
1758 SortKey { expr, descending, nulls_first }
1759}
1760
1761fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
1763 if left == right {
1764 return true;
1765 }
1766 if plan.expr_type(left) != plan.expr_type(right) {
1767 return false;
1768 }
1769 let lists = |left, right| {
1770 let left: &[ExprRef] = plan.expr_list(left);
1771 let right: &[ExprRef] = plan.expr_list(right);
1772 left.len() == right.len()
1773 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
1774 };
1775 match (plan.expr(left), plan.expr(right)) {
1776 (Expr::Column(left), Expr::Column(right)) => left == right,
1777 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
1778 (
1779 Expr::Cast { input: left, try_cast: left_try },
1780 Expr::Cast { input: right, try_cast: right_try },
1781 ) => left_try == right_try && same_expr(plan, *left, *right),
1782 (
1783 Expr::Compare { op: left_op, left: left_a, right: left_b },
1784 Expr::Compare { op: right_op, left: right_a, right: right_b },
1785 ) => {
1786 left_op == right_op
1787 && same_expr(plan, *left_a, *right_a)
1788 && same_expr(plan, *left_b, *right_b)
1789 }
1790 (
1791 Expr::Conjunction { op: left_op, children: left_children },
1792 Expr::Conjunction { op: right_op, children: right_children },
1793 ) => left_op == right_op && lists(*left_children, *right_children),
1794 (
1795 Expr::Function { name: left_name, args: left_args },
1796 Expr::Function { name: right_name, args: right_args },
1797 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
1798 (
1799 Expr::Aggregate {
1800 name: left_name,
1801 args: left_args,
1802 distinct: left_distinct,
1803 filter: left_filter,
1804 },
1805 Expr::Aggregate {
1806 name: right_name,
1807 args: right_args,
1808 distinct: right_distinct,
1809 filter: right_filter,
1810 },
1811 ) => {
1812 plan.string(*left_name) == plan.string(*right_name)
1813 && left_distinct == right_distinct
1814 && match (left_filter, right_filter) {
1815 (None, None) => true,
1816 (Some(left), Some(right)) => same_expr(plan, *left, *right),
1817 _ => false,
1818 }
1819 && lists(*left_args, *right_args)
1820 }
1821 (
1822 Expr::Case { arms: left_arms, otherwise: left_otherwise },
1823 Expr::Case { arms: right_arms, otherwise: right_otherwise },
1824 ) => {
1825 let left_arms = plan.arm_list(*left_arms);
1826 let right_arms = plan.arm_list(*right_arms);
1827 left_arms.len() == right_arms.len()
1828 && left_arms.iter().zip(right_arms).all(|(left, right)| {
1829 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
1830 })
1831 && match (left_otherwise, right_otherwise) {
1832 (None, None) => true,
1833 (Some(left), Some(right)) => same_expr(plan, *left, *right),
1834 _ => false,
1835 }
1836 }
1837 _ => false,
1838 }
1839}