Description
A savepoint rollback sequence that touches overflow pages leaves a page tracked as allocated but with no buffer loaded. The next get_contents() panics, preceded by short-read errors on many pages.
Reproducer
PRAGMA page_size = 2048;
PRAGMA cache_size = 8;
PRAGMA journal_mode = WAL;
CREATE TABLE t(id INTEGER PRIMARY KEY, x BLOB);
BEGIN;
INSERT INTO t VALUES(1, zeroblob(1720000));
SAVEPOINT s1;
UPDATE t SET x = randomblob(215000) WHERE id = 1;
ROLLBACK TO s1;
RELEASE s1;
INSERT INTO t VALUES(2, randomblob(860000));
COMMIT;
-- Turso: panic (see below), preceded by many
-- "short read on page N: expected 2048 bytes, got 0"
-- SQLite: commits cleanly
Panic Message
thread ''main'' panicked at core/storage/pager.rs:766:9:
page buffer not loaded | page_id=725
core/storage/pager.rs:764-772 - PageRef::get_contents() asserts the page buffer is loaded. The short-read entries from core/storage/sqlite3_ondisk.rs:566 indicate the pager requested a page that the underlying storage returned as zero bytes, and the buffer field was never populated.
A smaller non-WAL reproducer with PRAGMA synchronous=OFF, cache_size=1, and nested savepoints (s1/s2) reaches the same panic at pager.rs:766, so the bug is not WAL-specific.
This issue brought to you by Mikaël and Claude Code.
Description
A savepoint rollback sequence that touches overflow pages leaves a page tracked as allocated but with no buffer loaded. The next
get_contents()panics, preceded by short-read errors on many pages.Reproducer
Panic Message
core/storage/pager.rs:764-772-PageRef::get_contents()asserts the page buffer is loaded. The short-read entries fromcore/storage/sqlite3_ondisk.rs:566indicate the pager requested a page that the underlying storage returned as zero bytes, and the buffer field was never populated.A smaller non-WAL reproducer with
PRAGMA synchronous=OFF,cache_size=1, and nested savepoints (s1/s2) reaches the same panic atpager.rs:766, so the bug is not WAL-specific.This issue brought to you by Mikaël and Claude Code.