CoolFace
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
pagerfault.test1554 linesDownload Raw Back to test
1# 2010 June 152#3# The author disclaims copyright to this source code.  In place of4# 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 13set testdir [file dirname $argv0]14source $testdir/tester.tcl15source $testdir/lock_common.tcl16source $testdir/malloc_common.tcl17 18if {[permutation] == "inmemory_journal"} {19  finish_test20  return21}22 23if {$::tcl_platform(os) eq "Windows NT"} {24  finish_test25  return26}27 28set a_string_counter 129proc a_string {n} {30  global a_string_counter31  incr a_string_counter32  string range [string repeat "${a_string_counter}." $n] 1 $n33}34db func a_string a_string35 36#-------------------------------------------------------------------------37# Test fault-injection while rolling back a hot-journal file.38#39do_test pagerfault-1-pre1 {40  execsql {41    PRAGMA journal_mode = DELETE;42    PRAGMA cache_size = 10;43    CREATE TABLE t1(a UNIQUE, b UNIQUE);44    INSERT INTO t1 VALUES(a_string(200), a_string(300));45    INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;46    INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;47    BEGIN;48      INSERT INTO t1 SELECT a_string(201), a_string(301) FROM t1;49      INSERT INTO t1 SELECT a_string(202), a_string(302) FROM t1;50      INSERT INTO t1 SELECT a_string(203), a_string(303) FROM t1;51      INSERT INTO t1 SELECT a_string(204), a_string(304) FROM t1;52  }53  faultsim_save_and_close54} {}55do_faultsim_test pagerfault-1 -prep {56  faultsim_restore_and_reopen57} -body {58  execsql { SELECT count(*) FROM t1 }59} -test {60  faultsim_test_result {0 4} 61  faultsim_integrity_check62  if {[db one { SELECT count(*) FROM t1 }] != 4} {63    error "Database content appears incorrect"64  }65}66 67#-------------------------------------------------------------------------68# Test fault-injection while rolling back a hot-journal file with a 69# page-size different from the current value stored on page 1 of the70# database file.71#72do_test pagerfault-2-pre1 {73  testvfs tv -default 174  tv filter xSync75  tv script xSyncCb76  proc xSyncCb {filename args} {77    if {[string match *journal filename]==0} faultsim_save78  }79  faultsim_delete_and_reopen80  execsql {81    PRAGMA page_size = 4096;82    BEGIN;83      CREATE TABLE abc(a, b, c);84      INSERT INTO abc VALUES('o', 't', 't'); 85      INSERT INTO abc VALUES('f', 'f', 's'); 86      INSERT INTO abc SELECT * FROM abc; -- 487      INSERT INTO abc SELECT * FROM abc; -- 888      INSERT INTO abc SELECT * FROM abc; -- 1689      INSERT INTO abc SELECT * FROM abc; -- 3290      INSERT INTO abc SELECT * FROM abc; -- 6491      INSERT INTO abc SELECT * FROM abc; -- 12892      INSERT INTO abc SELECT * FROM abc; -- 25693    COMMIT;94    PRAGMA page_size = 1024;95    VACUUM;96  }97  db close98  tv delete99} {}100do_faultsim_test pagerfault-2 -prep {101  faultsim_restore_and_reopen102} -body {103  execsql { SELECT * FROM abc }104} -test {105  set answer [split [string repeat "ottffs" 128] ""]106  faultsim_test_result [list 0 $answer]107  faultsim_integrity_check108  set res [db eval { SELECT * FROM abc }]109  if {$res != $answer} { error "Database content appears incorrect ($res)" }110} 111 112#-------------------------------------------------------------------------113# Test fault-injection while rolling back hot-journals that were created114# as part of a multi-file transaction.115#116do_test pagerfault-3-pre1 {117  testvfs tstvfs -default 1118  tstvfs filter xDelete119  tstvfs script xDeleteCallback120 121  proc xDeleteCallback {method file args} {122    set file [file tail $file]123    if { [string match *mj* $file] } { faultsim_save }124  }125 126  faultsim_delete_and_reopen127  db func a_string a_string128 129  execsql {130    ATTACH 'test.db2' AS aux;131    PRAGMA journal_mode = DELETE;132    PRAGMA main.cache_size = 10;133    PRAGMA aux.cache_size = 10;134 135    CREATE TABLE t1(a UNIQUE, b UNIQUE);136    CREATE TABLE aux.t2(a UNIQUE, b UNIQUE);137    INSERT INTO t1 VALUES(a_string(200), a_string(300));138    INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;139    INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;140    INSERT INTO t2 SELECT * FROM t1;141 142    BEGIN;143      INSERT INTO t1 SELECT a_string(201), a_string(301) FROM t1;144      INSERT INTO t1 SELECT a_string(202), a_string(302) FROM t1;145      INSERT INTO t1 SELECT a_string(203), a_string(303) FROM t1;146      INSERT INTO t1 SELECT a_string(204), a_string(304) FROM t1;147      REPLACE INTO t2 SELECT * FROM t1;148    COMMIT;149  }150 151  db close152  tstvfs delete153} {}154do_faultsim_test pagerfault-3 -prep {155  faultsim_restore_and_reopen156} -body {157  execsql { 158    ATTACH 'test.db2' AS aux;159    SELECT count(*) FROM t2;160    SELECT count(*) FROM t1;161  }162} -test {163  faultsim_test_result {0 {4 4}} {1 {unable to open database: test.db2}}164  faultsim_integrity_check165  catchsql { ATTACH 'test.db2' AS aux }166  if {[db one { SELECT count(*) FROM t1 }] != 4167   || [db one { SELECT count(*) FROM t2 }] != 4168  } {169    error "Database content appears incorrect"170  }171}172 173#-------------------------------------------------------------------------174# Test fault-injection as part of a vanilla, no-transaction, INSERT175# statement.176#177do_faultsim_test pagerfault-4 -prep {178  faultsim_delete_and_reopen179} -body {180  execsql { 181    CREATE TABLE x(y);182    INSERT INTO x VALUES('z');183    SELECT * FROM x;184  }185} -test {186  faultsim_test_result {0 z}187  faultsim_integrity_check188}189 190#-------------------------------------------------------------------------191# Test fault-injection as part of a commit when using journal_mode=PERSIST.192# Three different cases:193#194#    pagerfault-5.1: With no journal_size_limit configured.195#    pagerfault-5.2: With a journal_size_limit configured.196#    pagerfault-5.4: Multi-file transaction. One connection has a 197#                    journal_size_limit of 0, the other has no limit.198#199do_test pagerfault-5-pre1 {200  faultsim_delete_and_reopen201  db func a_string a_string202  execsql {203    CREATE TABLE t1(a UNIQUE, b UNIQUE);204    INSERT INTO t1 VALUES(a_string(200), a_string(300));205    INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;206    INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;207  }208  faultsim_save_and_close209} {}210do_faultsim_test pagerfault-5.1 -prep {211  faultsim_restore_and_reopen212  db func a_string a_string213  execsql { PRAGMA journal_mode = PERSIST }214} -body {215  execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 }216} -test {217  faultsim_test_result {0 {}}218  faultsim_integrity_check219}220do_faultsim_test pagerfault-5.2 -prep {221  faultsim_restore_and_reopen222  db func a_string a_string223  execsql { 224    PRAGMA journal_mode = PERSIST;225    PRAGMA journal_size_limit = 2048;226  }227} -body {228  execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 }229} -test {230  faultsim_test_result {0 {}}231  faultsim_integrity_check232}233do_faultsim_test pagerfault-5.3 -faults oom-transient -prep {234  faultsim_restore_and_reopen235  db func a_string a_string236  forcedelete test2.db test2.db-journal test2.db-wal237  execsql { 238    PRAGMA journal_mode = PERSIST;239    ATTACH 'test2.db' AS aux;240    PRAGMA aux.journal_mode = PERSIST;241    PRAGMA aux.journal_size_limit = 0;242  }243} -body {244  execsql {245    BEGIN;246      INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;247      CREATE TABLE aux.t2 AS SELECT * FROM t1;248    COMMIT;249  }250} -test {251  faultsim_test_result {0 {}}252 253  catchsql { COMMIT }254  catchsql { ROLLBACK }255 256  faultsim_integrity_check257  set res ""258  set rc [catch { set res [db one { PRAGMA aux.integrity_check }] }]259  if {$rc!=0 || $res != "ok"} {error "integrity-check problem:$rc $res"}260}261 262#-------------------------------------------------------------------------263# Test fault-injection as part of a commit when using 264# journal_mode=TRUNCATE.265#266do_test pagerfault-6-pre1 {267  faultsim_delete_and_reopen268  db func a_string a_string269  execsql {270    CREATE TABLE t1(a UNIQUE, b UNIQUE);271    INSERT INTO t1 VALUES(a_string(200), a_string(300));272  }273  faultsim_save_and_close274} {}275 276do_faultsim_test pagerfault-6.1 -prep {277  faultsim_restore_and_reopen278  db func a_string a_string279  execsql { PRAGMA journal_mode = TRUNCATE }280} -body {281  execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 }282  execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 }283} -test {284  faultsim_test_result {0 {}}285  faultsim_integrity_check286}287 288# The unix vfs xAccess() method considers a file zero bytes in size to289# "not exist". This proc overrides that behaviour so that a zero length290# file is considered to exist.291#292proc xAccess {method filename op args} {293  if {$op != "SQLITE_ACCESS_EXISTS"} { return "" }294  return [file exists $filename]295}296do_faultsim_test pagerfault-6.2 -faults cantopen-* -prep {297  shmfault filter xAccess298  shmfault script xAccess299 300  faultsim_restore_and_reopen301  db func a_string a_string302  execsql { PRAGMA journal_mode = TRUNCATE }303} -body {304  execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 }305  execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 }306} -test {307  faultsim_test_result {0 {}}308  faultsim_integrity_check309}310 311# The following was an attempt to get a bitvec malloc to fail. Didn't work.312#313# do_test pagerfault-6-pre1 {314#   faultsim_delete_and_reopen315#   execsql {316#     CREATE TABLE t1(x, y, UNIQUE(x, y));317#     INSERT INTO t1 VALUES(1, randomblob(1501));318#     INSERT INTO t1 VALUES(2, randomblob(1502));319#     INSERT INTO t1 VALUES(3, randomblob(1503));320#     INSERT INTO t1 VALUES(4, randomblob(1504));321#     INSERT INTO t1 322#       SELECT x, randomblob(1500+oid+(SELECT max(oid) FROM t1)) FROM t1;323#     INSERT INTO t1 324#       SELECT x, randomblob(1500+oid+(SELECT max(oid) FROM t1)) FROM t1;325#     INSERT INTO t1 326#       SELECT x, randomblob(1500+oid+(SELECT max(oid) FROM t1)) FROM t1;327#     INSERT INTO t1 328#       SELECT x, randomblob(1500+oid+(SELECT max(oid) FROM t1)) FROM t1;329#   }330#   faultsim_save_and_close331# } {}332# do_faultsim_test pagerfault-6 -prep {333#   faultsim_restore_and_reopen334# } -body {335#   execsql { 336#     BEGIN;337#       UPDATE t1 SET x=x+4 WHERE x=1;338#       SAVEPOINT one;339#         UPDATE t1 SET x=x+4 WHERE x=2;340#         SAVEPOINT three;341#           UPDATE t1 SET x=x+4 WHERE x=3;342#           SAVEPOINT four;343#             UPDATE t1 SET x=x+4 WHERE x=4;344#         RELEASE three;345#     COMMIT;346#     SELECT DISTINCT x FROM t1;347#   }348# } -test {349#   faultsim_test_result {0 {5 6 7 8}}350#   faultsim_integrity_check351# }352#353 354# This is designed to provoke a special case in the pager code:355#356# If an error (specifically, a FULL or IOERR error) occurs while writing a357# dirty page to the file-system in order to free up memory, the pager enters358# the "error state". An IO error causes SQLite to roll back the current359# transaction (exiting the error state). A FULL error, however, may only360# rollback the current statement.361#362# This block tests that nothing goes wrong if a FULL error occurs while363# writing a dirty page out to free memory from within a statement that has364# opened a statement transaction.365#366do_test pagerfault-7-pre1 {367  faultsim_delete_and_reopen368  execsql {369    CREATE TABLE t2(a INTEGER PRIMARY KEY, b);370    BEGIN;371      INSERT INTO t2 VALUES(NULL, randomblob(1500));372      INSERT INTO t2 VALUES(NULL, randomblob(1500));373      INSERT INTO t2 SELECT NULL, randomblob(1500) FROM t2;    --  4374      INSERT INTO t2 SELECT NULL, randomblob(1500) FROM t2;    --  8375      INSERT INTO t2 SELECT NULL, randomblob(1500) FROM t2;    -- 16376      INSERT INTO t2 SELECT NULL, randomblob(1500) FROM t2;    -- 32377      INSERT INTO t2 SELECT NULL, randomblob(1500) FROM t2;    -- 64378    COMMIT;379    CREATE TABLE t1(a PRIMARY KEY, b);380    INSERT INTO t1 SELECT * FROM t2;381    DROP TABLE t2;382  }383  faultsim_save_and_close384} {}385do_faultsim_test pagerfault-7 -prep {386  faultsim_restore_and_reopen387  execsql { 388    PRAGMA cache_size = 10;389    BEGIN;390      UPDATE t1 SET b = randomblob(1500);391  }392} -body {393  execsql { UPDATE t1 SET a = 65, b = randomblob(1500) WHERE (a+1)>200 }394  execsql COMMIT395} -test {396  faultsim_test_result {0 {}}397  faultsim_integrity_check398}399 400do_test pagerfault-8-pre1 {401  faultsim_delete_and_reopen402  execsql {403    PRAGMA auto_vacuum = 1;404    CREATE TABLE t1(a INTEGER PRIMARY KEY, b);405    BEGIN;406      INSERT INTO t1 VALUES(NULL, randomblob(1500));407      INSERT INTO t1 VALUES(NULL, randomblob(1500));408      INSERT INTO t1 SELECT NULL, randomblob(1500) FROM t1;    --  4409      INSERT INTO t1 SELECT NULL, randomblob(1500) FROM t1;    --  8410      INSERT INTO t1 SELECT NULL, randomblob(1500) FROM t1;    -- 16411      INSERT INTO t1 SELECT NULL, randomblob(1500) FROM t1;    -- 32412      INSERT INTO t1 SELECT NULL, randomblob(1500) FROM t1;    -- 64413    COMMIT;414  }415  faultsim_save_and_close416  set filesize [file size test.db]417  set {} {}418} {}419do_test pagerfault-8-pre2 {420  faultsim_restore_and_reopen421  execsql { DELETE FROM t1 WHERE a>32 }422  expr {[file size test.db] < $filesize}423} {1}424do_faultsim_test pagerfault-8 -prep {425  faultsim_restore_and_reopen426  execsql { 427    BEGIN;428    DELETE FROM t1 WHERE a>32;429  }430} -body {431  execsql COMMIT432} -test {433  faultsim_test_result {0 {}}434  faultsim_integrity_check435}436 437#-------------------------------------------------------------------------438# This test case is specially designed so that during a savepoint 439# rollback, a new cache entry must be allocated (see comments surrounding440# the call to sqlite3PagerAcquire() from within pager_playback_one_page()441# for details). Test the effects of injecting an OOM at this point.442#443do_test pagerfault-9-pre1 {444  faultsim_delete_and_reopen445  execsql {446    PRAGMA auto_vacuum = incremental;447    CREATE TABLE t1(x);448    CREATE TABLE t2(y);449    CREATE TABLE t3(z);450 451    INSERT INTO t1 VALUES(randomblob(900));452    INSERT INTO t1 VALUES(randomblob(900));453    DELETE FROM t1;454  }455  faultsim_save_and_close456} {}457do_faultsim_test pagerfault-9.1 -prep {458  faultsim_restore_and_reopen459  execsql { 460    BEGIN;461      INSERT INTO t1 VALUES(randomblob(900));462      INSERT INTO t1 VALUES(randomblob(900));463      DROP TABLE t3;464      DROP TABLE t2;465      SAVEPOINT abc;466        PRAGMA incremental_vacuum;467  }468} -body {469  execsql {470    ROLLBACK TO abc;471    COMMIT;472    PRAGMA freelist_count473  }474} -test {475  faultsim_test_result {0 2}476  faultsim_integrity_check477 478  set sl [db one { SELECT COALESCE(sum(length(x)), 'null') FROM t1 }]479  if {$sl!="null" && $sl!=1800} { 480    error "Content looks no good... ($sl)" 481  }482}483 484#-------------------------------------------------------------------------485# Test fault injection with a temporary database file.486#487foreach v {a b} {488  do_faultsim_test pagerfault-10$v -prep {489    sqlite3 db ""490    db func a_string a_string;491    execsql {492      PRAGMA cache_size = 10;493      BEGIN;494        CREATE TABLE xx(a, b, UNIQUE(a, b));495        INSERT INTO xx VALUES(a_string(200), a_string(200));496        INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;497        INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;498        INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;499        INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;500      COMMIT;501    }502  } -body {503    execsql { UPDATE xx SET a = a_string(300) }504  } -test {505    faultsim_test_result {0 {}}506    if {$::v == "b"} { execsql { PRAGMA journal_mode = TRUNCATE } }507    faultsim_integrity_check508    faultsim_integrity_check509  }510}511 512#-------------------------------------------------------------------------513# Test fault injection with transaction savepoints (savepoints created514# when a SAVEPOINT command is executed outside of any other savepoint515# or transaction context).516#517do_test pagerfault-9-pre1 {518  faultsim_delete_and_reopen519  db func a_string a_string;520  execsql {521    PRAGMA auto_vacuum = on;522    CREATE TABLE t1(x UNIQUE);523    CREATE TABLE t2(y UNIQUE);524    CREATE TABLE t3(z UNIQUE);525    BEGIN;526      INSERT INTO t1 VALUES(a_string(202));527      INSERT INTO t2 VALUES(a_string(203));528      INSERT INTO t3 VALUES(a_string(204));529      INSERT INTO t1 SELECT a_string(202) FROM t1;530      INSERT INTO t1 SELECT a_string(203) FROM t1;531      INSERT INTO t1 SELECT a_string(204) FROM t1;532      INSERT INTO t1 SELECT a_string(205) FROM t1;533      INSERT INTO t2 SELECT a_string(length(x)) FROM t1;534      INSERT INTO t3 SELECT a_string(length(x)) FROM t1;535    COMMIT;536  }537  faultsim_save_and_close538} {}539do_faultsim_test pagerfault-11 -prep {540  faultsim_restore_and_reopen541  execsql { PRAGMA cache_size = 10 }542} -body {543  execsql {544    SAVEPOINT trans;545      UPDATE t2 SET y = y||'2';546      INSERT INTO t3 SELECT * FROM t2;547      DELETE FROM t1;548    ROLLBACK TO trans;549    UPDATE t1 SET x = x||'3';550    INSERT INTO t2 SELECT * FROM t1;551    DELETE FROM t3;552    RELEASE trans;553  }554} -test {555  faultsim_test_result {0 {}}556  faultsim_integrity_check557}558 559 560#-------------------------------------------------------------------------561# Test fault injection when writing to a database file that resides on562# a file-system with a sector-size larger than the database page-size.563#564do_test pagerfault-12-pre1 {565  testvfs ss_layer -default 1566  ss_layer sectorsize 4096567  faultsim_delete_and_reopen568  db func a_string a_string;569 570  execsql {571    PRAGMA page_size = 1024;572    PRAGMA journal_mode = PERSIST;573    PRAGMA cache_size = 10;574    BEGIN;575      CREATE TABLE t1(x, y UNIQUE);576      INSERT INTO t1 VALUES(a_string(333), a_string(444));577      INSERT INTO t1 SELECT a_string(333+rowid), a_string(444+rowid) FROM t1;578      INSERT INTO t1 SELECT a_string(333+rowid), a_string(444+rowid) FROM t1;579      INSERT INTO t1 SELECT a_string(333+rowid), a_string(444+rowid) FROM t1;580      INSERT INTO t1 SELECT a_string(333+rowid), a_string(444+rowid) FROM t1;581      INSERT INTO t1 SELECT a_string(44), a_string(55) FROM t1 LIMIT 13;582    COMMIT;583  }584  faultsim_save_and_close585} {}586 587do_faultsim_test pagerfault-12a -prep {588  faultsim_restore_and_reopen589  execsql { PRAGMA cache_size = 10 }590  db func a_string a_string;591} -body {592  execsql {593    UPDATE t1 SET x = a_string(length(x)), y = a_string(length(y));594  }595} -test {596  faultsim_test_result {0 {}}597  faultsim_integrity_check598}599 600do_test pagerfault-12-pre2 {601  faultsim_restore_and_reopen602  execsql {603    CREATE TABLE t2 AS SELECT * FROM t1 LIMIT 10;604  }605  faultsim_save_and_close606} {}607do_faultsim_test pagerfault-12b -prep {608  faultsim_restore_and_reopen609  db func a_string a_string;610  execsql { SELECT * FROM t1 }611} -body {612  set sql(1) { UPDATE t2 SET x = a_string(280) }613  set sql(2) { UPDATE t1 SET x = a_string(280) WHERE rowid = 5 }614 615  db eval { SELECT rowid FROM t1 LIMIT 2 } { db eval $sql($rowid) }616 617} -test {618  faultsim_test_result {0 {}}619  faultsim_integrity_check620}621 622catch { db close }623ss_layer delete624 625 626#-------------------------------------------------------------------------627# Test fault injection when SQLite opens a database where the size of the628# database file is zero bytes but the accompanying journal file is larger629# than that. In this scenario SQLite should delete the journal file 630# without rolling it back, even if it is in all other respects a valid631# hot-journal file.632#633do_test pagerfault-13-pre1 {634  faultsim_delete_and_reopen635  db func a_string a_string;636  execsql {637    PRAGMA journal_mode = PERSIST;638    BEGIN;639      CREATE TABLE t1(x, y UNIQUE);640      INSERT INTO t1 VALUES(a_string(333), a_string(444));641    COMMIT;642  }643  db close644  forcedelete test.db645  faultsim_save646} {}647do_faultsim_test pagerfault-13 -prep {648  faultsim_restore_and_reopen649} -body {650  execsql { CREATE TABLE xx(a, b) }651} -test {652  faultsim_test_result {0 {}}653}654 655#---------------------------------------------------------------------------656# Test fault injection into a small backup operation.657#658do_test pagerfault-14-pre1 {659  faultsim_delete_and_reopen660  db func a_string a_string;661  execsql {662    PRAGMA journal_mode = PERSIST;663    ATTACH 'test.db2' AS two;664    BEGIN;665      CREATE TABLE t1(x, y UNIQUE);666      CREATE TABLE two.t2(x, y UNIQUE);667      INSERT INTO t1 VALUES(a_string(333), a_string(444));668      INSERT INTO t2 VALUES(a_string(333), a_string(444));669    COMMIT;670  }671  faultsim_save_and_close672} {}673 674do_faultsim_test pagerfault-14a -prep {675  faultsim_restore_and_reopen676} -body {677  if {[catch {db backup test.db2} msg]} { error [regsub {.*: } $msg {}] }678} -test {679  faultsim_test_result {0 {}} {1 {}} {1 {SQL logic error}}680}681 682# If TEMP_STORE is 2 or greater, then the database [db2] will be created683# as an in-memory database. This test will not work in that case, as it684# is not possible to change the page-size of an in-memory database. Even685# using the backup API.686#687# Update: It is no longer possible to change the page size of any temp688# database after it has been created.689#690do_faultsim_test pagerfault-14b -prep {691  catch { db2 close }692  faultsim_restore_and_reopen693    sqlite3 db2 ""694    db2 eval { PRAGMA page_size = 4096; CREATE TABLE xx(a) }695} -body {696  sqlite3_backup B db2 main db main697  B step 200698  set rc [B finish]699  if {[string match SQLITE_IOERR_* $rc]} {set rc SQLITE_IOERR}700  if {$rc != "SQLITE_OK"} { error [sqlite3_test_errstr $rc] }701  set {} {}702} -test {703  faultsim_test_result {1 {attempt to write a readonly database}} \704                       {1 {sqlite3_backup_init() failed}}705}706 707do_faultsim_test pagerfault-14c -prep {708  catch { db2 close }709  faultsim_restore_and_reopen710  sqlite3 db2 test.db2711  db2 eval { 712    PRAGMA synchronous = off; 713    PRAGMA page_size = 4096; 714    CREATE TABLE xx(a);715  }716} -body {717  sqlite3_backup B db2 main db main718  B step 200719  set rc [B finish]720  if {[string match SQLITE_IOERR_* $rc]} {set rc SQLITE_IOERR}721  if {$rc != "SQLITE_OK"} { error [sqlite3_test_errstr $rc] }722  set {} {}723} -test {724  faultsim_test_result {0 {}} {1 {sqlite3_backup_init() failed}}725}726 727do_test pagerfault-15-pre1 {728  faultsim_delete_and_reopen729  db func a_string a_string;730  execsql {731    BEGIN;732      CREATE TABLE t1(x, y UNIQUE);733      INSERT INTO t1 VALUES(a_string(11), a_string(22));734      INSERT INTO t1 VALUES(a_string(11), a_string(22));735    COMMIT;736  }737  faultsim_save_and_close738} {}739do_faultsim_test pagerfault-15 -prep {740  faultsim_restore_and_reopen741  db func a_string a_string;742} -body {743  db eval { SELECT * FROM t1 LIMIT 1 } {744    execsql {745      BEGIN; INSERT INTO t1 VALUES(a_string(333), a_string(555)); COMMIT;746      BEGIN; INSERT INTO t1 VALUES(a_string(333), a_string(555)); COMMIT;747    }748  }749} -test {750  faultsim_test_result {0 {}}751  faultsim_integrity_check752}753 754 755do_test pagerfault-16-pre1 {756  faultsim_delete_and_reopen757  execsql { CREATE TABLE t1(x, y UNIQUE) }758  faultsim_save_and_close759} {}760do_faultsim_test pagerfault-16 -prep {761  faultsim_restore_and_reopen762} -body {763  execsql {764    PRAGMA locking_mode = exclusive;765    PRAGMA journal_mode = wal;766    INSERT INTO t1 VALUES(1, 2);767    INSERT INTO t1 VALUES(3, 4);768    PRAGMA journal_mode = delete;769    INSERT INTO t1 VALUES(4, 5);770    PRAGMA journal_mode = wal;771    INSERT INTO t1 VALUES(6, 7);772    PRAGMA journal_mode = persist;773    INSERT INTO t1 VALUES(8, 9);774  }775} -test {776  faultsim_test_result {0 {exclusive wal delete wal persist}}777  faultsim_integrity_check778}779 780 781#-------------------------------------------------------------------------782# Test fault injection while changing into and out of WAL mode.783#784do_test pagerfault-17-pre1 {785  faultsim_delete_and_reopen786  execsql {787    CREATE TABLE t1(a PRIMARY KEY, b);788    INSERT INTO t1 VALUES(1862, 'Botha');789    INSERT INTO t1 VALUES(1870, 'Smuts');790    INSERT INTO t1 VALUES(1866, 'Hertzog');791  }792  faultsim_save_and_close793} {}794do_faultsim_test pagerfault-17a -prep {795  faultsim_restore_and_reopen796} -body {797  execsql {798    PRAGMA journal_mode = wal;799    PRAGMA journal_mode = delete;800  }801} -test {802  faultsim_test_result {0 {wal delete}}803  faultsim_integrity_check804}805do_faultsim_test pagerfault-17b -prep {806  faultsim_restore_and_reopen807  execsql { PRAGMA synchronous = OFF }808} -body {809  execsql {810    PRAGMA journal_mode = wal;811    INSERT INTO t1 VALUES(22, 'Clarke');812    PRAGMA journal_mode = delete;813  }814} -test {815  faultsim_test_result {0 {wal delete}}816  faultsim_integrity_check817}818do_faultsim_test pagerfault-17c -prep {819  faultsim_restore_and_reopen820  execsql { 821    PRAGMA locking_mode = exclusive;822    PRAGMA journal_mode = wal;823  }824} -body {825  execsql { PRAGMA journal_mode = delete }826} -test {827  faultsim_test_result {0 delete}828  faultsim_integrity_check829}830do_faultsim_test pagerfault-17d -prep {831  catch { db2 close }832  faultsim_restore_and_reopen833  sqlite3 db2 test.db834  execsql { PRAGMA journal_mode = delete }835  execsql { PRAGMA journal_mode = wal }836  execsql { INSERT INTO t1 VALUES(99, 'Bradman') } db2837} -body {838  execsql { PRAGMA journal_mode = delete }839} -test {840  faultsim_test_result {1 {database is locked}}841  faultsim_integrity_check842}843do_faultsim_test pagerfault-17e -prep {844  catch { db2 close }845  faultsim_restore_and_reopen846  sqlite3 db2 test.db847  execsql { PRAGMA journal_mode = delete }848  execsql { PRAGMA journal_mode = wal }849  set ::chan [launch_testfixture]850  testfixture $::chan {851    sqlite3 db test.db852    db eval { INSERT INTO t1 VALUES(101, 'Latham') }853  }854  catch { testfixture $::chan sqlite_abort }855  catch { close $::chan }856} -body {857  execsql { PRAGMA journal_mode = delete }858} -test {859  faultsim_test_result {0 delete}860  faultsim_integrity_check861}862 863#-------------------------------------------------------------------------864# Test fault-injection when changing from journal_mode=persist to 865# journal_mode=delete (this involves deleting the journal file).866#867do_test pagerfault-18-pre1 {868  faultsim_delete_and_reopen869  execsql {870    CREATE TABLE qq(x);871    INSERT INTO qq VALUES('Herbert');872    INSERT INTO qq VALUES('Macalister');873    INSERT INTO qq VALUES('Mackenzie');874    INSERT INTO qq VALUES('Lilley');875    INSERT INTO qq VALUES('Palmer');876  }877  faultsim_save_and_close878} {}879do_faultsim_test pagerfault-18 -prep {880  faultsim_restore_and_reopen881  execsql {882    PRAGMA journal_mode = PERSIST;883    INSERT INTO qq VALUES('Beatty');884  }885} -body {886  execsql { PRAGMA journal_mode = delete }887} -test {888  faultsim_test_result {0 delete}889  faultsim_integrity_check890}891 892do_faultsim_test pagerfault-19a -prep {893  sqlite3 db :memory:894  db func a_string a_string895  execsql {896    PRAGMA auto_vacuum = FULL;897    BEGIN;898      CREATE TABLE t1(a, b);899      INSERT INTO t1 VALUES(a_string(5000), a_string(6000));900    COMMIT;901  }902} -body {903  execsql { 904    CREATE TABLE t2(a, b);905    INSERT INTO t2 SELECT * FROM t1; 906    DELETE FROM t1;907  }908} -test {909  faultsim_test_result {0 {}}910}911 912do_test pagerfault-19-pre1 {913  faultsim_delete_and_reopen914  execsql {915    PRAGMA auto_vacuum = FULL;916    CREATE TABLE t1(x); INSERT INTO t1 VALUES(1);917    CREATE TABLE t2(x); INSERT INTO t2 VALUES(2);918    CREATE TABLE t3(x); INSERT INTO t3 VALUES(3);919    CREATE TABLE t4(x); INSERT INTO t4 VALUES(4);920    CREATE TABLE t5(x); INSERT INTO t5 VALUES(5);921    CREATE TABLE t6(x); INSERT INTO t6 VALUES(6);922  }923  faultsim_save_and_close924} {}925do_faultsim_test pagerfault-19b -prep {926  faultsim_restore_and_reopen927} -body {928  execsql { 929    BEGIN;930      UPDATE t4 SET x = x+1;931      UPDATE t6 SET x = x+1;932      SAVEPOINT one;933        UPDATE t3 SET x = x+1;934        SAVEPOINT two;935          DROP TABLE t2;936      ROLLBACK TO one;937    COMMIT;938    SELECT * FROM t3;939    SELECT * FROM t4;940    SELECT * FROM t6;941  }942} -test {943  faultsim_test_result {0 {3 5 7}}944}945 946#-------------------------------------------------------------------------947# This tests fault-injection in a special case in the auto-vacuum code.948#949do_test pagerfault-20-pre1 {950  faultsim_delete_and_reopen951  execsql {952    PRAGMA cache_size = 10;953    PRAGMA auto_vacuum = FULL;954    CREATE TABLE t0(a, b);955  }956  faultsim_save_and_close957} {}958do_faultsim_test pagerfault-20 -prep {959  faultsim_restore_and_reopen960} -body {961  execsql { 962    BEGIN;963      CREATE TABLE t1(a, b);964      CREATE TABLE t2(a, b);965      DROP TABLE t1;966    COMMIT;967  }968} -test {969  faultsim_test_result {0 {}}970}971 972do_test pagerfault-21-pre1 {973  faultsim_delete_and_reopen974  execsql {975    PRAGMA cache_size = 10;976    CREATE TABLE t0(a PRIMARY KEY, b);977    INSERT INTO t0 VALUES(1, 2);978  }979  faultsim_save_and_close980} {}981do_faultsim_test pagerfault-21 -prep {982  faultsim_restore_and_reopen983} -body {984  db eval { SELECT * FROM t0 LIMIT 1 } {985    db eval { INSERT INTO t0 SELECT a+1, b FROM t0 }986    db eval { INSERT INTO t0 SELECT a+2, b FROM t0 }987  }988} -test {989  faultsim_test_result {0 {}}990}991 992 993#-------------------------------------------------------------------------994# Test fault-injection and rollback when the nReserve header value 995# is non-zero.996#997do_test pagerfault-21-pre1 {998  faultsim_delete_and_reopen999  execsql {1000    PRAGMA page_size = 1024;1001    PRAGMA journal_mode = WAL;1002    PRAGMA journal_mode = DELETE;1003  }1004  db close1005  hexio_write test.db 20    101006  hexio_write test.db 105 03F01007  sqlite3 db test.db1008  db func a_string a_string1009  execsql {1010    CREATE TABLE t0(a PRIMARY KEY, b UNIQUE);1011    INSERT INTO t0 VALUES(a_string(222), a_string(333));1012    INSERT INTO t0 VALUES(a_string(223), a_string(334));1013    INSERT INTO t0 VALUES(a_string(224), a_string(335));1014    INSERT INTO t0 VALUES(a_string(225), a_string(336));1015  }1016  faultsim_save_and_close1017} {}1018 1019do_faultsim_test pagerfault-21 -prep {1020  faultsim_restore_and_reopen1021} -body {1022  execsql { INSERT INTO t0 SELECT a||'x', b||'x' FROM t0 }1023} -test {1024  faultsim_test_result {0 {}}1025  faultsim_integrity_check1026}1027ifcapable crashtest {1028  faultsim_delete_and_reopen1029  execsql {1030    PRAGMA page_size = 1024;1031    PRAGMA journal_mode = WAL;1032    PRAGMA journal_mode = DELETE;1033  }1034  db close1035  hexio_write test.db 20    101036  hexio_write test.db 105 03F01037 1038  sqlite3 db test.db1039  db func a_string a_string1040  execsql {1041    CREATE TABLE t0(a PRIMARY KEY, b UNIQUE);1042    INSERT INTO t0 VALUES(a_string(222), a_string(333));1043    INSERT INTO t0 VALUES(a_string(223), a_string(334));1044  }1045  faultsim_save_and_close1046 1047  for {set iTest 1} {$iTest<50} {incr iTest} {1048    do_test pagerfault-21.crash.$iTest.1 {1049      crashsql -delay 1 -file test.db -seed $iTest {1050        BEGIN;1051          CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);1052          INSERT INTO t1 SELECT a, b FROM t0;1053        COMMIT;1054      }1055    } {1 {child process exited abnormally}}1056    do_test pagerfault-22.$iTest.2 {1057      sqlite3 db test.db1058      execsql { PRAGMA integrity_check }1059    } {ok}1060    db close1061  }1062}1063 1064 1065#-------------------------------------------------------------------------1066# When a 3.7.0 client opens a write-transaction on a database file that1067# has been appended to or truncated by a pre-370 client, it updates1068# the db-size in the file header immediately. This test case provokes1069# errors during that operation.1070#1071do_test pagerfault-22-pre1 {1072  faultsim_delete_and_reopen1073  db func a_string a_string1074  execsql {1075    PRAGMA page_size = 1024;1076    PRAGMA auto_vacuum = 0;1077    CREATE TABLE t1(a);1078    CREATE INDEX i1 ON t1(a);1079    INSERT INTO t1 VALUES(a_string(3000));1080    CREATE TABLE t2(a);1081    INSERT INTO t2 VALUES(1);1082  }1083  db close1084  sql36231 { INSERT INTO t1 VALUES(a_string(3000)) }1085  faultsim_save_and_close1086} {}1087do_faultsim_test pagerfault-22 -prep {1088  faultsim_restore_and_reopen1089} -body {1090  execsql { INSERT INTO t2 VALUES(2) }1091  execsql { SELECT * FROM t2 }1092} -test {1093  faultsim_test_result {0 {1 2}}1094  faultsim_integrity_check1095}1096 1097#-------------------------------------------------------------------------1098# Provoke an OOM error during a commit of multi-file transaction. One of1099# the databases written during the transaction is an in-memory database.1100# This test causes rollback of the in-memory database after CommitPhaseOne()1101# has successfully returned. i.e. the series of calls for the aborted commit 1102# is:1103#1104#   PagerCommitPhaseOne(<in-memory-db>)   ->   SQLITE_OK1105#   PagerCommitPhaseOne(<file-db>)        ->   SQLITE_IOERR1106#   PagerRollback(<in-memory-db>)1107#   PagerRollback(<file-db>)1108#1109do_faultsim_test pagerfault-23 -prep {1110  sqlite3 db :memory:1111  foreach f [glob -nocomplain test.db*] { forcedelete $f }1112  db eval { 1113    ATTACH 'test.db2' AS aux;1114    CREATE TABLE t1(a, b);1115    CREATE TABLE aux.t2(a, b);1116  }1117} -body {1118  execsql { 1119    BEGIN;1120      INSERT INTO t1 VALUES(1,2);1121      INSERT INTO t2 VALUES(3,4); 1122    COMMIT;1123  }1124} -test {1125  faultsim_test_result {0 {}}1126  faultsim_integrity_check1127}1128 1129do_faultsim_test pagerfault-24 -prep {1130  faultsim_delete_and_reopen1131  db eval { PRAGMA temp_store = file }1132  execsql { CREATE TABLE x(a, b) }1133} -body {1134  execsql { CREATE TEMP TABLE t1(a, b) }1135} -test {1136  faultsim_test_result {0 {}} \1137    {1 {unable to open a temporary database file for storing temporary tables}}1138  set ic [db eval { PRAGMA temp.integrity_check }]1139  if {$ic != "ok"} { error "Integrity check: $ic" }1140}1141 1142proc lockrows {n} {1143  if {$n==0} { return "" }1144  db eval { SELECT * FROM t1 WHERE oid = $n } { 1145    return [lockrows [expr {$n-1}]]1146  }1147}1148 1149 1150do_test pagerfault-25-pre1 {1151  faultsim_delete_and_reopen1152  db func a_string a_string1153  execsql {1154    PRAGMA page_size = 1024;1155    PRAGMA auto_vacuum = 0;1156    CREATE TABLE t1(a);1157    INSERT INTO t1 VALUES(a_string(500));1158    INSERT INTO t1 SELECT a_string(500) FROM t1;1159    INSERT INTO t1 SELECT a_string(500) FROM t1;1160    INSERT INTO t1 SELECT a_string(500) FROM t1;1161    INSERT INTO t1 SELECT a_string(500) FROM t1;1162    INSERT INTO t1 SELECT a_string(500) FROM t1;1163  }1164  faultsim_save_and_close1165} {}1166do_faultsim_test pagerfault-25 -prep {1167  faultsim_restore_and_reopen1168  db func a_string a_string1169  set ::channel [db incrblob -readonly t1 a 1]1170  execsql { 1171    PRAGMA cache_size = 10;1172    BEGIN;1173      INSERT INTO t1 VALUES(a_string(3000));1174      INSERT INTO t1 VALUES(a_string(3000));1175  }1176} -body {1177  lockrows 301178} -test {1179  catch { lockrows 30 }1180  catch { db eval COMMIT }1181  close $::channel1182  faultsim_test_result {0 {}} 1183}1184 1185do_faultsim_test pagerfault-26 -prep {1186  faultsim_delete_and_reopen1187  execsql {1188    PRAGMA page_size = 1024;1189    PRAGMA journal_mode = truncate;1190    PRAGMA auto_vacuum = full;1191    PRAGMA locking_mode=exclusive;1192    CREATE TABLE t1(a, b);1193    INSERT INTO t1 VALUES(1, 2);1194    PRAGMA page_size = 4096;1195  }1196} -body {1197  execsql {1198    VACUUM;1199  }1200} -test {

Showing the first 1,200 of 1554 lines. Download the file for the rest.