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