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