Skip to main content

partiql/planner/
logical_plan.rs

1use 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}