From 7fa5cfe27d4c07c366af2e3e21755d0e241f042e Mon Sep 17 00:00:00 2001 From: Aaron Paterson Date: Fri, 23 Oct 2026 22:09:10 -0500 Subject: [PATCH] Check only the deleted row's validity bit on DELETE vec0Update_Delete_ClearValidity() tested `bx >> (chunk_offset % CHAR_BIT)`, which is nonzero whenever a later row's bit in the same byte of the chunk's validity bitmap is set. Deleting a row whose own bit was already clear therefore succeeded instead of failing with "validity bit is not set". Only a damaged _chunks table has such a row. The check now tests the row's bit alone, `(bx >> (chunk_offset % CHAR_BIT)) & 1`. Ported from photostructure/sqlite-vec@f6a3244 by Matthew McEachen. test_vec0_delete_errors sets a chunk's validity byte to x'02', clearing row 1's bit while row 2's stays set, and expects the delete of row 1 to fail. It fails on main and passes here. The full suite passes (239 passed, 66 skipped, 204 snapshots). --- sqlite-vec.c | 2 +- tests/test-loadable.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sqlite-vec.c b/sqlite-vec.c index 7af3b6a7..4978a664 100644 --- a/sqlite-vec.c +++ b/sqlite-vec.c @@ -9496,7 +9496,7 @@ int vec0Update_Delete_ClearValidity(vec0_vtab *p, i64 chunk_id, p->schemaName, p->shadowChunksName, chunk_id, validityOffset); goto cleanup; } - if (!(bx >> (chunk_offset % CHAR_BIT))) { + if (!((bx >> (chunk_offset % CHAR_BIT)) & 1)) { // IMP: V21193_05263 rc = SQLITE_ERROR; vtab_set_error( diff --git a/tests/test-loadable.py b/tests/test-loadable.py index 0044144b..1bd710a1 100644 --- a/tests/test-loadable.py +++ b/tests/test-loadable.py @@ -1102,6 +1102,14 @@ def test_vec0_delete_errors(): ): db.execute("delete from t1 where rowid = 1") db.rollback() + # only the row's own bit counts, not a higher one in the same byte + db.execute("begin") + db.execute("UPDATE t1_chunks SET validity = x'02'") + with _raises( + "vec0 deletion error: validity bit is not set for main.t1_chunks.1 at 0" + ): + db.execute("delete from t1 where rowid = 1") + db.rollback() # EVIDENCE-OF: V21193_05263 vec0 DELETE raises error on validity blob error db.commit()