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 { next: None, .. } => None,
75 Self::Data {
76 next: Some(next), ..
77 } => next.get_alias_value(target_table_alias, target),
78 Self::Bridge { left, right } => left
79 .get_alias_value(target_table_alias, target)
80 .or_else(|| right.get_alias_value(target_table_alias, target)),
81 _ => None,
82 }
83 }
84
85 pub fn get_alias_entries(&self, alias: &str) -> Option<Vec<(&String, Value)>> {
86 match self {
87 Self::Data {
88 table_alias, row, ..
89 } if *table_alias == alias => Some(row.iter().map(|(k, v)| (k, v.clone())).collect()),
90 Self::Data { next: None, .. } => None,
91 Self::Data {
92 next: Some(next), ..
93 } => next.get_alias_entries(alias),
94 Self::Bridge { left, right } => left
95 .get_alias_entries(alias)
96 .or_else(|| right.get_alias_entries(alias)),
97 _ => None,
98 }
99 }
100
101 pub fn get_all_entries(&self) -> Vec<(&String, Value)> {
102 match self {
103 Self::Data {
104 row, next: None, ..
105 } => row.iter().map(|(k, v)| (k, v.clone())).collect(),
106 Self::Data {
107 row,
108 next: Some(next),
109 ..
110 } => next
111 .get_all_entries()
112 .into_iter()
113 .chain(row.iter().map(|(k, v)| (k, v.clone())))
114 .collect(),
115 Self::Bridge { left, right } => {
116 [left.get_all_entries(), right.get_all_entries()].concat()
117 }
118 _ => vec![],
119 }
120 }
121}