Skip to main content

rudb_bind/
binder.rs

1//! From an `Ast` to a `Plan`.
2//!
3//! The binder walks the written query once, in the order the operators end up in rather than the
4//! order the clauses are written in, which is `FROM`, `WHERE`, `GROUP BY`, `HAVING`, `SELECT`,
5//! `DISTINCT`, `ORDER BY`, `LIMIT`. That order is not a stylistic choice: it is the reason `WHERE`
6//! cannot see an output alias and `HAVING` cannot see a column that was not grouped, and doing it
7//! in any other order means special casing both of those instead of getting them for free.
8//!
9//! Two things leave here settled that nothing downstream reconsiders. Every column is a table index
10//! and a position rather than a name, so the optimizer never has to ask which `id` a name meant.
11//! And every expression has a type, with the casts that make the types line up already written into
12//! the plan as [`Expr::Cast`] nodes, so an executor never has to decide what a comparison between
13//! an `INTEGER` and a `BIGINT` does.
14
15use rudb_catalog::{Catalog, same_name};
16use rudb_common::{Error, Field, LogicalType, Result, Value};
17use rudb_functions::{resolve, resolve_table};
18use rudb_parse::ast::{self, Ast, Distinct, LiteralKind, Nulls, Order, Quantifier, SetOp};
19use rudb_parse::{NONE, parse_ast};
20use rudb_plan::{ColumnBinding, Expr, ExprRef, JoinKind, Node, NodeRef, Plan, SetOpKind, SortKey};
21
22use crate::expr::{describe, has_aggregate};
23use crate::scope::{Scope, Visible};
24
25/// Binds a parsed statement against a catalog.
26///
27/// # Errors
28///
29/// If the script does not hold exactly one statement, if a name does not resolve, if a type does
30/// not work out, or if the query uses something M0 does not bind yet.
31pub fn bind(ast: &Ast, catalog: &Catalog) -> Result<Plan> {
32    let query = match ast.statements.as_slice() {
33        [ast::Statement::Query(query)] => *query,
34        [] => return Err(Error::binder("no statement to bind")),
35        _ => return Err(Error::not_implemented("a script of more than one statement")),
36    };
37    let mut binder = Binder::new(catalog);
38    let (root, _) = binder.bind_query(ast, query)?;
39    let mut plan = binder.into_plan();
40    plan.set_root(root);
41    plan.validate()?;
42    Ok(plan)
43}
44
45/// Parses and binds one query, which is the whole front end in one call.
46///
47/// # Errors
48///
49/// Anything the parser or the binder reports.
50pub fn bind_sql(query: &str, catalog: &Catalog) -> Result<Plan> {
51    let ast = parse_ast(query)?;
52    bind(&ast, catalog)
53}
54
55/// What an aggregating select block has decided so far.
56#[derive(Debug)]
57pub(crate) struct Aggregation {
58    /// The table index the aggregate's output binds against.
59    pub(crate) index: u32,
60    /// The group expressions, over the input, which are the first output columns.
61    pub(crate) groups: Vec<ExprRef>,
62    /// The aggregate calls found so far, which follow the groups in the output.
63    pub(crate) aggregates: Vec<ExprRef>,
64}
65
66/// The state one binding run carries.
67#[derive(Debug)]
68pub(crate) struct Binder<'a> {
69    catalog: &'a Catalog,
70    plan: Plan,
71    next_index: u32,
72    /// Set while a select block aggregates, which changes what a bare column means.
73    pub(crate) aggregation: Option<Aggregation>,
74    /// Set while an aggregate's own arguments are being bound, so nesting is caught.
75    pub(crate) in_aggregate: bool,
76    /// Where we are, for an error message that says which clause the writer should look at.
77    pub(crate) clause: &'static str,
78}
79
80impl<'a> Binder<'a> {
81    pub(crate) fn new(catalog: &'a Catalog) -> Self {
82        Self {
83            catalog,
84            plan: Plan::new(),
85            next_index: 0,
86            aggregation: None,
87            in_aggregate: false,
88            clause: "SELECT clause",
89        }
90    }
91
92    pub(crate) fn plan(&self) -> &Plan {
93        &self.plan
94    }
95
96    pub(crate) fn plan_mut(&mut self) -> &mut Plan {
97        &mut self.plan
98    }
99
100    pub(crate) fn into_plan(self) -> Plan {
101        self.plan
102    }
103
104    /// A table index nothing else has.
105    pub(crate) fn fresh_index(&mut self) -> u32 {
106        let index = self.next_index;
107        self.next_index += 1;
108        index
109    }
110
111    /// A reference to one column of an operator's output.
112    fn column(&mut self, index: u32, position: usize, ty: LogicalType) -> ExprRef {
113        let binding = ColumnBinding::new(index, position as u32);
114        self.plan.add_expr(Expr::Column(binding), ty)
115    }
116
117    // ---------------------------------------------------------------- queries
118
119    pub(crate) fn bind_query(
120        &mut self,
121        ast: &Ast,
122        query: ast::QueryRef,
123    ) -> Result<(NodeRef, Scope)> {
124        let written = ast.query(query);
125        match written.body {
126            ast::QueryBody::Select(select) => self.bind_select(ast, select, &written),
127            ast::QueryBody::SetOp { op, quantifier, by_name, left, right } => {
128                if by_name {
129                    return Err(Error::not_implemented("UNION BY NAME"));
130                }
131                self.bind_set_op(ast, &written, op, quantifier, left, right)
132            }
133            ast::QueryBody::Values(rows) => self.bind_values(ast, &written, rows),
134        }
135    }
136
137    /// `VALUES (1, 'a'), (2, 'b')`, as a query in its own right.
138    ///
139    /// The column names are `col0`, `col1` and so on, which is what DuckDB calls them, and the
140    /// column types are what every row in that position promotes to. Promotion is the same rule a
141    /// set operation uses, and for the same reason: a column has one type and the rows have to
142    /// agree on it before anything downstream can read the column.
143    fn bind_values(
144        &mut self,
145        ast: &Ast,
146        query: &ast::Query,
147        rows: ast::Slice,
148    ) -> Result<(NodeRef, Scope)> {
149        let written = ast.rows(rows).to_vec();
150        let Some(first) = written.first() else {
151            return Err(Error::binder("VALUES needs at least one row"));
152        };
153        let width = first.len as usize;
154        for (at, row) in written.iter().enumerate() {
155            if row.len as usize != width {
156                return Err(Error::binder(format!(
157                    "VALUES lists must all be the same length, expected {width} columns but row {} has {}",
158                    at + 1,
159                    row.len
160                )));
161            }
162        }
163        // A row of a `VALUES` cannot see a column, because there is nothing under it to see.
164        let empty = Scope::empty();
165        let previous = std::mem::replace(&mut self.clause, "VALUES clause");
166        let mut bound: Vec<Vec<ExprRef>> = Vec::with_capacity(written.len());
167        for row in &written {
168            let mut items = Vec::with_capacity(width);
169            for &expr in ast.expr_list(*row) {
170                items.push(self.bind_expr(ast, expr, &empty)?);
171            }
172            bound.push(items);
173        }
174        self.clause = previous;
175        let mut types = Vec::with_capacity(width);
176        for at in 0..width {
177            let mut ty = self.plan.expr_type(bound[0][at]).clone();
178            for row in &bound[1..] {
179                let other = self.plan.expr_type(row[at]).clone();
180                ty = ty.promote(&other).ok_or_else(|| {
181                    Error::binder(format!(
182                        "Cannot combine a value of type {ty} with a value of type {other} in column {} of a VALUES",
183                        at + 1
184                    ))
185                })?;
186            }
187            types.push(ty);
188        }
189        let mut slices = Vec::with_capacity(bound.len());
190        for row in &bound {
191            let items: Vec<ExprRef> =
192                row.iter().zip(&types).map(|(&expr, ty)| self.cast_to(expr, ty)).collect();
193            slices.push(self.plan.add_expr_list(&items));
194        }
195        let rows = self.plan.add_rows(&slices);
196        let fields: Vec<Field> = types
197            .iter()
198            .enumerate()
199            .map(|(at, ty)| Field::new(format!("col{at}"), ty.clone()))
200            .collect();
201        let columns = self.plan.add_fields(&fields);
202        let index = self.fresh_index();
203        let mut node = self.plan.add_node(Node::Values { index, columns, rows });
204        let mut scope = Scope::empty();
205        for (at, field) in fields.iter().enumerate() {
206            scope.push(Visible {
207                table: String::new(),
208                name: field.name.clone(),
209                binding: ColumnBinding::new(index, at as u32),
210                ty: field.ty.clone(),
211            });
212        }
213        let keys = self.sort_keys(ast, query, &scope, &[])?;
214        if !keys.is_empty() {
215            let keys = self.plan.add_sort_keys(&keys);
216            node = self.plan.add_node(Node::Sort { input: node, keys });
217        }
218        node = self.apply_limit(ast, query, node)?;
219        Ok((node, scope))
220    }
221
222    fn bind_set_op(
223        &mut self,
224        ast: &Ast,
225        query: &ast::Query,
226        op: SetOp,
227        quantifier: Quantifier,
228        left: ast::QueryRef,
229        right: ast::QueryRef,
230    ) -> Result<(NodeRef, Scope)> {
231        let (left_node, left_scope) = self.bind_query(ast, left)?;
232        let (right_node, right_scope) = self.bind_query(ast, right)?;
233        if left_scope.len() != right_scope.len() {
234            return Err(Error::binder(format!(
235                "Set operations can only apply to expressions with the same number of result columns, but left side has {} and right side has {}",
236                left_scope.len(),
237                right_scope.len()
238            )));
239        }
240        // Both sides have to hand back one set of types, so each column meets the other side's.
241        let mut types = Vec::with_capacity(left_scope.len());
242        for (left, right) in left_scope.columns.iter().zip(&right_scope.columns) {
243            let common = left.ty.promote(&right.ty).ok_or_else(|| {
244                Error::binder(format!(
245                    "Cannot combine a column of type {} with a column of type {} in a set operation",
246                    left.ty, right.ty
247                ))
248            })?;
249            types.push(common);
250        }
251        let left_node = self.conform(left_node, &left_scope, &types);
252        let right_node = self.conform(right_node, &right_scope, &types);
253        let index = self.fresh_index();
254        let kind = match op {
255            SetOp::Union => SetOpKind::Union,
256            SetOp::Except => SetOpKind::Except,
257            SetOp::Intersect => SetOpKind::Intersect,
258        };
259        // UNION alone removes duplicates and UNION ALL keeps them, which is the one place the
260        // unwritten quantifier and ALL disagree.
261        let all = quantifier == Quantifier::All;
262        let mut node = self.plan.add_node(Node::SetOp {
263            left: left_node,
264            right: right_node,
265            kind,
266            all,
267            index,
268        });
269        let mut scope = Scope::empty();
270        for (at, (column, ty)) in left_scope.columns.iter().zip(&types).enumerate() {
271            scope.push(Visible {
272                table: String::new(),
273                name: column.name.clone(),
274                binding: ColumnBinding::new(index, at as u32),
275                ty: ty.clone(),
276            });
277        }
278        // Above a set operation there is nothing but the output columns, so an ORDER BY term is
279        // either a position, an output name, or an expression over the output, and never needs a
280        // column projected for it that the query did not ask for.
281        let keys = self.sort_keys(ast, query, &scope, &[])?;
282        if !keys.is_empty() {
283            let keys = self.plan.add_sort_keys(&keys);
284            node = self.plan.add_node(Node::Sort { input: node, keys });
285        }
286        node = self.apply_limit(ast, query, node)?;
287        Ok((node, scope))
288    }
289
290    /// Projects one side of a set operation so that its columns have the agreed types.
291    fn conform(&mut self, node: NodeRef, scope: &Scope, types: &[LogicalType]) -> NodeRef {
292        if scope.columns.iter().zip(types).all(|(column, ty)| &column.ty == ty) {
293            return node;
294        }
295        let index = self.fresh_index();
296        let mut exprs = Vec::with_capacity(types.len());
297        let mut names = Vec::with_capacity(types.len());
298        for (column, ty) in scope.columns.iter().zip(types) {
299            let expr = self.plan.add_expr(Expr::Column(column.binding), column.ty.clone());
300            exprs.push(self.cast_to(expr, ty));
301            names.push(self.plan.intern(&column.name));
302        }
303        let exprs = self.plan.add_expr_list(&exprs);
304        let names = self.plan.add_name_list(&names);
305        self.plan.add_node(Node::Project { input: node, index, exprs, names })
306    }
307
308    // ----------------------------------------------------------------- select
309
310    fn bind_select(
311        &mut self,
312        ast: &Ast,
313        select: ast::SelectRef,
314        query: &ast::Query,
315    ) -> Result<(NodeRef, Scope)> {
316        let written = ast.select(select);
317        let (mut node, input) = self.bind_from(ast, written.from)?;
318
319        if written.filter != NONE {
320            self.clause = "WHERE clause";
321            let predicate = self.bind_expr(ast, written.filter, &input)?;
322            let predicate = self.as_boolean(predicate, "WHERE")?;
323            node = self.plan.add_node(Node::Filter { input: node, predicate });
324        }
325
326        let targets = ast.target_list(written.targets).to_vec();
327        if targets.is_empty() {
328            return Err(Error::binder("a SELECT needs at least one expression to select"));
329        }
330
331        let group_items = self.group_items(ast, &written, &targets)?;
332        let aggregating = !group_items.is_empty()
333            || written.having != NONE
334            || targets.iter().any(|target| has_aggregate(ast, target.expr));
335        if aggregating {
336            self.clause = "GROUP BY clause";
337            let mut groups = Vec::with_capacity(group_items.len());
338            for item in &group_items {
339                groups.push(self.bind_expr(ast, *item, &input)?);
340            }
341            let index = self.fresh_index();
342            self.aggregation = Some(Aggregation { index, groups, aggregates: Vec::new() });
343        }
344
345        self.clause = "SELECT clause";
346        let (mut exprs, mut names) = self.bind_targets(ast, &targets, &input)?;
347        let visible = exprs.len();
348
349        let mut having = None;
350        if written.having != NONE {
351            self.clause = "HAVING clause";
352            let predicate = self.bind_expr(ast, written.having, &input)?;
353            let predicate = self.over_aggregate(predicate, &input)?;
354            having = Some(self.as_boolean(predicate, "HAVING")?);
355        }
356
357        // The projection's index has to exist before the sort keys are built, because a key is a
358        // reference to a projected column even when the expression it sorts on is not selected.
359        let project = self.fresh_index();
360        let mut output = Scope::empty();
361        for (at, (expr, name)) in exprs.iter().zip(&names).enumerate() {
362            output.push(Visible {
363                table: String::new(),
364                name: name.clone(),
365                binding: ColumnBinding::new(project, at as u32),
366                ty: self.plan.expr_type(*expr).clone(),
367            });
368        }
369
370        self.clause = "ORDER BY clause";
371        let mut extra = Vec::new();
372        let keys = self.select_sort_keys(
373            ast, query, &input, &output, project, &mut exprs, &mut names, &mut extra,
374        )?;
375        if !extra.is_empty() && written.distinct != Distinct::No {
376            return Err(Error::binder(
377                "For SELECT DISTINCT, ORDER BY expressions must appear in the select list",
378            ));
379        }
380        let on = self.distinct_on(ast, written.distinct, &output)?;
381
382        if let Some(aggregation) = self.aggregation.take() {
383            let index = aggregation.index;
384            let groups = self.plan.add_expr_list(&aggregation.groups);
385            let aggregates = self.plan.add_expr_list(&aggregation.aggregates);
386            node = self.plan.add_node(Node::Aggregate { input: node, index, groups, aggregates });
387        }
388        if let Some(predicate) = having {
389            node = self.plan.add_node(Node::Filter { input: node, predicate });
390        }
391
392        let interned: Vec<u32> = names.iter().map(|name| self.plan.intern(name)).collect();
393        let exprs_slice = self.plan.add_expr_list(&exprs);
394        let names_slice = self.plan.add_name_list(&interned);
395        node = self.plan.add_node(Node::Project {
396            input: node,
397            index: project,
398            exprs: exprs_slice,
399            names: names_slice,
400        });
401
402        if written.distinct != Distinct::No {
403            let on = self.plan.add_expr_list(&on);
404            node = self.plan.add_node(Node::Distinct { input: node, on });
405        }
406        if !keys.is_empty() {
407            let keys = self.plan.add_sort_keys(&keys);
408            node = self.plan.add_node(Node::Sort { input: node, keys });
409        }
410        node = self.apply_limit(ast, query, node)?;
411
412        if extra.is_empty() {
413            output.columns.truncate(visible);
414            return Ok((node, output));
415        }
416        // An expression sorted on but not selected was carried this far to make the sort possible,
417        // and now it goes, because the query did not ask for it.
418        let index = self.fresh_index();
419        let mut kept = Vec::with_capacity(visible);
420        let mut kept_names = Vec::with_capacity(visible);
421        let mut scope = Scope::empty();
422        for (at, name) in names.iter().enumerate().take(visible) {
423            let ty = output.columns[at].ty.clone();
424            kept.push(self.column(project, at, ty.clone()));
425            kept_names.push(self.plan.intern(name));
426            scope.push(Visible {
427                table: String::new(),
428                name: name.clone(),
429                binding: ColumnBinding::new(index, at as u32),
430                ty,
431            });
432        }
433        let exprs = self.plan.add_expr_list(&kept);
434        let names = self.plan.add_name_list(&kept_names);
435        node = self.plan.add_node(Node::Project { input: node, index, exprs, names });
436        Ok((node, scope))
437    }
438
439    /// Binds the target list, expanding every star into the columns it stands for.
440    fn bind_targets(
441        &mut self,
442        ast: &Ast,
443        targets: &[ast::Target],
444        input: &Scope,
445    ) -> Result<(Vec<ExprRef>, Vec<String>)> {
446        let mut exprs = Vec::with_capacity(targets.len());
447        let mut names = Vec::with_capacity(targets.len());
448        for target in targets {
449            if let ast::Expr::Star { qualifier } = ast.expr(target.expr) {
450                let table = ast.name(qualifier).last().map(str::to_string);
451                let expanded: Vec<Visible> =
452                    input.star(table.as_deref())?.into_iter().cloned().collect();
453                for column in expanded {
454                    let expr = self.plan.add_expr(Expr::Column(column.binding), column.ty);
455                    exprs.push(self.over_aggregate(expr, input)?);
456                    names.push(column.name);
457                }
458                continue;
459            }
460            let expr = self.bind_expr(ast, target.expr, input)?;
461            exprs.push(self.over_aggregate(expr, input)?);
462            names.push(if target.alias == NONE {
463                self.output_name(ast, target.expr, input)
464            } else {
465                ast.string(target.alias).to_string()
466            });
467        }
468        Ok((exprs, names))
469    }
470
471    /// The name an unaliased target gets.
472    ///
473    /// A bare column keeps the spelling the table was created with rather than the spelling the
474    /// query used, so `SELECT USERID FROM hits` has a column called `UserID`. Identifiers match
475    /// without regard to case and the catalog is the one that holds the case.
476    fn output_name(&self, ast: &Ast, target: ast::ExprRef, input: &Scope) -> String {
477        if let ast::Expr::Column { name } = ast.expr(target) {
478            let parts: Vec<&str> = ast.name(name).collect();
479            if let Ok(found) = input.resolve(&parts) {
480                return found.name.clone();
481            }
482        }
483        describe(ast, target)
484    }
485
486    /// The expressions a `GROUP BY` clause names, with positions and output aliases followed.
487    fn group_items(
488        &self,
489        ast: &Ast,
490        select: &ast::Select,
491        targets: &[ast::Target],
492    ) -> Result<Vec<ast::ExprRef>> {
493        if select.group_by_all {
494            // GROUP BY ALL means every target that is not itself an aggregate, which is the set
495            // that would otherwise have to be written out again by hand.
496            return Ok(targets
497                .iter()
498                .filter(|target| !has_aggregate(ast, target.expr))
499                .map(|target| target.expr)
500                .collect());
501        }
502        let mut items = Vec::new();
503        for &item in ast.expr_list(select.group_by) {
504            items.push(self.output_reference(ast, item, targets, "GROUP BY")?.unwrap_or(item));
505        }
506        Ok(items)
507    }
508
509    /// The target a `GROUP BY` or `ORDER BY` term names, when it names one by position or alias.
510    fn output_reference(
511        &self,
512        ast: &Ast,
513        item: ast::ExprRef,
514        targets: &[ast::Target],
515        clause: &str,
516    ) -> Result<Option<ast::ExprRef>> {
517        match ast.expr(item) {
518            ast::Expr::Literal { kind: LiteralKind::Number, text } => {
519                let written = ast.string(text);
520                let position: usize = written.parse().map_err(|_| {
521                    Error::binder(format!("{clause} term {written} is not a column"))
522                })?;
523                if position == 0 || position > targets.len() {
524                    return Err(Error::binder(format!(
525                        "{clause} term out of range - should be between 1 and {}",
526                        targets.len()
527                    )));
528                }
529                Ok(Some(targets[position - 1].expr))
530            }
531            ast::Expr::Column { name } => {
532                let parts: Vec<&str> = ast.name(name).collect();
533                let [written] = parts.as_slice() else { return Ok(None) };
534                let mut found = None;
535                for target in targets {
536                    if target.alias != NONE && same_name(ast.string(target.alias), written) {
537                        if found.is_some() {
538                            return Ok(None);
539                        }
540                        found = Some(target.expr);
541                    }
542                }
543                Ok(found)
544            }
545            _ => Ok(None),
546        }
547    }
548
549    // -------------------------------------------------------------- modifiers
550
551    /// Sort keys for a select, projecting anything sorted on that is not already selected.
552    #[allow(clippy::too_many_arguments)]
553    fn select_sort_keys(
554        &mut self,
555        ast: &Ast,
556        query: &ast::Query,
557        input: &Scope,
558        output: &Scope,
559        project: u32,
560        exprs: &mut Vec<ExprRef>,
561        names: &mut Vec<String>,
562        extra: &mut Vec<usize>,
563    ) -> Result<Vec<SortKey>> {
564        if query.order_by_all {
565            return Ok(self.every_column(output));
566        }
567        let items = ast.order_list(query.order_by).to_vec();
568        let mut keys = Vec::with_capacity(items.len());
569        for item in items {
570            let position = match self.output_position(ast, item.expr, output)? {
571                Some(position) => position,
572                None => {
573                    let bound = self.bind_expr(ast, item.expr, input)?;
574                    let bound = self.over_aggregate(bound, input)?;
575                    match exprs.iter().position(|&held| self.same_expr(held, bound)) {
576                        Some(position) => position,
577                        None => {
578                            exprs.push(bound);
579                            names.push(describe(ast, item.expr));
580                            extra.push(exprs.len() - 1);
581                            exprs.len() - 1
582                        }
583                    }
584                }
585            };
586            let ty = self.plan.expr_type(exprs[position]).clone();
587            let expr = self.column(project, position, ty);
588            keys.push(sort_key(expr, item));
589        }
590        Ok(keys)
591    }
592
593    /// Sort keys over an output that has nothing behind it to project, which is a set operation.
594    fn sort_keys(
595        &mut self,
596        ast: &Ast,
597        query: &ast::Query,
598        output: &Scope,
599        targets: &[ast::Target],
600    ) -> Result<Vec<SortKey>> {
601        if query.order_by_all {
602            return Ok(self.every_column(output));
603        }
604        let items = ast.order_list(query.order_by).to_vec();
605        let mut keys = Vec::with_capacity(items.len());
606        for item in items {
607            let expr = match self.output_position(ast, item.expr, output)? {
608                Some(position) => {
609                    let column = &output.columns[position];
610                    let (binding, ty) = (column.binding, column.ty.clone());
611                    self.plan.add_expr(Expr::Column(binding), ty)
612                }
613                None => {
614                    let _ = targets;
615                    self.bind_expr(ast, item.expr, output)?
616                }
617            };
618            keys.push(sort_key(expr, item));
619        }
620        Ok(keys)
621    }
622
623    fn every_column(&mut self, output: &Scope) -> Vec<SortKey> {
624        let columns: Vec<(ColumnBinding, LogicalType)> =
625            output.columns.iter().map(|column| (column.binding, column.ty.clone())).collect();
626        columns
627            .into_iter()
628            .map(|(binding, ty)| {
629                let expr = self.plan.add_expr(Expr::Column(binding), ty);
630                SortKey { expr, descending: false, nulls_first: false }
631            })
632            .collect()
633    }
634
635    /// Which output column a term names, by position or by name.
636    fn output_position(
637        &self,
638        ast: &Ast,
639        item: ast::ExprRef,
640        output: &Scope,
641    ) -> Result<Option<usize>> {
642        match ast.expr(item) {
643            ast::Expr::Literal { kind: LiteralKind::Number, text } => {
644                let written = ast.string(text);
645                if written.contains(['.', 'e', 'E']) {
646                    return Ok(None);
647                }
648                let position: usize = written.parse().map_err(|_| {
649                    Error::binder(format!("ORDER BY term {written} is not a column"))
650                })?;
651                if position == 0 || position > output.len() {
652                    return Err(Error::binder(format!(
653                        "ORDER BY term out of range - should be between 1 and {}",
654                        output.len()
655                    )));
656                }
657                Ok(Some(position - 1))
658            }
659            ast::Expr::Column { name } => {
660                let parts: Vec<&str> = ast.name(name).collect();
661                let [written] = parts.as_slice() else { return Ok(None) };
662                Ok(output.position_of(None, written))
663            }
664            _ => Ok(None),
665        }
666    }
667
668    /// The expressions a `DISTINCT ON` names, which have to be columns of the output.
669    fn distinct_on(
670        &mut self,
671        ast: &Ast,
672        distinct: Distinct,
673        output: &Scope,
674    ) -> Result<Vec<ExprRef>> {
675        let Distinct::On(items) = distinct else {
676            return Ok(Vec::new());
677        };
678        let items = ast.expr_list(items).to_vec();
679        let mut on = Vec::with_capacity(items.len());
680        for item in items {
681            let Some(position) = self.output_position(ast, item, output)? else {
682                return Err(Error::not_implemented(
683                    "DISTINCT ON an expression that is not in the select list",
684                ));
685            };
686            let column = &output.columns[position];
687            let (binding, ty) = (column.binding, column.ty.clone());
688            on.push(self.plan.add_expr(Expr::Column(binding), ty));
689        }
690        Ok(on)
691    }
692
693    fn apply_limit(&mut self, ast: &Ast, query: &ast::Query, input: NodeRef) -> Result<NodeRef> {
694        if query.limit_percent {
695            return Err(Error::not_implemented("LIMIT with a percentage"));
696        }
697        let count = self.constant_count(ast, query.limit, "LIMIT")?;
698        let offset = self.constant_count(ast, query.offset, "OFFSET")?.unwrap_or(0);
699        if count.is_none() && offset == 0 {
700            return Ok(input);
701        }
702        Ok(self.plan.add_node(Node::Limit { input, count, offset }))
703    }
704
705    /// The row count a `LIMIT` or an `OFFSET` names, which has to be a constant.
706    fn constant_count(
707        &mut self,
708        ast: &Ast,
709        written: ast::ExprRef,
710        clause: &str,
711    ) -> Result<Option<u64>> {
712        if written == NONE {
713            return Ok(None);
714        }
715        self.clause = "LIMIT clause";
716        let scope = Scope::empty();
717        let bound = self.bind_expr(ast, written, &scope)?;
718        let Expr::Constant(value) = *self.plan.expr(bound) else {
719            return Err(Error::not_implemented(format!("a {clause} that is not a constant")));
720        };
721        let count = match self.plan.value(value) {
722            Value::Null => return Ok(None),
723            Value::TinyInt(count) => i128::from(*count),
724            Value::SmallInt(count) => i128::from(*count),
725            Value::Integer(count) => i128::from(*count),
726            Value::BigInt(count) => i128::from(*count),
727            Value::HugeInt(count) => *count,
728            other => {
729                return Err(Error::binder(format!(
730                    "{clause} takes a whole number of rows, not a value of type {}",
731                    other.logical_type()
732                )));
733            }
734        };
735        u64::try_from(count)
736            .map(Some)
737            .map_err(|_| Error::binder(format!("{clause} must not be negative")))
738    }
739
740    // ------------------------------------------------------------------- from
741
742    fn bind_from(&mut self, ast: &Ast, from: ast::Slice) -> Result<(NodeRef, Scope)> {
743        let sources = ast.source_list(from).to_vec();
744        let Some((first, rest)) = sources.split_first() else {
745            // No FROM clause is one row of no columns, which is what SELECT 1 sits on. Not an
746            // empty table: an empty table would make SELECT 1 return nothing.
747            return Ok((self.plan.add_node(Node::Dummy), Scope::empty()));
748        };
749        let (mut node, mut scope) = self.bind_source(ast, *first)?;
750        for source in rest {
751            let (right, right_scope) = self.bind_source(ast, *source)?;
752            node = self.plan.add_node(Node::CrossProduct { left: node, right });
753            scope = scope.concat(right_scope);
754        }
755        Ok((node, scope))
756    }
757
758    fn bind_source(&mut self, ast: &Ast, source: ast::SourceRef) -> Result<(NodeRef, Scope)> {
759        match ast.source(source) {
760            ast::Source::Table { name, alias, columns } => {
761                self.bind_table(ast, name, alias, columns)
762            }
763            ast::Source::Function { name, args, alias, columns } => {
764                self.bind_table_function(ast, name, args, alias, columns)
765            }
766            ast::Source::Subquery { query, alias, columns } => {
767                let (node, mut scope) = self.bind_query(ast, query)?;
768                let label = if alias == NONE {
769                    "unnamed_subquery".to_string()
770                } else {
771                    ast.string(alias).to_string()
772                };
773                scope.relabel(&label);
774                if !columns.is_empty() {
775                    let names: Vec<&str> = ast.name(columns).collect();
776                    scope.rename(&names, &label)?;
777                }
778                Ok((node, scope))
779            }
780            ast::Source::Values { rows, alias, columns } => {
781                let bare = ast::Query::bare(ast::QueryBody::Values(rows));
782                let (node, mut scope) = self.bind_values(ast, &bare, rows)?;
783                let label =
784                    if alias == NONE { String::new() } else { ast.string(alias).to_string() };
785                scope.relabel(&label);
786                if !columns.is_empty() {
787                    let names: Vec<&str> = ast.name(columns).collect();
788                    scope.rename(&names, &label)?;
789                }
790                Ok((node, scope))
791            }
792            ast::Source::Join { left, right, kind, natural, on, using } => {
793                self.bind_join(ast, left, right, kind, natural, on, using)
794            }
795        }
796    }
797
798    fn bind_table(
799        &mut self,
800        ast: &Ast,
801        name: ast::Slice,
802        alias: ast::StrRef,
803        columns: ast::Slice,
804    ) -> Result<(NodeRef, Scope)> {
805        let parts: Vec<&str> = ast.name(name).collect();
806        let catalog = self.catalog;
807        let resolved = catalog.resolve(&parts)?;
808        let table = catalog.table(&resolved)?;
809        let fields: Vec<Field> = table.columns().to_vec();
810        let label =
811            if alias == NONE { resolved.table.clone() } else { ast.string(alias).to_string() };
812        let index = self.fresh_index();
813        let mut scope = Scope::empty();
814        for (at, field) in fields.iter().enumerate() {
815            scope.push(Visible {
816                table: label.clone(),
817                name: field.name.clone(),
818                binding: ColumnBinding::new(index, at as u32),
819                ty: field.ty.clone(),
820            });
821        }
822        if !columns.is_empty() {
823            let names: Vec<&str> = ast.name(columns).collect();
824            scope.rename(&names, &label)?;
825        }
826        let catalog_name = self.plan.intern(&resolved.catalog);
827        let schema = self.plan.intern(&resolved.schema);
828        let table_name = self.plan.intern(&resolved.table);
829        let alias = self.plan.intern(&label);
830        let columns = self.plan.add_fields(&fields);
831        let node = self.plan.add_node(Node::Get {
832            catalog: catalog_name,
833            schema,
834            table: table_name,
835            alias,
836            index,
837            columns,
838        });
839        Ok((node, scope))
840    }
841
842    /// A function call where a table goes, such as `range(10)`.
843    ///
844    /// The arguments are bound against an empty scope. A table function that can see the row on its
845    /// left is `LATERAL`, and this is not it, so a column name in here is not resolved against
846    /// whatever happens to be to the left in the `FROM` list. Letting it would mean `FROM t,
847    /// range(t.n)` quietly binding to something whose meaning depends on the order the sources were
848    /// written in.
849    fn bind_table_function(
850        &mut self,
851        ast: &Ast,
852        name: ast::Slice,
853        args: ast::Slice,
854        alias: ast::StrRef,
855        columns: ast::Slice,
856    ) -> Result<(NodeRef, Scope)> {
857        let parts: Vec<&str> = ast.name(name).collect();
858        // A qualified call names a schema, and the two schemas that exist are the ones every
859        // built-in lives in. Anything else is a name that has to fail rather than fall through to
860        // the unqualified lookup and be found somewhere it was not asked for.
861        let function_name = *parts.last().unwrap_or(&"");
862        if let Some(schema) = parts.iter().rev().nth(1) {
863            if !schema.eq_ignore_ascii_case("main") && !schema.eq_ignore_ascii_case("system") {
864                return Err(Error::catalog(format!(
865                    "Table Function with name {} does not exist!",
866                    parts.join(".")
867                )));
868            }
869        }
870        let written = ast.expr_list(args).to_vec();
871        let resolved = resolve_table(function_name, written.len())?;
872
873        let empty = Scope::empty();
874        let previous = std::mem::replace(&mut self.clause, "table function arguments");
875        let mut bound = Vec::with_capacity(written.len());
876        for expr in written {
877            bound.push(self.bind_expr(ast, expr, &empty)?);
878        }
879        self.clause = previous;
880        let cast: Vec<ExprRef> = bound
881            .iter()
882            .zip(&resolved.arguments)
883            .map(|(&expr, ty)| self.cast_to(expr, ty))
884            .collect();
885
886        let label = if alias == NONE {
887            resolved.function.name().to_string()
888        } else {
889            ast.string(alias).to_string()
890        };
891        let index = self.fresh_index();
892        let mut scope = Scope::empty();
893        for (at, field) in resolved.columns.iter().enumerate() {
894            scope.push(Visible {
895                table: label.clone(),
896                name: field.name.clone(),
897                binding: ColumnBinding::new(index, at as u32),
898                ty: field.ty.clone(),
899            });
900        }
901        if !columns.is_empty() {
902            let names: Vec<&str> = ast.name(columns).collect();
903            scope.rename(&names, &label)?;
904        }
905        let function = self.plan.intern(resolved.function.name());
906        let args = self.plan.add_expr_list(&cast);
907        let fields = self.plan.add_fields(&resolved.columns);
908        let node =
909            self.plan.add_node(Node::TableFunction { index, function, args, columns: fields });
910        Ok((node, scope))
911    }
912
913    #[allow(clippy::too_many_arguments)]
914    fn bind_join(
915        &mut self,
916        ast: &Ast,
917        left: ast::SourceRef,
918        right: ast::SourceRef,
919        kind: ast::JoinKind,
920        natural: bool,
921        on: ast::ExprRef,
922        using: ast::Slice,
923    ) -> Result<(NodeRef, Scope)> {
924        let (left_node, left_scope) = self.bind_source(ast, left)?;
925        let (right_node, right_scope) = self.bind_source(ast, right)?;
926        let split = left_scope.len();
927        let mut scope = left_scope.concat(right_scope);
928
929        // NATURAL is USING over whatever both sides happen to call the same thing, which is why it
930        // is resolved here and never reaches the plan as its own idea.
931        let merged: Vec<String> = if natural {
932            let mut names = Vec::new();
933            for (at, column) in scope.columns.iter().enumerate().take(split) {
934                if scope.columns[split..].iter().any(|right| same_name(&right.name, &column.name))
935                    && !names.iter().any(|held: &String| same_name(held, &column.name))
936                {
937                    let _ = at;
938                    names.push(column.name.clone());
939                }
940            }
941            names
942        } else {
943            ast.name(using).map(str::to_string).collect()
944        };
945
946        let mut conditions = Vec::new();
947        let mut dropped = Vec::new();
948        for name in &merged {
949            let left_at = scope.columns[..split]
950                .iter()
951                .position(|column| same_name(&column.name, name))
952                .ok_or_else(|| {
953                    Error::binder(format!(
954                        "column \"{name}\" specified in USING clause does not exist in left table"
955                    ))
956                })?;
957            let right_at = scope.columns[split..]
958                .iter()
959                .position(|column| same_name(&column.name, name))
960                .map(|at| at + split)
961                .ok_or_else(|| {
962                    Error::binder(format!(
963                        "column \"{name}\" specified in USING clause does not exist in right table"
964                    ))
965                })?;
966            let left_column = &scope.columns[left_at];
967            let (left_binding, left_type) = (left_column.binding, left_column.ty.clone());
968            let right_column = &scope.columns[right_at];
969            let (right_binding, right_type) = (right_column.binding, right_column.ty.clone());
970            let left_expr = self.plan.add_expr(Expr::Column(left_binding), left_type);
971            let right_expr = self.plan.add_expr(Expr::Column(right_binding), right_type);
972            conditions.push(self.compare(rudb_plan::CompareOp::Equal, left_expr, right_expr)?);
973            dropped.push(right_at);
974        }
975        // A joined-on column appears once, so the right side's copy goes. Dropping from the back
976        // keeps the positions of the ones still to drop correct.
977        dropped.sort_unstable();
978        for at in dropped.into_iter().rev() {
979            scope.remove(at);
980        }
981
982        if on != NONE {
983            if !merged.is_empty() {
984                return Err(Error::binder("a join cannot have both ON and USING"));
985            }
986            self.clause = "JOIN condition";
987            let predicate = self.bind_expr(ast, on, &scope)?;
988            conditions.push(self.as_boolean(predicate, "JOIN")?);
989        }
990
991        if kind == ast::JoinKind::Cross {
992            if !conditions.is_empty() {
993                return Err(Error::binder("a CROSS JOIN cannot have a condition"));
994            }
995            let node =
996                self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
997            return Ok((node, scope));
998        }
999        if conditions.is_empty() && kind == ast::JoinKind::Inner {
1000            let node =
1001                self.plan.add_node(Node::CrossProduct { left: left_node, right: right_node });
1002            return Ok((node, scope));
1003        }
1004        let kind = match kind {
1005            ast::JoinKind::Inner | ast::JoinKind::Cross => JoinKind::Inner,
1006            ast::JoinKind::Left => JoinKind::Left,
1007            ast::JoinKind::Right => JoinKind::Right,
1008            ast::JoinKind::Full => JoinKind::Full,
1009            ast::JoinKind::Semi => JoinKind::Semi,
1010            ast::JoinKind::Anti => JoinKind::Anti,
1011            ast::JoinKind::Positional => JoinKind::Positional,
1012        };
1013        let conditions = self.plan.add_expr_list(&conditions);
1014        let node =
1015            self.plan.add_node(Node::Join { left: left_node, right: right_node, kind, conditions });
1016        Ok((node, scope))
1017    }
1018
1019    // -------------------------------------------------------------- aggregates
1020
1021    /// Binds an aggregate call, records it, and hands back a reference to where its result lands.
1022    pub(crate) fn bind_aggregate(
1023        &mut self,
1024        ast: &Ast,
1025        name: &str,
1026        args: &[ast::ExprRef],
1027        distinct: bool,
1028        scope: &Scope,
1029    ) -> Result<ExprRef> {
1030        if self.in_aggregate {
1031            return Err(Error::binder(format!(
1032                "aggregate function calls cannot be nested, and {name}() is inside one"
1033            )));
1034        }
1035        if self.aggregation.is_none() {
1036            return Err(Error::binder(format!(
1037                "aggregate function calls cannot be used in the {}",
1038                self.clause
1039            )));
1040        }
1041        self.in_aggregate = true;
1042        let mut bound = Vec::with_capacity(args.len());
1043        let mut failure = None;
1044        for &arg in args {
1045            match self.bind_expr(ast, arg, scope) {
1046                Ok(expr) => bound.push(expr),
1047                Err(error) => {
1048                    failure = Some(error);
1049                    break;
1050                }
1051            }
1052        }
1053        self.in_aggregate = false;
1054        if let Some(error) = failure {
1055            return Err(error);
1056        }
1057
1058        let types: Vec<LogicalType> =
1059            bound.iter().map(|&arg| self.plan.expr_type(arg).clone()).collect();
1060        let resolved = resolve(name, &types)?;
1061        let mut cast = Vec::with_capacity(bound.len());
1062        for (arg, wanted) in bound.iter().zip(&resolved.arguments) {
1063            cast.push(self.cast_to(*arg, wanted));
1064        }
1065        let args = self.plan.add_expr_list(&cast);
1066        let name = self.plan.intern(resolved.name);
1067        let ty = resolved.returns;
1068        let call =
1069            self.plan.add_expr(Expr::Aggregate { name, args, distinct, filter: None }, ty.clone());
1070
1071        // Two identical aggregates are one column of the aggregate's output. `SELECT sum(x),
1072        // sum(x) / count(*)` computes one sum, not two.
1073        let existing = self.aggregation.as_ref().map(|held| held.aggregates.clone());
1074        let existing = existing.unwrap_or_default();
1075        let at = match existing.iter().position(|&held| self.same_expr(held, call)) {
1076            Some(at) => at,
1077            None => {
1078                let aggregation = self.aggregation.as_mut().expect("checked above");
1079                aggregation.aggregates.push(call);
1080                aggregation.aggregates.len() - 1
1081            }
1082        };
1083        let aggregation = self.aggregation.as_ref().expect("checked above");
1084        let (index, groups) = (aggregation.index, aggregation.groups.len());
1085        Ok(self.column(index, groups + at, ty))
1086    }
1087
1088    /// Rewrites a bound expression into one the aggregate's output can answer.
1089    ///
1090    /// A subexpression that is one of the group expressions becomes a reference to that group. A
1091    /// column that is neither grouped nor inside an aggregate is the error every SQL user has seen,
1092    /// and it is reported here because this is the first point where it is knowable.
1093    pub(crate) fn over_aggregate(&mut self, expr: ExprRef, scope: &Scope) -> Result<ExprRef> {
1094        let Some(aggregation) = self.aggregation.as_ref() else {
1095            return Ok(expr);
1096        };
1097        let index = aggregation.index;
1098        let groups = aggregation.groups.clone();
1099        for (at, group) in groups.iter().enumerate() {
1100            if self.same_expr(expr, *group) {
1101                let ty = self.plan.expr_type(*group).clone();
1102                return Ok(self.column(index, at, ty));
1103            }
1104        }
1105        let ty = self.plan.expr_type(expr).clone();
1106        match self.plan.expr(expr).clone() {
1107            Expr::Column(binding) if binding.table == index => Ok(expr),
1108            Expr::Column(binding) => {
1109                let name =
1110                    scope.columns.iter().find(|column| column.binding == binding).map_or_else(
1111                        || "a column".to_string(),
1112                        |column| format!("\"{}\"", column.name),
1113                    );
1114                Err(Error::binder(format!(
1115                    "column {name} must appear in the GROUP BY clause or must be part of an aggregate function"
1116                )))
1117            }
1118            Expr::Constant(_) | Expr::Aggregate { .. } => Ok(expr),
1119            Expr::Cast { input, try_cast } => {
1120                let input = self.over_aggregate(input, scope)?;
1121                Ok(self.plan.add_expr(Expr::Cast { input, try_cast }, ty))
1122            }
1123            Expr::Compare { op, left, right } => {
1124                let left = self.over_aggregate(left, scope)?;
1125                let right = self.over_aggregate(right, scope)?;
1126                Ok(self.plan.add_expr(Expr::Compare { op, left, right }, ty))
1127            }
1128            Expr::Conjunction { op, children } => {
1129                let written = self.plan.expr_list(children).to_vec();
1130                let mut rewritten = Vec::with_capacity(written.len());
1131                for child in written {
1132                    rewritten.push(self.over_aggregate(child, scope)?);
1133                }
1134                let children = self.plan.add_expr_list(&rewritten);
1135                Ok(self.plan.add_expr(Expr::Conjunction { op, children }, ty))
1136            }
1137            Expr::Function { name, args } => {
1138                let written = self.plan.expr_list(args).to_vec();
1139                let mut rewritten = Vec::with_capacity(written.len());
1140                for arg in written {
1141                    rewritten.push(self.over_aggregate(arg, scope)?);
1142                }
1143                let args = self.plan.add_expr_list(&rewritten);
1144                Ok(self.plan.add_expr(Expr::Function { name, args }, ty))
1145            }
1146            Expr::Case { arms, otherwise } => {
1147                let written = self.plan.arm_list(arms).to_vec();
1148                let mut rewritten = Vec::with_capacity(written.len());
1149                for arm in written {
1150                    let when = self.over_aggregate(arm.when, scope)?;
1151                    let then = self.over_aggregate(arm.then, scope)?;
1152                    rewritten.push(rudb_plan::Arm { when, then });
1153                }
1154                let otherwise = match otherwise {
1155                    Some(expr) => Some(self.over_aggregate(expr, scope)?),
1156                    None => None,
1157                };
1158                let arms = self.plan.add_arms(&rewritten);
1159                Ok(self.plan.add_expr(Expr::Case { arms, otherwise }, ty))
1160            }
1161        }
1162    }
1163
1164    /// Whether two bound expressions are the same expression, by shape rather than by reference.
1165    pub(crate) fn same_expr(&self, left: ExprRef, right: ExprRef) -> bool {
1166        same_expr(&self.plan, left, right)
1167    }
1168}
1169
1170/// A sort key with SQL's defaults filled in.
1171///
1172/// Unstated is ascending, and unstated nulls go where the direction puts them, which is last for
1173/// ascending and first for descending. That is DuckDB's rule and it is the one that makes
1174/// `ORDER BY x DESC` the exact reverse of `ORDER BY x`.
1175fn sort_key(expr: ExprRef, item: ast::OrderItem) -> SortKey {
1176    let descending = item.order == Order::Descending;
1177    let nulls_first = match item.nulls {
1178        Nulls::First => true,
1179        Nulls::Last => false,
1180        Nulls::Unstated => descending,
1181    };
1182    SortKey { expr, descending, nulls_first }
1183}
1184
1185/// Structural equality over two expressions of one plan.
1186fn same_expr(plan: &Plan, left: ExprRef, right: ExprRef) -> bool {
1187    if left == right {
1188        return true;
1189    }
1190    if plan.expr_type(left) != plan.expr_type(right) {
1191        return false;
1192    }
1193    let lists = |left, right| {
1194        let left: &[ExprRef] = plan.expr_list(left);
1195        let right: &[ExprRef] = plan.expr_list(right);
1196        left.len() == right.len()
1197            && left.iter().zip(right).all(|(&left, &right)| same_expr(plan, left, right))
1198    };
1199    match (plan.expr(left), plan.expr(right)) {
1200        (Expr::Column(left), Expr::Column(right)) => left == right,
1201        (Expr::Constant(left), Expr::Constant(right)) => plan.value(*left) == plan.value(*right),
1202        (
1203            Expr::Cast { input: left, try_cast: left_try },
1204            Expr::Cast { input: right, try_cast: right_try },
1205        ) => left_try == right_try && same_expr(plan, *left, *right),
1206        (
1207            Expr::Compare { op: left_op, left: left_a, right: left_b },
1208            Expr::Compare { op: right_op, left: right_a, right: right_b },
1209        ) => {
1210            left_op == right_op
1211                && same_expr(plan, *left_a, *right_a)
1212                && same_expr(plan, *left_b, *right_b)
1213        }
1214        (
1215            Expr::Conjunction { op: left_op, children: left_children },
1216            Expr::Conjunction { op: right_op, children: right_children },
1217        ) => left_op == right_op && lists(*left_children, *right_children),
1218        (
1219            Expr::Function { name: left_name, args: left_args },
1220            Expr::Function { name: right_name, args: right_args },
1221        ) => plan.string(*left_name) == plan.string(*right_name) && lists(*left_args, *right_args),
1222        (
1223            Expr::Aggregate {
1224                name: left_name,
1225                args: left_args,
1226                distinct: left_distinct,
1227                filter: left_filter,
1228            },
1229            Expr::Aggregate {
1230                name: right_name,
1231                args: right_args,
1232                distinct: right_distinct,
1233                filter: right_filter,
1234            },
1235        ) => {
1236            plan.string(*left_name) == plan.string(*right_name)
1237                && left_distinct == right_distinct
1238                && match (left_filter, right_filter) {
1239                    (None, None) => true,
1240                    (Some(left), Some(right)) => same_expr(plan, *left, *right),
1241                    _ => false,
1242                }
1243                && lists(*left_args, *right_args)
1244        }
1245        (
1246            Expr::Case { arms: left_arms, otherwise: left_otherwise },
1247            Expr::Case { arms: right_arms, otherwise: right_otherwise },
1248        ) => {
1249            let left_arms = plan.arm_list(*left_arms);
1250            let right_arms = plan.arm_list(*right_arms);
1251            left_arms.len() == right_arms.len()
1252                && left_arms.iter().zip(right_arms).all(|(left, right)| {
1253                    same_expr(plan, left.when, right.when) && same_expr(plan, left.then, right.then)
1254                })
1255                && match (left_otherwise, right_otherwise) {
1256                    (None, None) => true,
1257                    (Some(left), Some(right)) => same_expr(plan, *left, *right),
1258                    _ => false,
1259                }
1260        }
1261        _ => false,
1262    }
1263}