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