mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-07-07 20:45:01 +00:00
Merge 'Fix index update when INTEGER PRIMARY KEY (rowid alias)' from Adrian-Ryan Acala
When an `UPDATE` statement modifies a table's `INTEGER PRIMARY KEY` (which acts as a `rowid` alias) alongside other indexed columns, the index entries were incorrectly retaining the old `rowid`. This led to stale index references, causing subsequent queries to return incorrect results. This change ensures that when the `rowid` alias is part of the `SET` clause in an `UPDATE` statement, the new `rowid` value is used for generating and updating index records. This guarantees that all index entries correctly point to the updated row, resolving the data inconsistency. Fixes #1897 Closes #1916
This commit is contained in:
commit
471d26a632
2 changed files with 20 additions and 1 deletions
|
@ -888,7 +888,16 @@ fn emit_update_insns(
|
|||
// allocate scratch registers for the index columns plus rowid
|
||||
let idx_start_reg = program.alloc_registers(num_cols + 1);
|
||||
|
||||
let rowid_reg = beg;
|
||||
// Use the new rowid value (if the UPDATE statement sets the rowid alias),
|
||||
// otherwise keep using the original rowid. This guarantees that any
|
||||
// newly inserted/updated index entries point at the correct row after
|
||||
// the primary key change.
|
||||
let rowid_reg = if has_user_provided_rowid {
|
||||
// Safe to unwrap because `has_user_provided_rowid` implies the register was allocated.
|
||||
rowid_set_clause_reg.expect("rowid register must be set when updating rowid alias")
|
||||
} else {
|
||||
beg
|
||||
};
|
||||
let idx_cols_start_reg = beg + 1;
|
||||
|
||||
// copy each index column from the table's column registers into these scratch regs
|
||||
|
|
|
@ -205,6 +205,16 @@ if {[info exists ::env(SQLITE_EXEC)] && ($::env(SQLITE_EXEC) eq "scripts/limbo-s
|
|||
1
|
||||
2
|
||||
2}
|
||||
|
||||
do_execsql_test_on_specific_db {:memory:} update_rowid_alias_index_regression_test {
|
||||
CREATE TABLE t(a INTEGER PRIMARY KEY, b);
|
||||
CREATE INDEX idx_b ON t (b);
|
||||
INSERT INTO t VALUES (1, 'foo');
|
||||
SELECT a FROM t WHERE b = 'foo';
|
||||
UPDATE t SET a = 2, b = 'bar';
|
||||
SELECT a FROM t WHERE b = 'bar';
|
||||
} {1
|
||||
2}
|
||||
}
|
||||
|
||||
do_execsql_test_on_specific_db {:memory:} update_where_or_regression_test {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue