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