1use rudb_catalog::{Catalog, Entry, QualifiedName, same_name};
16use rudb_common::{Error, Field, LogicalType, Result, Semantics, Session, ShowBehavior, 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_pragma, 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 pub(crate) semantics: Semantics,
109 plan: Plan,
110 next_index: u32,
111 pub(crate) aggregation: Option<Aggregation>,
113 pub(crate) in_aggregate: bool,
115 pub(crate) clause: &'static str,
117 expanding: Vec<String>,
119 started: Option<i64>,
121}
122
123impl<'a> Binder<'a> {
124 pub(crate) fn with(
125 catalog: &'a Catalog,
126 parameters: &'a Parameters,
127 session: &'a Session,
128 ) -> Self {
129 Self {
130 catalog,
131 parameters,
132 session,
133 semantics: session.semantics(),
134 plan: Plan::new(),
135 next_index: 0,
136 aggregation: None,
137 in_aggregate: false,
138 clause: "SELECT clause",
139 expanding: Vec::new(),
140 started: None,
141 }
142 }
143
144 pub(crate) fn catalog(&self) -> &Catalog {
145 self.catalog
146 }
147
148 pub(crate) fn instant(&mut self) -> i64 {
155 *self.started.get_or_insert_with(crate::context::micros_now)
156 }
157
158 pub(crate) fn plan(&self) -> &Plan {
159 &self.plan
160 }
161
162 pub(crate) fn plan_mut(&mut self) -> &mut Plan {
163 &mut self.plan
164 }
165
166 pub(crate) fn into_plan(self) -> Plan {
167 self.plan
168 }
169
170 pub(crate) fn fresh_index(&mut self) -> u32 {
172 let index = self.next_index;
173 self.next_index += 1;
174 index
175 }
176
177 fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
179 let binding = ColumnBinding::new(index, position as u32);
180 self.plan.add_expr(Expr::Column(binding), ty)
181 }
182
183 pub(crate) fn bind_query(
186 &mut self,
187 ast: &Ast,
188 query: ast::QueryRef,
189 ) -> Result<(NodeRef, Scope)> {
190 let written = ast.query(query);
191 match written.body {
192 ast::QueryBody::Select(select) => self.bind_select(ast, select, &written),
193 ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
194 if by_name {
195 return Err(Error::not_implemented("UNION BY NAME"));
196 }
197 self.bind_set_op(ast, &written, op, quantifier, left, right)
198 }
199 ast::QueryBody::Values(rows) => self.bind_values(ast, &written, rows),
200 ast::QueryBody::Describe(inner) => self.bind_describe(ast, &written, inner),
201 ast::QueryBody::Show { name, relation } => {
202 self.bind_show(ast, &written, name, relation)
203 }
204 }
205 }
206
207 fn bind_show(
209 &mut self,
210 ast: &Ast,
211 query: &ast::Query,
212 name: ast::Slice,
213 relation: ast::QueryRef,
214 ) -> Result<(NodeRef, Scope)> {
215 let text = ast.name_text(name);
216 let parts: Vec<&str> = ast.name(name).collect();
217 let table_exists = self.catalog.resolve(&parts).is_ok();
218 let as_table = match self.semantics.show_behavior() {
219 ShowBehavior::Auto => table_exists,
220 ShowBehavior::Setting => false,
221 ShowBehavior::Table => true,
222 };
223 if as_table {
224 return self.bind_describe(ast, query, relation);
225 }
226 let Some((_, value)) =
227 self.session.iter().find(|(name, _)| name.eq_ignore_ascii_case(&text))
228 else {
229 return Err(Error::catalog(format!("Setting with name \"{text}\" does not exist")));
230 };
231 let field = Field::new(text, LogicalType::Varchar);
232 let expr = self.plan.add_constant(Value::Varchar(value.to_string()));
233 let row = self.plan.add_expr_list(&[expr]);
234 let rows = self.plan.add_rows(&[row]);
235 let columns = self.plan.add_fields(std::slice::from_ref(&field));
236 let index = self.fresh_index();
237 let node = self.plan.add_node(Node::Values { index, columns, rows });
238 let mut scope = Scope::empty();
239 scope.push(Visible {
240 table: String::new(),
241 name: field.name,
242 binding: ColumnBinding::new(index, 0),
243 ty: LogicalType::Varchar,
244 not_null: false,
245 });
246 Ok((node, scope))
247 }
248
249 fn bind_describe(
265 &mut self,
266 ast: &Ast,
267 query: &ast::Query,
268 inner: ast::QueryRef,
269 ) -> Result<(NodeRef, Scope)> {
270 let (_, described) = self.bind_query(ast, inner)?;
271 let fields: Vec<Field> = ["column_name", "column_type", "null", "key", "default", "extra"]
272 .iter()
273 .map(|name| Field::new(*name, LogicalType::Varchar))
274 .collect();
275 let mut slices = Vec::with_capacity(described.columns.len());
276 for column in described.columns.clone() {
277 let written = [
280 column.name.clone(),
281 column.ty.to_string(),
282 if column.not_null { "NO" } else { "YES" }.to_owned(),
283 ];
284 let mut items: Vec<ExprRef> = written
285 .into_iter()
286 .map(|text| self.plan.add_constant(Value::Varchar(text)))
287 .collect();
288 for _ in 0..3 {
289 let empty = self.plan.add_constant(Value::Null);
290 items.push(self.cast_to(empty, &LogicalType::Varchar));
291 }
292 slices.push(self.plan.add_expr_list(&items));
293 }
294 let rows = self.plan.add_rows(&slices);
295 let columns = self.plan.add_fields(&fields);
296 let index = self.fresh_index();
297 let mut node = self.plan.add_node(Node::Values { index, columns, rows });
298 let mut scope = Scope::empty();
299 for (at, field) in fields.iter().enumerate() {
300 scope.push(Visible {
301 table: String::new(),
302 name: field.name.clone(),
303 binding: ColumnBinding::new(index, at as u32),
304 ty: field.ty.clone(),
305 not_null: false,
306 });
307 }
308 let keys = self.sort_keys(ast, query, &scope, &[])?;
309 if !keys.is_empty() {
310 let keys = self.plan.add_sort_keys(&keys);
311 node = self.plan.add_node(Node::Sort { input: node, keys });
312 }
313 node = self.apply_limit(ast, query, node)?;
314 Ok((node, scope))
315 }
316
317 fn passes_through(&self, expr: ExprRef, input: &Scope) -> bool {
323 let Expr::Column(binding) = *self.plan.expr(expr) else { return false };
324 input.columns.iter().any(|column| column.binding == binding && column.not_null)
325 }
326
327 fn bind_values(
334 &mut self,
335 ast: &Ast,
336 query: &ast::Query,
337 rows: ast::Slice,
338 ) -> Result<(NodeRef, Scope)> {
339 let written = ast.rows(rows).to_vec();
340 let Some(first) = written.first() else {
341 return Err(Error::binder("VALUES needs at least one row"));
342 };
343 let width = first.len as usize;
344 for (at, row) in written.iter().enumerate() {
345 if row.len as usize != width {
346 return Err(Error::binder(format!(
347 "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
348 at + 1,
349 row.len
350 )));
351 }
352 }
353 let empty = Scope::empty();
355 let previous = std::mem::replace(&mut self.clause, "VALUES clause");
356 let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
357 for row in &written {
358 let mut items = Vec::with_capacity(width);
359 for &expr in ast.expr_list(*row) {
360 items.push(self.bind_expr(ast, expr, &empty)?);
361 }
362 bound.push(items);
363 }
364 self.clause = previous;
365 let mut types = Vec::with_capacity(width);
366 for at in 0..width {
367 let mut ty = self.plan.expr_type(bound[0][at]).clone();
368 for row in &bound[1..] {
369 let other = self.plan.expr_type(row[at]).clone();
370 ty = ty.promote(&other).ok_or_else(|| {
371 Error::binder(format!(
372 "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
373 at + 1
374 ))
375 })?;
376 }
377 types.push(ty);
378 }
379 let mut slices = Vec::with_capacity(bound.len());
380 for row in &bound {
381 let items: Vec<ExprRef> = row
382 .iter()
383 .zip(&types)
384 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
385 .collect::<Result<_>>()?;
386 slices.push(self.plan.add_expr_list(&items));
387 }
388 let rows = self.plan.add_rows(&slices);
389 let fields: Vec<Field> = types
390 .iter()
391 .enumerate()
392 .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
393 .collect();
394 let columns = self.plan.add_fields(&fields);
395 let index = self.fresh_index();
396 let mut node = self.plan.add_node(Node::Values { index, columns, rows });
397 let mut scope = Scope::empty();
398 for (at, field) in fields.iter().enumerate() {
399 scope.push(Visible {
400 table: String::new(),
401 name: field.name.clone(),
402 binding: ColumnBinding::new(index, at as u32),
403 ty: field.ty.clone(),
404 not_null: false,
405 });
406 }
407 let keys = self.sort_keys(ast, query, &scope, &[])?;
408 if !keys.is_empty() {
409 let keys = self.plan.add_sort_keys(&keys);
410 node = self.plan.add_node(Node::Sort { input: node, keys });
411 }
412 node = self.apply_limit(ast, query, node)?;
413 Ok((node, scope))
414 }
415
416 fn bind_set_op(
417 &mut self,
418 ast: &Ast,
419 query: &ast::Query,
420 op: SetOp,
421 quantifier: Quantifier,
422 left: ast::QueryRef,
423 right: ast::QueryRef,
424 ) -> Result<(NodeRef, Scope)> {
425 let (left_node, left_scope) = self.bind_query(ast, left)?;
426 let (right_node, right_scope) = self.bind_query(ast, right)?;
427 if left_scope.len() != right_scope.len() {
428 return Err(Error::binder(format!(
429 "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
430 left_scope.len(),
431 right_scope.len()
432 )));
433 }
434 let mut types = Vec::with_capacity(left_scope.len());
436 for (left, right) in left_scope.columns.iter().zip(&right_scope.columns) {
437 let common = left.ty.promote(&right.ty).ok_or_else(|| {
438 Error::binder(format!(
439 "Cannot combine a column of type {} with a column of type {} in a set operation",
440 left.ty, right.ty
441 ))
442 })?;
443 types.push(common);
444 }
445 let left_node = self.conform(left_node, &left_scope, &types)?;
446 let right_node = self.conform(right_node, &right_scope, &types)?;
447 let index = self.fresh_index();
448 let kind = match op {
449 SetOp::Union => SetOpKind::Union,
450 SetOp::Except => SetOpKind::Except,
451 SetOp::Intersect => SetOpKind::Intersect,
452 };
453 let all = quantifier == Quantifier::All;
456 let mut node = self.plan.add_node(Node::SetOp {
457 left: left_node,
458 right: right_node,
459 kind,
460 all,
461 index,
462 });
463 let mut scope = Scope::empty();
464 for (at, (column, ty)) in left_scope.columns.iter().zip(&types).enumerate() {
465 scope.push(Visible {
466 table: String::new(),
467 name: column.name.clone(),
468 binding: ColumnBinding::new(index, at as u32),
469 ty: ty.clone(),
470 not_null: false,
473 });
474 }
475 let keys = self.sort_keys(ast, query, &scope, &[])?;
479 if !keys.is_empty() {
480 let keys = self.plan.add_sort_keys(&keys);
481 node = self.plan.add_node(Node::Sort { input: node, keys });
482 }
483 node = self.apply_limit(ast, query, node)?;
484 Ok((node, scope))
485 }
486
487 fn conform(&mut self, node: NodeRef, scope: &Scope, types: &[LogicalType]) -> Result<NodeRef> {
489 if scope.columns.iter().zip(types).all(|(column, ty)| &column.ty == ty) {
490 return Ok(node);
491 }
492 let index = self.fresh_index();
493 let mut exprs = Vec::with_capacity(types.len());
494 let mut names = Vec::with_capacity(types.len());
495 for (column, ty) in scope.columns.iter().zip(types) {
496 let expr = self.plan.add_expr(Expr::Column(column.binding), column.ty.clone());
497 exprs.push(self.checked_cast_to(expr, ty, false)?);
498 names.push(self.plan.intern(&column.name));
499 }
500 let exprs = self.plan.add_expr_list(&exprs);
501 let names = self.plan.add_name_list(&names);
502 Ok(self.plan.add_node(Node::Project { input: node, index, exprs, names }))
503 }
504
505 fn bind_select(
508 &mut self,
509 ast: &Ast,
510 select: ast::SelectRef,
511 query: &ast::Query,
512 ) -> Result<(NodeRef, Scope)> {
513 let written = ast.select(select);
514 let (mut node, input) = self.bind_from(ast, written.from)?;
515
516 if written.filter != NONE {
517 self.clause = "WHERE clause";
518 let predicate = self.bind_expr(ast, written.filter, &input)?;
519 let predicate = self.as_boolean(predicate, "WHERE")?;
520 node = self.plan.add_node(Node::Filter { input: node, predicate });
521 }
522
523 let targets = ast.target_list(written.targets).to_vec();
524 if targets.is_empty() {
525 return Err(Error::binder("a SELECT needs at least one expression to select"));
526 }
527
528 let group_items = self.group_items(ast, &written, &targets)?;
529 let aggregating = !group_items.is_empty()
530 || written.having != NONE
531 || targets.iter().any(|target| has_aggregate(ast, target.expr));
532 if aggregating {
533 self.clause = "GROUP BY clause";
534 let mut groups = Vec::with_capacity(group_items.len());
535 for item in &group_items {
536 groups.push(self.bind_expr(ast, *item, &input)?);
537 }
538 let index = self.fresh_index();
539 self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
540 }
541
542 self.clause = "SELECT clause";
543 let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input)?;
544 let visible = exprs.len();
545
546 let mut having = None;
547 if written.having != NONE {
548 self.clause = "HAVING clause";
549 let predicate = self.bind_expr(ast, written.having, &input)?;
550 let predicate = self.over_aggregate(predicate, &input)?;
551 having = Some(self.as_boolean(predicate, "HAVING")?);
552 }
553
554 let project = self.fresh_index();
557 let mut output = Scope::empty();
558 for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
559 output.push(Visible {
560 table: String::new(),
561 name: name.clone(),
562 binding: ColumnBinding::new(project, at as u32),
563 ty: self.plan.expr_type(*expr).clone(),
564 not_null: self.passes_through(*expr, &input),
565 });
566 }
567
568 self.clause = "ORDER BY clause";
569 let mut extra = Vec::new();
570 let keys = self.select_sort_keys(
571 ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra,
572 )?;
573 if !extra.is_empty() && written.distinct != Distinct::No {
574 return Err(Error::binder(
575 "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
576 ));
577 }
578 let on = self.distinct_on(ast, written.distinct, &output)?;
579
580 if let Some(aggregation) = self.aggregation.take() {
581 let index = aggregation.index;
582 let groups = self.plan.add_expr_list(&aggregation.groups);
583 let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
584 node = self.plan.add_node(Node::Aggregate { input: node, index, groups, aggregates });
585 }
586 if let Some(predicate) = having {
587 node = self.plan.add_node(Node::Filter { input: node, predicate });
588 }
589
590 let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
591 let exprs_slice = self.plan.add_expr_list(&exprs);
592 let names_slice = self.plan.add_name_list(&interned);
593 node = self.plan.add_node(Node::Project {
594 input: node,
595 index: project,
596 exprs: exprs_slice,
597 names: names_slice,
598 });
599
600 if written.distinct != Distinct::No {
601 let on = self.plan.add_expr_list(&on);
602 node = self.plan.add_node(Node::Distinct { input: node, on });
603 }
604 if !keys.is_empty() {
605 let keys = self.plan.add_sort_keys(&keys);
606 node = self.plan.add_node(Node::Sort { input: node, keys });
607 }
608 node = self.apply_limit(ast, query, node)?;
609
610 if extra.is_empty() {
611 output.columns.truncate(visible);
612 return Ok((node, output));
613 }
614 let index = self.fresh_index();
617 let mut kept = Vec::with_capacity(visible);
618 let mut kept_names = Vec::with_capacity(visible);
619 let mut scope = Scope::empty();
620 for (at, name) in names.iter().enumerate().take(visible) {
621 let ty = output.columns[at].ty.clone();
622 kept.push(self.column(project, at, ty.clone()));
623 kept_names.push(self.plan.intern(name));
624 scope.push(Visible {
625 table: String::new(),
626 name: name.clone(),
627 binding: ColumnBinding::new(index, at as u32),
628 ty,
629 not_null: output.columns[at].not_null,
630 });
631 }
632 let exprs = self.plan.add_expr_list(&kept);
633 let names = self.plan.add_name_list(&kept_names);
634 node = self.plan.add_node(Node::Project { input: node, index, exprs, names });
635 Ok((node, scope))
636 }
637
638 fn bind_targets(
640 &mut self,
641 ast: &Ast,
642 targets: &[ast::Target],
643 input: &Scope,
644 ) -> Result<(Vec<ExprRef>, Vec<String>)> {
645 let mut exprs = Vec::with_capacity(targets.len());
646 let mut names = Vec::with_capacity(targets.len());
647 for target in targets {
648 if let ast::Expr::Star { qualifier, replacements } = ast.expr(target.expr) {
649 let table = ast.name(qualifier).last().map(str::to_string);
650 let expanded: Vec<Visible> =
651 input.star(table.as_deref())?.into_iter().cloned().collect();
652 let replacements = ast.target_list(replacements).to_vec();
653 let mut used = vec![false; replacements.len()];
654 for column in expanded {
655 let found = replacements.iter().zip(&mut used).find(|(replacement, _)| {
656 same_name(ast.string(replacement.alias), &column.name)
657 });
658 let (expr, name) = match found {
663 Some((replacement, used)) => {
664 *used = true;
665 let expr = self.bind_expr(ast, replacement.expr, input)?;
666 (expr, ast.string(replacement.alias).to_string())
667 }
668 None => (
669 self.plan.add_expr(Expr::Column(column.binding), column.ty),
670 column.name,
671 ),
672 };
673 exprs.push(self.over_aggregate(expr, input)?);
674 names.push(name);
675 }
676 if let Some((replacement, _)) =
680 replacements.iter().zip(&used).find(|(_, used)| !**used)
681 {
682 return Err(missing_replacement(ast.string(replacement.alias), input));
683 }
684 continue;
685 }
686 let expr = self.bind_expr(ast, target.expr, input)?;
687 exprs.push(self.over_aggregate(expr, input)?);
688 names.push(if target.alias == NONE {
689 self.output_name(ast, target.expr, input)
690 } else {
691 ast.string(target.alias).to_string()
692 });
693 }
694 Ok((exprs, names))
695 }
696
697 fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
703 if let ast::Expr::Column { name } = ast.expr(target) {
704 let parts: Vec<&str> = ast.name(name).collect();
705 if let Ok(found) = input.resolve(&parts) {
706 return found.name.clone();
707 }
708 }
709 describe(ast, target, self.semantics)
710 }
711
712 fn group_items(
714 &self,
715 ast: &Ast,
716 select: &ast::Select,
717 targets: &[ast::Target],
718 ) -> Result<Vec<ast::ExprRef>> {
719 if select.group_by_all {
720 return Ok(targets
723 .iter()
724 .filter(|target| !has_aggregate(ast, target.expr))
725 .map(|target| target.expr)
726 .collect());
727 }
728 let mut items = Vec::new();
729 for &item in ast.expr_list(select.group_by) {
730 items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
731 }
732 Ok(items)
733 }
734
735 fn output_reference(
737 &self,
738 ast: &Ast,
739 item: ast::ExprRef,
740 targets: &[ast::Target],
741 clause: &str,
742 ) -> Result<Option<ast::ExprRef>> {
743 match ast.expr(item) {
744 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
745 let written = ast.string(text);
746 let position: usize = written.parse().map_err(|_| {
747 Error::binder(format!("{clause} term {written} is not a column"))
748 })?;
749 if position == 0 || position > targets.len() {
750 return Err(Error::binder(format!(
751 "{clause} term out of range - should be between 1 and {}",
752 targets.len()
753 )));
754 }
755 Ok(Some(targets[position - 1].expr))
756 }
757 ast::Expr::Column { name } => {
758 let parts: Vec<&str> = ast.name(name).collect();
759 let [written] = parts.as_slice() else { return Ok(None) };
760 let mut found = None;
761 for target in targets {
762 if target.alias != NONE && same_name(ast.string(target.alias), written) {
763 if found.is_some() {
764 return Ok(None);
765 }
766 found = Some(target.expr);
767 }
768 }
769 Ok(found)
770 }
771 _ => Ok(None),
772 }
773 }
774
775 #[allow(clippy::too_many_arguments)]
779 fn select_sort_keys(
780 &mut self,
781 ast: &Ast,
782 query: &ast::Query,
783 input: &Scope,
784 output: &Scope,
785 project: u32,
786 exprs: &mut Vec<ExprRef>,
787 names: &mut Vec<String>,
788 extra: &mut Vec<usize>,
789 ) -> Result<Vec<SortKey>> {
790 if query.order_by_all {
791 return Ok(self.every_column(output));
792 }
793 let items = ast.order_list(query.order_by).to_vec();
794 let mut keys = Vec::with_capacity(items.len());
795 for item in items {
796 self.check_order_literal(ast, item.expr)?;
797 let position = match self.output_position(ast, item.expr, output)? {
798 Some(position) => position,
799 None => {
800 let bound = self.bind_expr(ast, item.expr, input)?;
801 let bound = self.over_aggregate(bound, input)?;
802 match exprs.iter().position(|&held| self.same_expr(held, bound)) {
803 Some(position) => position,
804 None => {
805 exprs.push(bound);
806 names.push(describe(ast, item.expr, self.semantics));
807 extra.push(exprs.len() - 1);
808 exprs.len() - 1
809 }
810 }
811 }
812 };
813 let ty = self.plan.expr_type(exprs[position]).clone();
814 let expr = self.column(project, position, ty);
815 keys.push(self.sort_key(expr, item));
816 }
817 Ok(keys)
818 }
819
820 fn sort_keys(
822 &mut self,
823 ast: &Ast,
824 query: &ast::Query,
825 output: &Scope,
826 targets: &[ast::Target],
827 ) -> Result<Vec<SortKey>> {
828 if query.order_by_all {
829 return Ok(self.every_column(output));
830 }
831 let items = ast.order_list(query.order_by).to_vec();
832 let mut keys = Vec::with_capacity(items.len());
833 for item in items {
834 self.check_order_literal(ast, item.expr)?;
835 let expr = match self.output_position(ast, item.expr, output)? {
836 Some(position) => {
837 let column = &output.columns[position];
838 let (binding, ty) = (column.binding, column.ty.clone());
839 self.plan.add_expr(Expr::Column(binding), ty)
840 }
841 None => {
842 let _ = targets;
843 self.bind_expr(ast, item.expr, output)?
844 }
845 };
846 keys.push(self.sort_key(expr, item));
847 }
848 Ok(keys)
849 }
850
851 fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
852 let columns: Vec<(ColumnBinding, LogicalType)> =
853 output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
854 columns
855 .into_iter()
856 .map(|(binding, ty)| {
857 let expr = self.plan.add_expr(Expr::Column(binding), ty);
858 let descending = self.semantics.default_descending();
859 SortKey { expr, descending, nulls_first: self.semantics.nulls_first(descending) }
860 })
861 .collect()
862 }
863
864 fn sort_key(&self, expr: ExprRef, item: ast::OrderItem) -> SortKey {
866 let descending = match item.order {
867 Order::Unstated => self.semantics.default_descending(),
868 Order::Ascending => false,
869 Order::Descending => true,
870 };
871 let nulls_first = match item.nulls {
872 Nulls::First => true,
873 Nulls::Last => false,
874 Nulls::Unstated => self.semantics.nulls_first(descending),
875 };
876 SortKey { expr, descending, nulls_first }
877 }
878
879 fn output_position(
881 &self,
882 ast: &Ast,
883 item: ast::ExprRef,
884 output: &Scope,
885 ) -> Result<Option<usize>> {
886 match ast.expr(item) {
887 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
888 let written = ast.string(text);
889 if written.contains(['.', 'e', 'E']) {
890 return Ok(None);
891 }
892 let position: usize = written.parse().map_err(|_| {
893 Error::binder(format!("ORDER BY term {written} is not a column"))
894 })?;
895 if position == 0 || position > output.len() {
896 return Err(Error::binder(format!(
897 "ORDER BY term out of range - should be between 1 and {}",
898 output.len()
899 )));
900 }
901 Ok(Some(position - 1))
902 }
903 ast::Expr::Column { name } => {
904 let parts: Vec<&str> = ast.name(name).collect();
905 let [written] = parts.as_slice() else { return Ok(None) };
906 Ok(output.position_of(None, written))
907 }
908 _ => Ok(None),
909 }
910 }
911
912 fn check_order_literal(&self, ast: &Ast, item: ast::ExprRef) -> Result<()> {
914 if !self.semantics.order_by_non_integer_literal()
915 && matches!(
916 ast.expr(item),
917 ast::Expr::Literal { kind, text }
918 if kind != LiteralKind::Number
919 || ast.string(text).contains(['.', 'e', 'E'])
920 )
921 {
922 return Err(Error::binder(
923 "ORDER BY non-integer literal has no effect.\n* SET order_by_non_integer_literal=true to allow this behavior.",
924 ));
925 }
926 Ok(())
927 }
928
929 fn distinct_on(
931 &mut self,
932 ast: &Ast,
933 distinct: Distinct,
934 output: &Scope,
935 ) -> Result<Vec<ExprRef>> {
936 let Distinct::On(items) = distinct else {
937 return Ok(Vec::new());
938 };
939 let items = ast.expr_list(items).to_vec();
940 let mut on = Vec::with_capacity(items.len());
941 for item in items {
942 let Some(position) = self.output_position(ast, item, output)? else {
943 return Err(Error::not_implemented(
944 "DISTINCT ON an expression that is not in the select list",
945 ));
946 };
947 let column = &output.columns[position];
948 let (binding, ty) = (column.binding, column.ty.clone());
949 on.push(self.plan.add_expr(Expr::Column(binding), ty));
950 }
951 Ok(on)
952 }
953
954 fn apply_limit(&mut self, ast: &Ast, query: &ast::Query, input: NodeRef) -> Result<NodeRef> {
955 if query.limit_percent {
956 return Err(Error::not_implemented("LIMIT with a percentage"));
957 }
958 let count = self.constant_count(ast, query.limit, "LIMIT")?;
959 let offset = self.constant_count(ast, query.offset, "OFFSET")?.unwrap_or(0);
960 if count.is_none() && offset == 0 {
961 return Ok(input);
962 }
963 Ok(self.plan.add_node(Node::Limit { input, count, offset }))
964 }
965
966 fn constant_count(
968 &mut self,
969 ast: &Ast,
970 written: ast::ExprRef,
971 clause: &str,
972 ) -> Result<Option<u64>> {
973 if written == NONE {
974 return Ok(None);
975 }
976 self.clause = "LIMIT clause";
977 let scope = Scope::empty();
978 let bound = self.bind_expr(ast, written, &scope)?;
979 let Expr::Constant(value) = *self.plan.expr(bound) else {
980 return Err(Error::not_implemented(format!("a {clause} that is not a constant")));
981 };
982 let count = match self.plan.value(value) {
983 Value::Null => return Ok(None),
984 Value::TinyInt(count) => i128::from(*count),
985 Value::SmallInt(count) => i128::from(*count),
986 Value::Integer(count) => i128::from(*count),
987 Value::BigInt(count) => i128::from(*count),
988 Value::HugeInt(count) => *count,
989 other => {
990 return Err(Error::binder(format!(
991 "{clause} takes a whole number of rows, not a value of type {}",
992 other.logical_type()
993 )));
994 }
995 };
996 u64::try_from(count)
997 .map(Some)
998 .map_err(|_| Error::binder(format!("{clause} must not be negative")))
999 }
1000
1001 fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
1004 let sources = ast.source_list(from).to_vec();
1005 let Some((first, rest)) = sources.split_first() else {
1006 return Ok((self.plan.add_node(Node::Dummy), Scope::empty()));
1009 };
1010 let (mut node, mut scope) = self.bind_source(ast, *first)?;
1011 for source in rest {
1012 let (right, right_scope) = self.bind_source(ast, *source)?;
1013 node = self.plan.add_node(Node::CrossProduct { left: node, right });
1014 scope = scope.concat(right_scope);
1015 }
1016 Ok((node, scope))
1017 }
1018
1019 fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
1020 match ast.source(source) {
1021 ast::Source::Table { name, alias, columns } => {
1022 self.bind_table(ast, name, alias, columns)
1023 }
1024 ast::Source::Function { name, args, alias, columns, pragma } => {
1025 self.bind_table_function(ast, name, args, alias, columns, pragma)
1026 }
1027 ast::Source::Subquery { query, alias, columns } => {
1028 let (node, mut scope) = self.bind_query(ast, query)?;
1029 let label = if alias == NONE {
1030 "unnamed_subquery".to_string()
1031 } else {
1032 ast.string(alias).to_string()
1033 };
1034 scope.relabel(&label);
1035 if !columns.is_empty() {
1036 let names: Vec<&str> = ast.name(columns).collect();
1037 scope.rename(&names, &label)?;
1038 }
1039 Ok((node, scope))
1040 }
1041 ast::Source::Values { rows, alias, columns } => {
1042 let bare = ast::Query::bare(ast::QueryBody::Values(rows));
1043 let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
1044 let label =
1045 if alias == NONE { String::new() } else { ast.string(alias).to_string() };
1046 scope.relabel(&label);
1047 if !columns.is_empty() {
1048 let names: Vec<&str> = ast.name(columns).collect();
1049 scope.rename(&names, &label)?;
1050 }
1051 Ok((node, scope))
1052 }
1053 ast::Source::Join { left, right, kind, natural, on, using } => {
1054 self.bind_join(ast, left, right, kind, natural, on, using)
1055 }
1056 }
1057 }
1058
1059 fn bind_table(
1060 &mut self,
1061 ast: &Ast,
1062 name: ast::Slice,
1063 alias: ast::StrRef,
1064 columns: ast::Slice,
1065 ) -> Result<(NodeRef, Scope)> {
1066 let parts: Vec<&str> = ast.name(name).collect();
1067 let catalog = self.catalog;
1068 let resolved = match catalog.resolve(&parts) {
1071 Ok(resolved) => resolved,
1072 Err(missing) => {
1073 return self.bind_replacement_scan(ast, &parts, alias, columns, missing);
1074 }
1075 };
1076 if catalog.entry(&resolved)? == Entry::View {
1077 return self.bind_view(ast, &resolved, alias, columns);
1078 }
1079 let table = catalog.table(&resolved)?;
1080 let fields: Vec<Field> = table.columns().to_vec();
1081 let label =
1082 if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
1083 let index = self.fresh_index();
1084 let mut scope = Scope::empty();
1085 for (at, field) in fields.iter().enumerate() {
1086 scope.push(Visible {
1087 table: label.clone(),
1088 name: field.name.clone(),
1089 binding: ColumnBinding::new(index, at as u32),
1090 ty: field.ty.clone(),
1091 not_null: field.not_null,
1092 });
1093 }
1094 if !columns.is_empty() {
1095 let names: Vec<&str> = ast.name(columns).collect();
1096 scope.rename(&names, &label)?;
1097 }
1098 let catalog_name = self.plan.intern(&resolved.catalog);
1099 let schema = self.plan.intern(&resolved.schema);
1100 let table_name = self.plan.intern(&resolved.table);
1101 let alias = self.plan.intern(&label);
1102 let columns = self.plan.add_fields(&fields);
1103 let node = self.plan.add_node(Node::Get {
1104 catalog: catalog_name,
1105 schema,
1106 table: table_name,
1107 alias,
1108 index,
1109 columns,
1110 });
1111 Ok((node, scope))
1112 }
1113
1114 fn bind_view(
1126 &mut self,
1127 ast: &Ast,
1128 name: &QualifiedName,
1129 alias: ast::StrRef,
1130 columns: ast::Slice,
1131 ) -> Result<(NodeRef, Scope)> {
1132 let view = self.catalog.view(name)?;
1133 let full = name.to_string();
1134 if self.expanding.contains(&full) {
1135 return Err(Error::binder(format!(
1139 "infinite recursion detected: attempting to recursively bind view \"\"{}\"\"",
1140 name.table
1141 )));
1142 }
1143 let body = parse_ast(view.sql())?;
1144 let query = match body.statements.as_slice() {
1145 [ast::Statement::Query(query)] => *query,
1146 _ => return Err(Error::binder(format!("view \"{}\" is not a query", name.table))),
1149 };
1150 self.expanding.push(full);
1151 let bound = self.bind_query(&body, query);
1152 self.expanding.pop();
1153 let (node, mut scope) = bound?;
1154
1155 let aliases: Vec<&str> = view.aliases().iter().map(String::as_str).collect();
1156 if !aliases.is_empty() {
1157 scope.rename(&aliases, "unnamed_subquery")?;
1158 }
1159 view.remember(scope.fields());
1166 let label = if alias == NONE { name.table.clone() } else { ast.string(alias).to_string() };
1167 scope.relabel(&label);
1168 if !columns.is_empty() {
1169 let names: Vec<&str> = ast.name(columns).collect();
1170 scope.rename(&names, &label)?;
1171 }
1172 Ok((node, scope))
1173 }
1174
1175 fn bind_table_function(
1183 &mut self,
1184 ast: &Ast,
1185 name: ast::Slice,
1186 args: ast::Slice,
1187 alias: ast::StrRef,
1188 columns: ast::Slice,
1189 pragma: bool,
1190 ) -> Result<(NodeRef, Scope)> {
1191 let parts: Vec<&str> = ast.name(name).collect();
1192 let function_name = *parts.last().unwrap_or(&"");
1196 if let Some(schema) = parts.iter().rev().nth(1) {
1197 if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
1198 return Err(Error::catalog(format!(
1199 "Table Function with name {} does not exist!",
1200 parts.join(".")
1201 )));
1202 }
1203 }
1204 let Some(called) = TableFunction::lookup(function_name) else {
1208 if pragma {
1209 if args.is_empty() && self.catalog.resolve(&parts).is_ok() {
1215 return self.bind_table(ast, name, alias, columns);
1216 }
1217 let spelled = function_name.strip_prefix("pragma_").unwrap_or(function_name);
1218 return Err(Error::catalog(format!(
1219 "Pragma Function with name {spelled} does not exist!"
1220 )));
1221 }
1222 return Err(Error::catalog(format!(
1223 "Table Function with name {function_name} does not exist!"
1224 )));
1225 };
1226 let written = ast.target_list(args).to_vec();
1227 let empty = Scope::empty();
1228 let previous = std::mem::replace(&mut self.clause, "table function arguments");
1229 let mut bound = Vec::new();
1230 let mut written_options = Vec::new();
1231 for argument in written {
1232 let expr = self.bind_expr(ast, argument.expr, &empty)?;
1233 if argument.alias == NONE {
1234 bound.push(expr);
1235 } else {
1236 let name = ast.string(argument.alias).to_string();
1237 let (parameter, value) = self.named_argument(called, &name, expr)?;
1238 written_options.push((parameter, value, expr));
1239 }
1240 }
1241 self.clause = previous;
1242 let options = Options::of(&written_options)?;
1243
1244 let given: Vec<LogicalType> =
1247 bound.iter().map(|&expr| self.plan.expr_type(expr).clone()).collect();
1248 let resolved = if pragma {
1249 resolve_pragma(function_name, &given)?
1250 } else {
1251 resolve_table(function_name, &given)?
1252 };
1253 let mut cast: Vec<ExprRef> = bound
1254 .iter()
1255 .zip(&resolved.arguments)
1256 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
1257 .collect::<Result<_>>()?;
1258
1259 if resolved.function.takes_a_name() {
1260 let Columns::Fixed(fields) = resolved.columns else {
1261 return Err(Error::internal("a pragma that resolved to a file"));
1262 };
1263 let [argument] = cast[..] else {
1264 return Err(Error::internal("a pragma that resolved to more than one name"));
1265 };
1266 return self.bind_pragma(ast, resolved.function, &fields, argument, alias, columns);
1267 }
1268 let fields = match resolved.columns {
1269 Columns::Fixed(fields) => fields,
1270 columns => {
1271 let paths = self.file_paths(cast[0], resolved.function.name())?;
1276 let first = paths.first().map_or("", String::as_str);
1277 let mut fields = match columns {
1278 Columns::Csv => csv_fields(&paths, options.given)?,
1281 _ => parquet_fields(first)?,
1282 };
1283 if options.all_varchar {
1284 for field in &mut fields {
1289 field.ty = LogicalType::Varchar;
1290 }
1291 }
1292 if options.binary_as_string {
1293 for field in &mut fields {
1298 if field.ty == LogicalType::Blob {
1299 field.ty = LogicalType::Varchar;
1300 }
1301 }
1302 }
1303 if options.file_row_number {
1304 if fields.iter().any(|field| field.name == FILE_ROW_NUMBER) {
1310 return Err(Error::binder(format!(
1311 "Duplicate column name \"{FILE_ROW_NUMBER}\": the file already has a \
1312 column of that name, so file_row_number cannot add one"
1313 )));
1314 }
1315 fields.push(Field::required(FILE_ROW_NUMBER.to_string(), LogicalType::BigInt));
1316 }
1317 cast = paths.iter().map(|path| self.path_constant(path)).collect();
1318 fields
1319 }
1320 };
1321 let label = if alias == NONE {
1322 resolved.function.name().to_string()
1323 } else {
1324 ast.string(alias).to_string()
1325 };
1326 let names: Vec<&str> = ast.name(columns).collect();
1327 self.table_function_source(
1328 resolved.function,
1329 &cast,
1330 &written_options,
1331 fields,
1332 &label,
1333 &names,
1334 )
1335 }
1336
1337 fn bind_pragma(
1350 &mut self,
1351 ast: &Ast,
1352 function: TableFunction,
1353 fields: &[Field],
1354 argument: ExprRef,
1355 alias: ast::StrRef,
1356 columns: ast::Slice,
1357 ) -> Result<(NodeRef, Scope)> {
1358 let written = self.pragma_name(argument, function)?;
1359 let parts = identifier_parts(&written);
1360 let spelled: Vec<&str> = parts.iter().map(String::as_str).collect();
1361 let name = self.catalog.resolve(&spelled)?;
1362 let described = self.described(ast, &name)?;
1363 let mut rows = Vec::with_capacity(described.len());
1364 for (at, field) in described.iter().enumerate() {
1365 let items = if matches!(function, TableFunction::PragmaShow) {
1366 self.describing(field)
1367 } else {
1368 self.table_info(at, field)
1369 };
1370 rows.push(self.plan.add_expr_list(&items));
1371 }
1372 let rows = self.plan.add_rows(&rows);
1373 let held = self.plan.add_fields(fields);
1374 let index = self.fresh_index();
1375 let node = self.plan.add_node(Node::Values { index, columns: held, rows });
1376 let label =
1377 if alias == NONE { function.name().to_string() } else { ast.string(alias).to_string() };
1378 let mut scope = Scope::empty();
1379 for (at, field) in fields.iter().enumerate() {
1380 scope.push(Visible {
1381 table: label.clone(),
1382 name: field.name.clone(),
1383 binding: ColumnBinding::new(index, at as u32),
1384 ty: field.ty.clone(),
1385 not_null: false,
1386 });
1387 }
1388 if !columns.is_empty() {
1389 let names: Vec<&str> = ast.name(columns).collect();
1390 scope.rename(&names, &label)?;
1391 }
1392 Ok((node, scope))
1393 }
1394
1395 fn pragma_name(&self, argument: ExprRef, function: TableFunction) -> Result<String> {
1405 let Expr::Constant(reference) = *self.plan.expr(argument) else {
1406 return Err(Error::not_implemented(format!(
1407 "{}() given a name that is not a constant",
1408 function.name()
1409 )));
1410 };
1411 match self.plan.value(reference) {
1412 Value::Varchar(name) => Ok(name.clone()),
1413 Value::Null => Ok("NULL".to_string()),
1414 other => {
1415 Err(Error::internal(format!("a pragma name bound as VARCHAR arrived as {other}")))
1416 }
1417 }
1418 }
1419
1420 fn described(&mut self, ast: &Ast, name: &QualifiedName) -> Result<Vec<Field>> {
1431 if self.catalog.entry(name)? == Entry::Table {
1432 return Ok(self.catalog.table(name)?.columns().to_vec());
1433 }
1434 let (_, scope) = self.bind_view(ast, name, NONE, ast::Slice::default())?;
1435 Ok(scope.fields())
1436 }
1437
1438 fn describing(&mut self, field: &Field) -> Vec<ExprRef> {
1440 let written = [
1441 field.name.clone(),
1442 field.ty.to_string(),
1443 if field.not_null { "NO" } else { "YES" }.to_owned(),
1444 ];
1445 let mut items: Vec<ExprRef> =
1446 written.into_iter().map(|text| self.plan.add_constant(Value::Varchar(text))).collect();
1447 for _ in 0..3 {
1448 let empty = self.plan.add_constant(Value::Null);
1449 items.push(self.cast_to(empty, &LogicalType::Varchar));
1450 }
1451 items
1452 }
1453
1454 fn table_info(&mut self, at: usize, field: &Field) -> Vec<ExprRef> {
1460 let cid = self.plan.add_constant(Value::Integer(i32::try_from(at).unwrap_or(i32::MAX)));
1461 let name = self.plan.add_constant(Value::Varchar(field.name.clone()));
1462 let ty = self.plan.add_constant(Value::Varchar(field.ty.to_string()));
1463 let not_null = self.plan.add_constant(Value::Boolean(field.not_null));
1464 let default = self.plan.add_constant(Value::Null);
1465 let default = self.cast_to(default, &LogicalType::Varchar);
1466 let key = self.plan.add_constant(Value::Boolean(false));
1467 vec![cid, name, ty, not_null, default, key]
1468 }
1469
1470 fn named_argument(
1484 &mut self,
1485 function: TableFunction,
1486 name: &str,
1487 expr: ExprRef,
1488 ) -> Result<(&'static str, Value)> {
1489 let known = function
1490 .parameters()
1491 .iter()
1492 .find(|(parameter, _)| parameter.eq_ignore_ascii_case(name));
1493 let Some((parameter, wanted)) = known else {
1494 let candidates: Vec<String> = function
1495 .parameters()
1496 .iter()
1497 .map(|(parameter, ty)| format!(" {parameter} {ty}"))
1498 .collect();
1499 return Err(Error::binder(format!(
1500 "Invalid named parameter \"{name}\" for function {}\nCandidates:\n{}\n",
1501 function.name(),
1502 candidates.join("\n")
1503 )));
1504 };
1505 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1506 return Err(Error::not_implemented(format!(
1507 "the named parameter {parameter} with a value that is not a constant"
1508 )));
1509 };
1510 let value = self.plan.value(reference).clone();
1511 if value == Value::Null {
1512 return Err(Error::binder(null_parameter(function, parameter)));
1513 }
1514 let given = self.plan.expr_type(expr).clone();
1515 if given != *wanted {
1516 return Err(Error::not_implemented(format!(
1517 "the named parameter {parameter} given a {given} where a {wanted} was wanted"
1518 )));
1519 }
1520 Ok((parameter, value))
1521 }
1522
1523 fn bind_replacement_scan(
1534 &mut self,
1535 ast: &Ast,
1536 parts: &[&str],
1537 alias: ast::StrRef,
1538 columns: ast::Slice,
1539 missing: Error,
1540 ) -> Result<(NodeRef, Scope)> {
1541 let [path] = parts else { return Err(missing) };
1542 let path = *path;
1543 let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
1544 let Some(function) = Self::reader_for(extension) else {
1545 if is_file(path) {
1546 return Err(Error::binder(format!(
1551 "No extension found that is capable of reading the file \"{path}\"\n* If this \
1552 file is a supported file format you can explicitly use the reader functions, \
1553 such as read_csv, read_json or read_parquet"
1554 )));
1555 }
1556 return Err(missing);
1557 };
1558 let paths = files(path)?;
1563 let first = paths.first().map_or("", String::as_str);
1564 let fields = match function {
1565 TableFunction::ReadParquet => parquet_fields(first)?,
1566 _ => csv_fields(&paths, Given::default())?,
1567 };
1568 let label = if alias == NONE {
1574 if is_pattern(path) {
1575 path.to_string()
1576 } else {
1577 let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
1578 file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
1579 }
1580 } else {
1581 ast.string(alias).to_string()
1582 };
1583 let arguments: Vec<ExprRef> = paths.iter().map(|path| self.path_constant(path)).collect();
1584 let names: Vec<&str> = ast.name(columns).collect();
1585 self.table_function_source(function, &arguments, &[], fields, &label, &names)
1586 }
1587
1588 fn path_constant(&mut self, path: &str) -> ExprRef {
1590 let value = self.plan.add_value(Value::Varchar(path.to_string()));
1591 self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar)
1592 }
1593
1594 fn reader_for(extension: &str) -> Option<TableFunction> {
1601 if extension.eq_ignore_ascii_case("parquet") {
1602 return Some(TableFunction::ReadParquet);
1603 }
1604 if extension.eq_ignore_ascii_case("csv") || extension.eq_ignore_ascii_case("tsv") {
1605 return Some(TableFunction::ReadCsv);
1606 }
1607 None
1608 }
1609
1610 fn table_function_source(
1615 &mut self,
1616 function: TableFunction,
1617 args: &[ExprRef],
1618 written: &[(&'static str, Value, ExprRef)],
1619 fields: Vec<Field>,
1620 label: &str,
1621 names: &[&str],
1622 ) -> Result<(NodeRef, Scope)> {
1623 let index = self.fresh_index();
1624 let mut scope = Scope::empty();
1625 for (at, field) in fields.iter().enumerate() {
1626 scope.push(Visible {
1627 table: label.to_string(),
1628 name: field.name.clone(),
1629 binding: ColumnBinding::new(index, at as u32),
1630 ty: field.ty.clone(),
1631 not_null: false,
1634 });
1635 }
1636 if !names.is_empty() {
1637 scope.rename(names, label)?;
1638 }
1639 let function = self.plan.intern(function.name());
1640 let args = self.plan.add_expr_list(args);
1641 let named: Vec<u32> =
1642 written.iter().map(|(parameter, _, _)| self.plan.intern(parameter)).collect();
1643 let settings: Vec<ExprRef> = written.iter().map(|(_, _, expr)| *expr).collect();
1644 let options = self.plan.add_name_list(&named);
1645 let settings = self.plan.add_expr_list(&settings);
1646 let columns = self.plan.add_fields(&fields);
1647 let node = self.plan.add_node(Node::TableFunction {
1648 index,
1649 function,
1650 args,
1651 options,
1652 settings,
1653 columns,
1654 });
1655 Ok((node, scope))
1656 }
1657
1658 fn file_paths(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1665 let mut paths = Vec::new();
1666 for pattern in self.file_patterns(expr, name)? {
1667 paths.extend(files(&pattern)?);
1668 }
1669 Ok(paths)
1670 }
1671
1672 fn file_patterns(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1684 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1685 return Err(Error::not_implemented(
1686 "a table function file name that is not a constant",
1687 ));
1688 };
1689 match self.plan.value(reference) {
1690 Value::Varchar(path) => Ok(vec![path.clone()]),
1691 Value::Null => Err(Error::parser(format!("{name} cannot take NULL list as parameter"))),
1693 Value::List { values, .. } => values
1694 .iter()
1695 .map(|value| match value {
1696 Value::Varchar(path) => Ok(path.clone()),
1697 _ => Err(Error::parser(format!(
1698 "{name} reader cannot take NULL input as parameter"
1699 ))),
1700 })
1701 .collect(),
1702 other => {
1703 Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
1704 }
1705 }
1706 }
1707
1708 #[allow(clippy::too_many_arguments)]
1709 fn bind_join(
1710 &mut self,
1711 ast: &Ast,
1712 left: ast::SourceRef,
1713 right: ast::SourceRef,
1714 kind: ast::JoinKind,
1715 natural: bool,
1716 on: ast::ExprRef,
1717 using: ast::Slice,
1718 ) -> Result<(NodeRef, Scope)> {
1719 let (left_node, left_scope) = self.bind_source(ast, left)?;
1720 let (right_node, right_scope) = self.bind_source(ast, right)?;
1721 let split = left_scope.len();
1722 let mut scope = left_scope.concat(right_scope);
1723
1724 let merged: Vec<String> = if natural {
1727 let mut names = Vec::new();
1728 for (at, column) in scope.columns.iter().enumerate().take(split) {
1729 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
1730 && !names.iter().any(|held: &String| same_name(held, &column.name))
1731 {
1732 let _ = at;
1733 names.push(column.name.clone());
1734 }
1735 }
1736 names
1737 } else {
1738 let mut names: Vec<String> = Vec::new();
1744 for name in ast.name(using) {
1745 if !names.iter().any(|held| same_name(held, name)) {
1746 names.push(name.to_string());
1747 }
1748 }
1749 names
1750 };
1751
1752 let mut conditions = Vec::new();
1753 let mut dropped = Vec::new();
1754 for name in &merged {
1755 let left_at = scope.columns[..split]
1756 .iter()
1757 .position(|column| same_name(&column.name, name))
1758 .ok_or_else(|| {
1759 Error::binder(format!(
1760 "column \"{name}\" specified in USING clause does not exist in left table"
1761 ))
1762 })?;
1763 let right_at = scope.columns[split..]
1764 .iter()
1765 .position(|column| same_name(&column.name, name))
1766 .map(|at| at + split)
1767 .ok_or_else(|| {
1768 Error::binder(format!(
1769 "column \"{name}\" specified in USING clause does not exist in right table"
1770 ))
1771 })?;
1772 let left_column = &scope.columns[left_at];
1773 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
1774 let right_column = &scope.columns[right_at];
1775 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
1776 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
1777 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
1778 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
1779 dropped.push(right_at);
1780 }
1781 dropped.sort_unstable();
1784 for at in dropped.into_iter().rev() {
1785 scope.remove(at);
1786 }
1787
1788 if on != NONE {
1789 if !merged.is_empty() {
1790 return Err(Error::binder("a join cannot have both ON and USING"));
1791 }
1792 self.clause = "JOIN condition";
1793 let predicate = self.bind_expr(ast, on, &scope)?;
1794 conditions.push(self.as_boolean(predicate, "JOIN")?);
1795 }
1796
1797 if kind == ast::JoinKind::Cross {
1798 if !conditions.is_empty() {
1799 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
1800 }
1801 let node =
1802 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1803 return Ok((node, scope));
1804 }
1805 if conditions.is_empty() && kind == ast::JoinKind::Inner {
1806 let node =
1807 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1808 return Ok((node, scope));
1809 }
1810 let kind = match kind {
1811 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
1812 ast::JoinKind::Left => JoinKind::Left,
1813 ast::JoinKind::Right => JoinKind::Right,
1814 ast::JoinKind::Full => JoinKind::Full,
1815 ast::JoinKind::Semi => JoinKind::Semi,
1816 ast::JoinKind::Anti => JoinKind::Anti,
1817 ast::JoinKind::Positional => JoinKind::Positional,
1818 };
1819 let conditions = self.plan.add_expr_list(&conditions);
1820 let node =
1821 self.plan.add_node(Node::Join { left: left_node, right: right_node, kind, conditions });
1822 Ok((node, scope))
1823 }
1824
1825 pub(crate) fn bind_aggregate(
1829 &mut self,
1830 ast: &Ast,
1831 name: &str,
1832 args: &[ast::ExprRef],
1833 distinct: bool,
1834 scope: &Scope,
1835 ) -> Result<ExprRef> {
1836 if self.in_aggregate {
1837 return Err(Error::binder(format!(
1838 "aggregate function calls cannot be nested, and {name}() is inside one"
1839 )));
1840 }
1841 if self.aggregation.is_none() {
1842 return Err(Error::binder(format!(
1843 "aggregate function calls cannot be used in the {}",
1844 self.clause
1845 )));
1846 }
1847 self.in_aggregate = true;
1848 let mut bound = Vec::with_capacity(args.len());
1849 let mut failure = None;
1850 for &arg in args {
1851 match self.bind_expr(ast, arg, scope) {
1852 Ok(expr) => bound.push(expr),
1853 Err(error) => {
1854 failure = Some(error);
1855 break;
1856 }
1857 }
1858 }
1859 self.in_aggregate = false;
1860 if let Some(error) = failure {
1861 return Err(error);
1862 }
1863
1864 let types: Vec<LogicalType> =
1865 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
1866 let resolved = resolve(name, &types)?;
1867 let mut cast = Vec::with_capacity(bound.len());
1868 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
1869 cast.push(self.checked_cast_to(*arg, wanted, false)?);
1870 }
1871 let args = self.plan.add_expr_list(&cast);
1872 let name = self.plan.intern(resolved.name);
1873 let ty = resolved.returns;
1874 let call =
1875 self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter: None }, ty.clone());
1876
1877 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
1880 let existing = existing.unwrap_or_default();
1881 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
1882 Some(at) => at,
1883 None => {
1884 let aggregation = self.aggregation.as_mut().expect("checked above");
1885 aggregation.aggregates.push(call);
1886 aggregation.aggregates.len() - 1
1887 }
1888 };
1889 let aggregation = self.aggregation.as_ref().expect("checked above");
1890 let (index, groups) = (aggregation.index, aggregation.groups.len());
1891 Ok(self.column(index, groups + at, ty))
1892 }
1893
1894 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
1900 let Some(aggregation) = self.aggregation.as_ref() else {
1901 return Ok(expr);
1902 };
1903 let index = aggregation.index;
1904 let groups = aggregation.groups.clone();
1905 for (at, group) in groups.iter().enumerate() {
1906 if self.same_expr(expr, *group) {
1907 let ty = self.plan.expr_type(*group).clone();
1908 return Ok(self.column(index, at, ty));
1909 }
1910 }
1911 let ty = self.plan.expr_type(expr).clone();
1912 match self.plan.expr(expr).clone() {
1913 Expr::Column(binding) if binding.table == index => Ok(expr),
1914 Expr::Column(binding) => {
1915 let name =
1916 scope.columns.iter().find(|column| column.binding == binding).map_or_else(
1917 || "a column".to_string(),
1918 |column| format!("\"{}\"", column.name),
1919 );
1920 Err(Error::binder(format!(
1921 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
1922 )))
1923 }
1924 Expr::Constant(_) | Expr::Aggregate { .. } => Ok(expr),
1925 Expr::Cast { input, try_cast } => {
1926 let input = self.over_aggregate(input, scope)?;
1927 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
1928 }
1929 Expr::Compare { op, left, right } => {
1930 let left = self.over_aggregate(left, scope)?;
1931 let right = self.over_aggregate(right, scope)?;
1932 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
1933 }
1934 Expr::Conjunction { op, children } => {
1935 let written = self.plan.expr_list(children).to_vec();
1936 let mut rewritten = Vec::with_capacity(written.len());
1937 for child in written {
1938 rewritten.push(self.over_aggregate(child, scope)?);
1939 }
1940 let children = self.plan.add_expr_list(&rewritten);
1941 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
1942 }
1943 Expr::Function { name, args } => {
1944 let written = self.plan.expr_list(args).to_vec();
1945 let mut rewritten = Vec::with_capacity(written.len());
1946 for arg in written {
1947 rewritten.push(self.over_aggregate(arg, scope)?);
1948 }
1949 let args = self.plan.add_expr_list(&rewritten);
1950 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
1951 }
1952 Expr::Case { arms, otherwise } => {
1953 let written = self.plan.arm_list(arms).to_vec();
1954 let mut rewritten = Vec::with_capacity(written.len());
1955 for arm in written {
1956 let when = self.over_aggregate(arm.when, scope)?;
1957 let then = self.over_aggregate(arm.then, scope)?;
1958 rewritten.push(rudb_plan::Arm { when, then });
1959 }
1960 let otherwise = match otherwise {
1961 Some(expr) => Some(self.over_aggregate(expr, scope)?),
1962 None => None,
1963 };
1964 let arms = self.plan.add_arms(&rewritten);
1965 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
1966 }
1967 }
1968 }
1969
1970 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
1972 same_expr(&self.plan, left, right)
1973 }
1974}
1975
1976#[derive(Debug, Default)]
1986struct Options {
1987 binary_as_string: bool,
1990 all_varchar: bool,
1992 file_row_number: bool,
1997 given: Given,
1999}
2000
2001impl Options {
2002 fn of(written: &[(&'static str, Value, ExprRef)]) -> Result<Self> {
2009 let mut options = Self::default();
2010 for (parameter, value, _) in written {
2011 match (*parameter, value) {
2012 ("binary_as_string", Value::Boolean(on)) => options.binary_as_string = *on,
2013 ("all_varchar", Value::Boolean(on)) => options.all_varchar = *on,
2014 ("file_row_number", Value::Boolean(on)) => options.file_row_number = *on,
2015 _ => {}
2016 }
2017 }
2018 let named: Vec<(&str, Value)> =
2019 written.iter().map(|(parameter, value, _)| (*parameter, value.clone())).collect();
2020 options.given = csv_given(&named)?;
2021 Ok(options)
2022 }
2023}
2024
2025fn null_parameter(function: TableFunction, parameter: &str) -> String {
2034 match parameter {
2035 "header" => format!("\"{parameter}\" expects a non-null boolean value (e.g. TRUE or 1)"),
2036 "all_varchar" => format!("{} \"{parameter}\" cannot be NULL", function.name()),
2037 _ => format!("Cannot use NULL as argument to \"{parameter}\""),
2038 }
2039}
2040
2041fn missing_replacement(name: &str, input: &Scope) -> Error {
2046 Error::binder(format!(
2047 "Column \"{name}\" in REPLACE list not found in FROM clause{}",
2048 input.candidates()
2049 ))
2050}
2051
2052fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
2054 if left == right {
2055 return true;
2056 }
2057 if plan.expr_type(left) != plan.expr_type(right) {
2058 return false;
2059 }
2060 let lists = |left, right| {
2061 let left: &[ExprRef] = plan.expr_list(left);
2062 let right: &[ExprRef] = plan.expr_list(right);
2063 left.len() == right.len()
2064 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
2065 };
2066 match (plan.expr(left), plan.expr(right)) {
2067 (Expr::Column(left), Expr::Column(right)) => left == right,
2068 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
2069 (
2070 Expr::Cast { input: left, try_cast: left_try },
2071 Expr::Cast { input: right, try_cast: right_try },
2072 ) => left_try == right_try && same_expr(plan, *left, *right),
2073 (
2074 Expr::Compare { op: left_op, left: left_a, right: left_b },
2075 Expr::Compare { op: right_op, left: right_a, right: right_b },
2076 ) => {
2077 left_op == right_op
2078 && same_expr(plan, *left_a, *right_a)
2079 && same_expr(plan, *left_b, *right_b)
2080 }
2081 (
2082 Expr::Conjunction { op: left_op, children: left_children },
2083 Expr::Conjunction { op: right_op, children: right_children },
2084 ) => left_op == right_op && lists(*left_children, *right_children),
2085 (
2086 Expr::Function { name: left_name, args: left_args },
2087 Expr::Function { name: right_name, args: right_args },
2088 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
2089 (
2090 Expr::Aggregate {
2091 name: left_name,
2092 args: left_args,
2093 distinct: left_distinct,
2094 filter: left_filter,
2095 },
2096 Expr::Aggregate {
2097 name: right_name,
2098 args: right_args,
2099 distinct: right_distinct,
2100 filter: right_filter,
2101 },
2102 ) => {
2103 plan.string(*left_name) == plan.string(*right_name)
2104 && left_distinct == right_distinct
2105 && match (left_filter, right_filter) {
2106 (None, None) => true,
2107 (Some(left), Some(right)) => same_expr(plan, *left, *right),
2108 _ => false,
2109 }
2110 && lists(*left_args, *right_args)
2111 }
2112 (
2113 Expr::Case { arms: left_arms, otherwise: left_otherwise },
2114 Expr::Case { arms: right_arms, otherwise: right_otherwise },
2115 ) => {
2116 let left_arms = plan.arm_list(*left_arms);
2117 let right_arms = plan.arm_list(*right_arms);
2118 left_arms.len() == right_arms.len()
2119 && left_arms.iter().zip(right_arms).all(|(left, right)| {
2120 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
2121 })
2122 && match (left_otherwise, right_otherwise) {
2123 (None, None) => true,
2124 (Some(left), Some(right)) => same_expr(plan, *left, *right),
2125 _ => false,
2126 }
2127 }
2128 _ => false,
2129 }
2130}