Skip to main content

qail_core/ast/
operators.rs

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