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 has_untyped_function(&self, name: &str) -> bool {
22 self.routines.has_untyped_function(name)
23 }
24
25 fn resolve_type_name(&self, name: &str) -> Result<Option<ColumnType>, SQLError> {
26 self.routines.resolve_type_name(name)
27 }
28
29 fn enum_labels(&self) -> Option<&dyn crate::expr::enums::EnumLabelCatalog> {
30 self.routines.enum_labels()
31 }
32
33 fn composite_types(&self) -> Option<&dyn crate::expr::composites::CompositeTypeCatalog> {
34 self.routines.composite_types()
35 }
36
37 fn resolve_function_type(
38 &self,
39 name: &str,
40 binding: Option<&FunctionBinding>,
41 argument_names: &[Option<String>],
42 argument_types: &[Option<ColumnType>],
43 explicit_variadic: bool,
44 ) -> Result<Option<ColumnType>, SQLError> {
45 self.routines.resolve_function_type(
46 name,
47 binding,
48 argument_names,
49 argument_types,
50 explicit_variadic,
51 )
52 }
53
54 fn resolve_function_overload(
55 &self,
56 name: &str,
57 binding: Option<&FunctionBinding>,
58 argument_names: &[Option<String>],
59 argument_types: &[Option<ColumnType>],
60 explicit_variadic: bool,
61 ) -> Result<Option<ResolvedFunctionOverload>, SQLError> {
62 self.routines.resolve_function_overload(
63 name,
64 binding,
65 argument_names,
66 argument_types,
67 explicit_variadic,
68 )
69 }
70
71 fn is_scalar_function_binding(&self, binding: &FunctionBinding) -> Result<bool, SQLError> {
72 self.routines.is_scalar_function_binding(binding)
73 }
74
75 fn resolve_function_overload_with_builtins(
76 &self,
77 name: &str,
78 binding: Option<&FunctionBinding>,
79 argument_names: &[Option<String>],
80 argument_types: &[Option<ColumnType>],
81 explicit_variadic: bool,
82 builtins: &[BuiltinFunctionOverload],
83 ) -> Result<Option<ResolvedFunctionOverload>, SQLError> {
84 self.routines.resolve_function_overload_with_builtins(
85 name,
86 binding,
87 argument_names,
88 argument_types,
89 explicit_variadic,
90 builtins,
91 )
92 }
93
94 fn resolve_scalar_subquery_type(
95 &self,
96 subquery: crate::SubqueryId,
97 outer_schema: &crate::RowSchema,
98 params: &[SQLParam],
99 ) -> Result<Option<ColumnType>, SQLError> {
100 let plan = self.scope.scalar_subqueries.get(subquery).ok_or_else(|| {
101 SQLError::Internal(format!(
102 "physical scalar subquery slot {subquery} is out of bounds"
103 ))
104 })?;
105 let output = crate::binding::bind_query_plan_schema(
106 self.routines,
107 plan,
108 params,
109 &self.scope.context(),
110 Some(outer_schema),
111 )?;
112 Ok(output.column_type(0).cloned())
113 }
114}