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::{resolve_relation_rename_source, RelationResolution},
15 SQLError,
16};
17
18pub enum BoundTableAlteration {
19 Table(AlterTableStmt),
20 Sequence(AlterSequence),
21 View(AlterViewStmt),
22 ForeignTable(AlterForeignTableStmt),
23 ViewEvents {
24 name: String,
25 actions: Vec<AlterTableAction>,
26 },
27 ForeignTableEvents {
28 name: String,
29 actions: Vec<AlterTableAction>,
30 },
31}
32
33pub fn bind_table_alteration(
34 resolution: RelationResolution,
35 mut statement: AlterTableStmt,
36 notice: &mut dyn FnMut(&str),
37) -> Result<Option<BoundTableAlteration>, SQLError> {
38 let resolution = if matches!(
39 statement.actions.as_slice(),
40 [AlterTableAction::RenameTable { .. }]
41 ) {
42 let Some(resolution) = resolve_relation_rename_source(
43 resolution,
44 &statement.table,
45 statement.if_exists,
46 notice,
47 )?
48 else {
49 return Ok(None);
50 };
51 Some(resolution)
52 } else {
53 resolution.into_found()
54 };
55 let bound = match resolution {
56 Some((canonical, "table")) => {
57 statement.table = canonical;
58 BoundTableAlteration::Table(statement)
59 }
60 Some((canonical, "sequence")) => BoundTableAlteration::Sequence(
61 alter_sequence_from_table_syntax(&canonical, &statement)?,
62 ),
63 Some((canonical, "foreign table")) => {
64 match alter_foreign_table_from_table_syntax(&canonical, &statement)? {
65 Some(change) => BoundTableAlteration::ForeignTable(change),
66 None => BoundTableAlteration::ForeignTableEvents {
67 name: canonical,
68 actions: statement.actions,
69 },
70 }
71 }
72 Some((canonical, kind @ ("view" | "materialized view"))) => {
73 match alter_view_from_table_syntax(&canonical, kind, &statement)? {
74 Some(change) => BoundTableAlteration::View(change),
75 None => BoundTableAlteration::ViewEvents {
76 name: canonical,
77 actions: statement.actions,
78 },
79 }
80 }
81 Some((canonical, kind)) => {
82 return Err(SQLError::Routine {
83 sqlstate: "42809".into(),
84 message: format!("ALTER TABLE: relation `{canonical}` is a {kind}, not a table"),
85 });
86 }
87 None if statement.if_exists => {
88 notice(&format!(
89 "relation \"{}\" does not exist, skipping",
90 statement.table
91 ));
92 return Ok(None);
93 }
94 None => {
95 return Err(SQLError::Unsupported(format!(
96 "ALTER TABLE: relation `{}` does not exist",
97 statement.table
98 )));
99 }
100 };
101 Ok(Some(bound))
102}