1use rudb_catalog::{Catalog, same_name};
16use rudb_common::{Error, Field, LogicalType, Result, Value};
17use rudb_functions::{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 resolved = catalog.resolve(&parts)?;
808 let table = catalog.table(&resolved)?;
809 let fields: Vec<Field> = table.columns().to_vec();
810 let label =
811 if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
812 let index = self.fresh_index();
813 let mut scope = Scope::empty();
814 for (at, field) in fields.iter().enumerate() {
815 scope.push(Visible {
816 table: label.clone(),
817 name: field.name.clone(),
818 binding: ColumnBinding::new(index, at as u32),
819 ty: field.ty.clone(),
820 });
821 }
822 if !columns.is_empty() {
823 let names: Vec<&str> = ast.name(columns).collect();
824 scope.rename(&names, &label)?;
825 }
826 let catalog_name = self.plan.intern(&resolved.catalog);
827 let schema = self.plan.intern(&resolved.schema);
828 let table_name = self.plan.intern(&resolved.table);
829 let alias = self.plan.intern(&label);
830 let columns = self.plan.add_fields(&fields);
831 let node = self.plan.add_node(Node::Get {
832 catalog: catalog_name,
833 schema,
834 table: table_name,
835 alias,
836 index,
837 columns,
838 });
839 Ok((node, scope))
840 }
841
842 fn bind_table_function(
850 &mut self,
851 ast: &Ast,
852 name: ast::Slice,
853 args: ast::Slice,
854 alias: ast::StrRef,
855 columns: ast::Slice,
856 ) -> Result<(NodeRef, Scope)> {
857 let parts: Vec<&str> = ast.name(name).collect();
858 let function_name = *parts.last().unwrap_or(&"");
862 if let Some(schema) = parts.iter().rev().nth(1) {
863 if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
864 return Err(Error::catalog(format!(
865 "Table Function with name {} does not exist!",
866 parts.join(".")
867 )));
868 }
869 }
870 let written = ast.expr_list(args).to_vec();
871 let resolved = resolve_table(function_name, written.len())?;
872
873 let empty = Scope::empty();
874 let previous = std::mem::replace(&mut self.clause, "table function arguments");
875 let mut bound = Vec::with_capacity(written.len());
876 for expr in written {
877 bound.push(self.bind_expr(ast, expr, &empty)?);
878 }
879 self.clause = previous;
880 let cast: Vec<ExprRef> = bound
881 .iter()
882 .zip(&resolved.arguments)
883 .map(|(&expr, ty)| self.cast_to(expr, ty))
884 .collect();
885
886 let label = if alias == NONE {
887 resolved.function.name().to_string()
888 } else {
889 ast.string(alias).to_string()
890 };
891 let index = self.fresh_index();
892 let mut scope = Scope::empty();
893 for (at, field) in resolved.columns.iter().enumerate() {
894 scope.push(Visible {
895 table: label.clone(),
896 name: field.name.clone(),
897 binding: ColumnBinding::new(index, at as u32),
898 ty: field.ty.clone(),
899 });
900 }
901 if !columns.is_empty() {
902 let names: Vec<&str> = ast.name(columns).collect();
903 scope.rename(&names, &label)?;
904 }
905 let function = self.plan.intern(resolved.function.name());
906 let args = self.plan.add_expr_list(&cast);
907 let fields = self.plan.add_fields(&resolved.columns);
908 let node =
909 self.plan.add_node(Node::TableFunction { index, function, args, columns: fields });
910 Ok((node, scope))
911 }
912
913 #[allow(clippy::too_many_arguments)]
914 fn bind_join(
915 &mut self,
916 ast: &Ast,
917 left: ast::SourceRef,
918 right: ast::SourceRef,
919 kind: ast::JoinKind,
920 natural: bool,
921 on: ast::ExprRef,
922 using: ast::Slice,
923 ) -> Result<(NodeRef, Scope)> {
924 let (left_node, left_scope) = self.bind_source(ast, left)?;
925 let (right_node, right_scope) = self.bind_source(ast, right)?;
926 let split = left_scope.len();
927 let mut scope = left_scope.concat(right_scope);
928
929 let merged: Vec<String> = if natural {
932 let mut names = Vec::new();
933 for (at, column) in scope.columns.iter().enumerate().take(split) {
934 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
935 && !names.iter().any(|held: &String| same_name(held, &column.name))
936 {
937 let _ = at;
938 names.push(column.name.clone());
939 }
940 }
941 names
942 } else {
943 ast.name(using).map(str::to_string).collect()
944 };
945
946 let mut conditions = Vec::new();
947 let mut dropped = Vec::new();
948 for name in &merged {
949 let left_at = scope.columns[..split]
950 .iter()
951 .position(|column| same_name(&column.name, name))
952 .ok_or_else(|| {
953 Error::binder(format!(
954 "column \"{name}\" specified in USING clause does not exist in left table"
955 ))
956 })?;
957 let right_at = scope.columns[split..]
958 .iter()
959 .position(|column| same_name(&column.name, name))
960 .map(|at| at + split)
961 .ok_or_else(|| {
962 Error::binder(format!(
963 "column \"{name}\" specified in USING clause does not exist in right table"
964 ))
965 })?;
966 let left_column = &scope.columns[left_at];
967 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
968 let right_column = &scope.columns[right_at];
969 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
970 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
971 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
972 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
973 dropped.push(right_at);
974 }
975 dropped.sort_unstable();
978 for at in dropped.into_iter().rev() {
979 scope.remove(at);
980 }
981
982 if on != NONE {
983 if !merged.is_empty() {
984 return Err(Error::binder("a join cannot have both ON and USING"));
985 }
986 self.clause = "JOIN condition";
987 let predicate = self.bind_expr(ast, on, &scope)?;
988 conditions.push(self.as_boolean(predicate, "JOIN")?);
989 }
990
991 if kind == ast::JoinKind::Cross {
992 if !conditions.is_empty() {
993 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
994 }
995 let node =
996 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
997 return Ok((node, scope));
998 }
999 if conditions.is_empty() && kind == ast::JoinKind::Inner {
1000 let node =
1001 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1002 return Ok((node, scope));
1003 }
1004 let kind = match kind {
1005 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
1006 ast::JoinKind::Left => JoinKind::Left,
1007 ast::JoinKind::Right => JoinKind::Right,
1008 ast::JoinKind::Full => JoinKind::Full,
1009 ast::JoinKind::Semi => JoinKind::Semi,
1010 ast::JoinKind::Anti => JoinKind::Anti,
1011 ast::JoinKind::Positional => JoinKind::Positional,
1012 };
1013 let conditions = self.plan.add_expr_list(&conditions);
1014 let node =
1015 self.plan.add_node(Node::Join { left: left_node, right: right_node, kind, conditions });
1016 Ok((node, scope))
1017 }
1018
1019 pub(crate) fn bind_aggregate(
1023 &mut self,
1024 ast: &Ast,
1025 name: &str,
1026 args: &[ast::ExprRef],
1027 distinct: bool,
1028 scope: &Scope,
1029 ) -> Result<ExprRef> {
1030 if self.in_aggregate {
1031 return Err(Error::binder(format!(
1032 "aggregate function calls cannot be nested, and {name}() is inside one"
1033 )));
1034 }
1035 if self.aggregation.is_none() {
1036 return Err(Error::binder(format!(
1037 "aggregate function calls cannot be used in the {}",
1038 self.clause
1039 )));
1040 }
1041 self.in_aggregate = true;
1042 let mut bound = Vec::with_capacity(args.len());
1043 let mut failure = None;
1044 for &arg in args {
1045 match self.bind_expr(ast, arg, scope) {
1046 Ok(expr) => bound.push(expr),
1047 Err(error) => {
1048 failure = Some(error);
1049 break;
1050 }
1051 }
1052 }
1053 self.in_aggregate = false;
1054 if let Some(error) = failure {
1055 return Err(error);
1056 }
1057
1058 let types: Vec<LogicalType> =
1059 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
1060 let resolved = resolve(name, &types)?;
1061 let mut cast = Vec::with_capacity(bound.len());
1062 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
1063 cast.push(self.cast_to(*arg, wanted));
1064 }
1065 let args = self.plan.add_expr_list(&cast);
1066 let name = self.plan.intern(resolved.name);
1067 let ty = resolved.returns;
1068 let call =
1069 self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter: None }, ty.clone());
1070
1071 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
1074 let existing = existing.unwrap_or_default();
1075 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
1076 Some(at) => at,
1077 None => {
1078 let aggregation = self.aggregation.as_mut().expect("checked above");
1079 aggregation.aggregates.push(call);
1080 aggregation.aggregates.len() - 1
1081 }
1082 };
1083 let aggregation = self.aggregation.as_ref().expect("checked above");
1084 let (index, groups) = (aggregation.index, aggregation.groups.len());
1085 Ok(self.column(index, groups + at, ty))
1086 }
1087
1088 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
1094 let Some(aggregation) = self.aggregation.as_ref() else {
1095 return Ok(expr);
1096 };
1097 let index = aggregation.index;
1098 let groups = aggregation.groups.clone();
1099 for (at, group) in groups.iter().enumerate() {
1100 if self.same_expr(expr, *group) {
1101 let ty = self.plan.expr_type(*group).clone();
1102 return Ok(self.column(index, at, ty));
1103 }
1104 }
1105 let ty = self.plan.expr_type(expr).clone();
1106 match self.plan.expr(expr).clone() {
1107 Expr::Column(binding) if binding.table == index => Ok(expr),
1108 Expr::Column(binding) => {
1109 let name =
1110 scope.columns.iter().find(|column| column.binding == binding).map_or_else(
1111 || "a column".to_string(),
1112 |column| format!("\"{}\"", column.name),
1113 );
1114 Err(Error::binder(format!(
1115 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
1116 )))
1117 }
1118 Expr::Constant(_) | Expr::Aggregate { .. } => Ok(expr),
1119 Expr::Cast { input, try_cast } => {
1120 let input = self.over_aggregate(input, scope)?;
1121 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
1122 }
1123 Expr::Compare { op, left, right } => {
1124 let left = self.over_aggregate(left, scope)?;
1125 let right = self.over_aggregate(right, scope)?;
1126 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
1127 }
1128 Expr::Conjunction { op, children } => {
1129 let written = self.plan.expr_list(children).to_vec();
1130 let mut rewritten = Vec::with_capacity(written.len());
1131 for child in written {
1132 rewritten.push(self.over_aggregate(child, scope)?);
1133 }
1134 let children = self.plan.add_expr_list(&rewritten);
1135 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
1136 }
1137 Expr::Function { name, args } => {
1138 let written = self.plan.expr_list(args).to_vec();
1139 let mut rewritten = Vec::with_capacity(written.len());
1140 for arg in written {
1141 rewritten.push(self.over_aggregate(arg, scope)?);
1142 }
1143 let args = self.plan.add_expr_list(&rewritten);
1144 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
1145 }
1146 Expr::Case { arms, otherwise } => {
1147 let written = self.plan.arm_list(arms).to_vec();
1148 let mut rewritten = Vec::with_capacity(written.len());
1149 for arm in written {
1150 let when = self.over_aggregate(arm.when, scope)?;
1151 let then = self.over_aggregate(arm.then, scope)?;
1152 rewritten.push(rudb_plan::Arm { when, then });
1153 }
1154 let otherwise = match otherwise {
1155 Some(expr) => Some(self.over_aggregate(expr, scope)?),
1156 None => None,
1157 };
1158 let arms = self.plan.add_arms(&rewritten);
1159 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
1160 }
1161 }
1162 }
1163
1164 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
1166 same_expr(&self.plan, left, right)
1167 }
1168}
1169
1170fn sort_key(expr: ExprRef, item: ast::OrderItem) -> SortKey {
1176 let descending = item.order == Order::Descending;
1177 let nulls_first = match item.nulls {
1178 Nulls::First => true,
1179 Nulls::Last => false,
1180 Nulls::Unstated => descending,
1181 };
1182 SortKey { expr, descending, nulls_first }
1183}
1184
1185fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
1187 if left == right {
1188 return true;
1189 }
1190 if plan.expr_type(left) != plan.expr_type(right) {
1191 return false;
1192 }
1193 let lists = |left, right| {
1194 let left: &[ExprRef] = plan.expr_list(left);
1195 let right: &[ExprRef] = plan.expr_list(right);
1196 left.len() == right.len()
1197 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
1198 };
1199 match (plan.expr(left), plan.expr(right)) {
1200 (Expr::Column(left), Expr::Column(right)) => left == right,
1201 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
1202 (
1203 Expr::Cast { input: left, try_cast: left_try },
1204 Expr::Cast { input: right, try_cast: right_try },
1205 ) => left_try == right_try && same_expr(plan, *left, *right),
1206 (
1207 Expr::Compare { op: left_op, left: left_a, right: left_b },
1208 Expr::Compare { op: right_op, left: right_a, right: right_b },
1209 ) => {
1210 left_op == right_op
1211 && same_expr(plan, *left_a, *right_a)
1212 && same_expr(plan, *left_b, *right_b)
1213 }
1214 (
1215 Expr::Conjunction { op: left_op, children: left_children },
1216 Expr::Conjunction { op: right_op, children: right_children },
1217 ) => left_op == right_op && lists(*left_children, *right_children),
1218 (
1219 Expr::Function { name: left_name, args: left_args },
1220 Expr::Function { name: right_name, args: right_args },
1221 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
1222 (
1223 Expr::Aggregate {
1224 name: left_name,
1225 args: left_args,
1226 distinct: left_distinct,
1227 filter: left_filter,
1228 },
1229 Expr::Aggregate {
1230 name: right_name,
1231 args: right_args,
1232 distinct: right_distinct,
1233 filter: right_filter,
1234 },
1235 ) => {
1236 plan.string(*left_name) == plan.string(*right_name)
1237 && left_distinct == right_distinct
1238 && match (left_filter, right_filter) {
1239 (None, None) => true,
1240 (Some(left), Some(right)) => same_expr(plan, *left, *right),
1241 _ => false,
1242 }
1243 && lists(*left_args, *right_args)
1244 }
1245 (
1246 Expr::Case { arms: left_arms, otherwise: left_otherwise },
1247 Expr::Case { arms: right_arms, otherwise: right_otherwise },
1248 ) => {
1249 let left_arms = plan.arm_list(*left_arms);
1250 let right_arms = plan.arm_list(*right_arms);
1251 left_arms.len() == right_arms.len()
1252 && left_arms.iter().zip(right_arms).all(|(left, right)| {
1253 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
1254 })
1255 && match (left_otherwise, right_otherwise) {
1256 (None, None) => true,
1257 (Some(left), Some(right)) => same_expr(plan, *left, *right),
1258 _ => false,
1259 }
1260 }
1261 _ => false,
1262 }
1263}