Annotation of embedaddon/sqlite3/test/pager1.test, revision 1.1.1.1

1.1       misho       1: # 2010 June 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: 
                     13: set testdir [file dirname $argv0]
                     14: source $testdir/tester.tcl
                     15: source $testdir/lock_common.tcl
                     16: source $testdir/malloc_common.tcl
                     17: source $testdir/wal_common.tcl
                     18: 
                     19: # Do not use a codec for tests in this file, as the database file is
                     20: # manipulated directly using tcl scripts (using the [hexio_write] command).
                     21: #
                     22: do_not_use_codec
                     23: 
                     24: #
                     25: # pager1-1.*: Test inter-process locking (clients in multiple processes).
                     26: #
                     27: # pager1-2.*: Test intra-process locking (multiple clients in this process).
                     28: #
                     29: # pager1-3.*: Savepoint related tests.
                     30: #
                     31: # pager1-4.*: Hot-journal related tests.
                     32: #
                     33: # pager1-5.*: Cases related to multi-file commits.
                     34: #
                     35: # pager1-6.*: Cases related to "PRAGMA max_page_count"
                     36: #
                     37: # pager1-7.*: Cases specific to "PRAGMA journal_mode=TRUNCATE"
                     38: #
                     39: # pager1-8.*: Cases using temporary and in-memory databases.
                     40: #
                     41: # pager1-9.*: Tests related to the backup API.
                     42: #
                     43: # pager1-10.*: Test that the assumed file-system sector-size is limited to
                     44: #              64KB.
                     45: #
                     46: # pager1-12.*: Tests involving "PRAGMA page_size"
                     47: #
                     48: # pager1-13.*: Cases specific to "PRAGMA journal_mode=PERSIST"
                     49: #
                     50: # pager1-14.*: Cases specific to "PRAGMA journal_mode=OFF"
                     51: #
                     52: # pager1-15.*: Varying sqlite3_vfs.szOsFile
                     53: #
                     54: # pager1-16.*: Varying sqlite3_vfs.mxPathname
                     55: #
                     56: # pager1-17.*: Tests related to "PRAGMA omit_readlock"
                     57: #
                     58: # pager1-18.*: Test that the pager layer responds correctly if the b-tree
                     59: #              requests an invalid page number (due to db corruption).
                     60: #
                     61: 
                     62: proc recursive_select {id table {script {}}} {
                     63:   set cnt 0
                     64:   db eval "SELECT rowid, * FROM $table WHERE rowid = ($id-1)" {
                     65:     recursive_select $rowid $table $script
                     66:     incr cnt
                     67:   }
                     68:   if {$cnt==0} { eval $script }
                     69: }
                     70: 
                     71: set a_string_counter 1
                     72: proc a_string {n} {
                     73:   global a_string_counter
                     74:   incr a_string_counter
                     75:   string range [string repeat "${a_string_counter}." $n] 1 $n
                     76: }
                     77: db func a_string a_string
                     78: 
                     79: do_multiclient_test tn {
                     80: 
                     81:   # Create and populate a database table using connection [db]. Check 
                     82:   # that connections [db2] and [db3] can see the schema and content.
                     83:   #
                     84:   do_test pager1-$tn.1 {
                     85:     sql1 {
                     86:       CREATE TABLE t1(a PRIMARY KEY, b);
                     87:       CREATE INDEX i1 ON t1(b);
                     88:       INSERT INTO t1 VALUES(1, 'one'); INSERT INTO t1 VALUES(2, 'two');
                     89:     }
                     90:   } {}
                     91:   do_test pager1-$tn.2 { sql2 { SELECT * FROM t1 } } {1 one 2 two}
                     92:   do_test pager1-$tn.3 { sql3 { SELECT * FROM t1 } } {1 one 2 two}
                     93: 
                     94:   # Open a transaction and add a row using [db]. This puts [db] in
                     95:   # RESERVED state. Check that connections [db2] and [db3] can still
                     96:   # read the database content as it was before the transaction was
                     97:   # opened. [db] should see the inserted row.
                     98:   #
                     99:   do_test pager1-$tn.4 {
                    100:     sql1 {
                    101:       BEGIN;
                    102:         INSERT INTO t1 VALUES(3, 'three');
                    103:     }
                    104:   } {}
                    105:   do_test pager1-$tn.5 { sql2 { SELECT * FROM t1 } } {1 one 2 two}
                    106:   do_test pager1-$tn.7 { sql1 { SELECT * FROM t1 } } {1 one 2 two 3 three}
                    107: 
                    108:   # [db] still has an open write transaction. Check that this prevents
                    109:   # other connections (specifically [db2]) from writing to the database.
                    110:   #
                    111:   # Even if [db2] opens a transaction first, it may not write to the
                    112:   # database. After the attempt to write the db within a transaction, 
                    113:   # [db2] is left with an open transaction, but not a read-lock on
                    114:   # the main database. So it does not prevent [db] from committing.
                    115:   #
                    116:   do_test pager1-$tn.8 { 
                    117:     csql2 { UPDATE t1 SET a = a + 10 }
                    118:   } {1 {database is locked}}
                    119:   do_test pager1-$tn.9 { 
                    120:     csql2 { 
                    121:       BEGIN;
                    122:       UPDATE t1 SET a = a + 10;
                    123:     }
                    124:   } {1 {database is locked}}
                    125: 
                    126:   # Have [db] commit its transactions. Check the other connections can
                    127:   # now see the new database content.
                    128:   #
                    129:   do_test pager1-$tn.10 { sql1 { COMMIT } } {}
                    130:   do_test pager1-$tn.11 { sql1 { SELECT * FROM t1 } } {1 one 2 two 3 three}
                    131:   do_test pager1-$tn.12 { sql2 { SELECT * FROM t1 } } {1 one 2 two 3 three}
                    132:   do_test pager1-$tn.13 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three}
                    133: 
                    134:   # Check that, as noted above, [db2] really did keep an open transaction
                    135:   # after the attempt to write the database failed.
                    136:   #
                    137:   do_test pager1-$tn.14 { 
                    138:     csql2 { BEGIN } 
                    139:   } {1 {cannot start a transaction within a transaction}}
                    140:   do_test pager1-$tn.15 { sql2 { ROLLBACK } } {}
                    141: 
                    142:   # Have [db2] open a transaction and take a read-lock on the database.
                    143:   # Check that this prevents [db] from writing to the database (outside
                    144:   # of any transaction). After this fails, check that [db3] can read
                    145:   # the db (showing that [db] did not take a PENDING lock etc.)
                    146:   #
                    147:   do_test pager1-$tn.15 { 
                    148:     sql2 { BEGIN; SELECT * FROM t1; }
                    149:   } {1 one 2 two 3 three}
                    150:   do_test pager1-$tn.16 { 
                    151:     csql1 { UPDATE t1 SET a = a + 10 }
                    152:   } {1 {database is locked}}
                    153:   do_test pager1-$tn.17 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three}
                    154: 
                    155:   # This time, have [db] open a transaction before writing the database.
                    156:   # This works - [db] gets a RESERVED lock which does not conflict with
                    157:   # the SHARED lock [db2] is holding.
                    158:   #
                    159:   do_test pager1-$tn.18 { 
                    160:     sql1 { 
                    161:       BEGIN;  
                    162:       UPDATE t1 SET a = a + 10; 
                    163:     }
                    164:   } {}
                    165:   do_test pager1-$tn-19 { 
                    166:     sql1 { PRAGMA lock_status } 
                    167:   } {main reserved temp closed}
                    168:   do_test pager1-$tn-20 { 
                    169:     sql2 { PRAGMA lock_status } 
                    170:   } {main shared temp closed}
                    171: 
                    172:   # Check that all connections can still read the database. Only [db] sees
                    173:   # the updated content (as the transaction has not been committed yet).
                    174:   #
                    175:   do_test pager1-$tn.21 { sql1 { SELECT * FROM t1 } } {11 one 12 two 13 three}
                    176:   do_test pager1-$tn.22 { sql2 { SELECT * FROM t1 } } {1 one 2 two 3 three}
                    177:   do_test pager1-$tn.23 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three}
                    178: 
                    179:   # Because [db2] still has the SHARED lock, [db] is unable to commit the
                    180:   # transaction. If it tries, an error is returned and the connection 
                    181:   # upgrades to a PENDING lock.
                    182:   #
                    183:   # Once this happens, [db] can read the database and see the new content,
                    184:   # [db2] (still holding SHARED) can still read the old content, but [db3]
                    185:   # (not holding any lock) is prevented by [db]'s PENDING from reading
                    186:   # the database.
                    187:   #
                    188:   do_test pager1-$tn.24 { csql1 { COMMIT } } {1 {database is locked}}
                    189:   do_test pager1-$tn-25 { 
                    190:     sql1 { PRAGMA lock_status } 
                    191:   } {main pending temp closed}
                    192:   do_test pager1-$tn.26 { sql1 { SELECT * FROM t1  } } {11 one 12 two 13 three}
                    193:   do_test pager1-$tn.27 { sql2 { SELECT * FROM t1  } } {1 one 2 two 3 three}
                    194:   do_test pager1-$tn.28 { csql3 { SELECT * FROM t1 } } {1 {database is locked}}
                    195: 
                    196:   # Have [db2] commit its read transaction, releasing the SHARED lock it
                    197:   # is holding. Now, neither [db2] nor [db3] may read the database (as [db]
                    198:   # is still holding a PENDING).
                    199:   #
                    200:   do_test pager1-$tn.29 { sql2 { COMMIT } } {}
                    201:   do_test pager1-$tn.30 { csql2 { SELECT * FROM t1 } } {1 {database is locked}}
                    202:   do_test pager1-$tn.31 { csql3 { SELECT * FROM t1 } } {1 {database is locked}}
                    203: 
                    204:   # [db] is now able to commit the transaction. Once the transaction is 
                    205:   # committed, all three connections can read the new content.
                    206:   #
                    207:   do_test pager1-$tn.25 { sql1 { UPDATE t1 SET a = a+10 } } {}
                    208:   do_test pager1-$tn.26 { sql1 { COMMIT } } {}
                    209:   do_test pager1-$tn.27 { sql1 { SELECT * FROM t1 } } {21 one 22 two 23 three}
                    210:   do_test pager1-$tn.27 { sql2 { SELECT * FROM t1 } } {21 one 22 two 23 three}
                    211:   do_test pager1-$tn.28 { sql3 { SELECT * FROM t1 } } {21 one 22 two 23 three}
                    212: 
                    213:   # Install a busy-handler for connection [db].
                    214:   #
                    215:   set ::nbusy [list]
                    216:   proc busy {n} {
                    217:     lappend ::nbusy $n
                    218:     if {$n>5} { sql2 COMMIT }
                    219:     return 0
                    220:   }
                    221:   db busy busy
                    222: 
                    223:   do_test pager1-$tn.29 { 
                    224:     sql1 { BEGIN ; INSERT INTO t1 VALUES('x', 'y') } 
                    225:   } {}
                    226:   do_test pager1-$tn.30 { 
                    227:     sql2 { BEGIN ; SELECT * FROM t1 } 
                    228:   } {21 one 22 two 23 three}
                    229:   do_test pager1-$tn.31 { sql1 COMMIT } {}
                    230:   do_test pager1-$tn.32 { set ::nbusy } {0 1 2 3 4 5 6}
                    231: }
                    232: 
                    233: #-------------------------------------------------------------------------
                    234: # Savepoint related test cases.
                    235: #
                    236: # pager1-3.1.2.*: Force a savepoint rollback to cause the database file
                    237: #                 to grow.
                    238: #
                    239: # pager1-3.1.3.*: Use a journal created in synchronous=off mode as part
                    240: #                 of a savepoint rollback.
                    241: # 
                    242: do_test pager1-3.1.1 {
                    243:   faultsim_delete_and_reopen
                    244:   execsql {
                    245:     CREATE TABLE t1(a PRIMARY KEY, b);
                    246:     CREATE TABLE counter(
                    247:       i CHECK (i<5), 
                    248:       u CHECK (u<10)
                    249:     );
                    250:     INSERT INTO counter VALUES(0, 0);
                    251:     CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
                    252:       UPDATE counter SET i = i+1;
                    253:     END;
                    254:     CREATE TRIGGER tr2 AFTER UPDATE ON t1 BEGIN
                    255:       UPDATE counter SET u = u+1;
                    256:     END;
                    257:   }
                    258:   execsql { SELECT * FROM counter }
                    259: } {0 0}
                    260: 
                    261: do_execsql_test pager1-3.1.2 {
                    262:   PRAGMA cache_size = 10;
                    263:   BEGIN;
                    264:     INSERT INTO t1 VALUES(1, randomblob(1500));
                    265:     INSERT INTO t1 VALUES(2, randomblob(1500));
                    266:     INSERT INTO t1 VALUES(3, randomblob(1500));
                    267:     SELECT * FROM counter;
                    268: } {3 0}
                    269: do_catchsql_test pager1-3.1.3 {
                    270:     INSERT INTO t1 SELECT a+3, randomblob(1500) FROM t1
                    271: } {1 {constraint failed}}
                    272: do_execsql_test pager1-3.4 { SELECT * FROM counter } {3 0}
                    273: do_execsql_test pager1-3.5 { SELECT a FROM t1 } {1 2 3}
                    274: do_execsql_test pager1-3.6 { COMMIT } {}
                    275: 
                    276: foreach {tn sql tcl} {
                    277:   7  { PRAGMA synchronous = NORMAL ; PRAGMA temp_store = 0 } {
                    278:     testvfs tv -default 1
                    279:     tv devchar safe_append
                    280:   }
                    281:   8  { PRAGMA synchronous = NORMAL ; PRAGMA temp_store = 2 } {
                    282:     testvfs tv -default 1
                    283:     tv devchar sequential
                    284:   }
                    285:   9  { PRAGMA synchronous = FULL } { }
                    286:   10 { PRAGMA synchronous = NORMAL } { }
                    287:   11 { PRAGMA synchronous = OFF } { }
                    288:   12 { PRAGMA synchronous = FULL ; PRAGMA fullfsync = 1 } { }
                    289:   13 { PRAGMA synchronous = FULL } {
                    290:     testvfs tv -default 1
                    291:     tv devchar sequential
                    292:   }
                    293:   14 { PRAGMA locking_mode = EXCLUSIVE } {
                    294:   }
                    295: } {
                    296:   do_test pager1-3.$tn.1 {
                    297:     eval $tcl
                    298:     faultsim_delete_and_reopen
                    299:     db func a_string a_string
                    300:     execsql $sql
                    301:     execsql {
                    302:       PRAGMA auto_vacuum = 2;
                    303:       PRAGMA cache_size = 10;
                    304:       CREATE TABLE z(x INTEGER PRIMARY KEY, y);
                    305:       BEGIN;
                    306:         INSERT INTO z VALUES(NULL, a_string(800));
                    307:         INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   2
                    308:         INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   4
                    309:         INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   8
                    310:         INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  16
                    311:         INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  32
                    312:         INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  64
                    313:         INSERT INTO z SELECT NULL, a_string(800) FROM z;     -- 128
                    314:         INSERT INTO z SELECT NULL, a_string(800) FROM z;     -- 256
                    315:       COMMIT;
                    316:     }
                    317:     execsql { PRAGMA auto_vacuum }
                    318:   } {2}
                    319:   do_execsql_test pager1-3.$tn.2 {
                    320:     BEGIN;
                    321:       INSERT INTO z VALUES(NULL, a_string(800));
                    322:       INSERT INTO z VALUES(NULL, a_string(800));
                    323:       SAVEPOINT one;
                    324:         UPDATE z SET y = NULL WHERE x>256;
                    325:         PRAGMA incremental_vacuum;
                    326:         SELECT count(*) FROM z WHERE x < 100;
                    327:       ROLLBACK TO one;
                    328:     COMMIT;
                    329:   } {99}
                    330: 
                    331:   do_execsql_test pager1-3.$tn.3 {
                    332:     BEGIN;
                    333:       SAVEPOINT one;
                    334:         UPDATE z SET y = y||x;
                    335:       ROLLBACK TO one;
                    336:     COMMIT;
                    337:     SELECT count(*) FROM z;
                    338:   } {258}
                    339: 
                    340:   do_execsql_test pager1-3.$tn.4 {
                    341:     SAVEPOINT one;
                    342:       UPDATE z SET y = y||x;
                    343:     ROLLBACK TO one;
                    344:   } {}
                    345:   do_execsql_test pager1-3.$tn.5 {
                    346:     SELECT count(*) FROM z;
                    347:     RELEASE one;
                    348:     PRAGMA integrity_check;
                    349:   } {258 ok}
                    350: 
                    351:   do_execsql_test pager1-3.$tn.6 {
                    352:     SAVEPOINT one;
                    353:     RELEASE one;
                    354:   } {}
                    355: 
                    356:   db close
                    357:   catch { tv delete }
                    358: }
                    359: 
                    360: #-------------------------------------------------------------------------
                    361: # Hot journal rollback related test cases.
                    362: #
                    363: # pager1.4.1.*: Test that the pager module deletes very small invalid
                    364: #               journal files.
                    365: #
                    366: # pager1.4.2.*: Test that if the master journal pointer at the end of a
                    367: #               hot-journal file appears to be corrupt (checksum does not
                    368: #               compute) the associated journal is rolled back (and no
                    369: #               xAccess() call to check for the presence of any master 
                    370: #               journal file is made).
                    371: #
                    372: # pager1.4.3.*: Test that the contents of a hot-journal are ignored if the
                    373: #               page-size or sector-size in the journal header appear to
                    374: #               be invalid (too large, too small or not a power of 2).
                    375: #
                    376: # pager1.4.4.*: Test hot-journal rollback of journal file with a master
                    377: #               journal pointer generated in various "PRAGMA synchronous"
                    378: #               modes.
                    379: #
                    380: # pager1.4.5.*: Test that hot-journal rollback stops if it encounters a
                    381: #               journal-record for which the checksum fails.
                    382: #
                    383: # pager1.4.6.*: Test that when rolling back a hot-journal that contains a
                    384: #               master journal pointer, the master journal file is deleted
                    385: #               after all the hot-journals that refer to it are deleted.
                    386: #
                    387: # pager1.4.7.*: Test that if a hot-journal file exists but a client can
                    388: #               open it for reading only, the database cannot be accessed and
                    389: #               SQLITE_CANTOPEN is returned.
                    390: # 
                    391: do_test pager1.4.1.1 {
                    392:   faultsim_delete_and_reopen
                    393:   execsql { 
                    394:     CREATE TABLE x(y, z);
                    395:     INSERT INTO x VALUES(1, 2);
                    396:   }
                    397:   set fd [open test.db-journal w]
                    398:   puts -nonewline $fd "helloworld"
                    399:   close $fd
                    400:   file exists test.db-journal
                    401: } {1}
                    402: do_test pager1.4.1.2 { execsql { SELECT * FROM x } } {1 2}
                    403: do_test pager1.4.1.3 { file exists test.db-journal } {0}
                    404: 
                    405: # Set up a [testvfs] to snapshot the file-system just before SQLite
                    406: # deletes the master-journal to commit a multi-file transaction.
                    407: #
                    408: # In subsequent test cases, invoking [faultsim_restore_and_reopen] sets
                    409: # up the file system to contain two databases, two hot-journal files and
                    410: # a master-journal.
                    411: #
                    412: do_test pager1.4.2.1 {
                    413:   testvfs tstvfs -default 1
                    414:   tstvfs filter xDelete
                    415:   tstvfs script xDeleteCallback
                    416:   proc xDeleteCallback {method file args} {
                    417:     set file [file tail $file]
                    418:     if { [string match *mj* $file] } { faultsim_save }
                    419:   }
                    420:   faultsim_delete_and_reopen
                    421:   db func a_string a_string
                    422:   execsql {
                    423:     ATTACH 'test.db2' AS aux;
                    424:     PRAGMA journal_mode = DELETE;
                    425:     PRAGMA main.cache_size = 10;
                    426:     PRAGMA aux.cache_size = 10;
                    427:     CREATE TABLE t1(a UNIQUE, b UNIQUE);
                    428:     CREATE TABLE aux.t2(a UNIQUE, b UNIQUE);
                    429:     INSERT INTO t1 VALUES(a_string(200), a_string(300));
                    430:     INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
                    431:     INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
                    432:     INSERT INTO t2 SELECT * FROM t1;
                    433:     BEGIN;
                    434:       INSERT INTO t1 SELECT a_string(201), a_string(301) FROM t1;
                    435:       INSERT INTO t1 SELECT a_string(202), a_string(302) FROM t1;
                    436:       INSERT INTO t1 SELECT a_string(203), a_string(303) FROM t1;
                    437:       INSERT INTO t1 SELECT a_string(204), a_string(304) FROM t1;
                    438:       REPLACE INTO t2 SELECT * FROM t1;
                    439:     COMMIT;
                    440:   }
                    441:   db close
                    442:   tstvfs delete
                    443: } {}
                    444: 
                    445: if {$::tcl_platform(platform)!="windows"} {
                    446: do_test pager1.4.2.2 {
                    447:   faultsim_restore_and_reopen
                    448:   execsql {
                    449:     SELECT count(*) FROM t1;
                    450:     PRAGMA integrity_check;
                    451:   }
                    452: } {4 ok}
                    453: do_test pager1.4.2.3 {
                    454:   faultsim_restore_and_reopen
                    455:   foreach f [glob test.db-mj*] { forcedelete $f }
                    456:   execsql {
                    457:     SELECT count(*) FROM t1;
                    458:     PRAGMA integrity_check;
                    459:   }
                    460: } {64 ok}
                    461: do_test pager1.4.2.4 {
                    462:   faultsim_restore_and_reopen
                    463:   hexio_write test.db-journal [expr [file size test.db-journal]-20] 123456
                    464:   execsql {
                    465:     SELECT count(*) FROM t1;
                    466:     PRAGMA integrity_check;
                    467:   }
                    468: } {4 ok}
                    469: do_test pager1.4.2.5 {
                    470:   faultsim_restore_and_reopen
                    471:   hexio_write test.db-journal [expr [file size test.db-journal]-20] 123456
                    472:   foreach f [glob test.db-mj*] { forcedelete $f }
                    473:   execsql {
                    474:     SELECT count(*) FROM t1;
                    475:     PRAGMA integrity_check;
                    476:   }
                    477: } {4 ok}
                    478: }
                    479: 
                    480: do_test pager1.4.3.1 {
                    481:   testvfs tstvfs -default 1
                    482:   tstvfs filter xSync
                    483:   tstvfs script xSyncCallback
                    484:   proc xSyncCallback {method file args} {
                    485:     set file [file tail $file]
                    486:     if { 0==[string match *journal $file] } { faultsim_save }
                    487:   }
                    488:   faultsim_delete_and_reopen
                    489:   execsql {
                    490:     PRAGMA journal_mode = DELETE;
                    491:     CREATE TABLE t1(a, b);
                    492:     INSERT INTO t1 VALUES(1, 2);
                    493:     INSERT INTO t1 VALUES(3, 4);
                    494:   }
                    495:   db close
                    496:   tstvfs delete
                    497: } {}
                    498: 
                    499: foreach {tn ofst value result} {
                    500:           2   20    31       {1 2 3 4}
                    501:           3   20    32       {1 2 3 4}
                    502:           4   20    33       {1 2 3 4}
                    503:           5   20    65536    {1 2 3 4}
                    504:           6   20    131072   {1 2 3 4}
                    505: 
                    506:           7   24    511      {1 2 3 4}
                    507:           8   24    513      {1 2 3 4}
                    508:           9   24    131072   {1 2 3 4}
                    509: 
                    510:          10   32    65536    {1 2}
                    511: } {
                    512:   do_test pager1.4.3.$tn {
                    513:     faultsim_restore_and_reopen
                    514:     hexio_write test.db-journal $ofst [format %.8x $value]
                    515:     execsql { SELECT * FROM t1 }
                    516:   } $result
                    517: }
                    518: db close
                    519: 
                    520: # Set up a VFS that snapshots the file-system just before a master journal
                    521: # file is deleted to commit a multi-file transaction. Specifically, the
                    522: # file-system is saved just before the xDelete() call to remove the 
                    523: # master journal file from the file-system.
                    524: #
                    525: testvfs tv -default 1
                    526: tv script copy_on_mj_delete
                    527: set ::mj_filename_length 0
                    528: proc copy_on_mj_delete {method filename args} {
                    529:   if {[string match *mj* [file tail $filename]]} { 
                    530:     set ::mj_filename_length [string length $filename]
                    531:     faultsim_save 
                    532:   }
                    533:   return SQLITE_OK
                    534: }
                    535: 
                    536: set pwd [pwd]
                    537: foreach {tn1 tcl} {
                    538:   1 { set prefix "test.db" }
                    539:   2 { 
                    540:     # This test depends on the underlying VFS being able to open paths
                    541:     # 512 bytes in length. The idea is to create a hot-journal file that
                    542:     # contains a master-journal pointer so large that it could contain
                    543:     # a valid page record (if the file page-size is 512 bytes). So as to
                    544:     # make sure SQLite doesn't get confused by this.
                    545:     #
                    546:     set nPadding [expr 511 - $::mj_filename_length]
                    547:     if {$tcl_platform(platform)=="windows"} {
                    548:       # TBD need to figure out how to do this correctly for Windows!!!
                    549:       set nPadding [expr 255 - $::mj_filename_length]
                    550:     }
                    551: 
                    552:     # We cannot just create a really long database file name to open, as
                    553:     # Linux limits a single component of a path to 255 bytes by default
                    554:     # (and presumably other systems have limits too). So create a directory
                    555:     # hierarchy to work in.
                    556:     #
                    557:     set dirname "d123456789012345678901234567890/"
                    558:     set nDir [expr $nPadding / 32]
                    559:     if { $nDir } {
                    560:       set p [string repeat $dirname $nDir]
                    561:       file mkdir $p
                    562:       cd $p
                    563:     }
                    564: 
                    565:     set padding [string repeat x [expr $nPadding %32]]
                    566:     set prefix "test.db${padding}"
                    567:   }
                    568: } {
                    569:   eval $tcl
                    570:   foreach {tn2 sql} {
                    571:     o { 
                    572:       PRAGMA main.synchronous=OFF;
                    573:       PRAGMA aux.synchronous=OFF;
                    574:       PRAGMA journal_mode = DELETE;
                    575:     }
                    576:     o512 { 
                    577:       PRAGMA main.synchronous=OFF;
                    578:       PRAGMA aux.synchronous=OFF;
                    579:       PRAGMA main.page_size = 512;
                    580:       PRAGMA aux.page_size = 512;
                    581:       PRAGMA journal_mode = DELETE;
                    582:     }
                    583:     n { 
                    584:       PRAGMA main.synchronous=NORMAL;
                    585:       PRAGMA aux.synchronous=NORMAL;
                    586:       PRAGMA journal_mode = DELETE;
                    587:     }
                    588:     f { 
                    589:       PRAGMA main.synchronous=FULL;
                    590:       PRAGMA aux.synchronous=FULL;
                    591:       PRAGMA journal_mode = DELETE;
                    592:     }
                    593:   } {
                    594: 
                    595:     set tn "${tn1}.${tn2}"
                    596:   
                    597:     # Set up a connection to have two databases, test.db (main) and 
                    598:     # test.db2 (aux). Then run a multi-file transaction on them. The
                    599:     # VFS will snapshot the file-system just before the master-journal
                    600:     # file is deleted to commit the transaction.
                    601:     #
                    602:     tv filter xDelete
                    603:     do_test pager1-4.4.$tn.1 {
                    604:       faultsim_delete_and_reopen $prefix
                    605:       execsql "
                    606:         ATTACH '${prefix}2' AS aux;
                    607:         $sql
                    608:         CREATE TABLE a(x);
                    609:         CREATE TABLE aux.b(x);
                    610:         INSERT INTO a VALUES('double-you');
                    611:         INSERT INTO a VALUES('why');
                    612:         INSERT INTO a VALUES('zed');
                    613:         INSERT INTO b VALUES('won');
                    614:         INSERT INTO b VALUES('too');
                    615:         INSERT INTO b VALUES('free');
                    616:       "
                    617:       execsql {
                    618:         BEGIN;
                    619:           INSERT INTO a SELECT * FROM b WHERE rowid<=3;
                    620:           INSERT INTO b SELECT * FROM a WHERE rowid<=3;
                    621:         COMMIT;
                    622:       }
                    623:     } {}
                    624:     tv filter {}
                    625:     
                    626:     # Check that the transaction was committed successfully.
                    627:     #
                    628:     do_execsql_test pager1-4.4.$tn.2 {
                    629:       SELECT * FROM a
                    630:     } {double-you why zed won too free}
                    631:     do_execsql_test pager1-4.4.$tn.3 {
                    632:       SELECT * FROM b
                    633:     } {won too free double-you why zed}
                    634:     
                    635:     # Restore the file-system and reopen the databases. Check that it now
                    636:     # appears that the transaction was not committed (because the file-system
                    637:     # was restored to the state where it had not been).
                    638:     #
                    639:     do_test pager1-4.4.$tn.4 {
                    640:       faultsim_restore_and_reopen $prefix
                    641:       execsql "ATTACH '${prefix}2' AS aux"
                    642:     } {}
                    643:     do_execsql_test pager1-4.4.$tn.5 {SELECT * FROM a} {double-you why zed}
                    644:     do_execsql_test pager1-4.4.$tn.6 {SELECT * FROM b} {won too free}
                    645:     
                    646:     # Restore the file-system again. This time, before reopening the databases,
                    647:     # delete the master-journal file from the file-system. It now appears that
                    648:     # the transaction was committed (no master-journal file == no rollback).
                    649:     #
                    650:     do_test pager1-4.4.$tn.7 {
                    651:       faultsim_restore_and_reopen $prefix
                    652:       foreach f [glob ${prefix}-mj*] { forcedelete $f }
                    653:       execsql "ATTACH '${prefix}2' AS aux"
                    654:     } {}
                    655:     do_execsql_test pager1-4.4.$tn.8 {
                    656:       SELECT * FROM a
                    657:     } {double-you why zed won too free}
                    658:     do_execsql_test pager1-4.4.$tn.9 {
                    659:       SELECT * FROM b
                    660:     } {won too free double-you why zed}
                    661:   }
                    662: 
                    663:   cd $pwd
                    664: }
                    665: db close
                    666: tv delete
                    667: forcedelete $dirname
                    668: 
                    669: 
                    670: # Set up a VFS to make a copy of the file-system just before deleting a
                    671: # journal file to commit a transaction. The transaction modifies exactly
                    672: # two database pages (and page 1 - the change counter).
                    673: #
                    674: testvfs tv -default 1
                    675: tv sectorsize 512
                    676: tv script copy_on_journal_delete
                    677: tv filter xDelete
                    678: proc copy_on_journal_delete {method filename args} {
                    679:   if {[string match *journal $filename]} faultsim_save 
                    680:   return SQLITE_OK
                    681: }
                    682: faultsim_delete_and_reopen
                    683: do_execsql_test pager1.4.5.1 {
                    684:   PRAGMA journal_mode = DELETE;
                    685:   PRAGMA page_size = 1024;
                    686:   CREATE TABLE t1(a, b);
                    687:   CREATE TABLE t2(a, b);
                    688:   INSERT INTO t1 VALUES('I', 'II');
                    689:   INSERT INTO t2 VALUES('III', 'IV');
                    690:   BEGIN;
                    691:     INSERT INTO t1 VALUES(1, 2);
                    692:     INSERT INTO t2 VALUES(3, 4);
                    693:   COMMIT;
                    694: } {delete}
                    695: tv filter {}
                    696: 
                    697: # Check the transaction was committed:
                    698: #
                    699: do_execsql_test pager1.4.5.2 {
                    700:   SELECT * FROM t1;
                    701:   SELECT * FROM t2;
                    702: } {I II 1 2 III IV 3 4}
                    703: 
                    704: # Now try four tests:
                    705: #
                    706: #  pager1-4.5.3: Restore the file-system. Check that the whole transaction 
                    707: #                is rolled back.
                    708: #
                    709: #  pager1-4.5.4: Restore the file-system. Corrupt the first record in the
                    710: #                journal. Check the transaction is not rolled back.
                    711: #
                    712: #  pager1-4.5.5: Restore the file-system. Corrupt the second record in the
                    713: #                journal. Check that the first record in the transaction is 
                    714: #                played back, but not the second.
                    715: #
                    716: #  pager1-4.5.6: Restore the file-system. Try to open the database with a
                    717: #                readonly connection. This should fail, as a read-only
                    718: #                connection cannot roll back the database file.
                    719: #
                    720: faultsim_restore_and_reopen
                    721: do_execsql_test pager1.4.5.3 {
                    722:   SELECT * FROM t1;
                    723:   SELECT * FROM t2;
                    724: } {I II III IV}
                    725: faultsim_restore_and_reopen
                    726: hexio_write test.db-journal [expr 512+4+1024 - 202] 0123456789ABCDEF
                    727: do_execsql_test pager1.4.5.4 {
                    728:   SELECT * FROM t1;
                    729:   SELECT * FROM t2;
                    730: } {I II 1 2 III IV 3 4}
                    731: faultsim_restore_and_reopen
                    732: hexio_write test.db-journal [expr 512+4+1024+4+4+1024 - 202] 0123456789ABCDEF
                    733: do_execsql_test pager1.4.5.5 {
                    734:   SELECT * FROM t1;
                    735:   SELECT * FROM t2;
                    736: } {I II III IV 3 4}
                    737: 
                    738: faultsim_restore_and_reopen
                    739: db close
                    740: sqlite3 db test.db -readonly 1
                    741: do_catchsql_test pager1.4.5.6 {
                    742:   SELECT * FROM t1;
                    743:   SELECT * FROM t2;
                    744: } {1 {disk I/O error}}
                    745: db close
                    746: 
                    747: # Snapshot the file-system just before multi-file commit. Save the name
                    748: # of the master journal file in $::mj_filename.
                    749: #
                    750: tv script copy_on_mj_delete
                    751: tv filter xDelete
                    752: proc copy_on_mj_delete {method filename args} {
                    753:   if {[string match *mj* [file tail $filename]]} { 
                    754:     set ::mj_filename $filename
                    755:     faultsim_save 
                    756:   }
                    757:   return SQLITE_OK
                    758: }
                    759: do_test pager1.4.6.1 {
                    760:   faultsim_delete_and_reopen
                    761:   execsql {
                    762:     PRAGMA journal_mode = DELETE;
                    763:     ATTACH 'test.db2' AS two;
                    764:     CREATE TABLE t1(a, b);
                    765:     CREATE TABLE two.t2(a, b);
                    766:     INSERT INTO t1 VALUES(1, 't1.1');
                    767:     INSERT INTO t2 VALUES(1, 't2.1');
                    768:     BEGIN;
                    769:       UPDATE t1 SET b = 't1.2';
                    770:       UPDATE t2 SET b = 't2.2';
                    771:     COMMIT;
                    772:   }
                    773:   tv filter {}
                    774:   db close
                    775: } {}
                    776: 
                    777: faultsim_restore_and_reopen
                    778: do_execsql_test pager1.4.6.2 { SELECT * FROM t1 }           {1 t1.1}
                    779: do_test         pager1.4.6.3 { file exists $::mj_filename } {1}
                    780: do_execsql_test pager1.4.6.4 {
                    781:   ATTACH 'test.db2' AS two;
                    782:   SELECT * FROM t2;
                    783: } {1 t2.1}
                    784: do_test pager1.4.6.5 { file exists $::mj_filename } {0}
                    785: 
                    786: faultsim_restore_and_reopen
                    787: db close
                    788: do_test pager1.4.6.8 {
                    789:   set ::mj_filename1 $::mj_filename
                    790:   tv filter xDelete
                    791:   sqlite3 db test.db2
                    792:   execsql {
                    793:     PRAGMA journal_mode = DELETE;
                    794:     ATTACH 'test.db3' AS three;
                    795:     CREATE TABLE three.t3(a, b);
                    796:     INSERT INTO t3 VALUES(1, 't3.1');
                    797:     BEGIN;
                    798:       UPDATE t2 SET b = 't2.3';
                    799:       UPDATE t3 SET b = 't3.3';
                    800:     COMMIT;
                    801:   }
                    802:   expr {$::mj_filename1 != $::mj_filename}
                    803: } {1}
                    804: faultsim_restore_and_reopen
                    805: tv filter {}
                    806: 
                    807: # The file-system now contains:
                    808: #
                    809: #   * three databases
                    810: #   * three hot-journal files
                    811: #   * two master-journal files.
                    812: #
                    813: # The hot-journals associated with test.db2 and test.db3 point to
                    814: # master journal $::mj_filename. The hot-journal file associated with
                    815: # test.db points to master journal $::mj_filename1. So reading from
                    816: # test.db should delete $::mj_filename1.
                    817: #
                    818: do_test pager1.4.6.9 {
                    819:   lsort [glob test.db*]
                    820: } [lsort [list                                           \
                    821:   test.db test.db2 test.db3                              \
                    822:   test.db-journal test.db2-journal test.db3-journal      \
                    823:   [file tail $::mj_filename] [file tail $::mj_filename1]
                    824: ]]
                    825: 
                    826: # The master-journal $::mj_filename1 contains pointers to test.db and 
                    827: # test.db2. However the hot-journal associated with test.db2 points to
                    828: # a different master-journal. Therefore, reading from test.db only should
                    829: # be enough to cause SQLite to delete $::mj_filename1.
                    830: #
                    831: do_test         pager1.4.6.10 { file exists $::mj_filename  } {1}
                    832: do_test         pager1.4.6.11 { file exists $::mj_filename1 } {1}
                    833: do_execsql_test pager1.4.6.12 { SELECT * FROM t1 } {1 t1.1}
                    834: do_test         pager1.4.6.13 { file exists $::mj_filename  } {1}
                    835: do_test         pager1.4.6.14 { file exists $::mj_filename1 } {0}
                    836: 
                    837: do_execsql_test pager1.4.6.12 {
                    838:   ATTACH 'test.db2' AS two;
                    839:   SELECT * FROM t2;
                    840: } {1 t2.1}
                    841: do_test         pager1.4.6.13 { file exists $::mj_filename }  {1}
                    842: do_execsql_test pager1.4.6.14 {
                    843:   ATTACH 'test.db3' AS three;
                    844:   SELECT * FROM t3;
                    845: } {1 t3.1}
                    846: do_test         pager1.4.6.15 { file exists $::mj_filename }  {0}
                    847: 
                    848: db close
                    849: tv delete
                    850: 
                    851: testvfs tv -default 1
                    852: tv sectorsize 512
                    853: tv script copy_on_journal_delete
                    854: tv filter xDelete
                    855: proc copy_on_journal_delete {method filename args} {
                    856:   if {[string match *journal $filename]} faultsim_save 
                    857:   return SQLITE_OK
                    858: }
                    859: faultsim_delete_and_reopen
                    860: do_execsql_test pager1.4.7.1 {
                    861:   PRAGMA journal_mode = DELETE;
                    862:   CREATE TABLE t1(x PRIMARY KEY, y);
                    863:   CREATE INDEX i1 ON t1(y);
                    864:   INSERT INTO t1 VALUES('I',   'one');
                    865:   INSERT INTO t1 VALUES('II',  'four');
                    866:   INSERT INTO t1 VALUES('III', 'nine');
                    867:   BEGIN;
                    868:     INSERT INTO t1 VALUES('IV', 'sixteen');
                    869:     INSERT INTO t1 VALUES('V' , 'twentyfive');
                    870:   COMMIT;
                    871: } {delete}
                    872: tv filter {}
                    873: db close
                    874: tv delete 
                    875: do_test pager1.4.7.2 {
                    876:   faultsim_restore_and_reopen
                    877:   catch {file attributes test.db-journal -permissions r--------}
                    878:   catch {file attributes test.db-journal -readonly 1}
                    879:   catchsql { SELECT * FROM t1 }
                    880: } {1 {unable to open database file}}
                    881: do_test pager1.4.7.3 {
                    882:   db close
                    883:   catch {file attributes test.db-journal -permissions rw-rw-rw-}
                    884:   catch {file attributes test.db-journal -readonly 0}
                    885:   delete_file test.db-journal
                    886:   file exists test.db-journal
                    887: } {0}
                    888: 
                    889: #-------------------------------------------------------------------------
                    890: # The following tests deal with multi-file commits.
                    891: #
                    892: # pager1-5.1.*: The case where a multi-file cannot be committed because
                    893: #               another connection is holding a SHARED lock on one of the
                    894: #               files. After the SHARED lock is removed, the COMMIT succeeds.
                    895: #
                    896: # pager1-5.2.*: Multi-file commits with journal_mode=memory.
                    897: #
                    898: # pager1-5.3.*: Multi-file commits with journal_mode=memory.
                    899: #
                    900: # pager1-5.4.*: Check that with synchronous=normal, the master-journal file
                    901: #               name is added to a journal file immediately after the last
                    902: #               journal record. But with synchronous=full, extra unused space
                    903: #               is allocated between the last journal record and the 
                    904: #               master-journal file name so that the master-journal file
                    905: #               name does not lie on the same sector as the last journal file
                    906: #               record.
                    907: #
                    908: # pager1-5.5.*: Check that in journal_mode=PERSIST mode, a journal file is
                    909: #               truncated to zero bytes when a multi-file transaction is 
                    910: #               committed (instead of the first couple of bytes being zeroed).
                    911: #
                    912: #
                    913: do_test pager1-5.1.1 {
                    914:   faultsim_delete_and_reopen
                    915:   execsql {
                    916:     ATTACH 'test.db2' AS aux;
                    917:     CREATE TABLE t1(a, b);
                    918:     CREATE TABLE aux.t2(a, b);
                    919:     INSERT INTO t1 VALUES(17, 'Lenin');
                    920:     INSERT INTO t1 VALUES(22, 'Stalin');
                    921:     INSERT INTO t1 VALUES(53, 'Khrushchev');
                    922:   }
                    923: } {}
                    924: do_test pager1-5.1.2 {
                    925:   execsql {
                    926:     BEGIN;
                    927:       INSERT INTO t1 VALUES(64, 'Brezhnev');
                    928:       INSERT INTO t2 SELECT * FROM t1;
                    929:   }
                    930:   sqlite3 db2 test.db2
                    931:   execsql {
                    932:     BEGIN;
                    933:       SELECT * FROM t2;
                    934:   } db2
                    935: } {}
                    936: do_test pager1-5.1.3 {
                    937:   catchsql COMMIT
                    938: } {1 {database is locked}}
                    939: do_test pager1-5.1.4 {
                    940:   execsql COMMIT db2
                    941:   execsql COMMIT
                    942:   execsql { SELECT * FROM t2 } db2
                    943: } {17 Lenin 22 Stalin 53 Khrushchev 64 Brezhnev}
                    944: do_test pager1-5.1.5 {
                    945:   db2 close
                    946: } {}
                    947: 
                    948: do_test pager1-5.2.1 {
                    949:   execsql {
                    950:     PRAGMA journal_mode = memory;
                    951:     BEGIN;
                    952:       INSERT INTO t1 VALUES(84, 'Andropov');
                    953:       INSERT INTO t2 VALUES(84, 'Andropov');
                    954:     COMMIT;
                    955:   }
                    956: } {memory}
                    957: do_test pager1-5.3.1 {
                    958:   execsql {
                    959:     PRAGMA journal_mode = off;
                    960:     BEGIN;
                    961:       INSERT INTO t1 VALUES(85, 'Gorbachev');
                    962:       INSERT INTO t2 VALUES(85, 'Gorbachev');
                    963:     COMMIT;
                    964:   }
                    965: } {off}
                    966: 
                    967: do_test pager1-5.4.1 {
                    968:   db close
                    969:   testvfs tv
                    970:   sqlite3 db test.db -vfs tv
                    971:   execsql { ATTACH 'test.db2' AS aux }
                    972: 
                    973:   tv filter xDelete
                    974:   tv script max_journal_size
                    975:   tv sectorsize 512
                    976:   set ::max_journal 0
                    977:   proc max_journal_size {method args} {
                    978:     set sz 0
                    979:     catch { set sz [file size test.db-journal] }
                    980:     if {$sz > $::max_journal} {
                    981:       set ::max_journal $sz
                    982:     }
                    983:     return SQLITE_OK
                    984:   }
                    985:   execsql {
                    986:     PRAGMA journal_mode = DELETE;
                    987:     PRAGMA synchronous = NORMAL;
                    988:     BEGIN;
                    989:       INSERT INTO t1 VALUES(85, 'Gorbachev');
                    990:       INSERT INTO t2 VALUES(85, 'Gorbachev');
                    991:     COMMIT;
                    992:   }
                    993: 
                    994:   # The size of the journal file is now:
                    995:   # 
                    996:   #   1) 512 byte header +
                    997:   #   2) 2 * (1024+8) byte records +
                    998:   #   3) 20+N bytes of master-journal pointer, where N is the size of 
                    999:   #      the master-journal name encoded as utf-8 with no nul term.
                   1000:   #
                   1001:   set mj_pointer [expr {
                   1002:     20 + [string length [pwd]] + [string length "/test.db-mjXXXXXX9XX"]
                   1003:   }]
                   1004:   expr {$::max_journal==(512+2*(1024+8)+$mj_pointer)}
                   1005: } 1
                   1006: do_test pager1-5.4.2 {
                   1007:   set ::max_journal 0
                   1008:   execsql {
                   1009:     PRAGMA synchronous = full;
                   1010:     BEGIN;
                   1011:       DELETE FROM t1 WHERE b = 'Lenin';
                   1012:       DELETE FROM t2 WHERE b = 'Lenin';
                   1013:     COMMIT;
                   1014:   }
                   1015: 
                   1016:   # In synchronous=full mode, the master-journal pointer is not written
                   1017:   # directly after the last record in the journal file. Instead, it is
                   1018:   # written starting at the next (in this case 512 byte) sector boundary.
                   1019:   #
                   1020:   set mj_pointer [expr {
                   1021:     20 + [string length [pwd]] + [string length "/test.db-mjXXXXXX9XX"]
                   1022:   }]
                   1023:   expr {$::max_journal==(((512+2*(1024+8)+511)/512)*512 + $mj_pointer)}
                   1024: } 1
                   1025: db close
                   1026: tv delete
                   1027: 
                   1028: do_test pager1-5.5.1 {
                   1029:   sqlite3 db test.db
                   1030:   execsql { 
                   1031:     ATTACH 'test.db2' AS aux;
                   1032:     PRAGMA journal_mode = PERSIST;
                   1033:     CREATE TABLE t3(a, b);
                   1034:     INSERT INTO t3 SELECT randomblob(1500), randomblob(1500) FROM t1;
                   1035:     UPDATE t3 SET b = randomblob(1500);
                   1036:   }
                   1037:   expr [file size test.db-journal] > 15000
                   1038: } {1}
                   1039: do_test pager1-5.5.2 {
                   1040:   execsql {
                   1041:     PRAGMA synchronous = full;
                   1042:     BEGIN;
                   1043:       DELETE FROM t1 WHERE b = 'Stalin';
                   1044:       DELETE FROM t2 WHERE b = 'Stalin';
                   1045:     COMMIT;
                   1046:   }
                   1047:   file size test.db-journal
                   1048: } {0}
                   1049: 
                   1050: 
                   1051: #-------------------------------------------------------------------------
                   1052: # The following tests work with "PRAGMA max_page_count"
                   1053: #
                   1054: do_test pager1-6.1 {
                   1055:   faultsim_delete_and_reopen
                   1056:   execsql {
                   1057:     PRAGMA auto_vacuum = none;
                   1058:     PRAGMA max_page_count = 10;
                   1059:     CREATE TABLE t2(a, b);
                   1060:     CREATE TABLE t3(a, b);
                   1061:     CREATE TABLE t4(a, b);
                   1062:     CREATE TABLE t5(a, b);
                   1063:     CREATE TABLE t6(a, b);
                   1064:     CREATE TABLE t7(a, b);
                   1065:     CREATE TABLE t8(a, b);
                   1066:     CREATE TABLE t9(a, b);
                   1067:     CREATE TABLE t10(a, b);
                   1068:   }
                   1069: } {10}
                   1070: do_catchsql_test pager1-6.2 {
                   1071:   CREATE TABLE t11(a, b)
                   1072: } {1 {database or disk is full}}
                   1073: do_execsql_test pager1-6.4 { PRAGMA max_page_count      } {10}
                   1074: do_execsql_test pager1-6.5 { PRAGMA max_page_count = 15 } {15}
                   1075: do_execsql_test pager1-6.6 { CREATE TABLE t11(a, b)     } {}
                   1076: do_execsql_test pager1-6.7 {
                   1077:   BEGIN;
                   1078:     INSERT INTO t11 VALUES(1, 2);
                   1079:     PRAGMA max_page_count = 13;
                   1080: } {13}
                   1081: do_execsql_test pager1-6.8 {
                   1082:     INSERT INTO t11 VALUES(3, 4);
                   1083:     PRAGMA max_page_count = 10;
                   1084: } {11}
                   1085: do_execsql_test pager1-6.9 { COMMIT } {}
                   1086: 
                   1087: do_execsql_test pager1-6.10 { PRAGMA max_page_count = 10 } {11}
                   1088: do_execsql_test pager1-6.11 { SELECT * FROM t11 }          {1 2 3 4}
                   1089: do_execsql_test pager1-6.12 { PRAGMA max_page_count }      {11}
                   1090: 
                   1091: 
                   1092: #-------------------------------------------------------------------------
                   1093: # The following tests work with "PRAGMA journal_mode=TRUNCATE" and
                   1094: # "PRAGMA locking_mode=EXCLUSIVE".
                   1095: #
                   1096: # Each test is specified with 5 variables. As follows:
                   1097: #
                   1098: #   $tn:  Test Number. Used as part of the [do_test] test names.
                   1099: #   $sql: SQL to execute.
                   1100: #   $res: Expected result of executing $sql.
                   1101: #   $js:  The expected size of the journal file, in bytes, after executing
                   1102: #         the SQL script. Or -1 if the journal is not expected to exist.
                   1103: #   $ws:  The expected size of the WAL file, in bytes, after executing
                   1104: #         the SQL script. Or -1 if the WAL is not expected to exist.
                   1105: #
                   1106: ifcapable wal {
                   1107:   faultsim_delete_and_reopen
                   1108:   foreach {tn sql res js ws} [subst {
                   1109:   
                   1110:     1  {
                   1111:       CREATE TABLE t1(a, b);
                   1112:       PRAGMA auto_vacuum=OFF;
                   1113:       PRAGMA synchronous=NORMAL;
                   1114:       PRAGMA page_size=1024;
                   1115:       PRAGMA locking_mode=EXCLUSIVE;
                   1116:       PRAGMA journal_mode=TRUNCATE;
                   1117:       INSERT INTO t1 VALUES(1, 2);
                   1118:     } {exclusive truncate} 0 -1
                   1119:   
                   1120:     2  {
                   1121:       BEGIN IMMEDIATE;
                   1122:         SELECT * FROM t1;
                   1123:       COMMIT;
                   1124:     } {1 2} 0 -1
                   1125:   
                   1126:     3  {
                   1127:       BEGIN;
                   1128:         SELECT * FROM t1;
                   1129:       COMMIT;
                   1130:     } {1 2} 0 -1
                   1131:   
                   1132:     4  { PRAGMA journal_mode = WAL }    wal       -1 -1
                   1133:     5  { INSERT INTO t1 VALUES(3, 4) }  {}        -1 [wal_file_size 1 1024]
                   1134:     6  { PRAGMA locking_mode = NORMAL } exclusive -1 [wal_file_size 1 1024]
                   1135:     7  { INSERT INTO t1 VALUES(5, 6); } {}        -1 [wal_file_size 2 1024]
                   1136:   
                   1137:     8  { PRAGMA journal_mode = TRUNCATE } truncate          0 -1
                   1138:     9  { INSERT INTO t1 VALUES(7, 8) }    {}                0 -1
                   1139:     10 { SELECT * FROM t1 }               {1 2 3 4 5 6 7 8} 0 -1
                   1140:   
                   1141:   }] {
                   1142:     do_execsql_test pager1-7.1.$tn.1 $sql $res
                   1143:     catch { set J -1 ; set J [file size test.db-journal] }
                   1144:     catch { set W -1 ; set W [file size test.db-wal] }
                   1145:     do_test pager1-7.1.$tn.2 { list $J $W } [list $js $ws]
                   1146:   }
                   1147: }
                   1148: 
                   1149: do_test pager1-7.2.1 {
                   1150:   faultsim_delete_and_reopen
                   1151:   execsql {
                   1152:     PRAGMA locking_mode = EXCLUSIVE;
                   1153:     CREATE TABLE t1(a, b);
                   1154:     BEGIN;
                   1155:       PRAGMA journal_mode = delete;
                   1156:       PRAGMA journal_mode = truncate;
                   1157:   }
                   1158: } {exclusive delete truncate}
                   1159: do_test pager1-7.2.2 {
                   1160:   execsql { INSERT INTO t1 VALUES(1, 2) }
                   1161:   execsql { PRAGMA journal_mode = persist }
                   1162: } {truncate}
                   1163: do_test pager1-7.2.3 {
                   1164:   execsql { COMMIT }
                   1165:   execsql {
                   1166:     PRAGMA journal_mode = persist;
                   1167:     PRAGMA journal_size_limit;
                   1168:   }
                   1169: } {persist -1}
                   1170: 
                   1171: #-------------------------------------------------------------------------
                   1172: # The following tests, pager1-8.*, test that the special filenames 
                   1173: # ":memory:" and "" open temporary databases.
                   1174: #
                   1175: foreach {tn filename} {
                   1176:   1 :memory:
                   1177:   2 ""
                   1178: } {
                   1179:   do_test pager1-8.$tn.1 {
                   1180:     faultsim_delete_and_reopen
                   1181:     db close
                   1182:     sqlite3 db $filename
                   1183:     execsql {
                   1184:       PRAGMA auto_vacuum = 1;
                   1185:       CREATE TABLE x1(x);
                   1186:       INSERT INTO x1 VALUES('Charles');
                   1187:       INSERT INTO x1 VALUES('James');
                   1188:       INSERT INTO x1 VALUES('Mary');
                   1189:       SELECT * FROM x1;
                   1190:     }
                   1191:   } {Charles James Mary}
                   1192: 
                   1193:   do_test pager1-8.$tn.2 {
                   1194:     sqlite3 db2 $filename
                   1195:     catchsql { SELECT * FROM x1 } db2
                   1196:   } {1 {no such table: x1}}
                   1197: 
                   1198:   do_execsql_test pager1-8.$tn.3 {
                   1199:     BEGIN;
                   1200:       INSERT INTO x1 VALUES('William');
                   1201:       INSERT INTO x1 VALUES('Anne');
                   1202:     ROLLBACK;
                   1203:   } {}
                   1204: }
                   1205: 
                   1206: #-------------------------------------------------------------------------
                   1207: # The next block of tests - pager1-9.* - deal with interactions between
                   1208: # the pager and the backup API. Test cases:
                   1209: #
                   1210: #   pager1-9.1.*: Test that a backup completes successfully even if the
                   1211: #                 source db is written to during the backup op.
                   1212: #
                   1213: #   pager1-9.2.*: Test that a backup completes successfully even if the
                   1214: #                 source db is written to and then rolled back during a 
                   1215: #                 backup operation.
                   1216: #
                   1217: do_test pager1-9.0.1 {
                   1218:   faultsim_delete_and_reopen
                   1219:   db func a_string a_string
                   1220:   execsql {
                   1221:     PRAGMA cache_size = 10;
                   1222:     BEGIN;
                   1223:       CREATE TABLE ab(a, b, UNIQUE(a, b));
                   1224:       INSERT INTO ab VALUES( a_string(200), a_string(300) );
                   1225:       INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
                   1226:       INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
                   1227:       INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
                   1228:       INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
                   1229:       INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
                   1230:       INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
                   1231:       INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
                   1232:     COMMIT;
                   1233:   }
                   1234: } {}
                   1235: do_test pager1-9.0.2 {
                   1236:   sqlite3 db2 test.db2
                   1237:   db2 eval { PRAGMA cache_size = 10 }
                   1238:   sqlite3_backup B db2 main db main
                   1239:   list [B step 10000] [B finish]
                   1240: } {SQLITE_DONE SQLITE_OK}
                   1241: do_test pager1-9.0.3 {
                   1242:  db one {SELECT md5sum(a, b) FROM ab}
                   1243: } [db2 one {SELECT md5sum(a, b) FROM ab}]
                   1244: 
                   1245: do_test pager1-9.1.1 {
                   1246:   execsql { UPDATE ab SET a = a_string(201) }
                   1247:   sqlite3_backup B db2 main db main
                   1248:   B step 30
                   1249: } {SQLITE_OK}
                   1250: do_test pager1-9.1.2 {
                   1251:   execsql { UPDATE ab SET b = a_string(301) }
                   1252:   list [B step 10000] [B finish]
                   1253: } {SQLITE_DONE SQLITE_OK}
                   1254: do_test pager1-9.1.3 {
                   1255:  db one {SELECT md5sum(a, b) FROM ab}
                   1256: } [db2 one {SELECT md5sum(a, b) FROM ab}]
                   1257: do_test pager1-9.1.4 { execsql { SELECT count(*) FROM ab } } {128}
                   1258: 
                   1259: do_test pager1-9.2.1 {
                   1260:   execsql { UPDATE ab SET a = a_string(202) }
                   1261:   sqlite3_backup B db2 main db main
                   1262:   B step 30
                   1263: } {SQLITE_OK}
                   1264: do_test pager1-9.2.2 {
                   1265:   execsql { 
                   1266:     BEGIN;
                   1267:       UPDATE ab SET b = a_string(301);
                   1268:     ROLLBACK;
                   1269:   }
                   1270:   list [B step 10000] [B finish]
                   1271: } {SQLITE_DONE SQLITE_OK}
                   1272: do_test pager1-9.2.3 {
                   1273:  db one {SELECT md5sum(a, b) FROM ab}
                   1274: } [db2 one {SELECT md5sum(a, b) FROM ab}]
                   1275: do_test pager1-9.2.4 { execsql { SELECT count(*) FROM ab } } {128}
                   1276: db close
                   1277: db2 close
                   1278: 
                   1279: do_test pager1-9.3.1 {
                   1280:   testvfs tv -default 1
                   1281:   tv sectorsize 4096
                   1282:   faultsim_delete_and_reopen
                   1283: 
                   1284:   execsql { PRAGMA page_size = 1024 }
                   1285:   for {set ii 0} {$ii < 4} {incr ii} { execsql "CREATE TABLE t${ii}(a, b)" }
                   1286: } {}
                   1287: do_test pager1-9.3.2 {
                   1288:   sqlite3 db2 test.db2
                   1289: 
                   1290:   execsql {
                   1291:     PRAGMA page_size = 4096;
                   1292:     PRAGMA synchronous = OFF;
                   1293:     CREATE TABLE t1(a, b);
                   1294:     CREATE TABLE t2(a, b);
                   1295:   } db2
                   1296: 
                   1297:   sqlite3_backup B db2 main db main
                   1298:   B step 30
                   1299:   list [B step 10000] [B finish]
                   1300: } {SQLITE_DONE SQLITE_OK}
                   1301: do_test pager1-9.3.3 {
                   1302:   db2 close
                   1303:   db close
                   1304:   tv delete
                   1305:   file size test.db2
                   1306: } [file size test.db]
                   1307: 
                   1308: do_test pager1-9.4.1 {
                   1309:   faultsim_delete_and_reopen
                   1310:   sqlite3 db2 test.db2
                   1311:   execsql {
                   1312:     PRAGMA page_size = 4096;
                   1313:     CREATE TABLE t1(a, b);
                   1314:     CREATE TABLE t2(a, b);
                   1315:   } db2
                   1316:   sqlite3_backup B db2 main db main
                   1317:   list [B step 10000] [B finish]
                   1318: } {SQLITE_DONE SQLITE_OK}
                   1319: do_test pager1-9.4.2 {
                   1320:   list [file size test.db2] [file size test.db]
                   1321: } {0 0}
                   1322: db2 close
                   1323: 
                   1324: #-------------------------------------------------------------------------
                   1325: # Test that regardless of the value returned by xSectorSize(), the
                   1326: # minimum effective sector-size is 512 and the maximum 65536 bytes.
                   1327: #
                   1328: testvfs tv -default 1
                   1329: foreach sectorsize {
                   1330:     32   64   128   256   512   1024   2048 
                   1331:     4096 8192 16384 32768 65536 131072 262144
                   1332: } {
                   1333:   tv sectorsize $sectorsize
                   1334:   tv devchar {}
                   1335:   set eff $sectorsize
                   1336:   if {$sectorsize < 512}   { set eff 512 }
                   1337:   if {$sectorsize > 65536} { set eff 65536 }
                   1338: 
                   1339:   do_test pager1-10.$sectorsize.1 {
                   1340:     faultsim_delete_and_reopen
                   1341:     db func a_string a_string
                   1342:     execsql {
                   1343:       PRAGMA journal_mode = PERSIST;
                   1344:       PRAGMA page_size = 1024;
                   1345:       BEGIN;
                   1346:         CREATE TABLE t1(a, b);
                   1347:         CREATE TABLE t2(a, b);
                   1348:         CREATE TABLE t3(a, b);
                   1349:       COMMIT;
                   1350:     }
                   1351:     file size test.db-journal
                   1352:   } [expr $sectorsize > 65536 ? 65536 : $sectorsize]
                   1353: 
                   1354:   do_test pager1-10.$sectorsize.2 {
                   1355:     execsql { 
                   1356:       INSERT INTO t3 VALUES(a_string(300), a_string(300));
                   1357:       INSERT INTO t3 SELECT * FROM t3;        /*  2 */
                   1358:       INSERT INTO t3 SELECT * FROM t3;        /*  4 */
                   1359:       INSERT INTO t3 SELECT * FROM t3;        /*  8 */
                   1360:       INSERT INTO t3 SELECT * FROM t3;        /* 16 */
                   1361:       INSERT INTO t3 SELECT * FROM t3;        /* 32 */
                   1362:     }
                   1363:   } {}
                   1364: 
                   1365:   do_test pager1-10.$sectorsize.3 {
                   1366:     db close
                   1367:     sqlite3 db test.db
                   1368:     execsql { 
                   1369:       PRAGMA cache_size = 10;
                   1370:       BEGIN;
                   1371:     }
                   1372:     recursive_select 32 t3 {db eval "INSERT INTO t2 VALUES(1, 2)"}
                   1373:     execsql {
                   1374:       COMMIT;
                   1375:       SELECT * FROM t2;
                   1376:     }
                   1377:   } {1 2}
                   1378: 
                   1379:   do_test pager1-10.$sectorsize.4 {
                   1380:     execsql {
                   1381:       CREATE TABLE t6(a, b);
                   1382:       CREATE TABLE t7(a, b);
                   1383:       CREATE TABLE t5(a, b);
                   1384:       DROP TABLE t6;
                   1385:       DROP TABLE t7;
                   1386:     }
                   1387:     execsql {
                   1388:       BEGIN;
                   1389:         CREATE TABLE t6(a, b);
                   1390:     }
                   1391:     recursive_select 32 t3 {db eval "INSERT INTO t5 VALUES(1, 2)"}
                   1392:     execsql {
                   1393:       COMMIT;
                   1394:       SELECT * FROM t5;
                   1395:     }
                   1396:   } {1 2}
                   1397:   
                   1398: }
                   1399: db close
                   1400: 
                   1401: tv sectorsize 4096
                   1402: do_test pager1.10.x.1 {
                   1403:   faultsim_delete_and_reopen
                   1404:   execsql {
                   1405:     PRAGMA auto_vacuum = none;
                   1406:     PRAGMA page_size = 1024;
                   1407:     CREATE TABLE t1(x);
                   1408:   }
                   1409:   for {set i 0} {$i<30} {incr i} {
                   1410:     execsql { INSERT INTO t1 VALUES(zeroblob(900)) }
                   1411:   }
                   1412:   file size test.db
                   1413: } {32768}
                   1414: do_test pager1.10.x.2 {
                   1415:   execsql {
                   1416:     CREATE TABLE t2(x);
                   1417:     DROP TABLE t2;
                   1418:   }
                   1419:   file size test.db
                   1420: } {33792}
                   1421: do_test pager1.10.x.3 {
                   1422:   execsql {
                   1423:     BEGIN;
                   1424:     CREATE TABLE t2(x);
                   1425:   }
                   1426:   recursive_select 30 t1
                   1427:   execsql {
                   1428:     CREATE TABLE t3(x);
                   1429:     COMMIT;
                   1430:   }
                   1431: } {}
                   1432: 
                   1433: db close
                   1434: tv delete
                   1435: 
                   1436: testvfs tv -default 1
                   1437: faultsim_delete_and_reopen
                   1438: db func a_string a_string
                   1439: do_execsql_test pager1-11.1 {
                   1440:   PRAGMA journal_mode = DELETE;
                   1441:   PRAGMA cache_size = 10;
                   1442:   BEGIN;
                   1443:     CREATE TABLE zz(top PRIMARY KEY);
                   1444:     INSERT INTO zz VALUES(a_string(222));
                   1445:     INSERT INTO zz SELECT a_string((SELECT 222+max(rowid) FROM zz)) FROM zz;
                   1446:     INSERT INTO zz SELECT a_string((SELECT 222+max(rowid) FROM zz)) FROM zz;
                   1447:     INSERT INTO zz SELECT a_string((SELECT 222+max(rowid) FROM zz)) FROM zz;
                   1448:     INSERT INTO zz SELECT a_string((SELECT 222+max(rowid) FROM zz)) FROM zz;
                   1449:     INSERT INTO zz SELECT a_string((SELECT 222+max(rowid) FROM zz)) FROM zz;
                   1450:   COMMIT;
                   1451:   BEGIN;
                   1452:     UPDATE zz SET top = a_string(345);
                   1453: } {delete}
                   1454: 
                   1455: proc lockout {method args} { return SQLITE_IOERR }
                   1456: tv script lockout
                   1457: tv filter {xWrite xTruncate xSync}
                   1458: do_catchsql_test pager1-11.2 { COMMIT } {1 {disk I/O error}}
                   1459: 
                   1460: tv script {}
                   1461: do_test pager1-11.3 {
                   1462:   sqlite3 db2 test.db
                   1463:   execsql {
                   1464:     PRAGMA journal_mode = TRUNCATE;
                   1465:     PRAGMA integrity_check;
                   1466:   } db2
                   1467: } {truncate ok}
                   1468: do_test pager1-11.4 {
                   1469:   db2 close
                   1470:   file exists test.db-journal
                   1471: } {0}
                   1472: do_execsql_test pager1-11.5 { SELECT count(*) FROM zz } {32}
                   1473: db close
                   1474: tv delete
                   1475:   
                   1476: #-------------------------------------------------------------------------
                   1477: # Test "PRAGMA page_size"
                   1478: #
                   1479: testvfs tv -default 1
                   1480: tv sectorsize 1024
                   1481: foreach pagesize {
                   1482:     512   1024   2048 4096 8192 16384 32768 
                   1483: } {
                   1484:   faultsim_delete_and_reopen
                   1485: 
                   1486:   # The sector-size (according to the VFS) is 1024 bytes. So if the
                   1487:   # page-size requested using "PRAGMA page_size" is greater than the
                   1488:   # compile time value of SQLITE_MAX_PAGE_SIZE, then the effective 
                   1489:   # page-size remains 1024 bytes.
                   1490:   #
                   1491:   set eff $pagesize
                   1492:   if {$eff > $::SQLITE_MAX_PAGE_SIZE} { set eff 1024 }
                   1493: 
                   1494:   do_test pager1-12.$pagesize.1 {
                   1495:     sqlite3 db2 test.db
                   1496:     execsql "
                   1497:       PRAGMA page_size = $pagesize;
                   1498:       CREATE VIEW v AS SELECT * FROM sqlite_master;
                   1499:     " db2
                   1500:     file size test.db
                   1501:   } $eff
                   1502:   do_test pager1-12.$pagesize.2 {
                   1503:     sqlite3 db2 test.db
                   1504:     execsql { 
                   1505:       SELECT count(*) FROM v;
                   1506:       PRAGMA main.page_size;
                   1507:     } db2
                   1508:   } [list 1 $eff]
                   1509:   do_test pager1-12.$pagesize.3 {
                   1510:     execsql { 
                   1511:       SELECT count(*) FROM v;
                   1512:       PRAGMA main.page_size;
                   1513:     }
                   1514:   } [list 1 $eff]
                   1515:   db2 close
                   1516: }
                   1517: db close
                   1518: tv delete
                   1519: 
                   1520: #-------------------------------------------------------------------------
                   1521: # Test specal "PRAGMA journal_mode=PERSIST" test cases.
                   1522: #
                   1523: # pager1-13.1.*: This tests a special case encountered in persistent 
                   1524: #                journal mode: If the journal associated with a transaction
                   1525: #                is smaller than the journal file (because a previous 
                   1526: #                transaction left a very large non-hot journal file in the
                   1527: #                file-system), then SQLite has to be careful that there is
                   1528: #                not a journal-header left over from a previous transaction
                   1529: #                immediately following the journal content just written.
                   1530: #                If there is, and the process crashes so that the journal
                   1531: #                becomes a hot-journal and must be rolled back by another
                   1532: #                process, there is a danger that the other process may roll
                   1533: #                back the aborted transaction, then continue copying data
                   1534: #                from an older transaction from the remainder of the journal.
                   1535: #                See the syncJournal() function for details.
                   1536: #
                   1537: # pager1-13.2.*: Same test as the previous. This time, throw an index into
                   1538: #                the mix to make the integrity-check more likely to catch
                   1539: #                errors.
                   1540: #
                   1541: testvfs tv -default 1
                   1542: tv script xSyncCb
                   1543: tv filter xSync
                   1544: proc xSyncCb {method filename args} {
                   1545:   set t [file tail $filename]
                   1546:   if {$t == "test.db"} faultsim_save
                   1547:   return SQLITE_OK
                   1548: }
                   1549: faultsim_delete_and_reopen
                   1550: db func a_string a_string
                   1551: 
                   1552: # The UPDATE statement at the end of this test case creates a really big
                   1553: # journal. Since the cache-size is only 10 pages, the journal contains 
                   1554: # frequent journal headers.
                   1555: #
                   1556: do_execsql_test pager1-13.1.1 {
                   1557:   PRAGMA page_size = 1024;
                   1558:   PRAGMA journal_mode = PERSIST;
                   1559:   PRAGMA cache_size = 10;
                   1560:   BEGIN;
                   1561:     CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB);
                   1562:     INSERT INTO t1 VALUES(NULL, a_string(400));
                   1563:     INSERT INTO t1 SELECT NULL, a_string(400) FROM t1;          /*   2 */
                   1564:     INSERT INTO t1 SELECT NULL, a_string(400) FROM t1;          /*   4 */
                   1565:     INSERT INTO t1 SELECT NULL, a_string(400) FROM t1;          /*   8 */
                   1566:     INSERT INTO t1 SELECT NULL, a_string(400) FROM t1;          /*  16 */
                   1567:     INSERT INTO t1 SELECT NULL, a_string(400) FROM t1;          /*  32 */
                   1568:     INSERT INTO t1 SELECT NULL, a_string(400) FROM t1;          /*  64 */
                   1569:     INSERT INTO t1 SELECT NULL, a_string(400) FROM t1;          /* 128 */
                   1570:   COMMIT;
                   1571:   UPDATE t1 SET b = a_string(400);
                   1572: } {persist}
                   1573: 
                   1574: if {$::tcl_platform(platform)!="windows"} {
                   1575: # Run transactions of increasing sizes. Eventually, one (or more than one)
                   1576: # of these will write just enough content that one of the old headers created 
                   1577: # by the transaction in the block above lies immediately after the content
                   1578: # journalled by the current transaction.
                   1579: #
                   1580: for {set nUp 1} {$nUp<64} {incr nUp} {
                   1581:   do_execsql_test pager1-13.1.2.$nUp.1 { 
                   1582:     UPDATE t1 SET b = a_string(399) WHERE a <= $nUp
                   1583:   } {}
                   1584:   do_execsql_test pager1-13.1.2.$nUp.2 { PRAGMA integrity_check } {ok} 
                   1585: 
                   1586:   # Try to access the snapshot of the file-system.
                   1587:   #
                   1588:   sqlite3 db2 sv_test.db
                   1589:   do_test pager1-13.1.2.$nUp.3 {
                   1590:     execsql { SELECT sum(length(b)) FROM t1 } db2
                   1591:   } [expr {128*400 - ($nUp-1)}]
                   1592:   do_test pager1-13.1.2.$nUp.4 {
                   1593:     execsql { PRAGMA integrity_check } db2
                   1594:   } {ok}
                   1595:   db2 close
                   1596: }
                   1597: }
                   1598: 
                   1599: if {$::tcl_platform(platform)!="windows"} {
                   1600: # Same test as above. But this time with an index on the table.
                   1601: #
                   1602: do_execsql_test pager1-13.2.1 {
                   1603:   CREATE INDEX i1 ON t1(b);
                   1604:   UPDATE t1 SET b = a_string(400);
                   1605: } {}
                   1606: for {set nUp 1} {$nUp<64} {incr nUp} {
                   1607:   do_execsql_test pager1-13.2.2.$nUp.1 { 
                   1608:     UPDATE t1 SET b = a_string(399) WHERE a <= $nUp
                   1609:   } {}
                   1610:   do_execsql_test pager1-13.2.2.$nUp.2 { PRAGMA integrity_check } {ok} 
                   1611:   sqlite3 db2 sv_test.db
                   1612:   do_test pager1-13.2.2.$nUp.3 {
                   1613:     execsql { SELECT sum(length(b)) FROM t1 } db2
                   1614:   } [expr {128*400 - ($nUp-1)}]
                   1615:   do_test pager1-13.2.2.$nUp.4 {
                   1616:     execsql { PRAGMA integrity_check } db2
                   1617:   } {ok}
                   1618:   db2 close
                   1619: }
                   1620: }
                   1621: 
                   1622: db close
                   1623: tv delete
                   1624: 
                   1625: #-------------------------------------------------------------------------
                   1626: # Test specal "PRAGMA journal_mode=OFF" test cases.
                   1627: #
                   1628: faultsim_delete_and_reopen
                   1629: do_execsql_test pager1-14.1.1 {
                   1630:   PRAGMA journal_mode = OFF;
                   1631:   CREATE TABLE t1(a, b);
                   1632:   BEGIN;
                   1633:     INSERT INTO t1 VALUES(1, 2);
                   1634:   COMMIT;
                   1635:   SELECT * FROM t1;
                   1636: } {off 1 2}
                   1637: do_catchsql_test pager1-14.1.2 {
                   1638:   BEGIN;
                   1639:     INSERT INTO t1 VALUES(3, 4);
                   1640:   ROLLBACK;
                   1641: } {0 {}}
                   1642: do_execsql_test pager1-14.1.3 {
                   1643:   SELECT * FROM t1;
                   1644: } {1 2}
                   1645: do_catchsql_test pager1-14.1.4 {
                   1646:   BEGIN;
                   1647:     INSERT INTO t1(rowid, a, b) SELECT a+3, b, b FROM t1;
                   1648:     INSERT INTO t1(rowid, a, b) SELECT a+3, b, b FROM t1;
                   1649: } {1 {PRIMARY KEY must be unique}}
                   1650: do_execsql_test pager1-14.1.5 {
                   1651:   COMMIT;
                   1652:   SELECT * FROM t1;
                   1653: } {1 2 2 2}
                   1654: 
                   1655: #-------------------------------------------------------------------------
                   1656: # Test opening and closing the pager sub-system with different values
                   1657: # for the sqlite3_vfs.szOsFile variable.
                   1658: #
                   1659: faultsim_delete_and_reopen
                   1660: do_execsql_test pager1-15.0 {
                   1661:   CREATE TABLE tx(y, z);
                   1662:   INSERT INTO tx VALUES('Ayutthaya', 'Beijing');
                   1663:   INSERT INTO tx VALUES('London', 'Tokyo');
                   1664: } {}
                   1665: db close
                   1666: for {set i 0} {$i<513} {incr i 3} {
                   1667:   testvfs tv -default 1 -szosfile $i
                   1668:   sqlite3 db test.db
                   1669:   do_execsql_test pager1-15.$i.1 {
                   1670:     SELECT * FROM tx;
                   1671:   } {Ayutthaya Beijing London Tokyo}
                   1672:   db close
                   1673:   tv delete
                   1674: }
                   1675: 
                   1676: #-------------------------------------------------------------------------
                   1677: # Check that it is not possible to open a database file if the full path
                   1678: # to the associated journal file will be longer than sqlite3_vfs.mxPathname.
                   1679: #
                   1680: testvfs tv -default 1
                   1681: tv script xOpenCb
                   1682: tv filter xOpen
                   1683: proc xOpenCb {method filename args} {
                   1684:   set ::file_len [string length $filename]
                   1685: }
                   1686: sqlite3 db test.db
                   1687: db close
                   1688: tv delete
                   1689: 
                   1690: for {set ii [expr $::file_len-5]} {$ii < [expr $::file_len+20]} {incr ii} {
                   1691:   testvfs tv -default 1 -mxpathname $ii
                   1692: 
                   1693:   # The length of the full path to file "test.db-journal" is ($::file_len+8).
                   1694:   # If the configured sqlite3_vfs.mxPathname value greater than or equal to
                   1695:   # this, then the file can be opened. Otherwise, it cannot.
                   1696:   #
                   1697:   if {$ii >= [expr $::file_len+8]} {
                   1698:     set res {0 {}}
                   1699:   } else {
                   1700:     set res {1 {unable to open database file}}
                   1701:   }
                   1702: 
                   1703:   do_test pager1-16.1.$ii {
                   1704:     list [catch { sqlite3 db test.db } msg] $msg
                   1705:   } $res
                   1706: 
                   1707:   catch {db close}
                   1708:   tv delete
                   1709: }
                   1710: 
                   1711: #-------------------------------------------------------------------------
                   1712: # Test "PRAGMA omit_readlock". 
                   1713: #
                   1714: #   pager1-17.$tn.1.*: Test that if a second connection has an open 
                   1715: #                      read-transaction, it is not usually possible to write 
                   1716: #                      the database.
                   1717: #
                   1718: #   pager1-17.$tn.2.*: Test that if the second connection was opened with
                   1719: #                      the SQLITE_OPEN_READONLY flag, and 
                   1720: #                      "PRAGMA omit_readlock = 1" is executed before attaching
                   1721: #                      the database and opening a read-transaction on it, it is
                   1722: #                      possible to write the db.
                   1723: #
                   1724: #   pager1-17.$tn.3.*: Test that if the second connection was *not* opened with
                   1725: #                      the SQLITE_OPEN_READONLY flag, executing 
                   1726: #                      "PRAGMA omit_readlock = 1" has no effect.
                   1727: #
                   1728: do_multiclient_test tn {
                   1729:   do_test pager1-17.$tn.1.1 {
                   1730:     sql1 { 
                   1731:       CREATE TABLE t1(a, b);
                   1732:       INSERT INTO t1 VALUES(1, 2);
                   1733:     }
                   1734:     sql2 {
                   1735:       BEGIN;
                   1736:       SELECT * FROM t1;
                   1737:     }
                   1738:   } {1 2}
                   1739:   do_test pager1-17.$tn.1.2 {
                   1740:     csql1 { INSERT INTO t1 VALUES(3, 4) }
                   1741:   } {1 {database is locked}}
                   1742:   do_test pager1-17.$tn.1.3 {
                   1743:     sql2 { COMMIT }
                   1744:     sql1 { INSERT INTO t1 VALUES(3, 4) }
                   1745:   } {}
                   1746: 
                   1747:   do_test pager1-17.$tn.2.1 {
                   1748:     code2 {
                   1749:       db2 close
                   1750:       sqlite3 db2 :memory: -readonly 1
                   1751:     }
                   1752:     sql2 { 
                   1753:       PRAGMA omit_readlock = 1;
                   1754:       ATTACH 'test.db' AS two;
                   1755:       BEGIN;
                   1756:       SELECT * FROM t1;
                   1757:     }
                   1758:   } {1 2 3 4}
                   1759:   do_test pager1-17.$tn.2.2 { sql1 "INSERT INTO t1 VALUES(5, 6)" } {}
                   1760:   do_test pager1-17.$tn.2.3 { sql2 "SELECT * FROM t1" }            {1 2 3 4}
                   1761:   do_test pager1-17.$tn.2.4 { sql2 "COMMIT ; SELECT * FROM t1" }   {1 2 3 4 5 6}
                   1762: 
                   1763:   do_test pager1-17.$tn.3.1 {
                   1764:     code2 {
                   1765:       db2 close
                   1766:       sqlite3 db2 :memory:
                   1767:     }
                   1768:     sql2 { 
                   1769:       PRAGMA omit_readlock = 1;
                   1770:       ATTACH 'test.db' AS two;
                   1771:       BEGIN;
                   1772:       SELECT * FROM t1;
                   1773:     }
                   1774:   } {1 2 3 4 5 6}
                   1775:   do_test pager1-17.$tn.3.2 {
                   1776:   csql1 { INSERT INTO t1 VALUES(3, 4) }
                   1777:   } {1 {database is locked}}
                   1778:   do_test pager1-17.$tn.3.3 { sql2 COMMIT } {}
                   1779: }
                   1780: 
                   1781: #-------------------------------------------------------------------------
                   1782: # Test the pagers response to the b-tree layer requesting illegal page 
                   1783: # numbers:
                   1784: #
                   1785: #   + The locking page,
                   1786: #   + Page 0,
                   1787: #   + A page with a page number greater than (2^31-1).
                   1788: #
                   1789: # These tests will not work if SQLITE_DIRECT_OVERFLOW_READ is defined. In
                   1790: # that case IO errors are sometimes reported instead of SQLITE_CORRUPT.
                   1791: #
                   1792: ifcapable !direct_read {
                   1793: do_test pager1-18.1 {
                   1794:   faultsim_delete_and_reopen
                   1795:   db func a_string a_string
                   1796:   execsql { 
                   1797:     PRAGMA page_size = 1024;
                   1798:     CREATE TABLE t1(a, b);
                   1799:     INSERT INTO t1 VALUES(a_string(500), a_string(200));
                   1800:     INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
                   1801:     INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
                   1802:     INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
                   1803:     INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
                   1804:     INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
                   1805:     INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
                   1806:     INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
                   1807:   }
                   1808: } {}
                   1809: do_test pager1-18.2 {
                   1810:   set root [db one "SELECT rootpage FROM sqlite_master"]
                   1811:   set lockingpage [expr (0x10000/1024) + 1]
                   1812:   execsql {
                   1813:     PRAGMA writable_schema = 1;
                   1814:     UPDATE sqlite_master SET rootpage = $lockingpage;
                   1815:   }
                   1816:   sqlite3 db2 test.db
                   1817:   catchsql { SELECT count(*) FROM t1 } db2
                   1818: } {1 {database disk image is malformed}}
                   1819: db2 close
                   1820: do_test pager1-18.3 {
                   1821:   execsql {
                   1822:     CREATE TABLE t2(x);
                   1823:     INSERT INTO t2 VALUES(a_string(5000));
                   1824:   }
                   1825:   set pgno [expr ([file size test.db] / 1024)-2]
                   1826:   hexio_write test.db [expr ($pgno-1)*1024] 00000000
                   1827:   sqlite3 db2 test.db
                   1828:   catchsql { SELECT length(x) FROM t2 } db2
                   1829: } {1 {database disk image is malformed}}
                   1830: db2 close
                   1831: do_test pager1-18.4 {
                   1832:   hexio_write test.db [expr ($pgno-1)*1024] 90000000
                   1833:   sqlite3 db2 test.db
                   1834:   catchsql { SELECT length(x) FROM t2 } db2
                   1835: } {1 {database disk image is malformed}}
                   1836: db2 close
                   1837: do_test pager1-18.5 {
                   1838:   sqlite3 db ""
                   1839:   execsql {
                   1840:     CREATE TABLE t1(a, b);
                   1841:     CREATE TABLE t2(a, b);
                   1842:     PRAGMA writable_schema = 1;
                   1843:     UPDATE sqlite_master SET rootpage=5 WHERE tbl_name = 't1';
                   1844:     PRAGMA writable_schema = 0;
                   1845:     ALTER TABLE t1 RENAME TO x1;
                   1846:   }
                   1847:   catchsql { SELECT * FROM x1 }
                   1848: } {1 {database disk image is malformed}}
                   1849: db close
                   1850: 
                   1851: do_test pager1-18.6 {
                   1852:   faultsim_delete_and_reopen
                   1853:   db func a_string a_string
                   1854:   execsql {
                   1855:     PRAGMA page_size = 1024;
                   1856:     CREATE TABLE t1(x);
                   1857:     INSERT INTO t1 VALUES(a_string(800));
                   1858:     INSERT INTO t1 VALUES(a_string(800));
                   1859:   }
                   1860: 
                   1861:   set root [db one "SELECT rootpage FROM sqlite_master"]
                   1862:   db close
                   1863: 
                   1864:   hexio_write test.db [expr ($root-1)*1024 + 8] 00000000
                   1865:   sqlite3 db test.db
                   1866:   catchsql { SELECT length(x) FROM t1 }
                   1867: } {1 {database disk image is malformed}}
                   1868: }
                   1869: 
                   1870: do_test pager1-19.1 {
                   1871:   sqlite3 db ""
                   1872:   db func a_string a_string
                   1873:   execsql {
                   1874:     PRAGMA page_size = 512;
                   1875:     PRAGMA auto_vacuum = 1;
                   1876:     CREATE TABLE t1(aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am, an,
                   1877:                     ba, bb, bc, bd, be, bf, bg, bh, bi, bj, bk, bl, bm, bn,
                   1878:                     ca, cb, cc, cd, ce, cf, cg, ch, ci, cj, ck, cl, cm, cn,
                   1879:                     da, db, dc, dd, de, df, dg, dh, di, dj, dk, dl, dm, dn,
                   1880:                     ea, eb, ec, ed, ee, ef, eg, eh, ei, ej, ek, el, em, en,
                   1881:                     fa, fb, fc, fd, fe, ff, fg, fh, fi, fj, fk, fl, fm, fn,
                   1882:                     ga, gb, gc, gd, ge, gf, gg, gh, gi, gj, gk, gl, gm, gn,
                   1883:                     ha, hb, hc, hd, he, hf, hg, hh, hi, hj, hk, hl, hm, hn,
                   1884:                     ia, ib, ic, id, ie, if, ig, ih, ii, ij, ik, il, im, ix,
                   1885:                     ja, jb, jc, jd, je, jf, jg, jh, ji, jj, jk, jl, jm, jn,
                   1886:                     ka, kb, kc, kd, ke, kf, kg, kh, ki, kj, kk, kl, km, kn,
                   1887:                     la, lb, lc, ld, le, lf, lg, lh, li, lj, lk, ll, lm, ln,
                   1888:                     ma, mb, mc, md, me, mf, mg, mh, mi, mj, mk, ml, mm, mn
                   1889:     );
                   1890:     CREATE TABLE t2(aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am, an,
                   1891:                     ba, bb, bc, bd, be, bf, bg, bh, bi, bj, bk, bl, bm, bn,
                   1892:                     ca, cb, cc, cd, ce, cf, cg, ch, ci, cj, ck, cl, cm, cn,
                   1893:                     da, db, dc, dd, de, df, dg, dh, di, dj, dk, dl, dm, dn,
                   1894:                     ea, eb, ec, ed, ee, ef, eg, eh, ei, ej, ek, el, em, en,
                   1895:                     fa, fb, fc, fd, fe, ff, fg, fh, fi, fj, fk, fl, fm, fn,
                   1896:                     ga, gb, gc, gd, ge, gf, gg, gh, gi, gj, gk, gl, gm, gn,
                   1897:                     ha, hb, hc, hd, he, hf, hg, hh, hi, hj, hk, hl, hm, hn,
                   1898:                     ia, ib, ic, id, ie, if, ig, ih, ii, ij, ik, il, im, ix,
                   1899:                     ja, jb, jc, jd, je, jf, jg, jh, ji, jj, jk, jl, jm, jn,
                   1900:                     ka, kb, kc, kd, ke, kf, kg, kh, ki, kj, kk, kl, km, kn,
                   1901:                     la, lb, lc, ld, le, lf, lg, lh, li, lj, lk, ll, lm, ln,
                   1902:                     ma, mb, mc, md, me, mf, mg, mh, mi, mj, mk, ml, mm, mn
                   1903:     );
                   1904:     INSERT INTO t1(aa) VALUES( a_string(100000) );
                   1905:     INSERT INTO t2(aa) VALUES( a_string(100000) );
                   1906:     VACUUM;
                   1907:   }
                   1908: } {}
                   1909: 
                   1910: #-------------------------------------------------------------------------
                   1911: # Test a couple of special cases that come up while committing 
                   1912: # transactions:
                   1913: #
                   1914: #   pager1-20.1.*: Committing an in-memory database transaction when the 
                   1915: #                  database has not been modified at all.
                   1916: #
                   1917: #   pager1-20.2.*: As above, but with a normal db in exclusive-locking mode.
                   1918: #
                   1919: #   pager1-20.3.*: Committing a transaction in WAL mode where the database has
                   1920: #                  been modified, but all dirty pages have been flushed to 
                   1921: #                  disk before the commit.
                   1922: #
                   1923: do_test pager1-20.1.1 {
                   1924:   catch {db close}
                   1925:   sqlite3 db :memory:
                   1926:   execsql {
                   1927:     CREATE TABLE one(two, three);
                   1928:     INSERT INTO one VALUES('a', 'b');
                   1929:   }
                   1930: } {}
                   1931: do_test pager1-20.1.2 {
                   1932:   execsql {
                   1933:     BEGIN EXCLUSIVE;
                   1934:     COMMIT;
                   1935:   }
                   1936: } {}
                   1937: 
                   1938: do_test pager1-20.2.1 {
                   1939:   faultsim_delete_and_reopen
                   1940:   execsql {
                   1941:     PRAGMA locking_mode = exclusive;
                   1942:     PRAGMA journal_mode = persist;
                   1943:     CREATE TABLE one(two, three);
                   1944:     INSERT INTO one VALUES('a', 'b');
                   1945:   }
                   1946: } {exclusive persist}
                   1947: do_test pager1-20.2.2 {
                   1948:   execsql {
                   1949:     BEGIN EXCLUSIVE;
                   1950:     COMMIT;
                   1951:   }
                   1952: } {}
                   1953: 
                   1954: ifcapable wal {
                   1955:   do_test pager1-20.3.1 {
                   1956:     faultsim_delete_and_reopen
                   1957:     db func a_string a_string
                   1958:     execsql {
                   1959:       PRAGMA cache_size = 10;
                   1960:       PRAGMA journal_mode = wal;
                   1961:       BEGIN;
                   1962:         CREATE TABLE t1(x);
                   1963:         CREATE TABLE t2(y);
                   1964:         INSERT INTO t1 VALUES(a_string(800));
                   1965:         INSERT INTO t1 SELECT a_string(800) FROM t1;         /*   2 */
                   1966:         INSERT INTO t1 SELECT a_string(800) FROM t1;         /*   4 */
                   1967:         INSERT INTO t1 SELECT a_string(800) FROM t1;         /*   8 */
                   1968:         INSERT INTO t1 SELECT a_string(800) FROM t1;         /*  16 */
                   1969:         INSERT INTO t1 SELECT a_string(800) FROM t1;         /*  32 */
                   1970:       COMMIT;
                   1971:     }
                   1972:   } {wal}
                   1973:   do_test pager1-20.3.2 {
                   1974:     execsql {
                   1975:       BEGIN;
                   1976:       INSERT INTO t2 VALUES('xxxx');
                   1977:     }
                   1978:     recursive_select 32 t1
                   1979:     execsql COMMIT
                   1980:   } {}
                   1981: }
                   1982: 
                   1983: #-------------------------------------------------------------------------
                   1984: # Test that a WAL database may not be opened if:
                   1985: #
                   1986: #   pager1-21.1.*: The VFS has an iVersion less than 2, or
                   1987: #   pager1-21.2.*: The VFS does not provide xShmXXX() methods.
                   1988: #
                   1989: ifcapable wal {
                   1990:   do_test pager1-21.0 {
                   1991:     faultsim_delete_and_reopen
                   1992:     execsql {
                   1993:       PRAGMA journal_mode = WAL;
                   1994:       CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
                   1995:       INSERT INTO ko DEFAULT VALUES;
                   1996:     }
                   1997:   } {wal}
                   1998:   do_test pager1-21.1 {
                   1999:     testvfs tv -noshm 1
                   2000:     sqlite3 db2 test.db -vfs tv
                   2001:     catchsql { SELECT * FROM ko } db2
                   2002:   } {1 {unable to open database file}}
                   2003:   db2 close
                   2004:   tv delete
                   2005:   do_test pager1-21.2 {
                   2006:     testvfs tv -iversion 1
                   2007:     sqlite3 db2 test.db -vfs tv
                   2008:     catchsql { SELECT * FROM ko } db2
                   2009:   } {1 {unable to open database file}}
                   2010:   db2 close
                   2011:   tv delete
                   2012: }
                   2013: 
                   2014: #-------------------------------------------------------------------------
                   2015: # Test that a "PRAGMA wal_checkpoint":
                   2016: #
                   2017: #   pager1-22.1.*: is a no-op on a non-WAL db, and
                   2018: #   pager1-22.2.*: does not cause xSync calls with a synchronous=off db.
                   2019: #
                   2020: ifcapable wal {
                   2021:   do_test pager1-22.1.1 {
                   2022:     faultsim_delete_and_reopen
                   2023:     execsql {
                   2024:       CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
                   2025:       INSERT INTO ko DEFAULT VALUES;
                   2026:     }
                   2027:     execsql { PRAGMA wal_checkpoint }
                   2028:   } {0 -1 -1}
                   2029:   do_test pager1-22.2.1 {
                   2030:     testvfs tv -default 1
                   2031:     tv filter xSync
                   2032:     tv script xSyncCb
                   2033:     proc xSyncCb {args} {incr ::synccount}
                   2034:     set ::synccount 0
                   2035:     sqlite3 db test.db
                   2036:     execsql {
                   2037:       PRAGMA synchronous = off;
                   2038:       PRAGMA journal_mode = WAL;
                   2039:       INSERT INTO ko DEFAULT VALUES;
                   2040:     }
                   2041:     execsql { PRAGMA wal_checkpoint }
                   2042:     set synccount
                   2043:   } {0}
                   2044:   db close
                   2045:   tv delete
                   2046: }
                   2047: 
                   2048: #-------------------------------------------------------------------------
                   2049: # Tests for changing journal mode.
                   2050: #
                   2051: #   pager1-23.1.*: Test that when changing from PERSIST to DELETE mode,
                   2052: #                  the journal file is deleted.
                   2053: #
                   2054: #   pager1-23.2.*: Same test as above, but while a shared lock is held
                   2055: #                  on the database file.
                   2056: #
                   2057: #   pager1-23.3.*: Same test as above, but while a reserved lock is held
                   2058: #                  on the database file.
                   2059: #
                   2060: #   pager1-23.4.*: And, for fun, while holding an exclusive lock.
                   2061: #
                   2062: #   pager1-23.5.*: Try to set various different journal modes with an
                   2063: #                  in-memory database (only MEMORY and OFF should work).
                   2064: #
                   2065: #   pager1-23.6.*: Try to set locking_mode=normal on an in-memory database
                   2066: #                  (doesn't work - in-memory databases always use
                   2067: #                  locking_mode=exclusive).
                   2068: #
                   2069: do_test pager1-23.1.1 {
                   2070:   faultsim_delete_and_reopen
                   2071:   execsql {
                   2072:     PRAGMA journal_mode = PERSIST;
                   2073:     CREATE TABLE t1(a, b);
                   2074:   }
                   2075:   file exists test.db-journal
                   2076: } {1}
                   2077: do_test pager1-23.1.2 {
                   2078:   execsql { PRAGMA journal_mode = DELETE }
                   2079:   file exists test.db-journal
                   2080: } {0}
                   2081: 
                   2082: do_test pager1-23.2.1 {
                   2083:   execsql {
                   2084:     PRAGMA journal_mode = PERSIST;
                   2085:     INSERT INTO t1 VALUES('Canberra', 'ACT');
                   2086:   }
                   2087:   db eval { SELECT * FROM t1 } {
                   2088:     db eval { PRAGMA journal_mode = DELETE }
                   2089:   }
                   2090:   execsql { PRAGMA journal_mode }
                   2091: } {delete}
                   2092: do_test pager1-23.2.2 {
                   2093:   file exists test.db-journal
                   2094: } {0}
                   2095: 
                   2096: do_test pager1-23.3.1 {
                   2097:   execsql {
                   2098:     PRAGMA journal_mode = PERSIST;
                   2099:     INSERT INTO t1 VALUES('Darwin', 'NT');
                   2100:     BEGIN IMMEDIATE;
                   2101:   }
                   2102:   db eval { PRAGMA journal_mode = DELETE }
                   2103:   execsql { PRAGMA journal_mode }
                   2104: } {delete}
                   2105: do_test pager1-23.3.2 {
                   2106:   file exists test.db-journal
                   2107: } {0}
                   2108: do_test pager1-23.3.3 {
                   2109:   execsql COMMIT
                   2110: } {}
                   2111: 
                   2112: do_test pager1-23.4.1 {
                   2113:   execsql {
                   2114:     PRAGMA journal_mode = PERSIST;
                   2115:     INSERT INTO t1 VALUES('Adelaide', 'SA');
                   2116:     BEGIN EXCLUSIVE;
                   2117:   }
                   2118:   db eval { PRAGMA journal_mode = DELETE }
                   2119:   execsql { PRAGMA journal_mode }
                   2120: } {delete}
                   2121: do_test pager1-23.4.2 {
                   2122:   file exists test.db-journal
                   2123: } {0}
                   2124: do_test pager1-23.4.3 {
                   2125:   execsql COMMIT
                   2126: } {}
                   2127: 
                   2128: do_test pager1-23.5.1 {
                   2129:   faultsim_delete_and_reopen
                   2130:   sqlite3 db :memory:
                   2131: } {}
                   2132: foreach {tn mode possible} {
                   2133:   2  off      1
                   2134:   3  memory   1
                   2135:   4  persist  0
                   2136:   5  delete   0
                   2137:   6  wal      0
                   2138:   7  truncate 0
                   2139: } {
                   2140:   do_test pager1-23.5.$tn.1 {
                   2141:     execsql "PRAGMA journal_mode = off"
                   2142:     execsql "PRAGMA journal_mode = $mode"
                   2143:   } [if $possible {list $mode} {list off}]
                   2144:   do_test pager1-23.5.$tn.2 {
                   2145:     execsql "PRAGMA journal_mode = memory"
                   2146:     execsql "PRAGMA journal_mode = $mode"
                   2147:   } [if $possible {list $mode} {list memory}]
                   2148: }
                   2149: do_test pager1-23.6.1 {
                   2150:   execsql {PRAGMA locking_mode = normal}
                   2151: } {exclusive}
                   2152: do_test pager1-23.6.2 {
                   2153:   execsql {PRAGMA locking_mode = exclusive}
                   2154: } {exclusive}
                   2155: do_test pager1-23.6.3 {
                   2156:   execsql {PRAGMA locking_mode}
                   2157: } {exclusive}
                   2158: do_test pager1-23.6.4 {
                   2159:   execsql {PRAGMA main.locking_mode}
                   2160: } {exclusive}
                   2161: 
                   2162: #-------------------------------------------------------------------------
                   2163: #
                   2164: do_test pager1-24.1.1 {
                   2165:   faultsim_delete_and_reopen
                   2166:   db func a_string a_string
                   2167:   execsql {
                   2168:     PRAGMA cache_size = 10;
                   2169:     PRAGMA auto_vacuum = FULL;
                   2170:     CREATE TABLE x1(x, y, z, PRIMARY KEY(y, z));
                   2171:     CREATE TABLE x2(x, y, z, PRIMARY KEY(y, z));
                   2172:     INSERT INTO x2 VALUES(a_string(400), a_string(500), a_string(600));
                   2173:     INSERT INTO x2 SELECT a_string(600), a_string(400), a_string(500) FROM x2;
                   2174:     INSERT INTO x2 SELECT a_string(500), a_string(600), a_string(400) FROM x2;
                   2175:     INSERT INTO x2 SELECT a_string(400), a_string(500), a_string(600) FROM x2;
                   2176:     INSERT INTO x2 SELECT a_string(600), a_string(400), a_string(500) FROM x2;
                   2177:     INSERT INTO x2 SELECT a_string(500), a_string(600), a_string(400) FROM x2;
                   2178:     INSERT INTO x2 SELECT a_string(400), a_string(500), a_string(600) FROM x2;
                   2179:     INSERT INTO x1 SELECT * FROM x2;
                   2180:   }
                   2181: } {}
                   2182: do_test pager1-24.1.2 {
                   2183:   execsql {
                   2184:     BEGIN;
                   2185:       DELETE FROM x1 WHERE rowid<32;
                   2186:   }
                   2187:   recursive_select 64 x2
                   2188: } {}
                   2189: do_test pager1-24.1.3 {
                   2190:   execsql { 
                   2191:       UPDATE x1 SET z = a_string(300) WHERE rowid>40;
                   2192:     COMMIT;
                   2193:     PRAGMA integrity_check;
                   2194:     SELECT count(*) FROM x1;
                   2195:   }
                   2196: } {ok 33}
                   2197: 
                   2198: do_test pager1-24.1.4 {
                   2199:   execsql {
                   2200:     DELETE FROM x1;
                   2201:     INSERT INTO x1 SELECT * FROM x2;
                   2202:     BEGIN;
                   2203:       DELETE FROM x1 WHERE rowid<32;
                   2204:       UPDATE x1 SET z = a_string(299) WHERE rowid>40;
                   2205:   }
                   2206:   recursive_select 64 x2 {db eval COMMIT}
                   2207:   execsql {
                   2208:     PRAGMA integrity_check;
                   2209:     SELECT count(*) FROM x1;
                   2210:   }
                   2211: } {ok 33}
                   2212: 
                   2213: do_test pager1-24.1.5 {
                   2214:   execsql {
                   2215:     DELETE FROM x1;
                   2216:     INSERT INTO x1 SELECT * FROM x2;
                   2217:   }
                   2218:   recursive_select 64 x2 { db eval {CREATE TABLE x3(x, y, z)} }
                   2219:   execsql { SELECT * FROM x3 }
                   2220: } {}
                   2221: 
                   2222: #-------------------------------------------------------------------------
                   2223: #
                   2224: do_test pager1-25-1 {
                   2225:   faultsim_delete_and_reopen
                   2226:   execsql {
                   2227:     BEGIN;
                   2228:       SAVEPOINT abc;
                   2229:         CREATE TABLE t1(a, b);
                   2230:       ROLLBACK TO abc;
                   2231:     COMMIT;
                   2232:   }
                   2233:   db close
                   2234: } {}
                   2235: breakpoint
                   2236: do_test pager1-25-2 {
                   2237:   faultsim_delete_and_reopen
                   2238:   execsql {
                   2239:     SAVEPOINT abc;
                   2240:       CREATE TABLE t1(a, b);
                   2241:     ROLLBACK TO abc;
                   2242:     COMMIT;
                   2243:   }
                   2244:   db close
                   2245: } {}
                   2246: 
                   2247: #-------------------------------------------------------------------------
                   2248: # Sector-size tests.
                   2249: #
                   2250: do_test pager1-26.1 {
                   2251:   testvfs tv -default 1
                   2252:   tv sectorsize 4096
                   2253:   faultsim_delete_and_reopen
                   2254:   db func a_string a_string
                   2255:   execsql {
                   2256:     PRAGMA page_size = 512;
                   2257:     CREATE TABLE tbl(a PRIMARY KEY, b UNIQUE);
                   2258:     BEGIN;
                   2259:       INSERT INTO tbl VALUES(a_string(25), a_string(600));
                   2260:       INSERT INTO tbl SELECT a_string(25), a_string(600) FROM tbl;
                   2261:       INSERT INTO tbl SELECT a_string(25), a_string(600) FROM tbl;
                   2262:       INSERT INTO tbl SELECT a_string(25), a_string(600) FROM tbl;
                   2263:       INSERT INTO tbl SELECT a_string(25), a_string(600) FROM tbl;
                   2264:       INSERT INTO tbl SELECT a_string(25), a_string(600) FROM tbl;
                   2265:       INSERT INTO tbl SELECT a_string(25), a_string(600) FROM tbl;
                   2266:       INSERT INTO tbl SELECT a_string(25), a_string(600) FROM tbl;
                   2267:     COMMIT;
                   2268:   }
                   2269: } {}
                   2270: do_execsql_test pager1-26.1 {
                   2271:   UPDATE tbl SET b = a_string(550);
                   2272: } {}
                   2273: db close
                   2274: tv delete
                   2275: 
                   2276: #-------------------------------------------------------------------------
                   2277: #
                   2278: do_test pager1.27.1 {
                   2279:   faultsim_delete_and_reopen
                   2280:   sqlite3_pager_refcounts db
                   2281:   execsql {
                   2282:     BEGIN;
                   2283:       CREATE TABLE t1(a, b);
                   2284:   }
                   2285:   sqlite3_pager_refcounts db
                   2286:   execsql COMMIT
                   2287: } {}
                   2288: 
                   2289: #-------------------------------------------------------------------------
                   2290: # Test that attempting to open a write-transaction with 
                   2291: # locking_mode=exclusive in WAL mode fails if there are other clients on 
                   2292: # the same database.
                   2293: #
                   2294: catch { db close }
                   2295: ifcapable wal {
                   2296:   do_multiclient_test tn {
                   2297:     do_test pager1-28.$tn.1 {
                   2298:       sql1 { 
                   2299:         PRAGMA journal_mode = WAL;
                   2300:         CREATE TABLE t1(a, b);
                   2301:         INSERT INTO t1 VALUES('a', 'b');
                   2302:       }
                   2303:     } {wal}
                   2304:     do_test pager1-28.$tn.2 { sql2 { SELECT * FROM t1 } } {a b}
                   2305: 
                   2306:     do_test pager1-28.$tn.3 { sql1 { PRAGMA locking_mode=exclusive } } {exclusive}
                   2307:     do_test pager1-28.$tn.4 { 
                   2308:       csql1 { BEGIN; INSERT INTO t1 VALUES('c', 'd'); }
                   2309:     } {1 {database is locked}}
                   2310:     code2 { db2 close ; sqlite3 db2 test.db }
                   2311:     do_test pager1-28.$tn.4 { 
                   2312:       sql1 { INSERT INTO t1 VALUES('c', 'd'); COMMIT }
                   2313:     } {}
                   2314:   }
                   2315: }
                   2316: 
                   2317: #-------------------------------------------------------------------------
                   2318: # Normally, when changing from journal_mode=PERSIST to DELETE the pager
                   2319: # attempts to delete the journal file. However, if it cannot obtain a
                   2320: # RESERVED lock on the database file, this step is skipped.
                   2321: #
                   2322: do_multiclient_test tn {
                   2323:   do_test pager1-28.$tn.1 {
                   2324:     sql1 { 
                   2325:       PRAGMA journal_mode = PERSIST;
                   2326:       CREATE TABLE t1(a, b);
                   2327:       INSERT INTO t1 VALUES('a', 'b');
                   2328:     }
                   2329:   } {persist}
                   2330:   do_test pager1-28.$tn.2 { file exists test.db-journal } 1
                   2331:   do_test pager1-28.$tn.3 { sql1 { PRAGMA journal_mode = DELETE } } delete
                   2332:   do_test pager1-28.$tn.4 { file exists test.db-journal } 0
                   2333: 
                   2334:   do_test pager1-28.$tn.5 {
                   2335:     sql1 { 
                   2336:       PRAGMA journal_mode = PERSIST;
                   2337:       INSERT INTO t1 VALUES('c', 'd');
                   2338:     }
                   2339:   } {persist}
                   2340:   do_test pager1-28.$tn.6 { file exists test.db-journal } 1
                   2341:   do_test pager1-28.$tn.7 {
                   2342:     sql2 { BEGIN; INSERT INTO t1 VALUES('e', 'f'); }
                   2343:   } {}
                   2344:   do_test pager1-28.$tn.8  { file exists test.db-journal } 1
                   2345:   do_test pager1-28.$tn.9  { sql1 { PRAGMA journal_mode = DELETE } } delete
                   2346:   do_test pager1-28.$tn.10 { file exists test.db-journal } 1
                   2347: 
                   2348:   do_test pager1-28.$tn.11 { sql2 COMMIT } {}
                   2349:   do_test pager1-28.$tn.12 { file exists test.db-journal } 0
                   2350: 
                   2351:   do_test pager1-28-$tn.13 {
                   2352:     code1 { set channel [db incrblob -readonly t1 a 2] }
                   2353:     sql1 {
                   2354:       PRAGMA journal_mode = PERSIST;
                   2355:       INSERT INTO t1 VALUES('g', 'h');
                   2356:     }
                   2357:   } {persist}
                   2358:   do_test pager1-28.$tn.14 { file exists test.db-journal } 1
                   2359:   do_test pager1-28.$tn.15 {
                   2360:     sql2 { BEGIN; INSERT INTO t1 VALUES('e', 'f'); }
                   2361:   } {}
                   2362:   do_test pager1-28.$tn.16 { sql1 { PRAGMA journal_mode = DELETE } } delete
                   2363:   do_test pager1-28.$tn.17 { file exists test.db-journal } 1
                   2364: 
                   2365:   do_test pager1-28.$tn.17 { csql2 { COMMIT } } {1 {database is locked}}
                   2366:   do_test pager1-28-$tn.18 { code1 { read $channel } } c
                   2367:   do_test pager1-28-$tn.19 { code1 { close $channel } } {}
                   2368:   do_test pager1-28.$tn.20 { sql2 { COMMIT } } {}
                   2369: }
                   2370: 
                   2371: do_test pager1-29.1 {
                   2372:   faultsim_delete_and_reopen
                   2373:   execsql {
                   2374:     PRAGMA page_size = 1024;
                   2375:     PRAGMA auto_vacuum = full;
                   2376:     PRAGMA locking_mode=exclusive;
                   2377:     CREATE TABLE t1(a, b);
                   2378:     INSERT INTO t1 VALUES(1, 2);
                   2379:   }
                   2380:   file size test.db
                   2381: } [expr 1024*3]
                   2382: do_test pager1-29.2 {
                   2383:   execsql {
                   2384:     PRAGMA page_size = 4096;
                   2385:     VACUUM;
                   2386:   }
                   2387:   file size test.db
                   2388: } [expr 4096*3]
                   2389: 
                   2390: #-------------------------------------------------------------------------
                   2391: # Test that if an empty database file (size 0 bytes) is opened in 
                   2392: # exclusive-locking mode, any journal file is deleted from the file-system
                   2393: # without being rolled back. And that the RESERVED lock obtained while
                   2394: # doing this is not released.
                   2395: #
                   2396: do_test pager1-30.1 {
                   2397:   db close
                   2398:   delete_file test.db
                   2399:   delete_file test.db-journal
                   2400:   set fd [open test.db-journal w]
                   2401:   seek $fd [expr 512+1032*2]
                   2402:   puts -nonewline $fd x
                   2403:   close $fd
                   2404: 
                   2405:   sqlite3 db test.db
                   2406:   execsql {
                   2407:     PRAGMA locking_mode=EXCLUSIVE;
                   2408:     SELECT count(*) FROM sqlite_master;
                   2409:     PRAGMA lock_status;
                   2410:   }
                   2411: } {exclusive 0 main reserved temp closed}
                   2412: 
                   2413: #-------------------------------------------------------------------------
                   2414: # Test that if the "page-size" field in a journal-header is 0, the journal
                   2415: # file can still be rolled back. This is required for backward compatibility -
                   2416: # versions of SQLite prior to 3.5.8 always set this field to zero.
                   2417: #
                   2418: if {$tcl_platform(platform)=="unix"} {
                   2419: do_test pager1-31.1 {
                   2420:   faultsim_delete_and_reopen
                   2421:   execsql {
                   2422:     PRAGMA cache_size = 10;
                   2423:     PRAGMA page_size = 1024;
                   2424:     CREATE TABLE t1(x, y, UNIQUE(x, y));
                   2425:     INSERT INTO t1 VALUES(randomblob(1500), randomblob(1500));
                   2426:     INSERT INTO t1 SELECT randomblob(1500), randomblob(1500) FROM t1;
                   2427:     INSERT INTO t1 SELECT randomblob(1500), randomblob(1500) FROM t1;
                   2428:     INSERT INTO t1 SELECT randomblob(1500), randomblob(1500) FROM t1;
                   2429:     INSERT INTO t1 SELECT randomblob(1500), randomblob(1500) FROM t1;
                   2430:     INSERT INTO t1 SELECT randomblob(1500), randomblob(1500) FROM t1;
                   2431:     INSERT INTO t1 SELECT randomblob(1500), randomblob(1500) FROM t1;
                   2432:     INSERT INTO t1 SELECT randomblob(1500), randomblob(1500) FROM t1;
                   2433:     INSERT INTO t1 SELECT randomblob(1500), randomblob(1500) FROM t1;
                   2434:     INSERT INTO t1 SELECT randomblob(1500), randomblob(1500) FROM t1;
                   2435:     INSERT INTO t1 SELECT randomblob(1500), randomblob(1500) FROM t1;
                   2436:     BEGIN;
                   2437:       UPDATE t1 SET y = randomblob(1499);
                   2438:   }
                   2439:   copy_file test.db test.db2
                   2440:   copy_file test.db-journal test.db2-journal
                   2441:   
                   2442:   hexio_write test.db2-journal 24 00000000
                   2443:   sqlite3 db2 test.db2
                   2444:   execsql { PRAGMA integrity_check } db2
                   2445: } {ok}
                   2446: }
                   2447: 
                   2448: #-------------------------------------------------------------------------
                   2449: # Test that a database file can be "pre-hinted" to a certain size and that
                   2450: # subsequent spilling of the pager cache does not result in the database
                   2451: # file being shrunk.
                   2452: #
                   2453: catch {db close}
                   2454: forcedelete test.db
                   2455: 
                   2456: do_test pager1-32.1 {
                   2457:   sqlite3 db test.db
                   2458:   execsql {
                   2459:     CREATE TABLE t1(x, y);
                   2460:   }
                   2461:   db close
                   2462:   sqlite3 db test.db
                   2463:   execsql {
                   2464:     BEGIN;
                   2465:     INSERT INTO t1 VALUES(1, randomblob(10000));
                   2466:   }
                   2467:   file_control_chunksize_test db main 1024
                   2468:   file_control_sizehint_test db main 20971520; # 20MB
                   2469:   execsql {
                   2470:     PRAGMA cache_size = 10;
                   2471:     INSERT INTO t1 VALUES(1, randomblob(10000));
                   2472:     INSERT INTO t1 VALUES(2, randomblob(10000));
                   2473:     INSERT INTO t1 SELECT x+2, randomblob(10000) from t1;
                   2474:     INSERT INTO t1 SELECT x+4, randomblob(10000) from t1;
                   2475:     INSERT INTO t1 SELECT x+8, randomblob(10000) from t1;
                   2476:     INSERT INTO t1 SELECT x+16, randomblob(10000) from t1;
                   2477:     SELECT count(*) FROM t1;
                   2478:     COMMIT;
                   2479:   }
                   2480:   db close
                   2481:   file size test.db
                   2482: } {20971520}
                   2483: 
                   2484: # Cleanup 20MB file left by the previous test.
                   2485: forcedelete test.db
                   2486: 
                   2487: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>