fix mviews with re-insertion of data with the same key

There is currently a bug found in our materialized view implementation
that happens when we delete a row, and then re-insert another row with
the same primary key.

Our insert code needs to detect updates and generate a DELETE +
INSERT. But in this case, after the initial DELETE, the fresh insert
generates another delete.

We ended up with the wrong response for aggregations (and I am pretty
sure even filter-only views would manifest the bug as well), where
groups that should still be present just disappeared because of the
extra delete.

A new test case is added that fails without the fix.
This commit is contained in:
Glauber Costa
2025-10-06 20:12:49 -05:00
parent f8bdc02986
commit beb44e8e8c
2 changed files with 64 additions and 14 deletions

View File

@@ -3,6 +3,35 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Test that INSERT with reused primary keys maintains correct aggregate counts
# When a row is deleted and a new row is inserted with the same primary key
# but different group value, all groups should maintain correct counts
do_execsql_test_on_specific_db {:memory:} matview-insert-reused-key-maintains-all-groups {
CREATE TABLE t(id INTEGER PRIMARY KEY, val TEXT);
INSERT INTO t VALUES (1, 'A'), (2, 'B');
CREATE MATERIALIZED VIEW v AS
SELECT val, COUNT(*) as cnt
FROM t
GROUP BY val;
-- Initial state: A=1, B=1
SELECT * FROM v ORDER BY val;
-- Delete id=1 (which has 'A')
DELETE FROM t WHERE id = 1;
SELECT * FROM v ORDER BY val;
-- Insert id=1 with different value 'C'
-- This should NOT affect group 'B'
INSERT INTO t VALUES (1, 'C');
SELECT * FROM v ORDER BY val;
} {A|1
B|1
B|1
B|1
C|1}
do_execsql_test_on_specific_db {:memory:} matview-basic-filter-population {
CREATE TABLE products(id INTEGER, name TEXT, price INTEGER, category TEXT);
INSERT INTO products VALUES