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