uqa_sql/binding/stored_columns/
statements.rs1use crate::ast::{MergeStmt, MergeWhen, RuleEvent};
10
11use super::{
12 action_returning_scope, ColumnBindingContext, ColumnBindingMode, ColumnScope, RelationIdentity,
13 RuleColumnDependency, SQLError, Statement, StoredColumnBinder, StoredColumnBindingContext,
14};
15
16pub fn rewrite_stored_statement_column(
17 catalog: StoredColumnBindingContext<'_>,
18 statement: &mut Statement,
19 relation: &RelationIdentity,
20 from: &str,
21 to: &str,
22) -> Result<bool, SQLError> {
23 let mode = ColumnBindingMode::Rename { relation, from, to };
24 let mut binder = StoredColumnBinder::new(catalog, mode);
25 binder.bind_statement(statement, &[], &ColumnBindingContext::default())?;
26 let shape_changed = binder.alias_shape_changed();
27 Ok(binder.finish().contains(&RuleColumnDependency {
28 relation: relation.clone(),
29 column: from.to_string(),
30 }) || shape_changed)
31}
32
33impl StoredColumnBinder<'_> {
34 pub(super) fn bind_merge(
35 &mut self,
36 merge: &mut MergeStmt,
37 outer: &[ColumnScope],
38 context: &ColumnBindingContext,
39 ) -> Result<(), SQLError> {
40 let context = self.bind_ctes(&mut merge.with, outer, context)?;
41 let target = self.table_scope(
42 &merge.target,
43 &merge.target_qualifier,
44 merge.target_alias.as_deref(),
45 &[],
46 None,
47 &ColumnBindingContext::default(),
48 )?;
49 let (local, scopes) =
50 self.bind_dml_source(Some(&mut merge.source), &target, outer, &context)?;
51 let dropped_targets =
52 crate::routines::merge_columns::dropped_stored_merge_targets(self.catalog.merge, merge);
53 self.bind_expr(&mut merge.join_condition, &scopes, &context)?;
54 for action in &mut merge.when_clauses {
55 let condition = match action {
56 MergeWhen::UpdateMatched {
57 condition,
58 assignments,
59 }
60 | MergeWhen::UpdateNotMatchedBySource {
61 condition,
62 assignments,
63 } => {
64 for (column, expression) in assignments {
65 for target_column in column.targets_mut() {
66 if self.mode.is_rename()
67 && !dropped_targets.contains(&target_column.column)
68 {
69 self.bind_target_name(&mut target_column.column, &target);
70 }
71 }
72 for expression in column.expressions_mut() {
73 self.bind_expr(expression, &scopes, &context)?;
74 }
75 self.bind_expr(expression, &scopes, &context)?;
76 }
77 condition
78 }
79 MergeWhen::InsertNotMatched {
80 condition,
81 columns,
82 values,
83 ..
84 } => {
85 if columns.is_empty() {
86 *columns = target
87 .output
88 .iter()
89 .take(values.len())
90 .map(|column| column.current_name.clone().into())
91 .collect();
92 }
93 for column in columns {
94 if self.mode.is_rename() && !dropped_targets.contains(&column.column) {
95 self.bind_target_name(&mut column.column, &target);
96 }
97 for expression in column.expressions_mut() {
98 self.bind_expr(expression, &scopes, &context)?;
99 }
100 }
101 for expression in values {
102 self.bind_expr(expression, &scopes, &context)?;
103 }
104 condition
105 }
106 MergeWhen::DeleteMatched { condition }
107 | MergeWhen::DeleteNotMatchedBySource { condition }
108 | MergeWhen::NothingMatched { condition }
109 | MergeWhen::NothingNotMatched { condition }
110 | MergeWhen::NothingNotMatchedBySource { condition } => condition,
111 };
112 if let Some(condition) = condition {
113 self.bind_expr(condition, &scopes, &context)?;
114 }
115 }
116 if let ColumnBindingMode::Rename { relation, from, to } = self.mode {
117 if merge.target == relation.qualified_name() && !dropped_targets.contains(from) {
118 if let Some(binding) = merge.target_column_bindings.remove(from) {
119 merge.target_column_bindings.insert(to.to_string(), binding);
120 }
121 }
122 }
123 let returning =
124 action_returning_scope(&local, &target, RuleEvent::Update, &merge.returning_aliases);
125 let mut scopes = vec![returning.clone()];
126 scopes.extend_from_slice(outer);
127 self.bind_projections(&mut merge.returning, Some(&returning), &scopes, &context)
128 }
129}