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