uqa_sql/prepared/
definition.rs1use crate::{
10 binding::statements::{StatementAnalysisScopes, StatementBindingScope},
11 plan::UnifiedPlan,
12 routines::RoutineResolution,
13 ColumnType, FunctionTypeResolver, RowSchema, SQLError,
14};
15
16#[derive(Clone, Copy)]
17pub struct PreparedDefinitionContext<'a> {
18 pub types: &'a dyn FunctionTypeResolver,
19 pub routines: &'a dyn RoutineResolution,
20 pub scopes: &'a dyn StatementAnalysisScopes,
21}
22
23pub struct PreparedDefinition {
24 pub logical_plan: UnifiedPlan,
25 pub parameter_types: Vec<Option<ColumnType>>,
26 pub result_schema: Option<RowSchema>,
27}
28
29pub fn analyze_definition(
30 context: &PreparedDefinitionContext<'_>,
31 mut logical_plan: UnifiedPlan,
32 declared: &[ColumnType],
33) -> Result<PreparedDefinition, SQLError> {
34 let parameter_types =
35 super::declared_parameter_types(context.types, &mut logical_plan, declared)?;
36 let parameter_types = with_scope_result(context.scopes, |scope| {
37 crate::binding::infer_prepared_parameter_types(
38 context.routines,
39 &logical_plan,
40 ¶meter_types,
41 &scope.binding_context()?,
42 )
43 })?;
44 let result_schema = analyze_result_schema(context, &logical_plan, ¶meter_types)?;
45 Ok(PreparedDefinition {
46 logical_plan,
47 parameter_types,
48 result_schema,
49 })
50}
51
52pub fn analyze_result_schema(
53 context: &PreparedDefinitionContext<'_>,
54 logical_plan: &UnifiedPlan,
55 parameter_types: &[Option<ColumnType>],
56) -> Result<Option<RowSchema>, SQLError> {
57 with_scope_result(context.scopes, |scope| {
58 super::analyze_prepared_plan(
59 context.routines,
60 logical_plan,
61 parameter_types,
62 &scope.binding_context()?,
63 )
64 })
65}
66
67fn with_scope_result<T>(
68 scopes: &dyn StatementAnalysisScopes,
69 mut analyze: impl FnMut(&dyn StatementBindingScope) -> Result<T, SQLError>,
70) -> Result<T, SQLError> {
71 let mut result = None;
72 scopes.with_scope(&mut |scope| {
73 result = Some(analyze(scope)?);
74 Ok(())
75 })?;
76 result.ok_or_else(|| {
77 SQLError::Internal("prepared analysis scope did not invoke its operation".into())
78 })
79}
80
81#[cfg(test)]
82mod tests;