Skip to main content

rudb_bind/
binder.rs

1//! From an `Ast` to a `Plan`.
2//!
3//! The binder walks the written query once, in the order the operators end up in rather than the
4//! order the clauses are written in, which is `FROM`, `WHERE`, `GROUP BY`, `HAVING`, `SELECT`,
5//! `DISTINCT`, `ORDER BY`, `LIMIT`. That order is not a stylistic choice: it is the reason `WHERE`
6//! cannot see an output alias and `HAVING` cannot see a column that was not grouped, and doing it
7//! in any other order means special casing both of those instead of getting them for free.
8//!
9//! Two things leave here settled that nothing downstream reconsiders. Every column is a table index
10//! and a position rather than a name, so the optimizer never has to ask which `id` a name meant.
11//! And every expression has a type, with the casts that make the types line up already written into
12//! the plan as [`Expr::Cast`] nodes, so an executor never has to decide what a comparison between
13//! an `INTEGER` and a `BIGINT` does.
14
15use 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
31/// Binds a parsed statement against a catalog.
32///
33/// # Errors
34///
35/// If the script does not hold exactly one statement, if a name does not resolve, if a type does
36/// not work out, or if the query uses something M0 does not bind yet.
37pub fn bind(ast: &Ast, catalog: &Catalog) -> Result<Plan> {
38    bind_with(ast, catalog, &Parameters::new(), &Session::new())
39}
40
41/// Binds a parsed query against a catalog, with values for its parameters and its settings.
42///
43/// The session is what `current_setting()` reads, and a caller with no database behind it passes an
44/// empty one, which makes every setting name unrecognized rather than making up an answer.
45///
46/// # Errors
47///
48/// Everything [`bind`] reports, plus an error for a parameter that was given no value.
49pub 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        // One statement that is not a query is its own answer. Reporting it as a script of several
59        // reads as a count being wrong, and the count is right.
60        [_] => 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
71/// Parses and binds one query, which is the whole front end in one call.
72///
73/// # Errors
74///
75/// Anything the parser or the binder reports.
76pub fn bind_sql(query: &str, catalog: &Catalog) -> Result<Plan> {
77    bind_sql_with(query, catalog, &Session::new())
78}
79
80/// Parses and binds one query, with the settings a call to `current_setting()` reads.
81///
82/// # Errors
83///
84/// Anything the parser or the binder reports.
85pub 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/// What an aggregating select block has decided so far.
91#[derive(Debug)]
92pub(crate) struct Aggregation {
93    /// The table index the aggregate's output binds against.
94    pub(crate) index: u32,
95    /// The group expressions, over the input, which are the first output columns.
96    pub(crate) groups: Vec<ExprRef>,
97    /// The aggregate calls found so far, which follow the groups in the output.
98    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/// The state one binding run carries.
110#[derive(Debug)]
111pub(crate) struct Binder<'a> {
112    catalog: &'a Catalog,
113    /// What the parameters were given, empty for a statement that is not prepared.
114    pub(crate) parameters: &'a Parameters,
115    /// What the settings are now, which is what `current_setting()` folds to.
116    pub(crate) session: &'a Session,
117    /// Meaning-changing choices copied once and resolved into the plan above execution.
118    pub(crate) semantics: Semantics,
119    plan: Plan,
120    next_index: u32,
121    /// Source range inherited by plan objects built for the current AST expression or query.
122    pub(crate) current_span: Span,
123    /// Set while a select block aggregates, which changes what a bare column means.
124    pub(crate) aggregation: Option<Aggregation>,
125    /// Set while an aggregate's own arguments are being bound, so nesting is caught.
126    pub(crate) in_aggregate: bool,
127    /// Uncorrelated scalar queries waiting to be joined into the select block that uses them.
128    pub(crate) scalar_subqueries: Vec<PendingSubquery>,
129    pub(crate) outer_scopes: Vec<Scope>,
130    pub(crate) correlations: Vec<Vec<ColumnBinding>>,
131    /// Where we are, for an error message that says which clause the writer should look at.
132    pub(crate) clause: &'static str,
133    /// The views whose bodies are open on the stack, which is what catches a cycle.
134    expanding: Vec<String>,
135    /// When this statement started, read once and kept, which is what `now()` folds to.
136    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    /// When this statement started, in microseconds since the epoch.
169    ///
170    /// Read from the clock the first time something asks and kept after that, so a query that
171    /// writes `now()` twice gets one answer for both. That is what the pin does and what it reports
172    /// in the `stability` column of `duckdb_functions()`, where every one of these is
173    /// `CONSISTENT_WITHIN_QUERY`. A query that never asks never reads the clock.
174    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    /// A table index nothing else has.
205    pub(crate) fn fresh_index(&mut self) -> u32 {
206        let index = self.next_index;
207        self.next_index += 1;
208        index
209    }
210
211    /// A reference to one column of an operator's output.
212    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    /// Joins scalar query results into the row stream that contains their expressions.
218    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    // ---------------------------------------------------------------- queries
237
238    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    /// `SHOW name`, resolved while binding so execution receives an ordinary constant plan.
270    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    /// `DESCRIBE <query>`, which is six VARCHAR columns saying what the query returns.
312    ///
313    /// The query is bound and never run, because binding is the whole of the answer: the names and
314    /// the types of a query's columns are settled by the time the binder is done with it, so the
315    /// rows of a describe are a constant from there on. That is why this comes out as a `VALUES`
316    /// whose rows were computed here rather than as an operator of its own, and it is what makes
317    /// `SELECT column_name FROM (DESCRIBE ...) WHERE ...` an ordinary query over an ordinary
318    /// relation with no special case above it.
319    ///
320    /// The six columns, their order and their types are the reference binary's. `key`, `default`
321    /// and `extra` are null for everything this engine can declare, since `PRIMARY KEY`, `UNIQUE`
322    /// and `DEFAULT` are all refused by `CREATE TABLE` today and there is nothing for the first two
323    /// to hold, and `extra` is empty upstream as well on every table it was asked about. They are
324    /// here rather than left out because the width of a result is part of the result, and a program
325    /// that reads the fifth column has to find one.
326    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            // `NO` and `YES` and not a boolean, because the column is VARCHAR upstream and a
340            // client that prints the result has to get the same four or three characters.
341            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    /// Whether a projected expression is a column passed straight through from below.
380    ///
381    /// Only `DESCRIBE` asks, and only to decide whether the `null` column says `NO`. Anything that
382    /// is computed is nullable however strict its inputs were, which is both the safe reading and
383    /// the one the reference binary gives.
384    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    /// `VALUES (1, 'a'), (2, 'b')`, as a query in its own right.
390    ///
391    /// The column names are `col0`, `col1` and so on, which is what DuckDB calls them, and the
392    /// column types are what every row in that position promotes to. Promotion is the same rule a
393    /// set operation uses, and for the same reason: a column has one type and the rows have to
394    /// agree on it before anything downstream can read the column.
395    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        // A row of a `VALUES` cannot see a column, because there is nothing under it to see.
416        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        // Both sides have to hand back one set of types, so each column meets the other side's.
497        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        // UNION alone removes duplicates and UNION ALL keeps them, which is the one place the
516        // unwritten quantifier and ALL disagree.
517        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                // A column of a set operation is nullable whatever the two sides were, because a
528                // column that refuses nulls on one side and takes them on the other takes them.
529                not_null: false,
530            });
531        }
532        // Above a set operation there is nothing but the output columns, so an ORDER BY term is
533        // either a position, an output name, or an expression over the output, and never needs a
534        // column projected for it that the query did not ask for.
535        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    /// Projects one side of a set operation so that its columns have the agreed types.
545    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    // ----------------------------------------------------------------- select
563
564    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        // The projection's index has to exist before the sort keys are built, because a key is a
614        // reference to a projected column even when the expression it sorts on is not selected.
615        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        // An expression sorted on but not selected was carried this far to make the sort possible,
676        // and now it goes, because the query did not ask for it.
677        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    /// Binds the target list, expanding every star into the columns it stands for.
700    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                    // The replacement takes the column's place and its position, and it is named the
720                    // way the replace list spells it rather than the way the table does. That only
721                    // shows when the two differ in case, and `AS EventDate` over a column called
722                    // `eventdate` is exactly the case that shows it.
723                    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                // A replace list that named something the star did not stand for is a mistake and
738                // not a no op, and it is caught here because this is the first point at which the
739                // set of names the star stands for is known.
740                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    /// The name an unaliased target gets.
759    ///
760    /// A bare column keeps the spelling the table was created with rather than the spelling the
761    /// query used, so `SELECT USERID FROM hits` has a column called `UserID`. Identifiers match
762    /// without regard to case and the catalog is the one that holds the case.
763    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    /// The expressions a `GROUP BY` clause names, with positions and output aliases followed.
774    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            // GROUP BY ALL means every target that is not itself an aggregate, which is the set
782            // that would otherwise have to be written out again by hand.
783            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    /// The target a `GROUP BY` or `ORDER BY` term names, when it names one by position or alias.
797    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    // -------------------------------------------------------------- modifiers
837
838    /// Sort keys for a select, projecting anything sorted on that is not already selected.
839    #[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    /// Sort keys over an output that has nothing behind it to project, which is a set operation.
882    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    /// A sort key with the session defaults filled in.
926    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    /// Which output column a term names, by position or by name.
941    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    /// Refuses a literal sort key unless the session explicitly accepts its no-op behavior.
974    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    /// The expressions a `DISTINCT ON` names, which have to be columns of the output.
991    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    /// The row count a `LIMIT` or an `OFFSET` names, which has to be a constant.
1028    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    // ------------------------------------------------------------------- from
1063
1064    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            // No FROM clause is one row of no columns, which is what SELECT 1 sits on. Not an
1068            // empty table: an empty table would make SELECT 1 return nothing.
1069            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        // The catalog is asked first and the file is the fallback, which is the order DuckDB uses:
1130        // a table really called `mixed.parquet` wins over a file of that name sitting next to it.
1131        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    /// A view where a table goes, which is the body bound again right here.
1176    ///
1177    /// Inline and not behind a node. The view is gone by the time the plan exists, so everything
1178    /// downstream sees the query somebody would have written by hand, and the column pruning that
1179    /// makes `SELECT COUNT(*) FROM 'hits.parquet'` read no columns at all keeps working through
1180    /// `FROM hits`. A `Node::View` would be a barrier with nothing on the other side of it.
1181    ///
1182    /// The scope this builds is a subquery's, right down to the name in the error message. duckdb
1183    /// v1.5.1 reports a view whose column list has gone stale as `table "unnamed_subquery" has 1
1184    /// columns available but 2 columns specified`, which is the sentence its subquery alias rule
1185    /// produces, so a view there is a subquery with the view's name written over it afterwards.
1186    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            // Two quotes each side, which is what the binary prints. It quotes the name on the way
1197            // in and then formats the quoted name into a quoted slot, so a view called `a` comes
1198            // back as `""a""`. That is upstream's wart and copying it is the whole job here.
1199            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            // Only a query can have got past the binder at creation, so this is a view the catalog
1208            // was handed some other way rather than anything a statement can produce.
1209            _ => 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        // What the catalog tables report as this view's columns, written down here because this is
1221        // the moment they are known. Upstream refreshes the same cache at the same point, which was
1222        // measured: both `duckdb_columns()` and `duckdb_views().column_count` keep reporting the old
1223        // list after an `ALTER TABLE` underneath until something reads the view, and then both move.
1224        // It is written before the label and before the `AS t(a, b)` list below, because those two
1225        // rename the view for one query and not for everyone.
1226        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    /// A function call where a table goes, such as `range(10)`.
1237    ///
1238    /// The arguments are bound against an empty scope. A table function that can see the row on its
1239    /// left is `LATERAL`, and this is not it, so a column name in here is not resolved against
1240    /// whatever happens to be to the left in the `FROM` list. Letting it would mean `FROM t,
1241    /// range(t.n)` quietly binding to something whose meaning depends on the order the sources were
1242    /// written in.
1243    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        // A qualified call names a schema, and the two schemas that exist are the ones every
1254        // built-in lives in. Anything else is a name that has to fail rather than fall through to
1255        // the unqualified lookup and be found somewhere it was not asked for.
1256        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        // The name is looked up before the arguments are bound so that a call of something that is
1266        // not a table function says that, rather than reporting whatever is wrong with the
1267        // arguments of a function that was never going to exist.
1268        let Some(called) = TableFunction::lookup(function_name) else {
1269            if pragma {
1270                // `PRAGMA database_list` is a view upstream and not a function, and the pragma
1271                // namespace holds both, so a name that is not a function gets one more look in the
1272                // catalog before it is turned down. It has to be the no argument form: a view
1273                // takes none, and `pragma_database_list()` with parentheses is a missing function
1274                // on the pin too.
1275                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        // The types are what resolve the call, not the count, because `read_parquet(3)` is a
1306        // different answer from `read_parquet('3')` and only the types tell them apart.
1307        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                // The one argument is a pattern, and what replaces it is one constant per file it
1333                // matched. The executor is handed names rather than a pattern, so it never walks a
1334                // directory and the answer cannot change between binding a prepared statement and
1335                // running it, which is the same reason the schema is settled here.
1336                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                    // Parquet takes the first file's footer as the answer and CSV sniffs all of
1340                    // them, which is not a choice made here. See `csv_fields`.
1341                    Columns::Csv => csv_fields(&paths, options.given)?,
1342                    _ => parquet_fields(first)?,
1343                };
1344                if options.all_varchar {
1345                    // The sniffer still ran, because the names come out of the same pass over the
1346                    // front of the file and only the types are being overruled. The executor reads
1347                    // the text as VARCHAR because this is the schema it is told to read into, which
1348                    // is the same road a file in a glob takes when the set is wider than the file.
1349                    for field in &mut fields {
1350                        field.ty = LogicalType::Varchar;
1351                    }
1352                }
1353                if options.binary_as_string {
1354                    // A byte array column with no annotation on it is a BLOB, and this is the caller
1355                    // saying that the file's writer meant text. The reader already holds both in the
1356                    // same string column and already validates the bytes, so the whole of the option
1357                    // is what the column is called from here on.
1358                    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                    // Not a column of the file, so it goes on the end where a projection cannot be
1366                    // confused about which one it is, and the executor counts it as the rows come
1367                    // out. A file that already has a column of that name is the one case where the
1368                    // option cannot be honoured, and saying so is better than handing back two
1369                    // columns with the same name and letting a reference to it pick one.
1370                    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    /// `pragma_table_info('t')` or `pragma_show('t')`, answered while it is bound.
1399    ///
1400    /// The same trick `DESCRIBE` uses and for the same reason: the columns of a table are settled by
1401    /// the time the name has resolved, so the rows are a constant from there on and this comes out
1402    /// as a `VALUES` rather than as an operator that reads a catalog while the query runs. It also
1403    /// means `SELECT name FROM pragma_table_info('t') WHERE notnull` is an ordinary query over an
1404    /// ordinary relation, which is the whole reason these exist as functions rather than only as
1405    /// statements.
1406    ///
1407    /// The name arrives as a string rather than as something the parser read, so it is split here
1408    /// under the identifier rule and then resolved like any other name. A name that is not there
1409    /// comes back as the catalog's own complaint, which is what the pin answers with too.
1410    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    /// The name a pragma was called with, which has to be a constant.
1457    ///
1458    /// A null is a name spelled `NULL` rather than an error about nulls, because the pin turns
1459    /// whatever it was handed into text before it goes looking and then says a table of that name
1460    /// does not exist. Writing `pragma_table_info(NULL)` is a mistake either way and this is the
1461    /// sentence the mistake already has.
1462    ///
1463    /// `pragma_table_info('t' || 'x')` is the pin's `tx` and is turned away here, which is the same
1464    /// missing constant folding [`Binder::named_argument`] writes about and closes the same day.
1465    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    /// The columns of whatever a pragma was pointed at.
1482    ///
1483    /// A view is bound here, which is how it comes to have columns at all. Reading a view is what
1484    /// binds it and describing one counts as reading it, so a view the engine ships with reports a
1485    /// column count from this point on, the same as it would after a select. The node that binding
1486    /// produces is thrown away, because the answer is the scope and not the query.
1487    ///
1488    /// Every column of a view is nullable whatever the column underneath was declared as, which is
1489    /// the pin's answer through `pragma_table_info()`, `pragma_show()` and `duckdb_columns()` alike.
1490    /// [`Scope::fields`] drops the flag on its own, so there is nothing to clear here.
1491    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    /// One row of `pragma_show()`, which is one row of `DESCRIBE` written by the other caller.
1500    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    /// One row of `pragma_table_info()`, which is SQLite's six columns about the same column.
1516    ///
1517    /// `cid` counts from zero, which is SQLite's numbering and not the one based `ordinal_position`
1518    /// the standard views report. `dflt_value` and `pk` are the two nothings rudb has to report
1519    /// until `CREATE TABLE` takes a `DEFAULT` or a key.
1520    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    /// One named parameter of a table function call, folded into what the call was given.
1532    ///
1533    /// The value has to be a constant of the type the parameter wants. It has to be constant
1534    /// because an option can decide what the columns are and the columns are settled here, and it
1535    /// has to be already of the type because there is no constant folding in front of the binder
1536    /// yet. DuckDB folds first, so `binary_as_string=1` and `binary_as_string='yes'` are both true
1537    /// there and both are turned away here, which is a gap that closes on its own the day the
1538    /// optimizer runs before the plan is finished. `binary_as_string=True` is what the ClickBench
1539    /// entry writes and is what has to work.
1540    ///
1541    /// A name that is not a parameter of this function is the binary's sentence followed by what it
1542    /// could have been. The binary puts the candidates on their own indented lines and this puts
1543    /// them on the same line, because an error is one line here.
1544    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    /// A file where a table name goes, which is what DuckDB calls a replacement scan.
1585    ///
1586    /// `SELECT * FROM 'hits.parquet'` is how most DuckDB queries in the wild are written, ClickBench
1587    /// among them, so this is not sugar over `read_parquet` so much as the spelling people use. The
1588    /// catalog has already been asked and has already said no, and `missing` is what it said, so a
1589    /// name that is not a file comes back with the catalog's own answer rather than with a complaint
1590    /// about files.
1591    ///
1592    /// Only a single unqualified name is a candidate. A qualified one names a schema and a schema
1593    /// that does not exist is not a path.
1594    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                // A file that is really there and that nothing here can read is a different mistake
1608                // from a name that is not a file, and DuckDB says so with both lines, the second of
1609                // which is the way out. A file with no dot in it lands here too, which is why the
1610                // test is on the extension having a reader rather than on there being an extension.
1611                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        // The pattern is expanded before it is known to match anything, so a name that ends in .csv
1620        // and is not there gives the reader's own message rather than the catalog's. That is
1621        // DuckDB's order and it is the helpful one: somebody who wrote a file name wants to hear
1622        // about the file.
1623        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        // The name the columns answer to is the file's stem, so `SELECT mixed.a FROM
1630        // 'data/mixed.parquet'` works. That is DuckDB's choice and it is the useful one, since the
1631        // alternative is a table name with a dot and a slash in it that nothing can write. A pattern
1632        // keeps the whole of what was written instead, which is DuckDB's choice too and was
1633        // measured: there is no stem to take when the name stands for a directory full of files.
1634        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    /// One file name, as a constant expression in the plan.
1650    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    /// The table function a file with this extension is read by, and `None` for one nothing reads.
1656    ///
1657    /// Both spellings of a tab separated file go to the CSV reader, which is not a shortcut: the
1658    /// extension picks the reader and the reader sniffs the punctuation, so a `.tsv` file that holds
1659    /// commas is read as commas. That was measured rather than assumed. The comparison ignores case
1660    /// because `UP.CSV` reads in duckdb v1.4.1.
1661    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    /// The node and the scope of a table function call whose arguments and columns are settled.
1672    ///
1673    /// The half a written out call shares with a replacement scan, which is everything after the
1674    /// question of what the file is called has been answered one way or the other.
1675    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                // A reader takes what the file has, and no file format this reads says a column
1693                // cannot be null. The reference binary answers YES for every column of a Parquet.
1694                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    /// Every file a table function's file argument names, in the order they were written.
1720    ///
1721    /// Each pattern has to find at least one file of its own, which is DuckDB's rule and is why
1722    /// this expands one at a time rather than gathering everything and looking at the total. A
1723    /// list keeps its written order and its duplicates, so a file named twice is read twice, which
1724    /// was measured: the sort and the dedup belong to one pattern rather than to the list.
1725    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    /// The patterns a table function argument names, which have to be constants.
1734    ///
1735    /// A table function that reads a file is resolved by opening the file, and that happens here
1736    /// rather than when the query runs, because the rest of the statement cannot bind until the
1737    /// column names are known. So the path has to be something this binder can work out without
1738    /// running anything, and a literal is that. DuckDB folds a constant expression first, so
1739    /// `read_parquet('a' || '.parquet')` works there, and folding is M1 work that this will pick up
1740    /// for free once the optimizer runs before the plan is finished rather than after.
1741    ///
1742    /// One string is one pattern and a list is one pattern an item, which is DuckDB's pair of
1743    /// overloads. A null is a different sentence in each of them, both of them measured.
1744    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            // DuckDB's own wording, which says list because its other overload takes one.
1753            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        // NATURAL is USING over whatever both sides happen to call the same thing, which is why it
1786        // is resolved here and never reaches the plan as its own idea.
1787        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            // A name written twice is one column, not two. `USING (id, id)` is legal and means what
1800            // `USING (id)` means, and the reference binary agrees. Taking it twice would build the
1801            // same equality twice and, worse, drop the right side's copy twice, which takes a
1802            // column out of the answer that nobody named and runs off the end of the scope when the
1803            // copy was the last column in it.
1804            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        // A joined-on column appears once, so the right side's copy goes. Dropping from the back
1843        // keeps the positions of the ones still to drop correct.
1844        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    // -------------------------------------------------------------- aggregates
1885
1886    /// Binds an aggregate call, records it, and hands back a reference to where its result lands.
1887    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        // Two identical aggregates are one column of the aggregate's output. `SELECT sum(x),
1937        // sum(x) / count(*)` computes one sum, not two.
1938        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    /// Rewrites a bound expression into one the aggregate's output can answer.
1954    ///
1955    /// A subexpression that is one of the group expressions becomes a reference to that group. A
1956    /// column that is neither grouped nor inside an aggregate is the error every SQL user has seen,
1957    /// and it is reported here because this is the first point where it is knowable.
1958    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    /// Whether two bound expressions are the same expression, by shape rather than by reference.
2030    pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
2031        same_expr(&self.plan, left, right)
2032    }
2033}
2034
2035/// The named parameters a table function call was written with.
2036///
2037/// A struct rather than the fields loose, because the seventeen DuckDB has on `read_parquet` and the
2038/// thirty on `read_csv` are all going to want somewhere to go, and because a call with none of them
2039/// written should read as the default of this rather than as a bare false somewhere.
2040///
2041/// The CSV half goes on to the reader and is opened with, here and again in the executor. The
2042/// Parquet half is answered here and nothing downstream sees it, which is what `binary_as_string`
2043/// turning a BLOB column into a VARCHAR one is.
2044#[derive(Debug, Default)]
2045struct Options {
2046    /// `binary_as_string`, which says an unannotated byte array column in a Parquet file holds
2047    /// text. The ClickBench file has twenty eight of those and every query reads them as strings.
2048    binary_as_string: bool,
2049    /// `all_varchar`, which reads every column of a CSV file as text rather than sniffing a type.
2050    all_varchar: bool,
2051    /// `file_row_number`, which adds a column holding each row's ordinal inside its own file.
2052    ///
2053    /// The one Parquet option here that the executor has to act on rather than the binder, since
2054    /// the column is not in the file and has to be counted as the rows come out of it.
2055    file_row_number: bool,
2056    /// `delim`, `sep`, `quote`, `escape` and `header`, which are what the sniffer would decide.
2057    given: Given,
2058}
2059
2060impl Options {
2061    /// What these named parameters add up to.
2062    ///
2063    /// Each one was already checked against the function's list, so a name in here is a name that
2064    /// function takes and the value is already the type it wants. What is left is reading them, and
2065    /// the last one written wins, which is DuckDB's answer to `delim='|', delim=','` and was
2066    /// measured rather than assumed.
2067    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
2084/// DuckDB's complaint about a named parameter that was given a null, which is a different sentence
2085/// for almost every parameter.
2086///
2087/// Three of them were measured on `v2.0.0-dev84237` and no two agree: `binary_as_string` is the
2088/// first, `all_varchar` is the second and `header` is the third. They read like three people each
2089/// writing the message in front of them, which is what they are, and a harness that compares error
2090/// text compares all of it. Anything not measured gets the first one, which is the most general of
2091/// the three.
2092fn 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
2100/// The complaint about a `REPLACE` entry that named a column the star did not stand for.
2101///
2102/// It reads like the complaint about any other name that is not there, down to the list of names
2103/// that are, because from the writer's side it is the same mistake.
2104fn 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
2111/// Structural equality over two expressions of one plan.
2112fn 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}