Improved comments, including a typo fix, on the whereLoopCheaperProperSubset()
[sqlite.git] / test / snapshot2.test
blob3faabd7f4c2a28f78d36c54b6591e242bac942ee
1 # 2016 November 18
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 focus
12 # of this file is the sqlite3_snapshot_xxx() APIs.
15 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
17 ifcapable !snapshot {finish_test; return}
18 set testprefix snapshot2
20 # This test does not work with the inmemory_journal permutation. The reason
21 # is that each connection opened as part of this permutation executes
22 # "PRAGMA journal_mode=memory", which fails if the database is in wal mode
23 # and there are one or more existing connections.
24 if {[permutation]=="inmemory_journal"} {
25   finish_test
26   return
29 #-------------------------------------------------------------------------
30 # Check that it is not possible to obtain a snapshot immediately after
31 # a wal mode database with an empty wal file is opened. But it is after
32 # the file has been written, even by some other connection.
34 do_execsql_test 1.0 {
35   PRAGMA journal_mode = wal;
36   CREATE TABLE t1(a, b, c);
37   INSERT INTO t1 VALUES(1, 2, 3);
38   INSERT INTO t1 VALUES(4, 5, 6);
39 } {wal}
41 db close
42 do_test 1.1.1 { list [file exists test.db] [file exists test.db-wal] } {1 0}
44 sqlite3 db test.db
45 do_execsql_test 1.1.2 { SELECT * FROM t1 } {1 2 3 4 5 6}
47 do_test 1.1.3 {
48   execsql BEGIN
49   list [catch { sqlite3_snapshot_get_blob db main } msg] $msg
50 } {1 SQLITE_ERROR}
51 execsql COMMIT
53 do_test 1.1.4 {
54   execsql { INSERT INTO t1 VALUES(7, 8, 9) }
55   execsql BEGIN
56   string length [sqlite3_snapshot_get_blob db main]
57 } 48
58 execsql COMMIT
60 db close
61 do_test 1.2.1 { list [file exists test.db] [file exists test.db-wal] } {1 0}
63 sqlite3 db test.db
64 do_execsql_test 1.2.2 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8 9}
66 do_test 1.2.3 {
67   execsql BEGIN
68   list [catch { sqlite3_snapshot_get_blob db main } msg] $msg
69 } {1 SQLITE_ERROR}
70 execsql COMMIT
72 do_test 1.2.4 {
73   sqlite3 db2 test.db
74   execsql { INSERT INTO t1 VALUES(10, 11, 12) } db2
75   execsql BEGIN
76   string length [sqlite3_snapshot_get_blob db main]
77 } 48
78 execsql COMMIT
79 db2 close
81 #-------------------------------------------------------------------------
82 # Simple tests for sqlite3_snapshot_recover().
84 reset_db
85 do_execsql_test 2.0 {
86   CREATE TABLE t1(x);
87   PRAGMA journal_mode = wal;
88   INSERT INTO t1 VALUES(1);
89   INSERT INTO t1 VALUES(2);
90 } {wal}
92 do_test 2.1 {
93   db trans { set snap [sqlite3_snapshot_get_blob db main] }
94   sqlite3_db_config db NO_CKPT_ON_CLOSE 1
95   db close
96   sqlite3 db test.db
98   execsql {SELECT * FROM sqlite_master}
99   execsql BEGIN
100   sqlite3_snapshot_open_blob db main $snap
101   execsql COMMIT;
102   execsql { INSERT INTO t1 VALUES(3); }
103 } {}
105 do_test 2.2 {
106   sqlite3_db_config db NO_CKPT_ON_CLOSE 1
107   db close
108   sqlite3 db test.db
110   execsql {SELECT * FROM sqlite_master}
111   execsql BEGIN
112   list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg
113 } {1 SQLITE_BUSY_SNAPSHOT}
115 do_test 2.3 {
116   execsql COMMIT
117   sqlite3_snapshot_recover db main
118   execsql BEGIN
119   sqlite3_snapshot_open_blob db main $snap
120   execsql { SELECT * FROM t1 }
121 } {1 2}
123 do_test 2.4 {
124   execsql COMMIT
125   execsql { SELECT * FROM t1 }
126 } {1 2 3}
128 do_test 2.5 {
129   execsql { PRAGMA wal_checkpoint }
130   sqlite3_db_config db NO_CKPT_ON_CLOSE 1
131   db close
132   sqlite3 db test.db
134   sqlite3_snapshot_recover db main
135   execsql BEGIN
136   list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg
137 } {1 SQLITE_BUSY_SNAPSHOT}
139 #-------------------------------------------------------------------------
140 # Check that calling sqlite3_snapshot_recover() does not confuse the
141 # pager cache.
142 reset_db
143 do_execsql_test 3.0 {
144   PRAGMA journal_mode = wal;
145   CREATE TABLE t1(x, y);
146   INSERT INTO t1 VALUES('a', 'b');
147   INSERT INTO t1 VALUES('c', 'd');
148 } {wal}
149 do_test 3.1 {
150   sqlite3 db2 test.db
151   execsql { INSERT INTO t1 VALUES('e', 'f') } db2
152   db2 close
153   sqlite3_snapshot_recover db main
154 } {}
155 do_execsql_test 3.2 {
156   SELECT * FROM t1;
157 } {a b c d e f}
159 #-------------------------------------------------------------------------
160 # Check that sqlite3_snapshot_recover() returns an error if it is called
161 # with an open read-transaction. Or on a database that does not exist. Or
162 # on the temp database. Or on a db that is not in wal mode.
164 do_test 4.1 {
165   sqlite3_snapshot_recover db main
166 } {}
167 do_test 4.2 {
168   execsql {
169     BEGIN;
170       SELECT * FROM sqlite_master;
171   }
172   list [catch { sqlite3_snapshot_recover db main } msg] $msg
173 } {1 SQLITE_ERROR}
174 do_test 4.3 {
175   execsql COMMIT
176   sqlite3_snapshot_recover db main
177 } {}
178 do_test 4.4 {
179   list [catch { sqlite3_snapshot_recover db aux } msg] $msg
180 } {1 SQLITE_ERROR}
181 do_test 4.5 {
182   forcedelete test.db2
183   execsql {
184     ATTACH 'test.db2' AS aux;
185     PRAGMA aux.journal_mode = wal;
186     CREATE TABLE aux.t2(x, y);
187   }
188   list [catch { sqlite3_snapshot_recover db aux } msg] $msg
189 } {0 {}}
190 do_test 4.6 {
191   list [catch { sqlite3_snapshot_recover db temp } msg] $msg
192 } {1 SQLITE_ERROR}
193 do_test 4.7 {
194   execsql {
195     PRAGMA aux.journal_mode = delete;
196   }
197   list [catch { sqlite3_snapshot_recover db aux } msg] $msg
198 } {1 SQLITE_ERROR}
200 #-------------------------------------------------------------------------
201 reset_db
202 sqlite3 db2 test.db 
203 do_execsql_test 5.0 {
204   CREATE TABLE t2(x);
205   PRAGMA journal_mode = wal;
206   INSERT INTO t2 VALUES('abc');
207   INSERT INTO t2 VALUES('def');
208   INSERT INTO t2 VALUES('ghi');
209 } {wal}
211 do_test 5.1 {
212   execsql { 
213     SELECT * FROM t2;
214     BEGIN;
215   } db2
216   set snap [sqlite3_snapshot_get_blob db2 main]
217   db2 eval END
218 } {}
220 do_test 5.2 {
221   execsql BEGIN db2
222   sqlite3_snapshot_open_blob db2 main $snap
223   db2 eval { SELECT * FROM t2 ; END }
224 } {abc def ghi}
226 do_test 5.3 {
227   execsql { PRAGMA wal_checkpoint = RESTART }
228   execsql BEGIN db2
229   sqlite3_snapshot_open_blob db2 main $snap
230   db2 eval { SELECT * FROM t2 ; END }
231 } {abc def ghi}
233 do_test 5.4 {
234   execsql { INSERT INTO t2 VALUES('jkl') } 
235   execsql BEGIN db2
236   list [catch { sqlite3_snapshot_open_blob db2 main $snap } msg] $msg
237 } {1 SQLITE_BUSY_SNAPSHOT}
240 finish_test