Skip to main content

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    /// COUNT query.
9    Cnt,
10    /// UPDATE statement.
11    Set,
12    /// DELETE statement.
13    Del,
14    /// INSERT statement.
15    Add,
16    /// Code generation.
17    Gen,
18    /// CREATE TABLE.
19    Make,
20    /// DROP TABLE.
21    Drop,
22    /// ALTER TABLE (add column).
23    Mod,
24    /// UPSERT / ON CONFLICT … DO UPDATE.
25    Over,
26    /// CTE / WITH clause.
27    With,
28    /// CREATE INDEX.
29    Index,
30    /// DROP INDEX.
31    DropIndex,
32    /// ALTER TABLE (generic).
33    Alter,
34    /// ALTER TABLE … DROP COLUMN.
35    AlterDrop,
36    /// ALTER TABLE … ALTER COLUMN TYPE.
37    AlterType,
38    /// BEGIN TRANSACTION.
39    TxnStart,
40    /// COMMIT.
41    TxnCommit,
42    /// ROLLBACK.
43    TxnRollback,
44    /// Bulk INSERT / COPY.
45    Put,
46    /// DROP COLUMN.
47    DropCol,
48    /// ALTER TABLE … RENAME COLUMN.
49    RenameCol,
50    /// JSONB_TO_RECORDSET.
51    JsonTable,
52    /// COPY … TO STDOUT.
53    Export,
54    /// TRUNCATE TABLE.
55    Truncate,
56    /// EXPLAIN.
57    Explain,
58    /// EXPLAIN ANALYZE.
59    ExplainAnalyze,
60    /// LOCK TABLE.
61    Lock,
62    /// CREATE MATERIALIZED VIEW.
63    CreateMaterializedView,
64    /// REFRESH MATERIALIZED VIEW.
65    RefreshMaterializedView,
66    /// DROP MATERIALIZED VIEW.
67    DropMaterializedView,
68    /// LISTEN (async notifications).
69    Listen,
70    /// NOTIFY (async notifications).
71    Notify,
72    /// UNLISTEN (async notifications).
73    Unlisten,
74    /// SAVEPOINT.
75    Savepoint,
76    /// RELEASE SAVEPOINT.
77    ReleaseSavepoint,
78    /// ROLLBACK TO SAVEPOINT.
79    RollbackToSavepoint,
80    /// CREATE VIEW.
81    CreateView,
82    /// DROP VIEW.
83    DropView,
84    /// Full-text or vector search.
85    Search,
86    /// INSERT … ON CONFLICT DO UPDATE.
87    Upsert,
88    /// Cursor-based scrolling.
89    Scroll,
90    /// Create vector collection (Qdrant).
91    CreateCollection,
92    /// Delete vector collection (Qdrant).
93    DeleteCollection,
94    /// CREATE FUNCTION.
95    CreateFunction,
96    /// DROP FUNCTION.
97    DropFunction,
98    /// CREATE TRIGGER.
99    CreateTrigger,
100    /// DROP TRIGGER.
101    DropTrigger,
102    /// CREATE EXTENSION.
103    CreateExtension,
104    /// DROP EXTENSION.
105    DropExtension,
106    /// COMMENT ON.
107    CommentOn,
108    /// CREATE SEQUENCE.
109    CreateSequence,
110    /// DROP SEQUENCE.
111    DropSequence,
112    /// CREATE TYPE … AS ENUM.
113    CreateEnum,
114    /// DROP TYPE.
115    DropEnum,
116    /// ALTER TYPE … ADD VALUE.
117    AlterEnumAddValue,
118    /// ALTER COLUMN SET NOT NULL.
119    AlterSetNotNull,
120    /// ALTER COLUMN DROP NOT NULL.
121    AlterDropNotNull,
122    /// ALTER COLUMN SET DEFAULT.
123    AlterSetDefault,
124    /// ALTER COLUMN DROP DEFAULT.
125    AlterDropDefault,
126    /// ALTER TABLE ENABLE ROW LEVEL SECURITY.
127    AlterEnableRls,
128    /// ALTER TABLE DISABLE ROW LEVEL SECURITY.
129    AlterDisableRls,
130    /// ALTER TABLE FORCE ROW LEVEL SECURITY.
131    AlterForceRls,
132    /// ALTER TABLE NO FORCE ROW LEVEL SECURITY.
133    AlterNoForceRls,
134    // Session & procedural commands
135    /// CALL procedure.
136    Call,
137    /// DO anonymous block.
138    Do,
139    /// SET session variable.
140    SessionSet,
141    /// SHOW session variable.
142    SessionShow,
143    /// RESET session variable.
144    SessionReset,
145}
146
147impl std::fmt::Display for Action {
148    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149        match self {
150            Action::Get => write!(f, "GET"),
151            Action::Cnt => write!(f, "CNT"),
152            Action::Set => write!(f, "SET"),
153            Action::Del => write!(f, "DEL"),
154            Action::Add => write!(f, "ADD"),
155            Action::Gen => write!(f, "GEN"),
156            Action::Make => write!(f, "MAKE"),
157            Action::Drop => write!(f, "DROP"),
158            Action::Mod => write!(f, "MOD"),
159            Action::Over => write!(f, "OVER"),
160            Action::With => write!(f, "WITH"),
161            Action::Index => write!(f, "INDEX"),
162            Action::DropIndex => write!(f, "DROP_INDEX"),
163            Action::Alter => write!(f, "ALTER"),
164            Action::AlterDrop => write!(f, "ALTER_DROP"),
165            Action::AlterType => write!(f, "ALTER_TYPE"),
166            Action::TxnStart => write!(f, "TXN_START"),
167            Action::TxnCommit => write!(f, "TXN_COMMIT"),
168            Action::TxnRollback => write!(f, "TXN_ROLLBACK"),
169            Action::Put => write!(f, "PUT"),
170            Action::DropCol => write!(f, "DROP_COL"),
171            Action::RenameCol => write!(f, "RENAME_COL"),
172            Action::JsonTable => write!(f, "JSON_TABLE"),
173            Action::Export => write!(f, "EXPORT"),
174            Action::Truncate => write!(f, "TRUNCATE"),
175            Action::Explain => write!(f, "EXPLAIN"),
176            Action::ExplainAnalyze => write!(f, "EXPLAIN_ANALYZE"),
177            Action::Lock => write!(f, "LOCK"),
178            Action::CreateMaterializedView => write!(f, "CREATE_MATERIALIZED_VIEW"),
179            Action::RefreshMaterializedView => write!(f, "REFRESH_MATERIALIZED_VIEW"),
180            Action::DropMaterializedView => write!(f, "DROP_MATERIALIZED_VIEW"),
181            Action::Listen => write!(f, "LISTEN"),
182            Action::Notify => write!(f, "NOTIFY"),
183            Action::Unlisten => write!(f, "UNLISTEN"),
184            Action::Savepoint => write!(f, "SAVEPOINT"),
185            Action::ReleaseSavepoint => write!(f, "RELEASE_SAVEPOINT"),
186            Action::RollbackToSavepoint => write!(f, "ROLLBACK_TO_SAVEPOINT"),
187            Action::CreateView => write!(f, "CREATE_VIEW"),
188            Action::DropView => write!(f, "DROP_VIEW"),
189            Action::Search => write!(f, "SEARCH"),
190            Action::Upsert => write!(f, "UPSERT"),
191            Action::Scroll => write!(f, "SCROLL"),
192            Action::CreateCollection => write!(f, "CREATE_COLLECTION"),
193            Action::DeleteCollection => write!(f, "DELETE_COLLECTION"),
194            Action::CreateFunction => write!(f, "CREATE_FUNCTION"),
195            Action::DropFunction => write!(f, "DROP_FUNCTION"),
196            Action::CreateTrigger => write!(f, "CREATE_TRIGGER"),
197            Action::DropTrigger => write!(f, "DROP_TRIGGER"),
198            Action::CreateExtension => write!(f, "CREATE_EXTENSION"),
199            Action::DropExtension => write!(f, "DROP_EXTENSION"),
200            Action::CommentOn => write!(f, "COMMENT_ON"),
201            Action::CreateSequence => write!(f, "CREATE_SEQUENCE"),
202            Action::DropSequence => write!(f, "DROP_SEQUENCE"),
203            Action::CreateEnum => write!(f, "CREATE_ENUM"),
204            Action::DropEnum => write!(f, "DROP_ENUM"),
205            Action::AlterEnumAddValue => write!(f, "ALTER_ENUM_ADD_VALUE"),
206            Action::AlterSetNotNull => write!(f, "ALTER_SET_NOT_NULL"),
207            Action::AlterDropNotNull => write!(f, "ALTER_DROP_NOT_NULL"),
208            Action::AlterSetDefault => write!(f, "ALTER_SET_DEFAULT"),
209            Action::AlterDropDefault => write!(f, "ALTER_DROP_DEFAULT"),
210            Action::AlterEnableRls => write!(f, "ALTER_ENABLE_RLS"),
211            Action::AlterDisableRls => write!(f, "ALTER_DISABLE_RLS"),
212            Action::AlterForceRls => write!(f, "ALTER_FORCE_RLS"),
213            Action::AlterNoForceRls => write!(f, "ALTER_NO_FORCE_RLS"),
214            Action::Call => write!(f, "CALL"),
215            Action::Do => write!(f, "DO"),
216            Action::SessionSet => write!(f, "SESSION_SET"),
217            Action::SessionShow => write!(f, "SESSION_SHOW"),
218            Action::SessionReset => write!(f, "SESSION_RESET"),
219        }
220    }
221}
222
223/// Logical operator between conditions.
224#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
225pub enum LogicalOp {
226    #[default]
227    /// Logical AND.
228    And,
229    /// Logical OR.
230    Or,
231}
232
233/// Sort direction.
234#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
235pub enum SortOrder {
236    /// Ascending.
237    Asc,
238    /// Descending.
239    Desc,
240    /// Ascending, NULLs first.
241    AscNullsFirst,
242    /// Ascending, NULLs last.
243    AscNullsLast,
244    /// Descending, NULLs first.
245    DescNullsFirst,
246    /// Descending, NULLs last.
247    DescNullsLast,
248}
249
250/// Comparison / filtering operator.
251#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
252pub enum Operator {
253    /// `=`
254    Eq,
255    /// `!=`
256    Ne,
257    /// `>`
258    Gt,
259    /// `>=`
260    Gte,
261    /// `<`
262    Lt,
263    /// `<=`
264    Lte,
265    /// Case-insensitive LIKE (legacy alias for [`ILike`](Operator::ILike)).
266    Fuzzy,
267    /// IN (list).
268    In,
269    /// NOT IN (list).
270    NotIn,
271    /// IS NULL.
272    IsNull,
273    /// IS NOT NULL.
274    IsNotNull,
275    /// JSONB `@>` containment.
276    Contains,
277    /// JSONB `?` key existence.
278    KeyExists,
279    /// JSON_EXISTS path check.
280    JsonExists,
281    /// JSON_QUERY path extraction.
282    JsonQuery,
283    /// JSON_VALUE scalar extraction.
284    JsonValue,
285    /// LIKE pattern match.
286    Like,
287    /// NOT LIKE.
288    NotLike,
289    /// ILIKE (case-insensitive).
290    ILike,
291    /// NOT ILIKE.
292    NotILike,
293    /// BETWEEN low AND high.
294    Between,
295    /// NOT BETWEEN.
296    NotBetween,
297    /// EXISTS (subquery).
298    Exists,
299    /// NOT EXISTS (subquery).
300    NotExists,
301    /// POSIX regex `~`.
302    Regex,
303    /// Case-insensitive regex `~*`.
304    RegexI,
305    /// SIMILAR TO.
306    SimilarTo,
307    /// JSONB `<@` contained-by.
308    ContainedBy,
309    /// Array `&&` overlap.
310    Overlaps,
311    /// Full-text search `@@`.
312    TextSearch,
313    /// `?|` — does JSONB contain ANY of the given keys?
314    KeyExistsAny,
315    /// `?&` — does JSONB contain ALL of the given keys?
316    KeyExistsAll,
317    /// `#>` — JSONB path extraction → jsonb
318    JsonPath,
319    /// `#>>` — JSONB path extraction → text
320    JsonPathText,
321    /// `LOWER(text) LIKE '%' || LOWER(array_element) || '%'` over `unnest(array_column)`.
322    /// Used for "does input text contain any keyword token?" matching.
323    ArrayElemContainedInText,
324}
325
326impl Operator {
327    /// For simple operators, returns the symbol directly.
328    /// For complex operators (BETWEEN, EXISTS), returns the keyword.
329    pub fn sql_symbol(&self) -> &'static str {
330        match self {
331            Operator::Eq => "=",
332            Operator::Ne => "!=",
333            Operator::Gt => ">",
334            Operator::Gte => ">=",
335            Operator::Lt => "<",
336            Operator::Lte => "<=",
337            Operator::Fuzzy => "ILIKE",
338            Operator::In => "IN",
339            Operator::NotIn => "NOT IN",
340            Operator::IsNull => "IS NULL",
341            Operator::IsNotNull => "IS NOT NULL",
342            Operator::Contains => "@>",
343            Operator::KeyExists => "?",
344            Operator::JsonExists => "JSON_EXISTS",
345            Operator::JsonQuery => "JSON_QUERY",
346            Operator::JsonValue => "JSON_VALUE",
347            Operator::Like => "LIKE",
348            Operator::NotLike => "NOT LIKE",
349            Operator::ILike => "ILIKE",
350            Operator::NotILike => "NOT ILIKE",
351            Operator::Between => "BETWEEN",
352            Operator::NotBetween => "NOT BETWEEN",
353            Operator::Exists => "EXISTS",
354            Operator::NotExists => "NOT EXISTS",
355            Operator::Regex => "~",
356            Operator::RegexI => "~*",
357            Operator::SimilarTo => "SIMILAR TO",
358            Operator::ContainedBy => "<@",
359            Operator::Overlaps => "&&",
360            Operator::TextSearch => "@@",
361            Operator::KeyExistsAny => "?|",
362            Operator::KeyExistsAll => "?&",
363            Operator::JsonPath => "#>",
364            Operator::JsonPathText => "#>>",
365            Operator::ArrayElemContainedInText => "CONTAINS_ANY_TOKEN",
366        }
367    }
368
369    /// IS NULL, IS NOT NULL, EXISTS, NOT EXISTS don't need values.
370    pub fn needs_value(&self) -> bool {
371        !matches!(
372            self,
373            Operator::IsNull | Operator::IsNotNull | Operator::Exists | Operator::NotExists
374        )
375    }
376
377    /// Returns `true` for simple binary operators (=, !=, >, <, LIKE, ILIKE, etc.).
378    pub fn is_simple_binary(&self) -> bool {
379        matches!(
380            self,
381            Operator::Eq
382                | Operator::Ne
383                | Operator::Gt
384                | Operator::Gte
385                | Operator::Lt
386                | Operator::Lte
387                | Operator::Like
388                | Operator::NotLike
389                | Operator::ILike
390                | Operator::NotILike
391        )
392    }
393}
394
395/// Aggregate function.
396#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
397pub enum AggregateFunc {
398    /// COUNT(*).
399    Count,
400    /// SUM.
401    Sum,
402    /// AVG.
403    Avg,
404    /// MIN.
405    Min,
406    /// MAX.
407    Max,
408    /// ARRAY_AGG.
409    ArrayAgg,
410    /// STRING_AGG.
411    StringAgg,
412    /// JSON_AGG.
413    JsonAgg,
414    /// JSONB_AGG.
415    JsonbAgg,
416    /// BOOL_AND.
417    BoolAnd,
418    /// BOOL_OR.
419    BoolOr,
420}
421
422impl std::fmt::Display for AggregateFunc {
423    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
424        match self {
425            AggregateFunc::Count => write!(f, "COUNT"),
426            AggregateFunc::Sum => write!(f, "SUM"),
427            AggregateFunc::Avg => write!(f, "AVG"),
428            AggregateFunc::Min => write!(f, "MIN"),
429            AggregateFunc::Max => write!(f, "MAX"),
430            AggregateFunc::ArrayAgg => write!(f, "ARRAY_AGG"),
431            AggregateFunc::StringAgg => write!(f, "STRING_AGG"),
432            AggregateFunc::JsonAgg => write!(f, "JSON_AGG"),
433            AggregateFunc::JsonbAgg => write!(f, "JSONB_AGG"),
434            AggregateFunc::BoolAnd => write!(f, "BOOL_AND"),
435            AggregateFunc::BoolOr => write!(f, "BOOL_OR"),
436        }
437    }
438}
439
440/// Join Type
441#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
442pub enum JoinKind {
443    /// INNER JOIN.
444    Inner,
445    /// LEFT (OUTER) JOIN.
446    Left,
447    /// RIGHT (OUTER) JOIN.
448    Right,
449    /// LATERAL join.
450    Lateral,
451    /// FULL (OUTER) JOIN.
452    Full,
453    /// CROSS JOIN.
454    Cross,
455}
456
457/// Set operation type for combining queries
458#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
459pub enum SetOp {
460    /// UNION (de-duplicated).
461    Union,
462    /// UNION ALL.
463    UnionAll,
464    /// INTERSECT.
465    Intersect,
466    /// EXCEPT.
467    Except,
468}
469
470/// ALTER TABLE modification kind.
471#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
472pub enum ModKind {
473    /// ADD.
474    Add,
475    /// DROP.
476    Drop,
477}
478
479/// GROUP BY mode for advanced aggregations
480#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
481pub enum GroupByMode {
482    #[default]
483    /// Standard GROUP BY.
484    Simple,
485    /// GROUP BY ROLLUP.
486    Rollup,
487    /// GROUP BY CUBE.
488    Cube,
489    /// GROUP BY GROUPING SETS.
490    GroupingSets(Vec<Vec<String>>),
491}
492
493impl GroupByMode {
494    /// Check if this is the default Simple mode (for serde skip)
495    pub fn is_simple(&self) -> bool {
496        matches!(self, GroupByMode::Simple)
497    }
498}
499
500/// Row locking mode for SELECT...FOR UPDATE/SHARE
501#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
502pub enum LockMode {
503    /// FOR UPDATE.
504    Update,
505    /// FOR NO KEY UPDATE.
506    NoKeyUpdate,
507    /// FOR SHARE.
508    Share,
509    /// FOR KEY SHARE.
510    KeyShare,
511}
512
513/// OVERRIDING clause for INSERT with GENERATED columns
514#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
515pub enum OverridingKind {
516    /// OVERRIDING SYSTEM VALUE.
517    SystemValue,
518    /// OVERRIDING USER VALUE.
519    UserValue,
520}
521
522/// TABLESAMPLE sampling method
523#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
524pub enum SampleMethod {
525    /// Random row sampling (row-level).
526    Bernoulli,
527    /// Block-level sampling.
528    System,
529}
530
531/// Distance metric for vector similarity
532#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
533pub enum Distance {
534    #[default]
535    /// Cosine similarity.
536    Cosine,
537    /// Euclidean distance.
538    Euclid,
539    /// Dot product.
540    Dot,
541}