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