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 std::sync::Arc;
16
17use rudb_catalog::{Catalog, Entry, QualifiedName, same_name};
18use rudb_common::bounds::Zones;
19use rudb_common::{
20    Error, Field, LogicalType, Result, Semantics, Session, ShowBehavior, Span, Stat, Value,
21};
22use rudb_functions::{
23    Columns, FILE_ROW_NUMBER, FunctionKind, Given, Resolved, TableFunction, csv_fields, csv_given,
24    files, is_file, is_pattern, kind_of, parquet_footers, resolve, resolve_pragma, resolve_table,
25};
26use rudb_kernels::{percentage, row_count};
27use rudb_parse::ast::{self, Ast, Distinct, LiteralKind, Nulls, Order, Quantifier, SetOp};
28use rudb_parse::{NONE, identifier_parts, parse_ast_with_case};
29use rudb_plan::{
30    Bound, BuildSide, ColumnBinding, ConjunctionOp, Expr, ExprRef, JoinKind, Node, NodeRef, Plan,
31    SetOpKind, Share, SortKey, WindowBound, WindowExclude, WindowFrame, WindowUnit,
32};
33
34use crate::expr::{describe, has_aggregate};
35use crate::fold;
36use crate::parameters::Parameters;
37use crate::scope::{Scope, Visible};
38
39/// Binds a parsed statement against a catalog.
40///
41/// # Errors
42///
43/// If the script does not hold exactly one statement, if a name does not resolve, if a type does
44/// not work out, or if the query uses something M0 does not bind yet.
45pub fn bind(ast: &Ast, catalog: &Catalog) -> Result<Plan> {
46    bind_with(ast, catalog, &Parameters::new(), &Session::new())
47}
48
49/// Binds a parsed query against a catalog, with values for its parameters and its settings.
50///
51/// The session is what `current_setting()` reads, and a caller with no database behind it passes an
52/// empty one, which makes every setting name unrecognized rather than making up an answer.
53///
54/// # Errors
55///
56/// Everything [`bind`] reports, plus an error for a parameter that was given no value.
57pub fn bind_with(
58    ast: &Ast,
59    catalog: &Catalog,
60    parameters: &Parameters,
61    session: &Session,
62) -> Result<Plan> {
63    let query = match ast.statements.as_slice() {
64        [ast::Statement::Query(query)] => *query,
65        [] => return Err(Error::binder("no statement to bind")),
66        // One statement that is not a query is its own answer. Reporting it as a script of several
67        // reads as a count being wrong, and the count is right.
68        [_] => return Err(Error::not_implemented("a statement that is not a query")),
69        _ => return Err(Error::not_implemented("a script of more than one statement")),
70    };
71    let mut binder = Binder::with(catalog, parameters, session);
72    let (root, _) = binder.bind_query(ast, query)?;
73    let mut plan = binder.into_plan();
74    plan.set_root(root);
75    plan.validate()?;
76    Ok(plan)
77}
78
79/// Parses and binds one query, which is the whole front end in one call.
80///
81/// # Errors
82///
83/// Anything the parser or the binder reports.
84pub fn bind_sql(query: &str, catalog: &Catalog) -> Result<Plan> {
85    bind_sql_with(query, catalog, &Session::new())
86}
87
88/// Parses and binds one query, with the settings a call to `current_setting()` reads.
89///
90/// # Errors
91///
92/// Anything the parser or the binder reports.
93pub fn bind_sql_with(query: &str, catalog: &Catalog, session: &Session) -> Result<Plan> {
94    let ast = parse_ast_with_case(query, session.semantics().identifier_case())?;
95    bind_with(&ast, catalog, &Parameters::new(), session)
96}
97
98/// What an aggregating select block has decided so far.
99#[derive(Debug)]
100pub(crate) struct Aggregation {
101    /// The table index the aggregate's output binds against.
102    pub(crate) index: u32,
103    /// The group expressions, over the input, which are the first output columns.
104    pub(crate) groups: Vec<ExprRef>,
105    /// The aggregate calls found so far, which follow the groups in the output.
106    pub(crate) aggregates: Vec<ExprRef>,
107}
108
109/// One run of window calls that agree on where the rows come from and in what order.
110///
111/// The run is the unit the plan has an operator for, so two calls that write the same partition,
112/// the same order and the same frame are one operator and one sort, and a third that writes a
113/// different order is a second operator stacked on the first. Nothing here merges runs that only
114/// look compatible, because a window is evaluated over the rows the operator below it produced and
115/// deciding two runs are the same is the optimizer's job rather than the binder's.
116#[derive(Debug)]
117pub(crate) struct WindowRun {
118    /// The table index the run's result columns bind against.
119    index: u32,
120    /// What divides the input into independent partitions.
121    partition: Vec<ExprRef>,
122    /// The order within a partition.
123    order: Vec<SortKey>,
124    /// The frame every call in the run shares.
125    frame: WindowFrame,
126    /// The calls, in the order their columns are appended.
127    calls: Vec<ExprRef>,
128}
129
130/// One window call as it was written, before any of it has been bound.
131///
132/// These six travel together from the parser all the way to the run they end up filed under, and
133/// carrying them as one thing keeps the call that binds them readable.
134pub(crate) struct WindowCall<'a> {
135    /// The function name, as written and not yet resolved.
136    pub(crate) name: &'a str,
137    /// The arguments, which may include a star that only `count` is allowed to be given.
138    pub(crate) args: &'a [ast::ExprRef],
139    /// Whether `DISTINCT` was written inside the parens.
140    pub(crate) distinct: bool,
141    /// The `FILTER (WHERE ...)` predicate, which is written before the `OVER`, or `NONE`.
142    pub(crate) filter: ast::ExprRef,
143    /// Whether `IGNORE NULLS` was written inside the parens, which is where DuckDB puts it.
144    pub(crate) ignore_nulls: bool,
145    /// The `ORDER BY` written inside the parens, which says what order the call reads the rows of
146    /// its frame in and is a different clause from the one in the `OVER`.
147    pub(crate) order: ast::Slice,
148    /// The `OVER`, which the parser has already resolved against any `WINDOW` clause.
149    pub(crate) spec: ast::WindowRef,
150}
151
152/// Everything inside one window call once it is bound, which is what decides its run.
153struct WindowParts {
154    /// The arguments, before the casts the resolved signature asks for.
155    args: Vec<ExprRef>,
156    /// What divides the input into independent partitions.
157    partition: Vec<ExprRef>,
158    /// The order within a partition.
159    order: Vec<SortKey>,
160    /// The order the call reads the rows of its frame in, which is the `ORDER BY` written inside
161    /// the brackets rather than the one in the `OVER` and is empty far more often than not.
162    inner: Vec<SortKey>,
163    /// The frame, with both ends and the exclusion.
164    frame: WindowFrame,
165}
166
167/// What opening the files behind a table function call said about them.
168///
169/// The answers travel together because they come out of the same footer. A Parquet file states its
170/// columns, its row count and its statistics in the same few kilobytes at the end of it, so a
171/// binder that has read one has read all of them, and splitting them into four arguments would
172/// mean four ways to forget one.
173#[derive(Debug)]
174struct Read {
175    /// The columns the call produces, in the order the file stores them.
176    fields: Vec<Field>,
177    /// How many rows all of the files hold, where anybody counted.
178    rows: Stat<u64>,
179    /// How many distinct values a column holds, by name, for the columns anybody counted.
180    distincts: Vec<(String, Stat<u64>)>,
181    /// The bounds the files keep per part of themselves, where anything can answer for them.
182    zones: Option<Arc<dyn Zones>>,
183}
184
185impl Read {
186    /// Columns that came from somewhere other than a file, so nothing counted anything.
187    fn uncounted(fields: Vec<Field>) -> Self {
188        Self { fields, rows: Stat::Unknown, distincts: Vec::new(), zones: None }
189    }
190}
191
192/// A materialised `WITH` definition that has been bound and can be read by name.
193#[derive(Debug)]
194struct Materialized {
195    /// Which written definition this is, as an index into `Ast::ctes`.
196    written: u32,
197    /// The number the plan uses to pair a read with what it reads.
198    cte: u32,
199    /// The name it was written with, which is the table name a read is reachable through.
200    name: String,
201    /// What it produces, in order, under the declared names when a column list was written.
202    fields: Vec<Field>,
203}
204
205#[derive(Debug)]
206pub(crate) struct PendingSubquery {
207    pub(crate) node: NodeRef,
208    pub(crate) kind: JoinKind,
209    pub(crate) conditions: Vec<ExprRef>,
210    pub(crate) dependent: bool,
211    /// The outer columns the query's body read, which is what `dependent` counts.
212    ///
213    /// Kept rather than reduced to the flag because a join's `ON` has to decide which of its two
214    /// inputs the query is joined into, and the answer is the side those columns come from. A
215    /// query that reads neither side can go on either.
216    pub(crate) reads: Vec<ColumnBinding>,
217    /// The table index this query's join adds to the rows it is joined into.
218    ///
219    /// Kept so that a `HAVING` which reads one of these can say which columns came from a query
220    /// joined above the grouping rather than from the table underneath it. Those columns are not
221    /// the table's and the grouping rule has nothing to say about them.
222    pub(crate) index: u32,
223    /// Whether the query was written inside an aggregate call's argument or its `FILTER`.
224    ///
225    /// One written there is read once per row going into the aggregate, so it has to be joined in
226    /// underneath the grouping however uncorrelated it is. Every other query a grouped block writes
227    /// is one row for the whole block and is lifted over the grouping instead, which is what
228    /// [`Binder::lift_over_aggregate`] decides.
229    pub(crate) inside_aggregate: bool,
230}
231
232/// Which input of a join a query written in that join's `ON` is joined into.
233#[derive(Debug, Clone, Copy, PartialEq, Eq)]
234enum Side {
235    Left,
236    Right,
237}
238
239/// The state one binding run carries.
240#[derive(Debug)]
241pub(crate) struct Binder<'a> {
242    catalog: &'a Catalog,
243    /// What the parameters were given, empty for a statement that is not prepared.
244    pub(crate) parameters: &'a Parameters,
245    /// What the settings are now, which is what `current_setting()` folds to.
246    pub(crate) session: &'a Session,
247    /// Meaning-changing choices copied once and resolved into the plan above execution.
248    pub(crate) semantics: Semantics,
249    plan: Plan,
250    next_index: u32,
251    /// Source range inherited by plan objects built for the current AST expression or query.
252    pub(crate) current_span: Span,
253    /// Set while a select block aggregates, which changes what a bare column means.
254    pub(crate) aggregation: Option<Aggregation>,
255    /// Set while an aggregate's own arguments are being bound, so nesting is caught.
256    pub(crate) in_aggregate: bool,
257    /// Set while an aggregate's `FILTER` is being bound, which is refused its own aggregate.
258    pub(crate) in_filter: bool,
259    /// The window runs this select block has collected, in the order they were first written.
260    pub(crate) windows: Vec<WindowRun>,
261    /// Set while a window call's own arguments and keys are being bound, so nesting is caught.
262    pub(crate) in_window: bool,
263    /// Uncorrelated scalar queries waiting to be joined into the select block that uses them.
264    pub(crate) scalar_subqueries: Vec<PendingSubquery>,
265    /// Table indices of the queries this block will join in above its grouping, not below it.
266    ///
267    /// Only ever set while a `HAVING` is being rewritten over the aggregate. A column from one of
268    /// these is not a column of the grouped table, so the rule about grouping every column does not
269    /// reach it, and the join that produces it goes on top of the `Aggregate` rather than under it.
270    pub(crate) joined_above: Vec<u32>,
271    pub(crate) outer_scopes: Vec<Scope>,
272    /// Which of the outer scopes are a FROM entry's left neighbours rather than an enclosing query.
273    ///
274    /// The two are resolved the same way and refused differently. An aggregate may read a column of
275    /// the query it is written in and may not read one a LATERAL brought in from the left, so the
276    /// check needs to know which scope the name came out of. Each entry is a position in
277    /// `outer_scopes`.
278    pub(crate) lateral_scopes: Vec<usize>,
279    pub(crate) correlations: Vec<Vec<ColumnBinding>>,
280    /// Where we are, for an error message that says which clause the writer should look at.
281    pub(crate) clause: &'static str,
282    /// The views whose bodies are open on the stack, which is what catches a cycle.
283    expanding: Vec<String>,
284    /// The materialised `WITH` definitions whose bodies are being bound, innermost last.
285    ///
286    /// A stack rather than a map from what was written, because a plain `WITH` is put into every
287    /// place it is named, so a materialised one written inside a plain one is bound once per use
288    /// and each of those is a materialisation of its own with a number of its own.
289    materialized: Vec<Materialized>,
290    /// How many materialisations have been numbered, which is where the next number comes from.
291    next_cte: u32,
292    /// When this statement started, read once and kept, which is what `now()` folds to.
293    started: Option<i64>,
294}
295
296impl<'a> Binder<'a> {
297    pub(crate) fn with(
298        catalog: &'a Catalog,
299        parameters: &'a Parameters,
300        session: &'a Session,
301    ) -> Self {
302        Self {
303            catalog,
304            parameters,
305            session,
306            semantics: session.semantics(),
307            plan: Plan::new(),
308            next_index: 0,
309            current_span: Span::new(0, 0),
310            aggregation: None,
311            in_aggregate: false,
312            in_filter: false,
313            windows: Vec::new(),
314            in_window: false,
315            scalar_subqueries: Vec::new(),
316            joined_above: Vec::new(),
317            outer_scopes: Vec::new(),
318            lateral_scopes: Vec::new(),
319            correlations: Vec::new(),
320            clause: "SELECT clause",
321            expanding: Vec::new(),
322            materialized: Vec::new(),
323            next_cte: 0,
324            started: None,
325        }
326    }
327
328    pub(crate) fn catalog(&self) -> &Catalog {
329        self.catalog
330    }
331
332    /// When this statement started, in microseconds since the epoch.
333    ///
334    /// Read from the clock the first time something asks and kept after that, so a query that
335    /// writes `now()` twice gets one answer for both. That is what the pin does and what it reports
336    /// in the `stability` column of `duckdb_functions()`, where every one of these is
337    /// `CONSISTENT_WITHIN_QUERY`. A query that never asks never reads the clock.
338    pub(crate) fn instant(&mut self) -> i64 {
339        *self.started.get_or_insert_with(crate::context::micros_now)
340    }
341
342    pub(crate) fn plan(&self) -> &Plan {
343        &self.plan
344    }
345
346    pub(crate) fn plan_mut(&mut self) -> &mut Plan {
347        &mut self.plan
348    }
349
350    pub(crate) fn add_expr(&mut self, expr: Expr, ty: LogicalType) -> ExprRef {
351        self.plan.add_expr_at(expr, ty, self.current_span)
352    }
353
354    pub(crate) fn add_constant(&mut self, value: Value) -> ExprRef {
355        let ty = value.logical_type();
356        let reference = self.plan.add_value(value);
357        self.plan.add_expr_at(Expr::Constant(reference), ty, self.current_span)
358    }
359
360    pub(crate) fn add_node(&mut self, node: Node) -> NodeRef {
361        self.plan.add_node_at(node, self.current_span)
362    }
363
364    pub(crate) fn into_plan(self) -> Plan {
365        self.plan
366    }
367
368    /// A table index nothing else has.
369    pub(crate) fn fresh_index(&mut self) -> u32 {
370        let index = self.next_index;
371        self.next_index += 1;
372        index
373    }
374
375    /// A reference to one column of an operator's output.
376    fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
377        let binding = ColumnBinding::new(index, position as u32);
378        self.plan.add_expr(Expr::Column(binding), ty)
379    }
380
381    /// Joins scalar query results into the row stream that contains their expressions.
382    fn attach_scalar_subqueries(&mut self, mut input: NodeRef) -> NodeRef {
383        let subqueries = std::mem::take(&mut self.scalar_subqueries);
384        for pending in subqueries {
385            input = self.attach_subquery(input, pending);
386        }
387        input
388    }
389
390    /// Joins one query's result into a row stream, which is where its columns come from.
391    ///
392    /// Split out from [`Self::attach_scalar_subqueries`] because a join's `ON` does not attach its
393    /// queries to the rows the whole `FROM` produced. It attaches them to one of the join's two
394    /// inputs, since a join condition is evaluated by the join and can only read what the join was
395    /// given.
396    fn attach_subquery(&mut self, input: NodeRef, pending: PendingSubquery) -> NodeRef {
397        let PendingSubquery {
398            node: mut right,
399            kind,
400            conditions,
401            dependent,
402            reads: _,
403            index: _,
404            inside_aggregate: _,
405        } = pending;
406        if kind == JoinKind::Single && !self.semantics.scalar_subquery_error_on_multiple_rows() {
407            right = self.add_node(Node::Limit {
408                input: right,
409                count: Bound::Rows(1),
410                offset: Bound::Rows(0),
411            });
412        }
413        let conditions = self.plan.add_expr_list(&conditions);
414        if dependent {
415            self.add_node(Node::DependentJoin { left: input, right, kind, conditions })
416        } else {
417            self.add_node(Node::Join {
418                left: input,
419                right,
420                kind,
421                conditions,
422                build: BuildSide::default(),
423            })
424        }
425    }
426
427    // ---------------------------------------------------------------- queries
428
429    pub(crate) fn bind_query(
430        &mut self,
431        ast: &Ast,
432        query: ast::QueryRef,
433    ) -> Result<(NodeRef, Scope)> {
434        let span = ast.query_span(query);
435        let outer = std::mem::replace(&mut self.current_span, span);
436        let result =
437            self.bind_query_inner(ast, query).map_err(|error| error.with_fallback_span(span));
438        self.current_span = outer;
439        result
440    }
441
442    fn bind_query_inner(&mut self, ast: &Ast, query: ast::QueryRef) -> Result<(NodeRef, Scope)> {
443        let written = ast.query(query);
444        if written.ctes.is_empty() {
445            return self.bind_body(ast, &written);
446        }
447        // The names a query introduces are gone again once it is bound, and they go whether the
448        // binding worked or not, which is why the stack is cut back here rather than at the end of
449        // the call that pushed onto it.
450        let depth = self.materialized.len();
451        let result = self.bind_materialized(ast, &written);
452        self.materialized.truncate(depth);
453        result
454    }
455
456    /// A query with materialised `WITH` definitions in front of it.
457    ///
458    /// The definitions are bound first and in the order they were written, so that a later one can
459    /// read an earlier one, and then the body. The wrapping runs backwards so that the first
460    /// definition ends up outermost, which is the order they have to be filled in.
461    fn bind_materialized(&mut self, ast: &Ast, written: &ast::Query) -> Result<(NodeRef, Scope)> {
462        let depth = self.materialized.len();
463        let held = ast.cte_list(written.ctes).to_vec();
464        let mut definitions = Vec::with_capacity(held.len());
465        for &index in &held {
466            definitions.push(self.bind_definition(ast, index)?);
467        }
468        let (mut node, scope) = self.bind_body(ast, written)?;
469        for (at, definition) in definitions.into_iter().enumerate().rev() {
470            let entry = &self.materialized[depth + at];
471            let cte = entry.cte;
472            let name = entry.name.clone();
473            let fields = entry.fields.clone();
474            let name = self.plan.intern(&name);
475            let columns = self.plan.add_fields(&fields);
476            node =
477                self.add_node(Node::MaterializedCte { definition, body: node, name, cte, columns });
478        }
479        Ok((node, scope))
480    }
481
482    /// Binds one materialised `WITH` definition and makes its name readable from there on.
483    ///
484    /// The definition is projected onto exactly the columns a read of it sees, under the names the
485    /// column list declared when there was one. That projection is not decoration: what is held is
486    /// what a read gets back, so the held rows have to be the rows of the definition's own select
487    /// list and nothing it happened to carry along underneath.
488    ///
489    /// A column list with more names in it than the definition has columns is not an error here,
490    /// which is the pinned build's rule and is written out on [`Scope::rename_prefix`].
491    fn bind_definition(&mut self, ast: &Ast, index: u32) -> Result<NodeRef> {
492        let held = ast.cte(index);
493        let name = ast.string(held.name).to_string();
494        let (node, mut scope) = self.bind_query(ast, held.query)?;
495        if !held.columns.is_empty() {
496            let names: Vec<&str> = ast.name(held.columns).collect();
497            scope.rename_prefix(&names);
498        }
499        let table = self.fresh_index();
500        let mut exprs = Vec::with_capacity(scope.len());
501        let mut names = Vec::with_capacity(scope.len());
502        for column in &scope.columns {
503            exprs.push(self.plan.add_expr(Expr::Column(column.binding), column.ty.clone()));
504            names.push(self.plan.intern(&column.name));
505        }
506        let exprs = self.plan.add_expr_list(&exprs);
507        let names = self.plan.add_name_list(&names);
508        let node = self.add_node(Node::Project { input: node, index: table, exprs, names });
509        let cte = self.next_cte;
510        self.next_cte += 1;
511        self.materialized.push(Materialized { written: index, cte, name, fields: scope.fields() });
512        Ok(node)
513    }
514
515    fn bind_body(&mut self, ast: &Ast, written: &ast::Query) -> Result<(NodeRef, Scope)> {
516        match written.body {
517            ast::QueryBody::Select(select) => self.bind_select(ast, select, written),
518            ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
519                let operator = Operator { op, quantifier, by_name };
520                self.bind_set_op(ast, written, operator, left, right)
521            }
522            ast::QueryBody::Values(rows) => self.bind_values(ast, written, rows),
523            ast::QueryBody::Describe(inner) => self.bind_describe(ast, written, inner),
524            ast::QueryBody::Show { name, relation } => self.bind_show(ast, written, name, relation),
525        }
526    }
527
528    /// `SHOW name`, resolved while binding so execution receives an ordinary constant plan.
529    fn bind_show(
530        &mut self,
531        ast: &Ast,
532        query: &ast::Query,
533        name: ast::Slice,
534        relation: ast::QueryRef,
535    ) -> Result<(NodeRef, Scope)> {
536        let text = ast.name_text(name);
537        let parts: Vec<&str> = ast.name(name).collect();
538        let table_exists = self.catalog.resolve(&parts).is_ok();
539        let as_table = match self.semantics.show_behavior() {
540            ShowBehavior::Auto => table_exists,
541            ShowBehavior::Setting => false,
542            ShowBehavior::Table => true,
543        };
544        if as_table {
545            return self.bind_describe(ast, query, relation);
546        }
547        let Some((_, value)) =
548            self.session.iter().find(|(name, _)| name.eq_ignore_ascii_case(&text))
549        else {
550            return Err(Error::catalog(format!("Setting with name \"{text}\" does not exist")));
551        };
552        let field = Field::new(text, LogicalType::Varchar);
553        let expr = self.plan.add_constant(Value::Varchar(value.to_string()));
554        let row = self.plan.add_expr_list(&[expr]);
555        let rows = self.plan.add_rows(&[row]);
556        let columns = self.plan.add_fields(std::slice::from_ref(&field));
557        let index = self.fresh_index();
558        let node = self.add_node(Node::Values { index, columns, rows });
559        let mut scope = Scope::empty();
560        scope.push(Visible {
561            table: String::new(),
562            name: field.name,
563            binding: ColumnBinding::new(index, 0),
564            ty: LogicalType::Varchar,
565            not_null: false,
566        });
567        Ok((node, scope))
568    }
569
570    /// `DESCRIBE <query>`, which is six VARCHAR columns saying what the query returns.
571    ///
572    /// The query is bound and never run, because binding is the whole of the answer: the names and
573    /// the types of a query's columns are settled by the time the binder is done with it, so the
574    /// rows of a describe are a constant from there on. That is why this comes out as a `VALUES`
575    /// whose rows were computed here rather than as an operator of its own, and it is what makes
576    /// `SELECT column_name FROM (DESCRIBE ...) WHERE ...` an ordinary query over an ordinary
577    /// relation with no special case above it.
578    ///
579    /// The six columns, their order and their types are the reference binary's. `key`, `default`
580    /// and `extra` are null for everything this engine can declare, since `PRIMARY KEY`, `UNIQUE`
581    /// and `DEFAULT` are all refused by `CREATE TABLE` today and there is nothing for the first two
582    /// to hold, and `extra` is empty upstream as well on every table it was asked about. They are
583    /// here rather than left out because the width of a result is part of the result, and a program
584    /// that reads the fifth column has to find one.
585    fn bind_describe(
586        &mut self,
587        ast: &Ast,
588        query: &ast::Query,
589        inner: ast::QueryRef,
590    ) -> Result<(NodeRef, Scope)> {
591        let (_, described) = self.bind_query(ast, inner)?;
592        let fields: Vec<Field> = ["column_name", "column_type", "null", "key", "default", "extra"]
593            .iter()
594            .map(|name| Field::new(*name, LogicalType::Varchar))
595            .collect();
596        let mut slices = Vec::with_capacity(described.columns.len());
597        for column in described.columns.clone() {
598            // `NO` and `YES` and not a boolean, because the column is VARCHAR upstream and a
599            // client that prints the result has to get the same four or three characters.
600            let written = [
601                column.name.clone(),
602                column.ty.to_string(),
603                if column.not_null { "NO" } else { "YES" }.to_owned(),
604            ];
605            let mut items: Vec<ExprRef> = written
606                .into_iter()
607                .map(|text| self.plan.add_constant(Value::Varchar(text)))
608                .collect();
609            for _ in 0..3 {
610                let empty = self.plan.add_constant(Value::Null);
611                items.push(self.cast_to(empty, &LogicalType::Varchar));
612            }
613            slices.push(self.plan.add_expr_list(&items));
614        }
615        let rows = self.plan.add_rows(&slices);
616        let columns = self.plan.add_fields(&fields);
617        let index = self.fresh_index();
618        let mut node = self.add_node(Node::Values { index, columns, rows });
619        let mut scope = Scope::empty();
620        for (at, field) in fields.iter().enumerate() {
621            scope.push(Visible {
622                table: String::new(),
623                name: field.name.clone(),
624                binding: ColumnBinding::new(index, at as u32),
625                ty: field.ty.clone(),
626                not_null: false,
627            });
628        }
629        let keys = self.sort_keys(ast, query, &scope, &[])?;
630        if !keys.is_empty() {
631            let keys = self.plan.add_sort_keys(&keys);
632            node = self.add_node(Node::Sort { input: node, keys });
633        }
634        node = self.apply_limit(ast, query, node, &mut scope)?;
635        Ok((node, scope))
636    }
637
638    /// Whether a projected expression is a column passed straight through from below.
639    ///
640    /// Only `DESCRIBE` asks, and only to decide whether the `null` column says `NO`. Anything that
641    /// is computed is nullable however strict its inputs were, which is both the safe reading and
642    /// the one the reference binary gives.
643    fn passes_through(&self, expr: ExprRef, input: &Scope) -> bool {
644        let Expr::Column(binding) = *self.plan.expr(expr) else { return false };
645        input.columns.iter().any(|column| column.binding == binding && column.not_null)
646    }
647
648    /// `VALUES (1, 'a'), (2, 'b')`, as a query in its own right.
649    ///
650    /// The column names are `col0`, `col1` and so on, which is what DuckDB calls them, and the
651    /// column types are what every row in that position promotes to. Promotion is the same rule a
652    /// set operation uses, and for the same reason: a column has one type and the rows have to
653    /// agree on it before anything downstream can read the column.
654    fn bind_values(
655        &mut self,
656        ast: &Ast,
657        query: &ast::Query,
658        rows: ast::Slice,
659    ) -> Result<(NodeRef, Scope)> {
660        let written = ast.rows(rows).to_vec();
661        let Some(first) = written.first() else {
662            return Err(Error::binder("VALUES needs at least one row"));
663        };
664        let width = first.len as usize;
665        for (at, row) in written.iter().enumerate() {
666            if row.len as usize != width {
667                return Err(Error::binder(format!(
668                    "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
669                    at + 1,
670                    row.len
671                )));
672            }
673        }
674        // A row of a `VALUES` cannot see a column, because there is nothing under it to see.
675        let empty = Scope::empty();
676        let previous = std::mem::replace(&mut self.clause, "VALUES clause");
677        let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
678        for row in &written {
679            let mut items = Vec::with_capacity(width);
680            for &expr in ast.expr_list(*row) {
681                items.push(self.bind_expr(ast, expr, &empty)?);
682            }
683            bound.push(items);
684        }
685        self.clause = previous;
686        let mut types = Vec::with_capacity(width);
687        for at in 0..width {
688            let mut ty = self.plan.expr_type(bound[0][at]).clone();
689            for row in &bound[1..] {
690                let other = self.plan.expr_type(row[at]).clone();
691                ty = ty.promote(&other).ok_or_else(|| {
692                    Error::binder(format!(
693                        "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
694                        at + 1
695                    ))
696                })?;
697            }
698            types.push(ty);
699        }
700        let mut slices = Vec::with_capacity(bound.len());
701        for row in &bound {
702            let items: Vec<ExprRef> = row
703                .iter()
704                .zip(&types)
705                .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
706                .collect::<Result<_>>()?;
707            slices.push(self.plan.add_expr_list(&items));
708        }
709        let rows = self.plan.add_rows(&slices);
710        let fields: Vec<Field> = types
711            .iter()
712            .enumerate()
713            .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
714            .collect();
715        let columns = self.plan.add_fields(&fields);
716        let index = self.fresh_index();
717        let mut node = self.add_node(Node::Values { index, columns, rows });
718        let mut scope = Scope::empty();
719        for (at, field) in fields.iter().enumerate() {
720            scope.push(Visible {
721                table: String::new(),
722                name: field.name.clone(),
723                binding: ColumnBinding::new(index, at as u32),
724                ty: field.ty.clone(),
725                not_null: false,
726            });
727        }
728        let keys = self.sort_keys(ast, query, &scope, &[])?;
729        if !keys.is_empty() {
730            let keys = self.plan.add_sort_keys(&keys);
731            node = self.add_node(Node::Sort { input: node, keys });
732        }
733        node = self.apply_limit(ast, query, node, &mut scope)?;
734        Ok((node, scope))
735    }
736
737    fn bind_set_op(
738        &mut self,
739        ast: &Ast,
740        query: &ast::Query,
741        operator: Operator,
742        left: ast::QueryRef,
743        right: ast::QueryRef,
744    ) -> Result<(NodeRef, Scope)> {
745        let (left_node, left_scope) = self.bind_query(ast, left)?;
746        let (right_node, right_scope) = self.bind_query(ast, right)?;
747        let merged = if operator.by_name {
748            match_by_name(&left_scope, &right_scope)?
749        } else {
750            match_by_position(&left_scope, &right_scope)?
751        };
752        let left_node = self.conform(left_node, &left_scope, &merged, |column| column.left)?;
753        let right_node = self.conform(right_node, &right_scope, &merged, |column| column.right)?;
754        let index = self.fresh_index();
755        let kind = match operator.op {
756            SetOp::Union => SetOpKind::Union,
757            SetOp::Except => SetOpKind::Except,
758            SetOp::Intersect => SetOpKind::Intersect,
759        };
760        // UNION alone removes duplicates and UNION ALL keeps them, which is the one place the
761        // unwritten quantifier and ALL disagree.
762        let all = operator.quantifier == Quantifier::All;
763        let mut node =
764            self.add_node(Node::SetOp { left: left_node, right: right_node, kind, all, index });
765        let mut scope = Scope::empty();
766        for (at, column) in merged.iter().enumerate() {
767            scope.push(Visible {
768                table: String::new(),
769                name: column.name.clone(),
770                binding: ColumnBinding::new(index, at as u32),
771                ty: column.ty.clone(),
772                // A column of a set operation is nullable whatever the two sides were, because a
773                // column that refuses nulls on one side and takes them on the other takes them.
774                not_null: false,
775            });
776        }
777        // Above a set operation there is nothing but the output columns, so an ORDER BY term is
778        // either a position, an output name, or an expression over the output, and never needs a
779        // column projected for it that the query did not ask for.
780        let keys = self.sort_keys(ast, query, &scope, &[])?;
781        if !keys.is_empty() {
782            let keys = self.plan.add_sort_keys(&keys);
783            node = self.add_node(Node::Sort { input: node, keys });
784        }
785        node = self.apply_limit(ast, query, node, &mut scope)?;
786        Ok((node, scope))
787    }
788
789    /// Projects one side of a set operation onto the columns the operation comes out with.
790    ///
791    /// `pick` says which column of this side each output column is. It answers nothing for a
792    /// column only the other side wrote, which happens under `BY NAME` and which this side fills
793    /// with a null, since that is the row it would have written if it had written the column.
794    fn conform(
795        &mut self,
796        node: NodeRef,
797        scope: &Scope,
798        merged: &[Merged],
799        pick: impl Fn(&Merged) -> Option<usize>,
800    ) -> Result<NodeRef> {
801        let unchanged = merged.len() == scope.len()
802            && merged
803                .iter()
804                .enumerate()
805                .all(|(at, column)| pick(column) == Some(at) && column.ty == scope.columns[at].ty);
806        if unchanged {
807            return Ok(node);
808        }
809        let index = self.fresh_index();
810        let mut exprs = Vec::with_capacity(merged.len());
811        let mut names = Vec::with_capacity(merged.len());
812        for column in merged {
813            let expr = match pick(column) {
814                Some(at) => {
815                    let held = &scope.columns[at];
816                    self.plan.add_expr(Expr::Column(held.binding), held.ty.clone())
817                }
818                None => self.plan.add_constant(Value::Null),
819            };
820            exprs.push(self.checked_cast_to(expr, &column.ty, false)?);
821            names.push(self.plan.intern(&column.name));
822        }
823        let exprs = self.plan.add_expr_list(&exprs);
824        let names = self.plan.add_name_list(&names);
825        Ok(self.add_node(Node::Project { input: node, index, exprs, names }))
826    }
827
828    // ----------------------------------------------------------------- select
829
830    fn bind_select(
831        &mut self,
832        ast: &Ast,
833        select: ast::SelectRef,
834        query: &ast::Query,
835    ) -> Result<(NodeRef, Scope)> {
836        let written = ast.select(select);
837        // A window belongs to the block that wrote it, and a block can be bound inside another one
838        // without a subquery in between, so the outer block's runs are put aside for the duration
839        // rather than left where a nested block would append to them.
840        let outer_windows = std::mem::take(&mut self.windows);
841        // Same argument for the queries lifted over this block's grouping. They are recorded while
842        // the select list is being bound and read until the sort keys are done, and a block bound
843        // inside that stretch has its own set, so the outer block's is put aside rather than left
844        // where the inner one would clear it.
845        let outer_joined_above = std::mem::take(&mut self.joined_above);
846        let (mut node, input) = self.bind_from(ast, written.from)?;
847        node = self.attach_scalar_subqueries(node);
848
849        if written.filter != NONE {
850            self.clause = "WHERE clause";
851            let predicate = self.bind_expr(ast, written.filter, &input)?;
852            let predicate = self.as_boolean(predicate, "WHERE")?;
853            node = self.attach_scalar_subqueries(node);
854            node = self.add_node(Node::Filter { input: node, predicate });
855        }
856
857        let targets = ast.target_list(written.targets).to_vec();
858        if targets.is_empty() {
859            return Err(Error::binder("a SELECT needs at least one expression to select"));
860        }
861
862        let group_items = self.group_items(ast, &written, &targets)?;
863        let aggregating = !group_items.is_empty()
864            || written.having != NONE
865            || targets.iter().any(|target| has_aggregate(ast, target.expr));
866        if aggregating {
867            self.clause = "GROUP BY clause";
868            let mut groups = Vec::with_capacity(group_items.len());
869            for item in &group_items {
870                groups.push(self.bind_expr(ast, *item, &input)?);
871            }
872            let index = self.fresh_index();
873            self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
874        }
875
876        // The queries this block's clauses wrote that are joined in above the grouping rather than
877        // below it. TPC-H q11 is the case in a `HAVING`: `HAVING sum(ps_supplycost * ps_availqty) >
878        // (SELECT sum(...))` compares one group's total against a total over the whole table, and
879        // the second total is one row that has nothing to do with the groups. Joined underneath the
880        // grouping it would be a column of every input row and the grouping rule would ask for it in
881        // the GROUP BY, which is the complaint this used to make.
882        let mut above = Vec::new();
883
884        self.clause = "SELECT clause";
885        let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input, &mut above)?;
886        let visible = exprs.len();
887
888        let mut having = None;
889        if written.having != NONE {
890            self.clause = "HAVING clause";
891            let before = self.scalar_subqueries.len();
892            let predicate = self.bind_expr(ast, written.having, &input)?;
893            self.lift_over_aggregate(before, &mut above, &input)?;
894            let predicate = self.over_aggregate(predicate, &input)?;
895            having = Some(self.as_boolean(predicate, "HAVING")?);
896        }
897
898        // The projection's index has to exist before the sort keys are built, because a key is a
899        // reference to a projected column even when the expression it sorts on is not selected.
900        let project = self.fresh_index();
901        let mut output = Scope::empty();
902        for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
903            output.push(Visible {
904                table: String::new(),
905                name: name.clone(),
906                binding: ColumnBinding::new(project, at as u32),
907                ty: self.plan.expr_type(*expr).clone(),
908                not_null: self.passes_through(*expr, &input),
909            });
910        }
911
912        self.clause = "ORDER BY clause";
913        let mut extra = Vec::new();
914        let keys = self.select_sort_keys(
915            ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra, &mut above,
916        )?;
917        self.joined_above = outer_joined_above;
918        if !extra.is_empty() && written.distinct != Distinct::No {
919            return Err(Error::binder(
920                "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
921            ));
922        }
923        let on = self.distinct_on(ast, written.distinct, &output)?;
924
925        node = self.attach_scalar_subqueries(node);
926
927        if let Some(aggregation) = self.aggregation.take() {
928            let index = aggregation.index;
929            let groups = self.plan.add_expr_list(&aggregation.groups);
930            let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
931            node = self.add_node(Node::Aggregate { input: node, index, groups, aggregates });
932        }
933        if !above.is_empty() {
934            debug_assert!(self.scalar_subqueries.is_empty(), "a query is waiting to be joined");
935            self.scalar_subqueries = above;
936            node = self.attach_scalar_subqueries(node);
937        }
938        if let Some(predicate) = having {
939            node = self.add_node(Node::Filter { input: node, predicate });
940        }
941
942        // After the grouping and after `HAVING`, which is where the reference binary puts it:
943        // `SELECT j, sum(count(i)) OVER () FROM t GROUP BY j HAVING count(i) > 1` totals only the
944        // groups that survived the filter.
945        for run in std::mem::replace(&mut self.windows, outer_windows) {
946            let partition = self.plan.add_expr_list(&run.partition);
947            let order = self.plan.add_sort_keys(&run.order);
948            let expressions = self.plan.add_expr_list(&run.calls);
949            node = self.add_node(Node::Window {
950                input: node,
951                index: run.index,
952                partition,
953                order,
954                frame: run.frame,
955                expressions,
956            });
957        }
958
959        let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
960        let exprs_slice = self.plan.add_expr_list(&exprs);
961        let names_slice = self.plan.add_name_list(&interned);
962        node = self.add_node(Node::Project {
963            input: node,
964            index: project,
965            exprs: exprs_slice,
966            names: names_slice,
967        });
968
969        if written.distinct != Distinct::No {
970            let on = self.plan.add_expr_list(&on);
971            node = self.add_node(Node::Distinct { input: node, on });
972        }
973        if !keys.is_empty() {
974            let keys = self.plan.add_sort_keys(&keys);
975            node = self.add_node(Node::Sort { input: node, keys });
976        }
977        node = self.apply_limit(ast, query, node, &mut output)?;
978
979        if extra.is_empty() {
980            output.columns.truncate(visible);
981            return Ok((node, output));
982        }
983        // An expression sorted on but not selected was carried this far to make the sort possible,
984        // and now it goes, because the query did not ask for it.
985        let index = self.fresh_index();
986        let mut kept = Vec::with_capacity(visible);
987        let mut kept_names = Vec::with_capacity(visible);
988        let mut scope = Scope::empty();
989        for (at, name) in names.iter().enumerate().take(visible) {
990            let ty = output.columns[at].ty.clone();
991            // Through the scope rather than through `project`, because a limit that had a query
992            // joined in under it put a projection of its own over the top and these columns are
993            // that projection's now.
994            let binding = output.columns[at].binding;
995            kept.push(self.plan.add_expr(Expr::Column(binding), ty.clone()));
996            kept_names.push(self.plan.intern(name));
997            scope.push(Visible {
998                table: String::new(),
999                name: name.clone(),
1000                binding: ColumnBinding::new(index, at as u32),
1001                ty,
1002                not_null: output.columns[at].not_null,
1003            });
1004        }
1005        let exprs = self.plan.add_expr_list(&kept);
1006        let names = self.plan.add_name_list(&kept_names);
1007        node = self.add_node(Node::Project { input: node, index, exprs, names });
1008        Ok((node, scope))
1009    }
1010
1011    /// Binds the target list, expanding every star into the columns it stands for.
1012    /// Moves the queries a clause just wrote from under this block's grouping to over it.
1013    ///
1014    /// A query written in a select list, a `HAVING` or an `ORDER BY` is one row that has nothing to
1015    /// do with the groups, so it belongs on top of the grouping and not underneath it. Underneath,
1016    /// its column is a column of every row going into the aggregate, which the grouping rule then
1017    /// asks for in the `GROUP BY`, and the aggregate carries nothing but its groups and its
1018    /// aggregates upward, so the projection could not read the column even if the rule let it
1019    /// through. That is both halves of #1027.
1020    ///
1021    /// A correlated one still goes underneath, because what it correlates to is a column of the
1022    /// rows going into the grouping and there is nothing above the grouping to read. So does one
1023    /// written inside an aggregate call, since that is read once per row going into the aggregate
1024    /// and lifting it over would put it where the aggregate that reads it cannot.
1025    ///
1026    /// `before` is what [`Self::scalar_subqueries`] held before the clause was bound, so only the
1027    /// queries that clause wrote are considered.
1028    fn lift_over_aggregate(
1029        &mut self,
1030        before: usize,
1031        above: &mut Vec<PendingSubquery>,
1032        scope: &Scope,
1033    ) -> Result<()> {
1034        if self.aggregation.is_none() {
1035            return Ok(());
1036        }
1037        let mut lifted = Vec::new();
1038        for pending in self.scalar_subqueries.split_off(before) {
1039            if pending.dependent || pending.inside_aggregate {
1040                self.scalar_subqueries.push(pending);
1041            } else {
1042                self.joined_above.push(pending.index);
1043                lifted.push(pending);
1044            }
1045        }
1046        // A mark join carries its comparison rather than the expression carrying it, and that
1047        // comparison is written over the outer rows, so it needs the same rewrite the expression
1048        // gets. It is done in a second pass so that a comparison reading another query lifted by
1049        // the same clause finds that query's index already recorded.
1050        for pending in &mut lifted {
1051            let conditions = std::mem::take(&mut pending.conditions);
1052            let mut over = Vec::with_capacity(conditions.len());
1053            for condition in conditions {
1054                over.push(self.over_aggregate(condition, scope)?);
1055            }
1056            pending.conditions = over;
1057        }
1058        above.append(&mut lifted);
1059        Ok(())
1060    }
1061
1062    fn bind_targets(
1063        &mut self,
1064        ast: &Ast,
1065        targets: &[ast::Target],
1066        input: &Scope,
1067        above: &mut Vec<PendingSubquery>,
1068    ) -> Result<(Vec<ExprRef>, Vec<String>)> {
1069        let mut exprs = Vec::with_capacity(targets.len());
1070        let mut names = Vec::with_capacity(targets.len());
1071        for target in targets {
1072            if let ast::Expr::Star { qualifier, replacements } = ast.expr(target.expr) {
1073                let table = ast.name(qualifier).last().map(str::to_string);
1074                let expanded: Vec<Visible> =
1075                    input.star(table.as_deref())?.into_iter().cloned().collect();
1076                let replacements = ast.target_list(replacements).to_vec();
1077                let mut used = vec![false; replacements.len()];
1078                for column in expanded {
1079                    let found = replacements.iter().zip(&mut used).find(|(replacement, _)| {
1080                        same_name(ast.string(replacement.alias), &column.name)
1081                    });
1082                    // The replacement takes the column's place and its position, and it is named the
1083                    // way the replace list spells it rather than the way the table does. That only
1084                    // shows when the two differ in case, and `AS EventDate` over a column called
1085                    // `eventdate` is exactly the case that shows it.
1086                    let before = self.scalar_subqueries.len();
1087                    let (expr, name) = match found {
1088                        Some((replacement, used)) => {
1089                            *used = true;
1090                            let expr = self.bind_expr(ast, replacement.expr, input)?;
1091                            (expr, ast.string(replacement.alias).to_string())
1092                        }
1093                        None => (
1094                            self.plan.add_expr(Expr::Column(column.binding), column.ty),
1095                            column.name,
1096                        ),
1097                    };
1098                    self.lift_over_aggregate(before, above, input)?;
1099                    exprs.push(self.over_aggregate(expr, input)?);
1100                    names.push(name);
1101                }
1102                // A replace list that named something the star did not stand for is a mistake and
1103                // not a no op, and it is caught here because this is the first point at which the
1104                // set of names the star stands for is known.
1105                if let Some((replacement, _)) =
1106                    replacements.iter().zip(&used).find(|(_, used)| !**used)
1107                {
1108                    return Err(missing_replacement(ast.string(replacement.alias), input));
1109                }
1110                continue;
1111            }
1112            let before = self.scalar_subqueries.len();
1113            let expr = self.bind_expr(ast, target.expr, input)?;
1114            self.lift_over_aggregate(before, above, input)?;
1115            exprs.push(self.over_aggregate(expr, input)?);
1116            names.push(if target.alias == NONE {
1117                self.output_name(ast, target.expr, input)
1118            } else {
1119                ast.string(target.alias).to_string()
1120            });
1121        }
1122        Ok((exprs, names))
1123    }
1124
1125    /// The name an unaliased target gets.
1126    ///
1127    /// A bare column keeps the spelling the table was created with rather than the spelling the
1128    /// query used, so `SELECT USERID FROM hits` has a column called `UserID`. Identifiers match
1129    /// without regard to case and the catalog is the one that holds the case.
1130    fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
1131        if let ast::Expr::Column { name } = ast.expr(target) {
1132            let parts: Vec<&str> = ast.name(name).collect();
1133            if let Ok(found) = input.resolve(&parts) {
1134                return found.name.clone();
1135            }
1136        }
1137        describe(ast, target, self.semantics)
1138    }
1139
1140    /// The expressions a `GROUP BY` clause names, with positions and output aliases followed.
1141    fn group_items(
1142        &self,
1143        ast: &Ast,
1144        select: &ast::Select,
1145        targets: &[ast::Target],
1146    ) -> Result<Vec<ast::ExprRef>> {
1147        if select.group_by_all {
1148            // GROUP BY ALL means every target that is not itself an aggregate, which is the set
1149            // that would otherwise have to be written out again by hand.
1150            return Ok(targets
1151                .iter()
1152                .filter(|target| !has_aggregate(ast, target.expr))
1153                .map(|target| target.expr)
1154                .collect());
1155        }
1156        let mut items = Vec::new();
1157        for &item in ast.expr_list(select.group_by) {
1158            items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
1159        }
1160        Ok(items)
1161    }
1162
1163    /// The target a `GROUP BY` or `ORDER BY` term names, when it names one by position or alias.
1164    fn output_reference(
1165        &self,
1166        ast: &Ast,
1167        item: ast::ExprRef,
1168        targets: &[ast::Target],
1169        clause: &str,
1170    ) -> Result<Option<ast::ExprRef>> {
1171        match ast.expr(item) {
1172            ast::Expr::Literal { kind: LiteralKind::Number, text } => {
1173                let written = ast.string(text);
1174                let position: usize = written.parse().map_err(|_| {
1175                    Error::binder(format!("{clause} term {written} is not a column"))
1176                })?;
1177                if position == 0 || position > targets.len() {
1178                    return Err(Error::binder(format!(
1179                        "{clause} term out of range - should be between 1 and {}",
1180                        targets.len()
1181                    )));
1182                }
1183                Ok(Some(targets[position - 1].expr))
1184            }
1185            ast::Expr::Column { name } => {
1186                let parts: Vec<&str> = ast.name(name).collect();
1187                let [written] = parts.as_slice() else { return Ok(None) };
1188                let mut found = None;
1189                for target in targets {
1190                    if target.alias != NONE && same_name(ast.string(target.alias), written) {
1191                        if found.is_some() {
1192                            return Ok(None);
1193                        }
1194                        found = Some(target.expr);
1195                    }
1196                }
1197                Ok(found)
1198            }
1199            _ => Ok(None),
1200        }
1201    }
1202
1203    // -------------------------------------------------------------- modifiers
1204
1205    /// Sort keys for a select, projecting anything sorted on that is not already selected.
1206    #[allow(clippy::too_many_arguments)]
1207    fn select_sort_keys(
1208        &mut self,
1209        ast: &Ast,
1210        query: &ast::Query,
1211        input: &Scope,
1212        output: &Scope,
1213        project: u32,
1214        exprs: &mut Vec<ExprRef>,
1215        names: &mut Vec<String>,
1216        extra: &mut Vec<usize>,
1217        above: &mut Vec<PendingSubquery>,
1218    ) -> Result<Vec<SortKey>> {
1219        if query.order_by_all {
1220            return Ok(self.every_column(output));
1221        }
1222        let items = ast.order_list(query.order_by).to_vec();
1223        let mut keys = Vec::with_capacity(items.len());
1224        for item in items {
1225            self.check_order_literal(ast, item.expr)?;
1226            let position = match self.output_position(ast, item.expr, output)? {
1227                Some(position) => position,
1228                None => {
1229                    let before = self.scalar_subqueries.len();
1230                    let bound = self.bind_expr(ast, item.expr, input)?;
1231                    self.lift_over_aggregate(before, above, input)?;
1232                    let bound = self.over_aggregate(bound, input)?;
1233                    match exprs.iter().position(|&held| self.same_expr(held, bound)) {
1234                        Some(position) => position,
1235                        None => {
1236                            exprs.push(bound);
1237                            names.push(describe(ast, item.expr, self.semantics));
1238                            extra.push(exprs.len() - 1);
1239                            exprs.len() - 1
1240                        }
1241                    }
1242                }
1243            };
1244            let ty = self.plan.expr_type(exprs[position]).clone();
1245            let expr = self.column(project, position, ty);
1246            keys.push(self.sort_key(expr, item));
1247        }
1248        Ok(keys)
1249    }
1250
1251    /// Sort keys over an output that has nothing behind it to project, which is a set operation.
1252    fn sort_keys(
1253        &mut self,
1254        ast: &Ast,
1255        query: &ast::Query,
1256        output: &Scope,
1257        targets: &[ast::Target],
1258    ) -> Result<Vec<SortKey>> {
1259        if query.order_by_all {
1260            return Ok(self.every_column(output));
1261        }
1262        let items = ast.order_list(query.order_by).to_vec();
1263        let mut keys = Vec::with_capacity(items.len());
1264        for item in items {
1265            self.check_order_literal(ast, item.expr)?;
1266            let expr = match self.output_position(ast, item.expr, output)? {
1267                Some(position) => {
1268                    let column = &output.columns[position];
1269                    let (binding, ty) = (column.binding, column.ty.clone());
1270                    self.plan.add_expr(Expr::Column(binding), ty)
1271                }
1272                None => {
1273                    let _ = targets;
1274                    self.bind_expr(ast, item.expr, output)?
1275                }
1276            };
1277            keys.push(self.sort_key(expr, item));
1278        }
1279        Ok(keys)
1280    }
1281
1282    fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
1283        let columns: Vec<(ColumnBinding, LogicalType)> =
1284            output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
1285        columns
1286            .into_iter()
1287            .map(|(binding, ty)| {
1288                let expr = self.plan.add_expr(Expr::Column(binding), ty);
1289                let descending = self.semantics.default_descending();
1290                SortKey { expr, descending, nulls_first: self.semantics.nulls_first(descending) }
1291            })
1292            .collect()
1293    }
1294
1295    /// A sort key with the session defaults filled in.
1296    fn sort_key(&self, expr: ExprRef, item: ast::OrderItem) -> SortKey {
1297        let descending = match item.order {
1298            Order::Unstated => self.semantics.default_descending(),
1299            Order::Ascending => false,
1300            Order::Descending => true,
1301        };
1302        let nulls_first = match item.nulls {
1303            Nulls::First => true,
1304            Nulls::Last => false,
1305            Nulls::Unstated => self.semantics.nulls_first(descending),
1306        };
1307        SortKey { expr, descending, nulls_first }
1308    }
1309
1310    /// Which output column a term names, by position or by name.
1311    fn output_position(
1312        &self,
1313        ast: &Ast,
1314        item: ast::ExprRef,
1315        output: &Scope,
1316    ) -> Result<Option<usize>> {
1317        match ast.expr(item) {
1318            ast::Expr::Literal { kind: LiteralKind::Number, text } => {
1319                let written = ast.string(text);
1320                if written.contains(['.', 'e', 'E']) {
1321                    return Ok(None);
1322                }
1323                let position: usize = written.parse().map_err(|_| {
1324                    Error::binder(format!("ORDER BY term {written} is not a column"))
1325                })?;
1326                if position == 0 || position > output.len() {
1327                    return Err(Error::binder(format!(
1328                        "ORDER BY term out of range - should be between 1 and {}",
1329                        output.len()
1330                    )));
1331                }
1332                Ok(Some(position - 1))
1333            }
1334            ast::Expr::Column { name } => {
1335                let parts: Vec<&str> = ast.name(name).collect();
1336                let [written] = parts.as_slice() else { return Ok(None) };
1337                Ok(output.position_of(None, written))
1338            }
1339            _ => Ok(None),
1340        }
1341    }
1342
1343    /// Refuses a literal sort key unless the session explicitly accepts its no-op behavior.
1344    fn check_order_literal(&self, ast: &Ast, item: ast::ExprRef) -> Result<()> {
1345        if !self.semantics.order_by_non_integer_literal()
1346            && matches!(
1347                ast.expr(item),
1348                ast::Expr::Literal { kind, text }
1349                    if kind != LiteralKind::Number
1350                        || ast.string(text).contains(['.', 'e', 'E'])
1351            )
1352        {
1353            return Err(Error::binder(
1354                "ORDER BY non-integer literal has no effect.\n* SET order_by_non_integer_literal=true to allow this behavior.",
1355            ));
1356        }
1357        Ok(())
1358    }
1359
1360    /// The expressions a `DISTINCT ON` names, which have to be columns of the output.
1361    fn distinct_on(
1362        &mut self,
1363        ast: &Ast,
1364        distinct: Distinct,
1365        output: &Scope,
1366    ) -> Result<Vec<ExprRef>> {
1367        let Distinct::On(items) = distinct else {
1368            return Ok(Vec::new());
1369        };
1370        let items = ast.expr_list(items).to_vec();
1371        let mut on = Vec::with_capacity(items.len());
1372        for item in items {
1373            let Some(position) = self.output_position(ast, item, output)? else {
1374                return Err(Error::not_implemented(
1375                    "DISTINCT ON an expression that is not in the select list",
1376                ));
1377            };
1378            let column = &output.columns[position];
1379            let (binding, ty) = (column.binding, column.ty.clone());
1380            on.push(self.plan.add_expr(Expr::Column(binding), ty));
1381        }
1382        Ok(on)
1383    }
1384
1385    /// The `LIMIT` and the `OFFSET`, over the rows everything else in the query produced.
1386    ///
1387    /// The scope is taken by reference because a limit the binder could not work out reads its
1388    /// number off a query joined in underneath, and that join puts a column in the rows which the
1389    /// query did not ask for. A projection over the limit drops it again, and the scope has to say
1390    /// so, since its bindings are what anything above this reads.
1391    fn apply_limit(
1392        &mut self,
1393        ast: &Ast,
1394        query: &ast::Query,
1395        input: NodeRef,
1396        scope: &mut Scope,
1397    ) -> Result<NodeRef> {
1398        let waiting = self.scalar_subqueries.len();
1399        if query.limit_percent {
1400            let percent = self.share(ast, query.limit)?;
1401            let offset = self.skipped(ast, query.offset)?;
1402            let node = |binder: &mut Self, input| match percent {
1403                Some(percent) => binder.add_node(Node::LimitPercent { input, percent, offset }),
1404                // A null share is no limit at all, the same as a null row count, so what is left
1405                // is whatever the offset asked for.
1406                None => binder.limited(input, Bound::All, offset),
1407            };
1408            return self.over_subqueries(waiting, input, scope, node);
1409        }
1410        let count = self.count_bound(ast, query.limit, "LIMIT")?;
1411        let offset = self.skipped(ast, query.offset)?;
1412        let node = |binder: &mut Self, input| binder.limited(input, count, offset);
1413        self.over_subqueries(waiting, input, scope, node)
1414    }
1415
1416    /// The offset a query wrote, as nought rows skipped when it wrote none.
1417    ///
1418    /// An offset the query left off is nought rows skipped, where a limit it left off is every row
1419    /// emitted, so the two clauses read the same word differently.
1420    fn skipped(&mut self, ast: &Ast, written: ast::ExprRef) -> Result<Bound> {
1421        Ok(match self.count_bound(ast, written, "OFFSET")? {
1422            Bound::All => Bound::Rows(0),
1423            named => named,
1424        })
1425    }
1426
1427    /// Builds a limit node over `input`, joining in whatever queries its bounds turned out to need.
1428    ///
1429    /// A bound the binder could not work out reads its number off a column, and that column comes
1430    /// from a query joined in underneath. The join puts a column in the rows nobody asked for, so a
1431    /// projection over the limit drops it again and the scope is told to read that projection. When
1432    /// no query had to be joined in there is nothing to drop and the limit stands on its own.
1433    fn over_subqueries(
1434        &mut self,
1435        waiting: usize,
1436        input: NodeRef,
1437        scope: &mut Scope,
1438        node: impl FnOnce(&mut Self, NodeRef) -> NodeRef,
1439    ) -> Result<NodeRef> {
1440        let joined = self.scalar_subqueries.split_off(waiting);
1441        if joined.is_empty() {
1442            return Ok(node(self, input));
1443        }
1444        let mut input = input;
1445        for pending in joined {
1446            input = self.attach_subquery(input, pending);
1447        }
1448        let limit = node(self, input);
1449        Ok(self.reproject(limit, scope))
1450    }
1451
1452    /// A row count limit over `input`, or `input` itself when neither half of the clause asks for
1453    /// anything.
1454    fn limited(&mut self, input: NodeRef, count: Bound, offset: Bound) -> NodeRef {
1455        if count == Bound::All && offset == Bound::Rows(0) {
1456            return input;
1457        }
1458        self.add_node(Node::Limit { input, count, offset })
1459    }
1460
1461    /// A projection over `node` handing back exactly the columns `scope` names.
1462    ///
1463    /// The scope's bindings are rewritten to this projection's, because its columns are the ones
1464    /// anything above reads. Only a limit that had a query joined in under it wants this, and only
1465    /// because there is not always a projection above to drop the column that join added.
1466    fn reproject(&mut self, node: NodeRef, scope: &mut Scope) -> NodeRef {
1467        let index = self.fresh_index();
1468        let mut exprs = Vec::with_capacity(scope.columns.len());
1469        let mut names = Vec::with_capacity(scope.columns.len());
1470        for column in &scope.columns {
1471            exprs.push(self.plan.add_expr(Expr::Column(column.binding), column.ty.clone()));
1472            names.push(self.plan.intern(&column.name));
1473        }
1474        for (at, column) in scope.columns.iter_mut().enumerate() {
1475            column.binding = ColumnBinding::new(index, at as u32);
1476        }
1477        let exprs = self.plan.add_expr_list(&exprs);
1478        let names = self.plan.add_name_list(&names);
1479        self.add_node(Node::Project { input: node, index, exprs, names })
1480    }
1481
1482    /// The share of the input a `LIMIT n PERCENT` names.
1483    ///
1484    /// The same evaluation as a row count and a different type at the end of it: the value is cast
1485    /// to `DOUBLE` rather than to `BIGINT`, so `LIMIT '30'%` is thirty percent and `LIMIT true%` is
1486    /// one percent, which is what the pin answers. A null is no limit at all.
1487    ///
1488    /// The range is checked here because the pin checks it here. `LIMIT 101 PERCENT` fails an
1489    /// `EXPLAIN` on the pinned binary, so it is refused while the query is planned and not when it
1490    /// is run, and a `NAN` is outside the range like any other value that is not between nought and
1491    /// a hundred.
1492    ///
1493    /// What the binder cannot work out is a subquery and a call that answers differently every
1494    /// time, the same two things a row count cannot work out, and those become a [`Share::Read`]
1495    /// over the expression. The value is checked where it turns up instead, which is the executor.
1496    /// Only the sign can be written that way, because the grammar refuses `PERCENT` after a closing
1497    /// bracket, but nothing below here depends on which of the two was typed.
1498    fn share(&mut self, ast: &Ast, written: ast::ExprRef) -> Result<Option<Share>> {
1499        if written == NONE {
1500            return Ok(None);
1501        }
1502        self.clause = "LIMIT clause";
1503        let scope = Scope::empty();
1504        let bound = self.bind_expr(ast, written, &scope)?;
1505        let Some(value) = fold::value_of(&self.plan, bound)? else {
1506            return Ok(Some(Share::Read(bound)));
1507        };
1508        if value.is_null() {
1509            return Ok(None);
1510        }
1511        let percent = percentage(&value)?;
1512        if !(0.0..=100.0).contains(&percent) {
1513            return Err(Error::out_of_range(
1514                "Limit percent out of range, should be between 0% and 100%",
1515            ));
1516        }
1517        Ok(Some(Share::Percent(percent)))
1518    }
1519
1520    /// The row count a `LIMIT` or an `OFFSET` names.
1521    ///
1522    /// It does not have to be a literal. Anything whose value is settled before the first row is
1523    /// read will do, so `LIMIT 1 + 1` and `LIMIT CAST(3 AS BIGINT)` are both two, and that is what
1524    /// the pin does with them: its binder evaluates the expression and writes the number down.
1525    ///
1526    /// What is left over is an expression the binder cannot settle, which is a subquery, because it
1527    /// has to run first, and a call that answers differently every time it is made, such as
1528    /// `RANDOM()` or `nextval`. Those become a [`Bound::Read`] holding the expression, and the
1529    /// number comes off the first chunk that reaches the limit. The pin takes both and answers them
1530    /// the same way.
1531    ///
1532    /// The value is cast to `BIGINT` whatever it was written as, which is the whole of the type
1533    /// rule. `LIMIT '3'` is three rows because the string converts, `LIMIT 2.5` is three rows
1534    /// because the conversion rounds, `LIMIT true` is one row, and `LIMIT DATE '2020-01-01'` is the
1535    /// cast refusing a date. Every one of those messages is the cast's own, which is why there is
1536    /// no type check here to write a worse one. A limit that is read while the query runs is cast
1537    /// the same way by the operator that reads it, so the two paths answer alike.
1538    fn count_bound(&mut self, ast: &Ast, written: ast::ExprRef, clause: &str) -> Result<Bound> {
1539        if written == NONE {
1540            return Ok(Bound::All);
1541        }
1542        self.clause = "LIMIT clause";
1543        let scope = Scope::empty();
1544        let bound = self.bind_expr(ast, written, &scope)?;
1545        let Some(value) = fold::value_of(&self.plan, bound)? else {
1546            return Ok(Bound::Read(bound));
1547        };
1548        // A null is no limit at all, the same as leaving the clause off, and the pin agrees:
1549        // `LIMIT NULL` and `LIMIT CAST(NULL AS INTEGER)` both answer every row.
1550        if value.is_null() {
1551            return Ok(Bound::All);
1552        }
1553        row_count(&value, clause).map(Bound::Rows)
1554    }
1555
1556    // ------------------------------------------------------------------- from
1557
1558    fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
1559        let sources = ast.source_list(from).to_vec();
1560        let Some((first, rest)) = sources.split_first() else {
1561            // No FROM clause is one row of no columns, which is what SELECT 1 sits on. Not an
1562            // empty table: an empty table would make SELECT 1 return nothing.
1563            return Ok((self.add_node(Node::Dummy), Scope::empty()));
1564        };
1565        let (mut node, mut scope) = self.bind_source(ast, *first)?;
1566        for source in rest {
1567            let (right, right_scope, correlations) = self.bind_lateral(ast, *source, &scope)?;
1568            node = if correlations.is_empty() {
1569                self.add_node(Node::CrossProduct { left: node, right })
1570            } else {
1571                let conditions = self.plan.add_expr_list(&[]);
1572                self.add_node(Node::DependentJoin {
1573                    left: node,
1574                    right,
1575                    kind: JoinKind::Inner,
1576                    conditions,
1577                })
1578            };
1579            scope = scope.concat(right_scope);
1580        }
1581        Ok((node, scope))
1582    }
1583
1584    /// Binds one FROM entry with everything written to its left already visible.
1585    ///
1586    /// That is what LATERAL means, and it is what a comma separated FROM does here whether the word
1587    /// was written or not, because the pinned build resolves `FROM o, (SELECT o.k + 1)` without it.
1588    /// The keyword therefore changes nothing and is accepted rather than acted on.
1589    ///
1590    /// The columns of the left that the entry read come back with it, and an entry that read none
1591    /// is an ordinary product. The rest are somebody else's: a name that resolved past the left
1592    /// neighbours belongs to an enclosing query, so it is handed up to whichever frame is waiting
1593    /// for it rather than counted here, or the subquery this FROM sits in would lose track of its
1594    /// own correlation.
1595    fn bind_lateral(
1596        &mut self,
1597        ast: &Ast,
1598        source: ast::SourceRef,
1599        left: &Scope,
1600    ) -> Result<(NodeRef, Scope, Vec<ColumnBinding>)> {
1601        self.lateral_scopes.push(self.outer_scopes.len());
1602        self.outer_scopes.push(left.clone());
1603        self.correlations.push(Vec::new());
1604        let bound = self.bind_source(ast, source);
1605        let read = self.correlations.pop().expect("correlation frame");
1606        self.outer_scopes.pop();
1607        self.lateral_scopes.pop();
1608        let (node, scope) = bound?;
1609
1610        let mut here = Vec::new();
1611        for binding in read {
1612            if left.columns.iter().any(|column| column.binding == binding) {
1613                here.push(binding);
1614            } else if let Some(enclosing) = self.correlations.last_mut() {
1615                if !enclosing.contains(&binding) {
1616                    enclosing.push(binding);
1617                }
1618            }
1619        }
1620        // A table function is allowed to read the left the same as anything else here. There is
1621        // nothing underneath one for the domain to be pushed into, since its arguments are what
1622        // produce its rows, so the unnesting pass turns it into a `LateralFunction` and the call is
1623        // made once per domain value. That is `domain.rs`.
1624        //
1625        // Nothing has to be turned down here for the functions that would not survive it. The only
1626        // table functions taking an argument that is not a name are the series family, which is the
1627        // family that operator answers, and a name that is not a constant is refused where the
1628        // columns are settled, because settling them means opening the file or reading the catalog.
1629        Ok((node, scope, here))
1630    }
1631
1632    fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
1633        match ast.source(source) {
1634            ast::Source::Table { name, alias, columns } => {
1635                self.bind_table(ast, name, alias, columns)
1636            }
1637            ast::Source::Function { name, args, alias, columns, pragma } => {
1638                self.bind_table_function(ast, name, args, alias, columns, pragma)
1639            }
1640            ast::Source::Subquery { query, alias, columns } => {
1641                let (node, mut scope) = self.bind_query(ast, query)?;
1642                let label = if alias == NONE {
1643                    "unnamed_subquery".to_string()
1644                } else {
1645                    ast.string(alias).to_string()
1646                };
1647                scope.relabel(&label);
1648                if !columns.is_empty() {
1649                    let names: Vec<&str> = ast.name(columns).collect();
1650                    scope.rename(&names, &label)?;
1651                }
1652                Ok((node, scope))
1653            }
1654            ast::Source::Values { rows, alias, columns } => {
1655                let bare = ast::Query::bare(ast::QueryBody::Values(rows));
1656                let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
1657                let label =
1658                    if alias == NONE { String::new() } else { ast.string(alias).to_string() };
1659                scope.relabel(&label);
1660                if !columns.is_empty() {
1661                    let names: Vec<&str> = ast.name(columns).collect();
1662                    scope.rename(&names, &label)?;
1663                }
1664                Ok((node, scope))
1665            }
1666            ast::Source::Cte { cte, alias, columns } => {
1667                self.bind_cte_scan(ast, cte, alias, columns)
1668            }
1669            ast::Source::Join { left, right, kind, natural, on, using } => {
1670                self.bind_join(ast, left, right, kind, natural, on, using)
1671            }
1672        }
1673    }
1674
1675    /// A read of a materialised `WITH`, which is a leaf the same way a table scan is.
1676    ///
1677    /// Which definition it reads was settled by the parser, so there is no name to look up here and
1678    /// no shadowing left to think about. What is looked up is the materialisation that definition
1679    /// turned into, and the search runs backwards because the same definition is bound again for
1680    /// each use of a plain `WITH` it sits inside, and a read means the innermost of those.
1681    fn bind_cte_scan(
1682        &mut self,
1683        ast: &Ast,
1684        written: u32,
1685        alias: ast::StrRef,
1686        columns: ast::Slice,
1687    ) -> Result<(NodeRef, Scope)> {
1688        let Some(held) = self.materialized.iter().rev().find(|held| held.written == written) else {
1689            let name = ast.string(ast.cte(written).name);
1690            return Err(Error::binder(format!("Table with name {name} does not exist!")));
1691        };
1692        let cte = held.cte;
1693        let fields = held.fields.clone();
1694        let text = held.name.clone();
1695        let label = if alias == NONE { text.clone() } else { ast.string(alias).to_string() };
1696        let name = self.plan.intern(&text);
1697        let index = self.fresh_index();
1698        let mut scope = Scope::empty();
1699        for (at, field) in fields.iter().enumerate() {
1700            scope.push(Visible {
1701                table: label.clone(),
1702                name: field.name.clone(),
1703                binding: ColumnBinding::new(index, at as u32),
1704                ty: field.ty.clone(),
1705                not_null: field.not_null,
1706            });
1707        }
1708        if !columns.is_empty() {
1709            let names: Vec<&str> = ast.name(columns).collect();
1710            scope.rename(&names, &label)?;
1711        }
1712        let columns = self.plan.add_fields(&fields);
1713        let node = self.add_node(Node::CteScan { index, cte, name, columns });
1714        Ok((node, scope))
1715    }
1716
1717    fn bind_table(
1718        &mut self,
1719        ast: &Ast,
1720        name: ast::Slice,
1721        alias: ast::StrRef,
1722        columns: ast::Slice,
1723    ) -> Result<(NodeRef, Scope)> {
1724        let parts: Vec<&str> = ast.name(name).collect();
1725        let catalog = self.catalog;
1726        // The catalog is asked first and the file is the fallback, which is the order DuckDB uses:
1727        // a table really called `mixed.parquet` wins over a file of that name sitting next to it.
1728        let resolved = match catalog.resolve(&parts) {
1729            Ok(resolved) => resolved,
1730            Err(missing) => {
1731                return self.bind_replacement_scan(ast, &parts, alias, columns, missing);
1732            }
1733        };
1734        if catalog.entry(&resolved)? == Entry::View {
1735            return self.bind_view(ast, &resolved, alias, columns);
1736        }
1737        let table = catalog.table(&resolved)?;
1738        let fields: Vec<Field> = table.columns().to_vec();
1739        let label =
1740            if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
1741        let index = self.fresh_index();
1742        let mut scope = Scope::empty();
1743        for (at, field) in fields.iter().enumerate() {
1744            scope.push(Visible {
1745                table: label.clone(),
1746                name: field.name.clone(),
1747                binding: ColumnBinding::new(index, at as u32),
1748                ty: field.ty.clone(),
1749                not_null: field.not_null,
1750            });
1751        }
1752        if !columns.is_empty() {
1753            let names: Vec<&str> = ast.name(columns).collect();
1754            scope.rename(&names, &label)?;
1755        }
1756        let catalog_name = self.plan.intern(&resolved.catalog);
1757        let schema = self.plan.intern(&resolved.schema);
1758        let table_name = self.plan.intern(&resolved.table);
1759        let alias = self.plan.intern(&label);
1760        let columns = self.plan.add_fields(&fields);
1761        // What the store wrote down about itself, against the table index the same way a Parquet
1762        // footer is. A table with nothing to say records nothing and the estimate falls back to the
1763        // constants it used before, which is what every table did until the file had a directory
1764        // worth asking.
1765        if let Some(zones) = table.rows().zones() {
1766            self.plan.set_zones(index, zones);
1767        }
1768        if let Some(frequencies) = table.frequencies() {
1769            self.plan.set_frequencies(index, frequencies);
1770        }
1771        for (column, distinct) in table.distincts() {
1772            self.plan.measure_distinct(index, &column, distinct);
1773        }
1774        let node = self.add_node(Node::Get {
1775            catalog: catalog_name,
1776            schema,
1777            table: table_name,
1778            alias,
1779            index,
1780            columns,
1781        });
1782        Ok((node, scope))
1783    }
1784
1785    /// A view where a table goes, which is the body bound again right here.
1786    ///
1787    /// Inline and not behind a node. The view is gone by the time the plan exists, so everything
1788    /// downstream sees the query somebody would have written by hand, and the column pruning that
1789    /// makes `SELECT COUNT(*) FROM 'hits.parquet'` read no columns at all keeps working through
1790    /// `FROM hits`. A `Node::View` would be a barrier with nothing on the other side of it.
1791    ///
1792    /// The scope this builds is a subquery's, right down to the name in the error message. duckdb
1793    /// v1.5.1 reports a view whose column list has gone stale as `table "unnamed_subquery" has 1
1794    /// columns available but 2 columns specified`, which is the sentence its subquery alias rule
1795    /// produces, so a view there is a subquery with the view's name written over it afterwards.
1796    fn bind_view(
1797        &mut self,
1798        ast: &Ast,
1799        name: &QualifiedName,
1800        alias: ast::StrRef,
1801        columns: ast::Slice,
1802    ) -> Result<(NodeRef, Scope)> {
1803        let view = self.catalog.view(name)?;
1804        let full = name.to_string();
1805        if self.expanding.contains(&full) {
1806            // Two quotes each side, which is what the binary prints. It quotes the name on the way
1807            // in and then formats the quoted name into a quoted slot, so a view called `a` comes
1808            // back as `""a""`. That is upstream's wart and copying it is the whole job here.
1809            return Err(Error::binder(format!(
1810                "infinite recursion detected: attempting to recursively bind view \"\"{}\"\"",
1811                name.table
1812            )));
1813        }
1814        let body = parse_ast_with_case(view.sql(), self.semantics.identifier_case())?;
1815        let query = match body.statements.as_slice() {
1816            [ast::Statement::Query(query)] => *query,
1817            // Only a query can have got past the binder at creation, so this is a view the catalog
1818            // was handed some other way rather than anything a statement can produce.
1819            _ => return Err(Error::binder(format!("view \"{}\" is not a query", name.table))),
1820        };
1821        self.expanding.push(full);
1822        let bound = self.bind_query(&body, query);
1823        self.expanding.pop();
1824        let (node, mut scope) = bound?;
1825
1826        let aliases: Vec<&str> = view.aliases().iter().map(String::as_str).collect();
1827        if !aliases.is_empty() {
1828            scope.rename(&aliases, "unnamed_subquery")?;
1829        }
1830        // What the catalog tables report as this view's columns, written down here because this is
1831        // the moment they are known. Upstream refreshes the same cache at the same point, which was
1832        // measured: both `duckdb_columns()` and `duckdb_views().column_count` keep reporting the old
1833        // list after an `ALTER TABLE` underneath until something reads the view, and then both move.
1834        // It is written before the label and before the `AS t(a, b)` list below, because those two
1835        // rename the view for one query and not for everyone.
1836        view.remember(scope.fields());
1837        let label = if alias == NONE { name.table.clone() } else { ast.string(alias).to_string() };
1838        scope.relabel(&label);
1839        if !columns.is_empty() {
1840            let names: Vec<&str> = ast.name(columns).collect();
1841            scope.rename(&names, &label)?;
1842        }
1843        Ok((node, scope))
1844    }
1845
1846    /// A function call where a table goes, such as `range(10)`.
1847    ///
1848    /// The arguments are bound against an empty scope. A table function that can see the row on its
1849    /// left is `LATERAL`, and this is not it, so a column name in here is not resolved against
1850    /// whatever happens to be to the left in the `FROM` list. Letting it would mean `FROM t,
1851    /// range(t.n)` quietly binding to something whose meaning depends on the order the sources were
1852    /// written in.
1853    fn bind_table_function(
1854        &mut self,
1855        ast: &Ast,
1856        name: ast::Slice,
1857        args: ast::Slice,
1858        alias: ast::StrRef,
1859        columns: ast::Slice,
1860        pragma: bool,
1861    ) -> Result<(NodeRef, Scope)> {
1862        let parts: Vec<&str> = ast.name(name).collect();
1863        // A qualified call names a schema, and the two schemas that exist are the ones every
1864        // built-in lives in. Anything else is a name that has to fail rather than fall through to
1865        // the unqualified lookup and be found somewhere it was not asked for.
1866        let function_name = *parts.last().unwrap_or(&"");
1867        if let Some(schema) = parts.iter().rev().nth(1) {
1868            if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
1869                return Err(Error::catalog(format!(
1870                    "Table Function with name {} does not exist!",
1871                    parts.join(".")
1872                )));
1873            }
1874        }
1875        // The name is looked up before the arguments are bound so that a call of something that is
1876        // not a table function says that, rather than reporting whatever is wrong with the
1877        // arguments of a function that was never going to exist.
1878        let Some(called) = TableFunction::lookup(function_name) else {
1879            if pragma {
1880                // `PRAGMA database_list` is a view upstream and not a function, and the pragma
1881                // namespace holds both, so a name that is not a function gets one more look in the
1882                // catalog before it is turned down. It has to be the no argument form: a view
1883                // takes none, and `pragma_database_list()` with parentheses is a missing function
1884                // on the pin too.
1885                if args.is_empty() && self.catalog.resolve(&parts).is_ok() {
1886                    return self.bind_table(ast, name, alias, columns);
1887                }
1888                let spelled = function_name.strip_prefix("pragma_").unwrap_or(function_name);
1889                return Err(Error::catalog(format!(
1890                    "Pragma Function with name {spelled} does not exist!"
1891                )));
1892            }
1893            return Err(Error::catalog(format!(
1894                "Table Function with name {function_name} does not exist!"
1895            )));
1896        };
1897        let written = ast.target_list(args).to_vec();
1898        let empty = Scope::empty();
1899        let previous = std::mem::replace(&mut self.clause, "table function arguments");
1900        let mut bound = Vec::new();
1901        let mut written_options = Vec::new();
1902        for argument in written {
1903            let expr = self.bind_expr(ast, argument.expr, &empty)?;
1904            if argument.alias == NONE {
1905                bound.push(expr);
1906            } else {
1907                let name = ast.string(argument.alias).to_string();
1908                let (parameter, value) = self.named_argument(called, &name, expr)?;
1909                written_options.push((parameter, value, expr));
1910            }
1911        }
1912        self.clause = previous;
1913        let options = Options::of(&written_options)?;
1914
1915        // The types are what resolve the call, not the count, because `read_parquet(3)` is a
1916        // different answer from `read_parquet('3')` and only the types tell them apart.
1917        let given: Vec<LogicalType> =
1918            bound.iter().map(|&expr| self.plan.expr_type(expr).clone()).collect();
1919        let resolved = if pragma {
1920            resolve_pragma(function_name, &given)?
1921        } else {
1922            resolve_table(function_name, &given)?
1923        };
1924        let mut cast: Vec<ExprRef> = bound
1925            .iter()
1926            .zip(&resolved.arguments)
1927            .map(|(&expr, ty)| self.checked_cast_to(expr, ty, false))
1928            .collect::<Result<_>>()?;
1929
1930        if resolved.function.answered_when_bound() {
1931            let Columns::Fixed(fields) = resolved.columns else {
1932                return Err(Error::internal("a pragma that resolved to a file"));
1933            };
1934            let [argument] = cast[..] else {
1935                return Err(Error::internal("a pragma that resolved to more than one name"));
1936            };
1937            return self.bind_pragma(ast, resolved.function, &fields, argument, alias, columns);
1938        }
1939        // Filled in by the arm below that has the file names, and left alone by a function whose
1940        // columns are fixed, because none of those reads a file to find out how tall it is.
1941        let mut measured = Stat::Unknown;
1942        let mut counted: Vec<(String, Stat<u64>)> = Vec::new();
1943        let mut bounded: Option<Arc<dyn Zones>> = None;
1944        let fields = match resolved.columns {
1945            Columns::Fixed(fields) => fields,
1946            columns => {
1947                // The one argument is a pattern, and what replaces it is one constant per file it
1948                // matched. The executor is handed names rather than a pattern, so it never walks a
1949                // directory and the answer cannot change between binding a prepared statement and
1950                // running it, which is the same reason the schema is settled here.
1951                let paths = self.file_paths(cast[0], resolved.function.name())?;
1952                let mut fields = match columns {
1953                    // Parquet takes the first file's footer as the answer and CSV sniffs all of
1954                    // them, which is not a choice made here. See `csv_fields`.
1955                    Columns::Csv => csv_fields(&paths, options.given)?,
1956                    _ => {
1957                        let footers = parquet_footers(&paths)?;
1958                        measured = footers.rows;
1959                        counted = footers.distincts;
1960                        bounded = footers.zones;
1961                        footers.fields
1962                    }
1963                };
1964                if options.all_varchar {
1965                    // The sniffer still ran, because the names come out of the same pass over the
1966                    // front of the file and only the types are being overruled. The executor reads
1967                    // the text as VARCHAR because this is the schema it is told to read into, which
1968                    // is the same road a file in a glob takes when the set is wider than the file.
1969                    for field in &mut fields {
1970                        field.ty = LogicalType::Varchar;
1971                    }
1972                }
1973                if options.binary_as_string {
1974                    // A byte array column with no annotation on it is a BLOB, and this is the caller
1975                    // saying that the file's writer meant text. The reader already holds both in the
1976                    // same string column and already validates the bytes, so the whole of the option
1977                    // is what the column is called from here on.
1978                    for field in &mut fields {
1979                        if field.ty == LogicalType::Blob {
1980                            field.ty = LogicalType::Varchar;
1981                        }
1982                    }
1983                }
1984                if options.file_row_number {
1985                    // Not a column of the file, so it goes on the end where a projection cannot be
1986                    // confused about which one it is, and the executor counts it as the rows come
1987                    // out. A file that already has a column of that name is the one case where the
1988                    // option cannot be honoured, and saying so is better than handing back two
1989                    // columns with the same name and letting a reference to it pick one.
1990                    if fields.iter().any(|field| field.name == FILE_ROW_NUMBER) {
1991                        return Err(Error::binder(format!(
1992                            "Duplicate column name \"{FILE_ROW_NUMBER}\": the file already has a \
1993                             column of that name, so file_row_number cannot add one"
1994                        )));
1995                    }
1996                    fields.push(Field::required(FILE_ROW_NUMBER.to_string(), LogicalType::BigInt));
1997                }
1998                cast = paths.iter().map(|path| self.path_constant(path)).collect();
1999                fields
2000            }
2001        };
2002        let label = if alias == NONE {
2003            resolved.function.name().to_string()
2004        } else {
2005            ast.string(alias).to_string()
2006        };
2007        let names: Vec<&str> = ast.name(columns).collect();
2008        self.table_function_source(
2009            resolved.function,
2010            &cast,
2011            &written_options,
2012            Read { fields, rows: measured, distincts: counted, zones: bounded },
2013            &label,
2014            &names,
2015        )
2016    }
2017
2018    /// `pragma_table_info('t')` or `pragma_show('t')`, answered while it is bound.
2019    ///
2020    /// The same trick `DESCRIBE` uses and for the same reason: the columns of a table are settled by
2021    /// the time the name has resolved, so the rows are a constant from there on and this comes out
2022    /// as a `VALUES` rather than as an operator that reads a catalog while the query runs. It also
2023    /// means `SELECT name FROM pragma_table_info('t') WHERE notnull` is an ordinary query over an
2024    /// ordinary relation, which is the whole reason these exist as functions rather than only as
2025    /// statements.
2026    ///
2027    /// The name arrives as a string rather than as something the parser read, so it is split here
2028    /// under the identifier rule and then resolved like any other name. A name that is not there
2029    /// comes back as the catalog's own complaint, which is what the pin answers with too.
2030    fn bind_pragma(
2031        &mut self,
2032        ast: &Ast,
2033        function: TableFunction,
2034        fields: &[Field],
2035        argument: ExprRef,
2036        alias: ast::StrRef,
2037        columns: ast::Slice,
2038    ) -> Result<(NodeRef, Scope)> {
2039        let written = self.pragma_name(argument, function)?;
2040        let parts = identifier_parts(&written);
2041        let spelled: Vec<&str> = parts.iter().map(String::as_str).collect();
2042        let name = self.catalog.resolve(&spelled)?;
2043        let described = self.described(ast, &name)?;
2044        let mut rows = Vec::with_capacity(described.len());
2045        for (at, field) in described.iter().enumerate() {
2046            let items = if matches!(function, TableFunction::PragmaShow) {
2047                self.describing(field)
2048            } else {
2049                self.table_info(at, field)
2050            };
2051            rows.push(self.plan.add_expr_list(&items));
2052        }
2053        let rows = self.plan.add_rows(&rows);
2054        let held = self.plan.add_fields(fields);
2055        let index = self.fresh_index();
2056        let node = self.add_node(Node::Values { index, columns: held, rows });
2057        let label =
2058            if alias == NONE { function.name().to_string() } else { ast.string(alias).to_string() };
2059        let mut scope = Scope::empty();
2060        for (at, field) in fields.iter().enumerate() {
2061            scope.push(Visible {
2062                table: label.clone(),
2063                name: field.name.clone(),
2064                binding: ColumnBinding::new(index, at as u32),
2065                ty: field.ty.clone(),
2066                not_null: false,
2067            });
2068        }
2069        if !columns.is_empty() {
2070            let names: Vec<&str> = ast.name(columns).collect();
2071            scope.rename(&names, &label)?;
2072        }
2073        Ok((node, scope))
2074    }
2075
2076    /// The name a pragma was called with, which has to be a constant.
2077    ///
2078    /// A null is a name spelled `NULL` rather than an error about nulls, because the pin turns
2079    /// whatever it was handed into text before it goes looking and then says a table of that name
2080    /// does not exist. Writing `pragma_table_info(NULL)` is a mistake either way and this is the
2081    /// sentence the mistake already has.
2082    ///
2083    /// `pragma_table_info('t' || 'x')` is the pin's `tx` and is turned away here, which is the same
2084    /// missing constant folding [`Binder::named_argument`] writes about and closes the same day.
2085    fn pragma_name(&self, argument: ExprRef, function: TableFunction) -> Result<String> {
2086        let Expr::Constant(reference) = *self.plan.expr(argument) else {
2087            return Err(Error::not_implemented(format!(
2088                "{}() given a name that is not a constant",
2089                function.name()
2090            )));
2091        };
2092        match self.plan.value(reference) {
2093            Value::Varchar(name) => Ok(name.clone()),
2094            Value::Null => Ok("NULL".to_string()),
2095            other => {
2096                Err(Error::internal(format!("a pragma name bound as VARCHAR arrived as {other}")))
2097            }
2098        }
2099    }
2100
2101    /// The columns of whatever a pragma was pointed at.
2102    ///
2103    /// A view is bound here, which is how it comes to have columns at all. Reading a view is what
2104    /// binds it and describing one counts as reading it, so a view the engine ships with reports a
2105    /// column count from this point on, the same as it would after a select. The node that binding
2106    /// produces is thrown away, because the answer is the scope and not the query.
2107    ///
2108    /// Every column of a view is nullable whatever the column underneath was declared as, which is
2109    /// the pin's answer through `pragma_table_info()`, `pragma_show()` and `duckdb_columns()` alike.
2110    /// [`Scope::fields`] drops the flag on its own, so there is nothing to clear here.
2111    fn described(&mut self, ast: &Ast, name: &QualifiedName) -> Result<Vec<Field>> {
2112        if self.catalog.entry(name)? == Entry::Table {
2113            return Ok(self.catalog.table(name)?.columns().to_vec());
2114        }
2115        let (_, scope) = self.bind_view(ast, name, NONE, ast::Slice::default())?;
2116        Ok(scope.fields())
2117    }
2118
2119    /// One row of `pragma_show()`, which is one row of `DESCRIBE` written by the other caller.
2120    fn describing(&mut self, field: &Field) -> Vec<ExprRef> {
2121        let written = [
2122            field.name.clone(),
2123            field.ty.to_string(),
2124            if field.not_null { "NO" } else { "YES" }.to_owned(),
2125        ];
2126        let mut items: Vec<ExprRef> =
2127            written.into_iter().map(|text| self.plan.add_constant(Value::Varchar(text))).collect();
2128        for _ in 0..3 {
2129            let empty = self.plan.add_constant(Value::Null);
2130            items.push(self.cast_to(empty, &LogicalType::Varchar));
2131        }
2132        items
2133    }
2134
2135    /// One row of `pragma_table_info()`, which is SQLite's six columns about the same column.
2136    ///
2137    /// `cid` counts from zero, which is SQLite's numbering and not the one based `ordinal_position`
2138    /// the standard views report. `dflt_value` and `pk` are the two nothings rudb has to report
2139    /// until `CREATE TABLE` takes a `DEFAULT` or a key.
2140    fn table_info(&mut self, at: usize, field: &Field) -> Vec<ExprRef> {
2141        let cid = self.plan.add_constant(Value::Integer(i32::try_from(at).unwrap_or(i32::MAX)));
2142        let name = self.plan.add_constant(Value::Varchar(field.name.clone()));
2143        let ty = self.plan.add_constant(Value::Varchar(field.ty.to_string()));
2144        let not_null = self.plan.add_constant(Value::Boolean(field.not_null));
2145        let default = self.plan.add_constant(Value::Null);
2146        let default = self.cast_to(default, &LogicalType::Varchar);
2147        let key = self.plan.add_constant(Value::Boolean(false));
2148        vec![cid, name, ty, not_null, default, key]
2149    }
2150
2151    /// One named parameter of a table function call, folded into what the call was given.
2152    ///
2153    /// The value has to be a constant of the type the parameter wants. It has to be constant
2154    /// because an option can decide what the columns are and the columns are settled here, and it
2155    /// has to be already of the type because there is no constant folding in front of the binder
2156    /// yet. DuckDB folds first, so `binary_as_string=1` and `binary_as_string='yes'` are both true
2157    /// there and both are turned away here, which is a gap that closes on its own the day the
2158    /// optimizer runs before the plan is finished. `binary_as_string=True` is what the ClickBench
2159    /// entry writes and is what has to work.
2160    ///
2161    /// A name that is not a parameter of this function is the binary's sentence followed by what it
2162    /// could have been. The binary puts the candidates on their own indented lines and this puts
2163    /// them on the same line, because an error is one line here.
2164    fn named_argument(
2165        &mut self,
2166        function: TableFunction,
2167        name: &str,
2168        expr: ExprRef,
2169    ) -> Result<(&'static str, Value)> {
2170        let known = function
2171            .parameters()
2172            .iter()
2173            .find(|(parameter, _)| parameter.eq_ignore_ascii_case(name));
2174        let Some((parameter, wanted)) = known else {
2175            let candidates: Vec<String> = function
2176                .parameters()
2177                .iter()
2178                .map(|(parameter, ty)| format!("    {parameter} {ty}"))
2179                .collect();
2180            return Err(Error::binder(format!(
2181                "Invalid named parameter \"{name}\" for function {}\nCandidates:\n{}\n",
2182                function.name(),
2183                candidates.join("\n")
2184            )));
2185        };
2186        let Expr::Constant(reference) = *self.plan.expr(expr) else {
2187            return Err(Error::not_implemented(format!(
2188                "the named parameter {parameter} with a value that is not a constant"
2189            )));
2190        };
2191        let value = self.plan.value(reference).clone();
2192        if value == Value::Null {
2193            return Err(Error::binder(null_parameter(function, parameter)));
2194        }
2195        let given = self.plan.expr_type(expr).clone();
2196        if given != *wanted {
2197            return Err(Error::not_implemented(format!(
2198                "the named parameter {parameter} given a {given} where a {wanted} was wanted"
2199            )));
2200        }
2201        Ok((parameter, value))
2202    }
2203
2204    /// A file where a table name goes, which is what DuckDB calls a replacement scan.
2205    ///
2206    /// `SELECT * FROM 'hits.parquet'` is how most DuckDB queries in the wild are written, ClickBench
2207    /// among them, so this is not sugar over `read_parquet` so much as the spelling people use. The
2208    /// catalog has already been asked and has already said no, and `missing` is what it said, so a
2209    /// name that is not a file comes back with the catalog's own answer rather than with a complaint
2210    /// about files.
2211    ///
2212    /// Only a single unqualified name is a candidate. A qualified one names a schema and a schema
2213    /// that does not exist is not a path.
2214    fn bind_replacement_scan(
2215        &mut self,
2216        ast: &Ast,
2217        parts: &[&str],
2218        alias: ast::StrRef,
2219        columns: ast::Slice,
2220        missing: Error,
2221    ) -> Result<(NodeRef, Scope)> {
2222        let [path] = parts else { return Err(missing) };
2223        let path = *path;
2224        let extension = path.rsplit_once('.').map(|(_, after)| after).unwrap_or_default();
2225        let Some(function) = Self::reader_for(extension) else {
2226            if is_file(path) {
2227                // A file that is really there and that nothing here can read is a different mistake
2228                // from a name that is not a file, and DuckDB says so with both lines, the second of
2229                // which is the way out. A file with no dot in it lands here too, which is why the
2230                // test is on the extension having a reader rather than on there being an extension.
2231                return Err(Error::binder(format!(
2232                    "No extension found that is capable of reading the file \"{path}\"\n* If this \
2233                     file is a supported file format you can explicitly use the reader functions, \
2234                     such as read_csv, read_json or read_parquet"
2235                )));
2236            }
2237            return Err(missing);
2238        };
2239        // The pattern is expanded before it is known to match anything, so a name that ends in .csv
2240        // and is not there gives the reader's own message rather than the catalog's. That is
2241        // DuckDB's order and it is the helpful one: somebody who wrote a file name wants to hear
2242        // about the file.
2243        let paths = files(path)?;
2244        let read = match function {
2245            TableFunction::ReadParquet => {
2246                let footers = parquet_footers(&paths)?;
2247                Read {
2248                    fields: footers.fields,
2249                    rows: footers.rows,
2250                    distincts: footers.distincts,
2251                    zones: footers.zones,
2252                }
2253            }
2254            _ => Read::uncounted(csv_fields(&paths, Given::default())?),
2255        };
2256        // The name the columns answer to is the file's stem, so `SELECT mixed.a FROM
2257        // 'data/mixed.parquet'` works. That is DuckDB's choice and it is the useful one, since the
2258        // alternative is a table name with a dot and a slash in it that nothing can write. A pattern
2259        // keeps the whole of what was written instead, which is DuckDB's choice too and was
2260        // measured: there is no stem to take when the name stands for a directory full of files.
2261        let label = if alias == NONE {
2262            if is_pattern(path) {
2263                path.to_string()
2264            } else {
2265                let file = path.rsplit_once('/').map_or(path, |(_, file)| file);
2266                file.rsplit_once('.').map_or(file, |(stem, _)| stem).to_string()
2267            }
2268        } else {
2269            ast.string(alias).to_string()
2270        };
2271        let arguments: Vec<ExprRef> = paths.iter().map(|path| self.path_constant(path)).collect();
2272        let names: Vec<&str> = ast.name(columns).collect();
2273        self.table_function_source(function, &arguments, &[], read, &label, &names)
2274    }
2275
2276    /// One file name, as a constant expression in the plan.
2277    fn path_constant(&mut self, path: &str) -> ExprRef {
2278        let value = self.plan.add_value(Value::Varchar(path.to_string()));
2279        self.plan.add_expr(Expr::Constant(value), LogicalType::Varchar)
2280    }
2281
2282    /// The table function a file with this extension is read by, and `None` for one nothing reads.
2283    ///
2284    /// Both spellings of a tab separated file go to the CSV reader, which is not a shortcut: the
2285    /// extension picks the reader and the reader sniffs the punctuation, so a `.tsv` file that holds
2286    /// commas is read as commas. That was measured rather than assumed. The comparison ignores case
2287    /// because `UP.CSV` reads in duckdb v1.4.1.
2288    fn reader_for(extension: &str) -> Option<TableFunction> {
2289        if extension.eq_ignore_ascii_case("parquet") {
2290            return Some(TableFunction::ReadParquet);
2291        }
2292        if extension.eq_ignore_ascii_case("csv") || extension.eq_ignore_ascii_case("tsv") {
2293            return Some(TableFunction::ReadCsv);
2294        }
2295        None
2296    }
2297
2298    /// The node and the scope of a table function call whose arguments and columns are settled.
2299    ///
2300    /// The half a written out call shares with a replacement scan, which is everything after the
2301    /// question of what the file is called has been answered one way or the other.
2302    ///
2303    /// `read` is what the caller found out about the files, which comes in here rather than being
2304    /// read here because this function has the names and not the files: a replacement scan has
2305    /// already expanded its pattern and a written out call has already cast its argument, and
2306    /// neither of them wants to do it twice.
2307    fn table_function_source(
2308        &mut self,
2309        function: TableFunction,
2310        args: &[ExprRef],
2311        written: &[(&'static str, Value, ExprRef)],
2312        read: Read,
2313        label: &str,
2314        names: &[&str],
2315    ) -> Result<(NodeRef, Scope)> {
2316        let Read { fields, rows, distincts, zones } = read;
2317        let index = self.fresh_index();
2318        // Against the table index rather than against the node, because a pass is free to move the
2319        // node and none of them can move an index: an index is what a column reference names and
2320        // rewriting one would mean rewriting every expression above it. Nothing is recorded for a
2321        // function nobody measured, since an absent entry already reads back as unknown.
2322        if rows.is_known() {
2323            self.plan.measure(index, rows);
2324        }
2325        for (column, distinct) in distincts {
2326            self.plan.measure_distinct(index, &column, distinct);
2327        }
2328        if let Some(zones) = zones {
2329            self.plan.set_zones(index, zones);
2330        }
2331        let mut scope = Scope::empty();
2332        for (at, field) in fields.iter().enumerate() {
2333            scope.push(Visible {
2334                table: label.to_string(),
2335                name: field.name.clone(),
2336                binding: ColumnBinding::new(index, at as u32),
2337                ty: field.ty.clone(),
2338                // A reader takes what the file has, and no file format this reads says a column
2339                // cannot be null. The reference binary answers YES for every column of a Parquet.
2340                not_null: false,
2341            });
2342        }
2343        if !names.is_empty() {
2344            scope.rename(names, label)?;
2345        }
2346        let function = self.plan.intern(function.name());
2347        let args = self.plan.add_expr_list(args);
2348        let named: Vec<u32> =
2349            written.iter().map(|(parameter, _, _)| self.plan.intern(parameter)).collect();
2350        let settings: Vec<ExprRef> = written.iter().map(|(_, _, expr)| *expr).collect();
2351        let options = self.plan.add_name_list(&named);
2352        let settings = self.plan.add_expr_list(&settings);
2353        let columns = self.plan.add_fields(&fields);
2354        let node = self.add_node(Node::TableFunction {
2355            index,
2356            function,
2357            args,
2358            options,
2359            settings,
2360            columns,
2361        });
2362        Ok((node, scope))
2363    }
2364
2365    /// Every file a table function's file argument names, in the order they were written.
2366    ///
2367    /// Each pattern has to find at least one file of its own, which is DuckDB's rule and is why
2368    /// this expands one at a time rather than gathering everything and looking at the total. A
2369    /// list keeps its written order and its duplicates, so a file named twice is read twice, which
2370    /// was measured: the sort and the dedup belong to one pattern rather than to the list.
2371    fn file_paths(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
2372        let mut paths = Vec::new();
2373        for pattern in self.file_patterns(expr, name)? {
2374            paths.extend(files(&pattern)?);
2375        }
2376        Ok(paths)
2377    }
2378
2379    /// The patterns a table function argument names, which have to be constants.
2380    ///
2381    /// A table function that reads a file is resolved by opening the file, and that happens here
2382    /// rather than when the query runs, because the rest of the statement cannot bind until the
2383    /// column names are known. So the path has to be something this binder can work out without
2384    /// running anything, and a literal is that. DuckDB folds a constant expression first, so
2385    /// `read_parquet('a' || '.parquet')` works there, and folding is M1 work that this will pick up
2386    /// for free once the optimizer runs before the plan is finished rather than after.
2387    ///
2388    /// One string is one pattern and a list is one pattern an item, which is DuckDB's pair of
2389    /// overloads. A null is a different sentence in each of them, both of them measured.
2390    fn file_patterns(&self, expr: ExprRef, name: &str) -> Result<Vec<String>> {
2391        let Expr::Constant(reference) = *self.plan.expr(expr) else {
2392            return Err(Error::not_implemented(
2393                "a table function file name that is not a constant",
2394            ));
2395        };
2396        match self.plan.value(reference) {
2397            Value::Varchar(path) => Ok(vec![path.clone()]),
2398            // DuckDB's own wording, which says list because its other overload takes one.
2399            Value::Null => Err(Error::parser(format!("{name} cannot take NULL list as parameter"))),
2400            Value::List { values, .. } => values
2401                .iter()
2402                .map(|value| match value {
2403                    Value::Varchar(path) => Ok(path.clone()),
2404                    _ => Err(Error::parser(format!(
2405                        "{name} reader cannot take NULL input as parameter"
2406                    ))),
2407                })
2408                .collect(),
2409            other => {
2410                Err(Error::internal(format!("a file name bound as VARCHAR arrived as {other}")))
2411            }
2412        }
2413    }
2414
2415    /// Which input of a join a query written in its `ON` has to be joined into.
2416    ///
2417    /// A join condition is evaluated by the join, over the rows its two inputs handed it, so a
2418    /// column the condition reads has to be produced by one of those two. A query written in the
2419    /// `ON` produces columns the condition reads, which means the query cannot be joined in above
2420    /// the join the way one written in a `WHERE` or a `SELECT` is. It has to go underneath, into
2421    /// one input or the other.
2422    ///
2423    /// Which input is decided by what the query reads. A query whose body reads the right side can
2424    /// only be evaluated where those rows are, so it goes into the right input, and the same for
2425    /// the left. A query that reads neither could go into either and goes into the left, which is
2426    /// also where an `IN` puts one whose left hand side reads the left and whose body reads
2427    /// nothing.
2428    ///
2429    /// The one that has no answer is a query that reads both sides. There is no single input that
2430    /// produces what it needs, and the shape upstream calls a pair dependent join is what handles
2431    /// it. `None` is that case, and the caller turns it into a refusal rather than a plan.
2432    fn side_of(
2433        &self,
2434        pending: &PendingSubquery,
2435        left_tables: &[u32],
2436        right_tables: &[u32],
2437    ) -> Option<Side> {
2438        let mut needs_left = false;
2439        let mut needs_right = false;
2440        let mut note = |binding: ColumnBinding| {
2441            needs_left |= left_tables.contains(&binding.table);
2442            needs_right |= right_tables.contains(&binding.table);
2443        };
2444        for &binding in &pending.reads {
2445            note(binding);
2446        }
2447        // A mark join carries the comparison rather than the condition carrying it, and that
2448        // comparison is written over the join's own rows. `l.a IN (SELECT ...)` reads the left side
2449        // there and nowhere else, so leaving it out would put the query on whichever side its body
2450        // happened to name and let the comparison ask a join for a column it was not given.
2451        for &condition in &pending.conditions {
2452            self.plan.read_columns(condition, &mut |_, binding| note(binding));
2453        }
2454        match (needs_left, needs_right) {
2455            (true, true) => None,
2456            (_, true) => Some(Side::Right),
2457            _ => Some(Side::Left),
2458        }
2459    }
2460
2461    /// A join whose condition holds a query that reads rows from both of its inputs.
2462    ///
2463    /// This is the one [`Binder::side_of`] has no side for. The query has to be evaluated once per
2464    /// pair of rows, and there is no input that produces a pair, so it cannot go into either input
2465    /// the way the other two cases do. What produces a pair is the join itself, so the join becomes
2466    /// a product, the query is joined into the product's rows the way a query in a `WHERE` is joined
2467    /// into the rows the whole `FROM` produced, and the condition becomes a filter above that.
2468    ///
2469    /// That rewrite is only the same query for an inner join. An inner join keeps the pairs its
2470    /// condition holds and drops the rest, which is what a product and a filter do. Every other kind
2471    /// does something with the pairs it dropped, a left join pads them, a semi join counts them, and
2472    /// a filter above a product has already thrown away which left row a dropped pair came from, so
2473    /// those are refused by name. Upstream plans them as a pair dependent join and rudb does not
2474    /// have one yet, which is what tamnd/rudb#913 stays open for.
2475    ///
2476    /// The product is not the plan that runs. The condition goes back into the join as a condition
2477    /// when filter pushdown looks at it, which is the pass that already turns a filter over an inner
2478    /// join into a join condition, so an equality in the `ON` is still an equality the hash join can
2479    /// build on. What cannot be pushed back down is the part that reads the query's output, and that
2480    /// part could not have been a join condition in the first place.
2481    #[allow(clippy::too_many_arguments)]
2482    fn bind_pair_dependent_join(
2483        &mut self,
2484        kind: ast::JoinKind,
2485        independent: bool,
2486        left: NodeRef,
2487        right: NodeRef,
2488        pair: Vec<PendingSubquery>,
2489        conditions: Vec<ExprRef>,
2490        scope: Scope,
2491    ) -> Result<(NodeRef, Scope)> {
2492        if kind != ast::JoinKind::Inner {
2493            return Err(Error::not_implemented(
2494                "a subquery that reads both sides of that join, written in the condition of a join \
2495                 that is not an inner join"
2496                    .to_string(),
2497            ));
2498        }
2499        // A lateral right side is already evaluated per left row, so the product this would build is
2500        // not the product the query means.
2501        if !independent {
2502            return Err(Error::not_implemented(
2503                "a subquery that reads both sides of that join, written in the condition of a join \
2504                 whose right side is lateral"
2505                    .to_string(),
2506            ));
2507        }
2508        let mut node = self.add_node(Node::CrossProduct { left, right });
2509        for pending in pair {
2510            node = self.attach_subquery(node, pending);
2511        }
2512        // `ON` and `USING` cannot both be written, and this is only reached from the `ON` path, so
2513        // the list is the one bound condition. The fold is here so that it stays right if that stops
2514        // being true rather than for a case that exists today.
2515        let mut conditions = conditions.into_iter();
2516        let mut predicate = conditions.next().expect("a join condition was bound");
2517        for next in conditions {
2518            let children = self.plan.add_expr_list(&[predicate, next]);
2519            let conjunction = Expr::Conjunction { op: ConjunctionOp::And, children };
2520            predicate = self.plan.add_expr(conjunction, LogicalType::Boolean);
2521        }
2522        let node = self.add_node(Node::Filter { input: node, predicate });
2523        Ok((node, scope))
2524    }
2525
2526    #[allow(clippy::too_many_arguments)]
2527    fn bind_join(
2528        &mut self,
2529        ast: &Ast,
2530        left: ast::SourceRef,
2531        right: ast::SourceRef,
2532        kind: ast::JoinKind,
2533        natural: bool,
2534        on: ast::ExprRef,
2535        using: ast::Slice,
2536    ) -> Result<(NodeRef, Scope)> {
2537        let (left_node, left_scope) = self.bind_source(ast, left)?;
2538        let (right_node, right_scope, correlated) = self.bind_lateral(ast, right, &left_scope)?;
2539        // A row of the right side exists only for the left row it was evaluated against, so a kind
2540        // that has to produce right rows with no left row has nothing to produce them from. The
2541        // pinned build says this and names only the two kinds that work.
2542        if !correlated.is_empty()
2543            && !matches!(kind, ast::JoinKind::Inner | ast::JoinKind::Cross | ast::JoinKind::Left)
2544        {
2545            return Err(Error::binder(
2546                "The combining JOIN type must be INNER or LEFT for a LATERAL reference",
2547            ));
2548        }
2549        let split = left_scope.len();
2550        // Which table index came from which side, kept before the two scopes become one. A query
2551        // written in the `ON` is joined into one of the inputs rather than above the join, and this
2552        // is what says which. A `USING` drops the right side's copy of a joined-on column out of
2553        // the scope below, and dropping a column does not change the index it came from, so the
2554        // answer this gives is still right afterwards.
2555        let left_tables: Vec<u32> =
2556            left_scope.columns.iter().map(|column| column.binding.table).collect();
2557        let right_tables: Vec<u32> =
2558            right_scope.columns.iter().map(|column| column.binding.table).collect();
2559        let mut scope = left_scope.concat(right_scope);
2560
2561        // NATURAL is USING over whatever both sides happen to call the same thing, which is why it
2562        // is resolved here and never reaches the plan as its own idea.
2563        let merged: Vec<String> = if natural {
2564            let mut names = Vec::new();
2565            for (at, column) in scope.columns.iter().enumerate().take(split) {
2566                if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
2567                    && !names.iter().any(|held: &String| same_name(held, &column.name))
2568                {
2569                    let _ = at;
2570                    names.push(column.name.clone());
2571                }
2572            }
2573            names
2574        } else {
2575            // A name written twice is one column, not two. `USING (id, id)` is legal and means what
2576            // `USING (id)` means, and the reference binary agrees. Taking it twice would build the
2577            // same equality twice and, worse, drop the right side's copy twice, which takes a
2578            // column out of the answer that nobody named and runs off the end of the scope when the
2579            // copy was the last column in it.
2580            let mut names: Vec<String> = Vec::new();
2581            for name in ast.name(using) {
2582                if !names.iter().any(|held| same_name(held, name)) {
2583                    names.push(name.to_string());
2584                }
2585            }
2586            names
2587        };
2588
2589        let mut conditions = Vec::new();
2590        let mut dropped = Vec::new();
2591        for name in &merged {
2592            let left_at = scope.columns[..split]
2593                .iter()
2594                .position(|column| same_name(&column.name, name))
2595                .ok_or_else(|| {
2596                    Error::binder(format!(
2597                        "column \"{name}\" specified in USING clause does not exist in left table"
2598                    ))
2599                })?;
2600            let right_at = scope.columns[split..]
2601                .iter()
2602                .position(|column| same_name(&column.name, name))
2603                .map(|at| at + split)
2604                .ok_or_else(|| {
2605                    Error::binder(format!(
2606                        "column \"{name}\" specified in USING clause does not exist in right table"
2607                    ))
2608                })?;
2609            let left_column = &scope.columns[left_at];
2610            let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
2611            let right_column = &scope.columns[right_at];
2612            let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
2613            let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
2614            let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
2615            conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
2616            dropped.push(right_at);
2617        }
2618        // A joined-on column appears once, so the right side's copy goes. Dropping from the back
2619        // keeps the positions of the ones still to drop correct.
2620        dropped.sort_unstable();
2621        for at in dropped.into_iter().rev() {
2622            scope.remove(at);
2623        }
2624
2625        let mut left_node = left_node;
2626        let mut right_node = right_node;
2627        let mut pair = Vec::new();
2628        if on != NONE {
2629            if !merged.is_empty() {
2630                return Err(Error::binder("a join cannot have both ON and USING"));
2631            }
2632            self.clause = "JOIN condition";
2633            let waiting = self.scalar_subqueries.len();
2634            let predicate = self.bind_expr(ast, on, &scope)?;
2635            conditions.push(self.as_boolean(predicate, "JOIN")?);
2636            for pending in self.scalar_subqueries.split_off(waiting) {
2637                match self.side_of(&pending, &left_tables, &right_tables) {
2638                    Some(Side::Right) => right_node = self.attach_subquery(right_node, pending),
2639                    Some(Side::Left) => left_node = self.attach_subquery(left_node, pending),
2640                    None => pair.push(pending),
2641                }
2642            }
2643        }
2644
2645        if kind == ast::JoinKind::Cross && !conditions.is_empty() {
2646            return Err(Error::binder("a CROSS JOIN cannot have a condition"));
2647        }
2648        if !pair.is_empty() {
2649            return self.bind_pair_dependent_join(
2650                kind,
2651                correlated.is_empty(),
2652                left_node,
2653                right_node,
2654                pair,
2655                conditions,
2656                scope,
2657            );
2658        }
2659        // A product is the join with nothing to join on, and it is not one when the right side has
2660        // to be evaluated per left row, because then there is a dependency to lower even though
2661        // there is no condition to test.
2662        if correlated.is_empty()
2663            && conditions.is_empty()
2664            && matches!(kind, ast::JoinKind::Cross | ast::JoinKind::Inner)
2665        {
2666            let node = self.add_node(Node::CrossProduct { left: left_node, right: right_node });
2667            return Ok((node, scope));
2668        }
2669        // A semi join and an anti join ask a question about the right side rather than producing
2670        // any of it, so what is in scope after one is the left side alone. The condition is bound
2671        // above and is the last thing that can name the right side. Without this, `SELECT *` over
2672        // one expanded to both sides and the projection asked a join whose output is the left side
2673        // for columns it does not have, which came out as an internal error about a column not
2674        // being in the schema. That is tamnd/rudb#847. The reference binary refuses `b.w` here with
2675        // a binder error naming `a` as the only candidate table, which is the same rule said from
2676        // the other end.
2677        if matches!(kind, ast::JoinKind::Semi | ast::JoinKind::Anti) {
2678            scope.truncate(split);
2679        }
2680        let kind = match kind {
2681            ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
2682            ast::JoinKind::Left => JoinKind::Left,
2683            ast::JoinKind::Right => JoinKind::Right,
2684            ast::JoinKind::Full => JoinKind::Full,
2685            ast::JoinKind::Semi => JoinKind::Semi,
2686            ast::JoinKind::Anti => JoinKind::Anti,
2687            ast::JoinKind::Positional => JoinKind::Positional,
2688        };
2689        let conditions = self.plan.add_expr_list(&conditions);
2690        let node = if correlated.is_empty() {
2691            self.add_node(Node::Join {
2692                left: left_node,
2693                right: right_node,
2694                kind,
2695                conditions,
2696                build: BuildSide::default(),
2697            })
2698        } else {
2699            self.add_node(Node::DependentJoin {
2700                left: left_node,
2701                right: right_node,
2702                kind,
2703                conditions,
2704            })
2705        };
2706        Ok((node, scope))
2707    }
2708
2709    // -------------------------------------------------------------- aggregates
2710
2711    /// Binds a `FILTER (WHERE ...)` predicate, or says there was none.
2712    ///
2713    /// The predicate is a condition over the input rows and not over the answer, so it is bound in
2714    /// the scope the arguments are bound in, and it is cast to `BOOLEAN` the way a `WHERE` is:
2715    /// `FILTER (WHERE i)` over an integer column is a filter on whether the integer is not zero.
2716    fn bind_filter(
2717        &mut self,
2718        ast: &Ast,
2719        filter: ast::ExprRef,
2720        scope: &Scope,
2721    ) -> Result<Option<ExprRef>> {
2722        if filter == NONE {
2723            return Ok(None);
2724        }
2725        let bound = self.bind_expr(ast, filter, scope)?;
2726        Ok(Some(self.checked_cast_to(bound, &LogicalType::Boolean, false)?))
2727    }
2728
2729    /// Binds an aggregate call, records it, and hands back a reference to where its result lands.
2730    pub(crate) fn bind_aggregate(
2731        &mut self,
2732        ast: &Ast,
2733        name: &str,
2734        args: &[ast::ExprRef],
2735        distinct: bool,
2736        filter: ast::ExprRef,
2737        scope: &Scope,
2738    ) -> Result<ExprRef> {
2739        if self.in_filter {
2740            return Err(Error::binder("aggregate functions are not allowed in FILTER"));
2741        }
2742        if self.in_aggregate {
2743            return Err(Error::binder(format!(
2744                "aggregate function calls cannot be nested, and {name}() is inside one"
2745            )));
2746        }
2747        if self.aggregation.is_none() {
2748            return Err(Error::binder(format!(
2749                "aggregate function calls cannot be used in the {}",
2750                self.clause
2751            )));
2752        }
2753        // The predicate goes first, which is the order the messages come out in upstream: a call
2754        // whose argument and whose filter both name columns that are not there is refused over the
2755        // filter. It is bound as if it were inside the call, so an aggregate in it is caught, and a
2756        // window in it is refused with the words a window inside an aggregate is refused with.
2757        self.in_aggregate = true;
2758        self.in_filter = true;
2759        let filter = self.bind_filter(ast, filter, scope);
2760        self.in_filter = false;
2761        self.in_aggregate = false;
2762        let filter = filter?;
2763
2764        self.in_aggregate = true;
2765        let mut bound = Vec::with_capacity(args.len());
2766        let mut failure = None;
2767        for &arg in args {
2768            match self.bind_expr(ast, arg, scope) {
2769                Ok(expr) => bound.push(expr),
2770                Err(error) => {
2771                    failure = Some(error);
2772                    break;
2773                }
2774            }
2775        }
2776        self.in_aggregate = false;
2777        if let Some(error) = failure {
2778            return Err(error);
2779        }
2780
2781        let types: Vec<LogicalType> =
2782            bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
2783        let resolved = resolve(name, &types)?;
2784        let mut cast = Vec::with_capacity(bound.len());
2785        for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
2786            cast.push(self.checked_cast_to(*arg, wanted, false)?);
2787        }
2788        let args = self.plan.add_expr_list(&cast);
2789        let name = self.plan.intern(resolved.name);
2790        let ty = resolved.returns;
2791        let call = self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter }, ty.clone());
2792
2793        // Two identical aggregates are one column of the aggregate's output. `SELECT sum(x),
2794        // sum(x) / count(*)` computes one sum, not two.
2795        let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
2796        let existing = existing.unwrap_or_default();
2797        let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
2798            Some(at) => at,
2799            None => {
2800                let aggregation = self.aggregation.as_mut().expect("checked above");
2801                aggregation.aggregates.push(call);
2802                aggregation.aggregates.len() - 1
2803            }
2804        };
2805        let aggregation = self.aggregation.as_ref().expect("checked above");
2806        let (index, groups) = (aggregation.index, aggregation.groups.len());
2807        Ok(self.column(index, groups + at, ty))
2808    }
2809
2810    // ----------------------------------------------------------------- windows
2811
2812    /// Binds a window call, files it under the run it belongs to, and hands back its column.
2813    ///
2814    /// The result is a column of a [`Node::Window`] rather than the call itself, for the reason the
2815    /// aggregate path returns a column too: the operator produces the value and everything above it
2816    /// reads the value, so a target that wraps a window in arithmetic is arithmetic over a column.
2817    pub(crate) fn bind_window(
2818        &mut self,
2819        ast: &Ast,
2820        written: &WindowCall<'_>,
2821        scope: &Scope,
2822    ) -> Result<ExprRef> {
2823        let WindowCall { name, args, distinct, filter, ignore_nulls, spec, .. } = *written;
2824        if self.in_aggregate {
2825            return Err(Error::binder(
2826                "aggregate function calls cannot contain window function calls",
2827            ));
2828        }
2829        if self.in_window {
2830            return Err(Error::binder("window function calls cannot be nested"));
2831        }
2832        // A join condition is part of the `WHERE` clause as far as this one sentence is concerned,
2833        // which is upstream's wording and not a simplification: `ON sum(a.i) OVER () = b.i` is
2834        // refused there with the words a window in a `WHERE` is refused with.
2835        let clause = if self.clause == "JOIN condition" { "WHERE clause" } else { self.clause };
2836        if clause != "SELECT clause" && clause != "ORDER BY clause" {
2837            return Err(Error::binder(format!("{clause} cannot contain window functions!")));
2838        }
2839
2840        // `count(*)` is a different function from `count(x)` here for the reason it is a different
2841        // function in an ordinary call: one counts rows and the other counts the rows where its
2842        // argument is not null. A star is not an expression and nothing below this binds one.
2843        let starred = args.iter().any(|&arg| {
2844            matches!(ast.expr(arg), ast::Expr::Star { qualifier, replacements }
2845                if qualifier.is_empty() && replacements.is_empty())
2846        });
2847        let (name, args): (&str, &[ast::ExprRef]) = if starred {
2848            if !same_name(name, "count") || args.len() != 1 {
2849                return Err(Error::binder(format!("* is not allowed in {name}()")));
2850            }
2851            ("count_star", &[])
2852        } else if same_name(name, "count") && args.is_empty() {
2853            // `count()` with nothing in it is upstream's other spelling of `count(*)`. It counts
2854            // rows the same way and it is not an arity mistake.
2855            ("count_star", &[])
2856        } else {
2857            (name, args)
2858        };
2859
2860        let held = ast.window(spec);
2861        self.in_window = true;
2862        let parts = self.window_parts(ast, written, args, held, scope);
2863        // The predicate goes last here, which is the other way round from an ordinary aggregate and
2864        // is again the order the messages come out in upstream. It is still inside the window, so a
2865        // window in it is a nested window, while an aggregate in it is an ordinary aggregate over
2866        // the same rows and is answered.
2867        let filter = if parts.is_ok() { self.bind_filter(ast, filter, scope) } else { Ok(None) };
2868        self.in_window = false;
2869        let parts = parts?;
2870        let filter = filter?;
2871        // Upstream's rule, in its words. A `RANGE` offset is a distance from the current row's sort
2872        // key, so there has to be exactly one sort key for it to be a distance from.
2873        let offsets = [parts.frame.start, parts.frame.end]
2874            .iter()
2875            .any(|end| matches!(end, WindowBound::Preceding(_) | WindowBound::Following(_)));
2876        if parts.frame.unit == WindowUnit::Range && offsets && parts.order.len() != 1 {
2877            return Err(Error::binder("RANGE frames must have only one ORDER BY expression"));
2878        }
2879
2880        let types: Vec<LogicalType> =
2881            parts.args.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
2882        let resolved = window_signature(name, &types)?;
2883        // `fill` reads the sort key rather than the frame, so what it needs from the query is not
2884        // what any other window needs and it is refused on its own terms.
2885        if resolved.name == "fill" {
2886            let keys: Vec<LogicalType> =
2887                parts.order.iter().map(|key| self.plan.expr_type(key.expr).clone()).collect();
2888            refuse_fill(&types[0], &keys, distinct, ignore_nulls)?;
2889        }
2890        // Upstream's sentence, doubled quotes and all. A DISTINCT over an aggregate inside an OVER
2891        // is ordinary and answered, and a DISTINCT over a ranking window is refused there, because
2892        // there is nothing for it to collapse when the call reads no values in the first place.
2893        if distinct && kind_of(resolved.name) == Some(FunctionKind::Window) {
2894            return Err(Error::binder(format!(
2895                "DISTINCT is not implemented for the window function \"\"{name}\"\""
2896            )));
2897        }
2898        // The same sentence for the same reason. A ranking window reads no values, so there is
2899        // nothing for a predicate over the values to keep or drop.
2900        if filter.is_some() && kind_of(resolved.name) == Some(FunctionKind::Window) {
2901            return Err(Error::binder(format!(
2902                "FILTER is not implemented for the window function \"\"{name}\"\""
2903            )));
2904        }
2905        // An `ORDER BY` inside the brackets puts the rows of the frame in a different order for
2906        // this one call to read them in, which is a question every aggregate and the three that
2907        // count through the frame have an answer to. The rest of the window functions read
2908        // something other than the frame, and what the reference binary does with them under an
2909        // order of their own is a different reading again, so they are turned down rather than
2910        // guessed at. The exclusion is refused first and in the reference binary's own sentence,
2911        // because that is the one it reaches for when both apply. Per #1204.
2912        if !parts.inner.is_empty() && kind_of(resolved.name) == Some(FunctionKind::Window) {
2913            let counts = matches!(resolved.name, "first_value" | "last_value" | "nth_value");
2914            if !counts {
2915                if parts.frame.exclude != WindowExclude::NoOthers {
2916                    return Err(Error::binder(format!(
2917                        "EXCLUDE is not supported for the window function \"\"{}\"\"",
2918                        resolved.name
2919                    )));
2920                }
2921                return Err(Error::not_implemented(format!(
2922                    "ORDER BY inside the arguments of the window function \"{}\"",
2923                    resolved.name
2924                )));
2925            }
2926        }
2927        let mut cast = Vec::with_capacity(parts.args.len());
2928        for (arg, wanted) in parts.args.iter().zip(&resolved.arguments) {
2929            cast.push(self.checked_cast_to(*arg, wanted, false)?);
2930        }
2931        let args = self.plan.add_expr_list(&cast);
2932        let order = self.plan.add_sort_keys(&parts.inner);
2933        let name = self.plan.intern(resolved.name);
2934        let ty = resolved.returns;
2935        let call = self.plan.add_expr(
2936            Expr::Window { name, args, distinct, filter, ignore_nulls, order },
2937            ty.clone(),
2938        );
2939
2940        let at = self.window_run(parts.partition, parts.order, parts.frame, call);
2941        let index = self.windows.last().expect("the run was just filed").index;
2942        Ok(self.column(index, at, ty))
2943    }
2944
2945    /// Files a call under the run that matches it, or opens a new run, and says which column it is.
2946    ///
2947    /// The run that matches is only ever the last one, because a query that goes back to an earlier
2948    /// partitioning after using a different one in between wants the operators in the order it wrote
2949    /// them. Merging the two would be a rewrite, and a rewrite over a window is the optimizer's to
2950    /// make once it knows what the sort below each one costs.
2951    fn window_run(
2952        &mut self,
2953        partition: Vec<ExprRef>,
2954        order: Vec<SortKey>,
2955        frame: WindowFrame,
2956        call: ExprRef,
2957    ) -> usize {
2958        let matches = self.windows.last().is_some_and(|run| {
2959            run.frame == frame
2960                && run.partition.len() == partition.len()
2961                && run.order.len() == order.len()
2962                && run.partition.iter().zip(&partition).all(|(&l, &r)| self.same_expr(l, r))
2963                && run.order.iter().zip(&order).all(|(l, r)| {
2964                    l.descending == r.descending
2965                        && l.nulls_first == r.nulls_first
2966                        && self.same_expr(l.expr, r.expr)
2967                })
2968        });
2969        if !matches {
2970            let index = self.fresh_index();
2971            self.windows.push(WindowRun { index, partition, order, frame, calls: Vec::new() });
2972        }
2973        // Two identical calls over one run are one column, the same way two identical aggregates
2974        // over one grouping are. `SELECT sum(i) OVER (), sum(i) OVER () + 1` totals once.
2975        let calls = self.windows.last().expect("a run is open").calls.clone();
2976        if let Some(at) = calls.iter().position(|&held| self.same_expr(held, call)) {
2977            return at;
2978        }
2979        let run = self.windows.last_mut().expect("a run is open");
2980        run.calls.push(call);
2981        run.calls.len() - 1
2982    }
2983
2984    /// Binds the arguments and everything inside the `OVER`, with the aggregate rule applied.
2985    ///
2986    /// The aggregate rule applies to all of it, which is measured rather than assumed: over a
2987    /// grouped block `sum(count(i)) OVER ()` binds and `sum(i) OVER ()` is the ungrouped column
2988    /// complaint, and the same pair of answers comes back for a partition key and for an order key.
2989    fn window_parts(
2990        &mut self,
2991        ast: &Ast,
2992        written: &WindowCall<'_>,
2993        args: &[ast::ExprRef],
2994        held: ast::WindowSpec,
2995        scope: &Scope,
2996    ) -> Result<WindowParts> {
2997        let mut bound = Vec::with_capacity(args.len());
2998        for &arg in args {
2999            let expr = self.bind_expr(ast, arg, scope)?;
3000            bound.push(self.over_aggregate(expr, scope)?);
3001        }
3002        // The keys inside the brackets are bound against the same rows the arguments are, because
3003        // that is what they sort: the call reads its frame in this order, and the frame is made of
3004        // the operator's input rows.
3005        let mut inner = Vec::new();
3006        for item in ast.order_list(written.order).to_vec() {
3007            let expr = self.bind_expr(ast, item.expr, scope)?;
3008            let expr = self.over_aggregate(expr, scope)?;
3009            inner.push(self.sort_key(expr, item));
3010        }
3011        let mut partition = Vec::new();
3012        for &key in ast.expr_list(held.partition) {
3013            let expr = self.bind_expr(ast, key, scope)?;
3014            partition.push(self.over_aggregate(expr, scope)?);
3015        }
3016        let mut order = Vec::new();
3017        for item in ast.order_list(held.order).to_vec() {
3018            let expr = self.bind_expr(ast, item.expr, scope)?;
3019            let expr = self.over_aggregate(expr, scope)?;
3020            order.push(self.sort_key(expr, item));
3021        }
3022        let frame = WindowFrame {
3023            unit: match held.unit {
3024                ast::WindowUnit::Rows => WindowUnit::Rows,
3025                ast::WindowUnit::Range => WindowUnit::Range,
3026                ast::WindowUnit::Groups => WindowUnit::Groups,
3027            },
3028            start: self.window_bound(ast, held.start, scope)?,
3029            end: self.window_bound(ast, held.end, scope)?,
3030            exclude: match held.exclude {
3031                ast::WindowExclude::NoOthers => WindowExclude::NoOthers,
3032                ast::WindowExclude::CurrentRow => WindowExclude::CurrentRow,
3033                ast::WindowExclude::Group => WindowExclude::Group,
3034                ast::WindowExclude::Ties => WindowExclude::Ties,
3035            },
3036        };
3037        Ok(WindowParts { args: bound, partition, order, inner, frame })
3038    }
3039
3040    /// One end of a frame, with its offset bound where it has one.
3041    fn window_bound(
3042        &mut self,
3043        ast: &Ast,
3044        bound: ast::WindowBound,
3045        scope: &Scope,
3046    ) -> Result<WindowBound> {
3047        let offset = |binder: &mut Self, written| {
3048            let expr = binder.bind_expr(ast, written, scope)?;
3049            binder.over_aggregate(expr, scope)
3050        };
3051        Ok(match bound {
3052            ast::WindowBound::UnboundedPreceding => WindowBound::UnboundedPreceding,
3053            ast::WindowBound::CurrentRow => WindowBound::CurrentRow,
3054            ast::WindowBound::UnboundedFollowing => WindowBound::UnboundedFollowing,
3055            ast::WindowBound::Preceding(written) => WindowBound::Preceding(offset(self, written)?),
3056            ast::WindowBound::Following(written) => WindowBound::Following(offset(self, written)?),
3057        })
3058    }
3059
3060    /// Whether a column is the result of a query this block wrote and has not joined in yet.
3061    fn is_pending_subquery(&self, binding: ColumnBinding) -> bool {
3062        self.scalar_subqueries.iter().any(|pending| pending.index == binding.table)
3063    }
3064
3065    /// Whether a column is the result of a window this block is building.
3066    fn is_window_output(&self, binding: ColumnBinding) -> bool {
3067        self.windows.iter().any(|run| run.index == binding.table)
3068    }
3069
3070    /// Whether a column was resolved in an enclosing query rather than in this one.
3071    ///
3072    /// Every such read is written into the frame of the query being bound as it is resolved, and
3073    /// the frame is only handed up once that query's body is done, so while a select list or a
3074    /// `HAVING` is being bound the frame still holds everything this query read from outside it.
3075    fn is_correlation(&self, binding: ColumnBinding) -> bool {
3076        self.correlations.last().is_some_and(|frame| frame.contains(&binding))
3077    }
3078
3079    /// The name a column is written under, for an error message to say which one it means.
3080    ///
3081    /// A column of an enclosing query is not in this query's scope, so the outer scopes are searched
3082    /// as well. Without that the message names no column at all, which is how `column a column must
3083    /// appear in the GROUP BY clause` came to be a sentence this engine printed.
3084    fn name_of(&self, binding: ColumnBinding, scope: &Scope) -> String {
3085        std::iter::once(scope)
3086            .chain(self.outer_scopes.iter().rev())
3087            .flat_map(|visible| visible.columns.iter())
3088            .find(|column| column.binding == binding)
3089            .map_or_else(|| "a column".to_string(), |column| format!("\"{}\"", column.name))
3090    }
3091
3092    /// Rewrites a bound expression into one the aggregate's output can answer.
3093    ///
3094    /// A subexpression that is one of the group expressions becomes a reference to that group. A
3095    /// column that is neither grouped nor inside an aggregate is the error every SQL user has seen,
3096    /// and it is reported here because this is the first point where it is knowable.
3097    pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
3098        let Some(aggregation) = self.aggregation.as_ref() else {
3099            return Ok(expr);
3100        };
3101        let index = aggregation.index;
3102        let groups = aggregation.groups.clone();
3103        for (at, group) in groups.iter().enumerate() {
3104            if self.same_expr(expr, *group) {
3105                let ty = self.plan.expr_type(*group).clone();
3106                return Ok(self.column(index, at, ty));
3107            }
3108        }
3109        let ty = self.plan.expr_type(expr).clone();
3110        match self.plan.expr(expr).clone() {
3111            Expr::Column(binding) if binding.table == index => Ok(expr),
3112            // A window result is not a column of the input and the grouping rule has nothing to say
3113            // about it. It reads the aggregate's output rather than the table's, which is why
3114            // `SELECT sum(count(i)) OVER () FROM t GROUP BY j` binds and `sum(i) OVER ()` over the
3115            // same block does not.
3116            Expr::Column(binding) if self.is_window_output(binding) => Ok(expr),
3117            // The same argument for a query joined in above the grouping. `HAVING sum(x) > (SELECT
3118            // ...)` reads one row out of a query that has nothing to do with the groups, and the
3119            // join that produces it sits on top of the `Aggregate`, so what it produces is not one
3120            // of the grouped table's columns either.
3121            Expr::Column(binding) if self.joined_above.contains(&binding.table) => Ok(expr),
3122            // A column of an enclosing query is one value for the whole of this one, because this
3123            // query is evaluated once per outer row. It is a constant here in the sense the grouping
3124            // rule cares about, so it is allowed wherever a grouped column is and needs no group of
3125            // its own. The grouping rule is about columns of this query's own `FROM`, and a name
3126            // that resolved past it is not one of those. That is #995.
3127            Expr::Column(binding) if self.is_correlation(binding) => Ok(expr),
3128            // A query this block wrote that is still waiting to be joined in underneath the
3129            // grouping, which is a correlated one, since an uncorrelated one was lifted over the
3130            // grouping by [`Self::lift_over_aggregate`] and is not here. It has to stay underneath,
3131            // because what it correlates to is a column of the rows going into the aggregate, and
3132            // underneath is where the aggregate cannot carry its column upward. That is a thing
3133            // this engine cannot plan rather than a GROUP BY the query is missing, and it is worth
3134            // saying so, because the column belongs to no table anybody wrote and the sentence
3135            // below could not name it. That is #1032.
3136            Expr::Column(binding) if self.is_pending_subquery(binding) => Err(Error::binder(
3137                "a correlated subquery over a grouped query is not supported here yet",
3138            )),
3139            Expr::Column(binding) => {
3140                let name = self.name_of(binding, scope);
3141                Err(Error::binder(format!(
3142                    "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
3143                )))
3144            }
3145            Expr::Constant(_) | Expr::Aggregate { .. } | Expr::Window { .. } => Ok(expr),
3146            Expr::Cast { input, try_cast } => {
3147                let input = self.over_aggregate(input, scope)?;
3148                Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
3149            }
3150            Expr::Compare { op, left, right } => {
3151                let left = self.over_aggregate(left, scope)?;
3152                let right = self.over_aggregate(right, scope)?;
3153                Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
3154            }
3155            Expr::Conjunction { op, children } => {
3156                let written = self.plan.expr_list(children).to_vec();
3157                let mut rewritten = Vec::with_capacity(written.len());
3158                for child in written {
3159                    rewritten.push(self.over_aggregate(child, scope)?);
3160                }
3161                let children = self.plan.add_expr_list(&rewritten);
3162                Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
3163            }
3164            Expr::Function { name, args } => {
3165                let written = self.plan.expr_list(args).to_vec();
3166                let mut rewritten = Vec::with_capacity(written.len());
3167                for arg in written {
3168                    rewritten.push(self.over_aggregate(arg, scope)?);
3169                }
3170                let args = self.plan.add_expr_list(&rewritten);
3171                Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
3172            }
3173            Expr::Case { arms, otherwise } => {
3174                let written = self.plan.arm_list(arms).to_vec();
3175                let mut rewritten = Vec::with_capacity(written.len());
3176                for arm in written {
3177                    let when = self.over_aggregate(arm.when, scope)?;
3178                    let then = self.over_aggregate(arm.then, scope)?;
3179                    rewritten.push(rudb_plan::Arm { when, then });
3180                }
3181                let otherwise = match otherwise {
3182                    Some(expr) => Some(self.over_aggregate(expr, scope)?),
3183                    None => None,
3184                };
3185                let arms = self.plan.add_arms(&rewritten);
3186                Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
3187            }
3188        }
3189    }
3190
3191    /// Whether two bound expressions are the same expression, by shape rather than by reference.
3192    pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
3193        same_expr(&self.plan, left, right)
3194    }
3195}
3196
3197/// The named parameters a table function call was written with.
3198///
3199/// A struct rather than the fields loose, because the seventeen DuckDB has on `read_parquet` and the
3200/// thirty on `read_csv` are all going to want somewhere to go, and because a call with none of them
3201/// written should read as the default of this rather than as a bare false somewhere.
3202///
3203/// The CSV half goes on to the reader and is opened with, here and again in the executor. The
3204/// Parquet half is answered here and nothing downstream sees it, which is what `binary_as_string`
3205/// turning a BLOB column into a VARCHAR one is.
3206#[derive(Debug, Default)]
3207struct Options {
3208    /// `binary_as_string`, which says an unannotated byte array column in a Parquet file holds
3209    /// text. The ClickBench file has twenty eight of those and every query reads them as strings.
3210    binary_as_string: bool,
3211    /// `all_varchar`, which reads every column of a CSV file as text rather than sniffing a type.
3212    all_varchar: bool,
3213    /// `file_row_number`, which adds a column holding each row's ordinal inside its own file.
3214    ///
3215    /// The one Parquet option here that the executor has to act on rather than the binder, since
3216    /// the column is not in the file and has to be counted as the rows come out of it.
3217    file_row_number: bool,
3218    /// `delim`, `sep`, `quote`, `escape` and `header`, which are what the sniffer would decide.
3219    given: Given,
3220}
3221
3222impl Options {
3223    /// What these named parameters add up to.
3224    ///
3225    /// Each one was already checked against the function's list, so a name in here is a name that
3226    /// function takes and the value is already the type it wants. What is left is reading them, and
3227    /// the last one written wins, which is DuckDB's answer to `delim='|', delim=','` and was
3228    /// measured rather than assumed.
3229    fn of(written: &[(&'static str, Value, ExprRef)]) -> Result<Self> {
3230        let mut options = Self::default();
3231        for (parameter, value, _) in written {
3232            match (*parameter, value) {
3233                ("binary_as_string", Value::Boolean(on)) => options.binary_as_string = *on,
3234                ("all_varchar", Value::Boolean(on)) => options.all_varchar = *on,
3235                ("file_row_number", Value::Boolean(on)) => options.file_row_number = *on,
3236                _ => {}
3237            }
3238        }
3239        let named: Vec<(&str, Value)> =
3240            written.iter().map(|(parameter, value, _)| (*parameter, value.clone())).collect();
3241        options.given = csv_given(&named)?;
3242        Ok(options)
3243    }
3244}
3245
3246/// What was written between the two sides of a set operation.
3247#[derive(Clone, Copy)]
3248struct Operator {
3249    /// `UNION`, `EXCEPT` or `INTERSECT`.
3250    op: SetOp,
3251    /// `ALL`, `DISTINCT`, or neither, which means `DISTINCT` everywhere it is allowed.
3252    quantifier: Quantifier,
3253    /// Whether `BY NAME` was written, which only `UNION` takes.
3254    by_name: bool,
3255}
3256
3257/// One column of the result of a set operation, and where each side keeps it.
3258struct Merged {
3259    /// The name it comes out under, which is the left side's when both sides wrote it.
3260    name: String,
3261    /// What it is, after the two sides' types have met.
3262    ty: LogicalType,
3263    /// Which column of the left side it is, absent when only the right side wrote it.
3264    left: Option<usize>,
3265    /// Which column of the right side it is, absent when only the left side wrote it.
3266    right: Option<usize>,
3267}
3268
3269/// Matches the two sides of an ordinary set operation, which is first column to first column.
3270///
3271/// The names are the left side's, so `SELECT a FROM t UNION SELECT b FROM u` comes out as `a`.
3272fn match_by_position(left: &Scope, right: &Scope) -> Result<Vec<Merged>> {
3273    if left.len() != right.len() {
3274        return Err(Error::binder(format!(
3275            "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
3276            left.len(),
3277            right.len()
3278        )));
3279    }
3280    let mut merged = Vec::with_capacity(left.len());
3281    for (at, (held, other)) in left.columns.iter().zip(&right.columns).enumerate() {
3282        merged.push(Merged {
3283            name: held.name.clone(),
3284            ty: meet(&held.ty, &other.ty)?,
3285            left: Some(at),
3286            right: Some(at),
3287        });
3288    }
3289    Ok(merged)
3290}
3291
3292/// Matches the two sides of a `UNION BY NAME`, which is by column name and not by position.
3293///
3294/// The result has the left side's columns in the order the left side wrote them, then the right
3295/// side's columns the left side did not write, in the order the right side wrote them. A column
3296/// only one side wrote is that side's type and the other side fills it with a null, which is why
3297/// nothing here needs the two sides to be the same width. Names match without regard to case, and
3298/// the spelling that comes out is the left side's, both of which follow the rest of the engine.
3299fn match_by_name(left: &Scope, right: &Scope) -> Result<Vec<Merged>> {
3300    named_once(left)?;
3301    named_once(right)?;
3302    let mut merged = Vec::with_capacity(left.len() + right.len());
3303    for (at, held) in left.columns.iter().enumerate() {
3304        let other = right.columns.iter().position(|column| same_name(&column.name, &held.name));
3305        let ty = match other {
3306            Some(other) => meet(&held.ty, &right.columns[other].ty)?,
3307            None => held.ty.clone(),
3308        };
3309        merged.push(Merged { name: held.name.clone(), ty, left: Some(at), right: other });
3310    }
3311    for (at, held) in right.columns.iter().enumerate() {
3312        if left.columns.iter().any(|column| same_name(&column.name, &held.name)) {
3313            continue;
3314        }
3315        merged.push(Merged {
3316            name: held.name.clone(),
3317            ty: held.ty.clone(),
3318            left: None,
3319            right: Some(at),
3320        });
3321    }
3322    Ok(merged)
3323}
3324
3325/// Refuses a side of a `UNION BY NAME` that wrote one name twice.
3326///
3327/// Matching by name needs the name to say which column, and a side that wrote `a` twice has no
3328/// answer to give. An ordinary union does not care, because there the position says which column.
3329/// The doubled quotes around the name are the reference binary's and not a mistake here.
3330fn named_once(scope: &Scope) -> Result<()> {
3331    for (at, held) in scope.columns.iter().enumerate() {
3332        if scope.columns[..at].iter().any(|column| same_name(&column.name, &held.name)) {
3333            return Err(Error::binder(format!(
3334                "UNION (ALL) BY NAME operation doesn't support duplicate names in the SELECT list - the name \"\"{}\"\" occurs multiple times",
3335                held.name
3336            )));
3337        }
3338    }
3339    Ok(())
3340}
3341
3342/// The one type a column of a set operation comes out as, given what each side wrote.
3343fn meet(left: &LogicalType, right: &LogicalType) -> Result<LogicalType> {
3344    left.promote(right).ok_or_else(|| {
3345        Error::binder(format!(
3346            "Cannot combine a column of type {left} with a column of type {right} in a set operation"
3347        ))
3348    })
3349}
3350
3351/// DuckDB's complaint about a named parameter that was given a null, which is a different sentence
3352/// for almost every parameter.
3353///
3354/// Three of them were measured on `v2.0.0-dev84237` and no two agree: `binary_as_string` is the
3355/// first, `all_varchar` is the second and `header` is the third. They read like three people each
3356/// writing the message in front of them, which is what they are, and a harness that compares error
3357/// text compares all of it. Anything not measured gets the first one, which is the most general of
3358/// the three.
3359fn null_parameter(function: TableFunction, parameter: &str) -> String {
3360    match parameter {
3361        "header" => format!("\"{parameter}\" expects a non-null boolean value (e.g. TRUE or 1)"),
3362        "all_varchar" => format!("{} \"{parameter}\" cannot be NULL", function.name()),
3363        _ => format!("Cannot use NULL as argument to \"{parameter}\""),
3364    }
3365}
3366
3367/// The complaint about a `REPLACE` entry that named a column the star did not stand for.
3368///
3369/// It reads like the complaint about any other name that is not there, down to the list of names
3370/// that are, because from the writer's side it is the same mistake.
3371fn missing_replacement(name: &str, input: &Scope) -> Error {
3372    Error::binder(format!(
3373        "Column \"{name}\" in REPLACE list not found in FROM clause{}",
3374        input.candidates()
3375    ))
3376}
3377
3378/// Whether a type is one `fill` can interpolate over, which is the pin's phrase for it.
3379///
3380/// The pin refuses `fill` with `FILL argument must support subtraction` and its sort key with
3381/// `FILL ordering must support subtraction`, and the two lists are not the same list, which is why
3382/// this takes a flag rather than answering one question. Every number is on both, so are `DATE`,
3383/// `TIME` and the two timestamps, and `TIME WITH TIME ZONE` is a sort key there but not an
3384/// argument. `INTERVAL` is on neither, which is worth saying out loud because an interval does
3385/// subtract: the sentence names subtraction and the rule is narrower than the sentence.
3386fn subtractable(ty: &LogicalType, ordering: bool) -> bool {
3387    if ty.is_numeric() {
3388        return true;
3389    }
3390    match ty {
3391        LogicalType::Date
3392        | LogicalType::Time
3393        | LogicalType::Timestamp
3394        | LogicalType::TimestampS
3395        | LogicalType::TimestampMs
3396        | LogicalType::TimestampNs
3397        | LogicalType::TimestampTz => true,
3398        LogicalType::TimeTz => ordering,
3399        _ => false,
3400    }
3401}
3402
3403/// Refuses a `fill` call the way the pin refuses one, in the pin's order.
3404///
3405/// The order was measured and it is not the order the clauses are written in. A `fill` over a
3406/// `VARCHAR` with no `ORDER BY` at all complains about the argument, so the argument is looked at
3407/// before the sort key is counted, and a `fill` with `DISTINCT` and no `ORDER BY` complains about
3408/// the `ORDER BY`, so the count comes before the clauses. `IGNORE NULLS` is refused here rather
3409/// than being answered as a no-op, since there is nothing for it to skip: `fill` is the one window
3410/// whose whole job is the nulls.
3411fn refuse_fill(
3412    argument: &LogicalType,
3413    order: &[LogicalType],
3414    distinct: bool,
3415    ignore_nulls: bool,
3416) -> Result<()> {
3417    if !subtractable(argument, false) {
3418        return Err(Error::binder("FILL argument must support subtraction"));
3419    }
3420    let [key] = order else {
3421        return Err(Error::binder("FILL functions must have only one ORDER BY expression"));
3422    };
3423    if !subtractable(key, true) {
3424        return Err(Error::binder("FILL ordering must support subtraction"));
3425    }
3426    if distinct {
3427        return Err(Error::binder(
3428            "DISTINCT is not implemented for the window function \"\"fill\"\"",
3429        ));
3430    }
3431    if ignore_nulls {
3432        return Err(Error::binder(
3433            "RESPECT/IGNORE NULLS is not supported for the window function \"fill\"",
3434        ));
3435    }
3436    Ok(())
3437}
3438
3439/// Resolves the call written inside an `OVER`.
3440///
3441/// Every aggregate is also a window, which is why this goes through the same signature table the
3442/// aggregate path uses, and the ranking windows go through it too because they are rows in the same
3443/// table. Everything else is one of three refusals, and all three are the reference binary's: a name
3444/// it knows as a scalar and a name it does not know at all each get their own sentence there.
3445fn window_signature(name: &str, types: &[LogicalType]) -> Result<Resolved> {
3446    match kind_of(name) {
3447        Some(FunctionKind::Aggregate | FunctionKind::Window) => resolve(name, types),
3448        Some(FunctionKind::Scalar) => {
3449            Err(Error::catalog(format!("{name} is not an aggregate function")))
3450        }
3451        None => Err(Error::catalog(format!("Aggregate Function with name {name} does not exist!"))),
3452    }
3453}
3454
3455/// Structural equality over two expressions of one plan.
3456fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
3457    if left == right {
3458        return true;
3459    }
3460    if plan.expr_type(left) != plan.expr_type(right) {
3461        return false;
3462    }
3463    let lists = |left, right| {
3464        let left: &[ExprRef] = plan.expr_list(left);
3465        let right: &[ExprRef] = plan.expr_list(right);
3466        left.len() == right.len()
3467            && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
3468    };
3469    match (plan.expr(left), plan.expr(right)) {
3470        (Expr::Column(left), Expr::Column(right)) => left == right,
3471        (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
3472        (
3473            Expr::Cast { input: left, try_cast: left_try },
3474            Expr::Cast { input: right, try_cast: right_try },
3475        ) => left_try == right_try && same_expr(plan, *left, *right),
3476        (
3477            Expr::Compare { op: left_op, left: left_a, right: left_b },
3478            Expr::Compare { op: right_op, left: right_a, right: right_b },
3479        ) => {
3480            left_op == right_op
3481                && same_expr(plan, *left_a, *right_a)
3482                && same_expr(plan, *left_b, *right_b)
3483        }
3484        (
3485            Expr::Conjunction { op: left_op, children: left_children },
3486            Expr::Conjunction { op: right_op, children: right_children },
3487        ) => left_op == right_op && lists(*left_children, *right_children),
3488        (
3489            Expr::Function { name: left_name, args: left_args },
3490            Expr::Function { name: right_name, args: right_args },
3491        ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
3492        (
3493            Expr::Aggregate {
3494                name: left_name,
3495                args: left_args,
3496                distinct: left_distinct,
3497                filter: left_filter,
3498            },
3499            Expr::Aggregate {
3500                name: right_name,
3501                args: right_args,
3502                distinct: right_distinct,
3503                filter: right_filter,
3504            },
3505        ) => {
3506            plan.string(*left_name) == plan.string(*right_name)
3507                && left_distinct == right_distinct
3508                && match (left_filter, right_filter) {
3509                    (None, None) => true,
3510                    (Some(left), Some(right)) => same_expr(plan, *left, *right),
3511                    _ => false,
3512                }
3513                && lists(*left_args, *right_args)
3514        }
3515        // The partition, the order and the frame are not compared here and do not need to be. Two
3516        // window calls are only ever asked about when they are already in the same run, which is
3517        // what agreeing on all three means.
3518        (
3519            Expr::Window {
3520                name: left_name,
3521                args: left_args,
3522                distinct: left_distinct,
3523                filter: left_filter,
3524                ignore_nulls: left_nulls,
3525                order: left_order,
3526            },
3527            Expr::Window {
3528                name: right_name,
3529                args: right_args,
3530                distinct: right_distinct,
3531                filter: right_filter,
3532                ignore_nulls: right_nulls,
3533                order: right_order,
3534            },
3535        ) => {
3536            // The keys inside the brackets are compared, unlike the ones in the `OVER`, because two
3537            // calls in the same run can still read their frame in different orders.
3538            let left_keys = plan.sort_key_list(*left_order);
3539            let right_keys = plan.sort_key_list(*right_order);
3540            plan.string(*left_name) == plan.string(*right_name)
3541                && left_distinct == right_distinct
3542                && left_nulls == right_nulls
3543                && left_keys.len() == right_keys.len()
3544                && left_keys.iter().zip(right_keys).all(|(left, right)| {
3545                    left.descending == right.descending
3546                        && left.nulls_first == right.nulls_first
3547                        && same_expr(plan, left.expr, right.expr)
3548                })
3549                && match (left_filter, right_filter) {
3550                    (None, None) => true,
3551                    (Some(left), Some(right)) => same_expr(plan, *left, *right),
3552                    _ => false,
3553                }
3554                && lists(*left_args, *right_args)
3555        }
3556        (
3557            Expr::Case { arms: left_arms, otherwise: left_otherwise },
3558            Expr::Case { arms: right_arms, otherwise: right_otherwise },
3559        ) => {
3560            let left_arms = plan.arm_list(*left_arms);
3561            let right_arms = plan.arm_list(*right_arms);
3562            left_arms.len() == right_arms.len()
3563                && left_arms.iter().zip(right_arms).all(|(left, right)| {
3564                    same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
3565                })
3566                && match (left_otherwise, right_otherwise) {
3567                    (None, None) => true,
3568                    (Some(left), Some(right)) => same_expr(plan, *left, *right),
3569                    _ => false,
3570                }
3571        }
3572        _ => false,
3573    }
3574}