multisql/executor/query/select/plan/
mod.rs1mod organise_joins;
2mod refine_item;
3pub(crate) use refine_item::*;
4use {
5 super::{join::JoinExecute, Manual, Order, SelectItem},
6 crate::{recipe::PlannedRecipe, Glue, Result},
7 serde::Serialize,
8 sqlparser::ast::{OrderByExpr, Select},
9 thiserror::Error as ThisError,
10};
11
12pub struct Plan {
13 pub joins: Vec<JoinExecute>,
14 pub select_items: Vec<PlannedRecipe>,
15 pub constraint: PlannedRecipe,
16 pub groups: Vec<PlannedRecipe>,
17 pub group_constraint: PlannedRecipe,
18 pub order_by: Order,
19 pub labels: Vec<String>,
20}
21
22#[derive(ThisError, Serialize, Debug, PartialEq)]
23pub enum PlanError {
24 #[error("this should be impossible, please report")]
25 UnreachableNoColumns,
26 #[error("this should be impossible, please report")]
27 UnreachableNoSelectItems,
28 #[error("this should be impossible, please report")]
29 Unreachable,
30}
31
32impl Plan {
33 pub async fn new(glue: &Glue, select: Select, order_by: Vec<OrderByExpr>) -> Result<Plan> {
34 let Manual {
35 joins,
36 select_items,
37 constraint,
38 group_constraint,
39 groups,
40 } = Manual::new(glue, select)?;
41
42 let (requested_joins, columns) = glue.arrange_joins(joins).await?;
43
44 let (constraint, mut index_filters) = PlannedRecipe::new_constraint(constraint, &columns)?;
45
46 let mut joins = requested_joins
47 .into_iter()
48 .map(|(_, join)| {
49 let index_filter = index_filters.remove(&join.table);
50 JoinExecute::new(join, &columns, index_filter)
51 })
52 .collect::<Result<Vec<JoinExecute>>>()?;
53
54 if let Some(first) = joins.first_mut() {
55 first.set_first_table()
56 }
57
58 let include_table = joins.len() != 1;
59 let select_items = refine_items(select_items, &columns, include_table)?;
60 let (select_items, labels) = select_items.into_iter().unzip();
61
62 let group_constraint = PlannedRecipe::new(group_constraint, &columns)?;
63 let groups = groups
64 .into_iter()
65 .map(|group| PlannedRecipe::new(group, &columns))
66 .collect::<Result<Vec<PlannedRecipe>>>()?;
67 let order_by = Order::new(order_by, &columns)?;
68
69 Ok(Plan {
70 joins,
71 select_items,
72 constraint,
73 groups,
74 group_constraint,
75 order_by,
76 labels,
77 })
78 }
79}