uqa_sql/binding/
scoped_types.rs1use super::snapshot::BindingSnapshot;
10use crate::{
11 ast::FunctionBinding, routines::RoutineResolution, BuiltinFunctionOverload, ColumnType,
12 FunctionTypeResolver, ResolvedFunctionOverload, SQLError, SQLParam,
13};
14
15pub struct BindingTypeResolver<'a> {
16 pub routines: &'a dyn RoutineResolution,
17 pub scope: &'a BindingSnapshot,
18}
19
20impl FunctionTypeResolver for BindingTypeResolver<'_> {
21 fn format_type_name(&self, ty: &ColumnType) -> Result<String, SQLError> {
22 self.routines.format_type_name(ty)
23 }
24
25 fn has_untyped_function(&self, name: &str) -> bool {
26 self.routines.has_untyped_function(name)
27 }
28
29 fn resolve_type_name(&self, name: &str) -> Result<Option<ColumnType>, SQLError> {
30 self.routines.resolve_type_name(name)
31 }
32
33 fn resolve_collation_name(&self, name: &str) -> Result<Option<u32>, SQLError> {
34 self.routines.resolve_collation_name(name)
35 }
36
37 fn enum_labels(&self) -> Option<&dyn crate::expr::enums::EnumLabelCatalog> {
38 self.routines.enum_labels()
39 }
40
41 fn composite_types(&self) -> Option<&dyn crate::expr::composites::CompositeTypeCatalog> {
42 self.routines.composite_types()
43 }
44
45 fn resolve_function_type(
46 &self,
47 name: &str,
48 binding: Option<&FunctionBinding>,
49 argument_names: &[Option<String>],
50 argument_types: &[Option<ColumnType>],
51 explicit_variadic: bool,
52 ) -> Result<Option<ColumnType>, SQLError> {
53 self.routines.resolve_function_type(
54 name,
55 binding,
56 argument_names,
57 argument_types,
58 explicit_variadic,
59 )
60 }
61
62 fn resolve_function_overload(
63 &self,
64 name: &str,
65 binding: Option<&FunctionBinding>,
66 argument_names: &[Option<String>],
67 argument_types: &[Option<ColumnType>],
68 explicit_variadic: bool,
69 ) -> Result<Option<ResolvedFunctionOverload>, SQLError> {
70 self.routines.resolve_function_overload(
71 name,
72 binding,
73 argument_names,
74 argument_types,
75 explicit_variadic,
76 )
77 }
78
79 fn is_scalar_function_binding(&self, binding: &FunctionBinding) -> Result<bool, SQLError> {
80 self.routines.is_scalar_function_binding(binding)
81 }
82
83 fn resolve_function_overload_with_builtins(
84 &self,
85 name: &str,
86 binding: Option<&FunctionBinding>,
87 argument_names: &[Option<String>],
88 argument_types: &[Option<ColumnType>],
89 explicit_variadic: bool,
90 builtins: &[BuiltinFunctionOverload],
91 ) -> Result<Option<ResolvedFunctionOverload>, SQLError> {
92 self.routines.resolve_function_overload_with_builtins(
93 name,
94 binding,
95 argument_names,
96 argument_types,
97 explicit_variadic,
98 builtins,
99 )
100 }
101
102 fn resolve_scalar_subquery_type(
103 &self,
104 subquery: crate::SubqueryId,
105 outer_schema: &crate::RowSchema,
106 params: &[SQLParam],
107 ) -> Result<Option<ColumnType>, SQLError> {
108 let plan = self.scope.scalar_subqueries.get(subquery).ok_or_else(|| {
109 SQLError::Internal(format!(
110 "physical scalar subquery slot {subquery} is out of bounds"
111 ))
112 })?;
113 let output = crate::binding::bind_query_plan_schema(
114 self.routines,
115 plan,
116 params,
117 &self.scope.context(),
118 Some(outer_schema),
119 )?;
120 Ok(output.column_type(0).cloned())
121 }
122}