uqa_sql/binding/stored_routines/
analysis.rs1use super::{BoundStatementRoutines, CatalogRoutineContext};
10use crate::{
11 ast::ColumnType,
12 binding::statements::{StatementAnalysisOperation, StatementBindingScope},
13 plan::{ExpressionPlan, UnifiedPlan},
14 routines::RoutineResolution,
15 RowSchema, SQLError, SQLParam,
16};
17
18pub trait CatalogRoutineScopes {
20 fn with_catalog_scope(&self, analyze: StatementAnalysisOperation<'_>) -> Result<(), SQLError>;
21}
22#[derive(Clone, Copy)]
23pub struct CatalogRoutineAnalysisContext<'a> {
24 pub scopes: &'a dyn CatalogRoutineScopes,
25 pub routines: &'a dyn RoutineResolution,
26}
27impl CatalogRoutineAnalysisContext<'_> {
28 fn with_scope_result<T>(
29 &self,
30 mut analyze: impl FnMut(&dyn StatementBindingScope) -> Result<T, SQLError>,
31 ) -> Result<T, SQLError> {
32 let mut result = None;
33 self.scopes.with_catalog_scope(&mut |scope| {
34 result = Some(analyze(scope)?);
35 Ok(())
36 })?;
37 result.ok_or_else(|| {
38 SQLError::Internal("catalog routine scope did not invoke analysis".into())
39 })
40 }
41 pub fn bind_statement(&self, plan: &UnifiedPlan) -> Result<BoundStatementRoutines, SQLError> {
42 self.with_scope_result(|scope| {
43 let binding = scope.binding_context()?;
44 super::bind_catalog_statement_routines(
45 &CatalogRoutineContext {
46 routines: self.routines,
47 binding: &binding,
48 },
49 plan,
50 &[],
51 )
52 })
53 }
54 pub fn bind_rule_inputs(
55 &self,
56 expression: &mut ExpressionPlan,
57 binding: &crate::catalog::events::RuleConditionBinding,
58 table: &str,
59 columns: &[crate::ast::ColumnDef],
60 ) -> Result<(), SQLError> {
61 let schema = binding.row_schema(columns);
62 self.with_scope_result(|scope| {
63 crate::binding::rule_inputs::expand(
64 self.routines,
65 &scope.binding_context()?,
66 expression,
67 binding,
68 table,
69 &schema,
70 )
71 })
72 }
73 pub fn bind_rule_condition(
74 &self,
75 expression: &mut ExpressionPlan,
76 outer: &RowSchema,
77 event: crate::ast::RuleEvent,
78 ) -> Result<Option<ColumnType>, SQLError> {
79 self.with_scope_result(|scope| {
80 crate::binding::routine_binding::bind_rule_condition_routines(
81 self.routines,
82 expression,
83 &scope.binding_context()?,
84 outer,
85 event,
86 )
87 })
88 }
89
90 pub fn bind_expression(
91 &self,
92 expression: &mut ExpressionPlan,
93 params: &[SQLParam],
94 outer: &RowSchema,
95 ) -> Result<Option<ColumnType>, SQLError> {
96 self.with_scope_result(|scope| {
97 crate::binding::bind_expression_plan_routines_for_storage(
98 self.routines,
99 expression,
100 params,
101 &scope.binding_context()?,
102 outer,
103 )
104 })
105 }
106}
107
108#[cfg(test)]
109mod tests;