1use crate::convert::ToValue;
11use crate::ops::Operation;
12use crate::runtime::eval_value;
13use crate::value::Value;
14use crate::Result;
15
16#[derive(Clone)]
18pub enum Expr {
19 Col(String),
21 Lit(Value),
23 Op(Operation, Vec<Expr>),
25 Call(String, Vec<Expr>),
29}
30
31pub trait IntoExpr {
34 fn into_expr(self) -> Expr;
35}
36
37impl IntoExpr for Expr {
38 fn into_expr(self) -> Expr {
39 self
40 }
41}
42impl IntoExpr for &Expr {
43 fn into_expr(self) -> Expr {
44 self.clone()
45 }
46}
47impl IntoExpr for Value {
48 fn into_expr(self) -> Expr {
49 Expr::Lit(self)
50 }
51}
52
53macro_rules! into_expr_lit {
54 ($($t:ty),*) => {$(
55 impl IntoExpr for $t {
56 fn into_expr(self) -> Expr { Expr::Lit(self.to_value()) }
57 }
58 )*};
59}
60into_expr_lit!(bool, u8, i16, i32, i64, f32, f64);
61
62impl IntoExpr for &str {
67 fn into_expr(self) -> Expr {
68 Expr::Lit(Value::string(self))
69 }
70}
71impl IntoExpr for String {
72 fn into_expr(self) -> Expr {
73 Expr::Lit(Value::string(&self))
74 }
75}
76impl<S: AsRef<str>> IntoExpr for crate::Str<S> {
77 fn into_expr(self) -> Expr {
78 Expr::Lit(self.to_value())
79 }
80}
81
82pub fn col(name: impl Into<String>) -> Expr {
84 Expr::Col(name.into())
85}
86
87pub fn lit(v: impl ToValue) -> Expr {
89 Expr::Lit(v.to_value())
90}
91
92impl Expr {
93 pub fn op(op: Operation, operands: Vec<Expr>) -> Expr {
95 Expr::Op(op, operands)
96 }
97
98 fn binary(self, op: Operation, rhs: impl IntoExpr) -> Expr {
99 Expr::Op(op, vec![self, rhs.into_expr()])
100 }
101 fn unary(self, op: Operation) -> Expr {
102 Expr::Op(op, vec![self])
103 }
104
105 pub fn eq(self, rhs: impl IntoExpr) -> Expr {
107 self.binary(Operation::Equals, rhs)
108 }
109 pub fn ne(self, rhs: impl IntoExpr) -> Expr {
110 self.binary(Operation::NotEquals, rhs)
111 }
112 pub fn lt(self, rhs: impl IntoExpr) -> Expr {
113 self.binary(Operation::LessThan, rhs)
114 }
115 pub fn le(self, rhs: impl IntoExpr) -> Expr {
116 self.binary(Operation::LessEqual, rhs)
117 }
118 pub fn gt(self, rhs: impl IntoExpr) -> Expr {
119 self.binary(Operation::GreaterThan, rhs)
120 }
121 pub fn ge(self, rhs: impl IntoExpr) -> Expr {
122 self.binary(Operation::GreaterEqual, rhs)
123 }
124 pub fn like(self, pattern: impl IntoExpr) -> Expr {
125 self.binary(Operation::Like, pattern)
126 }
127 pub fn is_in(self, set: impl IntoExpr) -> Expr {
128 self.binary(Operation::In, set)
129 }
130 pub fn within(self, range: impl IntoExpr) -> Expr {
131 self.binary(Operation::Within, range)
132 }
133
134 pub fn and(self, rhs: impl IntoExpr) -> Expr {
136 self.binary(Operation::And, rhs)
137 }
138 pub fn or(self, rhs: impl IntoExpr) -> Expr {
139 self.binary(Operation::Or, rhs)
140 }
141
142 pub fn sum(self) -> Expr {
144 self.unary(Operation::Sum)
145 }
146 pub fn avg(self) -> Expr {
147 self.unary(Operation::Avg)
148 }
149 pub fn count(self) -> Expr {
150 self.unary(Operation::Count)
151 }
152 pub fn min(self) -> Expr {
153 self.unary(Operation::Min)
154 }
155 pub fn max(self) -> Expr {
156 self.unary(Operation::Max)
157 }
158 pub fn first(self) -> Expr {
159 self.unary(Operation::First)
160 }
161 pub fn last(self) -> Expr {
162 self.unary(Operation::Last)
163 }
164 pub fn median(self) -> Expr {
165 self.unary(Operation::Median)
166 }
167 pub fn deviation(self) -> Expr {
168 self.unary(Operation::Deviation)
169 }
170 pub fn std(self) -> Expr {
171 self.unary(Operation::Stddev)
172 }
173 pub fn distinct(self) -> Expr {
174 self.unary(Operation::Distinct)
175 }
176
177 pub fn ceil(self) -> Expr {
179 self.unary(Operation::Ceil)
180 }
181 pub fn floor(self) -> Expr {
182 self.unary(Operation::Floor)
183 }
184 pub fn round(self) -> Expr {
185 self.unary(Operation::Round)
186 }
187
188 pub fn filter(self, mask: impl IntoExpr) -> Expr {
191 self.binary(Operation::Filter, mask)
192 }
193
194 pub fn compile(&self) -> Value {
196 match self {
197 Expr::Col(name) => Value::name_ref(name),
198 Expr::Lit(v) => v.clone(),
199 Expr::Op(op, operands) => {
200 let mut items = Vec::with_capacity(operands.len() + 1);
201 items.push(Value::name_ref(op.as_str()));
205 for o in operands {
206 items.push(o.compile());
207 }
208 Value::list(&items)
209 }
210 Expr::Call(name, operands) => {
211 let mut items = Vec::with_capacity(operands.len() + 1);
214 items.push(Value::name_ref(name));
215 for o in operands {
216 items.push(o.compile());
217 }
218 Value::list(&items)
219 }
220 }
221 }
222
223 pub fn execute(&self) -> Result<Value> {
225 eval_value(&self.compile())
226 }
227}
228
229macro_rules! bin_op {
232 ($trait:ident, $method:ident, $op:expr) => {
233 impl<R: IntoExpr> std::ops::$trait<R> for Expr {
234 type Output = Expr;
235 fn $method(self, rhs: R) -> Expr {
236 Expr::Op($op, vec![self, rhs.into_expr()])
237 }
238 }
239 };
240}
241bin_op!(Add, add, Operation::Add);
242bin_op!(Sub, sub, Operation::Subtract);
243bin_op!(Mul, mul, Operation::Multiply);
244bin_op!(Div, div, Operation::Divide);
245bin_op!(Rem, rem, Operation::Modulo);
246bin_op!(BitAnd, bitand, Operation::And);
247bin_op!(BitOr, bitor, Operation::Or);
248
249impl std::ops::Neg for Expr {
250 type Output = Expr;
251 fn neg(self) -> Expr {
252 self.unary(Operation::Negate)
253 }
254}
255impl std::ops::Not for Expr {
256 type Output = Expr;
257 fn not(self) -> Expr {
258 self.unary(Operation::Not)
259 }
260}
261
262macro_rules! free_agg {
265 ($name:ident, $op:expr) => {
266 pub fn $name(e: impl IntoExpr) -> Expr {
267 Expr::Op($op, vec![e.into_expr()])
268 }
269 };
270}
271free_agg!(sum, Operation::Sum);
272free_agg!(avg, Operation::Avg);
273free_agg!(count, Operation::Count);
274free_agg!(min, Operation::Min);
275free_agg!(max, Operation::Max);
276free_agg!(first, Operation::First);
277free_agg!(last, Operation::Last);
278free_agg!(median, Operation::Median);
279free_agg!(distinct, Operation::Distinct);