uqa_sql/binding/stored_columns/
lifecycle.rs1use super::{
10 BTreeSet, ColumnBindingContext, ColumnBindingMode, Expr, RelationIdentity,
11 RuleColumnDependency, SQLError, Statement, StoredColumnBinder, StoredColumnBindingContext,
12};
13
14pub fn bind_stored_statement_source_columns(
15 statement: &mut Statement,
16 mut source_columns: impl FnMut(&str) -> Result<Option<Vec<String>>, SQLError>,
17) -> Result<bool, SQLError> {
18 let mut changed = false;
19 crate::catalog::stored_ast::visit_stored_statement_sources(statement, &mut |source| {
20 let crate::ast::FromClause::Table {
21 name,
22 bound_columns,
23 ..
24 } = source
25 else {
26 return Ok(());
27 };
28 if bound_columns.is_some() {
29 return Ok(());
30 }
31 *bound_columns = source_columns(name)?;
32 changed |= bound_columns.is_some();
33 Ok(())
34 })?;
35 Ok(changed)
36}
37
38pub fn remove_stored_statement_source_column_aliases(
39 catalog: StoredColumnBindingContext<'_>,
40 statement: &mut Statement,
41 dependencies: &BTreeSet<RuleColumnDependency>,
42) -> Result<bool, SQLError> {
43 let mut planned = statement.clone();
44 let mut binder = StoredColumnBinder::new(catalog, ColumnBindingMode::Drop { dependencies });
45 binder.bind_statement(&mut planned, &[], &ColumnBindingContext::default())?;
46 let changed = binder.alias_shape_changed();
47 if changed {
48 crate::catalog::stored_ast::copy_stored_source_column_shapes(&mut planned, statement)?;
49 }
50 Ok(changed)
51}
52
53pub fn stored_statement_column_dependencies(
54 catalog: StoredColumnBindingContext<'_>,
55 statement: &Statement,
56) -> Result<BTreeSet<RuleColumnDependency>, SQLError> {
57 bind_rule_action_column_dependencies(catalog, &mut statement.clone())
58}
59
60#[derive(Debug, Clone, Default)]
62pub struct StoredStatementColumns {
63 pub dependencies: BTreeSet<RuleColumnDependency>,
64 pub unresolved: Vec<(Option<String>, String)>,
66}
67
68pub fn stored_statement_references(
69 catalog: StoredColumnBindingContext<'_>,
70 statement: &Statement,
71) -> Result<StoredStatementColumns, SQLError> {
72 let mut binder = StoredColumnBinder::new(catalog, ColumnBindingMode::Bind);
73 binder.bind_statement(
74 &mut statement.clone(),
75 &[],
76 &ColumnBindingContext::default(),
77 )?;
78 Ok(StoredStatementColumns {
79 dependencies: binder.dependencies,
80 unresolved: binder.unresolved,
81 })
82}
83
84pub fn bind_rule_condition_column_dependencies(
85 catalog: StoredColumnBindingContext<'_>,
86 condition: &mut Expr,
87) -> Result<BTreeSet<RuleColumnDependency>, SQLError> {
88 let mut binder = StoredColumnBinder::new(catalog, ColumnBindingMode::Bind);
89 binder.bind_expr(condition, &[], &ColumnBindingContext::default())?;
90 Ok(binder.finish())
91}
92
93pub fn bind_rule_action_column_dependencies(
94 catalog: StoredColumnBindingContext<'_>,
95 action: &mut Statement,
96) -> Result<BTreeSet<RuleColumnDependency>, SQLError> {
97 let mut binder = StoredColumnBinder::new(catalog, ColumnBindingMode::Bind);
98 binder.bind_statement(action, &[], &ColumnBindingContext::default())?;
99 Ok(binder.finish())
100}
101
102pub fn rewrite_rule_column_references(
103 catalog: StoredColumnBindingContext<'_>,
104 definition: &mut crate::ast::CreateRule,
105 relation: &RelationIdentity,
106 from: &str,
107 to: &str,
108) -> Result<(), SQLError> {
109 let mode = ColumnBindingMode::Rename { relation, from, to };
110 if let Some(condition) = &mut definition.condition {
111 let mut binder = StoredColumnBinder::new(catalog, mode);
112 binder.bind_expr(condition, &[], &ColumnBindingContext::default())?;
113 }
114 for action in &mut definition.actions {
115 let mut binder = StoredColumnBinder::new(catalog, mode);
116 binder.bind_statement(action, &[], &ColumnBindingContext::default())?;
117 }
118 Ok(())
119}
120
121pub fn remove_rule_source_column_aliases(
122 catalog: StoredColumnBindingContext<'_>,
123 definition: &mut crate::ast::CreateRule,
124 dependency: &RuleColumnDependency,
125) -> Result<bool, SQLError> {
126 let dependencies = BTreeSet::from([dependency.clone()]);
127 let mode = ColumnBindingMode::Drop {
128 dependencies: &dependencies,
129 };
130 let mut changed = false;
131 if let Some(condition) = &mut definition.condition {
132 let mut binder = StoredColumnBinder::new(catalog, mode);
133 binder.bind_expr(condition, &[], &ColumnBindingContext::default())?;
134 changed |= binder.alias_shape_changed();
135 }
136 for action in &mut definition.actions {
137 let mut binder = StoredColumnBinder::new(catalog, mode);
138 binder.bind_statement(action, &[], &ColumnBindingContext::default())?;
139 changed |= binder.alias_shape_changed();
140 }
141 Ok(changed)
142}