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