uqa_sql/schema/table_alteration/
targets.rs1use super::syntax::{
9 alter_foreign_table_from_table_syntax, alter_sequence_from_table_syntax,
10 alter_view_from_table_syntax,
11};
12use crate::{
13 ast::{AlterForeignTableStmt, AlterSequence, AlterTableAction, AlterTableStmt, AlterViewStmt},
14 catalog::resolution::RelationResolution,
15 schema::relation_alteration::RelationAlterTarget,
16 SQLError,
17};
18
19pub enum BoundTableAlteration {
20 Table(AlterTableStmt),
21 Sequence(AlterSequence),
22 View(AlterViewStmt),
23 ForeignTable(AlterForeignTableStmt),
24 IndexRename {
25 name: String,
26 new_name: String,
27 },
28 ViewEvents {
29 name: String,
30 actions: Vec<AlterTableAction>,
31 },
32 ForeignTableEvents {
33 name: String,
34 actions: Vec<AlterTableAction>,
35 },
36}
37
38pub fn table_alter_target(
39 resolution: RelationResolution,
40 statement: &AlterTableStmt,
41 notice: &mut dyn FnMut(&str),
42) -> Result<Option<RelationAlterTarget>, SQLError> {
43 RelationAlterTarget::resolve(resolution, &statement.table, statement.if_exists, notice)
44}
45
46pub fn bind_table_alteration(
47 target: RelationAlterTarget,
48 mut statement: AlterTableStmt,
49) -> Result<BoundTableAlteration, SQLError> {
50 let RelationAlterTarget {
51 canonical, kind, ..
52 } = target;
53 let bound = match kind {
54 "index"
55 if matches!(
56 statement.actions.as_slice(),
57 [AlterTableAction::RenameTable { .. }]
58 ) =>
59 {
60 let AlterTableAction::RenameTable { to } = &statement.actions[0] else {
61 unreachable!();
62 };
63 BoundTableAlteration::IndexRename {
64 name: canonical,
65 new_name: to.clone(),
66 }
67 }
68 "table" => {
69 statement.table = canonical;
70 BoundTableAlteration::Table(statement)
71 }
72 "sequence" => BoundTableAlteration::Sequence(alter_sequence_from_table_syntax(
73 &canonical, &statement,
74 )?),
75 "foreign table" => match alter_foreign_table_from_table_syntax(&canonical, &statement)? {
76 Some(change) => BoundTableAlteration::ForeignTable(change),
77 None => BoundTableAlteration::ForeignTableEvents {
78 name: canonical,
79 actions: statement.actions,
80 },
81 },
82 "view" | "materialized view" => {
83 match alter_view_from_table_syntax(&canonical, kind, &statement)? {
84 Some(change) => BoundTableAlteration::View(change),
85 None => BoundTableAlteration::ViewEvents {
86 name: canonical,
87 actions: statement.actions,
88 },
89 }
90 }
91 _ => {
92 return Err(SQLError::Routine {
93 sqlstate: "42809".into(),
94 message: format!("ALTER TABLE: relation `{canonical}` is a {kind}, not a table"),
95 });
96 }
97 };
98 Ok(bound)
99}
100
101#[cfg(test)]
102mod tests;