qail_core/ast/
operators.rs

1use serde::{Deserialize, Serialize};
2
3/// The action type (SQL operation).
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
5pub enum Action {
6    /// SELECT query
7    Get,
8    /// UPDATE query  
9    Set,
10    Del,
11    /// INSERT query
12    Add,
13    Gen,
14    Make,
15    Drop,
16    Mod,
17    Over,
18    With,
19    Index,
20    DropIndex,
21    Alter,
22    /// ALTER TABLE DROP COLUMN
23    AlterDrop,
24    /// ALTER TABLE ALTER COLUMN TYPE
25    AlterType,
26    // Transactions
27    TxnStart,
28    TxnCommit,
29    TxnRollback,
30    Put,
31    DropCol,
32    RenameCol,
33    // Additional clauses
34    /// JSON_TABLE - convert JSON to relational rows
35    JsonTable,
36    /// COPY TO STDOUT - bulk export data (AST-native)
37    Export,
38    /// TRUNCATE TABLE - fast delete all rows
39    Truncate,
40    /// EXPLAIN - query plan analysis
41    Explain,
42    /// EXPLAIN ANALYZE - execute and analyze query plan
43    ExplainAnalyze,
44    /// LOCK TABLE - explicit table locking
45    Lock,
46    CreateMaterializedView,
47    RefreshMaterializedView,
48    DropMaterializedView,
49    // Pub/Sub (LISTEN/NOTIFY)
50    /// LISTEN channel - subscribe to notifications
51    Listen,
52    /// NOTIFY channel, 'payload' - send notification
53    Notify,
54    /// UNLISTEN channel - unsubscribe from notifications
55    Unlisten,
56    // Savepoints
57    Savepoint,
58    ReleaseSavepoint,
59    RollbackToSavepoint,
60    // Views
61    /// CREATE VIEW name AS SELECT ...
62    CreateView,
63    /// DROP VIEW name
64    DropView,
65}
66
67impl std::fmt::Display for Action {
68    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69        match self {
70            Action::Get => write!(f, "GET"),
71            Action::Set => write!(f, "SET"),
72            Action::Del => write!(f, "DEL"),
73            Action::Add => write!(f, "ADD"),
74            Action::Gen => write!(f, "GEN"),
75            Action::Make => write!(f, "MAKE"),
76            Action::Drop => write!(f, "DROP"),
77            Action::Mod => write!(f, "MOD"),
78            Action::Over => write!(f, "OVER"),
79            Action::With => write!(f, "WITH"),
80            Action::Index => write!(f, "INDEX"),
81            Action::DropIndex => write!(f, "DROP_INDEX"),
82            Action::Alter => write!(f, "ALTER"),
83            Action::AlterDrop => write!(f, "ALTER_DROP"),
84            Action::AlterType => write!(f, "ALTER_TYPE"),
85            Action::TxnStart => write!(f, "TXN_START"),
86            Action::TxnCommit => write!(f, "TXN_COMMIT"),
87            Action::TxnRollback => write!(f, "TXN_ROLLBACK"),
88            Action::Put => write!(f, "PUT"),
89            Action::DropCol => write!(f, "DROP_COL"),
90            Action::RenameCol => write!(f, "RENAME_COL"),
91            Action::JsonTable => write!(f, "JSON_TABLE"),
92            Action::Export => write!(f, "EXPORT"),
93            Action::Truncate => write!(f, "TRUNCATE"),
94            Action::Explain => write!(f, "EXPLAIN"),
95            Action::ExplainAnalyze => write!(f, "EXPLAIN_ANALYZE"),
96            Action::Lock => write!(f, "LOCK"),
97            Action::CreateMaterializedView => write!(f, "CREATE_MATERIALIZED_VIEW"),
98            Action::RefreshMaterializedView => write!(f, "REFRESH_MATERIALIZED_VIEW"),
99            Action::DropMaterializedView => write!(f, "DROP_MATERIALIZED_VIEW"),
100            Action::Listen => write!(f, "LISTEN"),
101            Action::Notify => write!(f, "NOTIFY"),
102            Action::Unlisten => write!(f, "UNLISTEN"),
103            Action::Savepoint => write!(f, "SAVEPOINT"),
104            Action::ReleaseSavepoint => write!(f, "RELEASE_SAVEPOINT"),
105            Action::RollbackToSavepoint => write!(f, "ROLLBACK_TO_SAVEPOINT"),
106            Action::CreateView => write!(f, "CREATE_VIEW"),
107            Action::DropView => write!(f, "DROP_VIEW"),
108        }
109    }
110}
111
112/// Logical operator between conditions.
113#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
114pub enum LogicalOp {
115    #[default]
116    And,
117    Or,
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
121pub enum SortOrder {
122    Asc,
123    Desc,
124    AscNullsFirst,
125    AscNullsLast,
126    DescNullsFirst,
127    DescNullsLast,
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
131pub enum Operator {
132    Eq,
133    /// Not equal (!=, <>)
134    Ne,
135    /// Greater than (>)
136    Gt,
137    /// Greater than or equal (>=)
138    Gte,
139    /// Less than (<)
140    Lt,
141    /// Less than or equal (<=)  
142    Lte,
143    Fuzzy,
144    In,
145    NotIn,
146    IsNull,
147    IsNotNull,
148    Contains,
149    KeyExists,
150    /// JSON_EXISTS - check if path exists (Postgres 17+)
151    JsonExists,
152    /// JSON_QUERY - extract JSON object/array at path (Postgres 17+)
153    JsonQuery,
154    /// JSON_VALUE - extract scalar value at path (Postgres 17+)
155    JsonValue,
156    Like,
157    NotLike,
158    /// ILIKE case-insensitive pattern match (Postgres)
159    ILike,
160    /// NOT ILIKE case-insensitive pattern match (Postgres)
161    NotILike,
162    /// BETWEEN x AND y - range check (value stored as Value::Array with 2 elements)
163    Between,
164    NotBetween,
165    /// EXISTS (subquery) - check if subquery returns any rows
166    Exists,
167    NotExists,
168    /// Regular expression match (~ in Postgres)
169    Regex,
170    /// Case-insensitive regex (~* in Postgres)
171    RegexI,
172    SimilarTo,
173    ContainedBy,
174    /// Array overlap (&&)
175    Overlaps,
176}
177
178impl Operator {
179    /// For simple operators, returns the symbol directly.
180    /// For complex operators (BETWEEN, EXISTS), returns the keyword.
181    pub fn sql_symbol(&self) -> &'static str {
182        match self {
183            Operator::Eq => "=",
184            Operator::Ne => "!=",
185            Operator::Gt => ">",
186            Operator::Gte => ">=",
187            Operator::Lt => "<",
188            Operator::Lte => "<=",
189            Operator::Fuzzy => "ILIKE",
190            Operator::In => "IN",
191            Operator::NotIn => "NOT IN",
192            Operator::IsNull => "IS NULL",
193            Operator::IsNotNull => "IS NOT NULL",
194            Operator::Contains => "@>",
195            Operator::KeyExists => "?",
196            Operator::JsonExists => "JSON_EXISTS",
197            Operator::JsonQuery => "JSON_QUERY",
198            Operator::JsonValue => "JSON_VALUE",
199            Operator::Like => "LIKE",
200            Operator::NotLike => "NOT LIKE",
201            Operator::ILike => "ILIKE",
202            Operator::NotILike => "NOT ILIKE",
203            Operator::Between => "BETWEEN",
204            Operator::NotBetween => "NOT BETWEEN",
205            Operator::Exists => "EXISTS",
206            Operator::NotExists => "NOT EXISTS",
207            Operator::Regex => "~",
208            Operator::RegexI => "~*",
209            Operator::SimilarTo => "SIMILAR TO",
210            Operator::ContainedBy => "<@",
211            Operator::Overlaps => "&&",
212        }
213    }
214
215    /// IS NULL, IS NOT NULL, EXISTS, NOT EXISTS don't need values.
216    pub fn needs_value(&self) -> bool {
217        !matches!(
218            self,
219            Operator::IsNull | Operator::IsNotNull | Operator::Exists | Operator::NotExists
220        )
221    }
222
223    pub fn is_simple_binary(&self) -> bool {
224        matches!(
225            self,
226            Operator::Eq
227                | Operator::Ne
228                | Operator::Gt
229                | Operator::Gte
230                | Operator::Lt
231                | Operator::Lte
232                | Operator::Like
233                | Operator::NotLike
234                | Operator::ILike
235                | Operator::NotILike
236        )
237    }
238}
239
240#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
241pub enum AggregateFunc {
242    Count,
243    Sum,
244    Avg,
245    Min,
246    Max,
247    /// ARRAY_AGG - collect values into array
248    ArrayAgg,
249    /// STRING_AGG - concatenate strings with delimiter
250    StringAgg,
251    /// JSON_AGG - aggregate values as JSON array
252    JsonAgg,
253    /// JSONB_AGG - aggregate values as JSONB array
254    JsonbAgg,
255    /// BOOL_AND - logical AND of all values
256    BoolAnd,
257    /// BOOL_OR - logical OR of all values
258    BoolOr,
259}
260
261impl std::fmt::Display for AggregateFunc {
262    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
263        match self {
264            AggregateFunc::Count => write!(f, "COUNT"),
265            AggregateFunc::Sum => write!(f, "SUM"),
266            AggregateFunc::Avg => write!(f, "AVG"),
267            AggregateFunc::Min => write!(f, "MIN"),
268            AggregateFunc::Max => write!(f, "MAX"),
269            AggregateFunc::ArrayAgg => write!(f, "ARRAY_AGG"),
270            AggregateFunc::StringAgg => write!(f, "STRING_AGG"),
271            AggregateFunc::JsonAgg => write!(f, "JSON_AGG"),
272            AggregateFunc::JsonbAgg => write!(f, "JSONB_AGG"),
273            AggregateFunc::BoolAnd => write!(f, "BOOL_AND"),
274            AggregateFunc::BoolOr => write!(f, "BOOL_OR"),
275        }
276    }
277}
278
279/// Join Type
280#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
281pub enum JoinKind {
282    Inner,
283    Left,
284    Right,
285    Lateral,
286    Full,
287    Cross,
288}
289
290/// Set operation type for combining queries
291#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
292pub enum SetOp {
293    Union,
294    UnionAll,
295    Intersect,
296    Except,
297}
298
299#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
300pub enum ModKind {
301    Add,
302    Drop,
303}
304
305/// GROUP BY mode for advanced aggregations
306#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
307pub enum GroupByMode {
308    /// Standard GROUP BY
309    #[default]
310    Simple,
311    /// ROLLUP - hierarchical subtotals
312    Rollup,
313    /// CUBE - all combinations of subtotals
314    Cube,
315    /// GROUPING SETS - explicit grouping sets: GROUPING SETS ((a, b), (c))
316    GroupingSets(Vec<Vec<String>>),
317}
318
319/// Row locking mode for SELECT...FOR UPDATE/SHARE
320#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
321pub enum LockMode {
322    /// FOR UPDATE - exclusive lock
323    Update,
324    /// FOR NO KEY UPDATE - weaker exclusive lock
325    NoKeyUpdate,
326    /// FOR SHARE - shared lock
327    Share,
328    /// FOR KEY SHARE - weakest shared lock
329    KeyShare,
330}
331
332/// OVERRIDING clause for INSERT with GENERATED columns
333#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
334pub enum OverridingKind {
335    /// OVERRIDING SYSTEM VALUE - override GENERATED ALWAYS columns
336    SystemValue,
337    /// OVERRIDING USER VALUE - override GENERATED BY DEFAULT columns
338    UserValue,
339}
340
341/// TABLESAMPLE sampling method
342#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
343pub enum SampleMethod {
344    /// BERNOULLI - each row has independent probability
345    Bernoulli,
346    /// SYSTEM - faster but less random (block-level sampling)
347    System,
348}