1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub enum LiteralValue {
8 I64(i64),
9 F64(f64),
10 I32(i32),
11 Str(String),
12 Bool(bool),
13 Null,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
18pub enum ExprIr {
19 Column(String),
21 Lit(LiteralValue),
23
24 Eq(Box<ExprIr>, Box<ExprIr>),
26 Ne(Box<ExprIr>, Box<ExprIr>),
27 Gt(Box<ExprIr>, Box<ExprIr>),
28 Ge(Box<ExprIr>, Box<ExprIr>),
29 Lt(Box<ExprIr>, Box<ExprIr>),
30 Le(Box<ExprIr>, Box<ExprIr>),
31 EqNullSafe(Box<ExprIr>, Box<ExprIr>),
32
33 And(Box<ExprIr>, Box<ExprIr>),
35 Or(Box<ExprIr>, Box<ExprIr>),
36 Not(Box<ExprIr>),
37
38 Add(Box<ExprIr>, Box<ExprIr>),
40 Sub(Box<ExprIr>, Box<ExprIr>),
41 Mul(Box<ExprIr>, Box<ExprIr>),
42 Div(Box<ExprIr>, Box<ExprIr>),
43
44 Between {
46 left: Box<ExprIr>,
47 lower: Box<ExprIr>,
48 upper: Box<ExprIr>,
49 },
50 IsIn(Box<ExprIr>, Box<ExprIr>),
51
52 IsNull(Box<ExprIr>),
54 IsNotNull(Box<ExprIr>),
55
56 When {
58 condition: Box<ExprIr>,
59 then_expr: Box<ExprIr>,
60 otherwise: Box<ExprIr>,
61 },
62
63 Call {
65 name: String,
66 args: Vec<ExprIr>,
67 },
68}
69
70pub fn col(name: &str) -> ExprIr {
74 ExprIr::Column(name.to_string())
75}
76
77pub fn lit_i64(n: i64) -> ExprIr {
78 ExprIr::Lit(LiteralValue::I64(n))
79}
80
81pub fn lit_i32(n: i32) -> ExprIr {
82 ExprIr::Lit(LiteralValue::I32(n))
83}
84
85pub fn lit_f64(n: f64) -> ExprIr {
86 ExprIr::Lit(LiteralValue::F64(n))
87}
88
89pub fn lit_str(s: &str) -> ExprIr {
90 ExprIr::Lit(LiteralValue::Str(s.to_string()))
91}
92
93pub fn lit_bool(b: bool) -> ExprIr {
94 ExprIr::Lit(LiteralValue::Bool(b))
95}
96
97pub fn lit_null() -> ExprIr {
98 ExprIr::Lit(LiteralValue::Null)
99}
100
101pub fn call(name: &str, args: Vec<ExprIr>) -> ExprIr {
103 ExprIr::Call {
104 name: name.to_string(),
105 args,
106 }
107}
108
109pub struct WhenBuilder {
111 condition: ExprIr,
112}
113
114impl WhenBuilder {
115 pub fn then(self, then_expr: ExprIr) -> WhenThenBuilder {
116 WhenThenBuilder {
117 condition: self.condition,
118 then_expr,
119 }
120 }
121}
122
123pub struct WhenThenBuilder {
124 condition: ExprIr,
125 then_expr: ExprIr,
126}
127
128impl WhenThenBuilder {
129 pub fn otherwise(self, otherwise: ExprIr) -> ExprIr {
130 ExprIr::When {
131 condition: Box::new(self.condition),
132 then_expr: Box::new(self.then_expr),
133 otherwise: Box::new(otherwise),
134 }
135 }
136}
137
138pub fn when(condition: ExprIr) -> WhenBuilder {
140 WhenBuilder { condition }
141}
142
143pub fn eq(a: ExprIr, b: ExprIr) -> ExprIr {
146 ExprIr::Eq(Box::new(a), Box::new(b))
147}
148
149pub fn ne(a: ExprIr, b: ExprIr) -> ExprIr {
150 ExprIr::Ne(Box::new(a), Box::new(b))
151}
152
153pub fn gt(a: ExprIr, b: ExprIr) -> ExprIr {
154 ExprIr::Gt(Box::new(a), Box::new(b))
155}
156
157pub fn ge(a: ExprIr, b: ExprIr) -> ExprIr {
158 ExprIr::Ge(Box::new(a), Box::new(b))
159}
160
161pub fn lt(a: ExprIr, b: ExprIr) -> ExprIr {
162 ExprIr::Lt(Box::new(a), Box::new(b))
163}
164
165pub fn le(a: ExprIr, b: ExprIr) -> ExprIr {
166 ExprIr::Le(Box::new(a), Box::new(b))
167}
168
169pub fn and_(a: ExprIr, b: ExprIr) -> ExprIr {
170 ExprIr::And(Box::new(a), Box::new(b))
171}
172
173pub fn or_(a: ExprIr, b: ExprIr) -> ExprIr {
174 ExprIr::Or(Box::new(a), Box::new(b))
175}
176
177pub fn not_(a: ExprIr) -> ExprIr {
178 ExprIr::Not(Box::new(a))
179}
180
181pub fn is_null(a: ExprIr) -> ExprIr {
182 ExprIr::IsNull(Box::new(a))
183}
184
185pub fn between(left: ExprIr, lower: ExprIr, upper: ExprIr) -> ExprIr {
186 ExprIr::Between {
187 left: Box::new(left),
188 lower: Box::new(lower),
189 upper: Box::new(upper),
190 }
191}
192
193pub fn is_in(left: ExprIr, right: ExprIr) -> ExprIr {
194 ExprIr::IsIn(Box::new(left), Box::new(right))
195}
196
197pub fn sum(expr: ExprIr) -> ExprIr {
200 ExprIr::Call {
201 name: "sum".to_string(),
202 args: vec![expr],
203 }
204}
205
206pub fn count(expr: ExprIr) -> ExprIr {
207 ExprIr::Call {
208 name: "count".to_string(),
209 args: vec![expr],
210 }
211}
212
213pub fn min(expr: ExprIr) -> ExprIr {
214 ExprIr::Call {
215 name: "min".to_string(),
216 args: vec![expr],
217 }
218}
219
220pub fn max(expr: ExprIr) -> ExprIr {
221 ExprIr::Call {
222 name: "max".to_string(),
223 args: vec![expr],
224 }
225}
226
227pub fn mean(expr: ExprIr) -> ExprIr {
228 ExprIr::Call {
229 name: "mean".to_string(),
230 args: vec![expr],
231 }
232}
233
234pub fn alias(expr: ExprIr, name: &str) -> ExprIr {
236 ExprIr::Call {
237 name: "alias".to_string(),
238 args: vec![expr, lit_str(name)],
239 }
240}