partiql/planner/
logical_plan.rs1use crate::planner::drain::Drain;
2use crate::planner::filter::Filter;
3use crate::planner::project::Projection;
4use crate::sql::clause::Limit;
5use crate::sql::clause::OrderBy;
6use crate::sql::Env;
7use crate::sql::Expr;
8use crate::sql::Sql;
9use crate::value::BPqlValue;
10use crate::value::PqlValue;
11
12#[derive(Debug, Default)]
13pub struct LogicalPlan {
14 pub drains: Vec<Drain>,
15 pub filter: Filter,
16 pub project: Projection,
17 pub order_by: Option<OrderBy>,
18 pub limit: Option<Limit>,
19}
20
21impl From<Sql> for LogicalPlan {
22 fn from(sql: Sql) -> Self {
23 Self {
24 drains: vec![Drain(sql.from_clause), Drain(sql.left_join_clause)],
25 filter: Filter(sql.where_clause),
26 project: Projection(sql.select_clause),
27 order_by: sql.orderby,
28 limit: sql.limit,
29 }
30 }
31}
32
33impl LogicalPlan {
34 pub fn execute(self, env: &mut Env) -> PqlValue {
35 for drain in self.drains {
36 drain.execute(env);
37 }
38
39 {
40 if let Some(expr) = env.get("") {
41 let data = match expr {
42 Expr::Value(value) => {
43 let filtered = self.filter.execute(value.to_owned(), &env);
44 Expr::from(filtered)
45 }
46 Expr::Star => todo!(),
47 Expr::Selector(_) => todo!(),
48 Expr::Func(_) => todo!(),
49 Expr::Add(_, _) => todo!(),
50 Expr::Sub(_, _) => todo!(),
51 Expr::Mul(_, _) => todo!(),
52 Expr::Div(_, _) => todo!(),
53 Expr::Rem(_, _) => todo!(),
54 Expr::Exp(_, _) => todo!(),
55 Expr::Sql(_) => todo!(),
56 };
57 env.insert("", &data);
58 };
59 }
60
61 let mut list = self.project.execute(&env);
62 dbg!(&list);
63
64 if let Some(orderby) = &self.order_by {
65 let mut list_with_key = list
66 .into_iter()
67 .filter_map(|record| {
68 record
69 .to_owned()
70 .get(&orderby.label)
71 .map(|value| (BPqlValue::from(value), record))
72 })
73 .collect::<Vec<_>>();
74 list_with_key.sort_by(|x, y| {
75 if orderby.is_asc {
76 x.0.partial_cmp(&y.0).unwrap()
77 } else {
78 y.0.partial_cmp(&x.0).unwrap()
79 }
80 });
81 list = list_with_key
82 .into_iter()
83 .map(|(_k, v)| v)
84 .collect::<Vec<_>>();
85 }
86
87 if let Some(limit_clause) = &self.limit {
88 let (_, values) = list.split_at(limit_clause.offset as usize);
89 let (values, _) = values.split_at(limit_clause.limit as usize);
90 list = values.to_owned();
91 }
92
93 PqlValue::Array(list)
94 }
95}