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 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 cast = paths.iter().map(|path| self.path_constant(path)).collect();
1142 fields
1143 }
1144 };
1145 let label = if alias == NONE {
1146 resolved.function.name().to_string()
1147 } else {
1148 ast.string(alias).to_string()
1149 };
1150 let names: Vec<&str> = ast.name(columns).collect();
1151 self.table_function_source(
1152 resolved.function,
1153 &cast,
1154 &written_options,
1155 fields,
1156 &label,
1157 &names,
1158 )
1159 }
1160
1161 fn named_argument(
1175 &mut self,
1176 function: TableFunction,
1177 name: &str,
1178 expr: ExprRef,
1179 ) -> Result<(&'static str, Value)> {
1180 let known = function
1181 .parameters()
1182 .iter()
1183 .find(|(parameter, _)| parameter.eq_ignore_ascii_case(name));
1184 let Some((parameter, wanted)) = known else {
1185 let candidates: Vec<String> = function
1186 .parameters()
1187 .iter()
1188 .map(|(parameter, ty)| format!(" {parameter} {ty}"))
1189 .collect();
1190 return Err(Error::binder(format!(
1191 "Invalid named parameter \"{name}\" for function {}\nCandidates:\n{}\n",
1192 function.name(),
1193 candidates.join("\n")
1194 )));
1195 };
1196 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1197 return Err(Error::not_implemented(format!(
1198 "the named parameter {parameter} with a value that is not a constant"
1199 )));
1200 };
1201 let value = self.plan.value(reference).clone();
1202 if value == Value::Null {
1203 return Err(Error::binder(null_parameter(function, parameter)));
1204 }
1205 let given = self.plan.expr_type(expr).clone();
1206 if given != *wanted {
1207 return Err(Error::not_implemented(format!(
1208 "the named parameter {parameter} given a {given} where a {wanted} was wanted"
1209 )));
1210 }
1211 Ok((parameter, value))
1212 }
1213
1214 fn bind_replacement_scan(
1225 &mut self,
1226 ast: &Ast,
1227 parts: &[&str],
1228 alias: ast::StrRef,
1229 columns: ast::Slice,
1230 missing: Error,
1231 ) -> Result<(NodeRef, Scope)> {
1232 let [path] = parts else { return Err(missing) };
1233 let path = *path;
1234 let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
1235 let Some(function) = Self::reader_for(extension) else {
1236 if is_file(path) {
1237 return Err(Error::binder(format!(
1242 "No extension found that is capable of reading the file \"{path}\"\n* If this \
1243 file is a supported file format you can explicitly use the reader functions, \
1244 such as read_csv, read_json or read_parquet"
1245 )));
1246 }
1247 return Err(missing);
1248 };
1249 let paths = files(path)?;
1254 let first = paths.first().map_or("", String::as_str);
1255 let fields = match function {
1256 TableFunction::ReadParquet => parquet_fields(first)?,
1257 _ => csv_fields(&paths, Given::default())?,
1258 };
1259 let label = if alias == NONE {
1265 if is_pattern(path) {
1266 path.to_string()
1267 } else {
1268 let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
1269 file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
1270 }
1271 } else {
1272 ast.string(alias).to_string()
1273 };
1274 let arguments: Vec<ExprRef> = paths.iter().map(|path| self.path_constant(path)).collect();
1275 let names: Vec<&str> = ast.name(columns).collect();
1276 self.table_function_source(function, &arguments, &[], fields, &label, &names)
1277 }
1278
1279 fn path_constant(&mut self, path: &str) -> ExprRef {
1281 let value = self.plan.add_value(Value::Varchar(path.to_string()));
1282 self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar)
1283 }
1284
1285 fn reader_for(extension: &str) -> Option<TableFunction> {
1292 if extension.eq_ignore_ascii_case("parquet") {
1293 return Some(TableFunction::ReadParquet);
1294 }
1295 if extension.eq_ignore_ascii_case("csv") || extension.eq_ignore_ascii_case("tsv") {
1296 return Some(TableFunction::ReadCsv);
1297 }
1298 None
1299 }
1300
1301 fn table_function_source(
1306 &mut self,
1307 function: TableFunction,
1308 args: &[ExprRef],
1309 written: &[(&'static str, Value, ExprRef)],
1310 fields: Vec<Field>,
1311 label: &str,
1312 names: &[&str],
1313 ) -> Result<(NodeRef, Scope)> {
1314 let index = self.fresh_index();
1315 let mut scope = Scope::empty();
1316 for (at, field) in fields.iter().enumerate() {
1317 scope.push(Visible {
1318 table: label.to_string(),
1319 name: field.name.clone(),
1320 binding: ColumnBinding::new(index, at as u32),
1321 ty: field.ty.clone(),
1322 not_null: false,
1325 });
1326 }
1327 if !names.is_empty() {
1328 scope.rename(names, label)?;
1329 }
1330 let function = self.plan.intern(function.name());
1331 let args = self.plan.add_expr_list(args);
1332 let named: Vec<u32> =
1333 written.iter().map(|(parameter, _, _)| self.plan.intern(parameter)).collect();
1334 let settings: Vec<ExprRef> = written.iter().map(|(_, _, expr)| *expr).collect();
1335 let options = self.plan.add_name_list(&named);
1336 let settings = self.plan.add_expr_list(&settings);
1337 let columns = self.plan.add_fields(&fields);
1338 let node = self.plan.add_node(Node::TableFunction {
1339 index,
1340 function,
1341 args,
1342 options,
1343 settings,
1344 columns,
1345 });
1346 Ok((node, scope))
1347 }
1348
1349 fn file_paths(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1356 let mut paths = Vec::new();
1357 for pattern in self.file_patterns(expr, name)? {
1358 paths.extend(files(&pattern)?);
1359 }
1360 Ok(paths)
1361 }
1362
1363 fn file_patterns(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1375 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1376 return Err(Error::not_implemented(
1377 "a table function file name that is not a constant",
1378 ));
1379 };
1380 match self.plan.value(reference) {
1381 Value::Varchar(path) => Ok(vec![path.clone()]),
1382 Value::Null => Err(Error::parser(format!("{name} cannot take NULL list as parameter"))),
1384 Value::List { values, .. } => values
1385 .iter()
1386 .map(|value| match value {
1387 Value::Varchar(path) => Ok(path.clone()),
1388 _ => Err(Error::parser(format!(
1389 "{name} reader cannot take NULL input as parameter"
1390 ))),
1391 })
1392 .collect(),
1393 other => {
1394 Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
1395 }
1396 }
1397 }
1398
1399 #[allow(clippy::too_many_arguments)]
1400 fn bind_join(
1401 &mut self,
1402 ast: &Ast,
1403 left: ast::SourceRef,
1404 right: ast::SourceRef,
1405 kind: ast::JoinKind,
1406 natural: bool,
1407 on: ast::ExprRef,
1408 using: ast::Slice,
1409 ) -> Result<(NodeRef, Scope)> {
1410 let (left_node, left_scope) = self.bind_source(ast, left)?;
1411 let (right_node, right_scope) = self.bind_source(ast, right)?;
1412 let split = left_scope.len();
1413 let mut scope = left_scope.concat(right_scope);
1414
1415 let merged: Vec<String> = if natural {
1418 let mut names = Vec::new();
1419 for (at, column) in scope.columns.iter().enumerate().take(split) {
1420 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
1421 && !names.iter().any(|held: &String| same_name(held, &column.name))
1422 {
1423 let _ = at;
1424 names.push(column.name.clone());
1425 }
1426 }
1427 names
1428 } else {
1429 ast.name(using).map(str::to_string).collect()
1430 };
1431
1432 let mut conditions = Vec::new();
1433 let mut dropped = Vec::new();
1434 for name in &merged {
1435 let left_at = scope.columns[..split]
1436 .iter()
1437 .position(|column| same_name(&column.name, name))
1438 .ok_or_else(|| {
1439 Error::binder(format!(
1440 "column \"{name}\" specified in USING clause does not exist in left table"
1441 ))
1442 })?;
1443 let right_at = scope.columns[split..]
1444 .iter()
1445 .position(|column| same_name(&column.name, name))
1446 .map(|at| at + split)
1447 .ok_or_else(|| {
1448 Error::binder(format!(
1449 "column \"{name}\" specified in USING clause does not exist in right table"
1450 ))
1451 })?;
1452 let left_column = &scope.columns[left_at];
1453 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
1454 let right_column = &scope.columns[right_at];
1455 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
1456 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
1457 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
1458 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
1459 dropped.push(right_at);
1460 }
1461 dropped.sort_unstable();
1464 for at in dropped.into_iter().rev() {
1465 scope.remove(at);
1466 }
1467
1468 if on != NONE {
1469 if !merged.is_empty() {
1470 return Err(Error::binder("a join cannot have both ON and USING"));
1471 }
1472 self.clause = "JOIN condition";
1473 let predicate = self.bind_expr(ast, on, &scope)?;
1474 conditions.push(self.as_boolean(predicate, "JOIN")?);
1475 }
1476
1477 if kind == ast::JoinKind::Cross {
1478 if !conditions.is_empty() {
1479 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
1480 }
1481 let node =
1482 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1483 return Ok((node, scope));
1484 }
1485 if conditions.is_empty() && kind == ast::JoinKind::Inner {
1486 let node =
1487 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1488 return Ok((node, scope));
1489 }
1490 let kind = match kind {
1491 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
1492 ast::JoinKind::Left => JoinKind::Left,
1493 ast::JoinKind::Right => JoinKind::Right,
1494 ast::JoinKind::Full => JoinKind::Full,
1495 ast::JoinKind::Semi => JoinKind::Semi,
1496 ast::JoinKind::Anti => JoinKind::Anti,
1497 ast::JoinKind::Positional => JoinKind::Positional,
1498 };
1499 let conditions = self.plan.add_expr_list(&conditions);
1500 let node =
1501 self.plan.add_node(Node::Join { left: left_node, right: right_node, kind, conditions });
1502 Ok((node, scope))
1503 }
1504
1505 pub(crate) fn bind_aggregate(
1509 &mut self,
1510 ast: &Ast,
1511 name: &str,
1512 args: &[ast::ExprRef],
1513 distinct: bool,
1514 scope: &Scope,
1515 ) -> Result<ExprRef> {
1516 if self.in_aggregate {
1517 return Err(Error::binder(format!(
1518 "aggregate function calls cannot be nested, and {name}() is inside one"
1519 )));
1520 }
1521 if self.aggregation.is_none() {
1522 return Err(Error::binder(format!(
1523 "aggregate function calls cannot be used in the {}",
1524 self.clause
1525 )));
1526 }
1527 self.in_aggregate = true;
1528 let mut bound = Vec::with_capacity(args.len());
1529 let mut failure = None;
1530 for &arg in args {
1531 match self.bind_expr(ast, arg, scope) {
1532 Ok(expr) => bound.push(expr),
1533 Err(error) => {
1534 failure = Some(error);
1535 break;
1536 }
1537 }
1538 }
1539 self.in_aggregate = false;
1540 if let Some(error) = failure {
1541 return Err(error);
1542 }
1543
1544 let types: Vec<LogicalType> =
1545 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
1546 let resolved = resolve(name, &types)?;
1547 let mut cast = Vec::with_capacity(bound.len());
1548 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
1549 cast.push(self.cast_to(*arg, wanted));
1550 }
1551 let args = self.plan.add_expr_list(&cast);
1552 let name = self.plan.intern(resolved.name);
1553 let ty = resolved.returns;
1554 let call =
1555 self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter: None }, ty.clone());
1556
1557 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
1560 let existing = existing.unwrap_or_default();
1561 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
1562 Some(at) => at,
1563 None => {
1564 let aggregation = self.aggregation.as_mut().expect("checked above");
1565 aggregation.aggregates.push(call);
1566 aggregation.aggregates.len() - 1
1567 }
1568 };
1569 let aggregation = self.aggregation.as_ref().expect("checked above");
1570 let (index, groups) = (aggregation.index, aggregation.groups.len());
1571 Ok(self.column(index, groups + at, ty))
1572 }
1573
1574 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
1580 let Some(aggregation) = self.aggregation.as_ref() else {
1581 return Ok(expr);
1582 };
1583 let index = aggregation.index;
1584 let groups = aggregation.groups.clone();
1585 for (at, group) in groups.iter().enumerate() {
1586 if self.same_expr(expr, *group) {
1587 let ty = self.plan.expr_type(*group).clone();
1588 return Ok(self.column(index, at, ty));
1589 }
1590 }
1591 let ty = self.plan.expr_type(expr).clone();
1592 match self.plan.expr(expr).clone() {
1593 Expr::Column(binding) if binding.table == index => Ok(expr),
1594 Expr::Column(binding) => {
1595 let name =
1596 scope.columns.iter().find(|column| column.binding == binding).map_or_else(
1597 || "a column".to_string(),
1598 |column| format!("\"{}\"", column.name),
1599 );
1600 Err(Error::binder(format!(
1601 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
1602 )))
1603 }
1604 Expr::Constant(_) | Expr::Aggregate { .. } => Ok(expr),
1605 Expr::Cast { input, try_cast } => {
1606 let input = self.over_aggregate(input, scope)?;
1607 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
1608 }
1609 Expr::Compare { op, left, right } => {
1610 let left = self.over_aggregate(left, scope)?;
1611 let right = self.over_aggregate(right, scope)?;
1612 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
1613 }
1614 Expr::Conjunction { op, children } => {
1615 let written = self.plan.expr_list(children).to_vec();
1616 let mut rewritten = Vec::with_capacity(written.len());
1617 for child in written {
1618 rewritten.push(self.over_aggregate(child, scope)?);
1619 }
1620 let children = self.plan.add_expr_list(&rewritten);
1621 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
1622 }
1623 Expr::Function { name, args } => {
1624 let written = self.plan.expr_list(args).to_vec();
1625 let mut rewritten = Vec::with_capacity(written.len());
1626 for arg in written {
1627 rewritten.push(self.over_aggregate(arg, scope)?);
1628 }
1629 let args = self.plan.add_expr_list(&rewritten);
1630 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
1631 }
1632 Expr::Case { arms, otherwise } => {
1633 let written = self.plan.arm_list(arms).to_vec();
1634 let mut rewritten = Vec::with_capacity(written.len());
1635 for arm in written {
1636 let when = self.over_aggregate(arm.when, scope)?;
1637 let then = self.over_aggregate(arm.then, scope)?;
1638 rewritten.push(rudb_plan::Arm { when, then });
1639 }
1640 let otherwise = match otherwise {
1641 Some(expr) => Some(self.over_aggregate(expr, scope)?),
1642 None => None,
1643 };
1644 let arms = self.plan.add_arms(&rewritten);
1645 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
1646 }
1647 }
1648 }
1649
1650 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
1652 same_expr(&self.plan, left, right)
1653 }
1654}
1655
1656#[derive(Debug, Default)]
1666struct Options {
1667 binary_as_string: bool,
1670 all_varchar: bool,
1672 given: Given,
1674}
1675
1676impl Options {
1677 fn of(written: &[(&'static str, Value, ExprRef)]) -> Result<Self> {
1684 let mut options = Self::default();
1685 for (parameter, value, _) in written {
1686 match (*parameter, value) {
1687 ("binary_as_string", Value::Boolean(on)) => options.binary_as_string = *on,
1688 ("all_varchar", Value::Boolean(on)) => options.all_varchar = *on,
1689 _ => {}
1690 }
1691 }
1692 let named: Vec<(&str, Value)> =
1693 written.iter().map(|(parameter, value, _)| (*parameter, value.clone())).collect();
1694 options.given = csv_given(&named)?;
1695 Ok(options)
1696 }
1697}
1698
1699fn null_parameter(function: TableFunction, parameter: &str) -> String {
1708 match parameter {
1709 "header" => format!("\"{parameter}\" expects a non-null boolean value (e.g. TRUE or 1)"),
1710 "all_varchar" => format!("{} \"{parameter}\" cannot be NULL", function.name()),
1711 _ => format!("Cannot use NULL as argument to \"{parameter}\""),
1712 }
1713}
1714
1715fn missing_replacement(name: &str, input: &Scope) -> Error {
1720 Error::binder(format!(
1721 "Column \"{name}\" in REPLACE list not found in FROM clause{}",
1722 input.candidates()
1723 ))
1724}
1725
1726fn sort_key(expr: ExprRef, item: ast::OrderItem) -> SortKey {
1732 let descending = item.order == Order::Descending;
1733 let nulls_first = match item.nulls {
1734 Nulls::First => true,
1735 Nulls::Last => false,
1736 Nulls::Unstated => descending,
1737 };
1738 SortKey { expr, descending, nulls_first }
1739}
1740
1741fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
1743 if left == right {
1744 return true;
1745 }
1746 if plan.expr_type(left) != plan.expr_type(right) {
1747 return false;
1748 }
1749 let lists = |left, right| {
1750 let left: &[ExprRef] = plan.expr_list(left);
1751 let right: &[ExprRef] = plan.expr_list(right);
1752 left.len() == right.len()
1753 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
1754 };
1755 match (plan.expr(left), plan.expr(right)) {
1756 (Expr::Column(left), Expr::Column(right)) => left == right,
1757 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
1758 (
1759 Expr::Cast { input: left, try_cast: left_try },
1760 Expr::Cast { input: right, try_cast: right_try },
1761 ) => left_try == right_try && same_expr(plan, *left, *right),
1762 (
1763 Expr::Compare { op: left_op, left: left_a, right: left_b },
1764 Expr::Compare { op: right_op, left: right_a, right: right_b },
1765 ) => {
1766 left_op == right_op
1767 && same_expr(plan, *left_a, *right_a)
1768 && same_expr(plan, *left_b, *right_b)
1769 }
1770 (
1771 Expr::Conjunction { op: left_op, children: left_children },
1772 Expr::Conjunction { op: right_op, children: right_children },
1773 ) => left_op == right_op && lists(*left_children, *right_children),
1774 (
1775 Expr::Function { name: left_name, args: left_args },
1776 Expr::Function { name: right_name, args: right_args },
1777 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
1778 (
1779 Expr::Aggregate {
1780 name: left_name,
1781 args: left_args,
1782 distinct: left_distinct,
1783 filter: left_filter,
1784 },
1785 Expr::Aggregate {
1786 name: right_name,
1787 args: right_args,
1788 distinct: right_distinct,
1789 filter: right_filter,
1790 },
1791 ) => {
1792 plan.string(*left_name) == plan.string(*right_name)
1793 && left_distinct == right_distinct
1794 && match (left_filter, right_filter) {
1795 (None, None) => true,
1796 (Some(left), Some(right)) => same_expr(plan, *left, *right),
1797 _ => false,
1798 }
1799 && lists(*left_args, *right_args)
1800 }
1801 (
1802 Expr::Case { arms: left_arms, otherwise: left_otherwise },
1803 Expr::Case { arms: right_arms, otherwise: right_otherwise },
1804 ) => {
1805 let left_arms = plan.arm_list(*left_arms);
1806 let right_arms = plan.arm_list(*right_arms);
1807 left_arms.len() == right_arms.len()
1808 && left_arms.iter().zip(right_arms).all(|(left, right)| {
1809 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
1810 })
1811 && match (left_otherwise, right_otherwise) {
1812 (None, None) => true,
1813 (Some(left), Some(right)) => same_expr(plan, *left, *right),
1814 _ => false,
1815 }
1816 }
1817 _ => false,
1818 }
1819}