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