uqa_execution/batch/
owned_row.rs1use uqa_core::Value;
10use uqa_sql::expr::RowLookup;
11use uqa_sql::ResultRow;
12
13use crate::physical::{ExecError, ExecResult};
14
15use super::{PhysicalRow, PhysicalRowView, RowSchema};
16
17#[derive(Debug, Clone, PartialEq)]
19pub struct OwnedPhysicalRow {
20 pub schema: RowSchema,
21 pub row: PhysicalRow,
22}
23
24impl OwnedPhysicalRow {
25 pub fn new(schema: RowSchema, row: PhysicalRow) -> Self {
26 Self { schema, row }
27 }
28
29 pub fn view(&self) -> PhysicalRowView<'_> {
30 self.schema.view(&self.row)
31 }
32
33 pub fn get(&self, name: &str) -> Option<&Value> {
34 self.schema
35 .exact_slot(name)
36 .and_then(|slot| self.row.value(slot))
37 }
38
39 pub fn physical_value_at(&self, position: usize) -> Option<&Value> {
41 self.row.value(position)
42 }
43
44 pub fn relabel(self, schema: RowSchema) -> ExecResult<Self> {
46 if self.schema.len() != schema.len() {
47 return Err(ExecError::Other(format!(
48 "cannot relabel {} columns as {} columns",
49 self.schema.len(),
50 schema.len()
51 )));
52 }
53 let slots = self.schema.index.slots.to_vec();
54 Ok(Self::new(schema, self.row.project_slots(&slots)))
55 }
56
57 pub fn into_result_row(self) -> ResultRow {
58 self.schema.materialize_result_row(self.row)
59 }
60}
61
62impl RowLookup for OwnedPhysicalRow {
63 fn column(&self, name: &str) -> Option<&Value> {
64 self.schema
65 .column_slot(name)
66 .and_then(|slot| self.row.value(slot))
67 }
68
69 fn column_is_ambiguous(&self, name: &str) -> bool {
70 self.schema.column_is_ambiguous(name)
71 }
72
73 fn qualified_column(&self, qualifier: &str, column: &str) -> Option<&Value> {
74 self.schema
75 .qualified_slot(qualifier, column)
76 .and_then(|slot| self.row.value(slot))
77 }
78
79 fn qualified_column_is_ambiguous(&self, qualifier: &str, column: &str) -> bool {
80 self.schema.qualified_column_is_ambiguous(qualifier, column)
81 }
82
83 fn positional_column(&self, index: usize) -> Option<&Value> {
84 self.schema
85 .slot(index)
86 .and_then(|slot| self.row.value(slot))
87 }
88
89 fn internal_column(&self, column: uqa_sql::ast::InternalColumnRef) -> Option<&Value> {
90 self.schema
91 .internal_slot(column)
92 .and_then(|slot| self.row.value(slot))
93 }
94
95 fn score_source(&self, qualifier: Option<&str>) -> Option<&Value> {
96 self.schema
97 .score_source_slot(qualifier)
98 .and_then(|slot| self.row.value(slot))
99 }
100
101 fn score_source_is_ambiguous(&self, qualifier: Option<&str>) -> bool {
102 self.schema.score_source_is_ambiguous(qualifier)
103 }
104
105 fn visit_columns(&self, visitor: &mut dyn FnMut(&str, &Value)) {
106 self.view().visit_columns(visitor);
107 }
108}