multisql/executor/query/select/plan/
refine_item.rs1use {
2 super::SelectItem,
3 crate::{recipe::PlannedRecipe, types::ColumnInfo, Error, PlanError, Result},
4};
5
6pub(crate) fn refine_item(
7 index: usize,
8 select_item: SelectItem,
9 columns: &[ColumnInfo],
10 include_table: bool,
11) -> Result<Vec<(PlannedRecipe, String)>> {
12 Ok(match select_item {
13 SelectItem::Recipe(meta_recipe, alias) => {
14 let recipe = PlannedRecipe::new(meta_recipe, columns)?;
15 let label = alias.unwrap_or_else(|| recipe.get_label(index, include_table, &columns));
16 vec![(recipe, label)]
17 }
18 SelectItem::Wildcard(specifier) => {
19 let specified_table = specifier.and_then(|specifier| specifier.get(0).cloned());
20 let matches_table = |column: &ColumnInfo| {
21 specified_table
22 .clone()
23 .map(|specified_table| {
24 column.table.name == specified_table
25 || column
26 .table
27 .alias
28 .clone()
29 .map(|alias| alias == specified_table)
30 .unwrap_or(false)
31 })
32 .unwrap_or(true)
33 };
34 columns
35 .iter()
36 .enumerate()
37 .filter_map(|(index, column)| {
38 if matches_table(column) {
39 Some((
40 PlannedRecipe::of_index(index),
41 if include_table {
42 format!("{}.{}", column.table.name, column.name)
43 } else {
44 column.name.clone()
45 },
46 ))
47 } else {
48 None
49 }
50 })
51 .collect()
52 }
53 })
54}
55
56pub(crate) fn refine_items(
57 select_items: Vec<SelectItem>,
58 columns: &[ColumnInfo],
59 include_table: bool,
60) -> Result<Vec<(PlannedRecipe, String)>> {
61 select_items
62 .into_iter()
63 .enumerate()
64 .map(|(index, select_item)| refine_item(index, select_item, &columns, include_table))
65 .collect::<Result<Vec<Vec<(PlannedRecipe, String)>>>>()?
66 .into_iter()
67 .reduce(|mut select_items, select_item_set| {
68 select_items.extend(select_item_set);
69 select_items
70 })
71 .ok_or(Error::Plan(PlanError::UnreachableNoSelectItems))
72}