Skip to main content

inillucent_sql/
ast.rs

1//! The arena-backed abstract syntax tree.
2//!
3//! Invariant: a node is an index into an arena, never a box, so an adversarial
4//! nesting depth costs one vector push per node and a walker can be iterative.
5//! Every node carries the span it was parsed from, and no node has been
6//! normalised: `NOT IN`, `IS NOT DISTINCT FROM` and an implicit alias are all
7//! distinct nodes rather than reconstructions, because a diagnostic that has to
8//! guess what the user wrote points at the wrong place.
9//!
10//! Identifiers are interned once per parse. The interned form keeps the
11//! original spelling *and* an ASCII-folded lookup key, because SQL name
12//! resolution is case-insensitive while `sqlite_schema` records the spelling
13//! the user chose.
14
15use crate::lexer::{QuoteForm, Span};
16
17/// An identifier, interned per parse.
18#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub struct NameId(pub u32);
20
21/// An expression node.
22#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
23pub struct ExprId(pub u32);
24
25/// A compound SELECT.
26#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
27pub struct SelectId(pub u32);
28
29/// One arm of a compound SELECT.
30#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
31pub struct SelectCoreId(pub u32);
32
33/// A FROM term.
34#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
35pub struct FromTermId(pub u32);
36
37/// A window definition.
38#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
39pub struct WindowId(pub u32);
40
41/// An interned identifier: what was written and what it matches.
42#[derive(Clone, Debug, PartialEq, Eq)]
43pub struct Name {
44    /// The identifier exactly as written, with quoting removed.
45    pub text: Vec<u8>,
46    /// The ASCII-folded key names are compared by.
47    pub folded: Vec<u8>,
48    /// How it was quoted, which decides whether it may become a string.
49    pub quote: QuoteForm,
50    /// Where it came from.
51    pub span: Span,
52}
53
54impl Name {
55    /// Returns the written spelling as text, for diagnostics and schema SQL.
56    pub fn as_str(&self) -> &str {
57        core::str::from_utf8(&self.text).unwrap_or("")
58    }
59}
60
61/// A literal value, kept as the bytes it was written as.
62#[derive(Clone, Debug, PartialEq, Eq)]
63pub enum Literal {
64    /// `NULL`.
65    Null,
66    /// `TRUE` or `FALSE`, which SQLite treats as 1 and 0.
67    Boolean(bool),
68    /// An integer literal, as written.
69    Integer(Vec<u8>),
70    /// A floating-point literal, as written.
71    Float(Vec<u8>),
72    /// A string literal, unescaped.
73    String(Vec<u8>),
74    /// A blob literal, decoded.
75    Blob(Vec<u8>),
76    /// `CURRENT_DATE`, `CURRENT_TIME` or `CURRENT_TIMESTAMP`.
77    CurrentDate,
78    /// `CURRENT_TIME`.
79    CurrentTime,
80    /// `CURRENT_TIMESTAMP`.
81    CurrentTimestamp,
82}
83
84/// A unary operator.
85#[derive(Clone, Copy, Debug, PartialEq, Eq)]
86pub enum UnaryOp {
87    /// `-x`
88    Negate,
89    /// `+x`, which SQLite keeps as a no-op that still forces evaluation.
90    Identity,
91    /// `~x`
92    BitNot,
93    /// `NOT x`
94    Not,
95}
96
97/// A binary operator.
98#[derive(Clone, Copy, Debug, PartialEq, Eq)]
99pub enum BinaryOp {
100    /// `OR`
101    Or,
102    /// `AND`
103    And,
104    /// `=`
105    Equal,
106    /// `<>`
107    NotEqual,
108    /// `<`
109    Less,
110    /// `<=`
111    LessEqual,
112    /// `>`
113    Greater,
114    /// `>=`
115    GreaterEqual,
116    /// `+`
117    Add,
118    /// `-`
119    Subtract,
120    /// `*`
121    Multiply,
122    /// `/`
123    Divide,
124    /// `%`
125    Modulo,
126    /// `||`
127    Concat,
128    /// `&`
129    BitAnd,
130    /// `|`
131    BitOr,
132    /// `<<`
133    ShiftLeft,
134    /// `>>`
135    ShiftRight,
136    /// `->`
137    Extract,
138    /// `->>`
139    ExtractText,
140    /// `MATCH`
141    Match,
142    /// `REGEXP`
143    Regexp,
144    /// `<->`
145    L2Distance,
146    /// `<=>`
147    CosineDistance,
148    /// `<#>`
149    NegativeInnerProduct,
150    /// `<+>`
151    L1Distance,
152    /// `<~>`
153    HammingDistance,
154    /// `<%>`
155    JaccardDistance,
156}
157
158/// Which pattern operator was written.
159#[derive(Clone, Copy, Debug, PartialEq, Eq)]
160pub enum PatternOp {
161    /// `LIKE`
162    Like,
163    /// `GLOB`
164    Glob,
165    /// `REGEXP`
166    Regexp,
167    /// `MATCH`
168    Match,
169}
170
171/// The right-hand side of `IN`.
172#[derive(Clone, Debug, PartialEq, Eq)]
173pub enum InRhs {
174    /// `IN (1, 2, 3)`, including the empty list.
175    List(Vec<ExprId>),
176    /// `IN (SELECT ...)`.
177    Select(SelectId),
178    /// `IN table` or `IN schema.table`.
179    Table {
180        /// The schema qualifier, when written.
181        database: Option<NameId>,
182        /// The table or table-valued function name.
183        table: NameId,
184        /// Arguments, when the name is a table-valued function.
185        arguments: Option<Vec<ExprId>>,
186    },
187}
188
189/// A `RAISE()` action inside a trigger body.
190#[derive(Clone, Copy, Debug, PartialEq, Eq)]
191pub enum RaiseAction {
192    /// `RAISE(IGNORE)`
193    Ignore,
194    /// `RAISE(ROLLBACK, msg)`
195    Rollback,
196    /// `RAISE(ABORT, msg)`
197    Abort,
198    /// `RAISE(FAIL, msg)`
199    Fail,
200}
201
202/// An expression, in the shape it was written.
203#[derive(Clone, Debug, PartialEq, Eq)]
204pub enum Expr {
205    /// A literal.
206    Literal(Literal),
207    /// A bound parameter.
208    Parameter {
209        /// The one-based parameter index assigned at parse time.
210        index: u32,
211        /// The written name, for `:name` style parameters.
212        name: Option<NameId>,
213    },
214    /// A column reference, with as much qualification as was written.
215    Column {
216        /// The schema qualifier.
217        database: Option<NameId>,
218        /// The table qualifier or alias.
219        table: Option<NameId>,
220        /// The column name.
221        column: NameId,
222    },
223    /// `*` or `table.*`, legal only where the grammar allows it.
224    Star {
225        /// The table qualifier, when written.
226        table: Option<NameId>,
227    },
228    /// A unary operator applied to one operand.
229    Unary {
230        /// Which operator.
231        op: UnaryOp,
232        /// The operand.
233        operand: ExprId,
234    },
235    /// A binary operator applied to two operands.
236    Binary {
237        /// Which operator.
238        op: BinaryOp,
239        /// The left operand.
240        left: ExprId,
241        /// The right operand.
242        right: ExprId,
243    },
244    /// `expr COLLATE name`.
245    Collate {
246        /// The operand.
247        operand: ExprId,
248        /// The collation name.
249        collation: NameId,
250    },
251    /// `CAST(expr AS type)`.
252    Cast {
253        /// The operand.
254        operand: ExprId,
255        /// The declared type, as written.
256        declared: NameId,
257    },
258    /// `expr [NOT] LIKE|GLOB|REGEXP|MATCH pattern [ESCAPE expr]`.
259    Pattern {
260        /// Whether `NOT` was written.
261        negated: bool,
262        /// Which operator.
263        op: PatternOp,
264        /// The value being matched.
265        operand: ExprId,
266        /// The pattern.
267        pattern: ExprId,
268        /// The `ESCAPE` argument, when written.
269        escape: Option<ExprId>,
270    },
271    /// `expr [NOT] BETWEEN low AND high`.
272    Between {
273        /// Whether `NOT` was written.
274        negated: bool,
275        /// The value being tested.
276        operand: ExprId,
277        /// The lower bound.
278        low: ExprId,
279        /// The upper bound.
280        high: ExprId,
281    },
282    /// `expr [NOT] IN rhs`.
283    In {
284        /// Whether `NOT` was written.
285        negated: bool,
286        /// The value being tested.
287        operand: ExprId,
288        /// What it is tested against.
289        rhs: InRhs,
290    },
291    /// `expr ISNULL` / `expr NOTNULL` / `expr IS [NOT] NULL`.
292    IsNull {
293        /// Whether the test is for not-null.
294        negated: bool,
295        /// The operand.
296        operand: ExprId,
297    },
298    /// `left IS [NOT] [DISTINCT FROM] right`.
299    Is {
300        /// Whether `NOT` was written.
301        negated: bool,
302        /// Whether the `DISTINCT FROM` spelling was used.
303        distinct_from: bool,
304        /// The left operand.
305        left: ExprId,
306        /// The right operand.
307        right: ExprId,
308    },
309    /// `CASE [operand] WHEN ... THEN ... [ELSE ...] END`.
310    Case {
311        /// The base operand, when the form has one.
312        operand: Option<ExprId>,
313        /// The `WHEN`/`THEN` pairs, in written order.
314        branches: Vec<(ExprId, ExprId)>,
315        /// The `ELSE` arm.
316        otherwise: Option<ExprId>,
317    },
318    /// A function call, aggregate or scalar or window.
319    Function {
320        /// The function name.
321        name: NameId,
322        /// Whether `DISTINCT` was written.
323        distinct: bool,
324        /// The arguments, or `None` for `count(*)`.
325        arguments: Option<Vec<ExprId>>,
326        /// An `ORDER BY` inside the argument list.
327        order_by: Vec<OrderTerm>,
328        /// A `FILTER (WHERE ...)` clause.
329        filter: Option<ExprId>,
330        /// An `OVER` clause.
331        over: Option<WindowId>,
332    },
333    /// `[NOT] EXISTS (SELECT ...)`.
334    Exists {
335        /// Whether `NOT` was written.
336        negated: bool,
337        /// The subquery.
338        select: SelectId,
339    },
340    /// A scalar subquery.
341    Subquery(SelectId),
342    /// A parenthesised list of two or more expressions.
343    RowValue(Vec<ExprId>),
344    /// `RAISE(...)`, legal only inside a trigger body.
345    Raise {
346        /// Which action.
347        action: RaiseAction,
348        /// The message, when the action takes one.
349        ///
350        /// An expression, as SQLite takes it: `RAISE(ABORT, 'too big: ' ||
351        /// NEW.n)` names the value that broke the rule, which is the reason to
352        /// write a guard trigger at all. It used to be a string literal only,
353        /// and anything else was a syntax error pointing at the `||`.
354        message: Option<ExprId>,
355    },
356}
357
358/// Ascending or descending.
359#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
360pub enum SortOrder {
361    /// `ASC`, the default.
362    #[default]
363    Ascending,
364    /// `DESC`.
365    Descending,
366}
367
368/// Where NULLs sort, when written explicitly.
369#[derive(Clone, Copy, Debug, PartialEq, Eq)]
370pub enum NullOrder {
371    /// `NULLS FIRST`.
372    First,
373    /// `NULLS LAST`.
374    Last,
375}
376
377/// One term of an `ORDER BY`.
378#[derive(Clone, Copy, Debug, PartialEq, Eq)]
379pub struct OrderTerm {
380    /// The expression, which may be an ordinal or an alias.
381    pub expr: ExprId,
382    /// The written or defaulted direction.
383    pub order: SortOrder,
384    /// The written null ordering, when there was one.
385    pub nulls: Option<NullOrder>,
386}
387
388/// One result column of a SELECT.
389#[derive(Clone, Debug, PartialEq, Eq)]
390pub struct ResultColumn {
391    /// The expression, which may be `*` or `table.*`.
392    pub expr: ExprId,
393    /// The alias, when one was written.
394    pub alias: Option<NameId>,
395    /// Whether the alias was written with `AS`.
396    pub alias_was_explicit: bool,
397    /// The span of the whole result column.
398    pub span: Span,
399}
400
401/// Which join was written.
402#[derive(Clone, Copy, Debug, PartialEq, Eq)]
403pub enum JoinKind {
404    /// A comma, which is a cross join that may still be reordered.
405    Comma,
406    /// `[INNER] JOIN`.
407    Inner,
408    /// `CROSS JOIN`, which SQLite refuses to reorder.
409    Cross,
410    /// `LEFT [OUTER] JOIN`.
411    Left,
412    /// `RIGHT [OUTER] JOIN`.
413    Right,
414    /// `FULL [OUTER] JOIN`.
415    Full,
416}
417
418/// The `ON` or `USING` constraint of a join.
419#[derive(Clone, Debug, PartialEq, Eq)]
420pub enum JoinConstraint {
421    /// No constraint was written.
422    None,
423    /// `ON expr`.
424    On(ExprId),
425    /// `USING (a, b)`.
426    Using(Vec<NameId>),
427}
428
429/// How a FROM term names its rows.
430#[derive(Clone, Debug, PartialEq, Eq)]
431pub enum FromSource {
432    /// A table, view or table-valued function.
433    Table {
434        /// The schema qualifier.
435        database: Option<NameId>,
436        /// The object name.
437        name: NameId,
438        /// Arguments, when it is a table-valued function.
439        arguments: Option<Vec<ExprId>>,
440        /// `INDEXED BY name`, or `NOT INDEXED`.
441        indexed_by: IndexHint,
442    },
443    /// A subquery.
444    Subquery(SelectId),
445    /// A parenthesised join, which is one term to whatever contains it.
446    Join(Vec<FromTermId>),
447}
448
449/// An `INDEXED BY` hint.
450#[derive(Clone, Copy, Debug, PartialEq, Eq)]
451pub enum IndexHint {
452    /// Nothing was written.
453    None,
454    /// `NOT INDEXED`.
455    NotIndexed,
456    /// `INDEXED BY name`.
457    IndexedBy(NameId),
458}
459
460/// One term of a FROM clause, with the join that attached it.
461#[derive(Clone, Debug, PartialEq, Eq)]
462pub struct FromTerm {
463    /// Where the rows come from.
464    pub source: FromSource,
465    /// The alias, when one was written.
466    pub alias: Option<NameId>,
467    /// The join that attaches this term to the one before it.
468    pub join: JoinKind,
469    /// Whether `NATURAL` was written.
470    pub natural: bool,
471    /// The `ON` or `USING` constraint.
472    pub constraint: JoinConstraint,
473    /// The span of the whole term.
474    pub span: Span,
475}
476
477/// A window frame's unit.
478#[derive(Clone, Copy, Debug, PartialEq, Eq)]
479pub enum FrameUnit {
480    /// `ROWS`.
481    Rows,
482    /// `RANGE`.
483    Range,
484    /// `GROUPS`.
485    Groups,
486}
487
488/// One end of a window frame.
489#[derive(Clone, Copy, Debug, PartialEq, Eq)]
490pub enum FrameBound {
491    /// `UNBOUNDED PRECEDING`.
492    UnboundedPreceding,
493    /// `expr PRECEDING`.
494    Preceding(ExprId),
495    /// `CURRENT ROW`.
496    CurrentRow,
497    /// `expr FOLLOWING`.
498    Following(ExprId),
499    /// `UNBOUNDED FOLLOWING`.
500    UnboundedFollowing,
501}
502
503/// A frame's `EXCLUDE` clause.
504#[derive(Clone, Copy, Debug, PartialEq, Eq)]
505pub enum FrameExclude {
506    /// `EXCLUDE NO OTHERS`, the default.
507    NoOthers,
508    /// `EXCLUDE CURRENT ROW`.
509    CurrentRow,
510    /// `EXCLUDE GROUP`.
511    Group,
512    /// `EXCLUDE TIES`.
513    Ties,
514}
515
516/// A window definition, named or inline.
517#[derive(Clone, Debug, PartialEq, Eq)]
518pub struct Window {
519    /// The window this one inherits from, when written.
520    pub base: Option<NameId>,
521    /// `PARTITION BY`.
522    pub partition_by: Vec<ExprId>,
523    /// `ORDER BY`.
524    pub order_by: Vec<OrderTerm>,
525    /// The frame unit, when a frame was written.
526    pub unit: Option<FrameUnit>,
527    /// The frame start.
528    pub start: Option<FrameBound>,
529    /// The frame end.
530    pub end: Option<FrameBound>,
531    /// The `EXCLUDE` clause.
532    pub exclude: FrameExclude,
533    /// The span of the definition.
534    pub span: Span,
535    /// Whether this is `OVER name` with no parentheses.
536    ///
537    /// SQLite accepts that form for a window that has a frame, and refuses
538    /// `OVER (name)`, so the two have to be told apart.
539    pub bare_name: bool,
540}
541
542/// The rows of one arm of a compound SELECT.
543#[derive(Clone, Debug, PartialEq, Eq)]
544pub enum SelectBody {
545    /// `SELECT ...`.
546    Select {
547        /// Whether `DISTINCT` was written.
548        distinct: bool,
549        /// Whether `ALL` was written.
550        all: bool,
551        /// The result columns.
552        columns: Vec<ResultColumn>,
553        /// The FROM terms, in written order.
554        from: Vec<FromTermId>,
555        /// The WHERE clause.
556        filter: Option<ExprId>,
557        /// The GROUP BY terms.
558        group_by: Vec<ExprId>,
559        /// The HAVING clause.
560        having: Option<ExprId>,
561        /// Named windows.
562        windows: Vec<(NameId, WindowId)>,
563    },
564    /// `VALUES (...), (...)`.
565    Values(Vec<Vec<ExprId>>),
566}
567
568/// One arm of a compound SELECT.
569#[derive(Clone, Debug, PartialEq, Eq)]
570pub struct SelectCore {
571    /// What the arm produces.
572    pub body: SelectBody,
573    /// The span of the arm.
574    pub span: Span,
575}
576
577/// A compound operator.
578#[derive(Clone, Copy, Debug, PartialEq, Eq)]
579pub enum CompoundOp {
580    /// `UNION`.
581    Union,
582    /// `UNION ALL`.
583    UnionAll,
584    /// `INTERSECT`.
585    Intersect,
586    /// `EXCEPT`.
587    Except,
588}
589
590/// A common table expression.
591#[derive(Clone, Debug, PartialEq, Eq)]
592pub struct CommonTableExpr {
593    /// The name it is bound to.
594    pub name: NameId,
595    /// The explicit column list, when written.
596    pub columns: Vec<NameId>,
597    /// `MATERIALIZED` or `NOT MATERIALIZED`, when written.
598    pub materialized: Option<bool>,
599    /// The query.
600    pub select: SelectId,
601}
602
603/// A `WITH` prefix.
604#[derive(Clone, Debug, PartialEq, Eq, Default)]
605pub struct With {
606    /// Whether `RECURSIVE` was written.
607    pub recursive: bool,
608    /// The CTEs, in written order.
609    pub ctes: Vec<CommonTableExpr>,
610}
611
612/// A complete SELECT: a `WITH` prefix, compound arms, and the tail clauses.
613#[derive(Clone, Debug, PartialEq, Eq)]
614pub struct Select {
615    /// The `WITH` prefix.
616    pub with: With,
617    /// The first arm.
618    pub first: SelectCoreId,
619    /// Later arms, each with the operator that joined it.
620    pub compounds: Vec<(CompoundOp, SelectCoreId)>,
621    /// The `ORDER BY`, which belongs to the whole compound.
622    pub order_by: Vec<OrderTerm>,
623    /// The `LIMIT` expression.
624    pub limit: Option<ExprId>,
625    /// The `OFFSET` expression.
626    pub offset: Option<ExprId>,
627    /// The span of the whole statement.
628    pub span: Span,
629    /// Whether the parser built this select for a parenthesised join of several
630    /// terms, which SQLite treats as a subquery whose inner table names stay
631    /// visible to the enclosing query.
632    pub nested_from: bool,
633}
634
635/// A conflict-resolution algorithm.
636#[derive(Clone, Copy, Debug, PartialEq, Eq)]
637pub enum ConflictAction {
638    /// `ROLLBACK`.
639    Rollback,
640    /// `ABORT`, the default.
641    Abort,
642    /// `FAIL`.
643    Fail,
644    /// `IGNORE`.
645    Ignore,
646    /// `REPLACE`.
647    Replace,
648}
649
650/// A column constraint, in written order.
651#[derive(Clone, Debug, PartialEq, Eq)]
652pub enum ColumnConstraint {
653    /// `PRIMARY KEY [ASC|DESC] [conflict] [AUTOINCREMENT]`.
654    PrimaryKey {
655        /// The written direction.
656        order: SortOrder,
657        /// The conflict clause.
658        on_conflict: Option<ConflictAction>,
659        /// Whether `AUTOINCREMENT` was written.
660        autoincrement: bool,
661    },
662    /// `NOT NULL [conflict]`.
663    NotNull(Option<ConflictAction>),
664    /// `NULL`, which SQLite accepts and ignores.
665    Null,
666    /// `UNIQUE [conflict]`.
667    Unique(Option<ConflictAction>),
668    /// `CHECK (expr)`.
669    ///
670    /// **No conflict clause**, which is SQLite's grammar and not an omission:
671    /// `ccons ::= CHECK LP expr RP` has no `onconf`, so
672    /// `b INTEGER CHECK(b < 9) ON CONFLICT IGNORE` is a syntax error there and
673    /// has to be one here. Only a *table*-level `CHECK` takes the clause - see
674    /// [`TableConstraint::Check`].
675    Check(ExprId),
676    /// `DEFAULT expr`.
677    Default(ExprId),
678    /// `COLLATE name`.
679    Collate(NameId),
680    /// `REFERENCES ...`.
681    References(ForeignKeyClause),
682    /// `GENERATED ALWAYS AS (expr) [STORED|VIRTUAL]`.
683    Generated {
684        /// The generating expression.
685        expr: ExprId,
686        /// Whether `STORED` was written.
687        stored: bool,
688        /// Whether some other word followed the closing parenthesis.
689        ///
690        /// SQLite's grammar takes any identifier there and checks it afterwards, so
691        /// `b AS (a) WAT` is `error in generated column "b"` and not a syntax error.
692        bad_storage: bool,
693    },
694}
695
696/// A foreign-key clause, on a column or on a table.
697#[derive(Clone, Debug, PartialEq, Eq)]
698pub struct ForeignKeyClause {
699    /// The parent table.
700    pub table: NameId,
701    /// The parent columns, when written.
702    pub columns: Vec<NameId>,
703    /// The `ON DELETE`/`ON UPDATE`/`MATCH` clauses, as written.
704    pub actions: Vec<ForeignKeyAction>,
705    /// Whether the constraint is deferrable.
706    pub deferrable: Option<bool>,
707    /// Whether it is initially deferred.
708    pub initially_deferred: bool,
709}
710
711/// One `ON DELETE`, `ON UPDATE` or `MATCH` clause.
712#[derive(Clone, Copy, Debug, PartialEq, Eq)]
713pub enum ForeignKeyAction {
714    /// `ON DELETE <action>`.
715    OnDelete(ReferentialAction),
716    /// `ON UPDATE <action>`.
717    OnUpdate(ReferentialAction),
718    /// `MATCH name`.
719    Match(NameId),
720}
721
722/// What a referential action does.
723#[derive(Clone, Copy, Debug, PartialEq, Eq)]
724pub enum ReferentialAction {
725    /// `SET NULL`.
726    SetNull,
727    /// `SET DEFAULT`.
728    SetDefault,
729    /// `CASCADE`.
730    Cascade,
731    /// `RESTRICT`.
732    Restrict,
733    /// `NO ACTION`.
734    NoAction,
735}
736
737/// One column of a `CREATE TABLE`.
738#[derive(Clone, Debug, PartialEq, Eq)]
739pub struct ColumnDef {
740    /// The column name.
741    pub name: NameId,
742    /// The declared type, exactly as written, when there was one.
743    pub declared_type: Option<Vec<u8>>,
744    /// The constraints, in written order, each with its optional name.
745    pub constraints: Vec<(Option<NameId>, ColumnConstraint)>,
746    /// The span of the definition.
747    pub span: Span,
748    /// A reason SQLite refuses the definition only after it has changed the
749    /// schema, set when the definition is read for `ALTER TABLE ... ADD COLUMN`.
750    ///
751    /// For example `subqueries prohibited in CHECK constraints`. The failure is
752    /// reported when the statement runs, as SQLite reports it, and not when it
753    /// is compiled.
754    pub deferred_failure: Option<&'static str>,
755}
756
757/// One indexed column of a table constraint or an index.
758#[derive(Clone, Copy, Debug, PartialEq, Eq)]
759pub struct IndexedColumn {
760    /// The key expression, which may be a bare column.
761    pub expr: ExprId,
762    /// An explicit collation.
763    pub collation: Option<NameId>,
764    /// The direction.
765    pub order: SortOrder,
766    /// `NULLS FIRST` or `NULLS LAST`, which SQLite parses here and then refuses.
767    pub nulls: Option<NullOrder>,
768}
769
770/// A table-level constraint.
771#[derive(Clone, Debug, PartialEq, Eq)]
772pub enum TableConstraint {
773    /// `PRIMARY KEY (...)`.
774    PrimaryKey {
775        /// The key columns.
776        columns: Vec<IndexedColumn>,
777        /// The conflict clause.
778        on_conflict: Option<ConflictAction>,
779        /// Whether `AUTOINCREMENT` was written.
780        autoincrement: bool,
781    },
782    /// `UNIQUE (...)`.
783    Unique {
784        /// The key columns.
785        columns: Vec<IndexedColumn>,
786        /// The conflict clause.
787        on_conflict: Option<ConflictAction>,
788    },
789    /// `CHECK (expr) [conflict]`.
790    ///
791    /// **Parsed and then ignored, which is what SQLite does with it.**
792    /// `tcons ::= CHECK LP expr RP onconf` accepts the clause and
793    /// `sqlite3AddCheckConstraint` never reads it, so
794    /// `CONSTRAINT small CHECK(b < 9) ON CONFLICT FAIL` behaves exactly as
795    /// `ABORT`: measured against the pinned 3.53.4, an `INSERT` of three rows
796    /// whose second fails keeps none of them.
797    ///
798    /// It is in the tree rather than discarded at the token because the table's
799    /// `CREATE` text is stored and re-parsed on every open, so the grammar has
800    /// to accept everything the text can hold. Not accepting it did not cost
801    /// one statement a clause - it made the `CREATE TABLE` a parse error, and
802    /// every statement after it said `no such table`.
803    Check {
804        /// The predicate.
805        expr: ExprId,
806        /// The conflict clause, accepted and not acted on.
807        on_conflict: Option<ConflictAction>,
808    },
809    /// `FOREIGN KEY (...) REFERENCES ...`.
810    ForeignKey {
811        /// The child columns.
812        columns: Vec<NameId>,
813        /// The parent reference.
814        clause: ForeignKeyClause,
815    },
816}
817
818/// The body of a `CREATE TABLE`.
819#[derive(Clone, Debug, PartialEq, Eq)]
820pub enum CreateTableBody {
821    /// A column list.
822    Columns {
823        /// The columns, in written order.
824        columns: Vec<ColumnDef>,
825        /// The table constraints, in written order, each with its name.
826        constraints: Vec<(Option<NameId>, TableConstraint)>,
827        /// Whether `WITHOUT ROWID` was written.
828        without_rowid: bool,
829        /// Whether `STRICT` was written.
830        strict: bool,
831    },
832    /// `CREATE TABLE ... AS SELECT ...`.
833    AsSelect(SelectId),
834}
835
836/// An `UPSERT` clause.
837#[derive(Clone, Debug, PartialEq, Eq)]
838pub struct Upsert {
839    /// The conflict target columns, when written.
840    pub target: Vec<IndexedColumn>,
841    /// The conflict target's `WHERE`.
842    pub target_filter: Option<ExprId>,
843    /// The `DO UPDATE SET` assignments, empty for `DO NOTHING`.
844    pub assignments: Vec<(Vec<NameId>, ExprId)>,
845    /// Whether the action is `DO UPDATE`.
846    pub do_update: bool,
847    /// The `DO UPDATE`'s `WHERE`.
848    pub filter: Option<ExprId>,
849}
850
851/// What an INSERT inserts.
852#[derive(Clone, Debug, PartialEq, Eq)]
853pub enum InsertSource {
854    /// `VALUES`, or any SELECT.
855    Select(SelectId),
856    /// `DEFAULT VALUES`.
857    DefaultValues,
858}
859
860/// An `INSERT` statement.
861#[derive(Clone, Debug, PartialEq, Eq)]
862pub struct Insert {
863    /// The `WITH` prefix.
864    pub with: With,
865    /// The conflict algorithm from `INSERT OR ...` or `REPLACE`.
866    pub on_conflict: Option<ConflictAction>,
867    /// The schema qualifier.
868    pub database: Option<NameId>,
869    /// The target table.
870    pub table: NameId,
871    /// The table alias.
872    pub alias: Option<NameId>,
873    /// The column list, when written.
874    pub columns: Vec<NameId>,
875    /// The rows.
876    pub source: InsertSource,
877    /// The `ON CONFLICT` clauses, in written order.
878    pub upserts: Vec<Upsert>,
879    /// The `RETURNING` columns.
880    pub returning: Vec<ResultColumn>,
881}
882
883/// An `UPDATE` statement.
884#[derive(Clone, Debug, PartialEq, Eq)]
885pub struct Update {
886    /// The `WITH` prefix.
887    pub with: With,
888    /// The conflict algorithm from `UPDATE OR ...`.
889    pub on_conflict: Option<ConflictAction>,
890    /// The target term, which carries its own alias and index hint.
891    pub target: FromTermId,
892    /// The `SET` assignments; a group of names is the `(a, b) = ...` form.
893    pub assignments: Vec<(Vec<NameId>, ExprId)>,
894    /// An `UPDATE ... FROM` clause.
895    pub from: Vec<FromTermId>,
896    /// The `WHERE` clause.
897    pub filter: Option<ExprId>,
898    /// The `RETURNING` columns.
899    pub returning: Vec<ResultColumn>,
900    /// The `ORDER BY`, which SQLite allows with `LIMIT`.
901    pub order_by: Vec<OrderTerm>,
902    /// The `LIMIT`.
903    pub limit: Option<ExprId>,
904    /// The `OFFSET`.
905    pub offset: Option<ExprId>,
906    /// Where the clause the reference build has no grammar for was written.
907    ///
908    /// `ORDER BY` and `LIMIT` on a `DELETE` or an `UPDATE` are a compile-time
909    /// option in SQLite, and the pinned build is not compiled with it - so the
910    /// reference answers `near "ORDER": syntax error` and points at the word.
911    /// The syntax register requires these to *parse* here, so the refusal is
912    /// the binder's; it needs the position to be able to point at the same
913    /// word, and this is where the parser leaves it.
914    pub limited_at: Option<(Limited, crate::lexer::Span)>,
915}
916
917/// Which of the two words a limited `DELETE` or `UPDATE` was written with.
918///
919/// The reference names the first one it cannot parse, so a statement carrying
920/// both reports `ORDER` and one carrying only a `LIMIT` reports `LIMIT`.
921#[derive(Clone, Copy, Debug, PartialEq, Eq)]
922pub enum Limited {
923    /// `ORDER BY`.
924    OrderBy,
925    /// `LIMIT`.
926    Limit,
927}
928
929impl Limited {
930    /// Returns the word the refusal quotes.
931    pub fn word(self) -> &'static str {
932        match self {
933            Limited::OrderBy => "ORDER",
934            Limited::Limit => "LIMIT",
935        }
936    }
937}
938
939/// A `DELETE` statement.
940#[derive(Clone, Debug, PartialEq, Eq)]
941pub struct Delete {
942    /// The `WITH` prefix.
943    pub with: With,
944    /// The target term.
945    pub target: FromTermId,
946    /// The `WHERE` clause.
947    pub filter: Option<ExprId>,
948    /// The `RETURNING` columns.
949    pub returning: Vec<ResultColumn>,
950    /// The `ORDER BY`.
951    pub order_by: Vec<OrderTerm>,
952    /// The `LIMIT`.
953    pub limit: Option<ExprId>,
954    /// The `OFFSET`.
955    pub offset: Option<ExprId>,
956    /// Where the clause the reference build has no grammar for was written.
957    ///
958    /// `ORDER BY` and `LIMIT` on a `DELETE` or an `UPDATE` are a compile-time
959    /// option in SQLite, and the pinned build is not compiled with it - so the
960    /// reference answers `near "ORDER": syntax error` and points at the word.
961    /// The syntax register requires these to *parse* here, so the refusal is
962    /// the binder's; it needs the position to be able to point at the same
963    /// word, and this is where the parser leaves it.
964    pub limited_at: Option<(Limited, crate::lexer::Span)>,
965}
966
967/// Which kind of object a `DROP` names.
968#[derive(Clone, Copy, Debug, PartialEq, Eq)]
969pub enum ObjectKind {
970    /// A table.
971    Table,
972    /// An index.
973    Index,
974    /// A view.
975    View,
976    /// A trigger.
977    Trigger,
978}
979
980/// What an `ALTER TABLE` does.
981#[derive(Clone, Debug, PartialEq, Eq)]
982pub enum AlterAction {
983    /// `RENAME TO name`.
984    RenameTo(NameId),
985    /// `RENAME [COLUMN] a TO b`.
986    RenameColumn {
987        /// The current name.
988        from: NameId,
989        /// The new name.
990        to: NameId,
991    },
992    /// `ADD [COLUMN] def`.
993    AddColumn(ColumnDef),
994    /// `DROP [COLUMN] name`.
995    DropColumn(NameId),
996    /// `ALTER [COLUMN] name SET NOT NULL [ON CONFLICT action]`.
997    SetNotNull {
998        /// The column.
999        column: NameId,
1000        /// Where `NOT NULL` starts in the statement's own source.
1001        start: u32,
1002        /// Where the clause ends, after any `ON CONFLICT`.
1003        end: u32,
1004    },
1005    /// `ALTER [COLUMN] name DROP NOT NULL`.
1006    DropNotNull(NameId),
1007    /// `ADD [CONSTRAINT name] CHECK (expr) [ON CONFLICT action]`.
1008    AddCheck {
1009        /// The constraint's name, when one was written.
1010        name: Option<NameId>,
1011        /// The predicate.
1012        expr: ExprId,
1013        /// Where the constraint starts in the statement's own source.
1014        start: u32,
1015        /// Where it ends, after any `ON CONFLICT`.
1016        end: u32,
1017    },
1018    /// `DROP CONSTRAINT name`.
1019    DropConstraint(NameId),
1020}
1021
1022/// When a trigger fires.
1023#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1024pub enum TriggerTime {
1025    /// `BEFORE`.
1026    Before,
1027    /// `AFTER`.
1028    After,
1029    /// `INSTEAD OF`.
1030    InsteadOf,
1031}
1032
1033/// What a trigger fires on.
1034#[derive(Clone, Debug, PartialEq, Eq)]
1035pub enum TriggerEvent {
1036    /// `DELETE`.
1037    Delete,
1038    /// `INSERT`.
1039    Insert,
1040    /// `UPDATE [OF a, b]`.
1041    Update(Vec<NameId>),
1042}
1043
1044/// A `PRAGMA` argument.
1045#[derive(Clone, Debug, PartialEq, Eq)]
1046pub enum PragmaValue {
1047    /// Nothing was written.
1048    None,
1049    /// `= value` or `(value)`.
1050    Value(ExprId),
1051    /// `(name)`, which is a bare word rather than an expression.
1052    Name(NameId),
1053}
1054
1055/// A parsed statement.
1056#[derive(Clone, Debug, PartialEq, Eq)]
1057pub enum Statement {
1058    /// An empty statement, which SQLite compiles to nothing.
1059    Empty,
1060    /// `SELECT` or `VALUES`.
1061    Select(SelectId),
1062    /// `INSERT` or `REPLACE`.
1063    Insert(Box<Insert>),
1064    /// `UPDATE`.
1065    Update(Box<Update>),
1066    /// `DELETE`.
1067    Delete(Box<Delete>),
1068    /// `CREATE TABLE`.
1069    CreateTable {
1070        /// Whether `TEMP` was written.
1071        temporary: bool,
1072        /// Whether `IF NOT EXISTS` was written.
1073        if_not_exists: bool,
1074        /// The schema qualifier.
1075        database: Option<NameId>,
1076        /// The table name.
1077        name: NameId,
1078        /// The body.
1079        body: CreateTableBody,
1080    },
1081    /// `CREATE INDEX`.
1082    CreateIndex {
1083        /// Whether `UNIQUE` was written.
1084        unique: bool,
1085        /// Whether `IF NOT EXISTS` was written.
1086        if_not_exists: bool,
1087        /// The schema qualifier.
1088        database: Option<NameId>,
1089        /// The index name.
1090        name: NameId,
1091        /// The table it indexes.
1092        table: NameId,
1093        /// The module named by `USING`, when one was.
1094        ///
1095        /// SQLite has no `USING` on `CREATE INDEX`; PostgreSQL does, and it is
1096        /// how pgvector spells `USING hnsw`. This engine borrows the spelling
1097        /// for the same purpose: an index whose structure is not a b-tree.
1098        /// A plain `CREATE INDEX` leaves it `None` and nothing
1099        /// downstream changes.
1100        using: Option<NameId>,
1101        /// The key columns.
1102        columns: Vec<IndexedColumn>,
1103        /// The storage parameters `WITH ( ... )` named, as written.
1104        ///
1105        /// `m = 16`, `ef_construction = 64` and the rest: raw `name = value`
1106        /// slices, in the order they were written, for the structure named by
1107        /// `using` to read. Empty for a plain `CREATE INDEX`, which has no
1108        /// structure to read them.
1109        settings: Vec<Vec<u8>>,
1110        /// The partial-index predicate.
1111        filter: Option<ExprId>,
1112    },
1113    /// `CREATE VIEW`.
1114    CreateView {
1115        /// Whether `TEMP` was written.
1116        temporary: bool,
1117        /// Whether `IF NOT EXISTS` was written.
1118        if_not_exists: bool,
1119        /// The schema qualifier.
1120        database: Option<NameId>,
1121        /// The view name.
1122        name: NameId,
1123        /// The explicit column list.
1124        columns: Vec<NameId>,
1125        /// The query.
1126        select: SelectId,
1127    },
1128    /// `CREATE TRIGGER`.
1129    CreateTrigger {
1130        /// Whether `TEMP` was written.
1131        temporary: bool,
1132        /// Whether `IF NOT EXISTS` was written.
1133        if_not_exists: bool,
1134        /// The schema qualifier.
1135        database: Option<NameId>,
1136        /// The trigger name.
1137        name: NameId,
1138        /// When it fires.
1139        time: Option<TriggerTime>,
1140        /// What it fires on.
1141        event: TriggerEvent,
1142        /// The table it is attached to.
1143        table: NameId,
1144        /// The schema qualifier on the table, as in `ON main.t`.
1145        table_database: Option<NameId>,
1146        /// Whether `FOR EACH ROW` was written.
1147        for_each_row: bool,
1148        /// The `WHEN` guard.
1149        when: Option<ExprId>,
1150        /// The body statements, in written order.
1151        body: Vec<Statement>,
1152    },
1153    /// `CREATE VIRTUAL TABLE`.
1154    CreateVirtualTable {
1155        /// Whether `IF NOT EXISTS` was written.
1156        if_not_exists: bool,
1157        /// The schema qualifier.
1158        database: Option<NameId>,
1159        /// The table name.
1160        name: NameId,
1161        /// The module name.
1162        module: NameId,
1163        /// The module arguments, as written source slices.
1164        arguments: Vec<Vec<u8>>,
1165    },
1166    /// `DROP TABLE|INDEX|VIEW|TRIGGER`.
1167    Drop {
1168        /// Which kind of object.
1169        kind: ObjectKind,
1170        /// Whether `IF EXISTS` was written.
1171        if_exists: bool,
1172        /// The schema qualifier.
1173        database: Option<NameId>,
1174        /// The object name.
1175        name: NameId,
1176    },
1177    /// `ALTER TABLE`.
1178    AlterTable {
1179        /// The schema qualifier.
1180        database: Option<NameId>,
1181        /// The table name.
1182        table: NameId,
1183        /// What to do to it.
1184        action: AlterAction,
1185    },
1186    /// `BEGIN`.
1187    Begin {
1188        /// `DEFERRED`, `IMMEDIATE` or `EXCLUSIVE`, when written.
1189        behaviour: Option<TransactionBehaviour>,
1190    },
1191    /// `COMMIT` or `END`.
1192    Commit,
1193    /// `ROLLBACK [TO savepoint]`.
1194    Rollback {
1195        /// The savepoint to roll back to.
1196        savepoint: Option<NameId>,
1197    },
1198    /// `SAVEPOINT name`.
1199    Savepoint(NameId),
1200    /// `RELEASE [SAVEPOINT] name`.
1201    Release(NameId),
1202    /// `PRAGMA`.
1203    Pragma {
1204        /// The schema qualifier.
1205        database: Option<NameId>,
1206        /// The pragma name.
1207        name: NameId,
1208        /// The argument.
1209        value: PragmaValue,
1210    },
1211    /// `ATTACH`.
1212    Attach {
1213        /// The file expression.
1214        file: ExprId,
1215        /// The schema name expression.
1216        schema: ExprId,
1217        /// The `KEY` expression.
1218        key: Option<ExprId>,
1219    },
1220    /// `DETACH`.
1221    Detach {
1222        /// The schema name expression.
1223        schema: ExprId,
1224    },
1225    /// `VACUUM`.
1226    Vacuum {
1227        /// The schema to vacuum.
1228        database: Option<NameId>,
1229        /// The `INTO` target.
1230        into: Option<ExprId>,
1231    },
1232    /// `ANALYZE`.
1233    Analyze {
1234        /// The schema qualifier.
1235        database: Option<NameId>,
1236        /// The object to analyze.
1237        name: Option<NameId>,
1238    },
1239    /// `REINDEX`.
1240    Reindex {
1241        /// The schema qualifier.
1242        database: Option<NameId>,
1243        /// The collation, table or index to reindex.
1244        name: Option<NameId>,
1245    },
1246    /// `EXPLAIN` or `EXPLAIN QUERY PLAN`.
1247    Explain {
1248        /// Whether `QUERY PLAN` was written.
1249        query_plan: bool,
1250        /// The statement being explained.
1251        inner: Box<Statement>,
1252    },
1253}
1254
1255/// The behaviour of a `BEGIN`.
1256#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1257pub enum TransactionBehaviour {
1258    /// `DEFERRED`.
1259    Deferred,
1260    /// `IMMEDIATE`.
1261    Immediate,
1262    /// `EXCLUSIVE`.
1263    Exclusive,
1264}
1265
1266/// How many name buffers [`Ast::clear`] keeps for the next parse to fill.
1267///
1268/// **Because `clear` empties `names`, which drops each `Name`'s two `Vec<u8>`
1269/// (task-2039).** The arena keeps its *vectors'* capacity across a clear and
1270/// not its *entries'*, so a connection re-compiling the same statement paid
1271/// two allocations per distinct name for ever. A statement names a handful of
1272/// things, so a short list of buffers covers the repeating case; a statement
1273/// that names hundreds gives the surplus back to the allocator rather than
1274/// holding it on a connection that will never name that many again.
1275const SPARE_NAME_BUFFERS: usize = 64;
1276
1277/// How many names an arena searches one by one before it files them by hash.
1278///
1279/// A lookup in `Ast::interned` hashes the name with the arena's seeded hasher
1280/// and the map hashes that again, which cost more than comparing the name
1281/// against a dozen others. Past this many names the map is used, so the
1282/// parse of a statement with thousands of names stays linear (task-2185).
1283const LINEAR_NAMES: usize = 16;
1284
1285/// The largest name buffer [`Ast::clear`] keeps, in bytes of capacity.
1286///
1287/// A held buffer is memory the connection does not give back, so a long name -
1288/// a generated column alias, a quoted sentence - is dropped rather than kept.
1289/// With [`SPARE_NAME_BUFFERS`] this bounds what one arena holds between parses
1290/// at about 8 KiB.
1291const SPARE_NAME_CAPACITY: usize = 128;
1292
1293/// Which names share one hash of their spelling and quote form.
1294///
1295/// **A collision must not hand back the wrong `NameId`.** `NameId` equality is
1296/// read as "the same name" - the binder resolves a column reference by
1297/// comparing ids - so storing one index per hash and overwriting on collision
1298/// would silently make two different identifiers the same name. Every
1299/// candidate is compared against `Ast::names` before it is returned, and a
1300/// hash shared by two different spellings keeps both.
1301///
1302/// The single case is inline rather than a one-element `Vec` because that
1303/// `Vec` would be an allocation per distinct name, which is most of what
1304/// task-2039 removed. `Several` allocates, and needs a 64-bit collision to be
1305/// reached at all.
1306#[derive(Clone, Debug, PartialEq, Eq)]
1307enum Interned {
1308    /// The only name whose spelling and quote form hash to this value.
1309    One(u32),
1310    /// Two or more names that hashed the same, in the order they were interned.
1311    Several(Vec<u32>),
1312}
1313
1314/// The arena every node of one parse lives in.
1315#[derive(Clone, Debug, Default, Eq)]
1316pub struct Ast {
1317    names: Vec<Name>,
1318    /// Where a name already is, so `intern` is a lookup rather than a scan.
1319    ///
1320    /// **`intern` was a linear scan of every name interned so far, so N
1321    /// distinct identifiers cost N-squared comparisons (task-1932, H8).** The
1322    /// `SqlLength` default is 1 GiB, so a statement naming two hundred thousand
1323    /// distinct columns is well inside what the parser accepts and was
1324    /// quadratic to parse.
1325    ///
1326    /// **The key is a hash of the name and not the name itself (task-2039).**
1327    /// Owning `(folded, quote, text)` meant every lookup had to build an owned
1328    /// key to look up *with*, and finding the name already there still cost the
1329    /// folded copy plus two more from `key.clone()` on the way in - four
1330    /// allocations per distinct name, twelve of the ninety-three a compile of
1331    /// `SELECT a FROM t WHERE id = ?1` made. Hashing the bytes where they are
1332    /// and comparing the candidates against `names`, which already holds the
1333    /// spelling and the quote form, makes a hit free and leaves a miss paying
1334    /// only for what it stores.
1335    ///
1336    /// The hash comes from the map's own [`std::collections::hash_map::RandomState`],
1337    /// which is seeded per arena. That matters rather than being tidy: the
1338    /// parser accepts `Limit::Column * 64` distinct identifiers - 128,000 under
1339    /// the defaults - so a fixed hash an attacker could invert would let a
1340    /// statement drive every name into one `Several` and restore the quadratic
1341    /// parse this map exists to prevent.
1342    interned: std::collections::HashMap<u64, Interned>,
1343    /// Name byte buffers a previous parse used, waiting to be filled again.
1344    ///
1345    /// See [`SPARE_NAME_BUFFERS`]. Empty on a fresh arena, so the first parse
1346    /// pays what it always did and every parse after it does not.
1347    spare: Vec<Vec<u8>>,
1348    /// How many of `names`, from the first, are filed in `interned`.
1349    ///
1350    /// None while the arena holds fewer than [`LINEAR_NAMES`], which are
1351    /// searched; all of them from the first lookup past it (task-2185).
1352    filed: usize,
1353    exprs: Vec<Expr>,
1354    expr_spans: Vec<Span>,
1355    /// How deep each expression's own subtree is, one entry per node.
1356    ///
1357    /// **`Limit::ExprDepth` was declared in `compat/limits.toml` and enforced
1358    /// nowhere (task-1932, H8).** The parser charges `Limit::ParserDepth` in
1359    /// `enter`/`leave`, which counts recursion, and the two are different
1360    /// measurements: a flat chain `a1 = 1 AND a2 = 2 AND ...` enters and leaves
1361    /// `parse_expr_bp` once per term, so the recursion counter never
1362    /// accumulates, while the tree grows one level per term with nothing
1363    /// counting it. SQLite refuses at depth 1000. A tree that deep is accepted
1364    /// here and then walked recursively by the binder, the planner and the
1365    /// executor, each of which overflows the stack at some depth nobody
1366    /// measured.
1367    ///
1368    /// A node's depth is one more than the deepest of its children, and a child
1369    /// is always already in the arena when its parent is added, so this is one
1370    /// pass over the child ids at `add_expr` rather than a walk.
1371    expr_depths: Vec<u32>,
1372    /// The deepest expression tree in the arena.
1373    max_expr_depth: u32,
1374    selects: Vec<Select>,
1375    cores: Vec<SelectCore>,
1376    from_terms: Vec<FromTerm>,
1377    windows: Vec<Window>,
1378    bytes: usize,
1379}
1380
1381/// Two arenas are equal when they hold the same nodes.
1382///
1383/// **Hand-written rather than derived, because `interned` and `spare` are not
1384/// content (task-2039).** `interned` is an index over `names` keyed by a hash
1385/// the arena seeds for itself, so two arenas parsed from the same text hold
1386/// the same names under different keys; `spare` is buffers the allocator has
1387/// not been given back yet, which the next parse may or may not use. Comparing
1388/// either would report two identical parses as different. The fields are
1389/// destructured by name and none is skipped with `..`, so a field added later
1390/// fails to compile here rather than being silently left out of equality.
1391impl PartialEq for Ast {
1392    /// @param other - the arena to compare against
1393    fn eq(&self, other: &Ast) -> bool {
1394        let Ast {
1395            names,
1396            interned: _,
1397            spare: _,
1398            filed: _,
1399            exprs,
1400            expr_spans,
1401            expr_depths,
1402            max_expr_depth,
1403            selects,
1404            cores,
1405            from_terms,
1406            windows,
1407            bytes,
1408        } = self;
1409        *names == other.names
1410            && *exprs == other.exprs
1411            && *expr_spans == other.expr_spans
1412            && *expr_depths == other.expr_depths
1413            && *max_expr_depth == other.max_expr_depth
1414            && *selects == other.selects
1415            && *cores == other.cores
1416            && *from_terms == other.from_terms
1417            && *windows == other.windows
1418            && *bytes == other.bytes
1419    }
1420}
1421
1422impl Ast {
1423    /// Returns an empty arena.
1424    pub fn new() -> Ast {
1425        Ast::default()
1426    }
1427
1428    /// Empties the arena, keeping the memory it has already taken.
1429    ///
1430    /// **So that a second statement costs no allocations.** Every one of these
1431    /// vectors is empty at `Ast::new` and grows on its first push, so parsing
1432    /// `SELECT 1` takes half a dozen trips to the allocator - about 270 ns of a
1433    /// 1,337 ns prepare on this platform's CRT heap. A parser handed a cleared
1434    /// arena pushes into capacity that is already there.
1435    ///
1436    /// It is a `clear` rather than a `new` for exactly that reason, and the
1437    /// names are cleared with everything else: `intern` returns an existing id
1438    /// for equal text, so a name left behind from the previous statement would
1439    /// be a live id in the next one's arena.
1440    ///
1441    /// **The names keep their byte buffers even though the names go
1442    /// (task-2039).** Clearing `names` drops every `Name`, and a `Name` owns
1443    /// two `Vec<u8>` - so the vector's capacity survived a clear and the two
1444    /// allocations behind each entry in it did not, and a connection
1445    /// re-compiling one statement went back to the allocator twice per
1446    /// distinct name for ever. The buffers go on `spare` instead and `intern`
1447    /// fills them again. [`SPARE_NAME_BUFFERS`] is what bounds the list.
1448    pub fn clear(&mut self) {
1449        self.recycle_names();
1450        self.interned.clear();
1451        self.filed = 0;
1452        self.exprs.clear();
1453        self.expr_spans.clear();
1454        self.expr_depths.clear();
1455        self.max_expr_depth = 0;
1456        self.selects.clear();
1457        self.cores.clear();
1458        self.from_terms.clear();
1459        self.windows.clear();
1460        self.bytes = 0;
1461    }
1462
1463    /// Returns the number of arena bytes charged so far.
1464    ///
1465    /// This is what the `max_ast_bytes` limit is charged against. It counts the
1466    /// node structures rather than the source, because the source is borrowed.
1467    pub fn charged_bytes(&self) -> usize {
1468        self.bytes
1469    }
1470
1471    /// Interns an identifier, returning the id of an equal existing entry when
1472    /// there is one.
1473    ///
1474    /// **A map rather than a scan (task-1932, H8).** This walked every name
1475    /// interned so far and compared three fields against each, so a statement
1476    /// naming N distinct identifiers cost N-squared comparisons - and the
1477    /// `SqlLength` default is 1 GiB, which leaves room for hundreds of
1478    /// thousands of them. The key is exactly what the scan compared, so the
1479    /// answer is the same one and only the cost changed.
1480    ///
1481    /// The count is charged against `Limit::Column` for the same reason the
1482    /// depth is charged below: a bound that exists in `compat/limits.toml` and
1483    /// is enforced nowhere is not a bound. It is generous - a name is a column,
1484    /// a table, an alias, a function or a collation, so one statement
1485    /// legitimately interns more names than any one table has columns - and it
1486    /// is a ceiling on an arena that has to fit in memory rather than a
1487    /// statement about the schema.
1488    pub fn intern(&mut self, text: Vec<u8>, quote: QuoteForm, span: Span) -> NameId {
1489        let id = self.intern_bytes(&text, quote, span);
1490        Ast::keep_buffer(&mut self.spare, text);
1491        id
1492    }
1493
1494    /// Interns an identifier the caller does not own, returning the id of an
1495    /// equal existing entry when there is one.
1496    ///
1497    /// **The entry point that allocates nothing on a hit (task-2039).** The
1498    /// owned form above had to exist before the lookup could happen, so the
1499    /// parser called `identifier_text(..).into_owned()` on every identifier
1500    /// token whether or not the name was already interned - and `intern` then
1501    /// folded a copy and cloned the key, four allocations for a name the arena
1502    /// already held. This hashes the bytes where the source already has them.
1503    ///
1504    /// A miss allocates what it stores and nothing else: the spelling and the
1505    /// folded key, each taken from `spare` when a previous parse left one
1506    /// there.
1507    ///
1508    /// @param text - the identifier as written, with quoting already undone
1509    /// @param quote - how it was quoted, which decides whether it may become a
1510    ///   string
1511    /// @param span - where this occurrence came from
1512    pub fn intern_bytes(&mut self, text: &[u8], quote: QuoteForm, span: Span) -> NameId {
1513        // **A short statement's names are searched, not hashed** (task-2185).
1514        // Below `LINEAR_NAMES` a comparison per name is cheaper than the two
1515        // seeded hashes a lookup costs, which were 8% of compiling a one table
1516        // aggregate. Past it every name is filed under its hash once, so a
1517        // statement with thousands of names is still not quadratic.
1518        let hash = match self.names.len() < LINEAR_NAMES {
1519            true => {
1520                if let Some(index) = self
1521                    .names
1522                    .iter()
1523                    .position(|name| name.quote == quote && name.text == text)
1524                {
1525                    return NameId(index as u32);
1526                }
1527                None
1528            }
1529            false => {
1530                self.file_every_name();
1531                let hash = self.hash_of(text, quote);
1532                if let Some(index) = self.find_interned(hash, text, quote) {
1533                    return NameId(index);
1534                }
1535                Some(hash)
1536            }
1537        };
1538        let mut folded = Ast::take_buffer(&mut self.spare);
1539        folded.extend(text.iter().map(|byte| byte.to_ascii_lowercase()));
1540        let mut spelling = Ast::take_buffer(&mut self.spare);
1541        spelling.extend_from_slice(text);
1542        self.bytes = self.bytes.saturating_add(
1543            spelling
1544                .len()
1545                .saturating_add(folded.len())
1546                .saturating_add(32),
1547        );
1548        let index = self.names.len() as u32;
1549        self.names.push(Name {
1550            text: spelling,
1551            folded,
1552            quote,
1553            span,
1554        });
1555        if let Some(hash) = hash {
1556            self.remember_interned(hash, index);
1557            self.filed = self.names.len();
1558        }
1559        NameId(index)
1560    }
1561
1562    /// Files every name not yet filed under its hash.
1563    ///
1564    /// The names interned below [`LINEAR_NAMES`] were searched and never
1565    /// filed, so the first lookup past it files all of them at once; after
1566    /// that each new name is filed as it is interned and this files nothing.
1567    fn file_every_name(&mut self) {
1568        let hashes: Vec<(u64, u32)> = self
1569            .names
1570            .iter()
1571            .enumerate()
1572            .skip(self.filed)
1573            .map(|(index, name)| (self.hash_of(&name.text, name.quote), index as u32))
1574            .collect();
1575        for (hash, index) in hashes {
1576            self.remember_interned(hash, index);
1577        }
1578        self.filed = self.names.len();
1579    }
1580
1581    /// Returns the hash an identifier is filed under.
1582    ///
1583    /// The map's own hasher, so the seed belongs to this arena and no caller
1584    /// can choose names that collide. The folded key is not part of the hash:
1585    /// folding is a function of the spelling, so two identifiers written the
1586    /// same way and quoted the same way always fold the same, and no name is
1587    /// ever filed apart from itself.
1588    ///
1589    /// @param text - the identifier as written
1590    /// @param quote - how it was quoted
1591    fn hash_of(&self, text: &[u8], quote: QuoteForm) -> u64 {
1592        use std::hash::BuildHasher;
1593        self.interned.hasher().hash_one((text, quote))
1594    }
1595
1596    /// Returns the index of an interned name equal to this one, when there is
1597    /// one.
1598    ///
1599    /// Every candidate filed under the hash is compared against what `names`
1600    /// already holds, so a hash two different identifiers share returns the
1601    /// right one rather than whichever was stored last.
1602    ///
1603    /// @param hash - what [`Ast::hash_of`] returned for the identifier
1604    /// @param text - the identifier as written
1605    /// @param quote - how it was quoted
1606    fn find_interned(&self, hash: u64, text: &[u8], quote: QuoteForm) -> Option<u32> {
1607        let candidates: &[u32] = match self.interned.get(&hash)? {
1608            Interned::One(index) => core::slice::from_ref(index),
1609            Interned::Several(indexes) => indexes.as_slice(),
1610        };
1611        candidates.iter().copied().find(|index| {
1612            self.names
1613                .get(*index as usize)
1614                .is_some_and(|name| name.quote == quote && name.text == text)
1615        })
1616    }
1617
1618    /// Files a newly interned name under its hash.
1619    ///
1620    /// @param hash - what [`Ast::hash_of`] returned for the identifier
1621    /// @param index - where the name was pushed in `names`
1622    fn remember_interned(&mut self, hash: u64, index: u32) {
1623        use std::collections::hash_map::Entry;
1624        match self.interned.entry(hash) {
1625            Entry::Vacant(slot) => {
1626                slot.insert(Interned::One(index));
1627            }
1628            Entry::Occupied(mut slot) => match slot.get_mut() {
1629                Interned::Several(indexes) => indexes.push(index),
1630                Interned::One(first) => {
1631                    let first = *first;
1632                    slot.insert(Interned::Several(vec![first, index]));
1633                }
1634            },
1635        }
1636    }
1637
1638    /// Moves every name's byte buffers onto the free list and empties `names`.
1639    ///
1640    /// [`Ast::clear`] is the only caller, and its comment carries the argument.
1641    ///
1642    /// **Drained rather than taken.** `core::mem::take` on `self.names` leaves
1643    /// a `Vec` with no capacity behind, which hands the allocator back the one
1644    /// thing `clear` exists to keep - and cost a 256-byte `RawVec<Name>` regrow
1645    /// on every warm compile while this function was written that way. The
1646    /// free list and the names are separate fields, so the drain and the pushes
1647    /// borrow disjointly and neither has to be given up.
1648    fn recycle_names(&mut self) {
1649        let spare = &mut self.spare;
1650        for name in self.names.drain(..) {
1651            Ast::keep_buffer(spare, name.text);
1652            Ast::keep_buffer(spare, name.folded);
1653        }
1654    }
1655
1656    /// Keeps one byte buffer for the next parse, or gives it back.
1657    ///
1658    /// A buffer with no capacity never allocated, so keeping it would fill the
1659    /// list with entries that save nothing.
1660    ///
1661    /// @param spare - the free list to put it on
1662    /// @param buffer - the buffer nothing holds any more
1663    fn keep_buffer(spare: &mut Vec<Vec<u8>>, mut buffer: Vec<u8>) {
1664        if spare.len() >= SPARE_NAME_BUFFERS
1665            || buffer.capacity() == 0
1666            || buffer.capacity() > SPARE_NAME_CAPACITY
1667        {
1668            return;
1669        }
1670        buffer.clear();
1671        spare.push(buffer);
1672    }
1673
1674    /// Returns an empty byte buffer, reusing one a previous parse left.
1675    ///
1676    /// The buffer may be shorter than what is about to go into it, in which
1677    /// case filling it reallocates - which is the one allocation a fresh `Vec`
1678    /// would have made anyway, so a spare that is too small costs nothing over
1679    /// having no spare at all.
1680    ///
1681    /// @param spare - the free list to take from
1682    fn take_buffer(spare: &mut Vec<Vec<u8>>) -> Vec<u8> {
1683        spare.pop().unwrap_or_default()
1684    }
1685
1686    /// Returns how many distinct identifiers have been interned.
1687    pub fn name_count(&self) -> usize {
1688        self.names.len()
1689    }
1690
1691    /// Returns the depth of the deepest expression tree in the arena.
1692    ///
1693    /// What `Limit::ExprDepth` is charged against. See `expr_depths`.
1694    pub fn max_expr_depth(&self) -> u32 {
1695        self.max_expr_depth
1696    }
1697
1698    /// Returns how deep one expression's own subtree is.
1699    ///
1700    /// @param id - the node
1701    pub fn expr_depth(&self, id: ExprId) -> u32 {
1702        self.expr_depths.get(id.0 as usize).copied().unwrap_or(0)
1703    }
1704
1705    /// Returns an interned name.
1706    pub fn name(&self, id: NameId) -> Option<&Name> {
1707        self.names.get(id.0 as usize)
1708    }
1709
1710    /// Returns the folded key of an interned name, or an empty slice.
1711    pub fn folded(&self, id: NameId) -> &[u8] {
1712        self.names.get(id.0 as usize).map_or(&[], |n| &n.folded)
1713    }
1714
1715    /// Returns the written spelling of an interned name, or an empty slice.
1716    pub fn text(&self, id: NameId) -> &[u8] {
1717        self.names.get(id.0 as usize).map_or(&[], |n| &n.text)
1718    }
1719
1720    /// Adds an expression node.
1721    pub fn add_expr(&mut self, expr: Expr, span: Span) -> ExprId {
1722        self.bytes = self
1723            .bytes
1724            .saturating_add(core::mem::size_of::<Expr>().saturating_add(8));
1725        let depth = self.depth_of(&expr);
1726        self.max_expr_depth = self.max_expr_depth.max(depth);
1727        self.exprs.push(expr);
1728        self.expr_spans.push(span);
1729        self.expr_depths.push(depth);
1730        ExprId(self.exprs.len().saturating_sub(1) as u32)
1731    }
1732
1733    /// Returns how deep a node about to be added is.
1734    ///
1735    /// One more than the deepest of its children. Every child is already in the
1736    /// arena - the parser builds bottom up - so this reads their recorded
1737    /// depths rather than walking them, which is what keeps `add_expr` the
1738    /// constant-time push it was.
1739    ///
1740    /// A subquery's depth is one: the `SELECT` it names has an expression arena
1741    /// of its own and its own `max_expr_depth`, and charging the outer tree for
1742    /// the inner one would refuse a shallow expression that happens to contain
1743    /// a deep query rather than the deep query itself.
1744    ///
1745    /// @param expr - the node
1746    fn depth_of(&self, expr: &Expr) -> u32 {
1747        let deepest = |ids: &[ExprId]| -> u32 {
1748            ids.iter().map(|id| self.expr_depth(*id)).max().unwrap_or(0)
1749        };
1750        let children = match expr {
1751            Expr::Literal(_)
1752            | Expr::Parameter { .. }
1753            | Expr::Column { .. }
1754            | Expr::Star { .. }
1755            | Expr::Exists { .. }
1756            | Expr::Subquery(_)
1757            | Expr::Raise { message: None, .. } => 0,
1758            Expr::Raise {
1759                message: Some(message),
1760                ..
1761            } => self.expr_depth(*message),
1762            Expr::Unary { operand, .. }
1763            | Expr::Collate { operand, .. }
1764            | Expr::Cast { operand, .. }
1765            | Expr::IsNull { operand, .. } => self.expr_depth(*operand),
1766            Expr::Binary { left, right, .. } | Expr::Is { left, right, .. } => {
1767                self.expr_depth(*left).max(self.expr_depth(*right))
1768            }
1769            Expr::Pattern {
1770                operand,
1771                pattern,
1772                escape,
1773                ..
1774            } => self
1775                .expr_depth(*operand)
1776                .max(self.expr_depth(*pattern))
1777                .max(escape.map(|id| self.expr_depth(id)).unwrap_or(0)),
1778            Expr::Between {
1779                operand, low, high, ..
1780            } => self
1781                .expr_depth(*operand)
1782                .max(self.expr_depth(*low))
1783                .max(self.expr_depth(*high)),
1784            Expr::In { operand, rhs, .. } => {
1785                let right = match rhs {
1786                    InRhs::List(ids) => deepest(ids),
1787                    InRhs::Select(_) => 0,
1788                    InRhs::Table { arguments, .. } => {
1789                        arguments.as_deref().map(deepest).unwrap_or(0)
1790                    }
1791                };
1792                self.expr_depth(*operand).max(right)
1793            }
1794            Expr::Case {
1795                operand,
1796                branches,
1797                otherwise,
1798            } => {
1799                let mut deep = operand.map(|id| self.expr_depth(id)).unwrap_or(0);
1800                for (when, then) in branches {
1801                    deep = deep.max(self.expr_depth(*when)).max(self.expr_depth(*then));
1802                }
1803                deep.max(otherwise.map(|id| self.expr_depth(id)).unwrap_or(0))
1804            }
1805            Expr::Function {
1806                arguments, filter, ..
1807            } => arguments
1808                .as_deref()
1809                .map(deepest)
1810                .unwrap_or(0)
1811                .max(filter.map(|id| self.expr_depth(id)).unwrap_or(0)),
1812            Expr::RowValue(ids) => deepest(ids),
1813        };
1814        children.saturating_add(1)
1815    }
1816
1817    /// Returns an expression node.
1818    pub fn expr(&self, id: ExprId) -> Option<&Expr> {
1819        self.exprs.get(id.0 as usize)
1820    }
1821
1822    /// Returns the span an expression was parsed from.
1823    pub fn expr_span(&self, id: ExprId) -> Span {
1824        self.expr_spans
1825            .get(id.0 as usize)
1826            .copied()
1827            .unwrap_or_default()
1828    }
1829
1830    /// Returns the number of expression nodes in the arena.
1831    pub fn expr_count(&self) -> usize {
1832        self.exprs.len()
1833    }
1834
1835    /// Returns the number of compound SELECTs in the arena.
1836    pub fn select_count(&self) -> usize {
1837        self.selects.len()
1838    }
1839
1840    /// Returns the number of SELECT arms in the arena.
1841    pub fn core_count(&self) -> usize {
1842        self.cores.len()
1843    }
1844
1845    /// Returns the number of FROM terms in the arena.
1846    pub fn from_term_count(&self) -> usize {
1847        self.from_terms.len()
1848    }
1849
1850    /// Adds a compound SELECT.
1851    pub fn add_select(&mut self, select: Select) -> SelectId {
1852        self.bytes = self
1853            .bytes
1854            .saturating_add(core::mem::size_of::<Select>().saturating_add(32));
1855        self.selects.push(select);
1856        SelectId(self.selects.len().saturating_sub(1) as u32)
1857    }
1858
1859    /// Returns a compound SELECT.
1860    pub fn select(&self, id: SelectId) -> Option<&Select> {
1861        self.selects.get(id.0 as usize)
1862    }
1863
1864    /// Adds one arm of a compound SELECT.
1865    pub fn add_core(&mut self, core: SelectCore) -> SelectCoreId {
1866        self.bytes = self
1867            .bytes
1868            .saturating_add(core::mem::size_of::<SelectCore>().saturating_add(64));
1869        self.cores.push(core);
1870        SelectCoreId(self.cores.len().saturating_sub(1) as u32)
1871    }
1872
1873    /// Returns one arm of a compound SELECT.
1874    pub fn core(&self, id: SelectCoreId) -> Option<&SelectCore> {
1875        self.cores.get(id.0 as usize)
1876    }
1877
1878    /// Adds a FROM term.
1879    pub fn add_from_term(&mut self, term: FromTerm) -> FromTermId {
1880        self.bytes = self
1881            .bytes
1882            .saturating_add(core::mem::size_of::<FromTerm>().saturating_add(32));
1883        self.from_terms.push(term);
1884        FromTermId(self.from_terms.len().saturating_sub(1) as u32)
1885    }
1886
1887    /// Returns a FROM term.
1888    pub fn from_term(&self, id: FromTermId) -> Option<&FromTerm> {
1889        self.from_terms.get(id.0 as usize)
1890    }
1891
1892    /// Returns a FROM term for modification.
1893    ///
1894    /// A join's `ON` or `USING` clause follows the table it constrains, so the
1895    /// term is stored first and its constraint attached once the parser has
1896    /// read it. Building the term out of order instead would mean holding a
1897    /// half-built node across a recursive parse.
1898    pub fn from_term_mut(&mut self, id: FromTermId) -> Option<&mut FromTerm> {
1899        self.from_terms.get_mut(id.0 as usize)
1900    }
1901
1902    /// Adds a window definition.
1903    pub fn add_window(&mut self, window: Window) -> WindowId {
1904        self.bytes = self
1905            .bytes
1906            .saturating_add(core::mem::size_of::<Window>().saturating_add(32));
1907        self.windows.push(window);
1908        WindowId(self.windows.len().saturating_sub(1) as u32)
1909    }
1910
1911    /// Returns a window definition.
1912    pub fn window(&self, id: WindowId) -> Option<&Window> {
1913        self.windows.get(id.0 as usize)
1914    }
1915}
1916
1917#[cfg(test)]
1918mod tests {
1919    use super::*;
1920
1921    /// Interning is by folded key *and* spelling, so `a` and `A` are two
1922    /// entries that compare equal by key rather than one entry that has
1923    /// forgotten which spelling reached it.
1924    #[test]
1925    fn interning_keeps_the_spelling_and_folds_the_key() {
1926        let mut ast = Ast::new();
1927        let lower = ast.intern(b"abc".to_vec(), QuoteForm::Bare, Span::default());
1928        let upper = ast.intern(b"ABC".to_vec(), QuoteForm::Bare, Span::default());
1929        let again = ast.intern(b"abc".to_vec(), QuoteForm::Bare, Span::default());
1930        assert_eq!(lower, again);
1931        assert_ne!(lower, upper);
1932        assert_eq!(ast.folded(lower), ast.folded(upper));
1933        assert_eq!(ast.text(upper), b"ABC");
1934    }
1935
1936    /// Every node id resolves, and an id from another arena does not panic.
1937    #[test]
1938    fn an_unknown_id_returns_none_rather_than_panicking() {
1939        let ast = Ast::new();
1940        assert!(ast.expr(ExprId(7)).is_none());
1941        assert!(ast.select(SelectId(7)).is_none());
1942        assert!(ast.name(NameId(7)).is_none());
1943        assert_eq!(ast.expr_span(ExprId(7)), Span::default());
1944    }
1945
1946    /// The charge grows with the arena, which is what the limit is checked
1947    /// against before a deep parse allocates.
1948    #[test]
1949    fn the_arena_charges_for_what_it_holds() {
1950        let mut ast = Ast::new();
1951        let before = ast.charged_bytes();
1952        ast.add_expr(Expr::Literal(Literal::Null), Span::default());
1953        assert!(ast.charged_bytes() > before);
1954    }
1955
1956    /// The same name written twice is one entry however it arrives, so the
1957    /// borrowed entry point and the owned one agree.
1958    #[test]
1959    fn the_borrowed_and_owned_entry_points_intern_the_same_name() {
1960        let mut ast = Ast::new();
1961        let owned = ast.intern(b"col".to_vec(), QuoteForm::Bare, Span::default());
1962        let borrowed = ast.intern_bytes(b"col", QuoteForm::Bare, Span::default());
1963        assert_eq!(owned, borrowed);
1964        assert_eq!(ast.name_count(), 1);
1965        assert_eq!(ast.text(owned), b"col");
1966        assert_eq!(ast.folded(owned), b"col");
1967    }
1968
1969    /// The quote form is part of what makes a name, so `x` and `"x"` are two
1970    /// entries even though they spell the same word.
1971    #[test]
1972    fn the_quote_form_separates_two_names_that_spell_the_same_word() {
1973        let mut ast = Ast::new();
1974        let bare = ast.intern_bytes(b"x", QuoteForm::Bare, Span::default());
1975        let quoted = ast.intern_bytes(b"x", QuoteForm::Double, Span::default());
1976        assert_ne!(bare, quoted);
1977        assert_eq!(ast.name_count(), 2);
1978        assert_eq!(
1979            ast.intern_bytes(b"x", QuoteForm::Bare, Span::default()),
1980            bare
1981        );
1982        assert_eq!(
1983            ast.intern_bytes(b"x", QuoteForm::Double, Span::default()),
1984            quoted
1985        );
1986    }
1987
1988    /// A name filed under another name's hash gets its own id.
1989    ///
1990    /// **The failure the map is keyed on a hash to avoid (task-2039).** A map
1991    /// that stored one index per hash and trusted it would answer `gamma` with
1992    /// `alpha`'s id here, and `NameId` equality is read as "the same name" -
1993    /// the binder resolves a column reference by comparing ids - so two
1994    /// different identifiers becoming one id is a wrong query rather than a
1995    /// slow one. A 64-bit collision cannot be produced by interning names, so
1996    /// the collision is filed by hand: `remember_interned` is exactly what
1997    /// `intern_bytes` calls, with the hash of a different name.
1998    #[test]
1999    fn a_name_filed_under_another_names_hash_gets_its_own_id() {
2000        let mut ast = Ast::new();
2001        // Enough names first that every lookup below goes through the map;
2002        // fewer than `LINEAR_NAMES` are searched one by one (task-2185).
2003        for at in 0..LINEAR_NAMES {
2004            ast.intern_bytes(
2005                format!("filler{at}").as_bytes(),
2006                QuoteForm::Bare,
2007                Span::default(),
2008            );
2009        }
2010        let alpha = ast.intern_bytes(b"alpha", QuoteForm::Bare, Span::default());
2011        let stolen = ast.hash_of(b"gamma", QuoteForm::Bare);
2012        ast.remember_interned(stolen, alpha.0);
2013
2014        let gamma = ast.intern_bytes(b"gamma", QuoteForm::Bare, Span::default());
2015        assert_ne!(gamma, alpha);
2016        assert_eq!(ast.text(gamma), b"gamma");
2017        assert_eq!(ast.text(alpha), b"alpha");
2018
2019        // And both are still found, from the one slot that now holds both.
2020        assert_eq!(
2021            ast.intern_bytes(b"gamma", QuoteForm::Bare, Span::default()),
2022            gamma
2023        );
2024        assert_eq!(
2025            ast.intern_bytes(b"alpha", QuoteForm::Bare, Span::default()),
2026            alpha
2027        );
2028        assert_eq!(ast.name_count(), LINEAR_NAMES + 2);
2029    }
2030
2031    /// A name interned while the arena searched its names is found again once
2032    /// it files them by hash, and so is one interned after (task-2185).
2033    ///
2034    /// The names below `LINEAR_NAMES` are never put in the map as they come,
2035    /// so a filing step that missed them would give a repeated name a second
2036    /// id, which the binder reads as a different name.
2037    #[test]
2038    fn names_from_before_the_map_are_found_through_it() {
2039        let mut ast = Ast::new();
2040        let early: Vec<NameId> = (0..LINEAR_NAMES)
2041            .map(|at| {
2042                ast.intern_bytes(
2043                    format!("n{at}").as_bytes(),
2044                    QuoteForm::Bare,
2045                    Span::default(),
2046                )
2047            })
2048            .collect();
2049        let late: Vec<NameId> = (LINEAR_NAMES..LINEAR_NAMES * 3)
2050            .map(|at| {
2051                ast.intern_bytes(
2052                    format!("n{at}").as_bytes(),
2053                    QuoteForm::Bare,
2054                    Span::default(),
2055                )
2056            })
2057            .collect();
2058        for (at, id) in early.iter().chain(late.iter()).enumerate() {
2059            assert_eq!(
2060                ast.intern_bytes(
2061                    format!("n{at}").as_bytes(),
2062                    QuoteForm::Bare,
2063                    Span::default()
2064                ),
2065                *id
2066            );
2067        }
2068        assert_eq!(ast.name_count(), LINEAR_NAMES * 3);
2069        // A cleared arena searches again, and finds nothing from before.
2070        ast.clear();
2071        let again = ast.intern_bytes(b"n0", QuoteForm::Bare, Span::default());
2072        assert_eq!(ast.name_count(), 1);
2073        assert_eq!(ast.text(again), b"n0");
2074    }
2075
2076    /// Two hundred names all reach their own id and find it again.
2077    ///
2078    /// The map is keyed on a hash now, so "every name is distinct" is a claim
2079    /// about the candidate comparison rather than about the map, and a scan of
2080    /// a real number of names is what checks it.
2081    #[test]
2082    fn many_names_each_keep_their_own_id() {
2083        let mut ast = Ast::new();
2084        let spellings: Vec<Vec<u8>> = (0..200)
2085            .map(|nth| format!("column_{nth}").into_bytes())
2086            .collect();
2087        let ids: Vec<NameId> = spellings
2088            .iter()
2089            .map(|text| ast.intern_bytes(text, QuoteForm::Bare, Span::default()))
2090            .collect();
2091        assert_eq!(ast.name_count(), 200);
2092        for (text, id) in spellings.iter().zip(&ids) {
2093            assert_eq!(
2094                ast.intern_bytes(text, QuoteForm::Bare, Span::default()),
2095                *id
2096            );
2097            assert_eq!(ast.text(*id), text.as_slice());
2098        }
2099        let mut sorted = ids.clone();
2100        sorted.sort_unstable();
2101        sorted.dedup();
2102        assert_eq!(sorted.len(), 200);
2103    }
2104
2105    /// `clear` keeps the names' byte buffers and the names vector's capacity.
2106    ///
2107    /// **Both halves, because losing either one costs an allocation per warm
2108    /// compile (task-2039).** The buffers are what a second parse of the same
2109    /// statement fills instead of asking the allocator; the vector's capacity
2110    /// is what `clear` existed to keep in the first place, and a `clear` that
2111    /// moved the names out by `core::mem::take` silently gave it back.
2112    #[test]
2113    fn clearing_keeps_the_name_buffers_and_the_names_capacity() {
2114        let mut ast = Ast::new();
2115        for nth in 0..4u32 {
2116            ast.intern_bytes(
2117                format!("c{nth}").as_bytes(),
2118                QuoteForm::Bare,
2119                Span::default(),
2120            );
2121        }
2122        let capacity = ast.names.capacity();
2123        assert!(capacity >= 4);
2124
2125        ast.clear();
2126        assert_eq!(ast.name_count(), 0);
2127        assert_eq!(ast.names.capacity(), capacity);
2128        // Two buffers a name: the spelling and the folded key.
2129        assert_eq!(ast.spare.len(), 8);
2130        assert!(ast.spare.iter().all(|buffer| buffer.is_empty()));
2131
2132        // And the next parse takes them back rather than allocating.
2133        for nth in 0..4u32 {
2134            ast.intern_bytes(
2135                format!("c{nth}").as_bytes(),
2136                QuoteForm::Bare,
2137                Span::default(),
2138            );
2139        }
2140        assert_eq!(ast.spare.len(), 0);
2141        assert_eq!(ast.name_count(), 4);
2142        assert_eq!(ast.text(NameId(2)), b"c2");
2143    }
2144
2145    /// The free list is bounded, so a statement naming thousands of things
2146    /// does not leave the connection holding them.
2147    #[test]
2148    fn the_free_list_does_not_grow_without_bound() {
2149        let mut ast = Ast::new();
2150        for nth in 0..2_000u32 {
2151            ast.intern_bytes(
2152                format!("column_{nth}").as_bytes(),
2153                QuoteForm::Bare,
2154                Span::default(),
2155            );
2156        }
2157        ast.clear();
2158        assert_eq!(ast.spare.len(), SPARE_NAME_BUFFERS);
2159
2160        // A name longer than a buffer worth keeping is dropped rather than
2161        // held, so one enormous alias does not pin its bytes for ever.
2162        let mut ast = Ast::new();
2163        let long = vec![b'z'; SPARE_NAME_CAPACITY.saturating_add(1)];
2164        ast.intern_bytes(&long, QuoteForm::Bare, Span::default());
2165        ast.clear();
2166        assert_eq!(ast.spare.len(), 0);
2167    }
2168
2169    /// Two arenas holding the same nodes are equal, and the index behind them
2170    /// is not part of that.
2171    ///
2172    /// `Ast` compares by hand because `interned` is keyed on a hash each arena
2173    /// seeds for itself, so a derived comparison would report two identical
2174    /// parses as different (task-2039).
2175    #[test]
2176    fn two_arenas_holding_the_same_names_are_equal() {
2177        let mut one = Ast::new();
2178        let mut two = Ast::new();
2179        for text in [b"alpha".as_slice(), b"beta".as_slice()] {
2180            one.intern_bytes(text, QuoteForm::Bare, Span::default());
2181            two.intern_bytes(text, QuoteForm::Bare, Span::default());
2182        }
2183        assert_eq!(one, two);
2184
2185        two.intern_bytes(b"gamma", QuoteForm::Bare, Span::default());
2186        assert_ne!(one, two);
2187    }
2188}