Skip to main content

partiql/sql/
expr.rs

1use std::collections::HashSet;
2
3use collect_mac::collect;
4
5use ordered_float::OrderedFloat;
6
7use crate::sql::Env;
8use crate::sql::Selector;
9use crate::sql::Sql;
10use crate::value::PqlValue;
11
12#[derive(Debug, Clone, PartialEq)]
13pub enum Expr {
14    Star,
15    Selector(Selector),
16    Value(PqlValue),
17    Func(Box<Func>),
18    Add(Box<Expr>, Box<Expr>),
19    Sub(Box<Expr>, Box<Expr>),
20    Mul(Box<Expr>, Box<Expr>),
21    Div(Box<Expr>, Box<Expr>),
22    Rem(Box<Expr>, Box<Expr>),
23    Exp(Box<Expr>, Box<Expr>),
24    Sql(Sql),
25}
26
27impl Default for Expr {
28    fn default() -> Self {
29        Self::Value(PqlValue::default())
30    }
31}
32
33impl From<i64> for Expr {
34    fn from(i: i64) -> Self {
35        Self::Value(PqlValue::Int(i))
36    }
37}
38
39impl From<f64> for Expr {
40    fn from(f: f64) -> Self {
41        Self::Value(PqlValue::Float(OrderedFloat(f)))
42    }
43}
44
45impl From<&str> for Expr {
46    fn from(s: &str) -> Self {
47        Self::Value(PqlValue::from(s))
48    }
49}
50
51impl From<Selector> for Expr {
52    fn from(selector: Selector) -> Self {
53        Self::Selector(selector)
54    }
55}
56
57impl From<PqlValue> for Expr {
58    fn from(value: PqlValue) -> Self {
59        Self::Value(value)
60    }
61}
62
63impl From<Expr> for String {
64    fn from(expr: Expr) -> Self {
65        match expr {
66            Expr::Selector(selector) => selector.to_string(),
67            Expr::Value(value) => value.to_json().expect("to json"),
68            _ => todo!(),
69        }
70    }
71}
72
73impl Expr {
74    pub fn to_string(self) -> String {
75        String::from(self)
76    }
77
78    pub fn as_path(&self) -> Option<Selector> {
79        match self {
80            Expr::Selector(path) => Some(path.to_owned()),
81            _ => None,
82        }
83    }
84
85    pub fn expand_fullpath(&self, env: &Env) -> Self {
86        match self {
87            Self::Selector(path) => Self::Selector(path.expand_fullpath2(&env)),
88            Expr::Value(_) => self.to_owned(),
89            Expr::Star => todo!(),
90            Expr::Func(_) => todo!(),
91            Self::Add(left, right) => Self::Add(
92                Box::new((*left).expand_fullpath(&env)),
93                Box::new((*right).expand_fullpath(&env)),
94            ),
95            Self::Sub(left, right) => Self::Sub(
96                Box::new((*left).expand_fullpath(&env)),
97                Box::new((*right).expand_fullpath(&env)),
98            ),
99            Self::Mul(left, right) => Self::Mul(
100                Box::new((*left).expand_fullpath(&env)),
101                Box::new((*right).expand_fullpath(&env)),
102            ),
103            Self::Div(left, right) => Self::Div(
104                Box::new((*left).expand_fullpath(&env)),
105                Box::new((*right).expand_fullpath(&env)),
106            ),
107            Self::Rem(left, right) => Self::Rem(
108                Box::new((*left).expand_fullpath(&env)),
109                Box::new((*right).expand_fullpath(&env)),
110            ),
111            Self::Exp(left, right) => Self::Exp(
112                Box::new((*left).expand_fullpath(&env)),
113                Box::new((*right).expand_fullpath(&env)),
114            ),
115            Expr::Sql(_) => todo!(),
116        }
117    }
118
119    pub fn eval(self, env: &Env) -> PqlValue {
120        match self.to_owned() {
121            Self::Value(value) => value,
122            Self::Selector(selector) => selector.evaluate(&env).unwrap_or_default(),
123            Self::Star => todo!(),
124            Self::Func(_) => todo!(),
125            Self::Sql(_) => todo!(),
126            Self::Add(box expr1, box expr2) => (expr1).eval(&env) + (expr2).eval(&env),
127            Self::Sub(box expr1, box expr2) => (expr1).eval(&env) - (expr2).eval(&env),
128            Self::Mul(box expr1, box expr2) => (expr1).eval(&env) * (expr2).eval(&env),
129            Self::Div(box expr1, box expr2) => (expr1).eval(&env) / (expr2).eval(&env),
130            Self::Rem(box expr1, box expr2) => (expr1).eval(&env) % (expr2).eval(&env),
131            Self::Exp(box expr1, box expr2) => (expr1).eval(&env).powf((expr2).eval(&env)),
132        }
133    }
134
135    pub fn source_field_name_set(&self, env: &Env) -> HashSet<String> {
136        match self.to_owned() {
137            Expr::Selector(selector) => {
138                collect! {
139                    as HashSet<String>:
140                    selector.expand_fullpath2(&env).to_string()
141                }
142            }
143            Expr::Add(box expr1, box expr2) => {
144                let a = expr1.source_field_name_set(&env);
145                let b = expr2.source_field_name_set(&env);
146                a.union(&b).map(String::from).collect::<HashSet<_>>()
147            }
148            Expr::Sub(box expr1, box expr2) => {
149                let a = expr1.source_field_name_set(&env);
150                let b = expr2.source_field_name_set(&env);
151                a.union(&b).map(String::from).collect::<HashSet<_>>()
152            }
153            Expr::Mul(box expr1, box expr2) => {
154                let a = expr1.source_field_name_set(&env);
155                let b = expr2.source_field_name_set(&env);
156                a.union(&b).map(String::from).collect::<HashSet<_>>()
157            }
158            Expr::Div(box expr1, box expr2) => {
159                let a = expr1.source_field_name_set(&env);
160                let b = expr2.source_field_name_set(&env);
161                a.union(&b).map(String::from).collect::<HashSet<_>>()
162            }
163            Expr::Rem(box expr1, box expr2) => {
164                let a = expr1.source_field_name_set(&env);
165                let b = expr2.source_field_name_set(&env);
166                a.union(&b).map(String::from).collect::<HashSet<_>>()
167            }
168            Expr::Exp(box expr1, box expr2) => {
169                let a = expr1.source_field_name_set(&env);
170                let b = expr2.source_field_name_set(&env);
171                a.union(&b).map(String::from).collect::<HashSet<_>>()
172            }
173            _ => {
174                dbg!(&self);
175                todo!();
176            }
177        }
178    }
179}
180
181#[derive(Debug, Clone, PartialEq)]
182pub enum Func {
183    Count(Expr),
184    Upper(Expr),
185}
186
187#[cfg(test)]
188mod tests {
189    use std::str::FromStr;
190
191    use crate::parser;
192    use crate::planner::LogicalPlan;
193    use crate::sql::Env;
194
195    use crate::sql::Sql;
196    use crate::value::PqlValue;
197
198    #[test]
199    fn test_expr_mul() -> anyhow::Result<()> {
200        let mut sql = Sql::default();
201        sql.select_clause = parser::clauses::select(r#"SELECT 4 * a AS aa"#)?.1;
202        sql.from_clause = parser::clauses::from("FROM 3 as a")?.1;
203        let plan = LogicalPlan::from(sql);
204
205        let mut env = Env::default();
206        let res = plan.execute(&mut env);
207
208        assert_eq!(res, PqlValue::from_str(r#"[{ "aa": 12 }]"#)?);
209
210        Ok(())
211    }
212}