Skip to main content

qail_core/ast/
operators.rs

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