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_with_case};
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_with_case(query, session.semantics().identifier_case())?;
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)]
100pub(crate) struct PendingSubquery {
101 pub(crate) node: NodeRef,
102 pub(crate) kind: JoinKind,
103 pub(crate) conditions: Vec<ExprRef>,
104}
105
106#[derive(Debug)]
108pub(crate) struct Binder<'a> {
109 catalog: &'a Catalog,
110 pub(crate) parameters: &'a Parameters,
112 pub(crate) session: &'a Session,
114 pub(crate) semantics: Semantics,
116 plan: Plan,
117 next_index: u32,
118 pub(crate) aggregation: Option<Aggregation>,
120 pub(crate) in_aggregate: bool,
122 pub(crate) scalar_subqueries: Vec<PendingSubquery>,
124 pub(crate) clause: &'static str,
126 expanding: Vec<String>,
128 started: Option<i64>,
130}
131
132impl<'a> Binder<'a> {
133 pub(crate) fn with(
134 catalog: &'a Catalog,
135 parameters: &'a Parameters,
136 session: &'a Session,
137 ) -> Self {
138 Self {
139 catalog,
140 parameters,
141 session,
142 semantics: session.semantics(),
143 plan: Plan::new(),
144 next_index: 0,
145 aggregation: None,
146 in_aggregate: false,
147 scalar_subqueries: Vec::new(),
148 clause: "SELECT clause",
149 expanding: Vec::new(),
150 started: None,
151 }
152 }
153
154 pub(crate) fn catalog(&self) -> &Catalog {
155 self.catalog
156 }
157
158 pub(crate) fn instant(&mut self) -> i64 {
165 *self.started.get_or_insert_with(crate::context::micros_now)
166 }
167
168 pub(crate) fn plan(&self) -> &Plan {
169 &self.plan
170 }
171
172 pub(crate) fn plan_mut(&mut self) -> &mut Plan {
173 &mut self.plan
174 }
175
176 pub(crate) fn into_plan(self) -> Plan {
177 self.plan
178 }
179
180 pub(crate) fn fresh_index(&mut self) -> u32 {
182 let index = self.next_index;
183 self.next_index += 1;
184 index
185 }
186
187 fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
189 let binding = ColumnBinding::new(index, position as u32);
190 self.plan.add_expr(Expr::Column(binding), ty)
191 }
192
193 fn attach_scalar_subqueries(&mut self, mut input: NodeRef) -> NodeRef {
195 let subqueries = std::mem::take(&mut self.scalar_subqueries);
196 for pending in subqueries {
197 let PendingSubquery { node: mut right, kind, conditions } = pending;
198 if kind == JoinKind::Single && !self.semantics.scalar_subquery_error_on_multiple_rows()
199 {
200 right = self.plan.add_node(Node::Limit { input: right, count: Some(1), offset: 0 });
201 }
202 let conditions = self.plan.add_expr_list(&conditions);
203 input = self.plan.add_node(Node::Join { left: input, right, kind, conditions });
204 }
205 input
206 }
207
208 pub(crate) fn bind_query(
211 &mut self,
212 ast: &Ast,
213 query: ast::QueryRef,
214 ) -> Result<(NodeRef, Scope)> {
215 let written = ast.query(query);
216 match written.body {
217 ast::QueryBody::Select(select) => self.bind_select(ast, select, &written),
218 ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
219 if by_name {
220 return Err(Error::not_implemented("UNION BY NAME"));
221 }
222 self.bind_set_op(ast, &written, op, quantifier, left, right)
223 }
224 ast::QueryBody::Values(rows) => self.bind_values(ast, &written, rows),
225 ast::QueryBody::Describe(inner) => self.bind_describe(ast, &written, inner),
226 ast::QueryBody::Show { name, relation } => {
227 self.bind_show(ast, &written, name, relation)
228 }
229 }
230 }
231
232 fn bind_show(
234 &mut self,
235 ast: &Ast,
236 query: &ast::Query,
237 name: ast::Slice,
238 relation: ast::QueryRef,
239 ) -> Result<(NodeRef, Scope)> {
240 let text = ast.name_text(name);
241 let parts: Vec<&str> = ast.name(name).collect();
242 let table_exists = self.catalog.resolve(&parts).is_ok();
243 let as_table = match self.semantics.show_behavior() {
244 ShowBehavior::Auto => table_exists,
245 ShowBehavior::Setting => false,
246 ShowBehavior::Table => true,
247 };
248 if as_table {
249 return self.bind_describe(ast, query, relation);
250 }
251 let Some((_, value)) =
252 self.session.iter().find(|(name, _)| name.eq_ignore_ascii_case(&text))
253 else {
254 return Err(Error::catalog(format!("Setting with name \"{text}\" does not exist")));
255 };
256 let field = Field::new(text, LogicalType::Varchar);
257 let expr = self.plan.add_constant(Value::Varchar(value.to_string()));
258 let row = self.plan.add_expr_list(&[expr]);
259 let rows = self.plan.add_rows(&[row]);
260 let columns = self.plan.add_fields(std::slice::from_ref(&field));
261 let index = self.fresh_index();
262 let node = self.plan.add_node(Node::Values { index, columns, rows });
263 let mut scope = Scope::empty();
264 scope.push(Visible {
265 table: String::new(),
266 name: field.name,
267 binding: ColumnBinding::new(index, 0),
268 ty: LogicalType::Varchar,
269 not_null: false,
270 });
271 Ok((node, scope))
272 }
273
274 fn bind_describe(
290 &mut self,
291 ast: &Ast,
292 query: &ast::Query,
293 inner: ast::QueryRef,
294 ) -> Result<(NodeRef, Scope)> {
295 let (_, described) = self.bind_query(ast, inner)?;
296 let fields: Vec<Field> = ["column_name", "column_type", "null", "key", "default", "extra"]
297 .iter()
298 .map(|name| Field::new(*name, LogicalType::Varchar))
299 .collect();
300 let mut slices = Vec::with_capacity(described.columns.len());
301 for column in described.columns.clone() {
302 let written = [
305 column.name.clone(),
306 column.ty.to_string(),
307 if column.not_null { "NO" } else { "YES" }.to_owned(),
308 ];
309 let mut items: Vec<ExprRef> = written
310 .into_iter()
311 .map(|text| self.plan.add_constant(Value::Varchar(text)))
312 .collect();
313 for _ in 0..3 {
314 let empty = self.plan.add_constant(Value::Null);
315 items.push(self.cast_to(empty, &LogicalType::Varchar));
316 }
317 slices.push(self.plan.add_expr_list(&items));
318 }
319 let rows = self.plan.add_rows(&slices);
320 let columns = self.plan.add_fields(&fields);
321 let index = self.fresh_index();
322 let mut node = self.plan.add_node(Node::Values { index, columns, rows });
323 let mut scope = Scope::empty();
324 for (at, field) in fields.iter().enumerate() {
325 scope.push(Visible {
326 table: String::new(),
327 name: field.name.clone(),
328 binding: ColumnBinding::new(index, at as u32),
329 ty: field.ty.clone(),
330 not_null: false,
331 });
332 }
333 let keys = self.sort_keys(ast, query, &scope, &[])?;
334 if !keys.is_empty() {
335 let keys = self.plan.add_sort_keys(&keys);
336 node = self.plan.add_node(Node::Sort { input: node, keys });
337 }
338 node = self.apply_limit(ast, query, node)?;
339 Ok((node, scope))
340 }
341
342 fn passes_through(&self, expr: ExprRef, input: &Scope) -> bool {
348 let Expr::Column(binding) = *self.plan.expr(expr) else { return false };
349 input.columns.iter().any(|column| column.binding == binding && column.not_null)
350 }
351
352 fn bind_values(
359 &mut self,
360 ast: &Ast,
361 query: &ast::Query,
362 rows: ast::Slice,
363 ) -> Result<(NodeRef, Scope)> {
364 let written = ast.rows(rows).to_vec();
365 let Some(first) = written.first() else {
366 return Err(Error::binder("VALUES needs at least one row"));
367 };
368 let width = first.len as usize;
369 for (at, row) in written.iter().enumerate() {
370 if row.len as usize != width {
371 return Err(Error::binder(format!(
372 "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
373 at + 1,
374 row.len
375 )));
376 }
377 }
378 let empty = Scope::empty();
380 let previous = std::mem::replace(&mut self.clause, "VALUES clause");
381 let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
382 for row in &written {
383 let mut items = Vec::with_capacity(width);
384 for &expr in ast.expr_list(*row) {
385 items.push(self.bind_expr(ast, expr, &empty)?);
386 }
387 bound.push(items);
388 }
389 self.clause = previous;
390 let mut types = Vec::with_capacity(width);
391 for at in 0..width {
392 let mut ty = self.plan.expr_type(bound[0][at]).clone();
393 for row in &bound[1..] {
394 let other = self.plan.expr_type(row[at]).clone();
395 ty = ty.promote(&other).ok_or_else(|| {
396 Error::binder(format!(
397 "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
398 at + 1
399 ))
400 })?;
401 }
402 types.push(ty);
403 }
404 let mut slices = Vec::with_capacity(bound.len());
405 for row in &bound {
406 let items: Vec<ExprRef> = row
407 .iter()
408 .zip(&types)
409 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
410 .collect::<Result<_>>()?;
411 slices.push(self.plan.add_expr_list(&items));
412 }
413 let rows = self.plan.add_rows(&slices);
414 let fields: Vec<Field> = types
415 .iter()
416 .enumerate()
417 .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
418 .collect();
419 let columns = self.plan.add_fields(&fields);
420 let index = self.fresh_index();
421 let mut node = self.plan.add_node(Node::Values { index, columns, rows });
422 let mut scope = Scope::empty();
423 for (at, field) in fields.iter().enumerate() {
424 scope.push(Visible {
425 table: String::new(),
426 name: field.name.clone(),
427 binding: ColumnBinding::new(index, at as u32),
428 ty: field.ty.clone(),
429 not_null: false,
430 });
431 }
432 let keys = self.sort_keys(ast, query, &scope, &[])?;
433 if !keys.is_empty() {
434 let keys = self.plan.add_sort_keys(&keys);
435 node = self.plan.add_node(Node::Sort { input: node, keys });
436 }
437 node = self.apply_limit(ast, query, node)?;
438 Ok((node, scope))
439 }
440
441 fn bind_set_op(
442 &mut self,
443 ast: &Ast,
444 query: &ast::Query,
445 op: SetOp,
446 quantifier: Quantifier,
447 left: ast::QueryRef,
448 right: ast::QueryRef,
449 ) -> Result<(NodeRef, Scope)> {
450 let (left_node, left_scope) = self.bind_query(ast, left)?;
451 let (right_node, right_scope) = self.bind_query(ast, right)?;
452 if left_scope.len() != right_scope.len() {
453 return Err(Error::binder(format!(
454 "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
455 left_scope.len(),
456 right_scope.len()
457 )));
458 }
459 let mut types = Vec::with_capacity(left_scope.len());
461 for (left, right) in left_scope.columns.iter().zip(&right_scope.columns) {
462 let common = left.ty.promote(&right.ty).ok_or_else(|| {
463 Error::binder(format!(
464 "Cannot combine a column of type {} with a column of type {} in a set operation",
465 left.ty, right.ty
466 ))
467 })?;
468 types.push(common);
469 }
470 let left_node = self.conform(left_node, &left_scope, &types)?;
471 let right_node = self.conform(right_node, &right_scope, &types)?;
472 let index = self.fresh_index();
473 let kind = match op {
474 SetOp::Union => SetOpKind::Union,
475 SetOp::Except => SetOpKind::Except,
476 SetOp::Intersect => SetOpKind::Intersect,
477 };
478 let all = quantifier == Quantifier::All;
481 let mut node = self.plan.add_node(Node::SetOp {
482 left: left_node,
483 right: right_node,
484 kind,
485 all,
486 index,
487 });
488 let mut scope = Scope::empty();
489 for (at, (column, ty)) in left_scope.columns.iter().zip(&types).enumerate() {
490 scope.push(Visible {
491 table: String::new(),
492 name: column.name.clone(),
493 binding: ColumnBinding::new(index, at as u32),
494 ty: ty.clone(),
495 not_null: false,
498 });
499 }
500 let keys = self.sort_keys(ast, query, &scope, &[])?;
504 if !keys.is_empty() {
505 let keys = self.plan.add_sort_keys(&keys);
506 node = self.plan.add_node(Node::Sort { input: node, keys });
507 }
508 node = self.apply_limit(ast, query, node)?;
509 Ok((node, scope))
510 }
511
512 fn conform(&mut self, node: NodeRef, scope: &Scope, types: &[LogicalType]) -> Result<NodeRef> {
514 if scope.columns.iter().zip(types).all(|(column, ty)| &column.ty == ty) {
515 return Ok(node);
516 }
517 let index = self.fresh_index();
518 let mut exprs = Vec::with_capacity(types.len());
519 let mut names = Vec::with_capacity(types.len());
520 for (column, ty) in scope.columns.iter().zip(types) {
521 let expr = self.plan.add_expr(Expr::Column(column.binding), column.ty.clone());
522 exprs.push(self.checked_cast_to(expr, ty, false)?);
523 names.push(self.plan.intern(&column.name));
524 }
525 let exprs = self.plan.add_expr_list(&exprs);
526 let names = self.plan.add_name_list(&names);
527 Ok(self.plan.add_node(Node::Project { input: node, index, exprs, names }))
528 }
529
530 fn bind_select(
533 &mut self,
534 ast: &Ast,
535 select: ast::SelectRef,
536 query: &ast::Query,
537 ) -> Result<(NodeRef, Scope)> {
538 let written = ast.select(select);
539 let (mut node, input) = self.bind_from(ast, written.from)?;
540 node = self.attach_scalar_subqueries(node);
541
542 if written.filter != NONE {
543 self.clause = "WHERE clause";
544 let predicate = self.bind_expr(ast, written.filter, &input)?;
545 let predicate = self.as_boolean(predicate, "WHERE")?;
546 node = self.attach_scalar_subqueries(node);
547 node = self.plan.add_node(Node::Filter { input: node, predicate });
548 }
549
550 let targets = ast.target_list(written.targets).to_vec();
551 if targets.is_empty() {
552 return Err(Error::binder("a SELECT needs at least one expression to select"));
553 }
554
555 let group_items = self.group_items(ast, &written, &targets)?;
556 let aggregating = !group_items.is_empty()
557 || written.having != NONE
558 || targets.iter().any(|target| has_aggregate(ast, target.expr));
559 if aggregating {
560 self.clause = "GROUP BY clause";
561 let mut groups = Vec::with_capacity(group_items.len());
562 for item in &group_items {
563 groups.push(self.bind_expr(ast, *item, &input)?);
564 }
565 let index = self.fresh_index();
566 self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
567 }
568
569 self.clause = "SELECT clause";
570 let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input)?;
571 let visible = exprs.len();
572
573 let mut having = None;
574 if written.having != NONE {
575 self.clause = "HAVING clause";
576 let predicate = self.bind_expr(ast, written.having, &input)?;
577 let predicate = self.over_aggregate(predicate, &input)?;
578 having = Some(self.as_boolean(predicate, "HAVING")?);
579 }
580
581 let project = self.fresh_index();
584 let mut output = Scope::empty();
585 for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
586 output.push(Visible {
587 table: String::new(),
588 name: name.clone(),
589 binding: ColumnBinding::new(project, at as u32),
590 ty: self.plan.expr_type(*expr).clone(),
591 not_null: self.passes_through(*expr, &input),
592 });
593 }
594
595 self.clause = "ORDER BY clause";
596 let mut extra = Vec::new();
597 let keys = self.select_sort_keys(
598 ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra,
599 )?;
600 if !extra.is_empty() && written.distinct != Distinct::No {
601 return Err(Error::binder(
602 "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
603 ));
604 }
605 let on = self.distinct_on(ast, written.distinct, &output)?;
606
607 node = self.attach_scalar_subqueries(node);
608
609 if let Some(aggregation) = self.aggregation.take() {
610 let index = aggregation.index;
611 let groups = self.plan.add_expr_list(&aggregation.groups);
612 let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
613 node = self.plan.add_node(Node::Aggregate { input: node, index, groups, aggregates });
614 }
615 if let Some(predicate) = having {
616 node = self.plan.add_node(Node::Filter { input: node, predicate });
617 }
618
619 let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
620 let exprs_slice = self.plan.add_expr_list(&exprs);
621 let names_slice = self.plan.add_name_list(&interned);
622 node = self.plan.add_node(Node::Project {
623 input: node,
624 index: project,
625 exprs: exprs_slice,
626 names: names_slice,
627 });
628
629 if written.distinct != Distinct::No {
630 let on = self.plan.add_expr_list(&on);
631 node = self.plan.add_node(Node::Distinct { input: node, on });
632 }
633 if !keys.is_empty() {
634 let keys = self.plan.add_sort_keys(&keys);
635 node = self.plan.add_node(Node::Sort { input: node, keys });
636 }
637 node = self.apply_limit(ast, query, node)?;
638
639 if extra.is_empty() {
640 output.columns.truncate(visible);
641 return Ok((node, output));
642 }
643 let index = self.fresh_index();
646 let mut kept = Vec::with_capacity(visible);
647 let mut kept_names = Vec::with_capacity(visible);
648 let mut scope = Scope::empty();
649 for (at, name) in names.iter().enumerate().take(visible) {
650 let ty = output.columns[at].ty.clone();
651 kept.push(self.column(project, at, ty.clone()));
652 kept_names.push(self.plan.intern(name));
653 scope.push(Visible {
654 table: String::new(),
655 name: name.clone(),
656 binding: ColumnBinding::new(index, at as u32),
657 ty,
658 not_null: output.columns[at].not_null,
659 });
660 }
661 let exprs = self.plan.add_expr_list(&kept);
662 let names = self.plan.add_name_list(&kept_names);
663 node = self.plan.add_node(Node::Project { input: node, index, exprs, names });
664 Ok((node, scope))
665 }
666
667 fn bind_targets(
669 &mut self,
670 ast: &Ast,
671 targets: &[ast::Target],
672 input: &Scope,
673 ) -> Result<(Vec<ExprRef>, Vec<String>)> {
674 let mut exprs = Vec::with_capacity(targets.len());
675 let mut names = Vec::with_capacity(targets.len());
676 for target in targets {
677 if let ast::Expr::Star { qualifier, replacements } = ast.expr(target.expr) {
678 let table = ast.name(qualifier).last().map(str::to_string);
679 let expanded: Vec<Visible> =
680 input.star(table.as_deref())?.into_iter().cloned().collect();
681 let replacements = ast.target_list(replacements).to_vec();
682 let mut used = vec![false; replacements.len()];
683 for column in expanded {
684 let found = replacements.iter().zip(&mut used).find(|(replacement, _)| {
685 same_name(ast.string(replacement.alias), &column.name)
686 });
687 let (expr, name) = match found {
692 Some((replacement, used)) => {
693 *used = true;
694 let expr = self.bind_expr(ast, replacement.expr, input)?;
695 (expr, ast.string(replacement.alias).to_string())
696 }
697 None => (
698 self.plan.add_expr(Expr::Column(column.binding), column.ty),
699 column.name,
700 ),
701 };
702 exprs.push(self.over_aggregate(expr, input)?);
703 names.push(name);
704 }
705 if let Some((replacement, _)) =
709 replacements.iter().zip(&used).find(|(_, used)| !**used)
710 {
711 return Err(missing_replacement(ast.string(replacement.alias), input));
712 }
713 continue;
714 }
715 let expr = self.bind_expr(ast, target.expr, input)?;
716 exprs.push(self.over_aggregate(expr, input)?);
717 names.push(if target.alias == NONE {
718 self.output_name(ast, target.expr, input)
719 } else {
720 ast.string(target.alias).to_string()
721 });
722 }
723 Ok((exprs, names))
724 }
725
726 fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
732 if let ast::Expr::Column { name } = ast.expr(target) {
733 let parts: Vec<&str> = ast.name(name).collect();
734 if let Ok(found) = input.resolve(&parts) {
735 return found.name.clone();
736 }
737 }
738 describe(ast, target, self.semantics)
739 }
740
741 fn group_items(
743 &self,
744 ast: &Ast,
745 select: &ast::Select,
746 targets: &[ast::Target],
747 ) -> Result<Vec<ast::ExprRef>> {
748 if select.group_by_all {
749 return Ok(targets
752 .iter()
753 .filter(|target| !has_aggregate(ast, target.expr))
754 .map(|target| target.expr)
755 .collect());
756 }
757 let mut items = Vec::new();
758 for &item in ast.expr_list(select.group_by) {
759 items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
760 }
761 Ok(items)
762 }
763
764 fn output_reference(
766 &self,
767 ast: &Ast,
768 item: ast::ExprRef,
769 targets: &[ast::Target],
770 clause: &str,
771 ) -> Result<Option<ast::ExprRef>> {
772 match ast.expr(item) {
773 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
774 let written = ast.string(text);
775 let position: usize = written.parse().map_err(|_| {
776 Error::binder(format!("{clause} term {written} is not a column"))
777 })?;
778 if position == 0 || position > targets.len() {
779 return Err(Error::binder(format!(
780 "{clause} term out of range - should be between 1 and {}",
781 targets.len()
782 )));
783 }
784 Ok(Some(targets[position - 1].expr))
785 }
786 ast::Expr::Column { name } => {
787 let parts: Vec<&str> = ast.name(name).collect();
788 let [written] = parts.as_slice() else { return Ok(None) };
789 let mut found = None;
790 for target in targets {
791 if target.alias != NONE && same_name(ast.string(target.alias), written) {
792 if found.is_some() {
793 return Ok(None);
794 }
795 found = Some(target.expr);
796 }
797 }
798 Ok(found)
799 }
800 _ => Ok(None),
801 }
802 }
803
804 #[allow(clippy::too_many_arguments)]
808 fn select_sort_keys(
809 &mut self,
810 ast: &Ast,
811 query: &ast::Query,
812 input: &Scope,
813 output: &Scope,
814 project: u32,
815 exprs: &mut Vec<ExprRef>,
816 names: &mut Vec<String>,
817 extra: &mut Vec<usize>,
818 ) -> Result<Vec<SortKey>> {
819 if query.order_by_all {
820 return Ok(self.every_column(output));
821 }
822 let items = ast.order_list(query.order_by).to_vec();
823 let mut keys = Vec::with_capacity(items.len());
824 for item in items {
825 self.check_order_literal(ast, item.expr)?;
826 let position = match self.output_position(ast, item.expr, output)? {
827 Some(position) => position,
828 None => {
829 let bound = self.bind_expr(ast, item.expr, input)?;
830 let bound = self.over_aggregate(bound, input)?;
831 match exprs.iter().position(|&held| self.same_expr(held, bound)) {
832 Some(position) => position,
833 None => {
834 exprs.push(bound);
835 names.push(describe(ast, item.expr, self.semantics));
836 extra.push(exprs.len() - 1);
837 exprs.len() - 1
838 }
839 }
840 }
841 };
842 let ty = self.plan.expr_type(exprs[position]).clone();
843 let expr = self.column(project, position, ty);
844 keys.push(self.sort_key(expr, item));
845 }
846 Ok(keys)
847 }
848
849 fn sort_keys(
851 &mut self,
852 ast: &Ast,
853 query: &ast::Query,
854 output: &Scope,
855 targets: &[ast::Target],
856 ) -> Result<Vec<SortKey>> {
857 if query.order_by_all {
858 return Ok(self.every_column(output));
859 }
860 let items = ast.order_list(query.order_by).to_vec();
861 let mut keys = Vec::with_capacity(items.len());
862 for item in items {
863 self.check_order_literal(ast, item.expr)?;
864 let expr = match self.output_position(ast, item.expr, output)? {
865 Some(position) => {
866 let column = &output.columns[position];
867 let (binding, ty) = (column.binding, column.ty.clone());
868 self.plan.add_expr(Expr::Column(binding), ty)
869 }
870 None => {
871 let _ = targets;
872 self.bind_expr(ast, item.expr, output)?
873 }
874 };
875 keys.push(self.sort_key(expr, item));
876 }
877 Ok(keys)
878 }
879
880 fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
881 let columns: Vec<(ColumnBinding, LogicalType)> =
882 output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
883 columns
884 .into_iter()
885 .map(|(binding, ty)| {
886 let expr = self.plan.add_expr(Expr::Column(binding), ty);
887 let descending = self.semantics.default_descending();
888 SortKey { expr, descending, nulls_first: self.semantics.nulls_first(descending) }
889 })
890 .collect()
891 }
892
893 fn sort_key(&self, expr: ExprRef, item: ast::OrderItem) -> SortKey {
895 let descending = match item.order {
896 Order::Unstated => self.semantics.default_descending(),
897 Order::Ascending => false,
898 Order::Descending => true,
899 };
900 let nulls_first = match item.nulls {
901 Nulls::First => true,
902 Nulls::Last => false,
903 Nulls::Unstated => self.semantics.nulls_first(descending),
904 };
905 SortKey { expr, descending, nulls_first }
906 }
907
908 fn output_position(
910 &self,
911 ast: &Ast,
912 item: ast::ExprRef,
913 output: &Scope,
914 ) -> Result<Option<usize>> {
915 match ast.expr(item) {
916 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
917 let written = ast.string(text);
918 if written.contains(['.', 'e', 'E']) {
919 return Ok(None);
920 }
921 let position: usize = written.parse().map_err(|_| {
922 Error::binder(format!("ORDER BY term {written} is not a column"))
923 })?;
924 if position == 0 || position > output.len() {
925 return Err(Error::binder(format!(
926 "ORDER BY term out of range - should be between 1 and {}",
927 output.len()
928 )));
929 }
930 Ok(Some(position - 1))
931 }
932 ast::Expr::Column { name } => {
933 let parts: Vec<&str> = ast.name(name).collect();
934 let [written] = parts.as_slice() else { return Ok(None) };
935 Ok(output.position_of(None, written))
936 }
937 _ => Ok(None),
938 }
939 }
940
941 fn check_order_literal(&self, ast: &Ast, item: ast::ExprRef) -> Result<()> {
943 if !self.semantics.order_by_non_integer_literal()
944 && matches!(
945 ast.expr(item),
946 ast::Expr::Literal { kind, text }
947 if kind != LiteralKind::Number
948 || ast.string(text).contains(['.', 'e', 'E'])
949 )
950 {
951 return Err(Error::binder(
952 "ORDER BY non-integer literal has no effect.\n* SET order_by_non_integer_literal=true to allow this behavior.",
953 ));
954 }
955 Ok(())
956 }
957
958 fn distinct_on(
960 &mut self,
961 ast: &Ast,
962 distinct: Distinct,
963 output: &Scope,
964 ) -> Result<Vec<ExprRef>> {
965 let Distinct::On(items) = distinct else {
966 return Ok(Vec::new());
967 };
968 let items = ast.expr_list(items).to_vec();
969 let mut on = Vec::with_capacity(items.len());
970 for item in items {
971 let Some(position) = self.output_position(ast, item, output)? else {
972 return Err(Error::not_implemented(
973 "DISTINCT ON an expression that is not in the select list",
974 ));
975 };
976 let column = &output.columns[position];
977 let (binding, ty) = (column.binding, column.ty.clone());
978 on.push(self.plan.add_expr(Expr::Column(binding), ty));
979 }
980 Ok(on)
981 }
982
983 fn apply_limit(&mut self, ast: &Ast, query: &ast::Query, input: NodeRef) -> Result<NodeRef> {
984 if query.limit_percent {
985 return Err(Error::not_implemented("LIMIT with a percentage"));
986 }
987 let count = self.constant_count(ast, query.limit, "LIMIT")?;
988 let offset = self.constant_count(ast, query.offset, "OFFSET")?.unwrap_or(0);
989 if count.is_none() && offset == 0 {
990 return Ok(input);
991 }
992 Ok(self.plan.add_node(Node::Limit { input, count, offset }))
993 }
994
995 fn constant_count(
997 &mut self,
998 ast: &Ast,
999 written: ast::ExprRef,
1000 clause: &str,
1001 ) -> Result<Option<u64>> {
1002 if written == NONE {
1003 return Ok(None);
1004 }
1005 self.clause = "LIMIT clause";
1006 let scope = Scope::empty();
1007 let bound = self.bind_expr(ast, written, &scope)?;
1008 let Expr::Constant(value) = *self.plan.expr(bound) else {
1009 return Err(Error::not_implemented(format!("a {clause} that is not a constant")));
1010 };
1011 let count = match self.plan.value(value) {
1012 Value::Null => return Ok(None),
1013 Value::TinyInt(count) => i128::from(*count),
1014 Value::SmallInt(count) => i128::from(*count),
1015 Value::Integer(count) => i128::from(*count),
1016 Value::BigInt(count) => i128::from(*count),
1017 Value::HugeInt(count) => *count,
1018 other => {
1019 return Err(Error::binder(format!(
1020 "{clause} takes a whole number of rows, not a value of type {}",
1021 other.logical_type()
1022 )));
1023 }
1024 };
1025 u64::try_from(count)
1026 .map(Some)
1027 .map_err(|_| Error::binder(format!("{clause} must not be negative")))
1028 }
1029
1030 fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
1033 let sources = ast.source_list(from).to_vec();
1034 let Some((first, rest)) = sources.split_first() else {
1035 return Ok((self.plan.add_node(Node::Dummy), Scope::empty()));
1038 };
1039 let (mut node, mut scope) = self.bind_source(ast, *first)?;
1040 for source in rest {
1041 let (right, right_scope) = self.bind_source(ast, *source)?;
1042 node = self.plan.add_node(Node::CrossProduct { left: node, right });
1043 scope = scope.concat(right_scope);
1044 }
1045 Ok((node, scope))
1046 }
1047
1048 fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
1049 match ast.source(source) {
1050 ast::Source::Table { name, alias, columns } => {
1051 self.bind_table(ast, name, alias, columns)
1052 }
1053 ast::Source::Function { name, args, alias, columns, pragma } => {
1054 self.bind_table_function(ast, name, args, alias, columns, pragma)
1055 }
1056 ast::Source::Subquery { query, alias, columns } => {
1057 let (node, mut scope) = self.bind_query(ast, query)?;
1058 let label = if alias == NONE {
1059 "unnamed_subquery".to_string()
1060 } else {
1061 ast.string(alias).to_string()
1062 };
1063 scope.relabel(&label);
1064 if !columns.is_empty() {
1065 let names: Vec<&str> = ast.name(columns).collect();
1066 scope.rename(&names, &label)?;
1067 }
1068 Ok((node, scope))
1069 }
1070 ast::Source::Values { rows, alias, columns } => {
1071 let bare = ast::Query::bare(ast::QueryBody::Values(rows));
1072 let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
1073 let label =
1074 if alias == NONE { String::new() } else { ast.string(alias).to_string() };
1075 scope.relabel(&label);
1076 if !columns.is_empty() {
1077 let names: Vec<&str> = ast.name(columns).collect();
1078 scope.rename(&names, &label)?;
1079 }
1080 Ok((node, scope))
1081 }
1082 ast::Source::Join { left, right, kind, natural, on, using } => {
1083 self.bind_join(ast, left, right, kind, natural, on, using)
1084 }
1085 }
1086 }
1087
1088 fn bind_table(
1089 &mut self,
1090 ast: &Ast,
1091 name: ast::Slice,
1092 alias: ast::StrRef,
1093 columns: ast::Slice,
1094 ) -> Result<(NodeRef, Scope)> {
1095 let parts: Vec<&str> = ast.name(name).collect();
1096 let catalog = self.catalog;
1097 let resolved = match catalog.resolve(&parts) {
1100 Ok(resolved) => resolved,
1101 Err(missing) => {
1102 return self.bind_replacement_scan(ast, &parts, alias, columns, missing);
1103 }
1104 };
1105 if catalog.entry(&resolved)? == Entry::View {
1106 return self.bind_view(ast, &resolved, alias, columns);
1107 }
1108 let table = catalog.table(&resolved)?;
1109 let fields: Vec<Field> = table.columns().to_vec();
1110 let label =
1111 if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
1112 let index = self.fresh_index();
1113 let mut scope = Scope::empty();
1114 for (at, field) in fields.iter().enumerate() {
1115 scope.push(Visible {
1116 table: label.clone(),
1117 name: field.name.clone(),
1118 binding: ColumnBinding::new(index, at as u32),
1119 ty: field.ty.clone(),
1120 not_null: field.not_null,
1121 });
1122 }
1123 if !columns.is_empty() {
1124 let names: Vec<&str> = ast.name(columns).collect();
1125 scope.rename(&names, &label)?;
1126 }
1127 let catalog_name = self.plan.intern(&resolved.catalog);
1128 let schema = self.plan.intern(&resolved.schema);
1129 let table_name = self.plan.intern(&resolved.table);
1130 let alias = self.plan.intern(&label);
1131 let columns = self.plan.add_fields(&fields);
1132 let node = self.plan.add_node(Node::Get {
1133 catalog: catalog_name,
1134 schema,
1135 table: table_name,
1136 alias,
1137 index,
1138 columns,
1139 });
1140 Ok((node, scope))
1141 }
1142
1143 fn bind_view(
1155 &mut self,
1156 ast: &Ast,
1157 name: &QualifiedName,
1158 alias: ast::StrRef,
1159 columns: ast::Slice,
1160 ) -> Result<(NodeRef, Scope)> {
1161 let view = self.catalog.view(name)?;
1162 let full = name.to_string();
1163 if self.expanding.contains(&full) {
1164 return Err(Error::binder(format!(
1168 "infinite recursion detected: attempting to recursively bind view \"\"{}\"\"",
1169 name.table
1170 )));
1171 }
1172 let body = parse_ast_with_case(view.sql(), self.semantics.identifier_case())?;
1173 let query = match body.statements.as_slice() {
1174 [ast::Statement::Query(query)] => *query,
1175 _ => return Err(Error::binder(format!("view \"{}\" is not a query", name.table))),
1178 };
1179 self.expanding.push(full);
1180 let bound = self.bind_query(&body, query);
1181 self.expanding.pop();
1182 let (node, mut scope) = bound?;
1183
1184 let aliases: Vec<&str> = view.aliases().iter().map(String::as_str).collect();
1185 if !aliases.is_empty() {
1186 scope.rename(&aliases, "unnamed_subquery")?;
1187 }
1188 view.remember(scope.fields());
1195 let label = if alias == NONE { name.table.clone() } else { ast.string(alias).to_string() };
1196 scope.relabel(&label);
1197 if !columns.is_empty() {
1198 let names: Vec<&str> = ast.name(columns).collect();
1199 scope.rename(&names, &label)?;
1200 }
1201 Ok((node, scope))
1202 }
1203
1204 fn bind_table_function(
1212 &mut self,
1213 ast: &Ast,
1214 name: ast::Slice,
1215 args: ast::Slice,
1216 alias: ast::StrRef,
1217 columns: ast::Slice,
1218 pragma: bool,
1219 ) -> Result<(NodeRef, Scope)> {
1220 let parts: Vec<&str> = ast.name(name).collect();
1221 let function_name = *parts.last().unwrap_or(&"");
1225 if let Some(schema) = parts.iter().rev().nth(1) {
1226 if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
1227 return Err(Error::catalog(format!(
1228 "Table Function with name {} does not exist!",
1229 parts.join(".")
1230 )));
1231 }
1232 }
1233 let Some(called) = TableFunction::lookup(function_name) else {
1237 if pragma {
1238 if args.is_empty() && self.catalog.resolve(&parts).is_ok() {
1244 return self.bind_table(ast, name, alias, columns);
1245 }
1246 let spelled = function_name.strip_prefix("pragma_").unwrap_or(function_name);
1247 return Err(Error::catalog(format!(
1248 "Pragma Function with name {spelled} does not exist!"
1249 )));
1250 }
1251 return Err(Error::catalog(format!(
1252 "Table Function with name {function_name} does not exist!"
1253 )));
1254 };
1255 let written = ast.target_list(args).to_vec();
1256 let empty = Scope::empty();
1257 let previous = std::mem::replace(&mut self.clause, "table function arguments");
1258 let mut bound = Vec::new();
1259 let mut written_options = Vec::new();
1260 for argument in written {
1261 let expr = self.bind_expr(ast, argument.expr, &empty)?;
1262 if argument.alias == NONE {
1263 bound.push(expr);
1264 } else {
1265 let name = ast.string(argument.alias).to_string();
1266 let (parameter, value) = self.named_argument(called, &name, expr)?;
1267 written_options.push((parameter, value, expr));
1268 }
1269 }
1270 self.clause = previous;
1271 let options = Options::of(&written_options)?;
1272
1273 let given: Vec<LogicalType> =
1276 bound.iter().map(|&expr| self.plan.expr_type(expr).clone()).collect();
1277 let resolved = if pragma {
1278 resolve_pragma(function_name, &given)?
1279 } else {
1280 resolve_table(function_name, &given)?
1281 };
1282 let mut cast: Vec<ExprRef> = bound
1283 .iter()
1284 .zip(&resolved.arguments)
1285 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
1286 .collect::<Result<_>>()?;
1287
1288 if resolved.function.takes_a_name() {
1289 let Columns::Fixed(fields) = resolved.columns else {
1290 return Err(Error::internal("a pragma that resolved to a file"));
1291 };
1292 let [argument] = cast[..] else {
1293 return Err(Error::internal("a pragma that resolved to more than one name"));
1294 };
1295 return self.bind_pragma(ast, resolved.function, &fields, argument, alias, columns);
1296 }
1297 let fields = match resolved.columns {
1298 Columns::Fixed(fields) => fields,
1299 columns => {
1300 let paths = self.file_paths(cast[0], resolved.function.name())?;
1305 let first = paths.first().map_or("", String::as_str);
1306 let mut fields = match columns {
1307 Columns::Csv => csv_fields(&paths, options.given)?,
1310 _ => parquet_fields(first)?,
1311 };
1312 if options.all_varchar {
1313 for field in &mut fields {
1318 field.ty = LogicalType::Varchar;
1319 }
1320 }
1321 if options.binary_as_string {
1322 for field in &mut fields {
1327 if field.ty == LogicalType::Blob {
1328 field.ty = LogicalType::Varchar;
1329 }
1330 }
1331 }
1332 if options.file_row_number {
1333 if fields.iter().any(|field| field.name == FILE_ROW_NUMBER) {
1339 return Err(Error::binder(format!(
1340 "Duplicate column name \"{FILE_ROW_NUMBER}\": the file already has a \
1341 column of that name, so file_row_number cannot add one"
1342 )));
1343 }
1344 fields.push(Field::required(FILE_ROW_NUMBER.to_string(), LogicalType::BigInt));
1345 }
1346 cast = paths.iter().map(|path| self.path_constant(path)).collect();
1347 fields
1348 }
1349 };
1350 let label = if alias == NONE {
1351 resolved.function.name().to_string()
1352 } else {
1353 ast.string(alias).to_string()
1354 };
1355 let names: Vec<&str> = ast.name(columns).collect();
1356 self.table_function_source(
1357 resolved.function,
1358 &cast,
1359 &written_options,
1360 fields,
1361 &label,
1362 &names,
1363 )
1364 }
1365
1366 fn bind_pragma(
1379 &mut self,
1380 ast: &Ast,
1381 function: TableFunction,
1382 fields: &[Field],
1383 argument: ExprRef,
1384 alias: ast::StrRef,
1385 columns: ast::Slice,
1386 ) -> Result<(NodeRef, Scope)> {
1387 let written = self.pragma_name(argument, function)?;
1388 let parts = identifier_parts(&written);
1389 let spelled: Vec<&str> = parts.iter().map(String::as_str).collect();
1390 let name = self.catalog.resolve(&spelled)?;
1391 let described = self.described(ast, &name)?;
1392 let mut rows = Vec::with_capacity(described.len());
1393 for (at, field) in described.iter().enumerate() {
1394 let items = if matches!(function, TableFunction::PragmaShow) {
1395 self.describing(field)
1396 } else {
1397 self.table_info(at, field)
1398 };
1399 rows.push(self.plan.add_expr_list(&items));
1400 }
1401 let rows = self.plan.add_rows(&rows);
1402 let held = self.plan.add_fields(fields);
1403 let index = self.fresh_index();
1404 let node = self.plan.add_node(Node::Values { index, columns: held, rows });
1405 let label =
1406 if alias == NONE { function.name().to_string() } else { ast.string(alias).to_string() };
1407 let mut scope = Scope::empty();
1408 for (at, field) in fields.iter().enumerate() {
1409 scope.push(Visible {
1410 table: label.clone(),
1411 name: field.name.clone(),
1412 binding: ColumnBinding::new(index, at as u32),
1413 ty: field.ty.clone(),
1414 not_null: false,
1415 });
1416 }
1417 if !columns.is_empty() {
1418 let names: Vec<&str> = ast.name(columns).collect();
1419 scope.rename(&names, &label)?;
1420 }
1421 Ok((node, scope))
1422 }
1423
1424 fn pragma_name(&self, argument: ExprRef, function: TableFunction) -> Result<String> {
1434 let Expr::Constant(reference) = *self.plan.expr(argument) else {
1435 return Err(Error::not_implemented(format!(
1436 "{}() given a name that is not a constant",
1437 function.name()
1438 )));
1439 };
1440 match self.plan.value(reference) {
1441 Value::Varchar(name) => Ok(name.clone()),
1442 Value::Null => Ok("NULL".to_string()),
1443 other => {
1444 Err(Error::internal(format!("a pragma name bound as VARCHAR arrived as {other}")))
1445 }
1446 }
1447 }
1448
1449 fn described(&mut self, ast: &Ast, name: &QualifiedName) -> Result<Vec<Field>> {
1460 if self.catalog.entry(name)? == Entry::Table {
1461 return Ok(self.catalog.table(name)?.columns().to_vec());
1462 }
1463 let (_, scope) = self.bind_view(ast, name, NONE, ast::Slice::default())?;
1464 Ok(scope.fields())
1465 }
1466
1467 fn describing(&mut self, field: &Field) -> Vec<ExprRef> {
1469 let written = [
1470 field.name.clone(),
1471 field.ty.to_string(),
1472 if field.not_null { "NO" } else { "YES" }.to_owned(),
1473 ];
1474 let mut items: Vec<ExprRef> =
1475 written.into_iter().map(|text| self.plan.add_constant(Value::Varchar(text))).collect();
1476 for _ in 0..3 {
1477 let empty = self.plan.add_constant(Value::Null);
1478 items.push(self.cast_to(empty, &LogicalType::Varchar));
1479 }
1480 items
1481 }
1482
1483 fn table_info(&mut self, at: usize, field: &Field) -> Vec<ExprRef> {
1489 let cid = self.plan.add_constant(Value::Integer(i32::try_from(at).unwrap_or(i32::MAX)));
1490 let name = self.plan.add_constant(Value::Varchar(field.name.clone()));
1491 let ty = self.plan.add_constant(Value::Varchar(field.ty.to_string()));
1492 let not_null = self.plan.add_constant(Value::Boolean(field.not_null));
1493 let default = self.plan.add_constant(Value::Null);
1494 let default = self.cast_to(default, &LogicalType::Varchar);
1495 let key = self.plan.add_constant(Value::Boolean(false));
1496 vec![cid, name, ty, not_null, default, key]
1497 }
1498
1499 fn named_argument(
1513 &mut self,
1514 function: TableFunction,
1515 name: &str,
1516 expr: ExprRef,
1517 ) -> Result<(&'static str, Value)> {
1518 let known = function
1519 .parameters()
1520 .iter()
1521 .find(|(parameter, _)| parameter.eq_ignore_ascii_case(name));
1522 let Some((parameter, wanted)) = known else {
1523 let candidates: Vec<String> = function
1524 .parameters()
1525 .iter()
1526 .map(|(parameter, ty)| format!(" {parameter} {ty}"))
1527 .collect();
1528 return Err(Error::binder(format!(
1529 "Invalid named parameter \"{name}\" for function {}\nCandidates:\n{}\n",
1530 function.name(),
1531 candidates.join("\n")
1532 )));
1533 };
1534 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1535 return Err(Error::not_implemented(format!(
1536 "the named parameter {parameter} with a value that is not a constant"
1537 )));
1538 };
1539 let value = self.plan.value(reference).clone();
1540 if value == Value::Null {
1541 return Err(Error::binder(null_parameter(function, parameter)));
1542 }
1543 let given = self.plan.expr_type(expr).clone();
1544 if given != *wanted {
1545 return Err(Error::not_implemented(format!(
1546 "the named parameter {parameter} given a {given} where a {wanted} was wanted"
1547 )));
1548 }
1549 Ok((parameter, value))
1550 }
1551
1552 fn bind_replacement_scan(
1563 &mut self,
1564 ast: &Ast,
1565 parts: &[&str],
1566 alias: ast::StrRef,
1567 columns: ast::Slice,
1568 missing: Error,
1569 ) -> Result<(NodeRef, Scope)> {
1570 let [path] = parts else { return Err(missing) };
1571 let path = *path;
1572 let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
1573 let Some(function) = Self::reader_for(extension) else {
1574 if is_file(path) {
1575 return Err(Error::binder(format!(
1580 "No extension found that is capable of reading the file \"{path}\"\n* If this \
1581 file is a supported file format you can explicitly use the reader functions, \
1582 such as read_csv, read_json or read_parquet"
1583 )));
1584 }
1585 return Err(missing);
1586 };
1587 let paths = files(path)?;
1592 let first = paths.first().map_or("", String::as_str);
1593 let fields = match function {
1594 TableFunction::ReadParquet => parquet_fields(first)?,
1595 _ => csv_fields(&paths, Given::default())?,
1596 };
1597 let label = if alias == NONE {
1603 if is_pattern(path) {
1604 path.to_string()
1605 } else {
1606 let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
1607 file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
1608 }
1609 } else {
1610 ast.string(alias).to_string()
1611 };
1612 let arguments: Vec<ExprRef> = paths.iter().map(|path| self.path_constant(path)).collect();
1613 let names: Vec<&str> = ast.name(columns).collect();
1614 self.table_function_source(function, &arguments, &[], fields, &label, &names)
1615 }
1616
1617 fn path_constant(&mut self, path: &str) -> ExprRef {
1619 let value = self.plan.add_value(Value::Varchar(path.to_string()));
1620 self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar)
1621 }
1622
1623 fn reader_for(extension: &str) -> Option<TableFunction> {
1630 if extension.eq_ignore_ascii_case("parquet") {
1631 return Some(TableFunction::ReadParquet);
1632 }
1633 if extension.eq_ignore_ascii_case("csv") || extension.eq_ignore_ascii_case("tsv") {
1634 return Some(TableFunction::ReadCsv);
1635 }
1636 None
1637 }
1638
1639 fn table_function_source(
1644 &mut self,
1645 function: TableFunction,
1646 args: &[ExprRef],
1647 written: &[(&'static str, Value, ExprRef)],
1648 fields: Vec<Field>,
1649 label: &str,
1650 names: &[&str],
1651 ) -> Result<(NodeRef, Scope)> {
1652 let index = self.fresh_index();
1653 let mut scope = Scope::empty();
1654 for (at, field) in fields.iter().enumerate() {
1655 scope.push(Visible {
1656 table: label.to_string(),
1657 name: field.name.clone(),
1658 binding: ColumnBinding::new(index, at as u32),
1659 ty: field.ty.clone(),
1660 not_null: false,
1663 });
1664 }
1665 if !names.is_empty() {
1666 scope.rename(names, label)?;
1667 }
1668 let function = self.plan.intern(function.name());
1669 let args = self.plan.add_expr_list(args);
1670 let named: Vec<u32> =
1671 written.iter().map(|(parameter, _, _)| self.plan.intern(parameter)).collect();
1672 let settings: Vec<ExprRef> = written.iter().map(|(_, _, expr)| *expr).collect();
1673 let options = self.plan.add_name_list(&named);
1674 let settings = self.plan.add_expr_list(&settings);
1675 let columns = self.plan.add_fields(&fields);
1676 let node = self.plan.add_node(Node::TableFunction {
1677 index,
1678 function,
1679 args,
1680 options,
1681 settings,
1682 columns,
1683 });
1684 Ok((node, scope))
1685 }
1686
1687 fn file_paths(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1694 let mut paths = Vec::new();
1695 for pattern in self.file_patterns(expr, name)? {
1696 paths.extend(files(&pattern)?);
1697 }
1698 Ok(paths)
1699 }
1700
1701 fn file_patterns(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1713 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1714 return Err(Error::not_implemented(
1715 "a table function file name that is not a constant",
1716 ));
1717 };
1718 match self.plan.value(reference) {
1719 Value::Varchar(path) => Ok(vec![path.clone()]),
1720 Value::Null => Err(Error::parser(format!("{name} cannot take NULL list as parameter"))),
1722 Value::List { values, .. } => values
1723 .iter()
1724 .map(|value| match value {
1725 Value::Varchar(path) => Ok(path.clone()),
1726 _ => Err(Error::parser(format!(
1727 "{name} reader cannot take NULL input as parameter"
1728 ))),
1729 })
1730 .collect(),
1731 other => {
1732 Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
1733 }
1734 }
1735 }
1736
1737 #[allow(clippy::too_many_arguments)]
1738 fn bind_join(
1739 &mut self,
1740 ast: &Ast,
1741 left: ast::SourceRef,
1742 right: ast::SourceRef,
1743 kind: ast::JoinKind,
1744 natural: bool,
1745 on: ast::ExprRef,
1746 using: ast::Slice,
1747 ) -> Result<(NodeRef, Scope)> {
1748 let (left_node, left_scope) = self.bind_source(ast, left)?;
1749 let (right_node, right_scope) = self.bind_source(ast, right)?;
1750 let split = left_scope.len();
1751 let mut scope = left_scope.concat(right_scope);
1752
1753 let merged: Vec<String> = if natural {
1756 let mut names = Vec::new();
1757 for (at, column) in scope.columns.iter().enumerate().take(split) {
1758 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
1759 && !names.iter().any(|held: &String| same_name(held, &column.name))
1760 {
1761 let _ = at;
1762 names.push(column.name.clone());
1763 }
1764 }
1765 names
1766 } else {
1767 let mut names: Vec<String> = Vec::new();
1773 for name in ast.name(using) {
1774 if !names.iter().any(|held| same_name(held, name)) {
1775 names.push(name.to_string());
1776 }
1777 }
1778 names
1779 };
1780
1781 let mut conditions = Vec::new();
1782 let mut dropped = Vec::new();
1783 for name in &merged {
1784 let left_at = scope.columns[..split]
1785 .iter()
1786 .position(|column| same_name(&column.name, name))
1787 .ok_or_else(|| {
1788 Error::binder(format!(
1789 "column \"{name}\" specified in USING clause does not exist in left table"
1790 ))
1791 })?;
1792 let right_at = scope.columns[split..]
1793 .iter()
1794 .position(|column| same_name(&column.name, name))
1795 .map(|at| at + split)
1796 .ok_or_else(|| {
1797 Error::binder(format!(
1798 "column \"{name}\" specified in USING clause does not exist in right table"
1799 ))
1800 })?;
1801 let left_column = &scope.columns[left_at];
1802 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
1803 let right_column = &scope.columns[right_at];
1804 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
1805 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
1806 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
1807 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
1808 dropped.push(right_at);
1809 }
1810 dropped.sort_unstable();
1813 for at in dropped.into_iter().rev() {
1814 scope.remove(at);
1815 }
1816
1817 if on != NONE {
1818 if !merged.is_empty() {
1819 return Err(Error::binder("a join cannot have both ON and USING"));
1820 }
1821 self.clause = "JOIN condition";
1822 let predicate = self.bind_expr(ast, on, &scope)?;
1823 conditions.push(self.as_boolean(predicate, "JOIN")?);
1824 }
1825
1826 if kind == ast::JoinKind::Cross {
1827 if !conditions.is_empty() {
1828 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
1829 }
1830 let node =
1831 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1832 return Ok((node, scope));
1833 }
1834 if conditions.is_empty() && kind == ast::JoinKind::Inner {
1835 let node =
1836 self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1837 return Ok((node, scope));
1838 }
1839 let kind = match kind {
1840 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
1841 ast::JoinKind::Left => JoinKind::Left,
1842 ast::JoinKind::Right => JoinKind::Right,
1843 ast::JoinKind::Full => JoinKind::Full,
1844 ast::JoinKind::Semi => JoinKind::Semi,
1845 ast::JoinKind::Anti => JoinKind::Anti,
1846 ast::JoinKind::Positional => JoinKind::Positional,
1847 };
1848 let conditions = self.plan.add_expr_list(&conditions);
1849 let node =
1850 self.plan.add_node(Node::Join { left: left_node, right: right_node, kind, conditions });
1851 Ok((node, scope))
1852 }
1853
1854 pub(crate) fn bind_aggregate(
1858 &mut self,
1859 ast: &Ast,
1860 name: &str,
1861 args: &[ast::ExprRef],
1862 distinct: bool,
1863 scope: &Scope,
1864 ) -> Result<ExprRef> {
1865 if self.in_aggregate {
1866 return Err(Error::binder(format!(
1867 "aggregate function calls cannot be nested, and {name}() is inside one"
1868 )));
1869 }
1870 if self.aggregation.is_none() {
1871 return Err(Error::binder(format!(
1872 "aggregate function calls cannot be used in the {}",
1873 self.clause
1874 )));
1875 }
1876 self.in_aggregate = true;
1877 let mut bound = Vec::with_capacity(args.len());
1878 let mut failure = None;
1879 for &arg in args {
1880 match self.bind_expr(ast, arg, scope) {
1881 Ok(expr) => bound.push(expr),
1882 Err(error) => {
1883 failure = Some(error);
1884 break;
1885 }
1886 }
1887 }
1888 self.in_aggregate = false;
1889 if let Some(error) = failure {
1890 return Err(error);
1891 }
1892
1893 let types: Vec<LogicalType> =
1894 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
1895 let resolved = resolve(name, &types)?;
1896 let mut cast = Vec::with_capacity(bound.len());
1897 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
1898 cast.push(self.checked_cast_to(*arg, wanted, false)?);
1899 }
1900 let args = self.plan.add_expr_list(&cast);
1901 let name = self.plan.intern(resolved.name);
1902 let ty = resolved.returns;
1903 let call =
1904 self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter: None }, ty.clone());
1905
1906 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
1909 let existing = existing.unwrap_or_default();
1910 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
1911 Some(at) => at,
1912 None => {
1913 let aggregation = self.aggregation.as_mut().expect("checked above");
1914 aggregation.aggregates.push(call);
1915 aggregation.aggregates.len() - 1
1916 }
1917 };
1918 let aggregation = self.aggregation.as_ref().expect("checked above");
1919 let (index, groups) = (aggregation.index, aggregation.groups.len());
1920 Ok(self.column(index, groups + at, ty))
1921 }
1922
1923 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
1929 let Some(aggregation) = self.aggregation.as_ref() else {
1930 return Ok(expr);
1931 };
1932 let index = aggregation.index;
1933 let groups = aggregation.groups.clone();
1934 for (at, group) in groups.iter().enumerate() {
1935 if self.same_expr(expr, *group) {
1936 let ty = self.plan.expr_type(*group).clone();
1937 return Ok(self.column(index, at, ty));
1938 }
1939 }
1940 let ty = self.plan.expr_type(expr).clone();
1941 match self.plan.expr(expr).clone() {
1942 Expr::Column(binding) if binding.table == index => Ok(expr),
1943 Expr::Column(binding) => {
1944 let name =
1945 scope.columns.iter().find(|column| column.binding == binding).map_or_else(
1946 || "a column".to_string(),
1947 |column| format!("\"{}\"", column.name),
1948 );
1949 Err(Error::binder(format!(
1950 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
1951 )))
1952 }
1953 Expr::Constant(_) | Expr::Aggregate { .. } => Ok(expr),
1954 Expr::Cast { input, try_cast } => {
1955 let input = self.over_aggregate(input, scope)?;
1956 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
1957 }
1958 Expr::Compare { op, left, right } => {
1959 let left = self.over_aggregate(left, scope)?;
1960 let right = self.over_aggregate(right, scope)?;
1961 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
1962 }
1963 Expr::Conjunction { op, children } => {
1964 let written = self.plan.expr_list(children).to_vec();
1965 let mut rewritten = Vec::with_capacity(written.len());
1966 for child in written {
1967 rewritten.push(self.over_aggregate(child, scope)?);
1968 }
1969 let children = self.plan.add_expr_list(&rewritten);
1970 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
1971 }
1972 Expr::Function { name, args } => {
1973 let written = self.plan.expr_list(args).to_vec();
1974 let mut rewritten = Vec::with_capacity(written.len());
1975 for arg in written {
1976 rewritten.push(self.over_aggregate(arg, scope)?);
1977 }
1978 let args = self.plan.add_expr_list(&rewritten);
1979 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
1980 }
1981 Expr::Case { arms, otherwise } => {
1982 let written = self.plan.arm_list(arms).to_vec();
1983 let mut rewritten = Vec::with_capacity(written.len());
1984 for arm in written {
1985 let when = self.over_aggregate(arm.when, scope)?;
1986 let then = self.over_aggregate(arm.then, scope)?;
1987 rewritten.push(rudb_plan::Arm { when, then });
1988 }
1989 let otherwise = match otherwise {
1990 Some(expr) => Some(self.over_aggregate(expr, scope)?),
1991 None => None,
1992 };
1993 let arms = self.plan.add_arms(&rewritten);
1994 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
1995 }
1996 }
1997 }
1998
1999 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
2001 same_expr(&self.plan, left, right)
2002 }
2003}
2004
2005#[derive(Debug, Default)]
2015struct Options {
2016 binary_as_string: bool,
2019 all_varchar: bool,
2021 file_row_number: bool,
2026 given: Given,
2028}
2029
2030impl Options {
2031 fn of(written: &[(&'static str, Value, ExprRef)]) -> Result<Self> {
2038 let mut options = Self::default();
2039 for (parameter, value, _) in written {
2040 match (*parameter, value) {
2041 ("binary_as_string", Value::Boolean(on)) => options.binary_as_string = *on,
2042 ("all_varchar", Value::Boolean(on)) => options.all_varchar = *on,
2043 ("file_row_number", Value::Boolean(on)) => options.file_row_number = *on,
2044 _ => {}
2045 }
2046 }
2047 let named: Vec<(&str, Value)> =
2048 written.iter().map(|(parameter, value, _)| (*parameter, value.clone())).collect();
2049 options.given = csv_given(&named)?;
2050 Ok(options)
2051 }
2052}
2053
2054fn null_parameter(function: TableFunction, parameter: &str) -> String {
2063 match parameter {
2064 "header" => format!("\"{parameter}\" expects a non-null boolean value (e.g. TRUE or 1)"),
2065 "all_varchar" => format!("{} \"{parameter}\" cannot be NULL", function.name()),
2066 _ => format!("Cannot use NULL as argument to \"{parameter}\""),
2067 }
2068}
2069
2070fn missing_replacement(name: &str, input: &Scope) -> Error {
2075 Error::binder(format!(
2076 "Column \"{name}\" in REPLACE list not found in FROM clause{}",
2077 input.candidates()
2078 ))
2079}
2080
2081fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
2083 if left == right {
2084 return true;
2085 }
2086 if plan.expr_type(left) != plan.expr_type(right) {
2087 return false;
2088 }
2089 let lists = |left, right| {
2090 let left: &[ExprRef] = plan.expr_list(left);
2091 let right: &[ExprRef] = plan.expr_list(right);
2092 left.len() == right.len()
2093 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
2094 };
2095 match (plan.expr(left), plan.expr(right)) {
2096 (Expr::Column(left), Expr::Column(right)) => left == right,
2097 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
2098 (
2099 Expr::Cast { input: left, try_cast: left_try },
2100 Expr::Cast { input: right, try_cast: right_try },
2101 ) => left_try == right_try && same_expr(plan, *left, *right),
2102 (
2103 Expr::Compare { op: left_op, left: left_a, right: left_b },
2104 Expr::Compare { op: right_op, left: right_a, right: right_b },
2105 ) => {
2106 left_op == right_op
2107 && same_expr(plan, *left_a, *right_a)
2108 && same_expr(plan, *left_b, *right_b)
2109 }
2110 (
2111 Expr::Conjunction { op: left_op, children: left_children },
2112 Expr::Conjunction { op: right_op, children: right_children },
2113 ) => left_op == right_op && lists(*left_children, *right_children),
2114 (
2115 Expr::Function { name: left_name, args: left_args },
2116 Expr::Function { name: right_name, args: right_args },
2117 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
2118 (
2119 Expr::Aggregate {
2120 name: left_name,
2121 args: left_args,
2122 distinct: left_distinct,
2123 filter: left_filter,
2124 },
2125 Expr::Aggregate {
2126 name: right_name,
2127 args: right_args,
2128 distinct: right_distinct,
2129 filter: right_filter,
2130 },
2131 ) => {
2132 plan.string(*left_name) == plan.string(*right_name)
2133 && left_distinct == right_distinct
2134 && match (left_filter, right_filter) {
2135 (None, None) => true,
2136 (Some(left), Some(right)) => same_expr(plan, *left, *right),
2137 _ => false,
2138 }
2139 && lists(*left_args, *right_args)
2140 }
2141 (
2142 Expr::Case { arms: left_arms, otherwise: left_otherwise },
2143 Expr::Case { arms: right_arms, otherwise: right_otherwise },
2144 ) => {
2145 let left_arms = plan.arm_list(*left_arms);
2146 let right_arms = plan.arm_list(*right_arms);
2147 left_arms.len() == right_arms.len()
2148 && left_arms.iter().zip(right_arms).all(|(left, right)| {
2149 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
2150 })
2151 && match (left_otherwise, right_otherwise) {
2152 (None, None) => true,
2153 (Some(left), Some(right)) => same_expr(plan, *left, *right),
2154 _ => false,
2155 }
2156 }
2157 _ => false,
2158 }
2159}