mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-23 08:55:40 +01:00
Fix index bookkeeping in DROP COLUMN
See #3448 which this issue closes.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user