sql_from_models_parser/ast/expression/mod.rs
1mod display;
2use super::*;
3use serde::{Serialize, Deserialize};
4/// An SQL expression of any type.
5///
6/// The parser does not distinguish between expressions of different types
7/// (e.g. boolean vs string), so the caller must handle expressions of
8/// inappropriate type, like `WHERE 1` or `SELECT 1=1`, as necessary.
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11pub enum Expr {
12 /// Identifier e.g. table name or column name
13 Identifier(Ident),
14 /// Unqualified wildcard (`*`). SQL allows this in limited contexts, such as:
15 /// - right after `SELECT` (which is represented as a [SelectItem::Wildcard] instead)
16 /// - or as part of an aggregate function, e.g. `COUNT(*)`,
17 ///
18 /// ...but we currently also accept it in contexts where it doesn't make
19 /// sense, such as `* + *`
20 Wildcard,
21 /// Qualified wildcard, e.g. `alias.*` or `schema.table.*`.
22 /// (Same caveats apply to `QualifiedWildcard` as to `Wildcard`.)
23 QualifiedWildcard(Vec<Ident>),
24 /// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col`
25 CompoundIdentifier(Vec<Ident>),
26 /// `IS NULL` expression
27 IsNull(Box<Expr>),
28 /// `IS NOT NULL` expression
29 IsNotNull(Box<Expr>),
30 /// `[ NOT ] IN (val1, val2, ...)`
31 InList(InList),
32 /// `[ NOT ] IN (SELECT ...)`
33 InSubquery(InSubquery),
34 /// `<expr> [ NOT ] BETWEEN <low> AND <high>`
35 Between(Between),
36 /// Binary operation e.g. `1 + 1` or `foo > bar`
37 BinaryOp(BinaryOp),
38 /// Unary operation e.g. `NOT foo`
39 UnaryOp(UnaryOp),
40 /// CAST an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))`
41 Cast(Cast),
42 /// TRY_CAST an expression to a different data type e.g. `TRY_CAST(foo AS VARCHAR(123))`
43 // this differs from CAST in the choice of how to implement invalid conversions
44 TryCast(TryCast),
45 /// EXTRACT(DateTimeField FROM <expr>)
46 Extract(Extract),
47 /// SUBSTRING(<expr> [FROM <expr>] [FOR <expr>])
48 Substring(Substring),
49 /// TRIM([BOTH | LEADING | TRAILING] <expr> [FROM <expr>])\
50 /// Or\
51 /// TRIM(<expr>)
52 Trim(Trim),
53 /// `expr COLLATE collation`
54 Collate(Collate),
55 /// Nested expression e.g. `(foo > bar)` or `(1)`
56 Nested(Box<Expr>),
57 /// A literal value, such as string, number, date or NULL
58 Value(Value),
59 /// A constant of form `<data_type> 'value'`.
60 /// This can represent ANSI SQL `DATE`, `TIME`, and `TIMESTAMP` literals (such as `DATE '2020-01-01'`),
61 /// as well as constants of other types (a non-standard PostgreSQL extension).
62 TypedString(TypedString),
63 MapAccess(MapAccess),
64 /// Scalar function call e.g. `LEFT(foo, 5)`
65 Function(Function),
66 /// `CASE [<operand>] WHEN <condition> THEN <result> ... [ELSE <result>] END`
67 ///
68 /// Note we only recognize a complete single expression as `<condition>`,
69 /// not `< 0` nor `1, 2, 3` as allowed in a `<simple when clause>` per
70 /// <https://jakewheat.github.io/sql-overview/sql-2011-foundation-grammar.html#simple-when-clause>
71 Case(Case),
72 /// An exists expression `EXISTS(SELECT ...)`, used in expressions like
73 /// `WHERE EXISTS (SELECT ...)`.
74 Exists(Box<Query>),
75 /// A parenthesized subquery `(SELECT ...)`, used in expression like
76 /// `SELECT (subquery) AS x` or `WHERE (subquery) = x`
77 Subquery(Box<Query>),
78 /// The `LISTAGG` function `SELECT LISTAGG(...) WITHIN GROUP (ORDER BY ...)`
79 ListAgg(ListAgg),
80}
81
82/// `CASE [<operand>] WHEN <condition> THEN <result> ... [ELSE <result>] END`
83///
84/// Note we only recognize a complete single expression as `<condition>`,
85/// not `< 0` nor `1, 2, 3` as allowed in a `<simple when clause>` per
86/// <https://jakewheat.github.io/sql-overview/sql-2011-foundation-grammar.html#simple-when-clause>
87#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
88pub struct Case {
89 pub operand: Option<Box<Expr>>,
90 pub conditions: Vec<Expr>,
91 pub results: Vec<Expr>,
92 pub else_result: Option<Box<Expr>>,
93}
94
95/// `[ NOT ] IN (val1, val2, ...)`
96#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
97pub struct InList {
98 pub expr: Box<Expr>,
99 pub list: Vec<Expr>,
100 pub negated: bool,
101}
102/// `[ NOT ] IN (SELECT ...)`
103#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
104pub struct InSubquery {
105 pub expr: Box<Expr>,
106 pub subquery: Box<Query>,
107 pub negated: bool,
108}
109/// `<expr> [ NOT ] BETWEEN <low> AND <high>`
110#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
111pub struct Between {
112 pub expr: Box<Expr>,
113 pub negated: bool,
114 pub low: Box<Expr>,
115 pub high: Box<Expr>,
116}
117/// Binary operation e.g. `1 + 1` or `foo > bar`
118#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
119pub struct BinaryOp {
120 pub left: Box<Expr>,
121 pub op: BinaryOperator,
122 pub right: Box<Expr>,
123}
124/// Unary operation e.g. `NOT foo`
125#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
126pub struct UnaryOp {
127 pub op: UnaryOperator,
128 pub expr: Box<Expr>,
129}
130/// CAST an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))`
131#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
132pub struct Cast {
133 pub expr: Box<Expr>,
134 pub data_type: DataType,
135}
136/// TRY_CAST an expression to a different data type e.g. `TRY_CAST(foo AS VARCHAR(123))`
137// this differs from CAST in the choice of how to implement invalid conversions
138#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
139pub struct TryCast {
140 pub expr: Box<Expr>,
141 pub data_type: DataType,
142}
143/// EXTRACT(DateTimeField FROM <expr>)
144#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
145pub struct Extract {
146 pub field: DateTimeField,
147 pub expr: Box<Expr>,
148}
149/// SUBSTRING(<expr> [FROM <expr>] [FOR <expr>])
150#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
151pub struct Substring {
152 pub expr: Box<Expr>,
153 pub substring_from: Option<Box<Expr>>,
154 pub substring_for: Option<Box<Expr>>,
155}
156/// TRIM([BOTH | LEADING | TRAILING] <expr> [FROM <expr>])\
157/// Or\
158/// TRIM(<expr>)
159#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
160pub struct Trim {
161 pub expr: Box<Expr>,
162 // ([BOTH | LEADING | TRAILING], <expr>)
163 pub trim_where: Option<(TrimWhereField, Box<Expr>)>,
164}
165/// `expr COLLATE collation`
166#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
167pub struct Collate {
168 pub expr: Box<Expr>,
169 pub collation: ObjectName,
170}
171
172/// A constant of form `<data_type> 'value'`.
173/// This can represent ANSI SQL `DATE`, `TIME`, and `TIMESTAMP` literals (such as `DATE '2020-01-01'`),
174/// as well as constants of other types (a non-standard PostgreSQL extension).
175#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
176pub struct TypedString {
177 pub data_type: DataType,
178 pub value: String,
179}
180#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
181pub struct MapAccess {
182 pub column: Box<Expr>,
183 pub key: String,
184}