1use crate::types::{BinOper, ColumnRef, DynIden, UnOper, WindowStatement};
8use crate::value::Value;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum SubQueryOper {
15 Exists,
17 NotExists,
19 In,
21 NotIn,
23 All,
25 Any,
27 Some,
29}
30
31#[derive(Debug, Clone)]
55pub enum SimpleExpr {
56 Column(ColumnRef),
58
59 TableColumn(DynIden, DynIden),
61
62 Value(Value),
64
65 Unary(UnOper, Box<SimpleExpr>),
67
68 Binary(Box<SimpleExpr>, BinOper, Box<SimpleExpr>),
70
71 FunctionCall(DynIden, Vec<SimpleExpr>),
73
74 SubQuery(Option<SubQueryOper>, Box<crate::query::SelectStatement>),
80
81 Tuple(Vec<SimpleExpr>),
83
84 Custom(String),
91
92 CustomWithExpr(String, Vec<SimpleExpr>),
94
95 Constant(Keyword),
97
98 Asterisk,
100
101 Case(Box<CaseStatement>),
103
104 AsEnum(DynIden, Box<SimpleExpr>),
106
107 Cast(Box<SimpleExpr>, DynIden),
109
110 Window {
117 func: Box<SimpleExpr>,
119 window: WindowStatement,
121 },
122
123 WindowNamed {
131 func: Box<SimpleExpr>,
133 name: DynIden,
135 },
136}
137
138#[derive(Debug, Clone, Copy, PartialEq, Eq)]
140pub enum Keyword {
141 Null,
143 True,
145 False,
147 Default,
149 CurrentTimestamp,
151 CurrentDate,
153 CurrentTime,
155}
156
157impl Keyword {
158 #[must_use]
160 pub fn as_str(&self) -> &'static str {
161 match self {
162 Self::Null => "NULL",
163 Self::True => "TRUE",
164 Self::False => "FALSE",
165 Self::Default => "DEFAULT",
166 Self::CurrentTimestamp => "CURRENT_TIMESTAMP",
167 Self::CurrentDate => "CURRENT_DATE",
168 Self::CurrentTime => "CURRENT_TIME",
169 }
170 }
171}
172
173#[derive(Debug, Clone, Default)]
184pub struct CaseStatement {
185 pub when_clauses: Vec<(SimpleExpr, SimpleExpr)>,
187 pub else_clause: Option<SimpleExpr>,
189}
190
191impl CaseStatement {
192 pub fn new() -> Self {
194 Self::default()
195 }
196
197 #[must_use]
199 pub fn when<C, R>(mut self, condition: C, result: R) -> Self
200 where
201 C: Into<SimpleExpr>,
202 R: Into<SimpleExpr>,
203 {
204 self.when_clauses.push((condition.into(), result.into()));
205 self
206 }
207
208 #[must_use]
210 pub fn else_result<E>(mut self, result: E) -> Self
211 where
212 E: Into<SimpleExpr>,
213 {
214 self.else_clause = Some(result.into());
215 self
216 }
217}
218
219impl SimpleExpr {
220 pub fn binary(self, op: crate::types::BinOper, right: SimpleExpr) -> Self {
222 Self::Binary(Box::new(self), op, Box::new(right))
223 }
224}
225
226impl From<Value> for SimpleExpr {
229 fn from(v: Value) -> Self {
230 Self::Value(v)
231 }
232}
233
234impl From<ColumnRef> for SimpleExpr {
235 fn from(c: ColumnRef) -> Self {
236 Self::Column(c)
237 }
238}
239
240impl From<bool> for SimpleExpr {
241 fn from(b: bool) -> Self {
242 Self::Value(Value::Bool(Some(b)))
243 }
244}
245
246impl From<i32> for SimpleExpr {
247 fn from(i: i32) -> Self {
248 Self::Value(Value::Int(Some(i)))
249 }
250}
251
252impl From<i64> for SimpleExpr {
253 fn from(i: i64) -> Self {
254 Self::Value(Value::BigInt(Some(i)))
255 }
256}
257
258impl From<f32> for SimpleExpr {
259 fn from(f: f32) -> Self {
260 Self::Value(Value::Float(Some(f)))
261 }
262}
263
264impl From<f64> for SimpleExpr {
265 fn from(f: f64) -> Self {
266 Self::Value(Value::Double(Some(f)))
267 }
268}
269
270impl From<&str> for SimpleExpr {
271 fn from(s: &str) -> Self {
272 Self::Value(Value::String(Some(Box::new(s.to_string()))))
273 }
274}
275
276impl From<String> for SimpleExpr {
277 fn from(s: String) -> Self {
278 Self::Value(Value::String(Some(Box::new(s))))
279 }
280}
281
282impl From<Keyword> for SimpleExpr {
283 fn from(k: Keyword) -> Self {
284 Self::Constant(k)
285 }
286}
287
288impl From<CaseStatement> for SimpleExpr {
289 fn from(case: CaseStatement) -> Self {
290 Self::Case(Box::new(case))
291 }
292}
293
294#[cfg(test)]
295mod tests {
296 use super::*;
297 use rstest::rstest;
298
299 #[rstest]
300 fn test_simple_expr_from_value() {
301 let expr: SimpleExpr = Value::Int(Some(42)).into();
302 assert!(matches!(expr, SimpleExpr::Value(Value::Int(Some(42)))));
303 }
304
305 #[rstest]
306 fn test_simple_expr_from_bool() {
307 let expr: SimpleExpr = true.into();
308 assert!(matches!(expr, SimpleExpr::Value(Value::Bool(Some(true)))));
309 }
310
311 #[rstest]
312 fn test_simple_expr_from_i32() {
313 let expr: SimpleExpr = 42i32.into();
314 assert!(matches!(expr, SimpleExpr::Value(Value::Int(Some(42)))));
315 }
316
317 #[rstest]
318 fn test_simple_expr_from_str() {
319 let expr: SimpleExpr = "hello".into();
320 if let SimpleExpr::Value(Value::String(Some(s))) = expr {
321 assert_eq!(*s, "hello");
322 } else {
323 panic!("Expected String value");
324 }
325 }
326
327 #[rstest]
328 fn test_simple_expr_column() {
329 let col = ColumnRef::column("name");
330 let expr: SimpleExpr = col.into();
331 assert!(matches!(expr, SimpleExpr::Column(_)));
332 }
333
334 #[rstest]
335 fn test_keyword_as_str() {
336 assert_eq!(Keyword::Null.as_str(), "NULL");
337 assert_eq!(Keyword::True.as_str(), "TRUE");
338 assert_eq!(Keyword::False.as_str(), "FALSE");
339 assert_eq!(Keyword::CurrentTimestamp.as_str(), "CURRENT_TIMESTAMP");
340 }
341
342 #[rstest]
343 fn test_case_statement_builder() {
344 let case = CaseStatement::new()
345 .when(true, 1i32)
346 .when(false, 0i32)
347 .else_result(-1i32);
348
349 assert_eq!(case.when_clauses.len(), 2);
350 assert!(case.else_clause.is_some());
351 }
352
353 #[rstest]
354 fn test_simple_expr_binary() {
355 let left = SimpleExpr::Column(ColumnRef::column("age"));
356 let right = SimpleExpr::Value(Value::Int(Some(18)));
357 let binary =
358 SimpleExpr::Binary(Box::new(left), BinOper::GreaterThanOrEqual, Box::new(right));
359
360 assert!(matches!(
361 binary,
362 SimpleExpr::Binary(_, BinOper::GreaterThanOrEqual, _)
363 ));
364 }
365
366 #[rstest]
367 fn test_simple_expr_unary() {
368 let inner = SimpleExpr::Value(Value::Bool(Some(true)));
369 let unary = SimpleExpr::Unary(UnOper::Not, Box::new(inner));
370
371 assert!(matches!(unary, SimpleExpr::Unary(UnOper::Not, _)));
372 }
373}