1use crate::ast::ColumnType;
10use crate::plan::{ExpressionPlan, QueryPlan};
11use crate::RowSchema;
12use crate::{SQLError, SQLParam};
13
14use super::{BindingContext, ScalarExpr, SchemaScope};
15use crate::routines::RoutineResolution;
16
17pub fn bind_query_plan_schema(
19 routines: &dyn RoutineResolution,
20 plan: &QueryPlan,
21 params: &[SQLParam],
22 ctes: &BindingContext,
23 outer: Option<&RowSchema>,
24) -> Result<RowSchema, SQLError> {
25 SchemaScope::from_context(ctes)?.bind_query(routines, plan, params, outer)
26}
27
28pub fn bind_expression_plan_type(
30 routines: &dyn RoutineResolution,
31 plan: &ExpressionPlan,
32 params: &[SQLParam],
33 ctes: &BindingContext,
34) -> Result<Option<ColumnType>, SQLError> {
35 SchemaScope::from_context(ctes)?.bind_expression_type(
36 routines,
37 &plan.scalar,
38 &RowSchema::default(),
39 &plan.subqueries,
40 params,
41 None,
42 )
43}
44
45pub fn analyze_expression_plan_type(
47 routines: &dyn RoutineResolution,
48 plan: &ExpressionPlan,
49 params: &[SQLParam],
50 ctes: &BindingContext,
51) -> Result<Option<ColumnType>, SQLError> {
52 SchemaScope::for_analysis(ctes)?.bind_expression_type(
53 routines,
54 &plan.scalar,
55 &RowSchema::default(),
56 &plan.subqueries,
57 params,
58 None,
59 )
60}
61
62pub fn analyze_query_plan_schema(
64 routines: &dyn RoutineResolution,
65 plan: &QueryPlan,
66 params: &[SQLParam],
67 ctes: &BindingContext,
68 outer: Option<&RowSchema>,
69) -> Result<RowSchema, SQLError> {
70 SchemaScope::for_analysis(ctes)?.bind_query(routines, plan, params, outer)
71}
72
73pub fn analyze_query_plan_schema_with_catalog(
74 routines: &dyn RoutineResolution,
75 plan: &QueryPlan,
76 params: &[SQLParam],
77 catalog: crate::catalog::analysis::CatalogReadView,
78 resolution: crate::catalog::resolution::RelationNameResolution,
79) -> Result<RowSchema, SQLError> {
80 SchemaScope::for_catalog_analysis(catalog, resolution).bind_query(routines, plan, params, None)
81}
82
83pub fn overlay_outer_schema(current: &RowSchema, outer: Option<&RowSchema>) -> RowSchema {
84 outer.map_or_else(
85 || current.clone(),
86 |outer| RowSchema::with_outer_schema(current, outer),
87 )
88}
89
90pub fn values_types_in_scope(
91 routines: &dyn RoutineResolution,
92 rows: &[Vec<ScalarExpr>],
93 subqueries: &[QueryPlan],
94 schema: Option<&RowSchema>,
95 params: &[SQLParam],
96 ctes: &BindingContext,
97) -> Result<Vec<Option<ColumnType>>, SQLError> {
98 SchemaScope::from_context(ctes)?
99 .bind_values_types(routines, rows, subqueries, schema, params, schema)
100}
101
102pub(super) fn merge_types(
103 left: Option<&ColumnType>,
104 right: Option<&ColumnType>,
105) -> Result<Option<ColumnType>, SQLError> {
106 match (left, right) {
107 (None, None) => Ok(None),
108 (Some(ty), None) | (None, Some(ty)) => Ok(Some(ty.clone())),
109 (Some(left), Some(right)) => crate::common_type(left, right).map(Some),
110 }
111}