1use super::common::{FieldRef, OrderByDef};
2use super::conditions::Conditions;
3use super::custom::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 Raw { sql: String, params: Vec<Value> },
52
53 Custom(Box<dyn CustomExpr>),
55}
56
57impl Expr {
58 pub fn field(table: &str, name: &str) -> Self {
60 Expr::Field(FieldRef::new(table, name))
61 }
62
63 pub fn value(val: impl Into<Value>) -> Self {
65 Expr::Value(val.into())
66 }
67
68 pub fn raw(sql: impl Into<String>) -> Self {
70 Expr::Raw {
71 sql: sql.into(),
72 params: vec![],
73 }
74 }
75
76 pub fn func(name: impl Into<String>, args: Vec<Expr>) -> Self {
78 Expr::Func {
79 name: name.into(),
80 args,
81 }
82 }
83
84 pub fn cast(expr: Expr, to_type: impl Into<String>) -> Self {
86 Expr::Cast {
87 expr: Box::new(expr),
88 to_type: to_type.into(),
89 }
90 }
91
92 pub fn count(expr: Expr) -> Self {
94 Expr::Aggregate(AggregationDef {
95 name: "COUNT".into(),
96 expression: Some(Box::new(expr)),
97 distinct: false,
98 filter: None,
99 args: None,
100 order_by: None,
101 })
102 }
103
104 pub fn count_all() -> Self {
106 Expr::Aggregate(AggregationDef {
107 name: "COUNT".into(),
108 expression: None,
109 distinct: false,
110 filter: None,
111 args: None,
112 order_by: None,
113 })
114 }
115
116 pub fn sum(expr: Expr) -> Self {
118 Expr::Aggregate(AggregationDef {
119 name: "SUM".into(),
120 expression: Some(Box::new(expr)),
121 distinct: false,
122 filter: None,
123 args: None,
124 order_by: None,
125 })
126 }
127
128 pub fn avg(expr: Expr) -> Self {
130 Expr::Aggregate(AggregationDef {
131 name: "AVG".into(),
132 expression: Some(Box::new(expr)),
133 distinct: false,
134 filter: None,
135 args: None,
136 order_by: None,
137 })
138 }
139
140 pub fn min(expr: Expr) -> Self {
142 Expr::Aggregate(AggregationDef {
143 name: "MIN".into(),
144 expression: Some(Box::new(expr)),
145 distinct: false,
146 filter: None,
147 args: None,
148 order_by: None,
149 })
150 }
151
152 pub fn max(expr: Expr) -> Self {
154 Expr::Aggregate(AggregationDef {
155 name: "MAX".into(),
156 expression: Some(Box::new(expr)),
157 distinct: false,
158 filter: None,
159 args: None,
160 order_by: None,
161 })
162 }
163
164 pub fn exists(query: QueryStmt) -> Self {
166 Expr::Exists(Box::new(query))
167 }
168
169 pub fn subquery(query: QueryStmt) -> Self {
171 Expr::SubQuery(Box::new(query))
172 }
173}
174
175impl From<Value> for Expr {
176 fn from(v: Value) -> Self {
177 Expr::Value(v)
178 }
179}
180
181impl From<FieldRef> for Expr {
182 fn from(f: FieldRef) -> Self {
183 Expr::Field(f)
184 }
185}
186
187#[derive(Debug, Clone, Copy, PartialEq, Eq)]
189pub enum BinaryOp {
190 Add,
191 Sub,
192 Mul,
193 Div,
194 Mod,
195 BitwiseAnd,
196 BitwiseOr,
197 ShiftLeft,
198 ShiftRight,
199 Concat,
200}
201
202#[derive(Debug, Clone, Copy, PartialEq, Eq)]
204pub enum UnaryOp {
205 Neg,
206 Not,
207 BitwiseNot,
208}
209
210#[derive(Debug, Clone)]
212pub struct AggregationDef {
213 pub name: String,
214 pub expression: Option<Box<Expr>>,
215 pub distinct: bool,
216 pub filter: Option<Conditions>,
217 pub args: Option<Vec<Expr>>,
218 pub order_by: Option<Vec<OrderByDef>>,
219}
220
221impl AggregationDef {
222 pub fn new(name: impl Into<String>, expr: Expr) -> Self {
223 Self {
224 name: name.into(),
225 expression: Some(Box::new(expr)),
226 distinct: false,
227 filter: None,
228 args: None,
229 order_by: None,
230 }
231 }
232
233 pub fn count_all() -> Self {
234 Self {
235 name: "COUNT".into(),
236 expression: None,
237 distinct: false,
238 filter: None,
239 args: None,
240 order_by: None,
241 }
242 }
243
244 pub fn distinct(mut self) -> Self {
245 self.distinct = true;
246 self
247 }
248
249 pub fn filter(mut self, cond: Conditions) -> Self {
250 self.filter = Some(cond);
251 self
252 }
253
254 pub fn order_by(mut self, order: Vec<OrderByDef>) -> Self {
255 self.order_by = Some(order);
256 self
257 }
258}
259
260#[derive(Debug, Clone)]
262pub struct CaseDef {
263 pub cases: Vec<WhenClause>,
264 pub default: Option<Box<Expr>>,
265}
266
267#[derive(Debug, Clone)]
269pub struct WhenClause {
270 pub condition: Conditions,
271 pub result: Expr,
272}
273
274#[derive(Debug, Clone)]
276pub struct WindowDef {
277 pub expression: Box<Expr>,
278 pub partition_by: Option<Vec<Expr>>,
279 pub order_by: Option<Vec<OrderByDef>>,
280 pub frame: Option<WindowFrameDef>,
281}
282
283#[derive(Debug, Clone)]
285pub struct WindowFrameDef {
286 pub frame_type: WindowFrameType,
287 pub start: WindowFrameBound,
288 pub end: Option<WindowFrameBound>,
289}
290
291#[derive(Debug, Clone, Copy, PartialEq, Eq)]
293pub enum WindowFrameType {
294 Rows,
295 Range,
296 Groups,
297}
298
299#[derive(Debug, Clone, PartialEq, Eq)]
301pub enum WindowFrameBound {
302 CurrentRow,
303 Preceding(Option<u64>),
304 Following(Option<u64>),
305}