1use rudb_catalog::{Catalog, same_name};
16use rudb_common::{Error, Field, LogicalType, Result, Value};
17use rudb_functions::{Columns, TableFunction, parquet_fields, resolve, resolve_table};
18use rudb_parse::ast::{self, Ast, Distinct, LiteralKind, Nulls, Order, Quantifier, SetOp};
19use rudb_parse::{NONE, parse_ast};
20use rudb_plan::{ColumnBinding, Expr, ExprRef, JoinKind, Node, NodeRef, Plan, SetOpKind, SortKey};
21
22use crate::expr::{describe, has_aggregate};
23use crate::scope::{Scope, Visible};
24
25pub fn bind(ast: &Ast, catalog: &Catalog) -> Result<Plan> {
32 let query = match ast.statements.as_slice() {
33 [ast::Statement::Query(query)] => *query,
34 [] => return Err(Error::binder("no statement to bind")),
35 _ => return Err(Error::not_implemented("a script of more than one statement")),
36 };
37 let mut binder = Binder::new(catalog);
38 let (root, _) = binder.bind_query(ast, query)?;
39 let mut plan = binder.into_plan();
40 plan.set_root(root);
41 plan.validate()?;
42 Ok(plan)
43}
44
45pub fn bind_sql(query: &str, catalog: &Catalog) -> Result<Plan> {
51 let ast = parse_ast(query)?;
52 bind(&ast, catalog)
53}
54
55#[derive(Debug)]
57pub(crate) struct Aggregation {
58 pub(crate) index: u32,
60 pub(crate) groups: Vec<ExprRef>,
62 pub(crate) aggregates: Vec<ExprRef>,
64}
65
66#[derive(Debug)]
68pub(crate) struct Binder<'a> {
69 catalog: &'a Catalog,
70 plan: Plan,
71 next_index: u32,
72 pub(crate) aggregation: Option<Aggregation>,
74 pub(crate) in_aggregate: bool,
76 pub(crate) clause: &'static str,
78}
79
80impl<'a> Binder<'a> {
81 pub(crate) fn new(catalog: &'a Catalog) -> Self {
82 Self {
83 catalog,
84 plan: Plan::new(),
85 next_index: 0,
86 aggregation: None,
87 in_aggregate: false,
88 clause: "SELECT clause",
89 }
90 }
91
92 pub(crate) fn plan(&self) -> &Plan {
93 &self.plan
94 }
95
96 pub(crate) fn plan_mut(&mut self) -> &mut Plan {
97 &mut self.plan
98 }
99
100 pub(crate) fn into_plan(self) -> Plan {
101 self.plan
102 }
103
104 pub(crate) fn fresh_index(&mut self) -> u32 {
106 let index = self.next_index;
107 self.next_index += 1;
108 index
109 }
110
111 fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
113 let binding = ColumnBinding::new(index, position as u32);
114 self.plan.add_expr(Expr::Column(binding), ty)
115 }
116
117 pub(crate) fn bind_query(
120 &mut self,
121 ast: &Ast,
122 query: ast::QueryRef,
123 ) -> Result<(NodeRef, Scope)> {
124 let written = ast.query(query);
125 match written.body {
126 ast::QueryBody::Select(select) => self.bind_select(ast, select, &written),
127 ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
128 if by_name {
129 return Err(Error::not_implemented("UNION BY NAME"));
130 }
131 self.bind_set_op(ast, &written, op, quantifier, left, right)
132 }
133 ast::QueryBody::Values(rows) => self.bind_values(ast, &written, rows),
134 }
135 }
136
137 fn bind_values(
144 &mut self,
145 ast: &Ast,
146 query: &ast::Query,
147 rows: ast::Slice,
148 ) -> Result<(NodeRef, Scope)> {
149 let written = ast.rows(rows).to_vec();
150 let Some(first) = written.first() else {
151 return Err(Error::binder("VALUES needs at least one row"));
152 };
153 let width = first.len as usize;
154 for (at, row) in written.iter().enumerate() {
155 if row.len as usize != width {
156 return Err(Error::binder(format!(
157 "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
158 at + 1,
159 row.len
160 )));
161 }
162 }
163 let empty = Scope::empty();
165 let previous = std::mem::replace(&mut self.clause, "VALUES clause");
166 let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
167 for row in &written {
168 let mut items = Vec::with_capacity(width);
169 for &expr in ast.expr_list(*row) {
170 items.push(self.bind_expr(ast, expr, &empty)?);
171 }
172 bound.push(items);
173 }
174 self.clause = previous;
175 let mut types = Vec::with_capacity(width);
176 for at in 0..width {
177 let mut ty = self.plan.expr_type(bound[0][at]).clone();
178 for row in &bound[1..] {
179 let other = self.plan.expr_type(row[at]).clone();
180 ty = ty.promote(&other).ok_or_else(|| {
181 Error::binder(format!(
182 "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
183 at + 1
184 ))
185 })?;
186 }
187 types.push(ty);
188 }
189 let mut slices = Vec::with_capacity(bound.len());
190 for row in &bound {
191 let items: Vec<ExprRef> =
192 row.iter().zip(&types).map(|(&expr, ty)| self.cast_to(expr, ty)).collect();
193 slices.push(self.plan.add_expr_list(&items));
194 }
195 let rows = self.plan.add_rows(&slices);
196 let fields: Vec<Field> = types
197 .iter()
198 .enumerate()
199 .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
200 .collect();
201 let columns = self.plan.add_fields(&fields);
202 let index = self.fresh_index();
203 let mut node = self.plan.add_node(Node::Values { index, columns, rows });
204 let mut scope = Scope::empty();
205 for (at, field) in fields.iter().enumerate() {
206 scope.push(Visible {
207 table: String::new(),
208 name: field.name.clone(),
209 binding: ColumnBinding::new(index, at as u32),
210 ty: field.ty.clone(),
211 });
212 }
213 let keys = self.sort_keys(ast, query, &scope, &[])?;
214 if !keys.is_empty() {
215 let keys = self.plan.add_sort_keys(&keys);
216 node = self.plan.add_node(Node::Sort { input: node, keys });
217 }
218 node = self.apply_limit(ast, query, node)?;
219 Ok((node, scope))
220 }
221
222 fn bind_set_op(
223 &mut self,
224 ast: &Ast,
225 query: &ast::Query,
226 op: SetOp,
227 quantifier: Quantifier,
228 left: ast::QueryRef,
229 right: ast::QueryRef,
230 ) -> Result<(NodeRef, Scope)> {
231 let (left_node, left_scope) = self.bind_query(ast, left)?;
232 let (right_node, right_scope) = self.bind_query(ast, right)?;
233 if left_scope.len() != right_scope.len() {
234 return Err(Error::binder(format!(
235 "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
236 left_scope.len(),
237 right_scope.len()
238 )));
239 }
240 let mut types = Vec::with_capacity(left_scope.len());
242 for (left, right) in left_scope.columns.iter().zip(&right_scope.columns) {
243 let common = left.ty.promote(&right.ty).ok_or_else(|| {
244 Error::binder(format!(
245 "Cannot combine a column of type {} with a column of type {} in a set operation",
246 left.ty, right.ty
247 ))
248 })?;
249 types.push(common);
250 }
251 let left_node = self.conform(left_node, &left_scope, &types);
252 let right_node = self.conform(right_node, &right_scope, &types);
253 let index = self.fresh_index();
254 let kind = match op {
255 SetOp::Union => SetOpKind::Union,
256 SetOp::Except => SetOpKind::Except,
257 SetOp::Intersect => SetOpKind::Intersect,
258 };
259 let all = quantifier == Quantifier::All;
262 let mut node = self.plan.add_node(Node::SetOp {
263 left: left_node,
264 right: right_node,
265 kind,
266 all,
267 index,
268 });
269 let mut scope = Scope::empty();
270 for (at, (column, ty)) in left_scope.columns.iter().zip(&types).enumerate() {
271 scope.push(Visible {
272 table: String::new(),
273 name: column.name.clone(),
274 binding: ColumnBinding::new(index, at as u32),
275 ty: ty.clone(),
276 });
277 }
278 let keys = self.sort_keys(ast, query, &scope, &[])?;
282 if !keys.is_empty() {
283 let keys = self.plan.add_sort_keys(&keys);
284 node = self.plan.add_node(Node::Sort { input: node, keys });
285 }
286 node = self.apply_limit(ast, query, node)?;
287 Ok((node, scope))
288 }
289
290 fn conform(&mut self, node: NodeRef, scope: &Scope, types: &[LogicalType]) -> NodeRef {
292 if scope.columns.iter().zip(types).all(|(column, ty)| &column.ty == ty) {
293 return node;
294 }
295 let index = self.fresh_index();
296 let mut exprs = Vec::with_capacity(types.len());
297 let mut names = Vec::with_capacity(types.len());
298 for (column, ty) in scope.columns.iter().zip(types) {
299 let expr = self.plan.add_expr(Expr::Column(column.binding), column.ty.clone());
300 exprs.push(self.cast_to(expr, ty));
301 names.push(self.plan.intern(&column.name));
302 }
303 let exprs = self.plan.add_expr_list(&exprs);
304 let names = self.plan.add_name_list(&names);
305 self.plan.add_node(Node::Project { input: node, index, exprs, names })
306 }
307
308 fn bind_select(
311 &mut self,
312 ast: &Ast,
313 select: ast::SelectRef,
314 query: &ast::Query,
315 ) -> Result<(NodeRef, Scope)> {
316 let written = ast.select(select);
317 let (mut node, input) = self.bind_from(ast, written.from)?;
318
319 if written.filter != NONE {
320 self.clause = "WHERE clause";
321 let predicate = self.bind_expr(ast, written.filter, &input)?;
322 let predicate = self.as_boolean(predicate, "WHERE")?;
323 node = self.plan.add_node(Node::Filter { input: node, predicate });
324 }
325
326 let targets = ast.target_list(written.targets).to_vec();
327 if targets.is_empty() {
328 return Err(Error::binder("a SELECT needs at least one expression to select"));
329 }
330
331 let group_items = self.group_items(ast, &written, &targets)?;
332 let aggregating = !group_items.is_empty()
333 || written.having != NONE
334 || targets.iter().any(|target| has_aggregate(ast, target.expr));
335 if aggregating {
336 self.clause = "GROUP BY clause";
337 let mut groups = Vec::with_capacity(group_items.len());
338 for item in &group_items {
339 groups.push(self.bind_expr(ast, *item, &input)?);
340 }
341 let index = self.fresh_index();
342 self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
343 }
344
345 self.clause = "SELECT clause";
346 let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input)?;
347 let visible = exprs.len();
348
349 let mut having = None;
350 if written.having != NONE {
351 self.clause = "HAVING clause";
352 let predicate = self.bind_expr(ast, written.having, &input)?;
353 let predicate = self.over_aggregate(predicate, &input)?;
354 having = Some(self.as_boolean(predicate, "HAVING")?);
355 }
356
357 let project = self.fresh_index();
360 let mut output = Scope::empty();
361 for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
362 output.push(Visible {
363 table: String::new(),
364 name: name.clone(),
365 binding: ColumnBinding::new(project, at as u32),
366 ty: self.plan.expr_type(*expr).clone(),
367 });
368 }
369
370 self.clause = "ORDER BY clause";
371 let mut extra = Vec::new();
372 let keys = self.select_sort_keys(
373 ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra,
374 )?;
375 if !extra.is_empty() && written.distinct != Distinct::No {
376 return Err(Error::binder(
377 "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
378 ));
379 }
380 let on = self.distinct_on(ast, written.distinct, &output)?;
381
382 if let Some(aggregation) = self.aggregation.take() {
383 let index = aggregation.index;
384 let groups = self.plan.add_expr_list(&aggregation.groups);
385 let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
386 node = self.plan.add_node(Node::Aggregate { input: node, index, groups, aggregates });
387 }
388 if let Some(predicate) = having {
389 node = self.plan.add_node(Node::Filter { input: node, predicate });
390 }
391
392 let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
393 let exprs_slice = self.plan.add_expr_list(&exprs);
394 let names_slice = self.plan.add_name_list(&interned);
395 node = self.plan.add_node(Node::Project {
396 input: node,
397 index: project,
398 exprs: exprs_slice,
399 names: names_slice,
400 });
401
402 if written.distinct != Distinct::No {
403 let on = self.plan.add_expr_list(&on);
404 node = self.plan.add_node(Node::Distinct { input: node, on });
405 }
406 if !keys.is_empty() {
407 let keys = self.plan.add_sort_keys(&keys);
408 node = self.plan.add_node(Node::Sort { input: node, keys });
409 }
410 node = self.apply_limit(ast, query, node)?;
411
412 if extra.is_empty() {
413 output.columns.truncate(visible);
414 return Ok((node, output));
415 }
416 let index = self.fresh_index();
419 let mut kept = Vec::with_capacity(visible);
420 let mut kept_names = Vec::with_capacity(visible);
421 let mut scope = Scope::empty();
422 for (at, name) in names.iter().enumerate().take(visible) {
423 let ty = output.columns[at].ty.clone();
424 kept.push(self.column(project, at, ty.clone()));
425 kept_names.push(self.plan.intern(name));
426 scope.push(Visible {
427 table: String::new(),
428 name: name.clone(),
429 binding: ColumnBinding::new(index, at as u32),
430 ty,
431 });
432 }
433 let exprs = self.plan.add_expr_list(&kept);
434 let names = self.plan.add_name_list(&kept_names);
435 node = self.plan.add_node(Node::Project { input: node, index, exprs, names });
436 Ok((node, scope))
437 }
438
439 fn bind_targets(
441 &mut self,
442 ast: &Ast,
443 targets: &[ast::Target],
444 input: &Scope,
445 ) -> Result<(Vec<ExprRef>, Vec<String>)> {
446 let mut exprs = Vec::with_capacity(targets.len());
447 let mut names = Vec::with_capacity(targets.len());
448 for target in targets {
449 if let ast::Expr::Star { qualifier } = ast.expr(target.expr) {
450 let table = ast.name(qualifier).last().map(str::to_string);
451 let expanded: Vec<Visible> =
452 input.star(table.as_deref())?.into_iter().cloned().collect();
453 for column in expanded {
454 let expr = self.plan.add_expr(Expr::Column(column.binding), column.ty);
455 exprs.push(self.over_aggregate(expr, input)?);
456 names.push(column.name);
457 }
458 continue;
459 }
460 let expr = self.bind_expr(ast, target.expr, input)?;
461 exprs.push(self.over_aggregate(expr, input)?);
462 names.push(if target.alias == NONE {
463 self.output_name(ast, target.expr, input)
464 } else {
465 ast.string(target.alias).to_string()
466 });
467 }
468 Ok((exprs, names))
469 }
470
471 fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
477 if let ast::Expr::Column { name } = ast.expr(target) {
478 let parts: Vec<&str> = ast.name(name).collect();
479 if let Ok(found) = input.resolve(&parts) {
480 return found.name.clone();
481 }
482 }
483 describe(ast, target)
484 }
485
486 fn group_items(
488 &self,
489 ast: &Ast,
490 select: &ast::Select,
491 targets: &[ast::Target],
492 ) -> Result<Vec<ast::ExprRef>> {
493 if select.group_by_all {
494 return Ok(targets
497 .iter()
498 .filter(|target| !has_aggregate(ast, target.expr))
499 .map(|target| target.expr)
500 .collect());
501 }
502 let mut items = Vec::new();
503 for &item in ast.expr_list(select.group_by) {
504 items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
505 }
506 Ok(items)
507 }
508
509 fn output_reference(
511 &self,
512 ast: &Ast,
513 item: ast::ExprRef,
514 targets: &[ast::Target],
515 clause: &str,
516 ) -> Result<Option<ast::ExprRef>> {
517 match ast.expr(item) {
518 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
519 let written = ast.string(text);
520 let position: usize = written.parse().map_err(|_| {
521 Error::binder(format!("{clause} term {written} is not a column"))
522 })?;
523 if position == 0 || position > targets.len() {
524 return Err(Error::binder(format!(
525 "{clause} term out of range - should be between 1 and {}",
526 targets.len()
527 )));
528 }
529 Ok(Some(targets[position - 1].expr))
530 }
531 ast::Expr::Column { name } => {
532 let parts: Vec<&str> = ast.name(name).collect();
533 let [written] = parts.as_slice() else { return Ok(None) };
534 let mut found = None;
535 for target in targets {
536 if target.alias != NONE && same_name(ast.string(target.alias), written) {
537 if found.is_some() {
538 return Ok(None);
539 }
540 found = Some(target.expr);
541 }
542 }
543 Ok(found)
544 }
545 _ => Ok(None),
546 }
547 }
548
549 #[allow(clippy::too_many_arguments)]
553 fn select_sort_keys(
554 &mut self,
555 ast: &Ast,
556 query: &ast::Query,
557 input: &Scope,
558 output: &Scope,
559 project: u32,
560 exprs: &mut Vec<ExprRef>,
561 names: &mut Vec<String>,
562 extra: &mut Vec<usize>,
563 ) -> Result<Vec<SortKey>> {
564 if query.order_by_all {
565 return Ok(self.every_column(output));
566 }
567 let items = ast.order_list(query.order_by).to_vec();
568 let mut keys = Vec::with_capacity(items.len());
569 for item in items {
570 let position = match self.output_position(ast, item.expr, output)? {
571 Some(position) => position,
572 None => {
573 let bound = self.bind_expr(ast, item.expr, input)?;
574 let bound = self.over_aggregate(bound, input)?;
575 match exprs.iter().position(|&held| self.same_expr(held, bound)) {
576 Some(position) => position,
577 None => {
578 exprs.push(bound);
579 names.push(describe(ast, item.expr));
580 extra.push(exprs.len() - 1);
581 exprs.len() - 1
582 }
583 }
584 }
585 };
586 let ty = self.plan.expr_type(exprs[position]).clone();
587 let expr = self.column(project, position, ty);
588 keys.push(sort_key(expr, item));
589 }
590 Ok(keys)
591 }
592
593 fn sort_keys(
595 &mut self,
596 ast: &Ast,
597 query: &ast::Query,
598 output: &Scope,
599 targets: &[ast::Target],
600 ) -> Result<Vec<SortKey>> {
601 if query.order_by_all {
602 return Ok(self.every_column(output));
603 }
604 let items = ast.order_list(query.order_by).to_vec();
605 let mut keys = Vec::with_capacity(items.len());
606 for item in items {
607 let expr = match self.output_position(ast, item.expr, output)? {
608 Some(position) => {
609 let column = &output.columns[position];
610 let (binding, ty) = (column.binding, column.ty.clone());
611 self.plan.add_expr(Expr::Column(binding), ty)
612 }
613 None => {
614 let _ = targets;
615 self.bind_expr(ast, item.expr, output)?
616 }
617 };
618 keys.push(sort_key(expr, item));
619 }
620 Ok(keys)
621 }
622
623 fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
624 let columns: Vec<(ColumnBinding, LogicalType)> =
625 output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
626 columns
627 .into_iter()
628 .map(|(binding, ty)| {
629 let expr = self.plan.add_expr(Expr::Column(binding), ty);
630 SortKey { expr, descending: false, nulls_first: false }
631 })
632 .collect()
633 }
634
635 fn output_position(
637 &self,
638 ast: &Ast,
639 item: ast::ExprRef,
640 output: &Scope,
641 ) -> Result<Option<usize>> {
642 match ast.expr(item) {
643 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
644 let written = ast.string(text);
645 if written.contains(['.', 'e', 'E']) {
646 return Ok(None);
647 }
648 let position: usize = written.parse().map_err(|_| {
649 Error::binder(format!("ORDER BY term {written} is not a column"))
650 })?;
651 if position == 0 || position > output.len() {
652 return Err(Error::binder(format!(
653 "ORDER BY term out of range - should be between 1 and {}",
654 output.len()
655 )));
656 }
657 Ok(Some(position - 1))
658 }
659 ast::Expr::Column { name } => {
660 let parts: Vec<&str> = ast.name(name).collect();
661 let [written] = parts.as_slice() else { return Ok(None) };
662 Ok(output.position_of(None, written))
663 }
664 _ => Ok(None),
665 }
666 }
667
668 fn distinct_on(
670 &mut self,
671 ast: &Ast,
672 distinct: Distinct,
673 output: &Scope,
674 ) -> Result<Vec<ExprRef>> {
675 let Distinct::On(items) = distinct else {
676 return Ok(Vec::new());
677 };
678 let items = ast.expr_list(items).to_vec();
679 let mut on = Vec::with_capacity(items.len());
680 for item in items {
681 let Some(position) = self.output_position(ast, item, output)? else {
682 return Err(Error::not_implemented(
683 "DISTINCT ON an expression that is not in the select list",
684 ));
685 };
686 let column = &output.columns[position];
687 let (binding, ty) = (column.binding, column.ty.clone());
688 on.push(self.plan.add_expr(Expr::Column(binding), ty));
689 }
690 Ok(on)
691 }
692
693 fn apply_limit(&mut self, ast: &Ast, query: &ast::Query, input: NodeRef) -> Result<NodeRef> {
694 if query.limit_percent {
695 return Err(Error::not_implemented("LIMIT with a percentage"));
696 }
697 let count = self.constant_count(ast, query.limit, "LIMIT")?;
698 let offset = self.constant_count(ast, query.offset, "OFFSET")?.unwrap_or(0);
699 if count.is_none() && offset == 0 {
700 return Ok(input);
701 }
702 Ok(self.plan.add_node(Node::Limit { input, count, offset }))
703 }
704
705 fn constant_count(
707 &mut self,
708 ast: &Ast,
709 written: ast::ExprRef,
710 clause: &str,
711 ) -> Result<Option<u64>> {
712 if written == NONE {
713 return Ok(None);
714 }
715 self.clause = "LIMIT clause";
716 let scope = Scope::empty();
717 let bound = self.bind_expr(ast, written, &scope)?;
718 let Expr::Constant(value) = *self.plan.expr(bound) else {
719 return Err(Error::not_implemented(format!("a {clause} that is not a constant")));
720 };
721 let count = match self.plan.value(value) {
722 Value::Null => return Ok(None),
723 Value::TinyInt(count) => i128::from(*count),
724 Value::SmallInt(count) => i128::from(*count),
725 Value::Integer(count) => i128::from(*count),
726 Value::BigInt(count) => i128::from(*count),
727 Value::HugeInt(count) => *count,
728 other => {
729 return Err(Error::binder(format!(
730 "{clause} takes a whole number of rows, not a value of type {}",
731 other.logical_type()
732 )));
733 }
734 };
735 u64::try_from(count)
736 .map(Some)
737 .map_err(|_| Error::binder(format!("{clause} must not be negative")))
738 }
739
740 fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
743 let sources = ast.source_list(from).to_vec();
744 let Some((first, rest)) = sources.split_first() else {
745 return Ok((self.plan.add_node(Node::Dummy), Scope::empty()));
748 };
749 let (mut node, mut scope) = self.bind_source(ast, *first)?;
750 for source in rest {
751 let (right, right_scope) = self.bind_source(ast, *source)?;
752 node = self.plan.add_node(Node::CrossProduct { left: node, right });
753 scope = scope.concat(right_scope);
754 }
755 Ok((node, scope))
756 }
757
758 fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
759 match ast.source(source) {
760 ast::Source::Table { name, alias, columns } => {
761 self.bind_table(ast, name, alias, columns)
762 }
763 ast::Source::Function { name, args, alias, columns } => {
764 self.bind_table_function(ast, name, args, alias, columns)
765 }
766 ast::Source::Subquery { query, alias, columns } => {
767 let (node, mut scope) = self.bind_query(ast, query)?;
768 let label = if alias == NONE {
769 "unnamed_subquery".to_string()
770 } else {
771 ast.string(alias).to_string()
772 };
773 scope.relabel(&label);
774 if !columns.is_empty() {
775 let names: Vec<&str> = ast.name(columns).collect();
776 scope.rename(&names, &label)?;
777 }
778 Ok((node, scope))
779 }
780 ast::Source::Values { rows, alias, columns } => {
781 let bare = ast::Query::bare(ast::QueryBody::Values(rows));
782 let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
783 let label =
784 if alias == NONE { String::new() } else { ast.string(alias).to_string() };
785 scope.relabel(&label);
786 if !columns.is_empty() {
787 let names: Vec<&str> = ast.name(columns).collect();
788 scope.rename(&names, &label)?;
789 }
790 Ok((node, scope))
791 }
792 ast::Source::Join { left, right, kind, natural, on, using } => {
793 self.bind_join(ast, left, right, kind, natural, on, using)
794 }
795 }
796 }
797
798 fn bind_table(
799 &mut self,
800 ast: &Ast,
801 name: ast::Slice,
802 alias: ast::StrRef,
803 columns: ast::Slice,
804 ) -> Result<(NodeRef, Scope)> {
805 let parts: Vec<&str> = ast.name(name).collect();
806 let catalog = self.catalog;
807 let found = catalog.resolve(&parts).and_then(|resolved| {
810 let table = catalog.table(&resolved)?;
811 Ok((resolved, table))
812 });
813 let (resolved, table) = match found {
814 Ok(found) => found,
815 Err(missing) => {
816 return self.bind_replacement_scan(ast, &parts, alias, columns, missing);
817 }
818 };
819 let fields: Vec<Field> = table.columns().to_vec();
820 let label =
821 if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
822 let index = self.fresh_index();
823 let mut scope = Scope::empty();
824 for (at, field) in fields.iter().enumerate() {
825 scope.push(Visible {
826 table: label.clone(),
827 name: field.name.clone(),
828 binding: ColumnBinding::new(index, at as u32),
829 ty: field.ty.clone(),
830 });
831 }
832 if !columns.is_empty() {
833 let names: Vec<&str> = ast.name(columns).collect();
834 scope.rename(&names, &label)?;
835 }
836 let catalog_name = self.plan.intern(&resolved.catalog);
837 let schema = self.plan.intern(&resolved.schema);
838 let table_name = self.plan.intern(&resolved.table);
839 let alias = self.plan.intern(&label);
840 let columns = self.plan.add_fields(&fields);
841 let node = self.plan.add_node(Node::Get {
842 catalog: catalog_name,
843 schema,
844 table: table_name,
845 alias,
846 index,
847 columns,
848 });
849 Ok((node, scope))
850 }
851
852 fn bind_table_function(
860 &mut self,
861 ast: &Ast,
862 name: ast::Slice,
863 args: ast::Slice,
864 alias: ast::StrRef,
865 columns: ast::Slice,
866 ) -> Result<(NodeRef, Scope)> {
867 let parts: Vec<&str> = ast.name(name).collect();
868 let function_name = *parts.last().unwrap_or(&"");
872 if let Some(schema) = parts.iter().rev().nth(1) {
873 if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
874 return Err(Error::catalog(format!(
875 "Table Function with name {} does not exist!",
876 parts.join(".")
877 )));
878 }
879 }
880 if TableFunction::lookup(function_name).is_none() {
884 return Err(Error::catalog(format!(
885 "Table Function with name {function_name} does not exist!"
886 )));
887 }
888 let written = ast.expr_list(args).to_vec();
889 let empty = Scope::empty();
890 let previous = std::mem::replace(&mut self.clause, "table function arguments");
891 let mut bound = Vec::with_capacity(written.len());
892 for expr in written {
893 bound.push(self.bind_expr(ast, expr, &empty)?);
894 }
895 self.clause = previous;
896
897 let given: Vec<LogicalType> =
900 bound.iter().map(|&expr| self.plan.expr_type(expr).clone()).collect();
901 let resolved = resolve_table(function_name, &given)?;
902 let cast: Vec<ExprRef> = bound
903 .iter()
904 .zip(&resolved.arguments)
905 .map(|(&expr, ty)| self.cast_to(expr, ty))
906 .collect();
907
908 let fields = match resolved.columns {
909 Columns::Fixed(fields) => fields,
910 Columns::Parquet => parquet_fields(&self.file_argument(cast[0])?)?,
911 };
912 let label = if alias == NONE {
913 resolved.function.name().to_string()
914 } else {
915 ast.string(alias).to_string()
916 };
917 let names: Vec<&str> = ast.name(columns).collect();
918 self.table_function_source(resolved.function, &cast, fields, &label, &names)
919 }
920
921 fn bind_replacement_scan(
932 &mut self,
933 ast: &Ast,
934 parts: &[&str],
935 alias: ast::StrRef,
936 columns: ast::Slice,
937 missing: Error,
938 ) -> Result<(NodeRef, Scope)> {
939 let [path] = parts else { return Err(missing) };
940 let path = *path;
941 let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
942 if !extension.eq_ignore_ascii_case("parquet") {
943 return Err(missing);
944 }
945 let fields = parquet_fields(path)?;
946 let label = if alias == NONE {
950 let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
951 file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
952 } else {
953 ast.string(alias).to_string()
954 };
955 let value = self.plan.add_value(Value::Varchar(path.to_string()));
956 let argument = self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar);
957 let names: Vec<&str> = ast.name(columns).collect();
958 self.table_function_source(TableFunction::ReadParquet, &[argument], fields, &label, &names)
959 }
960
961 fn table_function_source(
966 &mut self,
967 function: TableFunction,
968 args: &[ExprRef],
969 fields: Vec<Field>,
970 label: &str,
971 names: &[&str],
972 ) -> Result<(NodeRef, Scope)> {
973 let index = self.fresh_index();
974 let mut scope = Scope::empty();
975 for (at, field) in fields.iter().enumerate() {
976 scope.push(Visible {
977 table: label.to_string(),
978 name: field.name.clone(),
979 binding: ColumnBinding::new(index, at as u32),
980 ty: field.ty.clone(),
981 });
982 }
983 if !names.is_empty() {
984 scope.rename(names, label)?;
985 }
986 let function = self.plan.intern(function.name());
987 let args = self.plan.add_expr_list(args);
988 let columns = self.plan.add_fields(&fields);
989 let node = self.plan.add_node(Node::TableFunction { index, function, args, columns });
990 Ok((node, scope))
991 }
992
993 fn file_argument(&self, expr: ExprRef) -> Result<String> {
1002 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1003 return Err(Error::not_implemented(
1004 "a table function file name that is not a constant",
1005 ));
1006 };
1007 match self.plan.value(reference) {
1008 Value::Varchar(path) => Ok(path.clone()),
1009 Value::Null => Err(Error::parser("read_parquet cannot take NULL list as parameter")),
1011 other => {
1012 Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
1013 }
1014 }
1015 }
1016
1017 #[allow(clippy::too_many_arguments)]
1018 fn bind_join(
1019 &mut self,
1020 ast: &Ast,
1021 left: ast::SourceRef,
1022 right: ast::SourceRef,
1023 kind: ast::JoinKind,
1024 natural: bool,
1025 on: ast::ExprRef,
1026 using: ast::Slice,
1027 ) -> Result<(NodeRef, Scope)> {
1028 let (left_node, left_scope) = self.bind_source(ast, left)?;
1029 let (right_node, right_scope) = self.bind_source(ast, right)?;
1030 let split = left_scope.len();
1031 let mut scope = left_scope.concat(right_scope);
1032
1033 let merged: Vec<String> = if natural {
1036 let mut names = Vec::new();
1037 for (at, column) in scope.columns.iter().enumerate().take(split) {
1038 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
1039 && !names.iter().any(|held: &String| same_name(held, &column.name))
1040 {
1041 let _ = at;
1042 names.push(column.name.clone());
1043 }
1044 }
1045 names
1046 } else {
1047 ast.name(using).map(str::to_string).collect()
1048 };
1049
1050 let mut conditions = Vec::new();
1051 let mut dropped = Vec::new();
1052 for name in &merged {
1053 let left_at = scope.columns[..split]
1054 .iter()
1055 .position(|column| same_name(&column.name, name))
1056 .ok_or_else(|| {
1057 Error::binder(format!(
1058 "column \"{name}\" specified in USING clause does not exist in left table"
1059 ))
1060 })?;
1061 let right_at = scope.columns[split..]
1062 .iter()
1063 .position(|column| same_name(&column.name, name))
1064 .map(|at| at + split)
1065 .ok_or_else(|| {
1066 Error::binder(format!(
1067 "column \"{name}\" specified in USING clause does not exist in right table"
1068 ))
1069 })?;
1070 let left_column = &scope.columns[left_at];
1071 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
1072 let right_column = &scope.columns[right_at];
1073 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
1074 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
1075 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
1076 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
1077 dropped.push(right_at);
1078 }
1079 dropped.sort_unstable();
1082 for at in dropped.into_iter().rev() {
1083 scope.remove(at);
1084 }
1085
1086 if on != NONE {
1087 if !merged.is_empty() {
1088 return Err(Error::binder("a join cannot have both ON and USING"));
1089 }
1090 self.clause = "JOIN condition";
1091 let predicate = self.bind_expr(ast, on, &scope)?;
1092 conditions.push(self.as_boolean(predicate, "JOIN")?);
1093 }
1094
1095 if kind == ast::JoinKind::Cross {
1096 if !conditions.is_empty() {
1097 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
1098 }
1099 let node =
1100 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1101 return Ok((node, scope));
1102 }
1103 if conditions.is_empty() && kind == ast::JoinKind::Inner {
1104 let node =
1105 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1106 return Ok((node, scope));
1107 }
1108 let kind = match kind {
1109 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
1110 ast::JoinKind::Left => JoinKind::Left,
1111 ast::JoinKind::Right => JoinKind::Right,
1112 ast::JoinKind::Full => JoinKind::Full,
1113 ast::JoinKind::Semi => JoinKind::Semi,
1114 ast::JoinKind::Anti => JoinKind::Anti,
1115 ast::JoinKind::Positional => JoinKind::Positional,
1116 };
1117 let conditions = self.plan.add_expr_list(&conditions);
1118 let node =
1119 self.plan.add_node(Node::Join { left: left_node, right: right_node, kind, conditions });
1120 Ok((node, scope))
1121 }
1122
1123 pub(crate) fn bind_aggregate(
1127 &mut self,
1128 ast: &Ast,
1129 name: &str,
1130 args: &[ast::ExprRef],
1131 distinct: bool,
1132 scope: &Scope,
1133 ) -> Result<ExprRef> {
1134 if self.in_aggregate {
1135 return Err(Error::binder(format!(
1136 "aggregate function calls cannot be nested, and {name}() is inside one"
1137 )));
1138 }
1139 if self.aggregation.is_none() {
1140 return Err(Error::binder(format!(
1141 "aggregate function calls cannot be used in the {}",
1142 self.clause
1143 )));
1144 }
1145 self.in_aggregate = true;
1146 let mut bound = Vec::with_capacity(args.len());
1147 let mut failure = None;
1148 for &arg in args {
1149 match self.bind_expr(ast, arg, scope) {
1150 Ok(expr) => bound.push(expr),
1151 Err(error) => {
1152 failure = Some(error);
1153 break;
1154 }
1155 }
1156 }
1157 self.in_aggregate = false;
1158 if let Some(error) = failure {
1159 return Err(error);
1160 }
1161
1162 let types: Vec<LogicalType> =
1163 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
1164 let resolved = resolve(name, &types)?;
1165 let mut cast = Vec::with_capacity(bound.len());
1166 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
1167 cast.push(self.cast_to(*arg, wanted));
1168 }
1169 let args = self.plan.add_expr_list(&cast);
1170 let name = self.plan.intern(resolved.name);
1171 let ty = resolved.returns;
1172 let call =
1173 self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter: None }, ty.clone());
1174
1175 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
1178 let existing = existing.unwrap_or_default();
1179 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
1180 Some(at) => at,
1181 None => {
1182 let aggregation = self.aggregation.as_mut().expect("checked above");
1183 aggregation.aggregates.push(call);
1184 aggregation.aggregates.len() - 1
1185 }
1186 };
1187 let aggregation = self.aggregation.as_ref().expect("checked above");
1188 let (index, groups) = (aggregation.index, aggregation.groups.len());
1189 Ok(self.column(index, groups + at, ty))
1190 }
1191
1192 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
1198 let Some(aggregation) = self.aggregation.as_ref() else {
1199 return Ok(expr);
1200 };
1201 let index = aggregation.index;
1202 let groups = aggregation.groups.clone();
1203 for (at, group) in groups.iter().enumerate() {
1204 if self.same_expr(expr, *group) {
1205 let ty = self.plan.expr_type(*group).clone();
1206 return Ok(self.column(index, at, ty));
1207 }
1208 }
1209 let ty = self.plan.expr_type(expr).clone();
1210 match self.plan.expr(expr).clone() {
1211 Expr::Column(binding) if binding.table == index => Ok(expr),
1212 Expr::Column(binding) => {
1213 let name =
1214 scope.columns.iter().find(|column| column.binding == binding).map_or_else(
1215 || "a column".to_string(),
1216 |column| format!("\"{}\"", column.name),
1217 );
1218 Err(Error::binder(format!(
1219 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
1220 )))
1221 }
1222 Expr::Constant(_) | Expr::Aggregate { .. } => Ok(expr),
1223 Expr::Cast { input, try_cast } => {
1224 let input = self.over_aggregate(input, scope)?;
1225 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
1226 }
1227 Expr::Compare { op, left, right } => {
1228 let left = self.over_aggregate(left, scope)?;
1229 let right = self.over_aggregate(right, scope)?;
1230 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
1231 }
1232 Expr::Conjunction { op, children } => {
1233 let written = self.plan.expr_list(children).to_vec();
1234 let mut rewritten = Vec::with_capacity(written.len());
1235 for child in written {
1236 rewritten.push(self.over_aggregate(child, scope)?);
1237 }
1238 let children = self.plan.add_expr_list(&rewritten);
1239 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
1240 }
1241 Expr::Function { name, args } => {
1242 let written = self.plan.expr_list(args).to_vec();
1243 let mut rewritten = Vec::with_capacity(written.len());
1244 for arg in written {
1245 rewritten.push(self.over_aggregate(arg, scope)?);
1246 }
1247 let args = self.plan.add_expr_list(&rewritten);
1248 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
1249 }
1250 Expr::Case { arms, otherwise } => {
1251 let written = self.plan.arm_list(arms).to_vec();
1252 let mut rewritten = Vec::with_capacity(written.len());
1253 for arm in written {
1254 let when = self.over_aggregate(arm.when, scope)?;
1255 let then = self.over_aggregate(arm.then, scope)?;
1256 rewritten.push(rudb_plan::Arm { when, then });
1257 }
1258 let otherwise = match otherwise {
1259 Some(expr) => Some(self.over_aggregate(expr, scope)?),
1260 None => None,
1261 };
1262 let arms = self.plan.add_arms(&rewritten);
1263 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
1264 }
1265 }
1266 }
1267
1268 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
1270 same_expr(&self.plan, left, right)
1271 }
1272}
1273
1274fn sort_key(expr: ExprRef, item: ast::OrderItem) -> SortKey {
1280 let descending = item.order == Order::Descending;
1281 let nulls_first = match item.nulls {
1282 Nulls::First => true,
1283 Nulls::Last => false,
1284 Nulls::Unstated => descending,
1285 };
1286 SortKey { expr, descending, nulls_first }
1287}
1288
1289fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
1291 if left == right {
1292 return true;
1293 }
1294 if plan.expr_type(left) != plan.expr_type(right) {
1295 return false;
1296 }
1297 let lists = |left, right| {
1298 let left: &[ExprRef] = plan.expr_list(left);
1299 let right: &[ExprRef] = plan.expr_list(right);
1300 left.len() == right.len()
1301 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
1302 };
1303 match (plan.expr(left), plan.expr(right)) {
1304 (Expr::Column(left), Expr::Column(right)) => left == right,
1305 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
1306 (
1307 Expr::Cast { input: left, try_cast: left_try },
1308 Expr::Cast { input: right, try_cast: right_try },
1309 ) => left_try == right_try && same_expr(plan, *left, *right),
1310 (
1311 Expr::Compare { op: left_op, left: left_a, right: left_b },
1312 Expr::Compare { op: right_op, left: right_a, right: right_b },
1313 ) => {
1314 left_op == right_op
1315 && same_expr(plan, *left_a, *right_a)
1316 && same_expr(plan, *left_b, *right_b)
1317 }
1318 (
1319 Expr::Conjunction { op: left_op, children: left_children },
1320 Expr::Conjunction { op: right_op, children: right_children },
1321 ) => left_op == right_op && lists(*left_children, *right_children),
1322 (
1323 Expr::Function { name: left_name, args: left_args },
1324 Expr::Function { name: right_name, args: right_args },
1325 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
1326 (
1327 Expr::Aggregate {
1328 name: left_name,
1329 args: left_args,
1330 distinct: left_distinct,
1331 filter: left_filter,
1332 },
1333 Expr::Aggregate {
1334 name: right_name,
1335 args: right_args,
1336 distinct: right_distinct,
1337 filter: right_filter,
1338 },
1339 ) => {
1340 plan.string(*left_name) == plan.string(*right_name)
1341 && left_distinct == right_distinct
1342 && match (left_filter, right_filter) {
1343 (None, None) => true,
1344 (Some(left), Some(right)) => same_expr(plan, *left, *right),
1345 _ => false,
1346 }
1347 && lists(*left_args, *right_args)
1348 }
1349 (
1350 Expr::Case { arms: left_arms, otherwise: left_otherwise },
1351 Expr::Case { arms: right_arms, otherwise: right_otherwise },
1352 ) => {
1353 let left_arms = plan.arm_list(*left_arms);
1354 let right_arms = plan.arm_list(*right_arms);
1355 left_arms.len() == right_arms.len()
1356 && left_arms.iter().zip(right_arms).all(|(left, right)| {
1357 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
1358 })
1359 && match (left_otherwise, right_otherwise) {
1360 (None, None) => true,
1361 (Some(left), Some(right)) => same_expr(plan, *left, *right),
1362 _ => false,
1363 }
1364 }
1365 _ => false,
1366 }
1367}