1e91a54e1Sdan# 2010 June 15 2e91a54e1Sdan# 3e91a54e1Sdan# The author disclaims copyright to this source code. In place of 4e91a54e1Sdan# a legal notice, here is a blessing: 5e91a54e1Sdan# 6e91a54e1Sdan# May you do good and not evil. 7e91a54e1Sdan# May you find forgiveness for yourself and forgive others. 8e91a54e1Sdan# May you share freely, never taking more than you give. 9e91a54e1Sdan# 10e91a54e1Sdan#*********************************************************************** 11e91a54e1Sdan# 12e91a54e1Sdan 13e91a54e1Sdanset testdir [file dirname $argv0] 14e91a54e1Sdansource $testdir/tester.tcl 15e91a54e1Sdansource $testdir/lock_common.tcl 16e91a54e1Sdansource $testdir/malloc_common.tcl 17e91a54e1Sdan 18b0ac3e3aSdan# 19b0ac3e3aSdan# pager1-1.*: Test inter-process locking (clients in multiple processes). 20b0ac3e3aSdan# 21b0ac3e3aSdan# pager1-2.*: Test intra-process locking (multiple clients in this process). 22b0ac3e3aSdan# 23b0ac3e3aSdan# pager1-3.*: Savepoint related tests. 24b0ac3e3aSdan# 251f4cb65aSdan# pager1-4.*: Hot-journal related tests. 261f4cb65aSdan# 27de4996e2Sdan# pager1-5.*: Cases related to multi-file commits. 28de4996e2Sdan# 29*146ed78bSdan# pager1-6.*: Cases related to "PRAGMA max_page_count" 30*146ed78bSdan# 31b0ac3e3aSdan 32b0ac3e3aSdanproc do_execsql_test {testname sql result} { 33b0ac3e3aSdan uplevel do_test $testname [list "execsql {$sql}"] [list $result] 34b0ac3e3aSdan} 35b0ac3e3aSdanproc do_catchsql_test {testname sql result} { 36b0ac3e3aSdan uplevel do_test $testname [list "catchsql {$sql}"] [list $result] 37b0ac3e3aSdan} 38b0ac3e3aSdan 3953f04f3bSdanset a_string_counter 1 4053f04f3bSdanproc a_string {n} { 4153f04f3bSdan global a_string_counter 4253f04f3bSdan incr a_string_counter 4353f04f3bSdan string range [string repeat "${a_string_counter}." $n] 1 $n 4453f04f3bSdan} 4553f04f3bSdandb func a_string a_string 4653f04f3bSdan 47a4a9095eSdando_multiclient_test tn { 48e91a54e1Sdan 49e91a54e1Sdan # Create and populate a database table using connection [db]. Check 50e91a54e1Sdan # that connections [db2] and [db3] can see the schema and content. 51e91a54e1Sdan # 52e91a54e1Sdan do_test pager1-$tn.1 { 53e91a54e1Sdan sql1 { 54e91a54e1Sdan CREATE TABLE t1(a PRIMARY KEY, b); 55e91a54e1Sdan CREATE INDEX i1 ON t1(b); 56e91a54e1Sdan INSERT INTO t1 VALUES(1, 'one'); 57e91a54e1Sdan INSERT INTO t1 VALUES(2, 'two'); 58e91a54e1Sdan } 59e91a54e1Sdan } {} 60e91a54e1Sdan do_test pager1-$tn.2 { sql2 { SELECT * FROM t1 } } {1 one 2 two} 61e91a54e1Sdan do_test pager1-$tn.3 { sql3 { SELECT * FROM t1 } } {1 one 2 two} 62e91a54e1Sdan 63e91a54e1Sdan # Open a transaction and add a row using [db]. This puts [db] in 64e91a54e1Sdan # RESERVED state. Check that connections [db2] and [db3] can still 65e91a54e1Sdan # read the database content as it was before the transaction was 66e91a54e1Sdan # opened. [db] should see the inserted row. 67e91a54e1Sdan # 68e91a54e1Sdan do_test pager1-$tn.4 { 69e91a54e1Sdan sql1 { 70e91a54e1Sdan BEGIN; 71e91a54e1Sdan INSERT INTO t1 VALUES(3, 'three'); 72e91a54e1Sdan } 73e91a54e1Sdan } {} 74e91a54e1Sdan do_test pager1-$tn.5 { sql2 { SELECT * FROM t1 } } {1 one 2 two} 75e91a54e1Sdan do_test pager1-$tn.7 { sql1 { SELECT * FROM t1 } } {1 one 2 two 3 three} 76e91a54e1Sdan 77e91a54e1Sdan # [db] still has an open write transaction. Check that this prevents 78e91a54e1Sdan # other connections (specifically [db2]) from writing to the database. 79e91a54e1Sdan # 80e91a54e1Sdan # Even if [db2] opens a transaction first, it may not write to the 81e91a54e1Sdan # database. After the attempt to write the db within a transaction, 82e91a54e1Sdan # [db2] is left with an open transaction, but not a read-lock on 83e91a54e1Sdan # the main database. So it does not prevent [db] from committing. 84e91a54e1Sdan # 85e91a54e1Sdan do_test pager1-$tn.8 { 86e91a54e1Sdan csql2 { UPDATE t1 SET a = a + 10 } 87e91a54e1Sdan } {1 {database is locked}} 88e91a54e1Sdan do_test pager1-$tn.9 { 89e91a54e1Sdan csql2 { 90e91a54e1Sdan BEGIN; 91e91a54e1Sdan UPDATE t1 SET a = a + 10; 92e91a54e1Sdan } 93e91a54e1Sdan } {1 {database is locked}} 94e91a54e1Sdan 95e91a54e1Sdan # Have [db] commit its transactions. Check the other connections can 96e91a54e1Sdan # now see the new database content. 97e91a54e1Sdan # 98e91a54e1Sdan do_test pager1-$tn.10 { sql1 { COMMIT } } {} 99e91a54e1Sdan do_test pager1-$tn.11 { sql1 { SELECT * FROM t1 } } {1 one 2 two 3 three} 100e91a54e1Sdan do_test pager1-$tn.12 { sql2 { SELECT * FROM t1 } } {1 one 2 two 3 three} 101e91a54e1Sdan do_test pager1-$tn.13 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three} 102e91a54e1Sdan 103e91a54e1Sdan # Check that, as noted above, [db2] really did keep an open transaction 104e91a54e1Sdan # after the attempt to write the database failed. 105e91a54e1Sdan # 106e91a54e1Sdan do_test pager1-$tn.14 { 107e91a54e1Sdan csql2 { BEGIN } 108e91a54e1Sdan } {1 {cannot start a transaction within a transaction}} 109e91a54e1Sdan do_test pager1-$tn.15 { sql2 { ROLLBACK } } {} 110e91a54e1Sdan 111e91a54e1Sdan # Have [db2] open a transaction and take a read-lock on the database. 112e91a54e1Sdan # Check that this prevents [db] from writing to the database (outside 113e91a54e1Sdan # of any transaction). After this fails, check that [db3] can read 114e91a54e1Sdan # the db (showing that [db] did not take a PENDING lock etc.) 115e91a54e1Sdan # 116e91a54e1Sdan do_test pager1-$tn.15 { 117e91a54e1Sdan sql2 { BEGIN; SELECT * FROM t1; } 118e91a54e1Sdan } {1 one 2 two 3 three} 119e91a54e1Sdan do_test pager1-$tn.16 { 120e91a54e1Sdan csql1 { UPDATE t1 SET a = a + 10 } 121e91a54e1Sdan } {1 {database is locked}} 122e91a54e1Sdan do_test pager1-$tn.17 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three} 123e91a54e1Sdan 124e91a54e1Sdan # This time, have [db] open a transaction before writing the database. 125e91a54e1Sdan # This works - [db] gets a RESERVED lock which does not conflict with 126e91a54e1Sdan # the SHARED lock [db2] is holding. 127e91a54e1Sdan # 128e91a54e1Sdan do_test pager1-$tn.18 { 129e91a54e1Sdan sql1 { 130e91a54e1Sdan BEGIN; 131e91a54e1Sdan UPDATE t1 SET a = a + 10; 132e91a54e1Sdan } 133e91a54e1Sdan } {} 134e91a54e1Sdan do_test pager1-$tn-19 { 135e91a54e1Sdan sql1 { PRAGMA lock_status } 136e91a54e1Sdan } {main reserved temp closed} 137e91a54e1Sdan do_test pager1-$tn-20 { 138e91a54e1Sdan sql2 { PRAGMA lock_status } 139e91a54e1Sdan } {main shared temp closed} 140e91a54e1Sdan 141e91a54e1Sdan # Check that all connections can still read the database. Only [db] sees 142e91a54e1Sdan # the updated content (as the transaction has not been committed yet). 143e91a54e1Sdan # 144e91a54e1Sdan do_test pager1-$tn.21 { sql1 { SELECT * FROM t1 } } {11 one 12 two 13 three} 145e91a54e1Sdan do_test pager1-$tn.22 { sql2 { SELECT * FROM t1 } } {1 one 2 two 3 three} 146e91a54e1Sdan do_test pager1-$tn.23 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three} 147e91a54e1Sdan 148e91a54e1Sdan # Because [db2] still has the SHARED lock, [db] is unable to commit the 149e91a54e1Sdan # transaction. If it tries, an error is returned and the connection 150e91a54e1Sdan # upgrades to a PENDING lock. 151e91a54e1Sdan # 152e91a54e1Sdan # Once this happens, [db] can read the database and see the new content, 153e91a54e1Sdan # [db2] (still holding SHARED) can still read the old content, but [db3] 154e91a54e1Sdan # (not holding any lock) is prevented by [db]'s PENDING from reading 155e91a54e1Sdan # the database. 156e91a54e1Sdan # 157e91a54e1Sdan do_test pager1-$tn.24 { csql1 { COMMIT } } {1 {database is locked}} 158e91a54e1Sdan do_test pager1-$tn-25 { 159e91a54e1Sdan sql1 { PRAGMA lock_status } 160e91a54e1Sdan } {main pending temp closed} 161e91a54e1Sdan do_test pager1-$tn.26 { sql1 { SELECT * FROM t1 } } {11 one 12 two 13 three} 162e91a54e1Sdan do_test pager1-$tn.27 { sql2 { SELECT * FROM t1 } } {1 one 2 two 3 three} 163e91a54e1Sdan do_test pager1-$tn.28 { csql3 { SELECT * FROM t1 } } {1 {database is locked}} 164e91a54e1Sdan 165e91a54e1Sdan # Have [db2] commit its read transaction, releasing the SHARED lock it 166e91a54e1Sdan # is holding. Now, neither [db2] nor [db3] may read the database (as [db] 167e91a54e1Sdan # is still holding a PENDING). 168e91a54e1Sdan # 169e91a54e1Sdan do_test pager1-$tn.29 { sql2 { COMMIT } } {} 170e91a54e1Sdan do_test pager1-$tn.30 { csql2 { SELECT * FROM t1 } } {1 {database is locked}} 171e91a54e1Sdan do_test pager1-$tn.31 { csql3 { SELECT * FROM t1 } } {1 {database is locked}} 172e91a54e1Sdan 173e91a54e1Sdan # [db] is now able to commit the transaction. Once the transaction is 174e91a54e1Sdan # committed, all three connections can read the new content. 175e91a54e1Sdan # 176e91a54e1Sdan do_test pager1-$tn.25 { sql1 { UPDATE t1 SET a = a+10 } } {} 177e91a54e1Sdan do_test pager1-$tn.26 { sql1 { COMMIT } } {} 178e91a54e1Sdan do_test pager1-$tn.27 { sql1 { SELECT * FROM t1 } } {21 one 22 two 23 three} 179e91a54e1Sdan do_test pager1-$tn.27 { sql2 { SELECT * FROM t1 } } {21 one 22 two 23 three} 180e91a54e1Sdan do_test pager1-$tn.28 { sql3 { SELECT * FROM t1 } } {21 one 22 two 23 three} 181e91a54e1Sdan} 182e91a54e1Sdan 18353f04f3bSdan#------------------------------------------------------------------------- 18453f04f3bSdan# Savepoint related test cases. 18553f04f3bSdan# 186b0ac3e3aSdando_test pager1-3.1 { 187b0ac3e3aSdan faultsim_delete_and_reopen 188b0ac3e3aSdan execsql { 189b0ac3e3aSdan CREATE TABLE t1(a PRIMARY KEY, b); 190b0ac3e3aSdan CREATE TABLE counter( 191b0ac3e3aSdan i CHECK (i<5), 192b0ac3e3aSdan u CHECK (u<10) 193b0ac3e3aSdan ); 194b0ac3e3aSdan INSERT INTO counter VALUES(0, 0); 195b0ac3e3aSdan CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN 196b0ac3e3aSdan UPDATE counter SET i = i+1; 197b0ac3e3aSdan END; 198b0ac3e3aSdan CREATE TRIGGER tr2 AFTER UPDATE ON t1 BEGIN 199b0ac3e3aSdan UPDATE counter SET u = u+1; 200b0ac3e3aSdan END; 201b0ac3e3aSdan } 202b0ac3e3aSdan execsql { SELECT * FROM counter } 203b0ac3e3aSdan} {0 0} 204b0ac3e3aSdan 205b0ac3e3aSdando_execsql_test pager1-3.2 { 206b0ac3e3aSdan BEGIN; 207b0ac3e3aSdan INSERT INTO t1 VALUES(1, randomblob(1500)); 208b0ac3e3aSdan INSERT INTO t1 VALUES(2, randomblob(1500)); 209b0ac3e3aSdan INSERT INTO t1 VALUES(3, randomblob(1500)); 210b0ac3e3aSdan SELECT * FROM counter; 211b0ac3e3aSdan} {3 0} 212b0ac3e3aSdando_catchsql_test pager1-3.3 { 213b0ac3e3aSdan INSERT INTO t1 SELECT a+3, randomblob(1500) FROM t1 214b0ac3e3aSdan} {1 {constraint failed}} 215b0ac3e3aSdando_execsql_test pager1-3.4 { SELECT * FROM counter } {3 0} 216b0ac3e3aSdando_execsql_test pager1-3.5 { SELECT a FROM t1 } {1 2 3} 217b0ac3e3aSdando_execsql_test pager1-3.6 { COMMIT } {} 218b0ac3e3aSdan 219de4996e2Sdanset otn 0 2201f4cb65aSdantestvfs tv -default 1 2211f4cb65aSdanforeach code [list { 2221f4cb65aSdan set s 512 2231f4cb65aSdan} { 2241f4cb65aSdan set s 1024 2251f4cb65aSdan set sql { PRAGMA journal_mode = memory } 2261f4cb65aSdan} { 227*146ed78bSdan set s 1024 228*146ed78bSdan set sql { 229*146ed78bSdan PRAGMA journal_mode = memory; 230*146ed78bSdan PRAGMA locking_mode = exclusive; 231*146ed78bSdan } 232*146ed78bSdan} { 2331f4cb65aSdan set s 2048 2341f4cb65aSdan tv devchar safe_append 2351f4cb65aSdan} { 2361f4cb65aSdan set s 4096 237de4996e2Sdan} { 238de4996e2Sdan set s 4096 2391f4cb65aSdan set sql { PRAGMA journal_mode = WAL } 240de4996e2Sdan} { 241de4996e2Sdan set s 8192 242de4996e2Sdan set sql { PRAGMA synchronous = off } 2431f4cb65aSdan}] { 244de4996e2Sdan 245de4996e2Sdan incr otn 246de4996e2Sdan set sql "" 247de4996e2Sdan tv devchar {} 2481f4cb65aSdan eval $code 2491f4cb65aSdan tv sectorsize $s 2501f4cb65aSdan 251de4996e2Sdan do_test pager1-3.7.$otn.0 { 2521f4cb65aSdan faultsim_delete_and_reopen 2531f4cb65aSdan execsql $sql 2541f4cb65aSdan execsql { 2551f4cb65aSdan PRAGMA cache_size = 10; 2561f4cb65aSdan CREATE TABLE t1(i INTEGER PRIMARY KEY, j blob); 2571f4cb65aSdan } 2581f4cb65aSdan } {} 2591f4cb65aSdan 2601f4cb65aSdan set tn 0 2611f4cb65aSdan set lowpoint 0 2621f4cb65aSdan foreach x { 263de4996e2Sdan 100 x 0 100 264de4996e2Sdan x 2651f4cb65aSdan 70 22 96 59 96 50 22 56 21 16 37 64 43 40 0 38 22 38 55 0 6 2661f4cb65aSdan 43 62 32 93 54 18 13 29 45 66 29 25 61 31 53 82 75 25 96 86 10 69 2671f4cb65aSdan 2 29 6 60 80 95 42 82 85 50 68 96 90 39 78 69 87 97 48 74 65 43 2681f4cb65aSdan x 2691f4cb65aSdan 86 34 26 50 41 85 58 44 89 22 6 51 45 46 58 32 97 6 1 12 32 2 2701f4cb65aSdan 69 39 48 71 33 31 5 58 90 43 24 54 12 9 18 57 4 38 91 42 27 45 2711f4cb65aSdan 50 38 56 29 10 0 26 37 83 1 78 15 47 30 75 62 46 29 68 5 30 4 2721f4cb65aSdan 27 96 33 95 79 75 56 10 29 70 32 75 52 88 5 36 50 57 46 63 88 65 2731f4cb65aSdan x 2741f4cb65aSdan 44 95 64 20 24 35 69 61 61 2 35 92 42 46 23 98 78 1 38 72 79 35 2751f4cb65aSdan 94 37 13 59 5 93 27 58 80 75 58 7 67 13 10 76 84 4 8 70 81 45 2761f4cb65aSdan 8 41 98 5 60 26 92 29 91 90 2 62 40 4 5 22 80 15 83 76 52 88 2771f4cb65aSdan 29 5 68 73 72 7 54 17 89 32 81 94 51 28 53 71 8 42 54 59 70 79 2781f4cb65aSdan x 2791f4cb65aSdan } { 2801f4cb65aSdan incr tn 2811f4cb65aSdan set now [db one {SELECT count(i) FROM t1}] 2821f4cb65aSdan if {$x == "x"} { 2831f4cb65aSdan execsql { COMMIT ; BEGIN } 2841f4cb65aSdan set lowpoint $now 285de4996e2Sdan do_test pager1.3.7.$otn.$tn { 2861f4cb65aSdan sqlite3 db2 test.db 2871f4cb65aSdan execsql { 2881f4cb65aSdan SELECT COALESCE(max(i), 0) FROM t1; 2891f4cb65aSdan PRAGMA integrity_check; 2901f4cb65aSdan } 2911f4cb65aSdan } [list $lowpoint ok] 2921f4cb65aSdan db2 close 2931f4cb65aSdan } else { 2941f4cb65aSdan if {$now > $x } { 2951f4cb65aSdan if { $x>=$lowpoint } { 2961f4cb65aSdan execsql "ROLLBACK TO sp_$x" 2971f4cb65aSdan } else { 2981f4cb65aSdan execsql "DELETE FROM t1 WHERE i>$x" 2991f4cb65aSdan set lowpoint $x 3001f4cb65aSdan } 3011f4cb65aSdan } elseif {$now < $x} { 3021f4cb65aSdan for {set k $now} {$k < $x} {incr k} { 3031f4cb65aSdan execsql "SAVEPOINT sp_$k" 3041f4cb65aSdan execsql { INSERT INTO t1(j) VALUES(randomblob(1500)) } 3051f4cb65aSdan } 3061f4cb65aSdan } 307de4996e2Sdan do_execsql_test pager1.3.7.$otn.$tn { 3081f4cb65aSdan SELECT COALESCE(max(i), 0) FROM t1; 3091f4cb65aSdan PRAGMA integrity_check; 3101f4cb65aSdan } [list $x ok] 3111f4cb65aSdan } 3121f4cb65aSdan } 3131f4cb65aSdan} 3141f4cb65aSdandb close 3151f4cb65aSdantv delete 3161f4cb65aSdan 31753f04f3bSdan#------------------------------------------------------------------------- 31853f04f3bSdan# Hot journal rollback related test cases. 31953f04f3bSdan# 32053f04f3bSdan# pager1.4.1.*: Test that the pager module deletes very small invalid 32153f04f3bSdan# journal files. 32253f04f3bSdan# 32353f04f3bSdan# pager1.4.2.*: Test that if the master journal pointer at the end of a 32453f04f3bSdan# hot-journal file appears to be corrupt (checksum does not 32553f04f3bSdan# compute) the associated journal is rolled back (and no 32653f04f3bSdan# xAccess() call to check for the presence of any master 32753f04f3bSdan# journal file is made). 32853f04f3bSdan# 329de4996e2Sdan# pager1.4.3.*: Test that the contents of a hot-journal are ignored if the 330de4996e2Sdan# page-size or sector-size in the journal header appear to 331de4996e2Sdan# be invalid (too large, too small or not a power of 2). 332de4996e2Sdan# 33353f04f3bSdando_test pager1.4.1.1 { 33453f04f3bSdan faultsim_delete_and_reopen 33553f04f3bSdan execsql { 33653f04f3bSdan CREATE TABLE x(y, z); 33753f04f3bSdan INSERT INTO x VALUES(1, 2); 33853f04f3bSdan } 33953f04f3bSdan set fd [open test.db-journal w] 34053f04f3bSdan puts -nonewline $fd "helloworld" 34153f04f3bSdan close $fd 34253f04f3bSdan file exists test.db-journal 34353f04f3bSdan} {1} 34453f04f3bSdando_test pager1.4.1.2 { execsql { SELECT * FROM x } } {1 2} 34553f04f3bSdando_test pager1.4.1.3 { file exists test.db-journal } {0} 34653f04f3bSdan 34753f04f3bSdan# Set up a [testvfs] to snapshot the file-system just before SQLite 34853f04f3bSdan# deletes the master-journal to commit a multi-file transaction. 34953f04f3bSdan# 35053f04f3bSdan# In subsequent test cases, invoking [faultsim_restore_and_reopen] sets 35153f04f3bSdan# up the file system to contain two databases, two hot-journal files and 35253f04f3bSdan# a master-journal. 35353f04f3bSdan# 35453f04f3bSdando_test pager1.4.2.1 { 35553f04f3bSdan testvfs tstvfs -default 1 35653f04f3bSdan tstvfs filter xDelete 35753f04f3bSdan tstvfs script xDeleteCallback 35853f04f3bSdan proc xDeleteCallback {method file args} { 35953f04f3bSdan set file [file tail $file] 36053f04f3bSdan if { [string match *mj* $file] } { faultsim_save } 36153f04f3bSdan } 36253f04f3bSdan faultsim_delete_and_reopen 36353f04f3bSdan db func a_string a_string 36453f04f3bSdan execsql { 36553f04f3bSdan ATTACH 'test.db2' AS aux; 36653f04f3bSdan PRAGMA journal_mode = DELETE; 36753f04f3bSdan PRAGMA main.cache_size = 10; 36853f04f3bSdan PRAGMA aux.cache_size = 10; 36953f04f3bSdan CREATE TABLE t1(a UNIQUE, b UNIQUE); 37053f04f3bSdan CREATE TABLE aux.t2(a UNIQUE, b UNIQUE); 37153f04f3bSdan INSERT INTO t1 VALUES(a_string(200), a_string(300)); 37253f04f3bSdan INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1; 37353f04f3bSdan INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1; 37453f04f3bSdan INSERT INTO t2 SELECT * FROM t1; 37553f04f3bSdan BEGIN; 37653f04f3bSdan INSERT INTO t1 SELECT a_string(201), a_string(301) FROM t1; 37753f04f3bSdan INSERT INTO t1 SELECT a_string(202), a_string(302) FROM t1; 37853f04f3bSdan INSERT INTO t1 SELECT a_string(203), a_string(303) FROM t1; 37953f04f3bSdan INSERT INTO t1 SELECT a_string(204), a_string(304) FROM t1; 38053f04f3bSdan REPLACE INTO t2 SELECT * FROM t1; 38153f04f3bSdan COMMIT; 38253f04f3bSdan } 38353f04f3bSdan db close 38453f04f3bSdan tstvfs delete 38553f04f3bSdan} {} 38653f04f3bSdando_test pager1.4.2.2 { 38753f04f3bSdan faultsim_restore_and_reopen 38853f04f3bSdan execsql { 38953f04f3bSdan SELECT count(*) FROM t1; 39053f04f3bSdan PRAGMA integrity_check; 39153f04f3bSdan } 39253f04f3bSdan} {4 ok} 39353f04f3bSdando_test pager1.4.2.3 { 39453f04f3bSdan faultsim_restore_and_reopen 39553f04f3bSdan foreach f [glob test.db-mj*] { file delete -force $f } 39653f04f3bSdan execsql { 39753f04f3bSdan SELECT count(*) FROM t1; 39853f04f3bSdan PRAGMA integrity_check; 39953f04f3bSdan } 40053f04f3bSdan} {64 ok} 40153f04f3bSdando_test pager1.4.2.4 { 40253f04f3bSdan faultsim_restore_and_reopen 40353f04f3bSdan hexio_write test.db-journal [expr [file size test.db-journal]-20] 123456 40453f04f3bSdan execsql { 40553f04f3bSdan SELECT count(*) FROM t1; 40653f04f3bSdan PRAGMA integrity_check; 40753f04f3bSdan } 40853f04f3bSdan} {4 ok} 40953f04f3bSdando_test pager1.4.2.5 { 41053f04f3bSdan faultsim_restore_and_reopen 41153f04f3bSdan hexio_write test.db-journal [expr [file size test.db-journal]-20] 123456 41253f04f3bSdan foreach f [glob test.db-mj*] { file delete -force $f } 41353f04f3bSdan execsql { 41453f04f3bSdan SELECT count(*) FROM t1; 41553f04f3bSdan PRAGMA integrity_check; 41653f04f3bSdan } 41753f04f3bSdan} {4 ok} 41853f04f3bSdan 419de4996e2Sdando_test pager1.4.3.1 { 420de4996e2Sdan testvfs tstvfs -default 1 421de4996e2Sdan tstvfs filter xSync 422de4996e2Sdan tstvfs script xSyncCallback 423de4996e2Sdan proc xSyncCallback {method file args} { 424de4996e2Sdan set file [file tail $file] 425de4996e2Sdan if { 0==[string match *journal $file] } { faultsim_save } 426de4996e2Sdan } 427de4996e2Sdan faultsim_delete_and_reopen 428de4996e2Sdan execsql { 429de4996e2Sdan PRAGMA journal_mode = DELETE; 430de4996e2Sdan CREATE TABLE t1(a, b); 431de4996e2Sdan INSERT INTO t1 VALUES(1, 2); 432de4996e2Sdan INSERT INTO t1 VALUES(3, 4); 433de4996e2Sdan } 434de4996e2Sdan db close 435de4996e2Sdan tstvfs delete 436de4996e2Sdan} {} 437de4996e2Sdan 438de4996e2Sdanforeach {tn ofst value result} { 439de4996e2Sdan 2 20 31 {1 2 3 4} 440de4996e2Sdan 3 20 32 {1 2 3 4} 441de4996e2Sdan 4 20 33 {1 2 3 4} 442de4996e2Sdan 5 20 65536 {1 2 3 4} 443de4996e2Sdan 6 20 131072 {1 2 3 4} 444de4996e2Sdan 445de4996e2Sdan 7 24 511 {1 2 3 4} 446de4996e2Sdan 8 24 513 {1 2 3 4} 447de4996e2Sdan 9 24 65536 {1 2 3 4} 448de4996e2Sdan 449de4996e2Sdan 10 32 65536 {1 2} 450de4996e2Sdan} { 451de4996e2Sdan do_test pager1.4.3.$tn { 452de4996e2Sdan faultsim_restore_and_reopen 453de4996e2Sdan hexio_write test.db-journal $ofst [format %.8x $value] 454de4996e2Sdan execsql { SELECT * FROM t1 } 455de4996e2Sdan } $result 456de4996e2Sdan} 457de4996e2Sdandb close 458de4996e2Sdan 459de4996e2Sdan#------------------------------------------------------------------------- 460*146ed78bSdan# The following tests deal with multi-file commits. 461de4996e2Sdan# 462*146ed78bSdan# pager1-5.1.*: The case where a multi-file cannot be committed because 463*146ed78bSdan# another connection is holding a SHARED lock on one of the 464*146ed78bSdan# files. After the SHARED lock is removed, the COMMIT succeeds. 465*146ed78bSdan# 466*146ed78bSdan# pager1-5.2.*: Multi-file commits with journal_mode=memory. 467*146ed78bSdan# 468*146ed78bSdan# pager1-5.3.*: Multi-file commits with journal_mode=memory. 469*146ed78bSdan# 470*146ed78bSdan# pager1-5.4.*: Check that with synchronous=normal, the master-journal file 471*146ed78bSdan# name is added to a journal file immediately after the last 472*146ed78bSdan# journal record. But with synchronous=full, extra unused space 473*146ed78bSdan# is allocated between the last journal record and the 474*146ed78bSdan# master-journal file name so that the master-journal file 475*146ed78bSdan# name does not lie on the same sector as the last journal file 476*146ed78bSdan# record. 477*146ed78bSdan# 478*146ed78bSdan# pager1-5.5.*: 479*146ed78bSdan# 480*146ed78bSdando_test pager1-5.1.1 { 481*146ed78bSdan faultsim_delete_and_reopen 482*146ed78bSdan execsql { 483*146ed78bSdan ATTACH 'test.db2' AS aux; 484*146ed78bSdan CREATE TABLE t1(a, b); 485*146ed78bSdan CREATE TABLE aux.t2(a, b); 486*146ed78bSdan INSERT INTO t1 VALUES(17, 'Lenin'); 487*146ed78bSdan INSERT INTO t1 VALUES(22, 'Stalin'); 488*146ed78bSdan INSERT INTO t1 VALUES(53, 'Khrushchev'); 489*146ed78bSdan } 490*146ed78bSdan} {} 491*146ed78bSdando_test pager1-5.1.2 { 492*146ed78bSdan execsql { 493*146ed78bSdan BEGIN; 494*146ed78bSdan INSERT INTO t1 VALUES(64, 'Brezhnev'); 495*146ed78bSdan INSERT INTO t2 SELECT * FROM t1; 496*146ed78bSdan } 497*146ed78bSdan sqlite3 db2 test.db2 498*146ed78bSdan execsql { 499*146ed78bSdan BEGIN; 500*146ed78bSdan SELECT * FROM t2; 501*146ed78bSdan } db2 502*146ed78bSdan} {} 503*146ed78bSdando_test pager1-5.1.3 { 504*146ed78bSdan catchsql COMMIT 505*146ed78bSdan} {1 {database is locked}} 506*146ed78bSdando_test pager1-5.1.4 { 507*146ed78bSdan execsql COMMIT db2 508*146ed78bSdan execsql COMMIT 509*146ed78bSdan execsql { SELECT * FROM t2 } db2 510*146ed78bSdan} {17 Lenin 22 Stalin 53 Khrushchev 64 Brezhnev} 511*146ed78bSdando_test pager1-5.1.5 { 512*146ed78bSdan db2 close 513*146ed78bSdan} {} 514*146ed78bSdan 515*146ed78bSdando_test pager1-5.2.1 { 516*146ed78bSdan execsql { 517*146ed78bSdan PRAGMA journal_mode = memory; 518*146ed78bSdan BEGIN; 519*146ed78bSdan INSERT INTO t1 VALUES(84, 'Andropov'); 520*146ed78bSdan INSERT INTO t2 VALUES(84, 'Andropov'); 521*146ed78bSdan COMMIT; 522*146ed78bSdan } 523*146ed78bSdan} {memory} 524*146ed78bSdando_test pager1-5.3.1 { 525*146ed78bSdan execsql { 526*146ed78bSdan PRAGMA journal_mode = off; 527*146ed78bSdan BEGIN; 528*146ed78bSdan INSERT INTO t1 VALUES(85, 'Gorbachev'); 529*146ed78bSdan INSERT INTO t2 VALUES(85, 'Gorbachev'); 530*146ed78bSdan COMMIT; 531*146ed78bSdan } 532*146ed78bSdan} {off} 533*146ed78bSdan 534*146ed78bSdando_test pager1-5.4.1 { 535*146ed78bSdan db close 536*146ed78bSdan testvfs tv 537*146ed78bSdan sqlite3 db test.db -vfs tv 538*146ed78bSdan execsql { ATTACH 'test.db2' AS aux } 539*146ed78bSdan 540*146ed78bSdan tv filter xDelete 541*146ed78bSdan tv script max_journal_size 542*146ed78bSdan tv sectorsize 512 543*146ed78bSdan set ::max_journal 0 544*146ed78bSdan proc max_journal_size {method args} { 545*146ed78bSdan set sz 0 546*146ed78bSdan catch { set sz [file size test.db-journal] } 547*146ed78bSdan if {$sz > $::max_journal} { 548*146ed78bSdan set ::max_journal $sz 549*146ed78bSdan } 550*146ed78bSdan return SQLITE_OK 551*146ed78bSdan } 552*146ed78bSdan execsql { 553*146ed78bSdan PRAGMA journal_mode = DELETE; 554*146ed78bSdan PRAGMA synchronous = NORMAL; 555*146ed78bSdan BEGIN; 556*146ed78bSdan INSERT INTO t1 VALUES(85, 'Gorbachev'); 557*146ed78bSdan INSERT INTO t2 VALUES(85, 'Gorbachev'); 558*146ed78bSdan COMMIT; 559*146ed78bSdan } 560*146ed78bSdan set ::max_journal 561*146ed78bSdan} [expr 2615+[string length [pwd]]] 562*146ed78bSdando_test pager1-5.4.2 { 563*146ed78bSdan set ::max_journal 0 564*146ed78bSdan execsql { 565*146ed78bSdan PRAGMA synchronous = full; 566*146ed78bSdan BEGIN; 567*146ed78bSdan DELETE FROM t1 WHERE b = 'Lenin'; 568*146ed78bSdan DELETE FROM t2 WHERE b = 'Lenin'; 569*146ed78bSdan COMMIT; 570*146ed78bSdan } 571*146ed78bSdan set ::max_journal 572*146ed78bSdan} [expr 3111+[string length [pwd]]] 573*146ed78bSdandb close 574*146ed78bSdantv delete 575*146ed78bSdan 576*146ed78bSdando_test pager1-5.5.1 { 577*146ed78bSdan sqlite3 db test.db 578*146ed78bSdan execsql { 579*146ed78bSdan ATTACH 'test.db2' AS aux; 580*146ed78bSdan PRAGMA journal_mode = PERSIST; 581*146ed78bSdan CREATE TABLE t3(a, b); 582*146ed78bSdan INSERT INTO t3 SELECT randomblob(1500), randomblob(1500) FROM t1; 583*146ed78bSdan UPDATE t3 SET b = randomblob(1500); 584*146ed78bSdan } 585*146ed78bSdan expr [file size test.db-journal] > 15000 586*146ed78bSdan} {1} 587*146ed78bSdando_test pager1-5.5.2 { 588*146ed78bSdan execsql { 589*146ed78bSdan PRAGMA synchronous = full; 590*146ed78bSdan BEGIN; 591*146ed78bSdan DELETE FROM t1 WHERE b = 'Stalin'; 592*146ed78bSdan DELETE FROM t2 WHERE b = 'Stalin'; 593*146ed78bSdan COMMIT; 594*146ed78bSdan } 595*146ed78bSdan file size test.db-journal 596*146ed78bSdan} {0} 597*146ed78bSdan 598*146ed78bSdan 599*146ed78bSdan#------------------------------------------------------------------------- 600*146ed78bSdan# The following tests work with "PRAGMA max_page_count" 601*146ed78bSdan# 602*146ed78bSdando_test pager1-6.1 { 603*146ed78bSdan faultsim_delete_and_reopen 604*146ed78bSdan execsql { 605*146ed78bSdan PRAGMA max_page_count = 10; 606*146ed78bSdan CREATE TABLE t2(a, b); 607*146ed78bSdan CREATE TABLE t3(a, b); 608*146ed78bSdan CREATE TABLE t4(a, b); 609*146ed78bSdan CREATE TABLE t5(a, b); 610*146ed78bSdan CREATE TABLE t6(a, b); 611*146ed78bSdan CREATE TABLE t7(a, b); 612*146ed78bSdan CREATE TABLE t8(a, b); 613*146ed78bSdan CREATE TABLE t9(a, b); 614*146ed78bSdan CREATE TABLE t10(a, b); 615*146ed78bSdan } 616*146ed78bSdan} {10} 617*146ed78bSdando_test pager1-6.2 { 618*146ed78bSdan catchsql { 619*146ed78bSdan CREATE TABLE t11(a, b); 620*146ed78bSdan } 621*146ed78bSdan} {1 {database or disk is full}} 622de4996e2Sdan 623e91a54e1Sdanfinish_test 624e91a54e1Sdan 625