wasm_dbms_sql/ast.rs
1//! Abstract syntax tree of the supported SQL dialect.
2//!
3//! [`parse`](crate::parse) produces these types. They describe the statement
4//! exactly as written: names are not checked against a schema and literals are
5//! not converted to column types yet. The grammar they model is documented in
6//! the SQL reference of the wasm-dbms book.
7
8/// A parsed SQL statement.
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum Statement {
11 /// `SELECT ...`
12 ///
13 /// Boxed because a `SELECT` is much larger than the other statements.
14 Select(Box<Select>),
15 /// `INSERT INTO ...`
16 Insert(Insert),
17 /// `UPDATE ...`
18 Update(Update),
19 /// `DELETE FROM ...`
20 Delete(Delete),
21 /// `BEGIN [TRANSACTION]`
22 Begin,
23 /// `COMMIT [TRANSACTION]`
24 Commit,
25 /// `ROLLBACK [TRANSACTION]`
26 Rollback,
27}
28
29/// A `SELECT` statement.
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct Select {
32 /// Whether `DISTINCT` follows `SELECT`.
33 pub distinct: bool,
34 /// The select list.
35 pub projection: Projection,
36 /// The `FROM` table.
37 pub from: TableRef,
38 /// The `JOIN` clauses, in source order.
39 pub joins: Vec<JoinClause>,
40 /// The `WHERE` condition.
41 pub filter: Option<Condition>,
42 /// The `GROUP BY` columns.
43 pub group_by: Vec<ColumnRef>,
44 /// The `HAVING` condition.
45 pub having: Option<Condition>,
46 /// The `ORDER BY` items, most significant first.
47 pub order_by: Vec<OrderItem>,
48 /// The `LIMIT` row count.
49 pub limit: Option<RowCount>,
50 /// The `OFFSET` row count.
51 pub offset: Option<RowCount>,
52}
53
54/// The select list of a [`Select`].
55#[derive(Debug, Clone, PartialEq, Eq)]
56pub enum Projection {
57 /// `*`: every column.
58 All,
59 /// An explicit list of columns and aggregates.
60 Items(Vec<SelectItem>),
61}
62
63/// One entry of an explicit select list: `operand [AS alias]`.
64#[derive(Debug, Clone, PartialEq, Eq)]
65pub struct SelectItem {
66 /// The selected column or aggregate.
67 pub operand: Operand,
68 /// The output name given with `AS`.
69 pub alias: Option<String>,
70}
71
72/// Something that yields a value per row or per group.
73#[derive(Debug, Clone, PartialEq, Eq)]
74pub enum Operand {
75 /// A column reference.
76 Column(ColumnRef),
77 /// An aggregate function call.
78 Aggregate(Aggregate),
79}
80
81/// A column name, optionally qualified: `column` or `table.column`.
82#[derive(Debug, Clone, PartialEq, Eq)]
83pub struct ColumnRef {
84 /// The table name or table alias before the dot.
85 pub table: Option<String>,
86 /// The column name.
87 pub column: String,
88}
89
90/// An aggregate function call such as `COUNT(*)` or `SUM(price)`.
91#[derive(Debug, Clone, PartialEq, Eq)]
92pub struct Aggregate {
93 /// The aggregate function.
94 pub function: AggregateKind,
95 /// The aggregated column; `None` only for `COUNT(*)`.
96 pub column: Option<ColumnRef>,
97}
98
99/// The supported aggregate functions.
100#[derive(Debug, Clone, Copy, PartialEq, Eq)]
101pub enum AggregateKind {
102 Count,
103 Sum,
104 Avg,
105 Min,
106 Max,
107}
108
109/// A table in `FROM` or `JOIN`: `name [[AS] alias]`.
110#[derive(Debug, Clone, PartialEq, Eq)]
111pub struct TableRef {
112 /// The table name.
113 pub name: String,
114 /// The alias that replaces the table name as column qualifier.
115 pub alias: Option<String>,
116}
117
118/// A `JOIN table ON left = right` clause.
119#[derive(Debug, Clone, PartialEq, Eq)]
120pub struct JoinClause {
121 /// The join type.
122 pub kind: JoinKind,
123 /// The joined table.
124 pub table: TableRef,
125 /// The column written on the left of `=`.
126 pub left: ColumnRef,
127 /// The column written on the right of `=`.
128 pub right: ColumnRef,
129}
130
131/// The supported join types.
132#[derive(Debug, Clone, Copy, PartialEq, Eq)]
133pub enum JoinKind {
134 /// `JOIN` or `INNER JOIN`
135 Inner,
136 /// `LEFT [OUTER] JOIN`
137 Left,
138 /// `RIGHT [OUTER] JOIN`
139 Right,
140 /// `FULL [OUTER] JOIN`
141 Full,
142}
143
144/// A boolean condition of a `WHERE` or `HAVING` clause.
145#[derive(Debug, Clone, PartialEq, Eq)]
146pub enum Condition {
147 /// `left AND right`
148 And(Box<Condition>, Box<Condition>),
149 /// `left OR right`
150 Or(Box<Condition>, Box<Condition>),
151 /// `NOT inner`
152 Not(Box<Condition>),
153 /// `operand op value`
154 Compare {
155 operand: Operand,
156 op: CompareOp,
157 value: ValueExpr,
158 },
159 /// `operand [NOT] IN (values)`
160 In {
161 operand: Operand,
162 values: Vec<ValueExpr>,
163 negated: bool,
164 },
165 /// `operand [NOT] LIKE pattern`
166 Like {
167 operand: Operand,
168 pattern: ValueExpr,
169 negated: bool,
170 },
171 /// `operand IS [NOT] NULL`
172 IsNull { operand: Operand, negated: bool },
173}
174
175/// A comparison operator.
176#[derive(Debug, Clone, Copy, PartialEq, Eq)]
177pub enum CompareOp {
178 /// `=`
179 Eq,
180 /// `!=` or `<>`
181 NotEq,
182 /// `<`
183 Lt,
184 /// `<=`
185 LtEq,
186 /// `>`
187 Gt,
188 /// `>=`
189 GtEq,
190}
191
192/// A value written in the statement: a literal or a `?` placeholder.
193#[derive(Debug, Clone, PartialEq, Eq)]
194pub enum ValueExpr {
195 /// A literal value.
196 Literal(Literal),
197 /// The `?` placeholder with this 0-based position in the statement.
198 Parameter(usize),
199}
200
201/// A literal value, before conversion to a column type.
202#[derive(Debug, Clone, PartialEq, Eq)]
203pub enum Literal {
204 /// An integer, with its sign applied.
205 Integer(i128),
206 /// A decimal number as written (`[-]digits.digits`).
207 Float(String),
208 /// The content of a single-quoted string.
209 String(String),
210 /// `TRUE` or `FALSE`
211 Boolean(bool),
212 /// `NULL`
213 Null,
214}
215
216/// One `ORDER BY` entry: `operand [ASC | DESC]`.
217#[derive(Debug, Clone, PartialEq, Eq)]
218pub struct OrderItem {
219 /// The column, select-list alias, or aggregate to sort by.
220 pub operand: Operand,
221 /// Whether `DESC` was given.
222 pub descending: bool,
223}
224
225/// The argument of `LIMIT` or `OFFSET`.
226#[derive(Debug, Clone, PartialEq, Eq)]
227pub enum RowCount {
228 /// A non-negative integer literal.
229 Value(u64),
230 /// The `?` placeholder with this 0-based position in the statement.
231 Parameter(usize),
232}
233
234/// An `INSERT INTO table (columns) VALUES (values)` statement.
235#[derive(Debug, Clone, PartialEq, Eq)]
236pub struct Insert {
237 /// The target table.
238 pub table: String,
239 /// The listed columns.
240 pub columns: Vec<String>,
241 /// One value per listed column, in the same order.
242 pub values: Vec<ValueExpr>,
243}
244
245/// An `UPDATE table SET assignments WHERE condition` statement.
246#[derive(Debug, Clone, PartialEq, Eq)]
247pub struct Update {
248 /// The target table.
249 pub table: String,
250 /// The `SET` assignments.
251 pub assignments: Vec<Assignment>,
252 /// The mandatory `WHERE` condition.
253 pub filter: Condition,
254}
255
256/// One `column = value` entry of an `UPDATE ... SET` list.
257#[derive(Debug, Clone, PartialEq, Eq)]
258pub struct Assignment {
259 /// The column to write.
260 pub column: String,
261 /// The new value.
262 pub value: ValueExpr,
263}
264
265/// A `DELETE FROM table WHERE condition [CASCADE | RESTRICT]` statement.
266#[derive(Debug, Clone, PartialEq, Eq)]
267pub struct Delete {
268 /// The target table.
269 pub table: String,
270 /// The mandatory `WHERE` condition.
271 pub filter: Condition,
272 /// Whether `CASCADE` was given; `RESTRICT` is the default.
273 pub cascade: bool,
274}