uqa_sql/schema/table_alteration/
syntax.rs1use crate::{
9 ast::{AlterTableAction, AlterTableStmt},
10 SQLError,
11};
12
13pub fn validate_alter_table_transaction(
14 stmt: &AlterTableStmt,
15 in_transaction_block: bool,
16) -> Result<(), SQLError> {
17 if in_transaction_block
18 && stmt.actions.iter().any(|action| {
19 matches!(
20 action,
21 AlterTableAction::DetachPartition {
22 concurrently: true,
23 ..
24 }
25 )
26 })
27 {
28 return Err(SQLError::Routine {
29 sqlstate: "25001".into(),
30 message: "ALTER TABLE ... DETACH CONCURRENTLY cannot run inside a transaction block"
31 .into(),
32 });
33 }
34 Ok(())
35}
36
37pub fn alter_sequence_from_table_syntax(
38 canonical: &str,
39 stmt: &AlterTableStmt,
40) -> Result<crate::ast::AlterSequence, SQLError> {
41 let mut alter = crate::ast::AlterSequence {
42 name: canonical.to_string(),
43 if_exists: stmt.if_exists,
44 ..crate::ast::AlterSequence::default()
45 };
46 match stmt.actions.as_slice() {
47 [AlterTableAction::SetPersistence { persistence }] => {
48 alter.persistence = Some(*persistence);
49 }
50 [AlterTableAction::RenameTable { to }] => {
51 alter.lifecycle = crate::ast::SequenceLifecycle::RenameTo { name: to.clone() };
52 }
53 [AlterTableAction::SetSchema { schema }] => {
54 alter.lifecycle = crate::ast::SequenceLifecycle::SetSchema {
55 schema: schema.clone(),
56 };
57 }
58 [AlterTableAction::ChangeOwner { owner }] => {
59 alter.role_owner = Some(owner.clone());
60 }
61 _ => {
62 return Err(SQLError::Routine {
63 sqlstate: "42809".into(),
64 message: format!("ALTER TABLE: relation `{canonical}` is a sequence, not a table"),
65 });
66 }
67 }
68 Ok(alter)
69}
70
71pub fn alter_view_from_table_syntax(
73 canonical: &str,
74 kind: &str,
75 stmt: &AlterTableStmt,
76) -> Result<Option<crate::ast::AlterViewStmt>, SQLError> {
77 if let [AlterTableAction::RenameTable { to }] = stmt.actions.as_slice() {
78 return Ok(Some(crate::ast::AlterViewStmt {
79 name: canonical.to_string(),
80 kind: if kind == "view" {
81 crate::ast::AlterViewKind::View
82 } else {
83 crate::ast::AlterViewKind::MaterializedView
84 },
85 if_exists: stmt.if_exists,
86 action: crate::ast::AlterViewAction::RenameTo(to.clone()),
87 }));
88 }
89 if kind == "view"
90 && stmt.actions.iter().all(|action| {
91 matches!(
92 action,
93 AlterTableAction::RenameRule { .. } | AlterTableAction::RenameTrigger { .. }
94 )
95 })
96 {
97 return Ok(None);
98 }
99 Err(SQLError::Routine {
100 sqlstate: "42809".into(),
101 message: format!("ALTER TABLE: relation `{canonical}` is a {kind}, not a table"),
102 })
103}
104
105pub fn alter_foreign_table_from_table_syntax(
107 canonical: &str,
108 stmt: &AlterTableStmt,
109) -> Result<Option<crate::ast::AlterForeignTableStmt>, SQLError> {
110 if stmt.actions.iter().all(|action| {
111 matches!(
112 action,
113 AlterTableAction::RenameTrigger { .. } | AlterTableAction::SetTriggerEnableMode { .. }
114 )
115 }) {
116 return Ok(None);
117 }
118 let action = match stmt.actions.as_slice() {
119 [AlterTableAction::ChangeOwner { owner }] => {
120 crate::ast::AlterForeignTableAction::OwnerTo(owner.clone())
121 }
122 [AlterTableAction::RenameTable { to }] => {
123 crate::ast::AlterForeignTableAction::RenameTo(to.clone())
124 }
125 _ => {
126 return Err(SQLError::Routine {
127 sqlstate: "42809".into(),
128 message: format!(
129 "ALTER TABLE: relation `{canonical}` is a foreign table, not a table"
130 ),
131 });
132 }
133 };
134 Ok(Some(crate::ast::AlterForeignTableStmt {
135 name: canonical.to_string(),
136 if_exists: stmt.if_exists,
137 action,
138 }))
139}