1use rudb_catalog::{Catalog, Entry, QualifiedName, same_name};
16use rudb_common::{
17 Error, Field, LogicalType, Result, Semantics, Session, ShowBehavior, Span, Value,
18};
19use rudb_functions::{
20 Columns, FILE_ROW_NUMBER, Given, TableFunction, csv_fields, csv_given, files, is_file,
21 is_pattern, parquet_fields, resolve, resolve_pragma, resolve_table,
22};
23use rudb_parse::ast::{self, Ast, Distinct, LiteralKind, Nulls, Order, Quantifier, SetOp};
24use rudb_parse::{NONE, identifier_parts, parse_ast_with_case};
25use rudb_plan::{ColumnBinding, Expr, ExprRef, JoinKind, Node, NodeRef, Plan, SetOpKind, SortKey};
26
27use crate::expr::{describe, has_aggregate};
28use crate::parameters::Parameters;
29use crate::scope::{Scope, Visible};
30
31pub fn bind(ast: &Ast, catalog: &Catalog) -> Result<Plan> {
38 bind_with(ast, catalog, &Parameters::new(), &Session::new())
39}
40
41pub fn bind_with(
50 ast: &Ast,
51 catalog: &Catalog,
52 parameters: &Parameters,
53 session: &Session,
54) -> Result<Plan> {
55 let query = match ast.statements.as_slice() {
56 [ast::Statement::Query(query)] => *query,
57 [] => return Err(Error::binder("no statement to bind")),
58 [_] => return Err(Error::not_implemented("a statement that is not a query")),
61 _ => return Err(Error::not_implemented("a script of more than one statement")),
62 };
63 let mut binder = Binder::with(catalog, parameters, session);
64 let (root, _) = binder.bind_query(ast, query)?;
65 let mut plan = binder.into_plan();
66 plan.set_root(root);
67 plan.validate()?;
68 Ok(plan)
69}
70
71pub fn bind_sql(query: &str, catalog: &Catalog) -> Result<Plan> {
77 bind_sql_with(query, catalog, &Session::new())
78}
79
80pub fn bind_sql_with(query: &str, catalog: &Catalog, session: &Session) -> Result<Plan> {
86 let ast = parse_ast_with_case(query, session.semantics().identifier_case())?;
87 bind_with(&ast, catalog, &Parameters::new(), session)
88}
89
90#[derive(Debug)]
92pub(crate) struct Aggregation {
93 pub(crate) index: u32,
95 pub(crate) groups: Vec<ExprRef>,
97 pub(crate) aggregates: Vec<ExprRef>,
99}
100
101#[derive(Debug)]
102pub(crate) struct PendingSubquery {
103 pub(crate) node: NodeRef,
104 pub(crate) kind: JoinKind,
105 pub(crate) conditions: Vec<ExprRef>,
106 pub(crate) dependent: bool,
107}
108
109#[derive(Debug)]
111pub(crate) struct Binder<'a> {
112 catalog: &'a Catalog,
113 pub(crate) parameters: &'a Parameters,
115 pub(crate) session: &'a Session,
117 pub(crate) semantics: Semantics,
119 plan: Plan,
120 next_index: u32,
121 pub(crate) current_span: Span,
123 pub(crate) aggregation: Option<Aggregation>,
125 pub(crate) in_aggregate: bool,
127 pub(crate) scalar_subqueries: Vec<PendingSubquery>,
129 pub(crate) outer_scopes: Vec<Scope>,
130 pub(crate) correlations: Vec<Vec<ColumnBinding>>,
131 pub(crate) clause: &'static str,
133 expanding: Vec<String>,
135 started: Option<i64>,
137}
138
139impl<'a> Binder<'a> {
140 pub(crate) fn with(
141 catalog: &'a Catalog,
142 parameters: &'a Parameters,
143 session: &'a Session,
144 ) -> Self {
145 Self {
146 catalog,
147 parameters,
148 session,
149 semantics: session.semantics(),
150 plan: Plan::new(),
151 next_index: 0,
152 current_span: Span::new(0, 0),
153 aggregation: None,
154 in_aggregate: false,
155 scalar_subqueries: Vec::new(),
156 outer_scopes: Vec::new(),
157 correlations: Vec::new(),
158 clause: "SELECT clause",
159 expanding: Vec::new(),
160 started: None,
161 }
162 }
163
164 pub(crate) fn catalog(&self) -> &Catalog {
165 self.catalog
166 }
167
168 pub(crate) fn instant(&mut self) -> i64 {
175 *self.started.get_or_insert_with(crate::context::micros_now)
176 }
177
178 pub(crate) fn plan(&self) -> &Plan {
179 &self.plan
180 }
181
182 pub(crate) fn plan_mut(&mut self) -> &mut Plan {
183 &mut self.plan
184 }
185
186 pub(crate) fn add_expr(&mut self, expr: Expr, ty: LogicalType) -> ExprRef {
187 self.plan.add_expr_at(expr, ty, self.current_span)
188 }
189
190 pub(crate) fn add_constant(&mut self, value: Value) -> ExprRef {
191 let ty = value.logical_type();
192 let reference = self.plan.add_value(value);
193 self.plan.add_expr_at(Expr::Constant(reference), ty, self.current_span)
194 }
195
196 pub(crate) fn add_node(&mut self, node: Node) -> NodeRef {
197 self.plan.add_node_at(node, self.current_span)
198 }
199
200 pub(crate) fn into_plan(self) -> Plan {
201 self.plan
202 }
203
204 pub(crate) fn fresh_index(&mut self) -> u32 {
206 let index = self.next_index;
207 self.next_index += 1;
208 index
209 }
210
211 fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
213 let binding = ColumnBinding::new(index, position as u32);
214 self.plan.add_expr(Expr::Column(binding), ty)
215 }
216
217 fn attach_scalar_subqueries(&mut self, mut input: NodeRef) -> NodeRef {
219 let subqueries = std::mem::take(&mut self.scalar_subqueries);
220 for pending in subqueries {
221 let PendingSubquery { node: mut right, kind, conditions, dependent } = pending;
222 if kind == JoinKind::Single && !self.semantics.scalar_subquery_error_on_multiple_rows()
223 {
224 right = self.add_node(Node::Limit { input: right, count: Some(1), offset: 0 });
225 }
226 let conditions = self.plan.add_expr_list(&conditions);
227 input = if dependent {
228 self.add_node(Node::DependentJoin { left: input, right, kind, conditions })
229 } else {
230 self.add_node(Node::Join { left: input, right, kind, conditions })
231 };
232 }
233 input
234 }
235
236 pub(crate) fn bind_query(
239 &mut self,
240 ast: &Ast,
241 query: ast::QueryRef,
242 ) -> Result<(NodeRef, Scope)> {
243 let span = ast.query_span(query);
244 let outer = std::mem::replace(&mut self.current_span, span);
245 let result =
246 self.bind_query_inner(ast, query).map_err(|error| error.with_fallback_span(span));
247 self.current_span = outer;
248 result
249 }
250
251 fn bind_query_inner(&mut self, ast: &Ast, query: ast::QueryRef) -> Result<(NodeRef, Scope)> {
252 let written = ast.query(query);
253 match written.body {
254 ast::QueryBody::Select(select) => self.bind_select(ast, select, &written),
255 ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
256 if by_name {
257 return Err(Error::not_implemented("UNION BY NAME"));
258 }
259 self.bind_set_op(ast, &written, op, quantifier, left, right)
260 }
261 ast::QueryBody::Values(rows) => self.bind_values(ast, &written, rows),
262 ast::QueryBody::Describe(inner) => self.bind_describe(ast, &written, inner),
263 ast::QueryBody::Show { name, relation } => {
264 self.bind_show(ast, &written, name, relation)
265 }
266 }
267 }
268
269 fn bind_show(
271 &mut self,
272 ast: &Ast,
273 query: &ast::Query,
274 name: ast::Slice,
275 relation: ast::QueryRef,
276 ) -> Result<(NodeRef, Scope)> {
277 let text = ast.name_text(name);
278 let parts: Vec<&str> = ast.name(name).collect();
279 let table_exists = self.catalog.resolve(&parts).is_ok();
280 let as_table = match self.semantics.show_behavior() {
281 ShowBehavior::Auto => table_exists,
282 ShowBehavior::Setting => false,
283 ShowBehavior::Table => true,
284 };
285 if as_table {
286 return self.bind_describe(ast, query, relation);
287 }
288 let Some((_, value)) =
289 self.session.iter().find(|(name, _)| name.eq_ignore_ascii_case(&text))
290 else {
291 return Err(Error::catalog(format!("Setting with name \"{text}\" does not exist")));
292 };
293 let field = Field::new(text, LogicalType::Varchar);
294 let expr = self.plan.add_constant(Value::Varchar(value.to_string()));
295 let row = self.plan.add_expr_list(&[expr]);
296 let rows = self.plan.add_rows(&[row]);
297 let columns = self.plan.add_fields(std::slice::from_ref(&field));
298 let index = self.fresh_index();
299 let node = self.add_node(Node::Values { index, columns, rows });
300 let mut scope = Scope::empty();
301 scope.push(Visible {
302 table: String::new(),
303 name: field.name,
304 binding: ColumnBinding::new(index, 0),
305 ty: LogicalType::Varchar,
306 not_null: false,
307 });
308 Ok((node, scope))
309 }
310
311 fn bind_describe(
327 &mut self,
328 ast: &Ast,
329 query: &ast::Query,
330 inner: ast::QueryRef,
331 ) -> Result<(NodeRef, Scope)> {
332 let (_, described) = self.bind_query(ast, inner)?;
333 let fields: Vec<Field> = ["column_name", "column_type", "null", "key", "default", "extra"]
334 .iter()
335 .map(|name| Field::new(*name, LogicalType::Varchar))
336 .collect();
337 let mut slices = Vec::with_capacity(described.columns.len());
338 for column in described.columns.clone() {
339 let written = [
342 column.name.clone(),
343 column.ty.to_string(),
344 if column.not_null { "NO" } else { "YES" }.to_owned(),
345 ];
346 let mut items: Vec<ExprRef> = written
347 .into_iter()
348 .map(|text| self.plan.add_constant(Value::Varchar(text)))
349 .collect();
350 for _ in 0..3 {
351 let empty = self.plan.add_constant(Value::Null);
352 items.push(self.cast_to(empty, &LogicalType::Varchar));
353 }
354 slices.push(self.plan.add_expr_list(&items));
355 }
356 let rows = self.plan.add_rows(&slices);
357 let columns = self.plan.add_fields(&fields);
358 let index = self.fresh_index();
359 let mut node = self.add_node(Node::Values { index, columns, rows });
360 let mut scope = Scope::empty();
361 for (at, field) in fields.iter().enumerate() {
362 scope.push(Visible {
363 table: String::new(),
364 name: field.name.clone(),
365 binding: ColumnBinding::new(index, at as u32),
366 ty: field.ty.clone(),
367 not_null: false,
368 });
369 }
370 let keys = self.sort_keys(ast, query, &scope, &[])?;
371 if !keys.is_empty() {
372 let keys = self.plan.add_sort_keys(&keys);
373 node = self.add_node(Node::Sort { input: node, keys });
374 }
375 node = self.apply_limit(ast, query, node)?;
376 Ok((node, scope))
377 }
378
379 fn passes_through(&self, expr: ExprRef, input: &Scope) -> bool {
385 let Expr::Column(binding) = *self.plan.expr(expr) else { return false };
386 input.columns.iter().any(|column| column.binding == binding && column.not_null)
387 }
388
389 fn bind_values(
396 &mut self,
397 ast: &Ast,
398 query: &ast::Query,
399 rows: ast::Slice,
400 ) -> Result<(NodeRef, Scope)> {
401 let written = ast.rows(rows).to_vec();
402 let Some(first) = written.first() else {
403 return Err(Error::binder("VALUES needs at least one row"));
404 };
405 let width = first.len as usize;
406 for (at, row) in written.iter().enumerate() {
407 if row.len as usize != width {
408 return Err(Error::binder(format!(
409 "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
410 at + 1,
411 row.len
412 )));
413 }
414 }
415 let empty = Scope::empty();
417 let previous = std::mem::replace(&mut self.clause, "VALUES clause");
418 let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
419 for row in &written {
420 let mut items = Vec::with_capacity(width);
421 for &expr in ast.expr_list(*row) {
422 items.push(self.bind_expr(ast, expr, &empty)?);
423 }
424 bound.push(items);
425 }
426 self.clause = previous;
427 let mut types = Vec::with_capacity(width);
428 for at in 0..width {
429 let mut ty = self.plan.expr_type(bound[0][at]).clone();
430 for row in &bound[1..] {
431 let other = self.plan.expr_type(row[at]).clone();
432 ty = ty.promote(&other).ok_or_else(|| {
433 Error::binder(format!(
434 "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
435 at + 1
436 ))
437 })?;
438 }
439 types.push(ty);
440 }
441 let mut slices = Vec::with_capacity(bound.len());
442 for row in &bound {
443 let items: Vec<ExprRef> = row
444 .iter()
445 .zip(&types)
446 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
447 .collect::<Result<_>>()?;
448 slices.push(self.plan.add_expr_list(&items));
449 }
450 let rows = self.plan.add_rows(&slices);
451 let fields: Vec<Field> = types
452 .iter()
453 .enumerate()
454 .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
455 .collect();
456 let columns = self.plan.add_fields(&fields);
457 let index = self.fresh_index();
458 let mut node = self.add_node(Node::Values { index, columns, rows });
459 let mut scope = Scope::empty();
460 for (at, field) in fields.iter().enumerate() {
461 scope.push(Visible {
462 table: String::new(),
463 name: field.name.clone(),
464 binding: ColumnBinding::new(index, at as u32),
465 ty: field.ty.clone(),
466 not_null: false,
467 });
468 }
469 let keys = self.sort_keys(ast, query, &scope, &[])?;
470 if !keys.is_empty() {
471 let keys = self.plan.add_sort_keys(&keys);
472 node = self.add_node(Node::Sort { input: node, keys });
473 }
474 node = self.apply_limit(ast, query, node)?;
475 Ok((node, scope))
476 }
477
478 fn bind_set_op(
479 &mut self,
480 ast: &Ast,
481 query: &ast::Query,
482 op: SetOp,
483 quantifier: Quantifier,
484 left: ast::QueryRef,
485 right: ast::QueryRef,
486 ) -> Result<(NodeRef, Scope)> {
487 let (left_node, left_scope) = self.bind_query(ast, left)?;
488 let (right_node, right_scope) = self.bind_query(ast, right)?;
489 if left_scope.len() != right_scope.len() {
490 return Err(Error::binder(format!(
491 "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
492 left_scope.len(),
493 right_scope.len()
494 )));
495 }
496 let mut types = Vec::with_capacity(left_scope.len());
498 for (left, right) in left_scope.columns.iter().zip(&right_scope.columns) {
499 let common = left.ty.promote(&right.ty).ok_or_else(|| {
500 Error::binder(format!(
501 "Cannot combine a column of type {} with a column of type {} in a set operation",
502 left.ty, right.ty
503 ))
504 })?;
505 types.push(common);
506 }
507 let left_node = self.conform(left_node, &left_scope, &types)?;
508 let right_node = self.conform(right_node, &right_scope, &types)?;
509 let index = self.fresh_index();
510 let kind = match op {
511 SetOp::Union => SetOpKind::Union,
512 SetOp::Except => SetOpKind::Except,
513 SetOp::Intersect => SetOpKind::Intersect,
514 };
515 let all = quantifier == Quantifier::All;
518 let mut node =
519 self.add_node(Node::SetOp { left: left_node, right: right_node, kind, all, index });
520 let mut scope = Scope::empty();
521 for (at, (column, ty)) in left_scope.columns.iter().zip(&types).enumerate() {
522 scope.push(Visible {
523 table: String::new(),
524 name: column.name.clone(),
525 binding: ColumnBinding::new(index, at as u32),
526 ty: ty.clone(),
527 not_null: false,
530 });
531 }
532 let keys = self.sort_keys(ast, query, &scope, &[])?;
536 if !keys.is_empty() {
537 let keys = self.plan.add_sort_keys(&keys);
538 node = self.add_node(Node::Sort { input: node, keys });
539 }
540 node = self.apply_limit(ast, query, node)?;
541 Ok((node, scope))
542 }
543
544 fn conform(&mut self, node: NodeRef, scope: &Scope, types: &[LogicalType]) -> Result<NodeRef> {
546 if scope.columns.iter().zip(types).all(|(column, ty)| &column.ty == ty) {
547 return Ok(node);
548 }
549 let index = self.fresh_index();
550 let mut exprs = Vec::with_capacity(types.len());
551 let mut names = Vec::with_capacity(types.len());
552 for (column, ty) in scope.columns.iter().zip(types) {
553 let expr = self.plan.add_expr(Expr::Column(column.binding), column.ty.clone());
554 exprs.push(self.checked_cast_to(expr, ty, false)?);
555 names.push(self.plan.intern(&column.name));
556 }
557 let exprs = self.plan.add_expr_list(&exprs);
558 let names = self.plan.add_name_list(&names);
559 Ok(self.add_node(Node::Project { input: node, index, exprs, names }))
560 }
561
562 fn bind_select(
565 &mut self,
566 ast: &Ast,
567 select: ast::SelectRef,
568 query: &ast::Query,
569 ) -> Result<(NodeRef, Scope)> {
570 let written = ast.select(select);
571 let (mut node, input) = self.bind_from(ast, written.from)?;
572 node = self.attach_scalar_subqueries(node);
573
574 if written.filter != NONE {
575 self.clause = "WHERE clause";
576 let predicate = self.bind_expr(ast, written.filter, &input)?;
577 let predicate = self.as_boolean(predicate, "WHERE")?;
578 node = self.attach_scalar_subqueries(node);
579 node = self.add_node(Node::Filter { input: node, predicate });
580 }
581
582 let targets = ast.target_list(written.targets).to_vec();
583 if targets.is_empty() {
584 return Err(Error::binder("a SELECT needs at least one expression to select"));
585 }
586
587 let group_items = self.group_items(ast, &written, &targets)?;
588 let aggregating = !group_items.is_empty()
589 || written.having != NONE
590 || targets.iter().any(|target| has_aggregate(ast, target.expr));
591 if aggregating {
592 self.clause = "GROUP BY clause";
593 let mut groups = Vec::with_capacity(group_items.len());
594 for item in &group_items {
595 groups.push(self.bind_expr(ast, *item, &input)?);
596 }
597 let index = self.fresh_index();
598 self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
599 }
600
601 self.clause = "SELECT clause";
602 let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input)?;
603 let visible = exprs.len();
604
605 let mut having = None;
606 if written.having != NONE {
607 self.clause = "HAVING clause";
608 let predicate = self.bind_expr(ast, written.having, &input)?;
609 let predicate = self.over_aggregate(predicate, &input)?;
610 having = Some(self.as_boolean(predicate, "HAVING")?);
611 }
612
613 let project = self.fresh_index();
616 let mut output = Scope::empty();
617 for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
618 output.push(Visible {
619 table: String::new(),
620 name: name.clone(),
621 binding: ColumnBinding::new(project, at as u32),
622 ty: self.plan.expr_type(*expr).clone(),
623 not_null: self.passes_through(*expr, &input),
624 });
625 }
626
627 self.clause = "ORDER BY clause";
628 let mut extra = Vec::new();
629 let keys = self.select_sort_keys(
630 ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra,
631 )?;
632 if !extra.is_empty() && written.distinct != Distinct::No {
633 return Err(Error::binder(
634 "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
635 ));
636 }
637 let on = self.distinct_on(ast, written.distinct, &output)?;
638
639 node = self.attach_scalar_subqueries(node);
640
641 if let Some(aggregation) = self.aggregation.take() {
642 let index = aggregation.index;
643 let groups = self.plan.add_expr_list(&aggregation.groups);
644 let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
645 node = self.add_node(Node::Aggregate { input: node, index, groups, aggregates });
646 }
647 if let Some(predicate) = having {
648 node = self.add_node(Node::Filter { input: node, predicate });
649 }
650
651 let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
652 let exprs_slice = self.plan.add_expr_list(&exprs);
653 let names_slice = self.plan.add_name_list(&interned);
654 node = self.add_node(Node::Project {
655 input: node,
656 index: project,
657 exprs: exprs_slice,
658 names: names_slice,
659 });
660
661 if written.distinct != Distinct::No {
662 let on = self.plan.add_expr_list(&on);
663 node = self.add_node(Node::Distinct { input: node, on });
664 }
665 if !keys.is_empty() {
666 let keys = self.plan.add_sort_keys(&keys);
667 node = self.add_node(Node::Sort { input: node, keys });
668 }
669 node = self.apply_limit(ast, query, node)?;
670
671 if extra.is_empty() {
672 output.columns.truncate(visible);
673 return Ok((node, output));
674 }
675 let index = self.fresh_index();
678 let mut kept = Vec::with_capacity(visible);
679 let mut kept_names = Vec::with_capacity(visible);
680 let mut scope = Scope::empty();
681 for (at, name) in names.iter().enumerate().take(visible) {
682 let ty = output.columns[at].ty.clone();
683 kept.push(self.column(project, at, ty.clone()));
684 kept_names.push(self.plan.intern(name));
685 scope.push(Visible {
686 table: String::new(),
687 name: name.clone(),
688 binding: ColumnBinding::new(index, at as u32),
689 ty,
690 not_null: output.columns[at].not_null,
691 });
692 }
693 let exprs = self.plan.add_expr_list(&kept);
694 let names = self.plan.add_name_list(&kept_names);
695 node = self.add_node(Node::Project { input: node, index, exprs, names });
696 Ok((node, scope))
697 }
698
699 fn bind_targets(
701 &mut self,
702 ast: &Ast,
703 targets: &[ast::Target],
704 input: &Scope,
705 ) -> Result<(Vec<ExprRef>, Vec<String>)> {
706 let mut exprs = Vec::with_capacity(targets.len());
707 let mut names = Vec::with_capacity(targets.len());
708 for target in targets {
709 if let ast::Expr::Star { qualifier, replacements } = ast.expr(target.expr) {
710 let table = ast.name(qualifier).last().map(str::to_string);
711 let expanded: Vec<Visible> =
712 input.star(table.as_deref())?.into_iter().cloned().collect();
713 let replacements = ast.target_list(replacements).to_vec();
714 let mut used = vec![false; replacements.len()];
715 for column in expanded {
716 let found = replacements.iter().zip(&mut used).find(|(replacement, _)| {
717 same_name(ast.string(replacement.alias), &column.name)
718 });
719 let (expr, name) = match found {
724 Some((replacement, used)) => {
725 *used = true;
726 let expr = self.bind_expr(ast, replacement.expr, input)?;
727 (expr, ast.string(replacement.alias).to_string())
728 }
729 None => (
730 self.plan.add_expr(Expr::Column(column.binding), column.ty),
731 column.name,
732 ),
733 };
734 exprs.push(self.over_aggregate(expr, input)?);
735 names.push(name);
736 }
737 if let Some((replacement, _)) =
741 replacements.iter().zip(&used).find(|(_, used)| !**used)
742 {
743 return Err(missing_replacement(ast.string(replacement.alias), input));
744 }
745 continue;
746 }
747 let expr = self.bind_expr(ast, target.expr, input)?;
748 exprs.push(self.over_aggregate(expr, input)?);
749 names.push(if target.alias == NONE {
750 self.output_name(ast, target.expr, input)
751 } else {
752 ast.string(target.alias).to_string()
753 });
754 }
755 Ok((exprs, names))
756 }
757
758 fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
764 if let ast::Expr::Column { name } = ast.expr(target) {
765 let parts: Vec<&str> = ast.name(name).collect();
766 if let Ok(found) = input.resolve(&parts) {
767 return found.name.clone();
768 }
769 }
770 describe(ast, target, self.semantics)
771 }
772
773 fn group_items(
775 &self,
776 ast: &Ast,
777 select: &ast::Select,
778 targets: &[ast::Target],
779 ) -> Result<Vec<ast::ExprRef>> {
780 if select.group_by_all {
781 return Ok(targets
784 .iter()
785 .filter(|target| !has_aggregate(ast, target.expr))
786 .map(|target| target.expr)
787 .collect());
788 }
789 let mut items = Vec::new();
790 for &item in ast.expr_list(select.group_by) {
791 items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
792 }
793 Ok(items)
794 }
795
796 fn output_reference(
798 &self,
799 ast: &Ast,
800 item: ast::ExprRef,
801 targets: &[ast::Target],
802 clause: &str,
803 ) -> Result<Option<ast::ExprRef>> {
804 match ast.expr(item) {
805 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
806 let written = ast.string(text);
807 let position: usize = written.parse().map_err(|_| {
808 Error::binder(format!("{clause} term {written} is not a column"))
809 })?;
810 if position == 0 || position > targets.len() {
811 return Err(Error::binder(format!(
812 "{clause} term out of range - should be between 1 and {}",
813 targets.len()
814 )));
815 }
816 Ok(Some(targets[position - 1].expr))
817 }
818 ast::Expr::Column { name } => {
819 let parts: Vec<&str> = ast.name(name).collect();
820 let [written] = parts.as_slice() else { return Ok(None) };
821 let mut found = None;
822 for target in targets {
823 if target.alias != NONE && same_name(ast.string(target.alias), written) {
824 if found.is_some() {
825 return Ok(None);
826 }
827 found = Some(target.expr);
828 }
829 }
830 Ok(found)
831 }
832 _ => Ok(None),
833 }
834 }
835
836 #[allow(clippy::too_many_arguments)]
840 fn select_sort_keys(
841 &mut self,
842 ast: &Ast,
843 query: &ast::Query,
844 input: &Scope,
845 output: &Scope,
846 project: u32,
847 exprs: &mut Vec<ExprRef>,
848 names: &mut Vec<String>,
849 extra: &mut Vec<usize>,
850 ) -> Result<Vec<SortKey>> {
851 if query.order_by_all {
852 return Ok(self.every_column(output));
853 }
854 let items = ast.order_list(query.order_by).to_vec();
855 let mut keys = Vec::with_capacity(items.len());
856 for item in items {
857 self.check_order_literal(ast, item.expr)?;
858 let position = match self.output_position(ast, item.expr, output)? {
859 Some(position) => position,
860 None => {
861 let bound = self.bind_expr(ast, item.expr, input)?;
862 let bound = self.over_aggregate(bound, input)?;
863 match exprs.iter().position(|&held| self.same_expr(held, bound)) {
864 Some(position) => position,
865 None => {
866 exprs.push(bound);
867 names.push(describe(ast, item.expr, self.semantics));
868 extra.push(exprs.len() - 1);
869 exprs.len() - 1
870 }
871 }
872 }
873 };
874 let ty = self.plan.expr_type(exprs[position]).clone();
875 let expr = self.column(project, position, ty);
876 keys.push(self.sort_key(expr, item));
877 }
878 Ok(keys)
879 }
880
881 fn sort_keys(
883 &mut self,
884 ast: &Ast,
885 query: &ast::Query,
886 output: &Scope,
887 targets: &[ast::Target],
888 ) -> Result<Vec<SortKey>> {
889 if query.order_by_all {
890 return Ok(self.every_column(output));
891 }
892 let items = ast.order_list(query.order_by).to_vec();
893 let mut keys = Vec::with_capacity(items.len());
894 for item in items {
895 self.check_order_literal(ast, item.expr)?;
896 let expr = match self.output_position(ast, item.expr, output)? {
897 Some(position) => {
898 let column = &output.columns[position];
899 let (binding, ty) = (column.binding, column.ty.clone());
900 self.plan.add_expr(Expr::Column(binding), ty)
901 }
902 None => {
903 let _ = targets;
904 self.bind_expr(ast, item.expr, output)?
905 }
906 };
907 keys.push(self.sort_key(expr, item));
908 }
909 Ok(keys)
910 }
911
912 fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
913 let columns: Vec<(ColumnBinding, LogicalType)> =
914 output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
915 columns
916 .into_iter()
917 .map(|(binding, ty)| {
918 let expr = self.plan.add_expr(Expr::Column(binding), ty);
919 let descending = self.semantics.default_descending();
920 SortKey { expr, descending, nulls_first: self.semantics.nulls_first(descending) }
921 })
922 .collect()
923 }
924
925 fn sort_key(&self, expr: ExprRef, item: ast::OrderItem) -> SortKey {
927 let descending = match item.order {
928 Order::Unstated => self.semantics.default_descending(),
929 Order::Ascending => false,
930 Order::Descending => true,
931 };
932 let nulls_first = match item.nulls {
933 Nulls::First => true,
934 Nulls::Last => false,
935 Nulls::Unstated => self.semantics.nulls_first(descending),
936 };
937 SortKey { expr, descending, nulls_first }
938 }
939
940 fn output_position(
942 &self,
943 ast: &Ast,
944 item: ast::ExprRef,
945 output: &Scope,
946 ) -> Result<Option<usize>> {
947 match ast.expr(item) {
948 ast::Expr::Literal { kind: LiteralKind::Number, text } => {
949 let written = ast.string(text);
950 if written.contains(['.', 'e', 'E']) {
951 return Ok(None);
952 }
953 let position: usize = written.parse().map_err(|_| {
954 Error::binder(format!("ORDER BY term {written} is not a column"))
955 })?;
956 if position == 0 || position > output.len() {
957 return Err(Error::binder(format!(
958 "ORDER BY term out of range - should be between 1 and {}",
959 output.len()
960 )));
961 }
962 Ok(Some(position - 1))
963 }
964 ast::Expr::Column { name } => {
965 let parts: Vec<&str> = ast.name(name).collect();
966 let [written] = parts.as_slice() else { return Ok(None) };
967 Ok(output.position_of(None, written))
968 }
969 _ => Ok(None),
970 }
971 }
972
973 fn check_order_literal(&self, ast: &Ast, item: ast::ExprRef) -> Result<()> {
975 if !self.semantics.order_by_non_integer_literal()
976 && matches!(
977 ast.expr(item),
978 ast::Expr::Literal { kind, text }
979 if kind != LiteralKind::Number
980 || ast.string(text).contains(['.', 'e', 'E'])
981 )
982 {
983 return Err(Error::binder(
984 "ORDER BY non-integer literal has no effect.\n* SET order_by_non_integer_literal=true to allow this behavior.",
985 ));
986 }
987 Ok(())
988 }
989
990 fn distinct_on(
992 &mut self,
993 ast: &Ast,
994 distinct: Distinct,
995 output: &Scope,
996 ) -> Result<Vec<ExprRef>> {
997 let Distinct::On(items) = distinct else {
998 return Ok(Vec::new());
999 };
1000 let items = ast.expr_list(items).to_vec();
1001 let mut on = Vec::with_capacity(items.len());
1002 for item in items {
1003 let Some(position) = self.output_position(ast, item, output)? else {
1004 return Err(Error::not_implemented(
1005 "DISTINCT ON an expression that is not in the select list",
1006 ));
1007 };
1008 let column = &output.columns[position];
1009 let (binding, ty) = (column.binding, column.ty.clone());
1010 on.push(self.plan.add_expr(Expr::Column(binding), ty));
1011 }
1012 Ok(on)
1013 }
1014
1015 fn apply_limit(&mut self, ast: &Ast, query: &ast::Query, input: NodeRef) -> Result<NodeRef> {
1016 if query.limit_percent {
1017 return Err(Error::not_implemented("LIMIT with a percentage"));
1018 }
1019 let count = self.constant_count(ast, query.limit, "LIMIT")?;
1020 let offset = self.constant_count(ast, query.offset, "OFFSET")?.unwrap_or(0);
1021 if count.is_none() && offset == 0 {
1022 return Ok(input);
1023 }
1024 Ok(self.add_node(Node::Limit { input, count, offset }))
1025 }
1026
1027 fn constant_count(
1029 &mut self,
1030 ast: &Ast,
1031 written: ast::ExprRef,
1032 clause: &str,
1033 ) -> Result<Option<u64>> {
1034 if written == NONE {
1035 return Ok(None);
1036 }
1037 self.clause = "LIMIT clause";
1038 let scope = Scope::empty();
1039 let bound = self.bind_expr(ast, written, &scope)?;
1040 let Expr::Constant(value) = *self.plan.expr(bound) else {
1041 return Err(Error::not_implemented(format!("a {clause} that is not a constant")));
1042 };
1043 let count = match self.plan.value(value) {
1044 Value::Null => return Ok(None),
1045 Value::TinyInt(count) => i128::from(*count),
1046 Value::SmallInt(count) => i128::from(*count),
1047 Value::Integer(count) => i128::from(*count),
1048 Value::BigInt(count) => i128::from(*count),
1049 Value::HugeInt(count) => *count,
1050 other => {
1051 return Err(Error::binder(format!(
1052 "{clause} takes a whole number of rows, not a value of type {}",
1053 other.logical_type()
1054 )));
1055 }
1056 };
1057 u64::try_from(count)
1058 .map(Some)
1059 .map_err(|_| Error::binder(format!("{clause} must not be negative")))
1060 }
1061
1062 fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
1065 let sources = ast.source_list(from).to_vec();
1066 let Some((first, rest)) = sources.split_first() else {
1067 return Ok((self.add_node(Node::Dummy), Scope::empty()));
1070 };
1071 let (mut node, mut scope) = self.bind_source(ast, *first)?;
1072 for source in rest {
1073 let (right, right_scope) = self.bind_source(ast, *source)?;
1074 node = self.add_node(Node::CrossProduct { left: node, right });
1075 scope = scope.concat(right_scope);
1076 }
1077 Ok((node, scope))
1078 }
1079
1080 fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
1081 match ast.source(source) {
1082 ast::Source::Table { name, alias, columns } => {
1083 self.bind_table(ast, name, alias, columns)
1084 }
1085 ast::Source::Function { name, args, alias, columns, pragma } => {
1086 self.bind_table_function(ast, name, args, alias, columns, pragma)
1087 }
1088 ast::Source::Subquery { query, alias, columns } => {
1089 let (node, mut scope) = self.bind_query(ast, query)?;
1090 let label = if alias == NONE {
1091 "unnamed_subquery".to_string()
1092 } else {
1093 ast.string(alias).to_string()
1094 };
1095 scope.relabel(&label);
1096 if !columns.is_empty() {
1097 let names: Vec<&str> = ast.name(columns).collect();
1098 scope.rename(&names, &label)?;
1099 }
1100 Ok((node, scope))
1101 }
1102 ast::Source::Values { rows, alias, columns } => {
1103 let bare = ast::Query::bare(ast::QueryBody::Values(rows));
1104 let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
1105 let label =
1106 if alias == NONE { String::new() } else { ast.string(alias).to_string() };
1107 scope.relabel(&label);
1108 if !columns.is_empty() {
1109 let names: Vec<&str> = ast.name(columns).collect();
1110 scope.rename(&names, &label)?;
1111 }
1112 Ok((node, scope))
1113 }
1114 ast::Source::Join { left, right, kind, natural, on, using } => {
1115 self.bind_join(ast, left, right, kind, natural, on, using)
1116 }
1117 }
1118 }
1119
1120 fn bind_table(
1121 &mut self,
1122 ast: &Ast,
1123 name: ast::Slice,
1124 alias: ast::StrRef,
1125 columns: ast::Slice,
1126 ) -> Result<(NodeRef, Scope)> {
1127 let parts: Vec<&str> = ast.name(name).collect();
1128 let catalog = self.catalog;
1129 let resolved = match catalog.resolve(&parts) {
1132 Ok(resolved) => resolved,
1133 Err(missing) => {
1134 return self.bind_replacement_scan(ast, &parts, alias, columns, missing);
1135 }
1136 };
1137 if catalog.entry(&resolved)? == Entry::View {
1138 return self.bind_view(ast, &resolved, alias, columns);
1139 }
1140 let table = catalog.table(&resolved)?;
1141 let fields: Vec<Field> = table.columns().to_vec();
1142 let label =
1143 if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
1144 let index = self.fresh_index();
1145 let mut scope = Scope::empty();
1146 for (at, field) in fields.iter().enumerate() {
1147 scope.push(Visible {
1148 table: label.clone(),
1149 name: field.name.clone(),
1150 binding: ColumnBinding::new(index, at as u32),
1151 ty: field.ty.clone(),
1152 not_null: field.not_null,
1153 });
1154 }
1155 if !columns.is_empty() {
1156 let names: Vec<&str> = ast.name(columns).collect();
1157 scope.rename(&names, &label)?;
1158 }
1159 let catalog_name = self.plan.intern(&resolved.catalog);
1160 let schema = self.plan.intern(&resolved.schema);
1161 let table_name = self.plan.intern(&resolved.table);
1162 let alias = self.plan.intern(&label);
1163 let columns = self.plan.add_fields(&fields);
1164 let node = self.add_node(Node::Get {
1165 catalog: catalog_name,
1166 schema,
1167 table: table_name,
1168 alias,
1169 index,
1170 columns,
1171 });
1172 Ok((node, scope))
1173 }
1174
1175 fn bind_view(
1187 &mut self,
1188 ast: &Ast,
1189 name: &QualifiedName,
1190 alias: ast::StrRef,
1191 columns: ast::Slice,
1192 ) -> Result<(NodeRef, Scope)> {
1193 let view = self.catalog.view(name)?;
1194 let full = name.to_string();
1195 if self.expanding.contains(&full) {
1196 return Err(Error::binder(format!(
1200 "infinite recursion detected: attempting to recursively bind view \"\"{}\"\"",
1201 name.table
1202 )));
1203 }
1204 let body = parse_ast_with_case(view.sql(), self.semantics.identifier_case())?;
1205 let query = match body.statements.as_slice() {
1206 [ast::Statement::Query(query)] => *query,
1207 _ => return Err(Error::binder(format!("view \"{}\" is not a query", name.table))),
1210 };
1211 self.expanding.push(full);
1212 let bound = self.bind_query(&body, query);
1213 self.expanding.pop();
1214 let (node, mut scope) = bound?;
1215
1216 let aliases: Vec<&str> = view.aliases().iter().map(String::as_str).collect();
1217 if !aliases.is_empty() {
1218 scope.rename(&aliases, "unnamed_subquery")?;
1219 }
1220 view.remember(scope.fields());
1227 let label = if alias == NONE { name.table.clone() } else { ast.string(alias).to_string() };
1228 scope.relabel(&label);
1229 if !columns.is_empty() {
1230 let names: Vec<&str> = ast.name(columns).collect();
1231 scope.rename(&names, &label)?;
1232 }
1233 Ok((node, scope))
1234 }
1235
1236 fn bind_table_function(
1244 &mut self,
1245 ast: &Ast,
1246 name: ast::Slice,
1247 args: ast::Slice,
1248 alias: ast::StrRef,
1249 columns: ast::Slice,
1250 pragma: bool,
1251 ) -> Result<(NodeRef, Scope)> {
1252 let parts: Vec<&str> = ast.name(name).collect();
1253 let function_name = *parts.last().unwrap_or(&"");
1257 if let Some(schema) = parts.iter().rev().nth(1) {
1258 if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
1259 return Err(Error::catalog(format!(
1260 "Table Function with name {} does not exist!",
1261 parts.join(".")
1262 )));
1263 }
1264 }
1265 let Some(called) = TableFunction::lookup(function_name) else {
1269 if pragma {
1270 if args.is_empty() && self.catalog.resolve(&parts).is_ok() {
1276 return self.bind_table(ast, name, alias, columns);
1277 }
1278 let spelled = function_name.strip_prefix("pragma_").unwrap_or(function_name);
1279 return Err(Error::catalog(format!(
1280 "Pragma Function with name {spelled} does not exist!"
1281 )));
1282 }
1283 return Err(Error::catalog(format!(
1284 "Table Function with name {function_name} does not exist!"
1285 )));
1286 };
1287 let written = ast.target_list(args).to_vec();
1288 let empty = Scope::empty();
1289 let previous = std::mem::replace(&mut self.clause, "table function arguments");
1290 let mut bound = Vec::new();
1291 let mut written_options = Vec::new();
1292 for argument in written {
1293 let expr = self.bind_expr(ast, argument.expr, &empty)?;
1294 if argument.alias == NONE {
1295 bound.push(expr);
1296 } else {
1297 let name = ast.string(argument.alias).to_string();
1298 let (parameter, value) = self.named_argument(called, &name, expr)?;
1299 written_options.push((parameter, value, expr));
1300 }
1301 }
1302 self.clause = previous;
1303 let options = Options::of(&written_options)?;
1304
1305 let given: Vec<LogicalType> =
1308 bound.iter().map(|&expr| self.plan.expr_type(expr).clone()).collect();
1309 let resolved = if pragma {
1310 resolve_pragma(function_name, &given)?
1311 } else {
1312 resolve_table(function_name, &given)?
1313 };
1314 let mut cast: Vec<ExprRef> = bound
1315 .iter()
1316 .zip(&resolved.arguments)
1317 .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
1318 .collect::<Result<_>>()?;
1319
1320 if resolved.function.takes_a_name() {
1321 let Columns::Fixed(fields) = resolved.columns else {
1322 return Err(Error::internal("a pragma that resolved to a file"));
1323 };
1324 let [argument] = cast[..] else {
1325 return Err(Error::internal("a pragma that resolved to more than one name"));
1326 };
1327 return self.bind_pragma(ast, resolved.function, &fields, argument, alias, columns);
1328 }
1329 let fields = match resolved.columns {
1330 Columns::Fixed(fields) => fields,
1331 columns => {
1332 let paths = self.file_paths(cast[0], resolved.function.name())?;
1337 let first = paths.first().map_or("", String::as_str);
1338 let mut fields = match columns {
1339 Columns::Csv => csv_fields(&paths, options.given)?,
1342 _ => parquet_fields(first)?,
1343 };
1344 if options.all_varchar {
1345 for field in &mut fields {
1350 field.ty = LogicalType::Varchar;
1351 }
1352 }
1353 if options.binary_as_string {
1354 for field in &mut fields {
1359 if field.ty == LogicalType::Blob {
1360 field.ty = LogicalType::Varchar;
1361 }
1362 }
1363 }
1364 if options.file_row_number {
1365 if fields.iter().any(|field| field.name == FILE_ROW_NUMBER) {
1371 return Err(Error::binder(format!(
1372 "Duplicate column name \"{FILE_ROW_NUMBER}\": the file already has a \
1373 column of that name, so file_row_number cannot add one"
1374 )));
1375 }
1376 fields.push(Field::required(FILE_ROW_NUMBER.to_string(), LogicalType::BigInt));
1377 }
1378 cast = paths.iter().map(|path| self.path_constant(path)).collect();
1379 fields
1380 }
1381 };
1382 let label = if alias == NONE {
1383 resolved.function.name().to_string()
1384 } else {
1385 ast.string(alias).to_string()
1386 };
1387 let names: Vec<&str> = ast.name(columns).collect();
1388 self.table_function_source(
1389 resolved.function,
1390 &cast,
1391 &written_options,
1392 fields,
1393 &label,
1394 &names,
1395 )
1396 }
1397
1398 fn bind_pragma(
1411 &mut self,
1412 ast: &Ast,
1413 function: TableFunction,
1414 fields: &[Field],
1415 argument: ExprRef,
1416 alias: ast::StrRef,
1417 columns: ast::Slice,
1418 ) -> Result<(NodeRef, Scope)> {
1419 let written = self.pragma_name(argument, function)?;
1420 let parts = identifier_parts(&written);
1421 let spelled: Vec<&str> = parts.iter().map(String::as_str).collect();
1422 let name = self.catalog.resolve(&spelled)?;
1423 let described = self.described(ast, &name)?;
1424 let mut rows = Vec::with_capacity(described.len());
1425 for (at, field) in described.iter().enumerate() {
1426 let items = if matches!(function, TableFunction::PragmaShow) {
1427 self.describing(field)
1428 } else {
1429 self.table_info(at, field)
1430 };
1431 rows.push(self.plan.add_expr_list(&items));
1432 }
1433 let rows = self.plan.add_rows(&rows);
1434 let held = self.plan.add_fields(fields);
1435 let index = self.fresh_index();
1436 let node = self.add_node(Node::Values { index, columns: held, rows });
1437 let label =
1438 if alias == NONE { function.name().to_string() } else { ast.string(alias).to_string() };
1439 let mut scope = Scope::empty();
1440 for (at, field) in fields.iter().enumerate() {
1441 scope.push(Visible {
1442 table: label.clone(),
1443 name: field.name.clone(),
1444 binding: ColumnBinding::new(index, at as u32),
1445 ty: field.ty.clone(),
1446 not_null: false,
1447 });
1448 }
1449 if !columns.is_empty() {
1450 let names: Vec<&str> = ast.name(columns).collect();
1451 scope.rename(&names, &label)?;
1452 }
1453 Ok((node, scope))
1454 }
1455
1456 fn pragma_name(&self, argument: ExprRef, function: TableFunction) -> Result<String> {
1466 let Expr::Constant(reference) = *self.plan.expr(argument) else {
1467 return Err(Error::not_implemented(format!(
1468 "{}() given a name that is not a constant",
1469 function.name()
1470 )));
1471 };
1472 match self.plan.value(reference) {
1473 Value::Varchar(name) => Ok(name.clone()),
1474 Value::Null => Ok("NULL".to_string()),
1475 other => {
1476 Err(Error::internal(format!("a pragma name bound as VARCHAR arrived as {other}")))
1477 }
1478 }
1479 }
1480
1481 fn described(&mut self, ast: &Ast, name: &QualifiedName) -> Result<Vec<Field>> {
1492 if self.catalog.entry(name)? == Entry::Table {
1493 return Ok(self.catalog.table(name)?.columns().to_vec());
1494 }
1495 let (_, scope) = self.bind_view(ast, name, NONE, ast::Slice::default())?;
1496 Ok(scope.fields())
1497 }
1498
1499 fn describing(&mut self, field: &Field) -> Vec<ExprRef> {
1501 let written = [
1502 field.name.clone(),
1503 field.ty.to_string(),
1504 if field.not_null { "NO" } else { "YES" }.to_owned(),
1505 ];
1506 let mut items: Vec<ExprRef> =
1507 written.into_iter().map(|text| self.plan.add_constant(Value::Varchar(text))).collect();
1508 for _ in 0..3 {
1509 let empty = self.plan.add_constant(Value::Null);
1510 items.push(self.cast_to(empty, &LogicalType::Varchar));
1511 }
1512 items
1513 }
1514
1515 fn table_info(&mut self, at: usize, field: &Field) -> Vec<ExprRef> {
1521 let cid = self.plan.add_constant(Value::Integer(i32::try_from(at).unwrap_or(i32::MAX)));
1522 let name = self.plan.add_constant(Value::Varchar(field.name.clone()));
1523 let ty = self.plan.add_constant(Value::Varchar(field.ty.to_string()));
1524 let not_null = self.plan.add_constant(Value::Boolean(field.not_null));
1525 let default = self.plan.add_constant(Value::Null);
1526 let default = self.cast_to(default, &LogicalType::Varchar);
1527 let key = self.plan.add_constant(Value::Boolean(false));
1528 vec![cid, name, ty, not_null, default, key]
1529 }
1530
1531 fn named_argument(
1545 &mut self,
1546 function: TableFunction,
1547 name: &str,
1548 expr: ExprRef,
1549 ) -> Result<(&'static str, Value)> {
1550 let known = function
1551 .parameters()
1552 .iter()
1553 .find(|(parameter, _)| parameter.eq_ignore_ascii_case(name));
1554 let Some((parameter, wanted)) = known else {
1555 let candidates: Vec<String> = function
1556 .parameters()
1557 .iter()
1558 .map(|(parameter, ty)| format!(" {parameter} {ty}"))
1559 .collect();
1560 return Err(Error::binder(format!(
1561 "Invalid named parameter \"{name}\" for function {}\nCandidates:\n{}\n",
1562 function.name(),
1563 candidates.join("\n")
1564 )));
1565 };
1566 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1567 return Err(Error::not_implemented(format!(
1568 "the named parameter {parameter} with a value that is not a constant"
1569 )));
1570 };
1571 let value = self.plan.value(reference).clone();
1572 if value == Value::Null {
1573 return Err(Error::binder(null_parameter(function, parameter)));
1574 }
1575 let given = self.plan.expr_type(expr).clone();
1576 if given != *wanted {
1577 return Err(Error::not_implemented(format!(
1578 "the named parameter {parameter} given a {given} where a {wanted} was wanted"
1579 )));
1580 }
1581 Ok((parameter, value))
1582 }
1583
1584 fn bind_replacement_scan(
1595 &mut self,
1596 ast: &Ast,
1597 parts: &[&str],
1598 alias: ast::StrRef,
1599 columns: ast::Slice,
1600 missing: Error,
1601 ) -> Result<(NodeRef, Scope)> {
1602 let [path] = parts else { return Err(missing) };
1603 let path = *path;
1604 let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
1605 let Some(function) = Self::reader_for(extension) else {
1606 if is_file(path) {
1607 return Err(Error::binder(format!(
1612 "No extension found that is capable of reading the file \"{path}\"\n* If this \
1613 file is a supported file format you can explicitly use the reader functions, \
1614 such as read_csv, read_json or read_parquet"
1615 )));
1616 }
1617 return Err(missing);
1618 };
1619 let paths = files(path)?;
1624 let first = paths.first().map_or("", String::as_str);
1625 let fields = match function {
1626 TableFunction::ReadParquet => parquet_fields(first)?,
1627 _ => csv_fields(&paths, Given::default())?,
1628 };
1629 let label = if alias == NONE {
1635 if is_pattern(path) {
1636 path.to_string()
1637 } else {
1638 let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
1639 file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
1640 }
1641 } else {
1642 ast.string(alias).to_string()
1643 };
1644 let arguments: Vec<ExprRef> = paths.iter().map(|path| self.path_constant(path)).collect();
1645 let names: Vec<&str> = ast.name(columns).collect();
1646 self.table_function_source(function, &arguments, &[], fields, &label, &names)
1647 }
1648
1649 fn path_constant(&mut self, path: &str) -> ExprRef {
1651 let value = self.plan.add_value(Value::Varchar(path.to_string()));
1652 self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar)
1653 }
1654
1655 fn reader_for(extension: &str) -> Option<TableFunction> {
1662 if extension.eq_ignore_ascii_case("parquet") {
1663 return Some(TableFunction::ReadParquet);
1664 }
1665 if extension.eq_ignore_ascii_case("csv") || extension.eq_ignore_ascii_case("tsv") {
1666 return Some(TableFunction::ReadCsv);
1667 }
1668 None
1669 }
1670
1671 fn table_function_source(
1676 &mut self,
1677 function: TableFunction,
1678 args: &[ExprRef],
1679 written: &[(&'static str, Value, ExprRef)],
1680 fields: Vec<Field>,
1681 label: &str,
1682 names: &[&str],
1683 ) -> Result<(NodeRef, Scope)> {
1684 let index = self.fresh_index();
1685 let mut scope = Scope::empty();
1686 for (at, field) in fields.iter().enumerate() {
1687 scope.push(Visible {
1688 table: label.to_string(),
1689 name: field.name.clone(),
1690 binding: ColumnBinding::new(index, at as u32),
1691 ty: field.ty.clone(),
1692 not_null: false,
1695 });
1696 }
1697 if !names.is_empty() {
1698 scope.rename(names, label)?;
1699 }
1700 let function = self.plan.intern(function.name());
1701 let args = self.plan.add_expr_list(args);
1702 let named: Vec<u32> =
1703 written.iter().map(|(parameter, _, _)| self.plan.intern(parameter)).collect();
1704 let settings: Vec<ExprRef> = written.iter().map(|(_, _, expr)| *expr).collect();
1705 let options = self.plan.add_name_list(&named);
1706 let settings = self.plan.add_expr_list(&settings);
1707 let columns = self.plan.add_fields(&fields);
1708 let node = self.add_node(Node::TableFunction {
1709 index,
1710 function,
1711 args,
1712 options,
1713 settings,
1714 columns,
1715 });
1716 Ok((node, scope))
1717 }
1718
1719 fn file_paths(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1726 let mut paths = Vec::new();
1727 for pattern in self.file_patterns(expr, name)? {
1728 paths.extend(files(&pattern)?);
1729 }
1730 Ok(paths)
1731 }
1732
1733 fn file_patterns(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
1745 let Expr::Constant(reference) = *self.plan.expr(expr) else {
1746 return Err(Error::not_implemented(
1747 "a table function file name that is not a constant",
1748 ));
1749 };
1750 match self.plan.value(reference) {
1751 Value::Varchar(path) => Ok(vec![path.clone()]),
1752 Value::Null => Err(Error::parser(format!("{name} cannot take NULL list as parameter"))),
1754 Value::List { values, .. } => values
1755 .iter()
1756 .map(|value| match value {
1757 Value::Varchar(path) => Ok(path.clone()),
1758 _ => Err(Error::parser(format!(
1759 "{name} reader cannot take NULL input as parameter"
1760 ))),
1761 })
1762 .collect(),
1763 other => {
1764 Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
1765 }
1766 }
1767 }
1768
1769 #[allow(clippy::too_many_arguments)]
1770 fn bind_join(
1771 &mut self,
1772 ast: &Ast,
1773 left: ast::SourceRef,
1774 right: ast::SourceRef,
1775 kind: ast::JoinKind,
1776 natural: bool,
1777 on: ast::ExprRef,
1778 using: ast::Slice,
1779 ) -> Result<(NodeRef, Scope)> {
1780 let (left_node, left_scope) = self.bind_source(ast, left)?;
1781 let (right_node, right_scope) = self.bind_source(ast, right)?;
1782 let split = left_scope.len();
1783 let mut scope = left_scope.concat(right_scope);
1784
1785 let merged: Vec<String> = if natural {
1788 let mut names = Vec::new();
1789 for (at, column) in scope.columns.iter().enumerate().take(split) {
1790 if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
1791 && !names.iter().any(|held: &String| same_name(held, &column.name))
1792 {
1793 let _ = at;
1794 names.push(column.name.clone());
1795 }
1796 }
1797 names
1798 } else {
1799 let mut names: Vec<String> = Vec::new();
1805 for name in ast.name(using) {
1806 if !names.iter().any(|held| same_name(held, name)) {
1807 names.push(name.to_string());
1808 }
1809 }
1810 names
1811 };
1812
1813 let mut conditions = Vec::new();
1814 let mut dropped = Vec::new();
1815 for name in &merged {
1816 let left_at = scope.columns[..split]
1817 .iter()
1818 .position(|column| same_name(&column.name, name))
1819 .ok_or_else(|| {
1820 Error::binder(format!(
1821 "column \"{name}\" specified in USING clause does not exist in left table"
1822 ))
1823 })?;
1824 let right_at = scope.columns[split..]
1825 .iter()
1826 .position(|column| same_name(&column.name, name))
1827 .map(|at| at + split)
1828 .ok_or_else(|| {
1829 Error::binder(format!(
1830 "column \"{name}\" specified in USING clause does not exist in right table"
1831 ))
1832 })?;
1833 let left_column = &scope.columns[left_at];
1834 let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
1835 let right_column = &scope.columns[right_at];
1836 let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
1837 let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
1838 let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
1839 conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
1840 dropped.push(right_at);
1841 }
1842 dropped.sort_unstable();
1845 for at in dropped.into_iter().rev() {
1846 scope.remove(at);
1847 }
1848
1849 if on != NONE {
1850 if !merged.is_empty() {
1851 return Err(Error::binder("a join cannot have both ON and USING"));
1852 }
1853 self.clause = "JOIN condition";
1854 let predicate = self.bind_expr(ast, on, &scope)?;
1855 conditions.push(self.as_boolean(predicate, "JOIN")?);
1856 }
1857
1858 if kind == ast::JoinKind::Cross {
1859 if !conditions.is_empty() {
1860 return Err(Error::binder("a CROSS JOIN cannot have a condition"));
1861 }
1862 let node = self.add_node(Node::CrossProduct { left: left_node, right: right_node });
1863 return Ok((node, scope));
1864 }
1865 if conditions.is_empty() && kind == ast::JoinKind::Inner {
1866 let node = self.add_node(Node::CrossProduct { left: left_node, right: right_node });
1867 return Ok((node, scope));
1868 }
1869 let kind = match kind {
1870 ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
1871 ast::JoinKind::Left => JoinKind::Left,
1872 ast::JoinKind::Right => JoinKind::Right,
1873 ast::JoinKind::Full => JoinKind::Full,
1874 ast::JoinKind::Semi => JoinKind::Semi,
1875 ast::JoinKind::Anti => JoinKind::Anti,
1876 ast::JoinKind::Positional => JoinKind::Positional,
1877 };
1878 let conditions = self.plan.add_expr_list(&conditions);
1879 let node =
1880 self.add_node(Node::Join { left: left_node, right: right_node, kind, conditions });
1881 Ok((node, scope))
1882 }
1883
1884 pub(crate) fn bind_aggregate(
1888 &mut self,
1889 ast: &Ast,
1890 name: &str,
1891 args: &[ast::ExprRef],
1892 distinct: bool,
1893 scope: &Scope,
1894 ) -> Result<ExprRef> {
1895 if self.in_aggregate {
1896 return Err(Error::binder(format!(
1897 "aggregate function calls cannot be nested, and {name}() is inside one"
1898 )));
1899 }
1900 if self.aggregation.is_none() {
1901 return Err(Error::binder(format!(
1902 "aggregate function calls cannot be used in the {}",
1903 self.clause
1904 )));
1905 }
1906 self.in_aggregate = true;
1907 let mut bound = Vec::with_capacity(args.len());
1908 let mut failure = None;
1909 for &arg in args {
1910 match self.bind_expr(ast, arg, scope) {
1911 Ok(expr) => bound.push(expr),
1912 Err(error) => {
1913 failure = Some(error);
1914 break;
1915 }
1916 }
1917 }
1918 self.in_aggregate = false;
1919 if let Some(error) = failure {
1920 return Err(error);
1921 }
1922
1923 let types: Vec<LogicalType> =
1924 bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
1925 let resolved = resolve(name, &types)?;
1926 let mut cast = Vec::with_capacity(bound.len());
1927 for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
1928 cast.push(self.checked_cast_to(*arg, wanted, false)?);
1929 }
1930 let args = self.plan.add_expr_list(&cast);
1931 let name = self.plan.intern(resolved.name);
1932 let ty = resolved.returns;
1933 let call =
1934 self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter: None }, ty.clone());
1935
1936 let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
1939 let existing = existing.unwrap_or_default();
1940 let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
1941 Some(at) => at,
1942 None => {
1943 let aggregation = self.aggregation.as_mut().expect("checked above");
1944 aggregation.aggregates.push(call);
1945 aggregation.aggregates.len() - 1
1946 }
1947 };
1948 let aggregation = self.aggregation.as_ref().expect("checked above");
1949 let (index, groups) = (aggregation.index, aggregation.groups.len());
1950 Ok(self.column(index, groups + at, ty))
1951 }
1952
1953 pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
1959 let Some(aggregation) = self.aggregation.as_ref() else {
1960 return Ok(expr);
1961 };
1962 let index = aggregation.index;
1963 let groups = aggregation.groups.clone();
1964 for (at, group) in groups.iter().enumerate() {
1965 if self.same_expr(expr, *group) {
1966 let ty = self.plan.expr_type(*group).clone();
1967 return Ok(self.column(index, at, ty));
1968 }
1969 }
1970 let ty = self.plan.expr_type(expr).clone();
1971 match self.plan.expr(expr).clone() {
1972 Expr::Column(binding) if binding.table == index => Ok(expr),
1973 Expr::Column(binding) => {
1974 let name =
1975 scope.columns.iter().find(|column| column.binding == binding).map_or_else(
1976 || "a column".to_string(),
1977 |column| format!("\"{}\"", column.name),
1978 );
1979 Err(Error::binder(format!(
1980 "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
1981 )))
1982 }
1983 Expr::Constant(_) | Expr::Aggregate { .. } => Ok(expr),
1984 Expr::Cast { input, try_cast } => {
1985 let input = self.over_aggregate(input, scope)?;
1986 Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
1987 }
1988 Expr::Compare { op, left, right } => {
1989 let left = self.over_aggregate(left, scope)?;
1990 let right = self.over_aggregate(right, scope)?;
1991 Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
1992 }
1993 Expr::Conjunction { op, children } => {
1994 let written = self.plan.expr_list(children).to_vec();
1995 let mut rewritten = Vec::with_capacity(written.len());
1996 for child in written {
1997 rewritten.push(self.over_aggregate(child, scope)?);
1998 }
1999 let children = self.plan.add_expr_list(&rewritten);
2000 Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
2001 }
2002 Expr::Function { name, args } => {
2003 let written = self.plan.expr_list(args).to_vec();
2004 let mut rewritten = Vec::with_capacity(written.len());
2005 for arg in written {
2006 rewritten.push(self.over_aggregate(arg, scope)?);
2007 }
2008 let args = self.plan.add_expr_list(&rewritten);
2009 Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
2010 }
2011 Expr::Case { arms, otherwise } => {
2012 let written = self.plan.arm_list(arms).to_vec();
2013 let mut rewritten = Vec::with_capacity(written.len());
2014 for arm in written {
2015 let when = self.over_aggregate(arm.when, scope)?;
2016 let then = self.over_aggregate(arm.then, scope)?;
2017 rewritten.push(rudb_plan::Arm { when, then });
2018 }
2019 let otherwise = match otherwise {
2020 Some(expr) => Some(self.over_aggregate(expr, scope)?),
2021 None => None,
2022 };
2023 let arms = self.plan.add_arms(&rewritten);
2024 Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
2025 }
2026 }
2027 }
2028
2029 pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
2031 same_expr(&self.plan, left, right)
2032 }
2033}
2034
2035#[derive(Debug, Default)]
2045struct Options {
2046 binary_as_string: bool,
2049 all_varchar: bool,
2051 file_row_number: bool,
2056 given: Given,
2058}
2059
2060impl Options {
2061 fn of(written: &[(&'static str, Value, ExprRef)]) -> Result<Self> {
2068 let mut options = Self::default();
2069 for (parameter, value, _) in written {
2070 match (*parameter, value) {
2071 ("binary_as_string", Value::Boolean(on)) => options.binary_as_string = *on,
2072 ("all_varchar", Value::Boolean(on)) => options.all_varchar = *on,
2073 ("file_row_number", Value::Boolean(on)) => options.file_row_number = *on,
2074 _ => {}
2075 }
2076 }
2077 let named: Vec<(&str, Value)> =
2078 written.iter().map(|(parameter, value, _)| (*parameter, value.clone())).collect();
2079 options.given = csv_given(&named)?;
2080 Ok(options)
2081 }
2082}
2083
2084fn null_parameter(function: TableFunction, parameter: &str) -> String {
2093 match parameter {
2094 "header" => format!("\"{parameter}\" expects a non-null boolean value (e.g. TRUE or 1)"),
2095 "all_varchar" => format!("{} \"{parameter}\" cannot be NULL", function.name()),
2096 _ => format!("Cannot use NULL as argument to \"{parameter}\""),
2097 }
2098}
2099
2100fn missing_replacement(name: &str, input: &Scope) -> Error {
2105 Error::binder(format!(
2106 "Column \"{name}\" in REPLACE list not found in FROM clause{}",
2107 input.candidates()
2108 ))
2109}
2110
2111fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
2113 if left == right {
2114 return true;
2115 }
2116 if plan.expr_type(left) != plan.expr_type(right) {
2117 return false;
2118 }
2119 let lists = |left, right| {
2120 let left: &[ExprRef] = plan.expr_list(left);
2121 let right: &[ExprRef] = plan.expr_list(right);
2122 left.len() == right.len()
2123 && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
2124 };
2125 match (plan.expr(left), plan.expr(right)) {
2126 (Expr::Column(left), Expr::Column(right)) => left == right,
2127 (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
2128 (
2129 Expr::Cast { input: left, try_cast: left_try },
2130 Expr::Cast { input: right, try_cast: right_try },
2131 ) => left_try == right_try && same_expr(plan, *left, *right),
2132 (
2133 Expr::Compare { op: left_op, left: left_a, right: left_b },
2134 Expr::Compare { op: right_op, left: right_a, right: right_b },
2135 ) => {
2136 left_op == right_op
2137 && same_expr(plan, *left_a, *right_a)
2138 && same_expr(plan, *left_b, *right_b)
2139 }
2140 (
2141 Expr::Conjunction { op: left_op, children: left_children },
2142 Expr::Conjunction { op: right_op, children: right_children },
2143 ) => left_op == right_op && lists(*left_children, *right_children),
2144 (
2145 Expr::Function { name: left_name, args: left_args },
2146 Expr::Function { name: right_name, args: right_args },
2147 ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
2148 (
2149 Expr::Aggregate {
2150 name: left_name,
2151 args: left_args,
2152 distinct: left_distinct,
2153 filter: left_filter,
2154 },
2155 Expr::Aggregate {
2156 name: right_name,
2157 args: right_args,
2158 distinct: right_distinct,
2159 filter: right_filter,
2160 },
2161 ) => {
2162 plan.string(*left_name) == plan.string(*right_name)
2163 && left_distinct == right_distinct
2164 && match (left_filter, right_filter) {
2165 (None, None) => true,
2166 (Some(left), Some(right)) => same_expr(plan, *left, *right),
2167 _ => false,
2168 }
2169 && lists(*left_args, *right_args)
2170 }
2171 (
2172 Expr::Case { arms: left_arms, otherwise: left_otherwise },
2173 Expr::Case { arms: right_arms, otherwise: right_otherwise },
2174 ) => {
2175 let left_arms = plan.arm_list(*left_arms);
2176 let right_arms = plan.arm_list(*right_arms);
2177 left_arms.len() == right_arms.len()
2178 && left_arms.iter().zip(right_arms).all(|(left, right)| {
2179 same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
2180 })
2181 && match (left_otherwise, right_otherwise) {
2182 (None, None) => true,
2183 (Some(left), Some(right)) => same_expr(plan, *left, *right),
2184 _ => false,
2185 }
2186 }
2187 _ => false,
2188 }
2189}