uqa_sql/schema/constraint_changes/
renaming.rs1use super::{
10 constraint_error, ensure_constraint_name_available, find_constraint, ConstraintLocation,
11};
12use crate::{
13 ast::{ColumnDef, TableConstraintSet},
14 SQLError,
15};
16
17pub fn ensure_recursive_rename(
18 name: &str,
19 recurse: bool,
20 has_children: bool,
21) -> Result<(), SQLError> {
22 if !recurse && has_children {
23 return Err(constraint_error(
24 "42P16",
25 format!("inherited constraint \"{name}\" must be renamed in child tables too"),
26 ));
27 }
28 Ok(())
29}
30
31pub fn ensure_rename_parents(name: &str, parents: usize, expected: usize) -> Result<(), SQLError> {
32 if parents > expected {
33 return Err(constraint_error(
34 "42P16",
35 format!("cannot rename inherited constraint \"{name}\""),
36 ));
37 }
38 Ok(())
39}
40
41pub fn rename_inherited_constraint(
42 table: &str,
43 columns: &mut [ColumnDef],
44 constraints: &mut TableConstraintSet,
45 from: &str,
46 to: &str,
47) -> Result<(), SQLError> {
48 let location = find_constraint(columns, constraints, from)
49 .filter(|location| {
50 matches!(
51 location,
52 ConstraintLocation::NotNull(_)
53 | ConstraintLocation::ColumnCheck(_)
54 | ConstraintLocation::TableCheck(_)
55 )
56 })
57 .ok_or_else(|| {
58 constraint_error(
59 "42704",
60 format!("constraint \"{from}\" for table \"{table}\" does not exist"),
61 )
62 })?;
63 ensure_constraint_name_available(columns, constraints, Some(to), table)?;
64 match location {
65 ConstraintLocation::NotNull(index) => columns[index].not_null_name = Some(to.to_string()),
66 ConstraintLocation::ColumnCheck(index) => columns[index].check_name = Some(to.to_string()),
67 ConstraintLocation::TableCheck(index) => {
68 constraints.checks[index].name = Some(to.to_string());
69 }
70 _ => unreachable!("only inherited constraint locations are selected"),
71 }
72 Ok(())
73}
74
75pub fn rename_foreign_key(
77 table: &str,
78 columns: &mut [ColumnDef],
79 constraints: &mut TableConstraintSet,
80 from: &str,
81 to: &str,
82) -> Result<bool, SQLError> {
83 let Some(location) = find_constraint(columns, constraints, from).filter(|location| {
84 matches!(
85 location,
86 ConstraintLocation::ColumnForeignKey(_) | ConstraintLocation::TableForeignKey(_)
87 )
88 }) else {
89 return Ok(false);
90 };
91 ensure_constraint_name_available(columns, constraints, Some(to), table)?;
92 let (name, identity) = match location {
93 ConstraintLocation::ColumnForeignKey(index) => {
94 let reference = columns[index]
95 .references
96 .as_mut()
97 .expect("selected foreign key");
98 (&mut reference.name, reference.catalog_identity)
99 }
100 ConstraintLocation::TableForeignKey(index) => {
101 let reference = &mut constraints.foreign_keys[index];
102 (&mut reference.name, reference.catalog_identity)
103 }
104 _ => unreachable!("only foreign-key locations are selected"),
105 };
106 let identity = identity
107 .ok_or_else(|| SQLError::Internal("FOREIGN KEY has no durable catalog identity".into()))?;
108 *name = Some(to.to_string());
109 for inherited in &mut constraints.hierarchy.partition_inherited_foreign_keys {
110 if inherited.catalog_identity == Some(identity) {
111 inherited.name = Some(to.to_string());
112 }
113 }
114 Ok(true)
115}
116
117#[cfg(test)]
118mod tests;