uqa_sql/schema/columns/
removal.rs1use crate::{assignment::columns::ColumnCatalogError, ast::ForeignKey, SQLError};
9pub trait ColumnRemovalCatalog {
10 fn try_resolve_table_name(&self, table: &str) -> Result<Option<String>, ColumnCatalogError>;
11 fn table_names(&self) -> Result<Vec<String>, ColumnCatalogError>;
12 fn try_foreign_keys(&self, table: &str) -> Result<Vec<ForeignKey>, ColumnCatalogError>;
13}
14pub fn foreign_keys_referencing_column(
15 catalog: &dyn ColumnRemovalCatalog,
16 table: &str,
17 column: &str,
18) -> Result<Vec<(String, String)>, SQLError> {
19 let canonical = catalog
20 .try_resolve_table_name(table)
21 .map_err(|error| {
22 crate::catalog::errors::storage_error("ALTER TABLE DROP COLUMN", error.as_ref())
23 })?
24 .ok_or_else(|| SQLError::UnknownTable(table.to_string()))?;
25 let mut dependents = Vec::new();
26 for referrer in catalog.table_names().map_err(|error| {
27 crate::catalog::errors::storage_error("ALTER TABLE DROP COLUMN", error.as_ref())
28 })? {
29 for foreign_key in catalog.try_foreign_keys(&referrer).map_err(|error| {
30 crate::catalog::errors::storage_error("ALTER TABLE DROP COLUMN", error.as_ref())
31 })? {
32 if foreign_key.ref_table == canonical
33 && foreign_key.ref_columns.iter().any(|name| name == column)
34 {
35 dependents.push((
36 referrer.clone(),
37 foreign_key.name.clone().ok_or_else(|| {
38 SQLError::Internal("dependent FOREIGN KEY has no durable name".into())
39 })?,
40 ));
41 }
42 }
43 }
44 Ok(dependents)
45}