xref: /sqlite-3.40.0/test/e_wal.test (revision 7aa3ebee)
1# 2011 May 06
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
15set testprefix e_wal
16
17db close
18testvfs oldvfs -iversion 1
19
20
21# EVIDENCE-OF: R-58297-14483 WAL databases can be created, read, and
22# written even if shared memory is unavailable as long as the
23# locking_mode is set to EXCLUSIVE before the first attempted access.
24#
25# EVIDENCE-OF: R-00449-33772 This feature allows WAL databases to be
26# created, read, and written by legacy VFSes that lack the "version 2"
27# shared-memory methods xShmMap, xShmLock, xShmBarrier, and xShmUnmap on
28# the sqlite3_io_methods object.
29#
30# 1.1: "create" tests.
31# 1.2: "read" tests.
32# 1.3: "write" tests.
33#
34# All three done with VFS "oldvfs", which has iVersion==1 and so does
35# not support shared memory.
36#
37sqlite3 db test.db -vfs oldvfs
38do_execsql_test 1.1.1 {
39  PRAGMA journal_mode = WAL;
40} {delete}
41do_execsql_test 1.1.2 {
42  PRAGMA locking_mode = EXCLUSIVE;
43  PRAGMA journal_mode = WAL;
44} {exclusive wal}
45do_execsql_test 1.1.3 {
46  CREATE TABLE t1(x, y);
47  INSERT INTO t1 VALUES(1, 2);
48} {}
49do_test 1.1.4 {
50  list [file exists test.db-shm] [file exists test.db-wal]
51} {0 1}
52
53do_test 1.2.1 {
54  db close
55  sqlite3 db test.db -vfs oldvfs
56  catchsql { SELECT * FROM t1 }
57} {1 {unable to open database file}}
58do_test 1.2.2 {
59  execsql { PRAGMA locking_mode = EXCLUSIVE }
60  execsql { SELECT * FROM t1 }
61} {1 2}
62do_test 1.2.3 {
63  list [file exists test.db-shm] [file exists test.db-wal]
64} {0 1}
65
66do_test 1.3.1 {
67  db close
68  sqlite3 db test.db -vfs oldvfs
69  catchsql { INSERT INTO t1 VALUES(3, 4) }
70} {1 {unable to open database file}}
71do_test 1.3.2 {
72  execsql { PRAGMA locking_mode = EXCLUSIVE }
73  execsql { INSERT INTO t1 VALUES(3, 4) }
74  execsql { SELECT * FROM t1 }
75} {1 2 3 4}
76do_test 1.3.3 {
77  list [file exists test.db-shm] [file exists test.db-wal]
78} {0 1}
79
80# EVIDENCE-OF: R-31969-57825 If EXCLUSIVE locking mode is set prior to
81# the first WAL-mode database access, then SQLite never attempts to call
82# any of the shared-memory methods and hence no shared-memory wal-index
83# is ever created.
84#
85db close
86sqlite3 db test.db
87do_execsql_test 2.1.1 {
88  PRAGMA locking_mode = EXCLUSIVE;
89  SELECT * FROM t1;
90} {exclusive 1 2 3 4}
91do_test 2.1.2 {
92  list [file exists test.db-shm] [file exists test.db-wal]
93} {0 1}
94
95# EVIDENCE-OF: R-36328-16367 In that case, the database connection
96# remains in EXCLUSIVE mode as long as the journal mode is WAL; attempts
97# to change the locking mode using "PRAGMA locking_mode=NORMAL;" are
98# no-ops.
99#
100do_execsql_test 2.2.1 {
101  PRAGMA locking_mode = NORMAL;
102  SELECT * FROM t1;
103} {exclusive 1 2 3 4}
104do_test 2.2.2 {
105  sqlite3 db2 test.db
106  catchsql {SELECT * FROM t1} db2
107} {1 {database is locked}}
108db2 close
109
110# EVIDENCE-OF: R-63522-46088 The only way to change out of EXCLUSIVE
111# locking mode is to first change out of WAL journal mode.
112#
113do_execsql_test 2.3.1 {
114  PRAGMA journal_mode = DELETE;
115  SELECT * FROM t1;
116} {delete 1 2 3 4}
117do_test 2.3.2 {
118  sqlite3 db2 test.db
119  catchsql {SELECT * FROM t1} db2
120} {1 {database is locked}}
121do_execsql_test 2.3.3 {
122  PRAGMA locking_mode = NORMAL;
123  SELECT * FROM t1;
124} {normal 1 2 3 4}
125do_test 2.3.4 {
126  sqlite3 db2 test.db
127  catchsql {SELECT * FROM t1} db2
128} {0 {1 2 3 4}}
129db2 close
130db close
131
132
133# EVIDENCE-OF: R-57239-11845 If NORMAL locking mode is in effect for the
134# first WAL-mode database access, then the shared-memory wal-index is
135# created.
136#
137do_test 3.0 {
138  sqlite3 db test.db
139  execsql { PRAGMA journal_mode = WAL }
140  db close
141} {}
142do_test 3.1 {
143  sqlite3 db test.db
144  execsql { SELECT * FROM t1 }
145  list [file exists test.db-shm] [file exists test.db-wal]
146} {1 1}
147
148# EVIDENCE-OF: R-13779-07711 As long as exactly one connection is using
149# a shared-memory wal-index, the locking mode can be changed freely
150# between NORMAL and EXCLUSIVE.
151#
152do_execsql_test 3.2.1 {
153  PRAGMA locking_mode = EXCLUSIVE;
154  PRAGMA locking_mode = NORMAL;
155  PRAGMA locking_mode = EXCLUSIVE;
156  INSERT INTO t1 VALUES(5, 6);
157} {exclusive normal exclusive}
158do_test 3.2.2 {
159  sqlite3 db2 test.db
160  catchsql { SELECT * FROM t1 } db2
161} {1 {database is locked}}
162
163# EVIDENCE-OF: R-10993-11647 It is only when the shared-memory wal-index
164# is omitted, when the locking mode is EXCLUSIVE prior to the first
165# WAL-mode database access, that the locking mode is stuck in EXCLUSIVE.
166#
167do_execsql_test 3.2.3 {
168  PRAGMA locking_mode = NORMAL;
169  SELECT * FROM t1;
170} {normal 1 2 3 4 5 6}
171do_test 3.2.4 {
172  catchsql { SELECT * FROM t1 } db2
173} {0 {1 2 3 4 5 6}}
174
175do_catchsql_test 3.2.5 {
176  PRAGMA locking_mode = EXCLUSIVE;
177  INSERT INTO t1 VALUES(7, 8);
178} {1 {database is locked}}
179
180db2 close
181
182# EVIDENCE-OF: R-46197-42811 This means that the underlying VFS must
183# support the "version 2" shared-memory.
184#
185# EVIDENCE-OF: R-55316-21772 If the VFS does not support shared-memory
186# methods, then the attempt to open a database that is already in WAL
187# mode, or the attempt convert a database into WAL mode, will fail.
188#
189db close
190do_test 3.4.1 {
191  sqlite3 db test.db -vfs oldvfs
192  catchsql { SELECT * FROM t1 }
193} {1 {unable to open database file}}
194db close
195do_test 3.4.2 {
196  forcedelete test.db2
197  sqlite3 db test.db2 -vfs oldvfs
198  catchsql { PRAGMA journal_mode = WAL }
199} {0 delete}
200db close
201
202
203# EVIDENCE-OF: R-45540-25505 To prevent older versions of SQLite (prior
204# to version 3.7.0, 2010-07-22) from trying to recover a WAL-mode
205# database (and making matters worse) the database file format version
206# numbers (bytes 18 and 19 in the database header) are increased from 1
207# to 2 in WAL mode.
208#
209reset_db
210do_execsql_test 4.1.1 { CREATE TABLE t1(x, y) }
211do_test 4.1.2 { hexio_read test.db 18 2 } {0101}
212do_execsql_test 4.1.3 { PRAGMA journal_mode = wAL } {wal}
213do_test 4.1.4 { hexio_read test.db 18 2 } {0202}
214
215
216# EVIDENCE-OF: R-02535-05811 One can explicitly change out of WAL mode
217# using a pragma such as this: PRAGMA journal_mode=DELETE;
218#
219do_execsql_test 4.2.1 { INSERT INTO t1 VALUES(1, 1); } {}
220do_test 4.2.2 { file exists test.db-wal } {1}
221do_execsql_test 4.2.3 { PRAGMA journal_mode = delete } {delete}
222do_test 4.2.4 { file exists test.db-wal } {0}
223
224# EVIDENCE-OF: R-60175-02388 Deliberately changing out of WAL mode
225# changes the database file format version numbers back to 1 so that
226# older versions of SQLite can once again access the database file.
227#
228do_test 4.3 { hexio_read test.db 18 2 } {0101}
229
230finish_test
231