MVCC does not reload planner statistics after ANALYZE
Problem
In MVCC mode, ANALYZE writes sqlite_stat1 but does not refresh the planner statistics on the same connection.
Later statements use default row estimates. This behavior can select a more expensive query plan.
WAL mode reloads the statistics after the same ANALYZE statement.
Reproduction
PRAGMA journal_mode = mvcc;
CREATE TABLE t(id INTEGER PRIMARY KEY, value INTEGER);
WITH RECURSIVE seq(n) AS (
VALUES(1)
UNION ALL
SELECT n + 1 FROM seq WHERE n < 100
)
INSERT INTO t SELECT n, n FROM seq;
ANALYZE;
SELECT tbl, idx, stat FROM sqlite_stat1;
EXPLAIN QUERY PLAN FORMAT=JSON SELECT * FROM t;sqlite_stat1 contains the correct row count:
t||100The plan still uses the default estimate:
"rows_per_input": 1000000,
"output_rows": 1000000Without MVCC, the same statements use the new statistic:
"rows_per_input": 100,
"output_rows": 100Cause
Statement::step() calls refresh_analyze_stats() after ANALYZE finishes.
The refresh returns immediately when the connection has TransactionState::Write. The MVCC connection still has this state at that point.
As a result, schema.analyze_stats keeps its old values.
Relevant code: core/stats.rs
Expected behavior
After an autocommit ANALYZE statement, the planner must use the new statistics for the next statement on the same connection.
MVCC and WAL must report the 100-row estimate in this example.
Suggested test
Add an MVCC SQL test that runs ANALYZE and checks the row estimate in the next plan.
Source: tursodatabase/turso