gluesql_core/executor/context/
row_context.rs1use {
2 crate::data::{Row, Value},
3 std::{borrow::Cow, collections::BTreeMap, fmt::Debug, sync::Arc},
4};
5
6#[derive(Debug)]
7pub enum RowContext<'a> {
8 Data {
9 table_alias: &'a str,
10 row: Cow<'a, Row>,
11 next: Option<Arc<RowContext<'a>>>,
12 },
13 RefVecData {
14 columns: &'a [String],
15 values: &'a [Value],
16 },
17 RefMapData(&'a BTreeMap<String, Value>),
18 Bridge {
19 left: Arc<RowContext<'a>>,
20 right: Arc<RowContext<'a>>,
21 },
22}
23
24impl<'a> RowContext<'a> {
25 pub fn new(table_alias: &'a str, row: Cow<'a, Row>, next: Option<Arc<RowContext<'a>>>) -> Self {
26 Self::Data {
27 table_alias,
28 row,
29 next,
30 }
31 }
32
33 pub fn concat(left: Arc<RowContext<'a>>, right: Arc<RowContext<'a>>) -> Self {
34 Self::Bridge { left, right }
35 }
36
37 pub fn get_value(&'a self, target: &str) -> Option<&'a Value> {
38 match self {
39 Self::Data {
40 row, next: None, ..
41 } => row.get_value(target),
42 Self::Data {
43 row,
44 next: Some(next),
45 ..
46 } => row.get_value(target).or_else(|| next.get_value(target)),
47 Self::Bridge { left, right } => {
48 left.get_value(target).or_else(|| right.get_value(target))
49 }
50 Self::RefVecData { columns, values } => columns
51 .iter()
52 .position(|column| column == target)
53 .and_then(|index| values.get(index)),
54 Self::RefMapData(values) => values.get(target),
55 }
56 }
57
58 pub fn get_alias_value(&'a self, target_table_alias: &str, target: &str) -> Option<&'a Value> {
59 match self {
60 Self::Data {
61 table_alias,
62 row,
63 next,
64 } if *table_alias == target_table_alias => {
65 let value = row.get_value(target);
66
67 if value.is_some() {
68 value
69 } else {
70 next.as_ref()
71 .and_then(|context| context.get_alias_value(target_table_alias, target))
72 }
73 }
74 Self::Data {
75 next: Some(next), ..
76 } => next.get_alias_value(target_table_alias, target),
77 Self::Bridge { left, right } => left
78 .get_alias_value(target_table_alias, target)
79 .or_else(|| right.get_alias_value(target_table_alias, target)),
80 _ => None,
81 }
82 }
83
84 pub fn get_alias_entries(&self, alias: &str) -> Option<Vec<(&String, Value)>> {
85 match self {
86 Self::Data {
87 table_alias, row, ..
88 } if *table_alias == alias => Some(row.iter().map(|(k, v)| (k, v.clone())).collect()),
89 Self::Data {
90 next: Some(next), ..
91 } => next.get_alias_entries(alias),
92 Self::Bridge { left, right } => left
93 .get_alias_entries(alias)
94 .or_else(|| right.get_alias_entries(alias)),
95 _ => None,
96 }
97 }
98
99 pub fn get_all_entries(&self) -> Vec<(&String, Value)> {
100 match self {
101 Self::Data {
102 row, next: None, ..
103 } => row.iter().map(|(k, v)| (k, v.clone())).collect(),
104 Self::Data {
105 row,
106 next: Some(next),
107 ..
108 } => next
109 .get_all_entries()
110 .into_iter()
111 .chain(row.iter().map(|(k, v)| (k, v.clone())))
112 .collect(),
113 Self::Bridge { left, right } => {
114 [left.get_all_entries(), right.get_all_entries()].concat()
115 }
116 _ => vec![],
117 }
118 }
119}