use {
super::{validate, AlterError},
crate::{data::get_name, Error, Glue, Result, SchemaDiff},
sqlparser::ast::{AlterTableOperation, ObjectName},
};
impl Glue {
pub async fn ast_alter_table(
&mut self,
name: &ObjectName,
operation: &AlterTableOperation,
) -> Result<()> {
let table_name = get_name(name).map_err(Error::from)?;
let database = &mut **self.get_mut_database(&None)?;
let diff = match operation {
AlterTableOperation::RenameTable {
table_name: new_table_name,
} => {
let new_table_name = get_name(new_table_name).map_err(Error::from)?;
SchemaDiff::new_rename(new_table_name.clone())
}
AlterTableOperation::RenameColumn {
old_column_name,
new_column_name,
} => {
let schema = database
.fetch_schema(table_name)
.await?
.ok_or(AlterError::TableNotFound(table_name.clone()))?;
let (column_index, column) = schema
.column_defs
.into_iter()
.enumerate()
.find(|(_, column)| column.name == old_column_name.value)
.ok_or(AlterError::ColumnNotFound(
table_name.clone(),
old_column_name.value.clone(),
))?;
SchemaDiff::new_rename_column(column_index, column, new_column_name.value.clone())
}
AlterTableOperation::AddColumn { column_def } => {
validate(column_def).map_err(Error::from)?;
SchemaDiff::new_add_column(column_def.into())
}
AlterTableOperation::DropColumn {
column_name,
if_exists: _,
..
} => {
let schema = database
.fetch_schema(table_name)
.await?
.ok_or(AlterError::TableNotFound(table_name.clone()))?;
let (column_index, _) = schema
.column_defs
.into_iter()
.enumerate()
.find(|(_, column)| column.name == column_name.value)
.ok_or(AlterError::ColumnNotFound(
table_name.clone(),
column_name.value.clone(),
))?;
SchemaDiff::new_remove_column(column_index)
}
_ => {
return Err(
AlterError::UnsupportedAlterTableOperation(operation.to_string()).into(),
)
}
};
database.alter_table(table_name, diff).await
}
}