blob: f760823c8d4980a0bdda5b70d81e0d18e02b6d8e [file] [log] [blame]
dane04dc882010-04-20 18:53:15 +00001# 2010 April 19
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# This file implements regression tests for SQLite library. The
12# focus of this file is testing the operation of the library in
13# "PRAGMA journal_mode=WAL" mode.
14#
15
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
dan3f94b602010-07-03 13:45:52 +000018source $testdir/malloc_common.tcl
dane04dc882010-04-20 18:53:15 +000019
dan5cf53532010-05-01 16:40:20 +000020# If the library was compiled without WAL support, check that the
21# "PRAGMA journal_mode=WAL" treats "WAL" as an unrecognized mode.
22#
23ifcapable !wal {
24
25 do_test walmode-0.1 {
26 execsql { PRAGMA journal_mode = wal }
27 } {delete}
28 do_test walmode-0.2 {
29 execsql { PRAGMA main.journal_mode = wal }
30 } {delete}
31 do_test walmode-0.3 {
32 execsql { PRAGMA main.journal_mode }
33 } {delete}
34
35 finish_test
36 return
37}
38
dane04dc882010-04-20 18:53:15 +000039do_test walmode-1.1 {
danb9780022010-04-21 18:37:57 +000040 set sqlite_sync_count 0
41 execsql { PRAGMA page_size = 1024 }
42 execsql { PRAGMA journal_mode = wal }
dane04dc882010-04-20 18:53:15 +000043} {wal}
danb9780022010-04-21 18:37:57 +000044do_test walmode-1.2 {
45 file size test.db
46} {1024}
shaneha10069d2010-05-11 02:46:16 +000047
dan69aedc82018-01-13 13:07:49 +000048if {[atomic_batch_write test.db]==0} {
49 set expected_sync_count 3
50 if {$::tcl_platform(platform)!="windows"} {
51 ifcapable dirsync {
52 incr expected_sync_count
53 }
shaneha10069d2010-05-11 02:46:16 +000054 }
dan69aedc82018-01-13 13:07:49 +000055 do_test walmode-1.3 {
56 set sqlite_sync_count
57 } $expected_sync_count
shaneha10069d2010-05-11 02:46:16 +000058}
shaneha10069d2010-05-11 02:46:16 +000059
danb9780022010-04-21 18:37:57 +000060do_test walmode-1.4 {
61 file exists test.db-wal
62} {0}
63do_test walmode-1.5 {
64 execsql { CREATE TABLE t1(a, b) }
65 file size test.db
66} {1024}
67do_test walmode-1.6 {
68 file exists test.db-wal
69} {1}
70do_test walmode-1.7 {
71 db close
72 file exists test.db-wal
73} {0}
74
75# There is now a database file with the read and write versions set to 2
76# in the file system. This file should default to WAL mode.
77#
78do_test walmode-2.1 {
79 sqlite3 db test.db
80 file exists test.db-wal
81} {0}
82do_test walmode-2.2 {
83 execsql { SELECT * FROM sqlite_master }
84 file exists test.db-wal
85} {1}
86do_test walmode-2.3 {
87 db close
88 file exists test.db-wal
89} {0}
90
91# If the first statement executed is "PRAGMA journal_mode = wal", and
92# the file is already configured for WAL (read and write versions set
93# to 2), then there should be no need to write the database. The
94# statement should cause the client to connect to the log file.
95#
96set sqlite_sync_count 0
97do_test walmode-3.1 {
98 sqlite3 db test.db
99 execsql { PRAGMA journal_mode = wal }
100} {wal}
101do_test walmode-3.2 {
102 list $sqlite_sync_count [file exists test.db-wal] [file size test.db-wal]
103} {0 1 0}
104
danede6eb82010-04-22 06:27:04 +0000105# Test that changing back to journal_mode=persist works.
106#
danb9780022010-04-21 18:37:57 +0000107do_test walmode-4.1 {
108 execsql { INSERT INTO t1 VALUES(1, 2) }
109 execsql { PRAGMA journal_mode = persist }
110} {persist}
dan69aedc82018-01-13 13:07:49 +0000111if {[atomic_batch_write test.db]==0} {
112 do_test walmode-4.2 {
113 list [file exists test.db-journal] [file exists test.db-wal]
114 } {1 0}
115}
danb9780022010-04-21 18:37:57 +0000116do_test walmode-4.3 {
117 execsql { SELECT * FROM t1 }
118} {1 2}
119do_test walmode-4.4 {
120 db close
121 sqlite3 db test.db
122 execsql { SELECT * FROM t1 }
123} {1 2}
dan69aedc82018-01-13 13:07:49 +0000124if {[atomic_batch_write test.db]==0} {
125 do_test walmode-4.5 {
126 list [file exists test.db-journal] [file exists test.db-wal]
127 } {1 0}
128}
dane04dc882010-04-20 18:53:15 +0000129
danede6eb82010-04-22 06:27:04 +0000130# Test that nothing goes wrong if a connection is prevented from changing
131# from WAL to rollback mode because a second connection has the database
132# open. Or from rollback to WAL.
133#
dand956efe2010-06-18 16:13:45 +0000134do_test walmode-4.6 {
danede6eb82010-04-22 06:27:04 +0000135 sqlite3 db2 test.db
136 execsql { PRAGMA main.journal_mode } db2
137} {delete}
dand956efe2010-06-18 16:13:45 +0000138do_test walmode-4.7 {
danede6eb82010-04-22 06:27:04 +0000139 execsql { PRAGMA main.journal_mode = wal } db
140} {wal}
dand956efe2010-06-18 16:13:45 +0000141do_test walmode-4.8 {
danede6eb82010-04-22 06:27:04 +0000142 execsql { SELECT * FROM t1 } db2
143} {1 2}
dand956efe2010-06-18 16:13:45 +0000144do_test walmode-4.9 {
danede6eb82010-04-22 06:27:04 +0000145 catchsql { PRAGMA journal_mode = delete } db
146} {1 {database is locked}}
dand956efe2010-06-18 16:13:45 +0000147do_test walmode-4.10 {
danede6eb82010-04-22 06:27:04 +0000148 execsql { PRAGMA main.journal_mode } db
149} {wal}
dand956efe2010-06-18 16:13:45 +0000150
151do_test walmode-4.11 {
danede6eb82010-04-22 06:27:04 +0000152 db2 close
153 execsql { PRAGMA journal_mode = delete } db
154} {delete}
dand956efe2010-06-18 16:13:45 +0000155do_test walmode-4.12 {
danede6eb82010-04-22 06:27:04 +0000156 execsql { PRAGMA main.journal_mode } db
157} {delete}
dand956efe2010-06-18 16:13:45 +0000158do_test walmode-4.13 {
danede6eb82010-04-22 06:27:04 +0000159 list [file exists test.db-journal] [file exists test.db-wal]
160} {0 0}
dand956efe2010-06-18 16:13:45 +0000161do_test walmode-4.14 {
danede6eb82010-04-22 06:27:04 +0000162 sqlite3 db2 test.db
163 execsql {
164 BEGIN;
165 SELECT * FROM t1;
166 } db2
167} {1 2}
dand956efe2010-06-18 16:13:45 +0000168
169do_test walmode-4.16 { execsql { PRAGMA main.journal_mode } db } {delete}
170do_test walmode-4.17 { execsql { PRAGMA main.journal_mode } db2 } {delete}
171
172do_test walmode-4.17 {
danede6eb82010-04-22 06:27:04 +0000173 catchsql { PRAGMA main.journal_mode = wal } db
174} {1 {database is locked}}
dand956efe2010-06-18 16:13:45 +0000175do_test walmode-4.18 {
danede6eb82010-04-22 06:27:04 +0000176 execsql { PRAGMA main.journal_mode } db
177} {delete}
danede6eb82010-04-22 06:27:04 +0000178catch { db close }
179catch { db2 close }
dane180c292010-04-26 17:42:56 +0000180
181# Test that it is not possible to change a temporary or in-memory database
182# to WAL mode. WAL mode is for persistent file-backed databases only.
183#
184# walmode-5.1.*: Try to set journal_mode=WAL on [sqlite3 db :memory:] database.
185# walmode-5.2.*: Try to set journal_mode=WAL on [sqlite3 db ""] database.
186# walmode-5.3.*: Try to set temp.journal_mode=WAL.
187#
188do_test walmode-5.1.1 {
189 sqlite3 db :memory:
190 execsql { PRAGMA main.journal_mode }
191} {memory}
192do_test walmode-5.1.2 {
193 execsql { PRAGMA main.journal_mode = wal }
194} {memory}
195do_test walmode-5.1.3 {
196 execsql {
197 BEGIN;
198 CREATE TABLE t1(a, b);
199 INSERT INTO t1 VALUES(1, 2);
200 COMMIT;
201 SELECT * FROM t1;
202 PRAGMA main.journal_mode;
203 }
204} {1 2 memory}
205do_test walmode-5.1.4 {
206 execsql { PRAGMA main.journal_mode = wal }
207} {memory}
208do_test walmode-5.1.5 {
209 execsql {
210 INSERT INTO t1 VALUES(3, 4);
211 SELECT * FROM t1;
212 PRAGMA main.journal_mode;
213 }
214} {1 2 3 4 memory}
215
dan45656822010-09-13 19:03:38 +0000216if {$TEMP_STORE>=2} {
217 set tempJrnlMode memory
218} else {
219 set tempJrnlMode delete
220}
dane180c292010-04-26 17:42:56 +0000221do_test walmode-5.2.1 {
222 sqlite3 db ""
223 execsql { PRAGMA main.journal_mode }
dan45656822010-09-13 19:03:38 +0000224} $tempJrnlMode
dane180c292010-04-26 17:42:56 +0000225do_test walmode-5.2.2 {
226 execsql { PRAGMA main.journal_mode = wal }
dan45656822010-09-13 19:03:38 +0000227} $tempJrnlMode
dane180c292010-04-26 17:42:56 +0000228do_test walmode-5.2.3 {
229 execsql {
230 BEGIN;
231 CREATE TABLE t1(a, b);
232 INSERT INTO t1 VALUES(1, 2);
233 COMMIT;
234 SELECT * FROM t1;
235 PRAGMA main.journal_mode;
236 }
dan45656822010-09-13 19:03:38 +0000237} [list 1 2 $tempJrnlMode]
dane180c292010-04-26 17:42:56 +0000238do_test walmode-5.2.4 {
239 execsql { PRAGMA main.journal_mode = wal }
dan45656822010-09-13 19:03:38 +0000240} $tempJrnlMode
dane180c292010-04-26 17:42:56 +0000241do_test walmode-5.2.5 {
242 execsql {
243 INSERT INTO t1 VALUES(3, 4);
244 SELECT * FROM t1;
245 PRAGMA main.journal_mode;
246 }
dan45656822010-09-13 19:03:38 +0000247} [list 1 2 3 4 $tempJrnlMode]
dane180c292010-04-26 17:42:56 +0000248
249do_test walmode-5.3.1 {
250 sqlite3 db test.db
251 execsql { PRAGMA temp.journal_mode }
drhd80b2332010-05-01 00:59:37 +0000252} $tempJrnlMode
dane180c292010-04-26 17:42:56 +0000253do_test walmode-5.3.2 {
254 execsql { PRAGMA temp.journal_mode = wal }
drhd80b2332010-05-01 00:59:37 +0000255} $tempJrnlMode
dane180c292010-04-26 17:42:56 +0000256do_test walmode-5.3.3 {
257 execsql {
258 BEGIN;
259 CREATE TEMP TABLE t1(a, b);
260 INSERT INTO t1 VALUES(1, 2);
261 COMMIT;
262 SELECT * FROM t1;
263 PRAGMA temp.journal_mode;
264 }
drhd80b2332010-05-01 00:59:37 +0000265} [list 1 2 $tempJrnlMode]
dane180c292010-04-26 17:42:56 +0000266do_test walmode-5.3.4 {
267 execsql { PRAGMA temp.journal_mode = wal }
drhd80b2332010-05-01 00:59:37 +0000268} $tempJrnlMode
dane180c292010-04-26 17:42:56 +0000269do_test walmode-5.3.5 {
270 execsql {
271 INSERT INTO t1 VALUES(3, 4);
272 SELECT * FROM t1;
273 PRAGMA temp.journal_mode;
274 }
drhd80b2332010-05-01 00:59:37 +0000275} [list 1 2 3 4 $tempJrnlMode]
dane180c292010-04-26 17:42:56 +0000276
dan3f94b602010-07-03 13:45:52 +0000277
278#-------------------------------------------------------------------------
279# Test changing to WAL mode from journal_mode=off or journal_mode=memory
280#
281foreach {tn mode} {
danf6c61472010-07-07 13:54:28 +0000282 1 off
283 2 memory
dan3f94b602010-07-03 13:45:52 +0000284 3 persist
285 4 delete
286 5 truncate
dan3f94b602010-07-03 13:45:52 +0000287} {
288 do_test walmode-6.$tn {
289 faultsim_delete_and_reopen
290 execsql "
291 PRAGMA journal_mode = $mode;
292 PRAGMA journal_mode = wal;
293 "
294 } [list $mode wal]
295}
danf6c61472010-07-07 13:54:28 +0000296db close
297
dan8700b1e2010-07-08 06:22:25 +0000298#-------------------------------------------------------------------------
299# Test the effect of a "PRAGMA journal_mode" command being the first
300# thing executed by a new connection. This means that the schema is not
301# loaded when sqlite3_prepare_v2() is called to compile the statement.
302#
danf6c61472010-07-07 13:54:28 +0000303do_test walmode-7.0 {
mistachkinfda06be2011-08-02 00:57:34 +0000304 forcedelete test.db
danf6c61472010-07-07 13:54:28 +0000305 sqlite3 db test.db
306 execsql {
307 PRAGMA journal_mode = WAL;
308 CREATE TABLE t1(a, b);
309 }
310} {wal}
311foreach {tn sql result} {
drhc6b2a0f2010-07-08 17:40:37 +0000312 1 "PRAGMA journal_mode" wal
danf6c61472010-07-07 13:54:28 +0000313 2 "PRAGMA main.journal_mode" wal
314 3 "PRAGMA journal_mode = delete" delete
315 4 "PRAGMA journal_mode" delete
316 5 "PRAGMA main.journal_mode" delete
317 6 "PRAGMA journal_mode = wal" wal
drhc6b2a0f2010-07-08 17:40:37 +0000318 7 "PRAGMA journal_mode" wal
danf6c61472010-07-07 13:54:28 +0000319 8 "PRAGMA main.journal_mode" wal
320
drhc6b2a0f2010-07-08 17:40:37 +0000321 9 "PRAGMA journal_mode" wal
danf6c61472010-07-07 13:54:28 +0000322 10 "PRAGMA main.journal_mode" wal
323 11 "PRAGMA main.journal_mode = delete" delete
324 12 "PRAGMA journal_mode" delete
325 13 "PRAGMA main.journal_mode" delete
326 14 "PRAGMA main.journal_mode = wal" wal
drhc6b2a0f2010-07-08 17:40:37 +0000327 15 "PRAGMA journal_mode" wal
danf6c61472010-07-07 13:54:28 +0000328 16 "PRAGMA main.journal_mode" wal
329} {
330 do_test walmode-7.$tn {
331 db close
332 sqlite3 db test.db
333 execsql $sql
334 } $result
335}
336db close
dan3f94b602010-07-03 13:45:52 +0000337
dan8700b1e2010-07-08 06:22:25 +0000338#-------------------------------------------------------------------------
339# Test the effect of a "PRAGMA journal_mode" command on an attached
340# database.
341#
342faultsim_delete_and_reopen
343do_execsql_test walmode-8.1 {
344 CREATE TABLE t1(a, b);
345 PRAGMA journal_mode = WAL;
346 ATTACH 'test.db2' AS two;
347 CREATE TABLE two.t2(a, b);
348} {wal}
349do_execsql_test walmode-8.2 { PRAGMA main.journal_mode } {wal}
drhc6b2a0f2010-07-08 17:40:37 +0000350do_execsql_test walmode-8.3 { PRAGMA two.journal_mode } {delete}
dan8700b1e2010-07-08 06:22:25 +0000351do_execsql_test walmode-8.4 { PRAGMA two.journal_mode = DELETE } {delete}
352
353db close
354sqlite3 db test.db
355do_execsql_test walmode-8.5 { ATTACH 'test.db2' AS two } {}
356do_execsql_test walmode-8.6 { PRAGMA main.journal_mode } {wal}
357do_execsql_test walmode-8.7 { PRAGMA two.journal_mode } {delete}
358do_execsql_test walmode-8.8 { INSERT INTO two.t2 DEFAULT VALUES } {}
359do_execsql_test walmode-8.9 { PRAGMA two.journal_mode } {delete}
360do_execsql_test walmode-8.10 { INSERT INTO t1 DEFAULT VALUES } {}
361do_execsql_test walmode-8.11 { PRAGMA main.journal_mode } {wal}
drhc6b2a0f2010-07-08 17:40:37 +0000362do_execsql_test walmode-8.12 { PRAGMA journal_mode } {wal}
363
364# Change to WAL mode on test2.db and make sure (in the tests that follow)
365# that this mode change persists.
366do_test walmode-8.x1 {
367 execsql {
368 PRAGMA two.journal_mode=WAL;
369 PRAGMA two.journal_mode;
370 }
371} {wal wal}
dan8700b1e2010-07-08 06:22:25 +0000372
373db close
374sqlite3 db test.db
375do_execsql_test walmode-8.13 { PRAGMA journal_mode = WAL } {wal}
376do_execsql_test walmode-8.14 { ATTACH 'test.db2' AS two } {}
377do_execsql_test walmode-8.15 { PRAGMA main.journal_mode } {wal}
378do_execsql_test walmode-8.16 { PRAGMA two.journal_mode } {wal}
379do_execsql_test walmode-8.17 { INSERT INTO two.t2 DEFAULT VALUES } {}
380do_execsql_test walmode-8.18 { PRAGMA two.journal_mode } {wal}
381
382sqlite3 db2 test.db2
383do_test walmode-8.19 { execsql { PRAGMA main.journal_mode } db2 } {wal}
384db2 close
385
dan73d66fd2010-08-07 16:17:48 +0000386do_execsql_test walmode-8.20 { PRAGMA journal_mode = DELETE } {delete}
387do_execsql_test walmode-8.21 { PRAGMA main.journal_mode } {delete}
388do_execsql_test walmode-8.22 { PRAGMA two.journal_mode } {delete}
389do_execsql_test walmode-8.21 { PRAGMA journal_mode = WAL } {wal}
390do_execsql_test walmode-8.21 { PRAGMA main.journal_mode } {wal}
391do_execsql_test walmode-8.22 { PRAGMA two.journal_mode } {wal}
392
dane04dc882010-04-20 18:53:15 +0000393finish_test