uqa_execution/scalar/
context.rs1use uqa_sql::expr::{EngineHook, EvalContext, RowLookup};
10use uqa_sql::{ResultRow, SQLParam};
11
12use crate::batch::{PhysicalRow, RowSchema};
13
14use super::subquery::ScalarSubqueryRunner;
15
16pub struct ScalarEvalContext<'a> {
17 row: Option<&'a ResultRow>,
18 row_lookup: Option<&'a dyn RowLookup>,
19 row_schema: Option<&'a RowSchema>,
20 params: &'a [SQLParam],
21 function_hook: Option<&'a dyn EngineHook>,
22 subquery_runner: Option<&'a dyn ScalarSubqueryRunner>,
23 physical_outer_row: Option<(&'a RowSchema, &'a PhysicalRow)>,
24}
25
26impl<'a> ScalarEvalContext<'a> {
27 #[must_use]
28 pub fn new(row: Option<&'a ResultRow>, params: &'a [SQLParam]) -> Self {
29 Self {
30 row,
31 row_lookup: row.map(|row| row as &dyn RowLookup),
32 row_schema: None,
33 params,
34 function_hook: None,
35 subquery_runner: None,
36 physical_outer_row: None,
37 }
38 }
39
40 #[must_use]
41 pub fn from_row_lookup(row: &'a dyn RowLookup, params: &'a [SQLParam]) -> Self {
42 Self {
43 row: None,
44 row_lookup: Some(row),
45 row_schema: None,
46 params,
47 function_hook: None,
48 subquery_runner: None,
49 physical_outer_row: None,
50 }
51 }
52
53 #[must_use]
54 pub fn with_function_hook(mut self, hook: &'a dyn EngineHook) -> Self {
55 self.function_hook = Some(hook);
56 self
57 }
58
59 #[must_use]
60 pub fn with_row_schema(mut self, schema: &'a RowSchema) -> Self {
61 self.row_schema = Some(schema);
62 self
63 }
64
65 #[must_use]
66 pub fn with_subquery_runner(mut self, runner: &'a dyn ScalarSubqueryRunner) -> Self {
67 self.subquery_runner = Some(runner);
68 self
69 }
70
71 #[must_use]
72 pub fn with_physical_outer_row(mut self, schema: &'a RowSchema, row: &'a PhysicalRow) -> Self {
73 self.physical_outer_row = Some((schema, row));
74 self
75 }
76
77 pub(super) fn sql_context(&self) -> EvalContext<'_> {
78 let context = self.row_lookup.map_or_else(
79 || EvalContext::new(self.row, self.params),
80 |row| EvalContext::from_row_lookup(row, self.params),
81 );
82 match self.function_hook {
83 Some(hook) => context.with_engine(hook),
84 None => context,
85 }
86 }
87
88 pub(super) fn outer_row(&self) -> Option<&dyn RowLookup> {
89 self.row_lookup
90 }
91
92 pub(super) fn row_lookup(&self) -> Option<&'a dyn RowLookup> {
93 self.row_lookup
94 }
95
96 pub(super) fn row_schema(&self) -> Option<&'a RowSchema> {
97 self.row_schema
98 }
99
100 pub(super) fn params(&self) -> &'a [SQLParam] {
101 self.params
102 }
103
104 pub(super) fn function_hook(&self) -> Option<&'a dyn EngineHook> {
105 self.function_hook
106 }
107
108 pub(super) fn subquery_runner(&self) -> Option<&'a dyn ScalarSubqueryRunner> {
109 self.subquery_runner
110 }
111
112 pub(super) fn physical_outer_row(&self) -> Option<(&'a RowSchema, &'a PhysicalRow)> {
113 self.physical_outer_row
114 }
115}