1use super::common::{FieldRef, OrderByDef};
2use super::conditions::Conditions;
3use super::custom::{CustomBinaryOp, CustomExpr};
4use super::query::QueryStmt;
5use super::value::Value;
6
7#[derive(Debug, Clone)]
9pub enum Expr {
10 Value(Value),
12
13 Field(FieldRef),
15
16 Binary {
18 left: Box<Expr>,
19 op: BinaryOp,
20 right: Box<Expr>,
21 },
22
23 Unary { op: UnaryOp, expr: Box<Expr> },
25
26 Func { name: String, args: Vec<Expr> },
28
29 Aggregate(AggregationDef),
31
32 Cast { expr: Box<Expr>, to_type: String },
34
35 Case(CaseDef),
37
38 Window(WindowDef),
40
41 Exists(Box<QueryStmt>),
43
44 SubQuery(Box<QueryStmt>),
46
47 ArraySubQuery(Box<QueryStmt>),
49
50 Collate { expr: Box<Expr>, collation: String },
52
53 JsonArray(Vec<Expr>),
55
56 JsonObject(Vec<(String, Expr)>),
58
59 JsonAgg {
61 expr: Box<Expr>,
62 distinct: bool,
63 filter: Option<Conditions>,
64 order_by: Option<Vec<OrderByDef>>,
65 },
66
67 StringAgg {
69 expr: Box<Expr>,
70 delimiter: String,
71 distinct: bool,
72 filter: Option<Conditions>,
73 order_by: Option<Vec<OrderByDef>>,
74 },
75
76 Now,
78
79 Raw { sql: String, params: Vec<Value> },
81
82 Custom(Box<dyn CustomExpr>),
84}
85
86impl Expr {
87 pub fn field(table: &str, name: &str) -> Self {
89 Expr::Field(FieldRef::new(table, name))
90 }
91
92 pub fn value(val: impl Into<Value>) -> Self {
94 Expr::Value(val.into())
95 }
96
97 pub fn raw(sql: impl Into<String>) -> Self {
99 Expr::Raw {
100 sql: sql.into(),
101 params: vec![],
102 }
103 }
104
105 pub fn func(name: impl Into<String>, args: Vec<Expr>) -> Self {
107 Expr::Func {
108 name: name.into(),
109 args,
110 }
111 }
112
113 pub fn cast(expr: Expr, to_type: impl Into<String>) -> Self {
115 Expr::Cast {
116 expr: Box::new(expr),
117 to_type: to_type.into(),
118 }
119 }
120
121 pub fn count(expr: Expr) -> Self {
123 Expr::Aggregate(AggregationDef {
124 name: "COUNT".into(),
125 expression: Some(Box::new(expr)),
126 distinct: false,
127 filter: None,
128 args: None,
129 order_by: None,
130 })
131 }
132
133 pub fn count_all() -> Self {
135 Expr::Aggregate(AggregationDef {
136 name: "COUNT".into(),
137 expression: None,
138 distinct: false,
139 filter: None,
140 args: None,
141 order_by: None,
142 })
143 }
144
145 pub fn sum(expr: Expr) -> Self {
147 Expr::Aggregate(AggregationDef {
148 name: "SUM".into(),
149 expression: Some(Box::new(expr)),
150 distinct: false,
151 filter: None,
152 args: None,
153 order_by: None,
154 })
155 }
156
157 pub fn avg(expr: Expr) -> Self {
159 Expr::Aggregate(AggregationDef {
160 name: "AVG".into(),
161 expression: Some(Box::new(expr)),
162 distinct: false,
163 filter: None,
164 args: None,
165 order_by: None,
166 })
167 }
168
169 pub fn min(expr: Expr) -> Self {
171 Expr::Aggregate(AggregationDef {
172 name: "MIN".into(),
173 expression: Some(Box::new(expr)),
174 distinct: false,
175 filter: None,
176 args: None,
177 order_by: None,
178 })
179 }
180
181 pub fn max(expr: Expr) -> Self {
183 Expr::Aggregate(AggregationDef {
184 name: "MAX".into(),
185 expression: Some(Box::new(expr)),
186 distinct: false,
187 filter: None,
188 args: None,
189 order_by: None,
190 })
191 }
192
193 pub fn exists(query: QueryStmt) -> Self {
195 Expr::Exists(Box::new(query))
196 }
197
198 pub fn subquery(query: QueryStmt) -> Self {
200 Expr::SubQuery(Box::new(query))
201 }
202
203 pub fn collate(self, collation: impl Into<String>) -> Self {
205 Expr::Collate {
206 expr: Box::new(self),
207 collation: collation.into(),
208 }
209 }
210
211 pub fn json_array(items: Vec<Expr>) -> Self {
213 Expr::JsonArray(items)
214 }
215
216 pub fn json_object(pairs: Vec<(impl Into<String>, Expr)>) -> Self {
218 Expr::JsonObject(pairs.into_iter().map(|(k, v)| (k.into(), v)).collect())
219 }
220
221 pub fn json_agg(expr: Expr) -> Self {
223 Expr::JsonAgg {
224 expr: Box::new(expr),
225 distinct: false,
226 filter: None,
227 order_by: None,
228 }
229 }
230
231 pub fn string_agg(expr: Expr, delimiter: impl Into<String>) -> Self {
233 Expr::StringAgg {
234 expr: Box::new(expr),
235 delimiter: delimiter.into(),
236 distinct: false,
237 filter: None,
238 order_by: None,
239 }
240 }
241
242 pub fn now() -> Self {
244 Expr::Now
245 }
246}
247
248impl From<Value> for Expr {
249 fn from(v: Value) -> Self {
250 Expr::Value(v)
251 }
252}
253
254impl From<FieldRef> for Expr {
255 fn from(f: FieldRef) -> Self {
256 Expr::Field(f)
257 }
258}
259
260#[derive(Debug, Clone)]
262pub enum BinaryOp {
263 Add,
264 Sub,
265 Mul,
266 Div,
267 Mod,
268 BitwiseAnd,
269 BitwiseOr,
270 ShiftLeft,
271 ShiftRight,
272 Concat,
273
274 Custom(Box<dyn CustomBinaryOp>),
276}
277
278#[derive(Debug, Clone, Copy, PartialEq, Eq)]
280pub enum UnaryOp {
281 Neg,
282 Not,
283 BitwiseNot,
284}
285
286#[derive(Debug, Clone)]
288pub struct AggregationDef {
289 pub name: String,
290 pub expression: Option<Box<Expr>>,
291 pub distinct: bool,
292 pub filter: Option<Conditions>,
293 pub args: Option<Vec<Expr>>,
294 pub order_by: Option<Vec<OrderByDef>>,
295}
296
297impl AggregationDef {
298 pub fn new(name: impl Into<String>, expr: Expr) -> Self {
299 Self {
300 name: name.into(),
301 expression: Some(Box::new(expr)),
302 distinct: false,
303 filter: None,
304 args: None,
305 order_by: None,
306 }
307 }
308
309 pub fn count_all() -> Self {
310 Self {
311 name: "COUNT".into(),
312 expression: None,
313 distinct: false,
314 filter: None,
315 args: None,
316 order_by: None,
317 }
318 }
319
320 pub fn distinct(mut self) -> Self {
321 self.distinct = true;
322 self
323 }
324
325 pub fn filter(mut self, cond: Conditions) -> Self {
326 self.filter = Some(cond);
327 self
328 }
329
330 pub fn order_by(mut self, order: Vec<OrderByDef>) -> Self {
331 self.order_by = Some(order);
332 self
333 }
334}
335
336#[derive(Debug, Clone)]
338pub struct CaseDef {
339 pub cases: Vec<WhenClause>,
340 pub default: Option<Box<Expr>>,
341}
342
343#[derive(Debug, Clone)]
345pub struct WhenClause {
346 pub condition: Conditions,
347 pub result: Expr,
348}
349
350#[derive(Debug, Clone)]
352pub struct WindowDef {
353 pub expression: Box<Expr>,
354 pub partition_by: Option<Vec<Expr>>,
355 pub order_by: Option<Vec<OrderByDef>>,
356 pub frame: Option<WindowFrameDef>,
357}
358
359#[derive(Debug, Clone)]
361pub struct WindowFrameDef {
362 pub frame_type: WindowFrameType,
363 pub start: WindowFrameBound,
364 pub end: Option<WindowFrameBound>,
365}
366
367#[derive(Debug, Clone, Copy, PartialEq, Eq)]
369pub enum WindowFrameType {
370 Rows,
371 Range,
372 Groups,
373}
374
375#[derive(Debug, Clone, PartialEq, Eq)]
377pub enum WindowFrameBound {
378 CurrentRow,
379 Preceding(Option<u64>),
380 Following(Option<u64>),
381}