Skip to main content

alopex_sql/ast/
expr.rs

1use super::ddl::DataType;
2use super::dml::OrderByExpr;
3use super::span::{Span, Spanned};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Expr {
8    pub kind: ExprKind,
9    pub span: Span,
10}
11
12impl Expr {
13    pub fn new(kind: ExprKind, span: Span) -> Self {
14        Self { kind, span }
15    }
16}
17
18impl Spanned for Expr {
19    fn span(&self) -> Span {
20        self.span
21    }
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25#[serde(tag = "variant")]
26#[allow(clippy::large_enum_variant)]
27pub enum ExprKind {
28    Literal {
29        literal: Literal,
30    },
31    ColumnRef {
32        table: Option<String>,
33        column: String,
34    },
35    BinaryOp {
36        left: Box<Expr>,
37        op: BinaryOp,
38        right: Box<Expr>,
39    },
40    UnaryOp {
41        op: UnaryOp,
42        operand: Box<Expr>,
43    },
44    Case {
45        operand: Option<Box<Expr>>,
46        branches: Vec<CaseWhen>,
47        else_expr: Option<Box<Expr>>,
48    },
49    FunctionCall {
50        name: String,
51        args: Vec<Expr>,
52        distinct: bool,
53        star: bool,
54        #[serde(default)]
55        over: Option<WindowSpec>,
56    },
57    Cast {
58        expr: Box<Expr>,
59        target_type: DataType,
60    },
61    Between {
62        expr: Box<Expr>,
63        low: Box<Expr>,
64        high: Box<Expr>,
65        negated: bool,
66    },
67    Like {
68        expr: Box<Expr>,
69        pattern: Box<Expr>,
70        escape: Option<Box<Expr>>,
71        negated: bool,
72        #[serde(default)]
73        kind: PatternMatchKind,
74    },
75    InList {
76        expr: Box<Expr>,
77        list: Vec<Expr>,
78        negated: bool,
79    },
80    IsNull {
81        expr: Box<Expr>,
82        negated: bool,
83    },
84    VectorLiteral {
85        values: Vec<f64>,
86    },
87    ScalarSubquery {
88        subquery: Box<super::Statement>,
89    },
90    InSubquery {
91        expr: Box<Expr>,
92        subquery: Box<super::Statement>,
93        negated: bool,
94    },
95    Exists {
96        subquery: Box<super::Statement>,
97        negated: bool,
98    },
99    Quantified {
100        expr: Box<Expr>,
101        op: BinaryOp,
102        quantifier: Quantifier,
103        subquery: Box<super::Statement>,
104    },
105}
106
107/// A window specification attached to a function call through `OVER (...)`.
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct WindowSpec {
110    #[serde(default)]
111    pub partition_by: Vec<Expr>,
112    #[serde(default)]
113    pub order_by: Vec<OrderByExpr>,
114    /// Optional explicit frame. `None` selects the SQL implicit frame.
115    #[serde(default)]
116    pub frame: Option<WindowFrame>,
117}
118
119/// An explicit SQL window frame.
120#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
121pub struct WindowFrame {
122    pub units: WindowFrameUnits,
123    pub start_bound: WindowFrameBound,
124    pub end_bound: WindowFrameBound,
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
128pub enum WindowFrameUnits {
129    Rows,
130    Range,
131}
132
133#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
134#[serde(tag = "variant", content = "value")]
135pub enum WindowFrameBound {
136    UnboundedPreceding,
137    Preceding(u64),
138    CurrentRow,
139    Following(u64),
140    UnboundedFollowing,
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct CaseWhen {
145    pub when: Expr,
146    pub then: Expr,
147}
148
149#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
150pub enum PatternMatchKind {
151    #[default]
152    Like,
153    ILike,
154    Glob,
155    SimilarTo,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize)]
159#[serde(tag = "variant", content = "value")]
160pub enum Literal {
161    Number(String),
162    String(String),
163    Boolean(bool),
164    Null,
165    /// SQL-TS interval text, preserved for a downstream semantic layer.
166    ///
167    /// Appended to preserve existing bincode discriminants.
168    Interval(String),
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
172pub enum BinaryOp {
173    Add,
174    Sub,
175    Mul,
176    Div,
177    Mod,
178    Eq,
179    Neq,
180    Lt,
181    Gt,
182    LtEq,
183    GtEq,
184    And,
185    Or,
186    StringConcat,
187}
188
189#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
190pub enum UnaryOp {
191    Not,
192    Minus,
193}
194
195#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
196pub enum Quantifier {
197    Any,
198    All,
199}