1# 2012 October 15 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# 12# This test case tests that a problem causing a failing assert() has 13# been fixed. The problem occurred if a writer process with a subset 14# of the *shm file mapped rolled back a transaction begun after the 15# entire WAL file was checkpointed into the db file (i.e. a transaction 16# that would have restarted the WAL file from the beginning). 17# 18 19set testdir [file dirname $argv0] 20source $testdir/tester.tcl 21set testprefix wal9 22 23sqlite3 db2 test.db 24 25do_execsql_test 1.0 { 26 PRAGMA page_size = 1024; 27 PRAGMA journal_mode = WAL; 28 PRAGMA wal_autocheckpoint = 0; 29 CREATE TABLE t(x); 30} {wal 0} 31 32do_test 1.1 { 33 execsql "SELECT * FROM t" db2 34} {} 35 36do_execsql_test 1.2 { 37 BEGIN; 38 INSERT INTO t VALUES(randomblob(100)); 39 INSERT INTO t SELECT randomblob(100) FROM t; 40 INSERT INTO t SELECT randomblob(100) FROM t; 41 INSERT INTO t SELECT randomblob(100) FROM t; 42 INSERT INTO t SELECT randomblob(100) FROM t; 43 INSERT INTO t SELECT randomblob(100) FROM t; 44 INSERT INTO t SELECT randomblob(100) FROM t; 45 INSERT INTO t SELECT randomblob(100) FROM t; 46 47 INSERT INTO t SELECT randomblob(100) FROM t; 48 INSERT INTO t SELECT randomblob(100) FROM t; 49 INSERT INTO t SELECT randomblob(100) FROM t; 50 INSERT INTO t SELECT randomblob(100) FROM t; 51 INSERT INTO t SELECT randomblob(100) FROM t; 52 INSERT INTO t SELECT randomblob(100) FROM t; 53 INSERT INTO t SELECT randomblob(100) FROM t; 54 INSERT INTO t SELECT randomblob(100) FROM t; 55 56 INSERT INTO t SELECT randomblob(100) FROM t; 57 INSERT INTO t SELECT randomblob(100) FROM t; 58 COMMIT; 59} {} 60 61# Check file sizes are as expected. The real requirement here is that 62# the *shm file is now more than one chunk (>32KiB). 63# 64# The sizes of various files are slightly different in normal and 65# auto-vacuum mode. 66do_test 1.3 { file size test.db } {1024} 67do_test 1.4 { expr {[file size test.db-wal]>(1500*1024)} } {1} 68do_test 1.5 { expr {[file size test.db-shm]>32768} } {1} 69do_test 1.6 { 70 foreach {a b c} [db eval {PRAGMA wal_checkpoint}] break 71 list [expr {$a==0}] [expr {$b>14500}] [expr {$c>14500}] [expr {$b==$c}] 72} {1 1 1 1} 73 74# At this point connection [db2] has mapped the first 32KB of the *shm file 75# only. Because the entire WAL file has been checkpointed, it is not 76# necessary to map any more of the *-shm file to read or write the database 77# (since all data will be read directly from the db file). 78# 79# However, at one point if a transaction that had not yet written to the 80# WAL file was rolled back an assert() attempting to verify that the entire 81# *-shm file was mapped would fail. If NDEBUG was defined (and the assert() 82# disabled) this bug caused SQLite to ignore the return code of a mmap() 83# call. 84# 85do_test 1.7 { 86 execsql { 87 BEGIN; 88 INSERT INTO t VALUES('hello'); 89 ROLLBACK; 90 } db2 91} {} 92db2 close 93 94finish_test 95