rudb_parse/ast.rs
1//! rudb's abstract syntax tree.
2//!
3//! The parse tree the matcher produces is DuckDB's grammar, faithfully. That is the point of it and
4//! it is also why nothing downstream should read it: a bump of the vendored grammar is allowed to
5//! rename `BetweenInLikeExpression`, and if the binder is matching on that name then the bump is a
6//! rewrite. This module is the boundary. It is ours, it changes when we decide it changes, and
7//! `transform` is the one place that knows both shapes.
8//!
9//! Everything is an arena with `u32` indices, per `spec/04-architecture.md` section 4.5. There is
10//! no `Box` and no `Vec` inside a node. A list of children is a [`Slice`] into a side vector, which
11//! means a node is a fixed size, the whole tree is a handful of allocations, and walking it is a
12//! sequential read rather than a pointer chase per node. It also means an `Ast` is `Clone` and
13//! `Send` without any thought, and that a subtree can be addressed by a `u32` in a plan or an
14//! error without borrowing anything.
15//!
16//! The one cost is that you cannot hold a reference to a node and index the arena at the same time,
17//! so the code reads a node out by value first. Nodes are small and `Copy`, so that is a register
18//! move.
19
20use rudb_common::Span;
21
22use crate::matcher::NONE;
23
24/// A run of items in one of the side vectors.
25///
26/// Empty is `len == 0`, and `start` is then meaningless rather than wrong. There is no `Option`
27/// wrapper because an absent list and an empty list are the same thing everywhere this is used.
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
29pub struct Slice {
30 /// The first item.
31 pub start: u32,
32 /// How many items.
33 pub len: u32,
34}
35
36impl Slice {
37 /// Whether the run is empty.
38 pub const fn is_empty(self) -> bool {
39 self.len == 0
40 }
41
42 /// The run as a range, for indexing the backing vector.
43 pub const fn range(self) -> std::ops::Range<usize> {
44 self.start as usize..(self.start + self.len) as usize
45 }
46}
47
48/// An index into `Ast::strings`.
49pub type StrRef = u32;
50/// An index into `Ast::exprs`.
51pub type ExprRef = u32;
52/// An index into `Ast::sources`.
53pub type SourceRef = u32;
54/// An index into `Ast::queries`.
55pub type QueryRef = u32;
56/// An index into `Ast::selects`.
57pub type SelectRef = u32;
58/// An index into `Ast::create_tables`.
59pub type CreateTableRef = u32;
60/// An index into `Ast::create_views`.
61pub type CreateViewRef = u32;
62/// An index into `Ast::drop_tables`.
63pub type DropTableRef = u32;
64/// An index into `Ast::inserts`.
65pub type InsertRef = u32;
66/// An index into `Ast::settings`.
67pub type SettingRef = u32;
68/// An index into `Ast::windows`.
69pub type WindowRef = u32;
70
71/// One statement.
72///
73/// Seven of the twenty seven the grammar reaches. The rest are a transform error naming the rule
74/// rather than a variant that nothing fills in, so that adding one is a compile error somewhere
75/// useful rather than a silent `todo!()`.
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
77pub enum Statement {
78 /// A query, meaning a `SELECT` or a set operation over two of them.
79 Query(QueryRef),
80 /// `CREATE TABLE`.
81 CreateTable(CreateTableRef),
82 /// `CREATE VIEW`.
83 CreateView(CreateViewRef),
84 /// `DROP TABLE` or `DROP VIEW`, which are one rule in the grammar and one statement here.
85 DropTable(DropTableRef),
86 /// `INSERT INTO`.
87 Insert(InsertRef),
88 /// `SET name = value`.
89 Set(SettingRef),
90 /// `RESET name`, which is the same shape with nothing on the right of it.
91 Reset(SettingRef),
92 /// `CHECKPOINT` or `FORCE CHECKPOINT`.
93 Checkpoint,
94 /// `EXPLAIN` over a query, and whether `ANALYZE` was asked for.
95 ///
96 /// The query rather than a statement, because the grammar lets every statement be explained
97 /// and a plan is the only thing there is to show. `EXPLAIN INSERT` is a refusal rather than a
98 /// plan of the source, since the source is not what the statement does.
99 ///
100 /// `ANALYZE` means the query is run and the plan is printed with what happened on it, so it is
101 /// a flag on the same statement rather than a statement of its own. Everything between the
102 /// parser and the printer is the same either way, which is the point: the analyzed plan has to
103 /// be the plan that ran.
104 Explain { query: QueryRef, analyze: bool },
105}
106
107/// `SET name = value` and `RESET name`.
108///
109/// One struct for the two, because `RESET name` is `SET name` with no value and giving it its own
110/// arena would mean two of everything to say the same thing twice.
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
112pub struct Setting {
113 /// The setting name, as written.
114 pub name: StrRef,
115 /// The scope word, if one was written.
116 pub scope: Scope,
117 /// The value, or `NONE` for a `RESET`.
118 ///
119 /// An expression rather than text. `SET memory_limit = '1GB'` writes a string and `SET threads
120 /// = 4` writes a number, and what a setting does with either is the setting's business.
121 pub value: ExprRef,
122 /// Whether the statement was written as a bare `PRAGMA name`.
123 ///
124 /// `PRAGMA disable_optimizer` is a `SET` with the name and the value both folded into one word,
125 /// and which word means what is the catalog's business rather than the parser's, so it arrives
126 /// here as a name with no value and this flag to say that no value is not a `RESET`.
127 pub pragma: bool,
128}
129
130/// Which copy of a setting a statement means.
131#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
132pub enum Scope {
133 /// No scope word, which every setting reads as the one it has.
134 #[default]
135 Unwritten,
136 /// `GLOBAL`.
137 Global,
138 /// `SESSION`.
139 Session,
140 /// `LOCAL`.
141 Local,
142}
143
144impl Scope {
145 /// The word that was written, for the sentence an error prints.
146 #[must_use]
147 pub const fn keyword(self) -> &'static str {
148 match self {
149 Self::Unwritten => "",
150 Self::Global => "GLOBAL",
151 Self::Session => "SESSION",
152 Self::Local => "LOCAL",
153 }
154 }
155}
156
157/// `CREATE TABLE name (columns)` or `CREATE TABLE name AS query`.
158///
159/// Exactly one of `columns` and `query` says what the table is. A column list is the ordinary form
160/// and `query` is `CREATE TABLE AS`, where the columns come from what the query produced and the
161/// only thing the syntax contributes is optionally renaming them, which is `columns` with the types
162/// left as `NONE`.
163#[derive(Debug, Clone, Copy, PartialEq, Eq)]
164pub struct CreateTable {
165 /// The table name, as a run of [`Slice`] parts, outermost first.
166 pub name: Slice,
167 /// The column definitions, as a run of [`ColumnDef`].
168 pub columns: Slice,
169 /// The `AS` query, or `NONE`.
170 pub query: QueryRef,
171 /// Whether `IF NOT EXISTS` was written.
172 pub if_not_exists: bool,
173 /// Whether `OR REPLACE` was written.
174 pub or_replace: bool,
175 /// Whether `TEMP` or `TEMPORARY` was written.
176 pub temporary: bool,
177}
178
179/// One column of a `CREATE TABLE`.
180///
181/// The type is the text as written rather than a resolved type, because resolving a type is the
182/// binder's job and this crate is syntax. `VARCHAR(10)` and `STRUCT(a INTEGER)` reach the binder
183/// as themselves.
184#[derive(Debug, Clone, Copy, PartialEq, Eq)]
185pub struct ColumnDef {
186 /// The column name.
187 pub name: StrRef,
188 /// The type as written, or `NONE` when the definition had none, which only `CREATE TABLE AS`
189 /// allows.
190 pub ty: StrRef,
191 /// Whether `NOT NULL` was written.
192 pub not_null: bool,
193}
194
195/// `CREATE VIEW name (columns) AS query`.
196///
197/// The body is kept twice over, as a bound reference into this same arena and as the text that was
198/// written. Both are needed and they are needed for different things. The reference is what binds
199/// the body at creation, which is where a view over a table that is not there is refused. The text
200/// is what the catalog keeps, because a view is bound again at every reference rather than frozen
201/// at creation: a view over `SELECT * FROM t` follows `t` when a column is added to it, which was
202/// measured, and the only way to follow it is to have the query to bind again.
203#[derive(Debug, Clone, Copy, PartialEq, Eq)]
204pub struct CreateView {
205 /// The view name, as a run of [`Slice`] parts, outermost first.
206 pub name: Slice,
207 /// The column aliases, as a run of parts, empty when the statement wrote no list.
208 pub columns: Slice,
209 /// The body.
210 pub query: QueryRef,
211 /// The body as it was written, which is what the catalog keeps.
212 pub sql: StrRef,
213 /// Whether `IF NOT EXISTS` was written.
214 pub if_not_exists: bool,
215 /// Whether `OR REPLACE` was written.
216 pub or_replace: bool,
217 /// Whether `TEMP` or `TEMPORARY` was written.
218 pub temporary: bool,
219}
220
221/// `DROP TABLE a, b` or `DROP VIEW a, b`.
222#[derive(Debug, Clone, Copy, PartialEq, Eq)]
223pub struct DropTable {
224 /// The names, as a run of [`Slice`] into `Ast::name_lists`, each of which is a run of parts.
225 pub names: Slice,
226 /// Whether `IF EXISTS` was written.
227 pub if_exists: bool,
228 /// Whether `VIEW` was written where `TABLE` could have been. Dropping one as the other is an
229 /// error rather than a synonym, so which word was written has to survive the transform.
230 pub view: bool,
231}
232
233/// `INSERT INTO name (columns) query`.
234#[derive(Debug, Clone, Copy, PartialEq, Eq)]
235pub struct Insert {
236 /// The table name, as a run of parts, outermost first.
237 pub name: Slice,
238 /// The column list, as a run of parts, empty when the statement did not write one.
239 pub columns: Slice,
240 /// What produces the rows, which is a `VALUES` clause or any other query.
241 pub source: QueryRef,
242}
243
244/// A `WITH name AS MATERIALIZED (query)`, which is run once and read wherever it is named.
245///
246/// Only the materialised ones are here. A plain `WITH` and a `NOT MATERIALIZED` one are put into
247/// every place they are named while the tree is being built, the way the reference binary does it,
248/// so by the time anything reads an [`Ast`] there is no name left to resolve.
249#[derive(Debug, Clone, Copy, PartialEq, Eq)]
250pub struct Cte {
251 /// The name it was written with.
252 pub name: StrRef,
253 /// What produces its rows.
254 pub query: QueryRef,
255 /// The column names from `AS name(a, b)`, as a run of [`StrRef`], empty when there were none.
256 pub columns: Slice,
257}
258
259/// A query: a body, plus the modifiers that apply to whatever the body produced.
260///
261/// The split is the grammar's, not an invention. `SelectStatementInternal <- WithClause?
262/// SelectSetOpChain ResultModifiers?` puts `ORDER BY` and `LIMIT` outside the set operator chain,
263/// which is the only place they can go and be right: `a UNION b ORDER BY x` sorts the union and not
264/// the second half of it. Hanging them off `Select` instead would have made that unrepresentable.
265#[derive(Debug, Clone, Copy, PartialEq, Eq)]
266pub struct Query {
267 /// The materialised `WITH` definitions this query introduces, as a run of indexes into
268 /// `Ast::ctes` held in `Ast::cte_lists`, outermost first.
269 ///
270 /// A list of indexes rather than a run of the arena itself, because a materialised `WITH`
271 /// inside another one is pushed while the outer one is still being built, so what one query
272 /// owns is not a contiguous stretch of the arena.
273 pub ctes: Slice,
274 /// What produces the rows.
275 pub body: QueryBody,
276 /// The `ORDER BY` list, as a run of [`OrderItem`].
277 pub order_by: Slice,
278 /// Whether the clause was `ORDER BY ALL`.
279 pub order_by_all: bool,
280 /// The `LIMIT` expression, or `NONE`.
281 pub limit: ExprRef,
282 /// Whether the limit was a percentage rather than a row count.
283 pub limit_percent: bool,
284 /// The `OFFSET` expression, or `NONE`.
285 pub offset: ExprRef,
286}
287
288impl Query {
289 /// A query with no modifiers on it.
290 pub const fn bare(body: QueryBody) -> Self {
291 Self {
292 ctes: Slice { start: 0, len: 0 },
293 body,
294 order_by: Slice { start: 0, len: 0 },
295 order_by_all: false,
296 limit: NONE,
297 limit_percent: false,
298 offset: NONE,
299 }
300 }
301}
302
303/// What produces the rows of a query.
304#[derive(Debug, Clone, Copy, PartialEq, Eq)]
305pub enum QueryBody {
306 /// One `SELECT ... FROM ... WHERE ...` block.
307 Select(SelectRef),
308 /// `UNION`, `EXCEPT` or `INTERSECT` over two queries.
309 SetOp {
310 /// Which operator.
311 op: SetOp,
312 /// Whether duplicates survive.
313 quantifier: Quantifier,
314 /// Whether the columns are matched up by name rather than by position.
315 by_name: bool,
316 /// The query on the left.
317 left: QueryRef,
318 /// The query on the right.
319 right: QueryRef,
320 },
321 /// `VALUES (1, 'a'), (2, 'b')`, as a run of [`Slice`] in `Ast::rows`.
322 ///
323 /// A row count and a column count and nothing else, so it is a query body rather than a
324 /// statement of its own. That is also what makes `INSERT INTO t VALUES (1)` and
325 /// `INSERT INTO t SELECT 1` the same shape by the time anything downstream sees them, which is
326 /// the reason the insert walker does not have two arms.
327 Values(Slice),
328 /// `DESCRIBE SELECT ...`, `DESCRIBE t` and `DESCRIBE 'file.parquet'`.
329 ///
330 /// A query body rather than a statement, because that is where the grammar puts it:
331 /// `SelectStatementType <- ... / DescribeStatement / ...`, so `FROM (DESCRIBE SELECT 1)` is a
332 /// subquery over one and needs no rule of its own. The two spellings that name something
333 /// instead of writing a query arrive here as `DESCRIBE SELECT * FROM that`, which is not a
334 /// shortcut: on the reference binary `DESCRIBE t` and `DESCRIBE SELECT * FROM t` produce the
335 /// same six columns and the same rows, down to the primary key and the default.
336 Describe(QueryRef),
337 /// `SHOW name`, resolved as a setting or a deprecated table description while binding.
338 Show { name: Slice, relation: QueryRef },
339}
340
341/// Which set operator.
342#[derive(Debug, Clone, Copy, PartialEq, Eq)]
343pub enum SetOp {
344 /// `UNION`.
345 Union,
346 /// `EXCEPT`.
347 Except,
348 /// `INTERSECT`.
349 Intersect,
350}
351
352/// Whether a set operator or an aggregate keeps duplicates.
353///
354/// `Unstated` is not the same as `All` even though the two agree for `UNION`, because they disagree
355/// for `INTERSECT` in some dialects and because an error message that says what was written is
356/// better than one that says what it was taken to mean.
357#[derive(Debug, Clone, Copy, PartialEq, Eq)]
358pub enum Quantifier {
359 /// Neither word was written.
360 Unstated,
361 /// `ALL`.
362 All,
363 /// `DISTINCT`.
364 Distinct,
365}
366
367/// What the `DISTINCT` clause of a select said.
368#[derive(Debug, Clone, Copy, PartialEq, Eq)]
369pub enum Distinct {
370 /// No clause, or the no-op `SELECT ALL`.
371 No,
372 /// `SELECT DISTINCT`.
373 Yes,
374 /// `SELECT DISTINCT ON (a, b)`, holding the expressions in the parentheses.
375 On(Slice),
376}
377
378/// One select block.
379///
380/// Every optional expression is `NONE` when it is absent rather than an `Option<u32>`, which keeps
381/// the struct at forty bytes and keeps the absent case spelled the same way it is spelled in the
382/// parse tree arena.
383#[derive(Debug, Clone, Copy, PartialEq, Eq)]
384pub struct Select {
385 /// The `DISTINCT` clause.
386 pub distinct: Distinct,
387 /// The target list, as a run of [`Target`].
388 pub targets: Slice,
389 /// The `FROM` list, as a run of [`SourceRef`]. Several entries mean a cross product.
390 pub from: Slice,
391 /// The `WHERE` expression, or `NONE`.
392 pub filter: ExprRef,
393 /// The `GROUP BY` list, as a run of [`ExprRef`].
394 pub group_by: Slice,
395 /// Whether the clause was `GROUP BY ALL`.
396 pub group_by_all: bool,
397 /// The `HAVING` expression, or `NONE`.
398 pub having: ExprRef,
399}
400
401impl Select {
402 /// An empty select, which is what the transformer fills in from.
403 pub const fn empty() -> Self {
404 Self {
405 distinct: Distinct::No,
406 targets: Slice { start: 0, len: 0 },
407 from: Slice { start: 0, len: 0 },
408 filter: NONE,
409 group_by: Slice { start: 0, len: 0 },
410 group_by_all: false,
411 having: NONE,
412 }
413 }
414}
415
416/// One entry of a target list.
417#[derive(Debug, Clone, Copy, PartialEq, Eq)]
418pub struct Target {
419 /// What is being selected.
420 pub expr: ExprRef,
421 /// The alias, or `NONE`. The binder invents one when there is none, because what it invents
422 /// depends on the expression and that is a binder question rather than a parser question.
423 pub alias: StrRef,
424}
425
426/// One entry of an order by list.
427#[derive(Debug, Clone, Copy, PartialEq, Eq)]
428pub struct OrderItem {
429 /// What to sort on.
430 pub expr: ExprRef,
431 /// The direction.
432 pub order: Order,
433 /// Where nulls go.
434 pub nulls: Nulls,
435}
436
437/// Sort direction, with the unwritten case kept apart from the default it resolves to.
438#[derive(Debug, Clone, Copy, PartialEq, Eq)]
439pub enum Order {
440 /// Nothing was written.
441 Unstated,
442 /// `ASC` or `ASCENDING`.
443 Ascending,
444 /// `DESC` or `DESCENDING`.
445 Descending,
446}
447
448/// Null placement in a sort.
449#[derive(Debug, Clone, Copy, PartialEq, Eq)]
450pub enum Nulls {
451 /// Nothing was written, so the session default applies.
452 Unstated,
453 /// `NULLS FIRST`.
454 First,
455 /// `NULLS LAST`.
456 Last,
457}
458
459/// How a window frame measures the distance to its bounds.
460#[derive(Debug, Clone, Copy, PartialEq, Eq)]
461pub enum WindowUnit {
462 /// `ROWS`, so a bound counts rows.
463 Rows,
464 /// `RANGE`, so a bound is a value offset from the current row's sort key.
465 Range,
466 /// `GROUPS`, so a bound counts runs of rows that tie on the sort key.
467 Groups,
468}
469
470/// One end of a window frame.
471#[derive(Debug, Clone, Copy, PartialEq, Eq)]
472pub enum WindowBound {
473 /// `UNBOUNDED PRECEDING`, the first row of the partition.
474 UnboundedPreceding,
475 /// `n PRECEDING`, holding the offset expression.
476 Preceding(ExprRef),
477 /// `CURRENT ROW`.
478 CurrentRow,
479 /// `n FOLLOWING`, holding the offset expression.
480 Following(ExprRef),
481 /// `UNBOUNDED FOLLOWING`, the last row of the partition.
482 UnboundedFollowing,
483}
484
485/// Which peers of the current row the frame drops once its bounds have been applied.
486#[derive(Debug, Clone, Copy, PartialEq, Eq)]
487pub enum WindowExclude {
488 /// `EXCLUDE NO OTHERS`, which is also what an unwritten clause means.
489 NoOthers,
490 /// `EXCLUDE CURRENT ROW`.
491 CurrentRow,
492 /// `EXCLUDE GROUP`, dropping the current row and everything that ties with it.
493 Group,
494 /// `EXCLUDE TIES`, dropping everything that ties with the current row but keeping it.
495 Ties,
496}
497
498/// Everything inside the parentheses of an `OVER`.
499///
500/// A named window is resolved here rather than downstream, because the resolution is a parser
501/// question on the reference binary: a reference to a window nobody defined is a `Parser Error`
502/// there, and a view written with `OVER w` comes back out of the catalog with the definition
503/// inlined. So nothing after the transform ever sees a name, and there is no window clause on
504/// [`Select`] for it to see one in.
505#[derive(Debug, Clone, Copy, PartialEq, Eq)]
506pub struct WindowSpec {
507 /// The `PARTITION BY` list, as a run of [`ExprRef`], empty when there was no clause.
508 pub partition: Slice,
509 /// The `ORDER BY` list, as a run of [`OrderItem`], empty when there was no clause.
510 pub order: Slice,
511 /// Which of the three units the bounds are measured in.
512 pub unit: WindowUnit,
513 /// Where the frame starts.
514 pub start: WindowBound,
515 /// Where the frame ends.
516 pub end: WindowBound,
517 /// Which peers the frame drops.
518 pub exclude: WindowExclude,
519}
520
521impl WindowSpec {
522 /// The frame a window with no frame clause gets, which the standard fixes and DuckDB follows.
523 pub const DEFAULT_UNIT: WindowUnit = WindowUnit::Range;
524 /// The start a window with no frame clause gets.
525 pub const DEFAULT_START: WindowBound = WindowBound::UnboundedPreceding;
526 /// The end a window with no frame clause gets.
527 pub const DEFAULT_END: WindowBound = WindowBound::CurrentRow;
528
529 /// A window with no clauses at all, which is what `OVER ()` means.
530 pub const fn empty() -> Self {
531 Self {
532 partition: Slice { start: 0, len: 0 },
533 order: Slice { start: 0, len: 0 },
534 unit: Self::DEFAULT_UNIT,
535 start: Self::DEFAULT_START,
536 end: Self::DEFAULT_END,
537 exclude: WindowExclude::NoOthers,
538 }
539 }
540
541 /// Whether the frame is the one an unwritten frame clause means.
542 ///
543 /// This is what decides whether the frame is printed, which is not a matter of taste: the
544 /// printed form is the column name a window target gets when the query wrote no alias, so
545 /// `SELECT sum(x) OVER (ORDER BY x)` has to be named without a frame in it to agree with the
546 /// reference binary.
547 pub fn frame_is_default(&self) -> bool {
548 self.unit == Self::DEFAULT_UNIT
549 && self.start == Self::DEFAULT_START
550 && self.end == Self::DEFAULT_END
551 && self.exclude == WindowExclude::NoOthers
552 }
553}
554
555/// One entry in a `FROM` clause, which is a tree because joins nest.
556#[derive(Debug, Clone, Copy, PartialEq, Eq)]
557pub enum Source {
558 /// A named table, possibly qualified by schema and catalog.
559 Table {
560 /// The name, as a run of [`StrRef`] in `Ast::parts`, outermost first.
561 name: Slice,
562 /// The alias, or `NONE`.
563 alias: StrRef,
564 /// Column aliases from `AS t(a, b)`, as a run of [`StrRef`].
565 columns: Slice,
566 },
567 /// A materialised `WITH` named where a table goes.
568 ///
569 /// Which definition it reads is settled here rather than left as a name, because shadowing is
570 /// a question about where the name was written and this is the only place that still knows.
571 Cte {
572 /// Which definition, as an index into `Ast::ctes`.
573 cte: u32,
574 /// The alias, or `NONE`, which for a bare name is the name itself.
575 alias: StrRef,
576 /// Column aliases from `AS c(a, b)`, as a run of [`StrRef`].
577 columns: Slice,
578 },
579 /// A parenthesised query in the `FROM` clause.
580 Subquery {
581 /// The query.
582 query: QueryRef,
583 /// The alias, or `NONE`.
584 alias: StrRef,
585 /// Column aliases, as a run of [`StrRef`].
586 columns: Slice,
587 },
588 /// A function call where a table goes, such as `range(10)`.
589 ///
590 /// Held with the name as a qualified run rather than a single string, because `main.range(10)`
591 /// is legal and a function in a schema that does not exist has to say so rather than being
592 /// looked up unqualified and found.
593 Function {
594 /// The name, as a run of [`StrRef`] in `Ast::parts`, outermost first.
595 name: Slice,
596 /// The arguments, as a run of [`Target`] where the alias is the parameter name and is
597 /// `NONE` for a positional one.
598 args: Slice,
599 /// The alias, or `NONE`.
600 alias: StrRef,
601 /// Column aliases from `AS t(a, b)`, as a run of [`StrRef`].
602 columns: Slice,
603 /// Whether the call was written as `PRAGMA name` rather than as a function call.
604 ///
605 /// The two are the same query, because `PRAGMA table_info('t')` is rewritten to
606 /// `SELECT * FROM pragma_table_info('t')` here the way upstream rewrites it, and the
607 /// rewritten form is what the plan and the deparser see. What the flag is for is the two
608 /// messages a bad call produces, which upstream writes in the spelling the user used:
609 /// `table_info()` rather than `pragma_table_info()`, and a candidate line reading
610 /// `PRAGMA "table_info"(VARCHAR)`. A user who wrote a pragma and is told about a function
611 /// they did not name has been handed the rewrite to debug rather than their own statement.
612 pragma: bool,
613 },
614 /// A `VALUES` in the `FROM` clause.
615 Values {
616 /// The rows, as a run of [`Slice`] in `Ast::rows`.
617 rows: Slice,
618 /// The alias, or `NONE`.
619 alias: StrRef,
620 /// Column aliases, as a run of [`StrRef`].
621 columns: Slice,
622 },
623 /// Two sources joined.
624 Join {
625 /// The left side.
626 left: SourceRef,
627 /// The right side.
628 right: SourceRef,
629 /// Which join.
630 kind: JoinKind,
631 /// Whether it was written `NATURAL`.
632 natural: bool,
633 /// The `ON` expression, or `NONE`.
634 on: ExprRef,
635 /// The `USING` column list, as a run of [`StrRef`].
636 using: Slice,
637 },
638}
639
640/// Which join.
641#[derive(Debug, Clone, Copy, PartialEq, Eq)]
642pub enum JoinKind {
643 /// `[INNER] JOIN`.
644 Inner,
645 /// `LEFT [OUTER] JOIN`.
646 Left,
647 /// `RIGHT [OUTER] JOIN`.
648 Right,
649 /// `FULL [OUTER] JOIN`.
650 Full,
651 /// `SEMI JOIN`.
652 Semi,
653 /// `ANTI JOIN`.
654 Anti,
655 /// `CROSS JOIN`.
656 Cross,
657 /// `POSITIONAL JOIN`, which is DuckDB's own and pairs rows by ordinal.
658 Positional,
659}
660
661/// One expression.
662///
663/// Twenty four bytes, which is the widest variant rounded up. The precedence chain in the grammar
664/// does not survive into here: twenty levels of `X <- Y Tail*` become one [`Expr::Binary`] tree,
665/// because the levels exist to make the grammar unambiguous and mean nothing afterwards.
666#[derive(Debug, Clone, Copy, PartialEq, Eq)]
667pub enum Expr {
668 /// `*`, or `t.*` with a qualifier.
669 Star {
670 /// The qualifier, as a run of [`StrRef`], empty for a bare star.
671 qualifier: Slice,
672 /// `REPLACE (expression AS column)`, as a run of [`Target`] where the alias is the column
673 /// being replaced, empty for a star with no replace list.
674 ///
675 /// A [`Target`] rather than a type of its own because a replacement is an expression and a
676 /// name, which is exactly what a target is, and because that puts it in the arena every
677 /// other expression and name pair already lives in.
678 replacements: Slice,
679 },
680 /// A column reference, qualified or not.
681 Column {
682 /// The name, as a run of [`StrRef`], outermost first, so `s.t.a` is three parts.
683 name: Slice,
684 },
685 /// A literal, kept as the text that was written.
686 Literal {
687 /// Which kind.
688 kind: LiteralKind,
689 /// The text, with quotes stripped and escapes resolved for a string, `NONE` for a keyword
690 /// literal like `NULL` where the kind already says everything.
691 text: StrRef,
692 },
693 /// A prefix or postfix operator.
694 Unary {
695 /// Which operator.
696 op: UnaryOp,
697 /// What it applies to.
698 operand: ExprRef,
699 },
700 /// An infix operator.
701 Binary {
702 /// Which operator.
703 op: BinaryOp,
704 /// The left operand.
705 left: ExprRef,
706 /// The right operand.
707 right: ExprRef,
708 },
709 /// A function call.
710 Function {
711 /// The name, as a run of [`StrRef`], so `main.count` is two parts.
712 name: Slice,
713 /// The arguments, as a run of [`ExprRef`].
714 args: Slice,
715 /// Whether the call said `DISTINCT`.
716 distinct: bool,
717 /// The `FILTER (WHERE ...)` predicate, or `NONE`. Kept on every call and not only on the
718 /// ones that can carry it, because which names can carry it is a question about the
719 /// function catalog and the parser does not have one.
720 filter: ExprRef,
721 },
722 /// A function call with an `OVER` on the end of it.
723 ///
724 /// Kept apart from [`Expr::Function`] rather than given an optional window, because the two
725 /// are different things by every rule that applies to them: a window call is refused in a
726 /// `WHERE` and in a `HAVING`, it may not appear inside an aggregate, and it resolves against a
727 /// different set of names. A variant that only some of the code has to remember to look at is
728 /// a variant the rest of the code gets wrong.
729 Window {
730 /// The name, as a run of [`StrRef`], so `main.sum` is two parts.
731 name: Slice,
732 /// The arguments, as a run of [`ExprRef`].
733 args: Slice,
734 /// Whether the call said `DISTINCT`.
735 distinct: bool,
736 /// The `FILTER (WHERE ...)` predicate, or `NONE`. It is written before the `OVER` and not
737 /// after it, which is a rule of the grammar rather than of the binder.
738 filter: ExprRef,
739 /// Whether the call said `IGNORE NULLS`. `RESPECT NULLS` is the default and is not kept,
740 /// because the reference binary drops it: a view written with it comes back without it.
741 ignore_nulls: bool,
742 /// The window itself, into `Ast::windows`.
743 spec: WindowRef,
744 },
745 /// `CAST(x AS t)` or `TRY_CAST(x AS t)`.
746 Cast {
747 /// What is being cast.
748 operand: ExprRef,
749 /// The target type, as the text it was written with. Parsing it is `rudb-common`'s job and
750 /// doing it here would put the type system in the parser.
751 ty: StrRef,
752 /// Whether a failure yields null rather than an error.
753 try_cast: bool,
754 },
755 /// `CASE`, searched or simple.
756 Case {
757 /// The operand of a simple `CASE x WHEN`, or `NONE` for a searched one.
758 operand: ExprRef,
759 /// The arms, as a run of [`CaseArm`].
760 arms: Slice,
761 /// The `ELSE`, or `NONE`.
762 otherwise: ExprRef,
763 },
764 /// `x BETWEEN a AND b`.
765 Between {
766 /// What is being tested.
767 operand: ExprRef,
768 /// The lower bound.
769 low: ExprRef,
770 /// The upper bound.
771 high: ExprRef,
772 /// Whether it was written `NOT BETWEEN`.
773 negated: bool,
774 },
775 /// `x IN (a, b, c)`.
776 In {
777 /// What is being tested.
778 operand: ExprRef,
779 /// The list, as a run of [`ExprRef`].
780 list: Slice,
781 /// Whether it was written `NOT IN`.
782 negated: bool,
783 },
784 /// `x IN (SELECT ...)` or its negation.
785 InSubquery {
786 /// What is being tested.
787 operand: ExprRef,
788 /// The query producing the candidates.
789 query: QueryRef,
790 /// Whether it was written `NOT IN`.
791 negated: bool,
792 },
793 /// `x op ANY (SELECT ...)` or `x op ALL (SELECT ...)`.
794 QuantifiedSubquery {
795 /// The value on the left of the comparison.
796 operand: ExprRef,
797 /// The comparison applied to each candidate.
798 op: BinaryOp,
799 /// The query producing the candidates.
800 query: QueryRef,
801 /// Whether the quantifier was `ALL` rather than `ANY`.
802 all: bool,
803 },
804 /// A prepared statement parameter, written `?`, `?1`, `$1` or `$name`.
805 Parameter {
806 /// The identifier, which is the number for a positional one and the word for a named one.
807 /// A bare `?` is numbered by where it was written, so the identifier is there either way.
808 name: StrRef,
809 },
810 /// A bracketed list of expressions, `[a, b, c]`, which is a LIST value.
811 List {
812 /// The items, as a run of [`ExprRef`], in the order they were written.
813 items: Slice,
814 },
815 /// A parenthesised list of more than one expression, which is a row value.
816 Row {
817 /// The items, as a run of [`ExprRef`].
818 items: Slice,
819 },
820 /// A scalar subquery, `(SELECT ...)` where an expression is expected.
821 Subquery {
822 /// The query.
823 query: QueryRef,
824 },
825 /// `EXISTS (SELECT ...)` or its negation.
826 Exists {
827 /// The query whose cardinality is tested.
828 query: QueryRef,
829 /// Whether `NOT` was written before `EXISTS`.
830 negated: bool,
831 },
832}
833
834/// One `WHEN a THEN b`.
835#[derive(Debug, Clone, Copy, PartialEq, Eq)]
836pub struct CaseArm {
837 /// The `WHEN`.
838 pub when: ExprRef,
839 /// The `THEN`.
840 pub then: ExprRef,
841}
842
843/// Which literal.
844#[derive(Debug, Clone, Copy, PartialEq, Eq)]
845pub enum LiteralKind {
846 /// A number, kept as text because the width it wants depends on where it lands.
847 Number,
848 /// A string.
849 String,
850 /// A blob, kept as the text a blob prints as, which is the text a cast reads it back from.
851 Blob,
852 /// `NULL`.
853 Null,
854 /// `TRUE`.
855 True,
856 /// `FALSE`.
857 False,
858}
859
860/// A prefix or postfix operator.
861#[derive(Debug, Clone, Copy, PartialEq, Eq)]
862pub enum UnaryOp {
863 /// `NOT x`.
864 Not,
865 /// `-x`.
866 Negate,
867 /// `+x`, which is a no-op that still has to survive to the binder so that `+'a'` errors.
868 Plus,
869 /// `~x`.
870 BitNot,
871 /// `x!`.
872 Factorial,
873 /// `x IS NULL` or `x ISNULL`.
874 IsNull,
875 /// `x IS NOT NULL` or `x NOTNULL`.
876 IsNotNull,
877 /// `x IS TRUE`.
878 IsTrue,
879 /// `x IS NOT TRUE`.
880 IsNotTrue,
881 /// `x IS FALSE`.
882 IsFalse,
883 /// `x IS NOT FALSE`.
884 IsNotFalse,
885 /// `x IS UNKNOWN`.
886 IsUnknown,
887 /// `x IS NOT UNKNOWN`.
888 IsNotUnknown,
889}
890
891/// An infix operator.
892///
893/// The list is the dialect and not a general idea of what operators are. `Named` is the one open
894/// door, because `OperatorLiteral` in the grammar takes any run of operator characters that is not
895/// already a token, and rejecting that here would reject SQL DuckDB accepts.
896#[derive(Debug, Clone, Copy, PartialEq, Eq)]
897pub enum BinaryOp {
898 /// `OR`.
899 Or,
900 /// `AND`.
901 And,
902 /// `=` or `==`.
903 Eq,
904 /// `!=` or `<>`.
905 NotEq,
906 /// `<`.
907 Lt,
908 /// `>`.
909 Gt,
910 /// `<=`.
911 LtEq,
912 /// `>=`.
913 GtEq,
914 /// `IS DISTINCT FROM`.
915 IsDistinctFrom,
916 /// `IS NOT DISTINCT FROM`.
917 IsNotDistinctFrom,
918 /// `+`.
919 Add,
920 /// `-`.
921 Subtract,
922 /// `*`.
923 Multiply,
924 /// `/`.
925 Divide,
926 /// `//`, integer division.
927 IntegerDivide,
928 /// `%`.
929 Modulo,
930 /// `^` or `**`.
931 Power,
932 /// `&`.
933 BitAnd,
934 /// `|`.
935 BitOr,
936 /// `<<`.
937 ShiftLeft,
938 /// `>>`.
939 ShiftRight,
940 /// `||`.
941 Concat,
942 /// `LIKE` or `~~`.
943 Like,
944 /// `NOT LIKE` or `!~~`.
945 NotLike,
946 /// `ILIKE` or `~~*`.
947 ILike,
948 /// `NOT ILIKE` or `!~~*`.
949 NotILike,
950 /// `GLOB` or `~~~`.
951 Glob,
952 /// `SIMILAR TO`.
953 SimilarTo,
954 /// `NOT SIMILAR TO`.
955 NotSimilarTo,
956 /// `~`, a regex match.
957 Regex,
958 /// `!~`, a negated regex match.
959 NotRegex,
960 /// `~*`, a case insensitive regex match.
961 RegexInsensitive,
962 /// `!~*`, a negated case insensitive regex match.
963 NotRegexInsensitive,
964 /// `COLLATE`.
965 Collate,
966 /// `AT TIME ZONE`.
967 AtTimeZone,
968 /// `->`.
969 Arrow,
970 /// `->>`.
971 LongArrow,
972 /// `@>`, contains.
973 Contains,
974 /// `<@`, contained by.
975 ContainedBy,
976 /// `&&`, overlaps.
977 Overlaps,
978 /// `^@`, starts with.
979 StartsWith,
980 /// `<<=`, an inet operator.
981 InetContainedByOrEq,
982 /// `>>=`, an inet operator.
983 InetContainsOrEq,
984 /// An operator the dialect does not name, which DuckDB resolves as a binary function of that
985 /// name. `a <=> b` is the shape.
986 Named(StrRef),
987}
988
989/// A parsed statement or script, with every arena it points into.
990///
991/// Cheap to clone, cheap to send, and self contained: no index in here refers to anything outside
992/// it, and nothing in here borrows the query text. The text is copied into `strings` on the way in,
993/// which costs one allocation per distinct identifier and buys an `Ast` that outlives the string it
994/// came from.
995#[derive(Debug, Clone, Default, PartialEq, Eq)]
996pub struct Ast {
997 /// The statements in the script, in order.
998 pub statements: Vec<Statement>,
999 /// The query arena.
1000 pub queries: Vec<Query>,
1001 /// Source ranges parallel to `queries`.
1002 pub query_spans: Vec<Span>,
1003 /// The select arena.
1004 pub selects: Vec<Select>,
1005 /// The expression arena.
1006 pub exprs: Vec<Expr>,
1007 /// Source ranges parallel to `exprs`.
1008 pub expr_spans: Vec<Span>,
1009 /// The from-item arena.
1010 pub sources: Vec<Source>,
1011 /// Interned text. Identifiers keep the case they were written in, because DuckDB does not fold
1012 /// it at any point, including for quoted identifiers.
1013 pub strings: Vec<String>,
1014 /// Backing store for every [`Slice`] of names.
1015 pub parts: Vec<StrRef>,
1016 /// Backing store for every [`Slice`] of expressions.
1017 pub expr_lists: Vec<ExprRef>,
1018 /// Backing store for every [`Slice`] of from items.
1019 pub source_lists: Vec<SourceRef>,
1020 /// Backing store for every [`Slice`] of target list entries.
1021 pub targets: Vec<Target>,
1022 /// Backing store for every [`Slice`] of order by entries.
1023 pub order_items: Vec<OrderItem>,
1024 /// Backing store for every [`Slice`] of case arms.
1025 pub case_arms: Vec<CaseArm>,
1026 /// The `CREATE TABLE` arena.
1027 pub create_tables: Vec<CreateTable>,
1028 /// The `CREATE VIEW` arena.
1029 pub create_views: Vec<CreateView>,
1030 /// The `DROP TABLE` arena.
1031 pub drop_tables: Vec<DropTable>,
1032 /// The `INSERT` arena.
1033 pub inserts: Vec<Insert>,
1034 /// The `SET` and `RESET` arena.
1035 pub settings: Vec<Setting>,
1036 /// Backing store for every [`Slice`] of column definitions.
1037 pub column_defs: Vec<ColumnDef>,
1038 /// Backing store for every [`Slice`] of names, which is a name list rather than a name.
1039 pub name_lists: Vec<Slice>,
1040 /// Backing store for the rows of a `VALUES`, each of which is a run of expressions.
1041 pub rows: Vec<Slice>,
1042 /// The window arena, holding what was inside the parentheses of every `OVER`.
1043 pub windows: Vec<WindowSpec>,
1044 /// The materialised `WITH` arena.
1045 pub ctes: Vec<Cte>,
1046 /// Backing store for every [`Slice`] of materialised `WITH` indexes.
1047 pub cte_lists: Vec<u32>,
1048}
1049
1050impl Ast {
1051 /// The source range of an expression.
1052 pub fn expr_span(&self, expr: ExprRef) -> Span {
1053 self.expr_spans[expr as usize]
1054 }
1055
1056 /// The source range of a query.
1057 pub fn query_span(&self, query: QueryRef) -> Span {
1058 self.query_spans[query as usize]
1059 }
1060
1061 /// The text behind a [`StrRef`], or the empty string for `NONE`.
1062 pub fn string(&self, index: StrRef) -> &str {
1063 if index == NONE { "" } else { &self.strings[index as usize] }
1064 }
1065
1066 /// Every parameter identifier the statement uses, once each, in the order they were written.
1067 ///
1068 /// The arena is built as the walk goes, so its order is the written order, and a parameter used
1069 /// twice is one identifier here because it is one value to provide.
1070 pub fn parameters(&self) -> Vec<&str> {
1071 let mut found: Vec<&str> = Vec::new();
1072 for expr in &self.exprs {
1073 if let Expr::Parameter { name } = *expr {
1074 let name = self.string(name);
1075 if !found.contains(&name) {
1076 found.push(name);
1077 }
1078 }
1079 }
1080 found
1081 }
1082
1083 /// The parts of a name, outermost first.
1084 pub fn name(&self, slice: Slice) -> impl Iterator<Item = &str> {
1085 self.parts[slice.range()].iter().map(|&part| self.string(part))
1086 }
1087
1088 /// A name written back out with dots between the parts, for error messages and tests.
1089 pub fn name_text(&self, slice: Slice) -> String {
1090 self.name(slice).collect::<Vec<_>>().join(".")
1091 }
1092
1093 /// One expression.
1094 pub fn expr(&self, index: ExprRef) -> Expr {
1095 self.exprs[index as usize]
1096 }
1097
1098 /// One from item.
1099 pub fn source(&self, index: SourceRef) -> Source {
1100 self.sources[index as usize]
1101 }
1102
1103 /// One query.
1104 pub fn query(&self, index: QueryRef) -> Query {
1105 self.queries[index as usize]
1106 }
1107
1108 /// One select block.
1109 pub fn select(&self, index: SelectRef) -> Select {
1110 self.selects[index as usize]
1111 }
1112
1113 /// One window.
1114 pub fn window(&self, index: WindowRef) -> WindowSpec {
1115 self.windows[index as usize]
1116 }
1117
1118 /// One materialised `WITH` definition.
1119 pub fn cte(&self, index: u32) -> Cte {
1120 self.ctes[index as usize]
1121 }
1122
1123 /// The materialised `WITH` definitions a query introduces, outermost first.
1124 pub fn cte_list(&self, slice: Slice) -> &[u32] {
1125 &self.cte_lists[slice.range()]
1126 }
1127
1128 /// The expressions of a list.
1129 pub fn expr_list(&self, slice: Slice) -> &[ExprRef] {
1130 &self.expr_lists[slice.range()]
1131 }
1132
1133 /// The from items of a list.
1134 pub fn source_list(&self, slice: Slice) -> &[SourceRef] {
1135 &self.source_lists[slice.range()]
1136 }
1137
1138 /// The entries of a target list.
1139 pub fn target_list(&self, slice: Slice) -> &[Target] {
1140 &self.targets[slice.range()]
1141 }
1142
1143 /// The entries of an order by list.
1144 pub fn order_list(&self, slice: Slice) -> &[OrderItem] {
1145 &self.order_items[slice.range()]
1146 }
1147
1148 /// The arms of a case.
1149 pub fn arm_list(&self, slice: Slice) -> &[CaseArm] {
1150 &self.case_arms[slice.range()]
1151 }
1152
1153 /// One `CREATE TABLE`.
1154 pub fn create_table(&self, index: CreateTableRef) -> CreateTable {
1155 self.create_tables[index as usize]
1156 }
1157
1158 /// One `CREATE VIEW`.
1159 pub fn create_view(&self, index: CreateViewRef) -> CreateView {
1160 self.create_views[index as usize]
1161 }
1162
1163 /// One `DROP TABLE`.
1164 pub fn drop_table(&self, index: DropTableRef) -> DropTable {
1165 self.drop_tables[index as usize]
1166 }
1167
1168 /// One `INSERT`.
1169 pub fn insert(&self, index: InsertRef) -> Insert {
1170 self.inserts[index as usize]
1171 }
1172
1173 /// One `SET` or `RESET`.
1174 pub fn setting(&self, index: SettingRef) -> Setting {
1175 self.settings[index as usize]
1176 }
1177
1178 /// The column definitions of a `CREATE TABLE`.
1179 pub fn column_defs(&self, slice: Slice) -> &[ColumnDef] {
1180 &self.column_defs[slice.range()]
1181 }
1182
1183 /// The names of a name list, each of which is itself a run of parts.
1184 pub fn name_list(&self, slice: Slice) -> &[Slice] {
1185 &self.name_lists[slice.range()]
1186 }
1187
1188 /// The rows of a `VALUES`, each of which is itself a run of expressions.
1189 pub fn rows(&self, slice: Slice) -> &[Slice] {
1190 &self.rows[slice.range()]
1191 }
1192
1193 /// How many nodes the whole tree is, across every arena.
1194 ///
1195 /// The number to watch when the transformer changes. A parse tree of five thousand nodes that
1196 /// becomes an AST of thirty is the twenty precedence levels being thrown away, which is the
1197 /// whole reason this module exists.
1198 pub fn node_count(&self) -> usize {
1199 self.queries.len() + self.selects.len() + self.exprs.len() + self.sources.len()
1200 }
1201}