xref: /sqlite-3.40.0/test/walmode.test (revision 69aedc8d)
1e04dc88bSdan# 2010 April 19
2e04dc88bSdan#
3e04dc88bSdan# The author disclaims copyright to this source code.  In place of
4e04dc88bSdan# a legal notice, here is a blessing:
5e04dc88bSdan#
6e04dc88bSdan#    May you do good and not evil.
7e04dc88bSdan#    May you find forgiveness for yourself and forgive others.
8e04dc88bSdan#    May you share freely, never taking more than you give.
9e04dc88bSdan#
10e04dc88bSdan#***********************************************************************
11e04dc88bSdan# This file implements regression tests for SQLite library.  The
12e04dc88bSdan# focus of this file is testing the operation of the library in
13e04dc88bSdan# "PRAGMA journal_mode=WAL" mode.
14e04dc88bSdan#
15e04dc88bSdan
16e04dc88bSdanset testdir [file dirname $argv0]
17e04dc88bSdansource $testdir/tester.tcl
183f94b609Sdansource $testdir/malloc_common.tcl
19e04dc88bSdan
205cf53537Sdan# If the library was compiled without WAL support, check that the
215cf53537Sdan# "PRAGMA journal_mode=WAL" treats "WAL" as an unrecognized mode.
225cf53537Sdan#
235cf53537Sdanifcapable !wal {
245cf53537Sdan
255cf53537Sdan  do_test walmode-0.1 {
265cf53537Sdan    execsql { PRAGMA journal_mode = wal }
275cf53537Sdan  } {delete}
285cf53537Sdan  do_test walmode-0.2 {
295cf53537Sdan    execsql { PRAGMA main.journal_mode = wal }
305cf53537Sdan  } {delete}
315cf53537Sdan  do_test walmode-0.3 {
325cf53537Sdan    execsql { PRAGMA main.journal_mode }
335cf53537Sdan  } {delete}
345cf53537Sdan
355cf53537Sdan  finish_test
365cf53537Sdan  return
375cf53537Sdan}
385cf53537Sdan
39e04dc88bSdando_test walmode-1.1 {
40b9780027Sdan  set sqlite_sync_count 0
41b9780027Sdan  execsql { PRAGMA page_size = 1024 }
42b9780027Sdan  execsql { PRAGMA journal_mode = wal }
43e04dc88bSdan} {wal}
44b9780027Sdando_test walmode-1.2 {
45b9780027Sdan  file size test.db
46b9780027Sdan} {1024}
47a10069ddSshaneh
48*69aedc8dSdanif {[atomic_batch_write test.db]==0} {
49a10069ddSshaneh  set expected_sync_count 3
50a10069ddSshaneh  if {$::tcl_platform(platform)!="windows"} {
51a10069ddSshaneh    ifcapable dirsync {
52a10069ddSshaneh      incr expected_sync_count
53a10069ddSshaneh    }
54a10069ddSshaneh  }
55b9780027Sdan  do_test walmode-1.3 {
56b9780027Sdan    set sqlite_sync_count
57a10069ddSshaneh  } $expected_sync_count
58*69aedc8dSdan}
59a10069ddSshaneh
60b9780027Sdando_test walmode-1.4 {
61b9780027Sdan  file exists test.db-wal
62b9780027Sdan} {0}
63b9780027Sdando_test walmode-1.5 {
64b9780027Sdan  execsql { CREATE TABLE t1(a, b) }
65b9780027Sdan  file size test.db
66b9780027Sdan} {1024}
67b9780027Sdando_test walmode-1.6 {
68b9780027Sdan  file exists test.db-wal
69b9780027Sdan} {1}
70b9780027Sdando_test walmode-1.7 {
71b9780027Sdan  db close
72b9780027Sdan  file exists test.db-wal
73b9780027Sdan} {0}
74b9780027Sdan
75b9780027Sdan# There is now a database file with the read and write versions set to 2
76b9780027Sdan# in the file system. This file should default to WAL mode.
77b9780027Sdan#
78b9780027Sdando_test walmode-2.1 {
79b9780027Sdan  sqlite3 db test.db
80b9780027Sdan  file exists test.db-wal
81b9780027Sdan} {0}
82b9780027Sdando_test walmode-2.2 {
83b9780027Sdan  execsql { SELECT * FROM sqlite_master }
84b9780027Sdan  file exists test.db-wal
85b9780027Sdan} {1}
86b9780027Sdando_test walmode-2.3 {
87b9780027Sdan  db close
88b9780027Sdan  file exists test.db-wal
89b9780027Sdan} {0}
90b9780027Sdan
91b9780027Sdan# If the first statement executed is "PRAGMA journal_mode = wal", and
92b9780027Sdan# the file is already configured for WAL (read and write versions set
93b9780027Sdan# to 2), then there should be no need to write the database. The
94b9780027Sdan# statement should cause the client to connect to the log file.
95b9780027Sdan#
96b9780027Sdanset sqlite_sync_count 0
97b9780027Sdando_test walmode-3.1 {
98b9780027Sdan  sqlite3 db test.db
99b9780027Sdan  execsql { PRAGMA journal_mode = wal }
100b9780027Sdan} {wal}
101b9780027Sdando_test walmode-3.2 {
102b9780027Sdan  list $sqlite_sync_count [file exists test.db-wal] [file size test.db-wal]
103b9780027Sdan} {0 1 0}
104b9780027Sdan
105ede6eb8dSdan# Test that changing back to journal_mode=persist works.
106ede6eb8dSdan#
107b9780027Sdando_test walmode-4.1 {
108b9780027Sdan  execsql { INSERT INTO t1 VALUES(1, 2) }
109b9780027Sdan  execsql { PRAGMA journal_mode = persist }
110b9780027Sdan} {persist}
111*69aedc8dSdanif {[atomic_batch_write test.db]==0} {
112b9780027Sdan  do_test walmode-4.2 {
113b9780027Sdan    list [file exists test.db-journal] [file exists test.db-wal]
114b9780027Sdan  } {1 0}
115*69aedc8dSdan}
116b9780027Sdando_test walmode-4.3 {
117b9780027Sdan  execsql { SELECT * FROM t1 }
118b9780027Sdan} {1 2}
119b9780027Sdando_test walmode-4.4 {
120b9780027Sdan  db close
121b9780027Sdan  sqlite3 db test.db
122b9780027Sdan  execsql { SELECT * FROM t1 }
123b9780027Sdan} {1 2}
124*69aedc8dSdanif {[atomic_batch_write test.db]==0} {
125b9780027Sdan  do_test walmode-4.5 {
126b9780027Sdan    list [file exists test.db-journal] [file exists test.db-wal]
127b9780027Sdan  } {1 0}
128*69aedc8dSdan}
129e04dc88bSdan
130ede6eb8dSdan# Test that nothing goes wrong if a connection is prevented from changing
131ede6eb8dSdan# from WAL to rollback mode because a second connection has the database
132ede6eb8dSdan# open. Or from rollback to WAL.
133ede6eb8dSdan#
134d956efebSdando_test walmode-4.6 {
135ede6eb8dSdan  sqlite3 db2 test.db
136ede6eb8dSdan  execsql { PRAGMA main.journal_mode } db2
137ede6eb8dSdan} {delete}
138d956efebSdando_test walmode-4.7 {
139ede6eb8dSdan  execsql { PRAGMA main.journal_mode = wal } db
140ede6eb8dSdan} {wal}
141d956efebSdando_test walmode-4.8 {
142ede6eb8dSdan  execsql { SELECT * FROM t1 } db2
143ede6eb8dSdan} {1 2}
144d956efebSdando_test walmode-4.9 {
145ede6eb8dSdan  catchsql { PRAGMA journal_mode = delete } db
146ede6eb8dSdan} {1 {database is locked}}
147d956efebSdando_test walmode-4.10 {
148ede6eb8dSdan  execsql { PRAGMA main.journal_mode } db
149ede6eb8dSdan} {wal}
150d956efebSdan
151d956efebSdando_test walmode-4.11 {
152ede6eb8dSdan  db2 close
153ede6eb8dSdan  execsql { PRAGMA journal_mode = delete } db
154ede6eb8dSdan} {delete}
155d956efebSdando_test walmode-4.12 {
156ede6eb8dSdan  execsql { PRAGMA main.journal_mode } db
157ede6eb8dSdan} {delete}
158d956efebSdando_test walmode-4.13 {
159ede6eb8dSdan  list [file exists test.db-journal] [file exists test.db-wal]
160ede6eb8dSdan} {0 0}
161d956efebSdando_test walmode-4.14 {
162ede6eb8dSdan  sqlite3 db2 test.db
163ede6eb8dSdan  execsql {
164ede6eb8dSdan    BEGIN;
165ede6eb8dSdan      SELECT * FROM t1;
166ede6eb8dSdan  } db2
167ede6eb8dSdan} {1 2}
168d956efebSdan
169d956efebSdando_test walmode-4.16 { execsql { PRAGMA main.journal_mode } db  } {delete}
170d956efebSdando_test walmode-4.17 { execsql { PRAGMA main.journal_mode } db2 } {delete}
171d956efebSdan
172d956efebSdando_test walmode-4.17 {
173ede6eb8dSdan  catchsql { PRAGMA main.journal_mode = wal } db
174ede6eb8dSdan} {1 {database is locked}}
175d956efebSdando_test walmode-4.18 {
176ede6eb8dSdan  execsql { PRAGMA main.journal_mode } db
177ede6eb8dSdan} {delete}
178ede6eb8dSdancatch { db close }
179ede6eb8dSdancatch { db2 close }
180e180c296Sdan
181e180c296Sdan# Test that it is not possible to change a temporary or in-memory database
182e180c296Sdan# to WAL mode. WAL mode is for persistent file-backed databases only.
183e180c296Sdan#
184e180c296Sdan#   walmode-5.1.*: Try to set journal_mode=WAL on [sqlite3 db :memory:] database.
185e180c296Sdan#   walmode-5.2.*: Try to set journal_mode=WAL on [sqlite3 db ""] database.
186e180c296Sdan#   walmode-5.3.*: Try to set temp.journal_mode=WAL.
187e180c296Sdan#
188e180c296Sdando_test walmode-5.1.1 {
189e180c296Sdan  sqlite3 db :memory:
190e180c296Sdan  execsql { PRAGMA main.journal_mode }
191e180c296Sdan} {memory}
192e180c296Sdando_test walmode-5.1.2 {
193e180c296Sdan  execsql { PRAGMA main.journal_mode = wal }
194e180c296Sdan} {memory}
195e180c296Sdando_test walmode-5.1.3 {
196e180c296Sdan  execsql {
197e180c296Sdan    BEGIN;
198e180c296Sdan      CREATE TABLE t1(a, b);
199e180c296Sdan      INSERT INTO t1 VALUES(1, 2);
200e180c296Sdan    COMMIT;
201e180c296Sdan    SELECT * FROM t1;
202e180c296Sdan    PRAGMA main.journal_mode;
203e180c296Sdan  }
204e180c296Sdan} {1 2 memory}
205e180c296Sdando_test walmode-5.1.4 {
206e180c296Sdan  execsql { PRAGMA main.journal_mode = wal }
207e180c296Sdan} {memory}
208e180c296Sdando_test walmode-5.1.5 {
209e180c296Sdan  execsql {
210e180c296Sdan    INSERT INTO t1 VALUES(3, 4);
211e180c296Sdan    SELECT * FROM t1;
212e180c296Sdan    PRAGMA main.journal_mode;
213e180c296Sdan  }
214e180c296Sdan} {1 2 3 4 memory}
215e180c296Sdan
2164565682fSdanif {$TEMP_STORE>=2} {
2174565682fSdan  set tempJrnlMode memory
2184565682fSdan} else {
2194565682fSdan  set tempJrnlMode delete
2204565682fSdan}
221e180c296Sdando_test walmode-5.2.1 {
222e180c296Sdan  sqlite3 db ""
223e180c296Sdan  execsql { PRAGMA main.journal_mode }
2244565682fSdan} $tempJrnlMode
225e180c296Sdando_test walmode-5.2.2 {
226e180c296Sdan  execsql { PRAGMA main.journal_mode = wal }
2274565682fSdan} $tempJrnlMode
228e180c296Sdando_test walmode-5.2.3 {
229e180c296Sdan  execsql {
230e180c296Sdan    BEGIN;
231e180c296Sdan      CREATE TABLE t1(a, b);
232e180c296Sdan      INSERT INTO t1 VALUES(1, 2);
233e180c296Sdan    COMMIT;
234e180c296Sdan    SELECT * FROM t1;
235e180c296Sdan    PRAGMA main.journal_mode;
236e180c296Sdan  }
2374565682fSdan} [list 1 2 $tempJrnlMode]
238e180c296Sdando_test walmode-5.2.4 {
239e180c296Sdan  execsql { PRAGMA main.journal_mode = wal }
2404565682fSdan} $tempJrnlMode
241e180c296Sdando_test walmode-5.2.5 {
242e180c296Sdan  execsql {
243e180c296Sdan    INSERT INTO t1 VALUES(3, 4);
244e180c296Sdan    SELECT * FROM t1;
245e180c296Sdan    PRAGMA main.journal_mode;
246e180c296Sdan  }
2474565682fSdan} [list 1 2 3 4 $tempJrnlMode]
248e180c296Sdan
249e180c296Sdando_test walmode-5.3.1 {
250e180c296Sdan  sqlite3 db test.db
251e180c296Sdan  execsql { PRAGMA temp.journal_mode }
252d80b2338Sdrh} $tempJrnlMode
253e180c296Sdando_test walmode-5.3.2 {
254e180c296Sdan  execsql { PRAGMA temp.journal_mode = wal }
255d80b2338Sdrh} $tempJrnlMode
256e180c296Sdando_test walmode-5.3.3 {
257e180c296Sdan  execsql {
258e180c296Sdan    BEGIN;
259e180c296Sdan      CREATE TEMP TABLE t1(a, b);
260e180c296Sdan      INSERT INTO t1 VALUES(1, 2);
261e180c296Sdan    COMMIT;
262e180c296Sdan    SELECT * FROM t1;
263e180c296Sdan    PRAGMA temp.journal_mode;
264e180c296Sdan  }
265d80b2338Sdrh} [list 1 2 $tempJrnlMode]
266e180c296Sdando_test walmode-5.3.4 {
267e180c296Sdan  execsql { PRAGMA temp.journal_mode = wal }
268d80b2338Sdrh} $tempJrnlMode
269e180c296Sdando_test walmode-5.3.5 {
270e180c296Sdan  execsql {
271e180c296Sdan    INSERT INTO t1 VALUES(3, 4);
272e180c296Sdan    SELECT * FROM t1;
273e180c296Sdan    PRAGMA temp.journal_mode;
274e180c296Sdan  }
275d80b2338Sdrh} [list 1 2 3 4 $tempJrnlMode]
276e180c296Sdan
2773f94b609Sdan
2783f94b609Sdan#-------------------------------------------------------------------------
2793f94b609Sdan# Test changing to WAL mode from journal_mode=off or journal_mode=memory
2803f94b609Sdan#
2813f94b609Sdanforeach {tn mode} {
282f6c61471Sdan  1 off
283f6c61471Sdan  2 memory
2843f94b609Sdan  3 persist
2853f94b609Sdan  4 delete
2863f94b609Sdan  5 truncate
2873f94b609Sdan} {
2883f94b609Sdan  do_test walmode-6.$tn {
2893f94b609Sdan    faultsim_delete_and_reopen
2903f94b609Sdan    execsql "
2913f94b609Sdan      PRAGMA journal_mode = $mode;
2923f94b609Sdan      PRAGMA journal_mode = wal;
2933f94b609Sdan    "
2943f94b609Sdan  } [list $mode wal]
2953f94b609Sdan}
296f6c61471Sdandb close
297f6c61471Sdan
2988700b1e5Sdan#-------------------------------------------------------------------------
2998700b1e5Sdan# Test the effect of a "PRAGMA journal_mode" command being the first
3008700b1e5Sdan# thing executed by a new connection. This means that the schema is not
3018700b1e5Sdan# loaded when sqlite3_prepare_v2() is called to compile the statement.
3028700b1e5Sdan#
303f6c61471Sdando_test walmode-7.0 {
304fda06befSmistachkin  forcedelete test.db
305f6c61471Sdan  sqlite3 db test.db
306f6c61471Sdan  execsql {
307f6c61471Sdan    PRAGMA journal_mode = WAL;
308f6c61471Sdan    CREATE TABLE t1(a, b);
309f6c61471Sdan  }
310f6c61471Sdan} {wal}
311f6c61471Sdanforeach {tn sql result} {
312c6b2a0ffSdrh  1  "PRAGMA journal_mode"                wal
313f6c61471Sdan  2  "PRAGMA main.journal_mode"           wal
314f6c61471Sdan  3  "PRAGMA journal_mode = delete"       delete
315f6c61471Sdan  4  "PRAGMA journal_mode"                delete
316f6c61471Sdan  5  "PRAGMA main.journal_mode"           delete
317f6c61471Sdan  6  "PRAGMA journal_mode = wal"          wal
318c6b2a0ffSdrh  7  "PRAGMA journal_mode"                wal
319f6c61471Sdan  8  "PRAGMA main.journal_mode"           wal
320f6c61471Sdan
321c6b2a0ffSdrh  9  "PRAGMA journal_mode"                wal
322f6c61471Sdan 10  "PRAGMA main.journal_mode"           wal
323f6c61471Sdan 11  "PRAGMA main.journal_mode = delete"  delete
324f6c61471Sdan 12  "PRAGMA journal_mode"                delete
325f6c61471Sdan 13  "PRAGMA main.journal_mode"           delete
326f6c61471Sdan 14  "PRAGMA main.journal_mode = wal"     wal
327c6b2a0ffSdrh 15  "PRAGMA journal_mode"                wal
328f6c61471Sdan 16  "PRAGMA main.journal_mode"           wal
329f6c61471Sdan} {
330f6c61471Sdan  do_test walmode-7.$tn {
331f6c61471Sdan    db close
332f6c61471Sdan    sqlite3 db test.db
333f6c61471Sdan    execsql $sql
334f6c61471Sdan  } $result
335f6c61471Sdan}
336f6c61471Sdandb close
3373f94b609Sdan
3388700b1e5Sdan#-------------------------------------------------------------------------
3398700b1e5Sdan# Test the effect of a "PRAGMA journal_mode" command on an attached
3408700b1e5Sdan# database.
3418700b1e5Sdan#
3428700b1e5Sdanfaultsim_delete_and_reopen
3438700b1e5Sdando_execsql_test walmode-8.1 {
3448700b1e5Sdan  CREATE TABLE t1(a, b);
3458700b1e5Sdan  PRAGMA journal_mode = WAL;
3468700b1e5Sdan  ATTACH 'test.db2' AS two;
3478700b1e5Sdan  CREATE TABLE two.t2(a, b);
3488700b1e5Sdan} {wal}
3498700b1e5Sdando_execsql_test walmode-8.2 { PRAGMA main.journal_mode }         {wal}
350c6b2a0ffSdrhdo_execsql_test walmode-8.3 { PRAGMA two.journal_mode  }         {delete}
3518700b1e5Sdando_execsql_test walmode-8.4 { PRAGMA two.journal_mode = DELETE } {delete}
3528700b1e5Sdan
3538700b1e5Sdandb close
3548700b1e5Sdansqlite3 db test.db
3558700b1e5Sdando_execsql_test walmode-8.5  { ATTACH 'test.db2' AS two }          {}
3568700b1e5Sdando_execsql_test walmode-8.6  { PRAGMA main.journal_mode }          {wal}
3578700b1e5Sdando_execsql_test walmode-8.7  { PRAGMA two.journal_mode  }          {delete}
3588700b1e5Sdando_execsql_test walmode-8.8  { INSERT INTO two.t2 DEFAULT VALUES } {}
3598700b1e5Sdando_execsql_test walmode-8.9  { PRAGMA two.journal_mode  }          {delete}
3608700b1e5Sdando_execsql_test walmode-8.10 { INSERT INTO t1 DEFAULT VALUES } {}
3618700b1e5Sdando_execsql_test walmode-8.11 { PRAGMA main.journal_mode  }         {wal}
362c6b2a0ffSdrhdo_execsql_test walmode-8.12 { PRAGMA journal_mode  }              {wal}
363c6b2a0ffSdrh
364c6b2a0ffSdrh# Change to WAL mode on test2.db and make sure (in the tests that follow)
365c6b2a0ffSdrh# that this mode change persists.
366c6b2a0ffSdrhdo_test walmode-8.x1 {
367c6b2a0ffSdrh  execsql {
368c6b2a0ffSdrh     PRAGMA two.journal_mode=WAL;
369c6b2a0ffSdrh     PRAGMA two.journal_mode;
370c6b2a0ffSdrh  }
371c6b2a0ffSdrh} {wal wal}
3728700b1e5Sdan
3738700b1e5Sdandb close
3748700b1e5Sdansqlite3 db test.db
3758700b1e5Sdando_execsql_test walmode-8.13 { PRAGMA journal_mode = WAL }         {wal}
3768700b1e5Sdando_execsql_test walmode-8.14 { ATTACH 'test.db2' AS two  }         {}
3778700b1e5Sdando_execsql_test walmode-8.15 { PRAGMA main.journal_mode  }         {wal}
3788700b1e5Sdando_execsql_test walmode-8.16 { PRAGMA two.journal_mode   }         {wal}
3798700b1e5Sdando_execsql_test walmode-8.17 { INSERT INTO two.t2 DEFAULT VALUES } {}
3808700b1e5Sdando_execsql_test walmode-8.18 { PRAGMA two.journal_mode   }         {wal}
3818700b1e5Sdan
3828700b1e5Sdansqlite3 db2 test.db2
3838700b1e5Sdando_test walmode-8.19 { execsql { PRAGMA main.journal_mode } db2 }  {wal}
3848700b1e5Sdandb2 close
3858700b1e5Sdan
38673d66fdbSdando_execsql_test walmode-8.20 { PRAGMA journal_mode = DELETE } {delete}
38773d66fdbSdando_execsql_test walmode-8.21 { PRAGMA main.journal_mode }     {delete}
38873d66fdbSdando_execsql_test walmode-8.22 { PRAGMA two.journal_mode }      {delete}
38973d66fdbSdando_execsql_test walmode-8.21 { PRAGMA journal_mode = WAL }    {wal}
39073d66fdbSdando_execsql_test walmode-8.21 { PRAGMA main.journal_mode }     {wal}
39173d66fdbSdando_execsql_test walmode-8.22 { PRAGMA two.journal_mode }      {wal}
39273d66fdbSdan
393e04dc88bSdanfinish_test
394