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}