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