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 JsonPathText { expr: Box<Expr>, path: String },
79
80 Now,
82
83 CurrentTimestamp,
85
86 CurrentDate,
88
89 CurrentTime,
91
92 Tuple(Vec<Expr>),
94
95 Param { type_hint: Option<String> },
99
100 Raw { sql: String, params: Vec<Value> },
102
103 Custom(Box<dyn CustomExpr>),
105}
106
107impl Expr {
108 pub fn field(table: &str, name: &str) -> Self {
110 Expr::Field(FieldRef::new(table, name))
111 }
112
113 pub fn value(val: impl Into<Value>) -> Self {
115 Expr::Value(val.into())
116 }
117
118 pub fn raw(sql: impl Into<String>) -> Self {
120 Expr::Raw {
121 sql: sql.into(),
122 params: vec![],
123 }
124 }
125
126 pub fn func(name: impl Into<String>, args: Vec<Expr>) -> Self {
128 Expr::Func {
129 name: name.into(),
130 args,
131 }
132 }
133
134 pub fn cast(expr: Expr, to_type: impl Into<String>) -> Self {
136 Expr::Cast {
137 expr: Box::new(expr),
138 to_type: to_type.into(),
139 }
140 }
141
142 pub fn count(expr: Expr) -> Self {
144 Expr::Aggregate(AggregationDef {
145 name: "COUNT".into(),
146 expression: Some(Box::new(expr)),
147 distinct: false,
148 filter: None,
149 args: None,
150 order_by: None,
151 })
152 }
153
154 pub fn count_all() -> Self {
156 Expr::Aggregate(AggregationDef {
157 name: "COUNT".into(),
158 expression: None,
159 distinct: false,
160 filter: None,
161 args: None,
162 order_by: None,
163 })
164 }
165
166 pub fn sum(expr: Expr) -> Self {
168 Expr::Aggregate(AggregationDef {
169 name: "SUM".into(),
170 expression: Some(Box::new(expr)),
171 distinct: false,
172 filter: None,
173 args: None,
174 order_by: None,
175 })
176 }
177
178 pub fn avg(expr: Expr) -> Self {
180 Expr::Aggregate(AggregationDef {
181 name: "AVG".into(),
182 expression: Some(Box::new(expr)),
183 distinct: false,
184 filter: None,
185 args: None,
186 order_by: None,
187 })
188 }
189
190 pub fn min(expr: Expr) -> Self {
192 Expr::Aggregate(AggregationDef {
193 name: "MIN".into(),
194 expression: Some(Box::new(expr)),
195 distinct: false,
196 filter: None,
197 args: None,
198 order_by: None,
199 })
200 }
201
202 pub fn max(expr: Expr) -> Self {
204 Expr::Aggregate(AggregationDef {
205 name: "MAX".into(),
206 expression: Some(Box::new(expr)),
207 distinct: false,
208 filter: None,
209 args: None,
210 order_by: None,
211 })
212 }
213
214 pub fn exists(query: QueryStmt) -> Self {
216 Expr::Exists(Box::new(query))
217 }
218
219 pub fn subquery(query: QueryStmt) -> Self {
221 Expr::SubQuery(Box::new(query))
222 }
223
224 pub fn collate(self, collation: impl Into<String>) -> Self {
226 Expr::Collate {
227 expr: Box::new(self),
228 collation: collation.into(),
229 }
230 }
231
232 pub fn json_array(items: Vec<Expr>) -> Self {
234 Expr::JsonArray(items)
235 }
236
237 pub fn json_object(pairs: Vec<(impl Into<String>, Expr)>) -> Self {
239 Expr::JsonObject(pairs.into_iter().map(|(k, v)| (k.into(), v)).collect())
240 }
241
242 pub fn json_agg(expr: Expr) -> Self {
244 Expr::JsonAgg {
245 expr: Box::new(expr),
246 distinct: false,
247 filter: None,
248 order_by: None,
249 }
250 }
251
252 pub fn string_agg(expr: Expr, delimiter: impl Into<String>) -> Self {
254 Expr::StringAgg {
255 expr: Box::new(expr),
256 delimiter: delimiter.into(),
257 distinct: false,
258 filter: None,
259 order_by: None,
260 }
261 }
262
263 pub fn json_path_text(expr: Expr, path: impl Into<String>) -> Self {
265 Expr::JsonPathText {
266 expr: Box::new(expr),
267 path: path.into(),
268 }
269 }
270
271 pub fn now() -> Self {
273 Expr::Now
274 }
275}
276
277impl From<Value> for Expr {
278 fn from(v: Value) -> Self {
279 Expr::Value(v)
280 }
281}
282
283impl From<FieldRef> for Expr {
284 fn from(f: FieldRef) -> Self {
285 Expr::Field(f)
286 }
287}
288
289#[derive(Debug, Clone)]
291pub enum BinaryOp {
292 Add,
293 Sub,
294 Mul,
295 Div,
296 Mod,
297 BitwiseAnd,
298 BitwiseOr,
299 ShiftLeft,
300 ShiftRight,
301 Concat,
302
303 Custom(Box<dyn CustomBinaryOp>),
305}
306
307#[derive(Debug, Clone, Copy, PartialEq, Eq)]
309pub enum UnaryOp {
310 Neg,
311 Not,
312 BitwiseNot,
313}
314
315#[derive(Debug, Clone)]
317pub struct AggregationDef {
318 pub name: String,
319 pub expression: Option<Box<Expr>>,
320 pub distinct: bool,
321 pub filter: Option<Conditions>,
322 pub args: Option<Vec<Expr>>,
323 pub order_by: Option<Vec<OrderByDef>>,
324}
325
326impl AggregationDef {
327 pub fn new(name: impl Into<String>, expr: Expr) -> Self {
328 Self {
329 name: name.into(),
330 expression: Some(Box::new(expr)),
331 distinct: false,
332 filter: None,
333 args: None,
334 order_by: None,
335 }
336 }
337
338 pub fn count_all() -> Self {
339 Self {
340 name: "COUNT".into(),
341 expression: None,
342 distinct: false,
343 filter: None,
344 args: None,
345 order_by: None,
346 }
347 }
348
349 pub fn distinct(mut self) -> Self {
350 self.distinct = true;
351 self
352 }
353
354 pub fn filter(mut self, cond: Conditions) -> Self {
355 self.filter = Some(cond);
356 self
357 }
358
359 pub fn order_by(mut self, order: Vec<OrderByDef>) -> Self {
360 self.order_by = Some(order);
361 self
362 }
363}
364
365#[derive(Debug, Clone)]
367pub struct CaseDef {
368 pub cases: Vec<WhenClause>,
369 pub default: Option<Box<Expr>>,
370}
371
372#[derive(Debug, Clone)]
374pub struct WhenClause {
375 pub condition: Conditions,
376 pub result: Expr,
377}
378
379#[derive(Debug, Clone)]
381pub struct WindowDef {
382 pub expression: Box<Expr>,
383 pub partition_by: Option<Vec<Expr>>,
384 pub order_by: Option<Vec<OrderByDef>>,
385 pub frame: Option<WindowFrameDef>,
386}
387
388#[derive(Debug, Clone)]
390pub struct WindowFrameDef {
391 pub frame_type: WindowFrameType,
392 pub start: WindowFrameBound,
393 pub end: Option<WindowFrameBound>,
394}
395
396#[derive(Debug, Clone, Copy, PartialEq, Eq)]
398pub enum WindowFrameType {
399 Rows,
400 Range,
401 Groups,
402}
403
404#[derive(Debug, Clone, PartialEq, Eq)]
406pub enum WindowFrameBound {
407 CurrentRow,
408 Preceding(Option<u64>),
409 Following(Option<u64>),
410}