Fix a case where a corrupt stat4 record could go unrecognized due to integer overflow.
[sqlite.git] / test / walmode.test
blobf760823c8d4980a0bdda5b70d81e0d18e02b6d8e
1 # 2010 April 19
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
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.
16 set testdir [file dirname $argv0]
17 source $testdir/tester.tcl
18 source $testdir/malloc_common.tcl
20 # If the library was compiled without WAL support, check that the 
21 # "PRAGMA journal_mode=WAL" treats "WAL" as an unrecognized mode.
23 ifcapable !wal {
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}
35   finish_test
36   return
39 do_test walmode-1.1 {
40   set sqlite_sync_count 0
41   execsql { PRAGMA page_size = 1024 }
42   execsql { PRAGMA journal_mode = wal }
43 } {wal}
44 do_test walmode-1.2 {
45   file size test.db
46 } {1024}
48 if {[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     }
54   }
55   do_test walmode-1.3 {
56     set sqlite_sync_count
57   } $expected_sync_count
60 do_test walmode-1.4 {
61   file exists test.db-wal
62 } {0}
63 do_test walmode-1.5 {
64   execsql { CREATE TABLE t1(a, b) }
65   file size test.db
66 } {1024}
67 do_test walmode-1.6 {
68   file exists test.db-wal
69 } {1}
70 do_test walmode-1.7 {
71   db close
72   file exists test.db-wal
73 } {0}
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.
78 do_test walmode-2.1 {
79   sqlite3 db test.db
80   file exists test.db-wal
81 } {0}
82 do_test walmode-2.2 {
83   execsql { SELECT * FROM sqlite_master }
84   file exists test.db-wal
85 } {1}
86 do_test walmode-2.3 {
87   db close
88   file exists test.db-wal
89 } {0}
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.
96 set sqlite_sync_count 0
97 do_test walmode-3.1 {
98   sqlite3 db test.db
99   execsql { PRAGMA journal_mode = wal }
100 } {wal}
101 do_test walmode-3.2 {
102   list $sqlite_sync_count [file exists test.db-wal] [file size test.db-wal]
103 } {0 1 0}
105 # Test that changing back to journal_mode=persist works.
107 do_test walmode-4.1 {
108   execsql { INSERT INTO t1 VALUES(1, 2) }
109   execsql { PRAGMA journal_mode = persist }
110 } {persist}
111 if {[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}
116 do_test walmode-4.3 {
117   execsql { SELECT * FROM t1 }
118 } {1 2}
119 do_test walmode-4.4 {
120   db close
121   sqlite3 db test.db
122   execsql { SELECT * FROM t1 }
123 } {1 2}
124 if {[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}
130 # 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.
134 do_test walmode-4.6 {
135   sqlite3 db2 test.db
136   execsql { PRAGMA main.journal_mode } db2
137 } {delete}
138 do_test walmode-4.7 {
139   execsql { PRAGMA main.journal_mode = wal } db
140 } {wal}
141 do_test walmode-4.8 {
142   execsql { SELECT * FROM t1 } db2
143 } {1 2}
144 do_test walmode-4.9 {
145   catchsql { PRAGMA journal_mode = delete } db
146 } {1 {database is locked}}
147 do_test walmode-4.10 {
148   execsql { PRAGMA main.journal_mode } db
149 } {wal}
151 do_test walmode-4.11 {
152   db2 close
153   execsql { PRAGMA journal_mode = delete } db
154 } {delete}
155 do_test walmode-4.12 {
156   execsql { PRAGMA main.journal_mode } db
157 } {delete}
158 do_test walmode-4.13 {
159   list [file exists test.db-journal] [file exists test.db-wal]
160 } {0 0}
161 do_test walmode-4.14 {
162   sqlite3 db2 test.db
163   execsql {
164     BEGIN;
165       SELECT * FROM t1;
166   } db2
167 } {1 2}
169 do_test walmode-4.16 { execsql { PRAGMA main.journal_mode } db  } {delete}
170 do_test walmode-4.17 { execsql { PRAGMA main.journal_mode } db2 } {delete}
172 do_test walmode-4.17 {
173   catchsql { PRAGMA main.journal_mode = wal } db
174 } {1 {database is locked}}
175 do_test walmode-4.18 {
176   execsql { PRAGMA main.journal_mode } db
177 } {delete}
178 catch { db close }
179 catch { db2 close }
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.
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.
188 do_test walmode-5.1.1 {
189   sqlite3 db :memory:
190   execsql { PRAGMA main.journal_mode }
191 } {memory}
192 do_test walmode-5.1.2 {
193   execsql { PRAGMA main.journal_mode = wal }
194 } {memory}
195 do_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}
205 do_test walmode-5.1.4 {
206   execsql { PRAGMA main.journal_mode = wal }
207 } {memory}
208 do_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}
216 if {$TEMP_STORE>=2} {
217   set tempJrnlMode memory
218 } else {
219   set tempJrnlMode delete
221 do_test walmode-5.2.1 {
222   sqlite3 db ""
223   execsql { PRAGMA main.journal_mode }
224 } $tempJrnlMode
225 do_test walmode-5.2.2 {
226   execsql { PRAGMA main.journal_mode = wal }
227 } $tempJrnlMode
228 do_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   }
237 } [list 1 2 $tempJrnlMode]
238 do_test walmode-5.2.4 {
239   execsql { PRAGMA main.journal_mode = wal }
240 } $tempJrnlMode
241 do_test walmode-5.2.5 {
242   execsql { 
243     INSERT INTO t1 VALUES(3, 4);
244     SELECT * FROM t1;
245     PRAGMA main.journal_mode;
246   }
247 } [list 1 2 3 4 $tempJrnlMode]
249 do_test walmode-5.3.1 {
250   sqlite3 db test.db
251   execsql { PRAGMA temp.journal_mode }
252 } $tempJrnlMode
253 do_test walmode-5.3.2 {
254   execsql { PRAGMA temp.journal_mode = wal }
255 } $tempJrnlMode
256 do_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   }
265 } [list 1 2 $tempJrnlMode]
266 do_test walmode-5.3.4 {
267   execsql { PRAGMA temp.journal_mode = wal }
268 } $tempJrnlMode
269 do_test walmode-5.3.5 {
270   execsql { 
271     INSERT INTO t1 VALUES(3, 4);
272     SELECT * FROM t1;
273     PRAGMA temp.journal_mode;
274   }
275 } [list 1 2 3 4 $tempJrnlMode]
278 #-------------------------------------------------------------------------
279 # Test changing to WAL mode from journal_mode=off or journal_mode=memory
281 foreach {tn mode} {
282   1 off
283   2 memory
284   3 persist
285   4 delete
286   5 truncate
287 } {
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]
296 db close
298 #-------------------------------------------------------------------------
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.
303 do_test walmode-7.0 {
304   forcedelete test.db
305   sqlite3 db test.db
306   execsql {
307     PRAGMA journal_mode = WAL;
308     CREATE TABLE t1(a, b);
309   }
310 } {wal}
311 foreach {tn sql result} {
312   1  "PRAGMA journal_mode"                wal
313   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
318   7  "PRAGMA journal_mode"                wal
319   8  "PRAGMA main.journal_mode"           wal
321   9  "PRAGMA journal_mode"                wal
322  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
327  15  "PRAGMA journal_mode"                wal
328  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
336 db close
338 #-------------------------------------------------------------------------
339 # Test the effect of a "PRAGMA journal_mode" command on an attached 
340 # database.
342 faultsim_delete_and_reopen
343 do_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}
349 do_execsql_test walmode-8.2 { PRAGMA main.journal_mode }         {wal}
350 do_execsql_test walmode-8.3 { PRAGMA two.journal_mode  }         {delete}
351 do_execsql_test walmode-8.4 { PRAGMA two.journal_mode = DELETE } {delete}
353 db close
354 sqlite3 db test.db
355 do_execsql_test walmode-8.5  { ATTACH 'test.db2' AS two }          {}
356 do_execsql_test walmode-8.6  { PRAGMA main.journal_mode }          {wal}
357 do_execsql_test walmode-8.7  { PRAGMA two.journal_mode  }          {delete}
358 do_execsql_test walmode-8.8  { INSERT INTO two.t2 DEFAULT VALUES } {}
359 do_execsql_test walmode-8.9  { PRAGMA two.journal_mode  }          {delete}
360 do_execsql_test walmode-8.10 { INSERT INTO t1 DEFAULT VALUES } {}
361 do_execsql_test walmode-8.11 { PRAGMA main.journal_mode  }         {wal}
362 do_execsql_test walmode-8.12 { PRAGMA journal_mode  }              {wal}
364 # Change to WAL mode on test2.db and make sure (in the tests that follow)
365 # that this mode change persists. 
366 do_test walmode-8.x1 {
367   execsql {
368      PRAGMA two.journal_mode=WAL;
369      PRAGMA two.journal_mode;
370   }
371 } {wal wal}
373 db close
374 sqlite3 db test.db
375 do_execsql_test walmode-8.13 { PRAGMA journal_mode = WAL }         {wal}
376 do_execsql_test walmode-8.14 { ATTACH 'test.db2' AS two  }         {}
377 do_execsql_test walmode-8.15 { PRAGMA main.journal_mode  }         {wal}
378 do_execsql_test walmode-8.16 { PRAGMA two.journal_mode   }         {wal}
379 do_execsql_test walmode-8.17 { INSERT INTO two.t2 DEFAULT VALUES } {}
380 do_execsql_test walmode-8.18 { PRAGMA two.journal_mode   }         {wal}
382 sqlite3 db2 test.db2
383 do_test walmode-8.19 { execsql { PRAGMA main.journal_mode } db2 }  {wal}
384 db2 close
386 do_execsql_test walmode-8.20 { PRAGMA journal_mode = DELETE } {delete}
387 do_execsql_test walmode-8.21 { PRAGMA main.journal_mode }     {delete}
388 do_execsql_test walmode-8.22 { PRAGMA two.journal_mode }      {delete}
389 do_execsql_test walmode-8.21 { PRAGMA journal_mode = WAL }    {wal}
390 do_execsql_test walmode-8.21 { PRAGMA main.journal_mode }     {wal}
391 do_execsql_test walmode-8.22 { PRAGMA two.journal_mode }      {wal}
393 finish_test