diff --git a/src/storage/local_storage.cpp b/src/storage/local_storage.cpp index 35a5277a4e6..de41644ffde 100644 --- a/src/storage/local_storage.cpp +++ b/src/storage/local_storage.cpp @@ -222,6 +222,29 @@ idx_t LocalStorage::Delete(DataTable *table, Vector &row_ids, idx_t count) { idx_t chunk_idx = GetChunk(row_ids); D_ASSERT(chunk_idx < storage->collection.ChunkCount()); + // delete from unique indices (if any) + if (!storage->indexes.empty()) { + // Index::Delete assumes that ALL rows are being deleted, so + // Slice out the rows that are being deleted from the storage Chunk + auto &chunk = storage->collection.GetChunk(chunk_idx); + + VectorData row_ids_data; + row_ids.Orrify(count, row_ids_data); + auto row_identifiers = (const row_t *)row_ids_data.data; + SelectionVector sel(count); + for (idx_t i = 0; i < count; ++i) { + const auto idx = row_ids_data.sel->get_index(i); + sel.set_index(i, row_identifiers[idx] - MAX_ROW_ID); + } + + DataChunk deleted; + deleted.InitializeEmpty(chunk.GetTypes()); + deleted.Slice(chunk, sel, count); + for (auto &index : storage->indexes) { + index->Delete(deleted, row_ids); + } + } + // get a pointer to the deleted entries for this chunk bool *deleted; auto entry = storage->deleted_entries.find(chunk_idx); diff --git a/test/sql/transactions/test_index_transaction_local.test b/test/sql/transactions/test_index_transaction_local.test index b14a02578e7..b59fa6f50f3 100644 --- a/test/sql/transactions/test_index_transaction_local.test +++ b/test/sql/transactions/test_index_transaction_local.test @@ -99,3 +99,24 @@ COMMIT statement error con2 COMMIT +# Issue #2241: Delete and reinsert fails on unique/indexed column +statement ok +BEGIN TRANSACTION; + +statement ok +CREATE TABLE issue2241 (id text primary key); + +statement ok +INSERT INTO issue2241 VALUES ('Alice'); + +statement ok +INSERT INTO issue2241 VALUES ('Bob'); + +statement ok +DELETE FROM issue2241 WHERE id = 'Bob'; + +statement ok +INSERT INTO issue2241 VALUES ('Bob'); + +statement ok +COMMIT;