1use rudb_catalog::{Catalog, Entry, QualifiedName, same_name};
16use rudb_common::{Error, Field, LogicalType, Result, Session, Value};
17use rudb_functions::{
18 Columns, FILE_ROW_NUMBER, Given, TableFunction, csv_fields, csv_given, files, is_file,
19 is_pattern, parquet_fields, resolve, resolve_table,
20};
21use rudb_parse::ast::{self, Ast, Distinct, LiteralKind, Nulls, Order, Quantifier, SetOp};
22use rudb_parse::{NONE, identifier_parts, 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(), &Session::new())
37}
38
39pub fn bind_with(
48 ast: &Ast,
49 catalog: &Catalog,
50 parameters: &Parameters,
51 session: &Session,
52) -> Result<Plan> {
53 let query = match ast.statements.as_slice() {
54 [ast::Statement::Query(query)] => *query,
55 [] => return Err(Error::binder("no statement to bind")),
56 [_] => return Err(Error::not_implemented("a statement that is not a query")),
59 _ => return Err(Error::not_implemented("a script of more than one statement")),
60 };
61 let mut binder = Binder::with(catalog, parameters, session);
62 let (root, _) = binder.bind_query(ast, query)?;
63 let mut plan = binder.into_plan();
64 plan.set_root(root);
65 plan.validate()?;
66 Ok(plan)
67}
68
69pub fn bind_sql(query: &str, catalog: &Catalog) -> Result<Plan> {
75 bind_sql_with(query, catalog, &Session::new())
76}
77
78pub fn bind_sql_with(query: &str, catalog: &Catalog, session: &Session) -> Result<Plan> {
84 let ast = parse_ast(query)?;
85 bind_with(&ast, catalog, &Parameters::new(), session)
86}
87
88#[derive(Debug)]
90pub(crate) struct Aggregation {
91 pub(crate) index: u32,
93 pub(crate) groups: Vec<ExprRef>,
95 pub(crate) aggregates: Vec<ExprRef>,
97}
98
99#[derive(Debug)]
101pub(crate) struct Binder<'a> {
102 catalog: &'a Catalog,
103 pub(crate) parameters: &'a Parameters,
105 pub(crate) session: &'a Session,
107 plan: Plan,
108 next_index: u32,
109 pub(crate) aggregation: Option<Aggregation>,
111 pub(crate) in_aggregate: bool,
113 pub(crate) clause: &'static str,
115 expanding: Vec<String>,
117 started: Option<i64>,
119}
120
121impl<'a> Binder<'a> {
122 pub(crate) fn with(
123 catalog: &'a Catalog,
124 parameters: &'a Parameters,
125 session: &'a Session,
126 ) -> Self {
127 Self {
128 catalog,
129 parameters,
130 session,
131 plan: Plan::new(),
132 next_index: 0,
133 aggregation: None,
134 in_aggregate: false,
135 clause: "SELECT clause",
136 expanding: Vec::new(),
137 started: None,
138 }
139 }
140
141 pub(crate) fn catalog(&self) -> &Catalog {
142 self.catalog
143 }
144
145 pub(crate) fn instant(&mut self) -> i64 {
152 *self.started.get_or_insert_with(crate::context::micros_now)
153 }
154
155 pub(crate) fn plan(&self) -> &Plan {
156 &self.plan
157 }
158
159 pub(crate) fn plan_mut(&mut self) -> &mut Plan {
160 &mut self.plan
161 }
162
163 pub(crate) fn into_plan(self) -> Plan {
164 self.plan
165 }
166
167 pub(crate) fn fresh_index(&mut self) -> u32 {
169 let index = self.next_index;
170 self.next_index += 1;
171 index
172 }
173
174 fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
176 let binding = ColumnBinding::new(index, position as u32);
177 self.plan.add_expr(Expr::Column(binding), ty)
178 }
179
180 pub(crate) fn bind_query(
183 &mut self,
184 ast: &Ast,
185 query: ast::QueryRef,
186 ) -> Result<(NodeRef, Scope)> {
187 let written = ast.query(query);
188 match written.body {
189 ast::QueryBody::Select(select) => self.bind_select(ast, select, &written),
190 ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
191 if by_name {
192 return Err(Error::not_implemented("UNION BY NAME"));
193 }
194 self.bind_set_op(ast, &written, op, quantifier, left, right)
195 }
196 ast::QueryBody::Values(rows) => self.bind_values(ast, &written, rows),
197 ast::QueryBody::Describe(inner) => self.bind_describe(ast, &written, inner),
198 }
199 }
200
201 fn bind_describe(
217 &mut self,
218 ast: &Ast,
219 query: &ast::Query,
220 inner: ast::QueryRef,
221 ) -> Result<(NodeRef, Scope)> {
222 let (_, described) = self.bind_query(ast, inner)?;
223 let fields: Vec<Field> = ["column_name", "column_type", "null", "key", "default", "extra"]
224 .iter()
225 .map(|name| Field::new(*name, LogicalType::Varchar))
226 .collect();
227 let mut slices = Vec::with_capacity(described.columns.len());
228 for column in described.columns.clone() {
229 let written = [
232 column.name.clone(),
233 column.ty.to_string(),
234 if column.not_null { "NO" } else { "YES" }.to_owned(),
235 ];
236 let mut items: Vec<ExprRef> = written
237 .into_iter()
238 .map(|text| self.plan.add_constant(Value::Varchar(text)))
239 .collect();
240 for _ in 0..3 {
241 let empty = self.plan.add_constant(Value::Null);
242 items.push(self.cast_to(empty, &LogicalType::Varchar));
243 }
244 slices.push(self.plan.add_expr_list(&items));
245 }
246 let rows = self.plan.add_rows(&slices);
247 let columns = self.plan.add_fields(&fields);
248 let index = self.fresh_index();
249 let mut node = self.plan.add_node(Node::Values { index, columns, rows });
250 let mut scope = Scope::empty();
251 for (at, field) in fields.iter().enumerate() {
252 scope.push(Visible {
253 table: String::new(),
254 name: field.name.clone(),
255 binding: ColumnBinding::new(index, at as u32),
256 ty: field.ty.clone(),
257 not_null: false,
258 });
259 }
260 let keys = self.sort_keys(ast, query, &scope, &[])?;
261 if !keys.is_empty() {
262 let keys = self.plan.add_sort_keys(&keys);
263 node = self.plan.add_node(Node::Sort { input: node, keys });
264 }
265 node = self.apply_limit(ast, query, node)?;
266 Ok((node, scope))
267 }
268
269 fn passes_through(&self, expr: ExprRef, input: &Scope) -> bool {
275 let Expr::Column(binding) = *self.plan.expr(expr) else { return false };
276 input.columns.iter().any(|column| column.binding == binding && column.not_null)
277 }
278
279 fn bind_values(
286 &mut self,
287 ast: &Ast,
288 query: &ast::Query,
289 rows: ast::Slice,
290 ) -> Result<(NodeRef, Scope)> {
291 let written = ast.rows(rows).to_vec();
292 let Some(first) = written.first() else {
293 return Err(Error::binder("VALUES needs at least one row"));
294 };
295 let width = first.len as usize;
296 for (at, row) in written.iter().enumerate() {
297 if row.len as usize != width {
298 return Err(Error::binder(format!(
299 "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
300 at + 1,
301 row.len
302 )));
303 }
304 }
305 let empty = Scope::empty();
307 let previous = std::mem::replace(&mut self.clause, "VALUES clause");
308 let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
309 for row in &written {
310 let mut items = Vec::with_capacity(width);
311 for &expr in ast.expr_list(*row) {
312 items.push(self.bind_expr(ast, expr, &empty)?);
313 }
314 bound.push(items);
315 }
316 self.clause = previous;
317 let mut types = Vec::with_capacity(width);
318 for at in 0..width {
319 let mut ty = self.plan.expr_type(bound[0][at]).clone();
320 for row in &bound[1..] {
321 let other = self.plan.expr_type(row[at]).clone();
322 ty = ty.promote(&other).ok_or_else(|| {
323 Error::binder(format!(
324 "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
325 at + 1
326 ))
327 })?;
328 }
329 types.push(ty);
330 }
331 let mut slices = Vec::with_capacity(bound.len());
332 for row in &bound {
333 let items: Vec<ExprRef> =
334 row.iter().zip(&types).map(|(&expr, ty)| self.cast_to(expr, ty)).collect();
335 slices.push(self.plan.add_expr_list(&items));
336 }
337 let rows = self.plan.add_rows(&slices);
338 let fields: Vec<Field> = types
339 .iter()
340 .enumerate()
341 .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
342 .collect();
343 let columns = self.plan.add_fields(&fields);
344 let index = self.fresh_index();
345 let mut node = self.plan.add_node(Node::Values { index, columns, rows });
346 let mut scope = Scope::empty();
347 for (at, field) in fields.iter().enumerate() {
348 scope.push(Visible {
349 table: String::new(),
350 name: field.name.clone(),
351 binding: ColumnBinding::new(index, at as u32),
352 ty: field.ty.clone(),
353 not_null: false,
354 });
355 }
356 let keys = self.sort_keys(ast, query, &scope, &[])?;
357 if !keys.is_empty() {
358 let keys = self.plan.add_sort_keys(&keys);
359 node = self.plan.add_node(Node::Sort { input: node, keys });
360 }
361 node = self.apply_limit(ast, query, node)?;
362 Ok((node, scope))
363 }
364
365 fn bind_set_op(
366 &mut self,
367 ast: &Ast,
368 query: &ast::Query,
369 op: SetOp,
370 quantifier: Quantifier,
371 left: ast::QueryRef,
372 right: ast::QueryRef,
373 ) -> Result<(NodeRef, Scope)> {
374 let (left_node, left_scope) = self.bind_query(ast, left)?;
375 let (right_node, right_scope) = self.bind_query(ast, right)?;
376 if left_scope.len() != right_scope.len() {
377 return Err(Error::binder(format!(
378 "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
379 left_scope.len(),
380 right_scope.len()
381 )));
382 }
383 let mut types = Vec::with_capacity(left_scope.len());
385 for (left, right) in left_scope.columns.iter().zip(&right_scope.columns) {
386 let common = left.ty.promote(&right.ty).ok_or_else(|| {
387 Error::binder(format!(
388 "Cannot combine a column of type {} with a column of type {} in a set operation",
389 left.ty, right.ty
390 ))
391 })?;
392 types.push(common);
393 }
394 let left_node = self.conform(left_node, &left_scope, &types);
395 let right_node = self.conform(right_node, &right_scope, &types);
396 let index = self.fresh_index();
397 let kind = match op {
398 SetOp::Union => SetOpKind::Union,
399 SetOp::Except => SetOpKind::Except,
400 SetOp::Intersect => SetOpKind::Intersect,
401 };
402 let all = quantifier == Quantifier::All;
405 let mut node = self.plan.add_node(Node::SetOp {
406 left: left_node,
407 right: right_node,
408 kind,
409 all,
410 index,
411 });
412 let mut scope = Scope::empty();
413 for (at, (column, ty)) in left_scope.columns.iter().zip(&types).enumerate() {
414 scope.push(Visible {
415 table: String::new(),
416 name: column.name.clone(),
417 binding: ColumnBinding::new(index, at as u32),
418 ty: ty.clone(),
419 not_null: false,
422 });
423 }
424 let keys = self.sort_keys(ast, query, &scope, &[])?;
428 if !keys.is_empty() {
429 let keys = self.plan.add_sort_keys(&keys);
430 node = self.plan.add_node(Node::Sort { input: node, keys });
431 }
432 node = self.apply_limit(ast, query, node)?;
433 Ok((node, scope))
434 }
435
436 fn conform(&mut self, node: NodeRef, scope: &Scope, types: &[LogicalType]) -> NodeRef {
438 if scope.columns.iter().zip(types).all(|(column, ty)| &column.ty == ty) {
439 return node;
440 }
441 let index = self.fresh_index();
442 let mut exprs = Vec::with_capacity(types.len());
443 let mut names = Vec::with_capacity(types.len());
444 for (column, ty) in scope.columns.iter().zip(types) {
445 let expr = self.plan.add_expr(Expr::Column(column.binding), column.ty.clone());
446 exprs.push(self.cast_to(expr, ty));
447 names.push(self.plan.intern(&column.name));
448 }
449 let exprs = self.plan.add_expr_list(&exprs);
450 let names = self.plan.add_name_list(&names);
451 self.plan.add_node(Node::Project { input: node, index, exprs, names })
452 }
453
454 fn bind_select(
457 &mut self,
458 ast: &Ast,
459 select: ast::SelectRef,
460 query: &ast::Query,
461 ) -> Result<(NodeRef, Scope)> {
462 let written = ast.select(select);
463 let (mut node, input) = self.bind_from(ast, written.from)?;
464
465 if written.filter != NONE {
466 self.clause = "WHERE clause";
467 let predicate = self.bind_expr(ast, written.filter, &input)?;
468 let predicate = self.as_boolean(predicate, "WHERE")?;
469 node = self.plan.add_node(Node::Filter { input: node, predicate });
470 }
471
472 let targets = ast.target_list(written.targets).to_vec();
473 if targets.is_empty() {
474 return Err(Error::binder("a SELECT needs at least one expression to select"));
475 }
476
477 let group_items = self.group_items(ast, &written, &targets)?;
478 let aggregating = !group_items.is_empty()
479 || written.having != NONE
480 || targets.iter().any(|target| has_aggregate(ast, target.expr));
481 if aggregating {
482 self.clause = "GROUP BY clause";
483 let mut groups = Vec::with_capacity(group_items.len());
484 for item in &group_items {
485 groups.push(self.bind_expr(ast, *item, &input)?);
486 }
487 let index = self.fresh_index();
488 self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
489 }
490
491 self.clause = "SELECT clause";
492 let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input)?;
493 let visible = exprs.len();
494
495 let mut having = None;
496 if written.having != NONE {
497 self.clause = "HAVING clause";
498 let predicate = self.bind_expr(ast, written.having, &input)?;
499 let predicate = self.over_aggregate(predicate, &input)?;
500 having = Some(self.as_boolean(predicate, "HAVING")?);
501 }
502
503 let project = self.fresh_index();
506 let mut output = Scope::empty();
507 for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
508 output.push(Visible {
509 table: String::new(),
510 name: name.clone(),
511 binding: ColumnBinding::new(project, at as u32),
512 ty: self.plan.expr_type(*expr).clone(),
513 not_null: self.passes_through(*expr, &input),
514 });
515 }
516
517 self.clause = "ORDER BY clause";
518 let mut extra = Vec::new();
519 let keys = self.select_sort_keys(
520 ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra,
521 )?;
522 if !extra.is_empty() && written.distinct != Distinct::No {
523 return Err(Error::binder(
524 "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
525 ));
526 }
527 let on = self.distinct_on(ast, written.distinct, &output)?;
528
529 if let Some(aggregation) = self.aggregation.take() {
530 let index = aggregation.index;
531 let groups = self.plan.add_expr_list(&aggregation.groups);
532 let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
533 node = self.plan.add_node(Node::Aggregate { input: node, index, groups, aggregates });
534 }
535 if let Some(predicate) = having {
536 node = self.plan.add_node(Node::Filter { input: node, predicate });
537 }
538
539 let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
540 let exprs_slice = self.plan.add_expr_list(&exprs);
541 let names_slice = self.plan.add_name_list(&interned);
542 node = self.plan.add_node(Node::Project {
543 input: node,
544 index: project,
545 exprs: exprs_slice,
546 names: names_slice,
547 });
548
549 if written.distinct != Distinct::No {
550 let on = self.plan.add_expr_list(&on);
551 node = self.plan.add_node(Node::Distinct { input: node, on });
552 }
553 if !keys.is_empty() {
554 let keys = self.plan.add_sort_keys(&keys);
555 node = self.plan.add_node(Node::Sort { input: node, keys });
556 }
557 node = self.apply_limit(ast, query, node)?;
558
559 if extra.is_empty() {
560 output.columns.truncate(visible);
561 return Ok((node, output));
562 }
563 let index = self.fresh_index();
566 let mut kept = Vec::with_capacity(visible);
567 let mut kept_names = Vec::with_capacity(visible);
568 let mut scope = Scope::empty();
569 for (at, name) in names.iter().enumerate().take(visible) {
570 let ty = output.columns[at].ty.clone();
571 kept.push(self.column(project, at, ty.clone()));
572 kept_names.push(self.plan.intern(name));
573 scope.push(Visible {
574 table: String::new(),
575 name: name.clone(),
576 binding: ColumnBinding::new(index, at as u32),
577 ty,
578 not_null: output.columns[at].not_null,
579 });
580 }
581 let exprs = self.plan.add_expr_list(&kept);
582 let names = self.plan.add_name_list(&kept_names);
583 node = self.plan.add_node(Node::Project { input: node, index, exprs, names });
584 Ok((node, scope))
585 }
586
587 fn bind_targets(
589 &mut self,
590 ast: &Ast,
591 targets: &[ast::Target],
592 input: &Scope,
593 ) -> Result<(Vec<ExprRef>, Vec<String>)> {
594 let mut exprs = Vec::with_capacity(targets.len());
595 let mut names = Vec::with_capacity(targets.len());
596 for target in targets {
597 if let ast::Expr::Star { qualifier, replacements } = ast.expr(target.expr) {
598 let table = ast.name(qualifier).last().map(str::to_string);
599 let expanded: Vec<Visible> =
600 input.star(table.as_deref())?.into_iter().cloned().collect();
601 let replacements = ast.target_list(replacements).to_vec();
602 let mut used = vec![false; replacements.len()];
603 for column in expanded {
604 let found = replacements.iter().zip(&mut used).find(|(replacement, _)| {
605 same_name(ast.string(replacement.alias), &column.name)
606 });
607 let (expr, name) = match found {
612 Some((replacement, used)) => {
613 *used = true;
614 let expr = self.bind_expr(ast, replacement.expr, input)?;
615 (expr, ast.string(replacement.alias).to_string())
616 }
617 None => (
618 self.plan.add_expr(Expr::Column(column.binding), column.ty),
619 column.name,
620 ),
621 };
622 exprs.push(self.over_aggregate(expr, input)?);
623 names.push(name);
624 }
625 if let Some((replacement, _)) =
629 replacements.iter().zip(&used).find(|(_, used)| !**used)
630 {
631 return Err(missing_replacement(ast.string(replacement.alias), input));
632 }
633 continue;
634 }
635 let expr = self.bind_expr(ast, target.expr, input)?;
636 exprs.push(self.over_aggregate(expr, input)?);
637 names.push(if target.alias == NONE {
638 self.output_name(ast, target.expr, input)
639 } else {
640 ast.string(target.alias).to_string()
641 });
642 }
643 Ok((exprs, names))
644 }
645
646 fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
652 if let ast::Expr::Column { name } = ast.expr(target) {
653 let parts: Vec<&str> = ast.name(name).collect();
654 if let Ok(found) = input.resolve(&parts) {
655 return found.name.clone();
656 }
657 }
658 describe(ast, target)
659 }
660
661 fn group_items(
663 &self,
664 ast: &Ast,
665 select: &ast::Select,
666 targets: &[ast::Target],
667 ) -> Result<Vec<ast::ExprRef>> {
668 if select.group_by_all {
669 return Ok(targets
672 .iter()
673 .filter(|target| !has_aggregate(ast, target.expr))
674 .map(|target| target.expr)
675 .collect());
676 }
677 let mut items = Vec::new();
678 for &item in ast.expr_list(select.group_by) {
679 items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
680 }
681 Ok(items)
682 }
683
684 fn output_reference(
686 &self,
687 ast: &Ast,
688 item: ast::ExprRef,
689 targets: &[ast::Target],
690 clause: &str,
691 ) -> Result<Option<ast::ExprRef>> {
692 match ast.expr(item) {
693 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
694 let written = ast.string(text);
695 let position: usize = written.parse().map_err(|_| {
696 Error::binder(format!("{clause} term {written} is not a column"))
697 })?;
698 if position == 0 || position > targets.len() {
699 return Err(Error::binder(format!(
700 "{clause} term out of range - should be between 1 and {}",
701 targets.len()
702 )));
703 }
704 Ok(Some(targets[position - 1].expr))
705 }
706 ast::Expr::Column { name } => {
707 let parts: Vec<&str> = ast.name(name).collect();
708 let [written] = parts.as_slice() else { return Ok(None) };
709 let mut found = None;
710 for target in targets {
711 if target.alias != NONE && same_name(ast.string(target.alias), written) {
712 if found.is_some() {
713 return Ok(None);
714 }
715 found = Some(target.expr);
716 }
717 }
718 Ok(found)
719 }
720 _ => Ok(None),
721 }
722 }
723
724 #[allow(clippy::too_many_arguments)]
728 fn select_sort_keys(
729 &mut self,
730 ast: &Ast,
731 query: &ast::Query,
732 input: &Scope,
733 output: &Scope,
734 project: u32,
735 exprs: &mut Vec<ExprRef>,
736 names: &mut Vec<String>,
737 extra: &mut Vec<usize>,
738 ) -> Result<Vec<SortKey>> {
739 if query.order_by_all {
740 return Ok(self.every_column(output));
741 }
742 let items = ast.order_list(query.order_by).to_vec();
743 let mut keys = Vec::with_capacity(items.len());
744 for item in items {
745 let position = match self.output_position(ast, item.expr, output)? {
746 Some(position) => position,
747 None => {
748 let bound = self.bind_expr(ast, item.expr, input)?;
749 let bound = self.over_aggregate(bound, input)?;
750 match exprs.iter().position(|&held| self.same_expr(held, bound)) {
751 Some(position) => position,
752 None => {
753 exprs.push(bound);
754 names.push(describe(ast, item.expr));
755 extra.push(exprs.len() - 1);
756 exprs.len() - 1
757 }
758 }
759 }
760 };
761 let ty = self.plan.expr_type(exprs[position]).clone();
762 let expr = self.column(project, position, ty);
763 keys.push(sort_key(expr, item));
764 }
765 Ok(keys)
766 }
767
768 fn sort_keys(
770 &mut self,
771 ast: &Ast,
772 query: &ast::Query,
773 output: &Scope,
774 targets: &[ast::Target],
775 ) -> Result<Vec<SortKey>> {
776 if query.order_by_all {
777 return Ok(self.every_column(output));
778 }
779 let items = ast.order_list(query.order_by).to_vec();
780 let mut keys = Vec::with_capacity(items.len());
781 for item in items {
782 let expr = match self.output_position(ast, item.expr, output)? {
783 Some(position) => {
784 let column = &output.columns[position];
785 let (binding, ty) = (column.binding, column.ty.clone());
786 self.plan.add_expr(Expr::Column(binding), ty)
787 }
788 None => {
789 let _ = targets;
790 self.bind_expr(ast, item.expr, output)?
791 }
792 };
793 keys.push(sort_key(expr, item));
794 }
795 Ok(keys)
796 }
797
798 fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
799 let columns: Vec<(ColumnBinding, LogicalType)> =
800 output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
801 columns
802 .into_iter()
803 .map(|(binding, ty)| {
804 let expr = self.plan.add_expr(Expr::Column(binding), ty);
805 SortKey { expr, descending: false, nulls_first: false }
806 })
807 .collect()
808 }
809
810 fn output_position(
812 &self,
813 ast: &Ast,
814 item: ast::ExprRef,
815 output: &Scope,
816 ) -> Result<Option<usize>> {
817 match ast.expr(item) {
818 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
819 let written = ast.string(text);
820 if written.contains(['.', 'e', 'E']) {
821 return Ok(None);
822 }
823 let position: usize = written.parse().map_err(|_| {
824 Error::binder(format!("ORDER BY term {written} is not a column"))
825 })?;
826 if position == 0 || position > output.len() {
827 return Err(Error::binder(format!(
828 "ORDER BY term out of range - should be between 1 and {}",
829 output.len()
830 )));
831 }
832 Ok(Some(position - 1))
833 }
834 ast::Expr::Column { name } => {
835 let parts: Vec<&str> = ast.name(name).collect();
836 let [written] = parts.as_slice() else { return Ok(None) };
837 Ok(output.position_of(None, written))
838 }
839 _ => Ok(None),
840 }
841 }
842
843 fn distinct_on(
845 &mut self,
846 ast: &Ast,
847 distinct: Distinct,
848 output: &Scope,
849 ) -> Result<Vec<ExprRef>> {
850 let Distinct::On(items) = distinct else {
851 return Ok(Vec::new());
852 };
853 let items = ast.expr_list(items).to_vec();
854 let mut on = Vec::with_capacity(items.len());
855 for item in items {
856 let Some(position) = self.output_position(ast, item, output)? else {
857 return Err(Error::not_implemented(
858 "DISTINCT ON an expression that is not in the select list",
859 ));
860 };
861 let column = &output.columns[position];
862 let (binding, ty) = (column.binding, column.ty.clone());
863 on.push(self.plan.add_expr(Expr::Column(binding), ty));
864 }
865 Ok(on)
866 }
867
868 fn apply_limit(&mut self, ast: &Ast, query: &ast::Query, input: NodeRef) -> Result<NodeRef> {
869 if query.limit_percent {
870 return Err(Error::not_implemented("LIMIT with a percentage"));
871 }
872 let count = self.constant_count(ast, query.limit, "LIMIT")?;
873 let offset = self.constant_count(ast, query.offset, "OFFSET")?.unwrap_or(0);
874 if count.is_none() && offset == 0 {
875 return Ok(input);
876 }
877 Ok(self.plan.add_node(Node::Limit { input, count, offset }))
878 }
879
880 fn constant_count(
882 &mut self,
883 ast: &Ast,
884 written: ast::ExprRef,
885 clause: &str,
886 ) -> Result<Option<u64>> {
887 if written == NONE {
888 return Ok(None);
889 }
890 self.clause = "LIMIT clause";
891 let scope = Scope::empty();
892 let bound = self.bind_expr(ast, written, &scope)?;
893 let Expr::Constant(value) = *self.plan.expr(bound) else {
894 return Err(Error::not_implemented(format!("a {clause} that is not a constant")));
895 };
896 let count = match self.plan.value(value) {
897 Value::Null => return Ok(None),
898 Value::TinyInt(count) => i128::from(*count),
899 Value::SmallInt(count) => i128::from(*count),
900 Value::Integer(count) => i128::from(*count),
901 Value::BigInt(count) => i128::from(*count),
902 Value::HugeInt(count) => *count,
903 other => {
904 return Err(Error::binder(format!(
905 "{clause} takes a whole number of rows, not a value of type {}",
906 other.logical_type()
907 )));
908 }
909 };
910 u64::try_from(count)
911 .map(Some)
912 .map_err(|_| Error::binder(format!("{clause} must not be negative")))
913 }
914
915 fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
918 let sources = ast.source_list(from).to_vec();
919 let Some((first, rest)) = sources.split_first() else {
920 return Ok((self.plan.add_node(Node::Dummy), Scope::empty()));
923 };
924 let (mut node, mut scope) = self.bind_source(ast, *first)?;
925 for source in rest {
926 let (right, right_scope) = self.bind_source(ast, *source)?;
927 node = self.plan.add_node(Node::CrossProduct { left: node, right });
928 scope = scope.concat(right_scope);
929 }
930 Ok((node, scope))
931 }
932
933 fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
934 match ast.source(source) {
935 ast::Source::Table { name, alias, columns } => {
936 self.bind_table(ast, name, alias, columns)
937 }
938 ast::Source::Function { name, args, alias, columns } => {
939 self.bind_table_function(ast, name, args, alias, columns)
940 }
941 ast::Source::Subquery { query, alias, columns } => {
942 let (node, mut scope) = self.bind_query(ast, query)?;
943 let label = if alias == NONE {
944 "unnamed_subquery".to_string()
945 } else {
946 ast.string(alias).to_string()
947 };
948 scope.relabel(&label);
949 if !columns.is_empty() {
950 let names: Vec<&str> = ast.name(columns).collect();
951 scope.rename(&names, &label)?;
952 }
953 Ok((node, scope))
954 }
955 ast::Source::Values { rows, alias, columns } => {
956 let bare = ast::Query::bare(ast::QueryBody::Values(rows));
957 let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
958 let label =
959 if alias == NONE { String::new() } else { ast.string(alias).to_string() };
960 scope.relabel(&label);
961 if !columns.is_empty() {
962 let names: Vec<&str> = ast.name(columns).collect();
963 scope.rename(&names, &label)?;
964 }
965 Ok((node, scope))
966 }
967 ast::Source::Join { left, right, kind, natural, on, using } => {
968 self.bind_join(ast, left, right, kind, natural, on, using)
969 }
970 }
971 }
972
973 fn bind_table(
974 &mut self,
975 ast: &Ast,
976 name: ast::Slice,
977 alias: ast::StrRef,
978 columns: ast::Slice,
979 ) -> Result<(NodeRef, Scope)> {
980 let parts: Vec<&str> = ast.name(name).collect();
981 let catalog = self.catalog;
982 let resolved = match catalog.resolve(&parts) {
985 Ok(resolved) => resolved,
986 Err(missing) => {
987 return self.bind_replacement_scan(ast, &parts, alias, columns, missing);
988 }
989 };
990 if catalog.entry(&resolved)? == Entry::View {
991 return self.bind_view(ast, &resolved, alias, columns);
992 }
993 let table = catalog.table(&resolved)?;
994 let fields: Vec<Field> = table.columns().to_vec();
995 let label =
996 if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
997 let index = self.fresh_index();
998 let mut scope = Scope::empty();
999 for (at, field) in fields.iter().enumerate() {
1000 scope.push(Visible {
1001 table: label.clone(),
1002 name: field.name.clone(),
1003 binding: ColumnBinding::new(index, at as u32),
1004 ty: field.ty.clone(),
1005 not_null: field.not_null,
1006 });
1007 }
1008 if !columns.is_empty() {
1009 let names: Vec<&str> = ast.name(columns).collect();
1010 scope.rename(&names, &label)?;
1011 }
1012 let catalog_name = self.plan.intern(&resolved.catalog);
1013 let schema = self.plan.intern(&resolved.schema);
1014 let table_name = self.plan.intern(&resolved.table);
1015 let alias = self.plan.intern(&label);
1016 let columns = self.plan.add_fields(&fields);
1017 let node = self.plan.add_node(Node::Get {
1018 catalog: catalog_name,
1019 schema,
1020 table: table_name,
1021 alias,
1022 index,
1023 columns,
1024 });
1025 Ok((node, scope))
1026 }
1027
1028 fn bind_view(
1040 &mut self,
1041 ast: &Ast,
1042 name: &QualifiedName,
1043 alias: ast::StrRef,
1044 columns: ast::Slice,
1045 ) -> Result<(NodeRef, Scope)> {
1046 let view = self.catalog.view(name)?;
1047 let full = name.to_string();
1048 if self.expanding.contains(&full) {
1049 return Err(Error::binder(format!(
1053 "infinite recursion detected: attempting to recursively bind view \"\"{}\"\"",
1054 name.table
1055 )));
1056 }
1057 let body = parse_ast(view.sql())?;
1058 let query = match body.statements.as_slice() {
1059 [ast::Statement::Query(query)] => *query,
1060 _ => return Err(Error::binder(format!("view \"{}\" is not a query", name.table))),
1063 };
1064 self.expanding.push(full);
1065 let bound = self.bind_query(&body, query);
1066 self.expanding.pop();
1067 let (node, mut scope) = bound?;
1068
1069 let aliases: Vec<&str> = view.aliases().iter().map(String::as_str).collect();
1070 if !aliases.is_empty() {
1071 scope.rename(&aliases, "unnamed_subquery")?;
1072 }
1073 view.remember(scope.fields());
1080 let label = if alias == NONE { name.table.clone() } else { ast.string(alias).to_string() };
1081 scope.relabel(&label);
1082 if !columns.is_empty() {
1083 let names: Vec<&str> = ast.name(columns).collect();
1084 scope.rename(&names, &label)?;
1085 }
1086 Ok((node, scope))
1087 }
1088
1089 fn bind_table_function(
1097 &mut self,
1098 ast: &Ast,
1099 name: ast::Slice,
1100 args: ast::Slice,
1101 alias: ast::StrRef,
1102 columns: ast::Slice,
1103 ) -> Result<(NodeRef, Scope)> {
1104 let parts: Vec<&str> = ast.name(name).collect();
1105 let function_name = *parts.last().unwrap_or(&"");
1109 if let Some(schema) = parts.iter().rev().nth(1) {
1110 if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
1111 return Err(Error::catalog(format!(
1112 "Table Function with name {} does not exist!",
1113 parts.join(".")
1114 )));
1115 }
1116 }
1117 let Some(called) = TableFunction::lookup(function_name) else {
1121 return Err(Error::catalog(format!(
1122 "Table Function with name {function_name} does not exist!"
1123 )));
1124 };
1125 let written = ast.target_list(args).to_vec();
1126 let empty = Scope::empty();
1127 let previous = std::mem::replace(&mut self.clause, "table function arguments");
1128 let mut bound = Vec::new();
1129 let mut written_options = Vec::new();
1130 for argument in written {
1131 let expr = self.bind_expr(ast, argument.expr, &empty)?;
1132 if argument.alias == NONE {
1133 bound.push(expr);
1134 } else {
1135 let name = ast.string(argument.alias).to_string();
1136 let (parameter, value) = self.named_argument(called, &name, expr)?;
1137 written_options.push((parameter, value, expr));
1138 }
1139 }
1140 self.clause = previous;
1141 let options = Options::of(&written_options)?;
1142
1143 let given: Vec<LogicalType> =
1146 bound.iter().map(|&expr| self.plan.expr_type(expr).clone()).collect();
1147 let resolved = resolve_table(function_name, &given)?;
1148 let mut cast: Vec<ExprRef> = bound
1149 .iter()
1150 .zip(&resolved.arguments)
1151 .map(|(&expr, ty)| self.cast_to(expr, ty))
1152 .collect();
1153
1154 if resolved.function.takes_a_name() {
1155 let Columns::Fixed(fields) = resolved.columns else {
1156 return Err(Error::internal("a pragma that resolved to a file"));
1157 };
1158 let [argument] = cast[..] else {
1159 return Err(Error::internal("a pragma that resolved to more than one name"));
1160 };
1161 return self.bind_pragma(ast, resolved.function, &fields, argument, alias, columns);
1162 }
1163 let fields = match resolved.columns {
1164 Columns::Fixed(fields) => fields,
1165 columns => {
1166 let paths = self.file_paths(cast[0], resolved.function.name())?;
1171 let first = paths.first().map_or("", String::as_str);
1172 let mut fields = match columns {
1173 Columns::Csv => csv_fields(&paths, options.given)?,
1176 _ => parquet_fields(first)?,
1177 };
1178 if options.all_varchar {
1179 for field in &mut fields {
1184 field.ty = LogicalType::Varchar;
1185 }
1186 }
1187 if options.binary_as_string {
1188 for field in &mut fields {
1193 if field.ty == LogicalType::Blob {
1194 field.ty = LogicalType::Varchar;
1195 }
1196 }
1197 }
1198 if options.file_row_number {
1199 if fields.iter().any(|field| field.name == FILE_ROW_NUMBER) {
1205 return Err(Error::binder(format!(
1206 "Duplicate column name \"{FILE_ROW_NUMBER}\": the file already has a \
1207 column of that name, so file_row_number cannot add one"
1208 )));
1209 }
1210 fields.push(Field::required(FILE_ROW_NUMBER.to_string(), LogicalType::BigInt));
1211 }
1212 cast = paths.iter().map(|path| self.path_constant(path)).collect();
1213 fields
1214 }
1215 };
1216 let label = if alias == NONE {
1217 resolved.function.name().to_string()
1218 } else {
1219 ast.string(alias).to_string()
1220 };
1221 let names: Vec<&str> = ast.name(columns).collect();
1222 self.table_function_source(
1223 resolved.function,
1224 &cast,
1225 &written_options,
1226 fields,
1227 &label,
1228 &names,
1229 )
1230 }
1231
1232 fn bind_pragma(
1245 &mut self,
1246 ast: &Ast,
1247 function: TableFunction,
1248 fields: &[Field],
1249 argument: ExprRef,
1250 alias: ast::StrRef,
1251 columns: ast::Slice,
1252 ) -> Result<(NodeRef, Scope)> {
1253 let written = self.pragma_name(argument, function)?;
1254 let parts = identifier_parts(&written);
1255 let spelled: Vec<&str> = parts.iter().map(String::as_str).collect();
1256 let name = self.catalog.resolve(&spelled)?;
1257 let described = self.described(ast, &name)?;
1258 let mut rows = Vec::with_capacity(described.len());
1259 for (at, field) in described.iter().enumerate() {
1260 let items = if matches!(function, TableFunction::PragmaShow) {
1261 self.describing(field)
1262 } else {
1263 self.table_info(at, field)
1264 };
1265 rows.push(self.plan.add_expr_list(&items));
1266 }
1267 let rows = self.plan.add_rows(&rows);
1268 let held = self.plan.add_fields(fields);
1269 let index = self.fresh_index();
1270 let node = self.plan.add_node(Node::Values { index, columns: held, rows });
1271 let label =
1272 if alias == NONE { function.name().to_string() } else { ast.string(alias).to_string() };
1273 let mut scope = Scope::empty();
1274 for (at, field) in fields.iter().enumerate() {
1275 scope.push(Visible {
1276 table: label.clone(),
1277 name: field.name.clone(),
1278 binding: ColumnBinding::new(index, at as u32),
1279 ty: field.ty.clone(),
1280 not_null: false,
1281 });
1282 }
1283 if !columns.is_empty() {
1284 let names: Vec<&str> = ast.name(columns).collect();
1285 scope.rename(&names, &label)?;
1286 }
1287 Ok((node, scope))
1288 }
1289
1290 fn pragma_name(&self, argument: ExprRef, function: TableFunction) -> Result<String> {
1300 let Expr::Constant(reference) = *self.plan.expr(argument) else {
1301 return Err(Error::not_implemented(format!(
1302 "{}() given a name that is not a constant",
1303 function.name()
1304 )));
1305 };
1306 match self.plan.value(reference) {
1307 Value::Varchar(name) => Ok(name.clone()),
1308 Value::Null => Ok("NULL".to_string()),
1309 other => {
1310 Err(Error::internal(format!("a pragma name bound as VARCHAR arrived as {other}")))
1311 }
1312 }
1313 }
1314
1315 fn described(&mut self, ast: &Ast, name: &QualifiedName) -> Result<Vec<Field>> {
1326 if self.catalog.entry(name)? == Entry::Table {
1327 return Ok(self.catalog.table(name)?.columns().to_vec());
1328 }
1329 let (_, scope) = self.bind_view(ast, name, NONE, ast::Slice::default())?;
1330 Ok(scope.fields())
1331 }
1332
1333 fn describing(&mut self, field: &Field) -> Vec<ExprRef> {
1335 let written = [
1336 field.name.clone(),
1337 field.ty.to_string(),
1338 if field.not_null { "NO" } else { "YES" }.to_owned(),
1339 ];
1340 let mut items: Vec<ExprRef> =
1341 written.into_iter().map(|text| self.plan.add_constant(Value::Varchar(text))).collect();
1342 for _ in 0..3 {
1343 let empty = self.plan.add_constant(Value::Null);
1344 items.push(self.cast_to(empty, &LogicalType::Varchar));
1345 }
1346 items
1347 }
1348
1349 fn table_info(&mut self, at: usize, field: &Field) -> Vec<ExprRef> {
1355 let cid = self.plan.add_constant(Value::Integer(i32::try_from(at).unwrap_or(i32::MAX)));
1356 let name = self.plan.add_constant(Value::Varchar(field.name.clone()));
1357 let ty = self.plan.add_constant(Value::Varchar(field.ty.to_string()));
1358 let not_null = self.plan.add_constant(Value::Boolean(field.not_null));
1359 let default = self.plan.add_constant(Value::Null);
1360 let default = self.cast_to(default, &LogicalType::Varchar);
1361 let key = self.plan.add_constant(Value::Boolean(false));
1362 vec![cid, name, ty, not_null, default, key]
1363 }
1364
1365 fn named_argument(
1379 &mut self,
1380 function: TableFunction,
1381 name: &str,
1382 expr: ExprRef,
1383 ) -> Result<(&'static str, Value)> {
1384 let known = function
1385 .parameters()
1386 .iter()
1387 .find(|(parameter, _)| parameter.eq_ignore_ascii_case(name));
1388 let Some((parameter, wanted)) = known else {
1389 let candidates: Vec<String> = function
1390 .parameters()
1391 .iter()
1392 .map(|(parameter, ty)| format!(" {parameter} {ty}"))
1393 .collect();
1394 return Err(Error::binder(format!(
1395 "Invalid named parameter \"{name}\" for function {}\nCandidates:\n{}\n",
1396 function.name(),
1397 candidates.join("\n")
1398 )));
1399 };
1400 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1401 return Err(Error::not_implemented(format!(
1402 "the named parameter {parameter} with a value that is not a constant"
1403 )));
1404 };
1405 let value = self.plan.value(reference).clone();
1406 if value == Value::Null {
1407 return Err(Error::binder(null_parameter(function, parameter)));
1408 }
1409 let given = self.plan.expr_type(expr).clone();
1410 if given != *wanted {
1411 return Err(Error::not_implemented(format!(
1412 "the named parameter {parameter} given a {given} where a {wanted} was wanted"
1413 )));
1414 }
1415 Ok((parameter, value))
1416 }
1417
1418 fn bind_replacement_scan(
1429 &mut self,
1430 ast: &Ast,
1431 parts: &[&str],
1432 alias: ast::StrRef,
1433 columns: ast::Slice,
1434 missing: Error,
1435 ) -> Result<(NodeRef, Scope)> {
1436 let [path] = parts else { return Err(missing) };
1437 let path = *path;
1438 let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
1439 let Some(function) = Self::reader_for(extension) else {
1440 if is_file(path) {
1441 return Err(Error::binder(format!(
1446 "No extension found that is capable of reading the file \"{path}\"\n* If this \
1447 file is a supported file format you can explicitly use the reader functions, \
1448 such as read_csv, read_json or read_parquet"
1449 )));
1450 }
1451 return Err(missing);
1452 };
1453 let paths = files(path)?;
1458 let first = paths.first().map_or("", String::as_str);
1459 let fields = match function {
1460 TableFunction::ReadParquet => parquet_fields(first)?,
1461 _ => csv_fields(&paths, Given::default())?,
1462 };
1463 let label = if alias == NONE {
1469 if is_pattern(path) {
1470 path.to_string()
1471 } else {
1472 let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
1473 file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
1474 }
1475 } else {
1476 ast.string(alias).to_string()
1477 };
1478 let arguments: Vec<ExprRef> = paths.iter().map(|path| self.path_constant(path)).collect();
1479 let names: Vec<&str> = ast.name(columns).collect();
1480 self.table_function_source(function, &arguments, &[], fields, &label, &names)
1481 }
1482
1483 fn path_constant(&mut self, path: &str) -> ExprRef {
1485 let value = self.plan.add_value(Value::Varchar(path.to_string()));
1486 self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar)
1487 }
1488
1489 fn reader_for(extension: &str) -> Option<TableFunction> {
1496 if extension.eq_ignore_ascii_case("parquet") {
1497 return Some(TableFunction::ReadParquet);
1498 }
1499 if extension.eq_ignore_ascii_case("csv") || extension.eq_ignore_ascii_case("tsv") {
1500 return Some(TableFunction::ReadCsv);
1501 }
1502 None
1503 }
1504
1505 fn table_function_source(
1510 &mut self,
1511 function: TableFunction,
1512 args: &[ExprRef],
1513 written: &[(&'static str, Value, ExprRef)],
1514 fields: Vec<Field>,
1515 label: &str,
1516 names: &[&str],
1517 ) -> Result<(NodeRef, Scope)> {
1518 let index = self.fresh_index();
1519 let mut scope = Scope::empty();
1520 for (at, field) in fields.iter().enumerate() {
1521 scope.push(Visible {
1522 table: label.to_string(),
1523 name: field.name.clone(),
1524 binding: ColumnBinding::new(index, at as u32),
1525 ty: field.ty.clone(),
1526 not_null: false,
1529 });
1530 }
1531 if !names.is_empty() {
1532 scope.rename(names, label)?;
1533 }
1534 let function = self.plan.intern(function.name());
1535 let args = self.plan.add_expr_list(args);
1536 let named: Vec<u32> =
1537 written.iter().map(|(parameter, _, _)| self.plan.intern(parameter)).collect();
1538 let settings: Vec<ExprRef> = written.iter().map(|(_, _, expr)| *expr).collect();
1539 let options = self.plan.add_name_list(&named);
1540 let settings = self.plan.add_expr_list(&settings);
1541 let columns = self.plan.add_fields(&fields);
1542 let node = self.plan.add_node(Node::TableFunction {
1543 index,
1544 function,
1545 args,
1546 options,
1547 settings,
1548 columns,
1549 });
1550 Ok((node, scope))
1551 }
1552
1553 fn file_paths(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1560 let mut paths = Vec::new();
1561 for pattern in self.file_patterns(expr, name)? {
1562 paths.extend(files(&pattern)?);
1563 }
1564 Ok(paths)
1565 }
1566
1567 fn file_patterns(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1579 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1580 return Err(Error::not_implemented(
1581 "a table function file name that is not a constant",
1582 ));
1583 };
1584 match self.plan.value(reference) {
1585 Value::Varchar(path) => Ok(vec![path.clone()]),
1586 Value::Null => Err(Error::parser(format!("{name} cannot take NULL list as parameter"))),
1588 Value::List { values, .. } => values
1589 .iter()
1590 .map(|value| match value {
1591 Value::Varchar(path) => Ok(path.clone()),
1592 _ => Err(Error::parser(format!(
1593 "{name} reader cannot take NULL input as parameter"
1594 ))),
1595 })
1596 .collect(),
1597 other => {
1598 Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
1599 }
1600 }
1601 }
1602
1603 #[allow(clippy::too_many_arguments)]
1604 fn bind_join(
1605 &mut self,
1606 ast: &Ast,
1607 left: ast::SourceRef,
1608 right: ast::SourceRef,
1609 kind: ast::JoinKind,
1610 natural: bool,
1611 on: ast::ExprRef,
1612 using: ast::Slice,
1613 ) -> Result<(NodeRef, Scope)> {
1614 let (left_node, left_scope) = self.bind_source(ast, left)?;
1615 let (right_node, right_scope) = self.bind_source(ast, right)?;
1616 let split = left_scope.len();
1617 let mut scope = left_scope.concat(right_scope);
1618
1619 let merged: Vec<String> = if natural {
1622 let mut names = Vec::new();
1623 for (at, column) in scope.columns.iter().enumerate().take(split) {
1624 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
1625 && !names.iter().any(|held: &String| same_name(held, &column.name))
1626 {
1627 let _ = at;
1628 names.push(column.name.clone());
1629 }
1630 }
1631 names
1632 } else {
1633 let mut names: Vec<String> = Vec::new();
1639 for name in ast.name(using) {
1640 if !names.iter().any(|held| same_name(held, name)) {
1641 names.push(name.to_string());
1642 }
1643 }
1644 names
1645 };
1646
1647 let mut conditions = Vec::new();
1648 let mut dropped = Vec::new();
1649 for name in &merged {
1650 let left_at = scope.columns[..split]
1651 .iter()
1652 .position(|column| same_name(&column.name, name))
1653 .ok_or_else(|| {
1654 Error::binder(format!(
1655 "column \"{name}\" specified in USING clause does not exist in left table"
1656 ))
1657 })?;
1658 let right_at = scope.columns[split..]
1659 .iter()
1660 .position(|column| same_name(&column.name, name))
1661 .map(|at| at + split)
1662 .ok_or_else(|| {
1663 Error::binder(format!(
1664 "column \"{name}\" specified in USING clause does not exist in right table"
1665 ))
1666 })?;
1667 let left_column = &scope.columns[left_at];
1668 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
1669 let right_column = &scope.columns[right_at];
1670 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
1671 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
1672 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
1673 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
1674 dropped.push(right_at);
1675 }
1676 dropped.sort_unstable();
1679 for at in dropped.into_iter().rev() {
1680 scope.remove(at);
1681 }
1682
1683 if on != NONE {
1684 if !merged.is_empty() {
1685 return Err(Error::binder("a join cannot have both ON and USING"));
1686 }
1687 self.clause = "JOIN condition";
1688 let predicate = self.bind_expr(ast, on, &scope)?;
1689 conditions.push(self.as_boolean(predicate, "JOIN")?);
1690 }
1691
1692 if kind == ast::JoinKind::Cross {
1693 if !conditions.is_empty() {
1694 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
1695 }
1696 let node =
1697 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1698 return Ok((node, scope));
1699 }
1700 if conditions.is_empty() && kind == ast::JoinKind::Inner {
1701 let node =
1702 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1703 return Ok((node, scope));
1704 }
1705 let kind = match kind {
1706 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
1707 ast::JoinKind::Left => JoinKind::Left,
1708 ast::JoinKind::Right => JoinKind::Right,
1709 ast::JoinKind::Full => JoinKind::Full,
1710 ast::JoinKind::Semi => JoinKind::Semi,
1711 ast::JoinKind::Anti => JoinKind::Anti,
1712 ast::JoinKind::Positional => JoinKind::Positional,
1713 };
1714 let conditions = self.plan.add_expr_list(&conditions);
1715 let node =
1716 self.plan.add_node(Node::Join { left: left_node, right: right_node, kind, conditions });
1717 Ok((node, scope))
1718 }
1719
1720 pub(crate) fn bind_aggregate(
1724 &mut self,
1725 ast: &Ast,
1726 name: &str,
1727 args: &[ast::ExprRef],
1728 distinct: bool,
1729 scope: &Scope,
1730 ) -> Result<ExprRef> {
1731 if self.in_aggregate {
1732 return Err(Error::binder(format!(
1733 "aggregate function calls cannot be nested, and {name}() is inside one"
1734 )));
1735 }
1736 if self.aggregation.is_none() {
1737 return Err(Error::binder(format!(
1738 "aggregate function calls cannot be used in the {}",
1739 self.clause
1740 )));
1741 }
1742 self.in_aggregate = true;
1743 let mut bound = Vec::with_capacity(args.len());
1744 let mut failure = None;
1745 for &arg in args {
1746 match self.bind_expr(ast, arg, scope) {
1747 Ok(expr) => bound.push(expr),
1748 Err(error) => {
1749 failure = Some(error);
1750 break;
1751 }
1752 }
1753 }
1754 self.in_aggregate = false;
1755 if let Some(error) = failure {
1756 return Err(error);
1757 }
1758
1759 let types: Vec<LogicalType> =
1760 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
1761 let resolved = resolve(name, &types)?;
1762 let mut cast = Vec::with_capacity(bound.len());
1763 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
1764 cast.push(self.cast_to(*arg, wanted));
1765 }
1766 let args = self.plan.add_expr_list(&cast);
1767 let name = self.plan.intern(resolved.name);
1768 let ty = resolved.returns;
1769 let call =
1770 self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter: None }, ty.clone());
1771
1772 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
1775 let existing = existing.unwrap_or_default();
1776 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
1777 Some(at) => at,
1778 None => {
1779 let aggregation = self.aggregation.as_mut().expect("checked above");
1780 aggregation.aggregates.push(call);
1781 aggregation.aggregates.len() - 1
1782 }
1783 };
1784 let aggregation = self.aggregation.as_ref().expect("checked above");
1785 let (index, groups) = (aggregation.index, aggregation.groups.len());
1786 Ok(self.column(index, groups + at, ty))
1787 }
1788
1789 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
1795 let Some(aggregation) = self.aggregation.as_ref() else {
1796 return Ok(expr);
1797 };
1798 let index = aggregation.index;
1799 let groups = aggregation.groups.clone();
1800 for (at, group) in groups.iter().enumerate() {
1801 if self.same_expr(expr, *group) {
1802 let ty = self.plan.expr_type(*group).clone();
1803 return Ok(self.column(index, at, ty));
1804 }
1805 }
1806 let ty = self.plan.expr_type(expr).clone();
1807 match self.plan.expr(expr).clone() {
1808 Expr::Column(binding) if binding.table == index => Ok(expr),
1809 Expr::Column(binding) => {
1810 let name =
1811 scope.columns.iter().find(|column| column.binding == binding).map_or_else(
1812 || "a column".to_string(),
1813 |column| format!("\"{}\"", column.name),
1814 );
1815 Err(Error::binder(format!(
1816 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
1817 )))
1818 }
1819 Expr::Constant(_) | Expr::Aggregate { .. } => Ok(expr),
1820 Expr::Cast { input, try_cast } => {
1821 let input = self.over_aggregate(input, scope)?;
1822 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
1823 }
1824 Expr::Compare { op, left, right } => {
1825 let left = self.over_aggregate(left, scope)?;
1826 let right = self.over_aggregate(right, scope)?;
1827 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
1828 }
1829 Expr::Conjunction { op, children } => {
1830 let written = self.plan.expr_list(children).to_vec();
1831 let mut rewritten = Vec::with_capacity(written.len());
1832 for child in written {
1833 rewritten.push(self.over_aggregate(child, scope)?);
1834 }
1835 let children = self.plan.add_expr_list(&rewritten);
1836 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
1837 }
1838 Expr::Function { name, args } => {
1839 let written = self.plan.expr_list(args).to_vec();
1840 let mut rewritten = Vec::with_capacity(written.len());
1841 for arg in written {
1842 rewritten.push(self.over_aggregate(arg, scope)?);
1843 }
1844 let args = self.plan.add_expr_list(&rewritten);
1845 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
1846 }
1847 Expr::Case { arms, otherwise } => {
1848 let written = self.plan.arm_list(arms).to_vec();
1849 let mut rewritten = Vec::with_capacity(written.len());
1850 for arm in written {
1851 let when = self.over_aggregate(arm.when, scope)?;
1852 let then = self.over_aggregate(arm.then, scope)?;
1853 rewritten.push(rudb_plan::Arm { when, then });
1854 }
1855 let otherwise = match otherwise {
1856 Some(expr) => Some(self.over_aggregate(expr, scope)?),
1857 None => None,
1858 };
1859 let arms = self.plan.add_arms(&rewritten);
1860 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
1861 }
1862 }
1863 }
1864
1865 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
1867 same_expr(&self.plan, left, right)
1868 }
1869}
1870
1871#[derive(Debug, Default)]
1881struct Options {
1882 binary_as_string: bool,
1885 all_varchar: bool,
1887 file_row_number: bool,
1892 given: Given,
1894}
1895
1896impl Options {
1897 fn of(written: &[(&'static str, Value, ExprRef)]) -> Result<Self> {
1904 let mut options = Self::default();
1905 for (parameter, value, _) in written {
1906 match (*parameter, value) {
1907 ("binary_as_string", Value::Boolean(on)) => options.binary_as_string = *on,
1908 ("all_varchar", Value::Boolean(on)) => options.all_varchar = *on,
1909 ("file_row_number", Value::Boolean(on)) => options.file_row_number = *on,
1910 _ => {}
1911 }
1912 }
1913 let named: Vec<(&str, Value)> =
1914 written.iter().map(|(parameter, value, _)| (*parameter, value.clone())).collect();
1915 options.given = csv_given(&named)?;
1916 Ok(options)
1917 }
1918}
1919
1920fn null_parameter(function: TableFunction, parameter: &str) -> String {
1929 match parameter {
1930 "header" => format!("\"{parameter}\" expects a non-null boolean value (e.g. TRUE or 1)"),
1931 "all_varchar" => format!("{} \"{parameter}\" cannot be NULL", function.name()),
1932 _ => format!("Cannot use NULL as argument to \"{parameter}\""),
1933 }
1934}
1935
1936fn missing_replacement(name: &str, input: &Scope) -> Error {
1941 Error::binder(format!(
1942 "Column \"{name}\" in REPLACE list not found in FROM clause{}",
1943 input.candidates()
1944 ))
1945}
1946
1947fn sort_key(expr: ExprRef, item: ast::OrderItem) -> SortKey {
1953 let descending = item.order == Order::Descending;
1954 let nulls_first = match item.nulls {
1955 Nulls::First => true,
1956 Nulls::Last => false,
1957 Nulls::Unstated => descending,
1958 };
1959 SortKey { expr, descending, nulls_first }
1960}
1961
1962fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
1964 if left == right {
1965 return true;
1966 }
1967 if plan.expr_type(left) != plan.expr_type(right) {
1968 return false;
1969 }
1970 let lists = |left, right| {
1971 let left: &[ExprRef] = plan.expr_list(left);
1972 let right: &[ExprRef] = plan.expr_list(right);
1973 left.len() == right.len()
1974 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
1975 };
1976 match (plan.expr(left), plan.expr(right)) {
1977 (Expr::Column(left), Expr::Column(right)) => left == right,
1978 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
1979 (
1980 Expr::Cast { input: left, try_cast: left_try },
1981 Expr::Cast { input: right, try_cast: right_try },
1982 ) => left_try == right_try && same_expr(plan, *left, *right),
1983 (
1984 Expr::Compare { op: left_op, left: left_a, right: left_b },
1985 Expr::Compare { op: right_op, left: right_a, right: right_b },
1986 ) => {
1987 left_op == right_op
1988 && same_expr(plan, *left_a, *right_a)
1989 && same_expr(plan, *left_b, *right_b)
1990 }
1991 (
1992 Expr::Conjunction { op: left_op, children: left_children },
1993 Expr::Conjunction { op: right_op, children: right_children },
1994 ) => left_op == right_op && lists(*left_children, *right_children),
1995 (
1996 Expr::Function { name: left_name, args: left_args },
1997 Expr::Function { name: right_name, args: right_args },
1998 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
1999 (
2000 Expr::Aggregate {
2001 name: left_name,
2002 args: left_args,
2003 distinct: left_distinct,
2004 filter: left_filter,
2005 },
2006 Expr::Aggregate {
2007 name: right_name,
2008 args: right_args,
2009 distinct: right_distinct,
2010 filter: right_filter,
2011 },
2012 ) => {
2013 plan.string(*left_name) == plan.string(*right_name)
2014 && left_distinct == right_distinct
2015 && match (left_filter, right_filter) {
2016 (None, None) => true,
2017 (Some(left), Some(right)) => same_expr(plan, *left, *right),
2018 _ => false,
2019 }
2020 && lists(*left_args, *right_args)
2021 }
2022 (
2023 Expr::Case { arms: left_arms, otherwise: left_otherwise },
2024 Expr::Case { arms: right_arms, otherwise: right_otherwise },
2025 ) => {
2026 let left_arms = plan.arm_list(*left_arms);
2027 let right_arms = plan.arm_list(*right_arms);
2028 left_arms.len() == right_arms.len()
2029 && left_arms.iter().zip(right_arms).all(|(left, right)| {
2030 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
2031 })
2032 && match (left_otherwise, right_otherwise) {
2033 (None, None) => true,
2034 (Some(left), Some(right)) => same_expr(plan, *left, *right),
2035 _ => false,
2036 }
2037 }
2038 _ => false,
2039 }
2040}