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}