Fix index bookkeeping in DROP COLUMN

See #3448 which this issue closes.
This commit is contained in:
Jussi Saurio
2025-09-30 10:00:16 +03:00
parent 2b59863447
commit 6bff9e53e5
2 changed files with 45 additions and 23 deletions

View File

@@ -119,13 +119,15 @@ pub fn translate_alter_table(
for index in table_indexes.iter() {
// Referenced in regular index
if index
let maybe_indexed_col = index
.columns
.iter()
.any(|col| col.pos_in_table == dropped_index)
{
.enumerate()
.find(|(_, col)| col.pos_in_table == dropped_index);
if let Some((pos_in_index, indexed_col)) = maybe_indexed_col {
return Err(LimboError::ParseError(format!(
"cannot drop column \"{column_name}\": indexed"
"cannot drop column \"{column_name}\": it is referenced in the index {}; position in index is {pos_in_index}, position in table is {}",
index.name, indexed_col.pos_in_table
)));
}
// Referenced in partial index

View File

@@ -7921,29 +7921,49 @@ pub fn op_drop_column(
btree.columns.remove(*column_index)
});
let schema = conn.schema.read();
if let Some(indexes) = schema.indexes.get(&normalized_table_name) {
for index in indexes {
if index
.columns
.iter()
.any(|column| column.pos_in_table == *column_index)
{
return Err(LimboError::ParseError(format!(
"cannot drop column \"{column_name}\": indexed"
)));
{
let schema = conn.schema.read();
if let Some(indexes) = schema.indexes.get(&normalized_table_name) {
for index in indexes {
if index
.columns
.iter()
.any(|column| column.pos_in_table == *column_index)
{
return Err(LimboError::ParseError(format!(
"cannot drop column \"{column_name}\": indexed"
)));
}
}
}
}
for (view_name, view) in schema.views.iter() {
let view_select_sql = format!("SELECT * FROM {view_name}");
conn.prepare(view_select_sql.as_str()).map_err(|e| {
LimboError::ParseError(format!(
"cannot drop column \"{}\": referenced in VIEW {view_name}: {}",
column_name, view.sql,
))
})?;
// Update index.pos_in_table for all indexes.
// For example, if the dropped column had index 2, then anything that was indexed on column 3 or higher should be decremented by 1.
conn.with_schema_mut(|schema| {
if let Some(indexes) = schema.indexes.get_mut(&normalized_table_name) {
for index in indexes {
let index = Arc::make_mut(index);
for index_column in index.columns.iter_mut() {
if index_column.pos_in_table > *column_index {
index_column.pos_in_table -= 1;
}
}
}
}
});
{
let schema = conn.schema.read();
for (view_name, view) in schema.views.iter() {
let view_select_sql = format!("SELECT * FROM {view_name}");
conn.prepare(view_select_sql.as_str()).map_err(|e| {
LimboError::ParseError(format!(
"cannot drop column \"{}\": referenced in VIEW {view_name}: {}",
column_name, view.sql,
))
})?;
}
}
state.pc += 1;