xref: /sqlite-3.40.0/test/wal9.test (revision 8411b25c)
17eb05752Sdan# 2012 October 15
27eb05752Sdan#
37eb05752Sdan# The author disclaims copyright to this source code.  In place of
47eb05752Sdan# a legal notice, here is a blessing:
57eb05752Sdan#
67eb05752Sdan#    May you do good and not evil.
77eb05752Sdan#    May you find forgiveness for yourself and forgive others.
87eb05752Sdan#    May you share freely, never taking more than you give.
97eb05752Sdan#
107eb05752Sdan#***********************************************************************
117eb05752Sdan#
127eb05752Sdan# This test case tests that a problem causing a failing assert() has
137eb05752Sdan# been fixed. The problem occurred if a writer process with a subset
147eb05752Sdan# of the *shm file mapped rolled back a transaction begun after the
157eb05752Sdan# entire WAL file was checkpointed into the db file (i.e. a transaction
167eb05752Sdan# that would have restarted the WAL file from the beginning).
177eb05752Sdan#
187eb05752Sdan
197eb05752Sdanset testdir [file dirname $argv0]
207eb05752Sdansource $testdir/tester.tcl
217eb05752Sdanset testprefix wal9
227eb05752Sdan
237eb05752Sdansqlite3 db2 test.db
247eb05752Sdan
257eb05752Sdando_execsql_test 1.0 {
267eb05752Sdan  PRAGMA page_size = 1024;
277eb05752Sdan  PRAGMA journal_mode = WAL;
287eb05752Sdan  PRAGMA wal_autocheckpoint = 0;
297eb05752Sdan  CREATE TABLE t(x);
307eb05752Sdan} {wal 0}
317eb05752Sdan
327eb05752Sdando_test 1.1 {
337eb05752Sdan  execsql "SELECT * FROM t" db2
347eb05752Sdan} {}
357eb05752Sdan
367eb05752Sdando_execsql_test 1.2 {
377eb05752Sdan  BEGIN;
387eb05752Sdan    INSERT INTO t VALUES(randomblob(100));
397eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
407eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
417eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
427eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
437eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
447eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
457eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
467eb05752Sdan
477eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
487eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
497eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
507eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
517eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
527eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
537eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
547eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
557eb05752Sdan
567eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
577eb05752Sdan    INSERT INTO t SELECT randomblob(100) FROM t;
587eb05752Sdan  COMMIT;
597eb05752Sdan} {}
607eb05752Sdan
617eb05752Sdan# Check file sizes are as expected. The real requirement here is that
627eb05752Sdan# the *shm file is now more than one chunk (>32KiB).
63*8411b25cSdan#
64*8411b25cSdan# The sizes of various files are slightly different in normal and
65*8411b25cSdan# auto-vacuum mode.
667eb05752Sdando_test 1.3 { file size test.db     } {1024}
67*8411b25cSdando_test 1.4 { expr {[file size test.db-wal]>(1500*1024)} } {1}
680fbb50eeSdrhdo_test 1.5 { expr {[file size test.db-shm]>32768} }       {1}
69*8411b25cSdando_test 1.6 {
70*8411b25cSdan  foreach {a b c} [db eval {PRAGMA wal_checkpoint}] break
71*8411b25cSdan  list [expr {$a==0}] [expr {$b>14500}] [expr {$c>14500}] [expr {$b==$c}]
72*8411b25cSdan} {1 1 1 1}
737eb05752Sdan
747eb05752Sdan# At this point connection [db2] has mapped the first 32KB of the *shm file
757eb05752Sdan# only. Because the entire WAL file has been checkpointed, it is not
767eb05752Sdan# necessary to map any more of the *-shm file to read or write the database
777eb05752Sdan# (since all data will be read directly from the db file).
787eb05752Sdan#
797eb05752Sdan# However, at one point if a transaction that had not yet written to the
807eb05752Sdan# WAL file was rolled back an assert() attempting to verify that the entire
817eb05752Sdan# *-shm file was mapped would fail. If NDEBUG was defined (and the assert()
827eb05752Sdan# disabled) this bug caused SQLite to ignore the return code of a mmap()
837eb05752Sdan# call.
847eb05752Sdan#
857eb05752Sdando_test 1.7 {
867eb05752Sdan  execsql {
877eb05752Sdan    BEGIN;
887eb05752Sdan      INSERT INTO t VALUES('hello');
897eb05752Sdan    ROLLBACK;
907eb05752Sdan  } db2
917eb05752Sdan} {}
927eb05752Sdandb2 close
937eb05752Sdan
947eb05752Sdanfinish_test
95