multisql/executor/query/select/plan/
mod.rs

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