Use a mini Bloom filter to help reduce the number of pointless searches for
[sqlite.git] / test / temptable2.test
blob2ee4adb9f76b3d79d53c4621f6dc46aa6e90ba6b
1 # 2016 March 3
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 #***********************************************************************
12 # TESTRUNNER: slow
15 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
17 set testprefix temptable2
19 do_execsql_test 1.1 {
20   CREATE TEMP TABLE t1(a, b);
21   CREATE INDEX i1 ON t1(a, b);
24 do_execsql_test 1.2 {
25   WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100000 )
26   INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM X;
27 } {}
29 do_execsql_test 1.3 {
30   PRAGMA temp.integrity_check;
31 } {ok}
33 #-------------------------------------------------------------------------
35 reset_db
36 do_execsql_test 2.1 {
37   CREATE TEMP TABLE t2(a, b);
38   INSERT INTO t2 VALUES(1, 2);
39 } {}
41 do_execsql_test 2.2 {
42   BEGIN;
43     INSERT INTO t2 VALUES(3, 4);
44     SELECT * FROM t2;
45 } {1 2 3 4}
47 do_execsql_test 2.3 {
48   ROLLBACK;
49   SELECT * FROM t2;
50 } {1 2}
52 #-------------------------------------------------------------------------
54 reset_db
55 do_execsql_test 3.1.1 {
56   PRAGMA main.cache_size = 10;
57   PRAGMA temp.cache_size = 10;
59   CREATE TEMP TABLE t1(a, b);
60   CREATE INDEX i1 ON t1(a, b);
62   WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 )
63   INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
65   SELECT count(*) FROM t1;
66 } {1000}
67 do_execsql_test 3.1.2 {
68   BEGIN;
69     UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==0;
70   ROLLBACK;
72 do_execsql_test 3.1.3 {
73   SELECT count(*) FROM t1;
74 } {1000}
75 do_execsql_test 3.1.4 { PRAGMA temp.integrity_check } {ok}
77 do_execsql_test 3.2.1 {
78   BEGIN;
79     UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==0;
80     SAVEPOINT abc;
81       UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==1;
82     ROLLBACK TO abc;
83     UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==2;
84   COMMIT;
86 do_execsql_test 3.2.2 { PRAGMA temp.integrity_check } {ok}
88 #-------------------------------------------------------------------------
90 reset_db
91 do_execsql_test 4.1.1 {
92   PRAGMA main.cache_size = 10;
93   PRAGMA temp.cache_size = 10;
95   CREATE TEMP TABLE t1(a, b);
96   CREATE INDEX i1 ON t1(a, b);
98   WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<10 )
99   INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
101   SELECT count(*) FROM t1;
102   PRAGMA temp.page_count;
103 } {10 9}
105 do_execsql_test 4.1.2 {
106   BEGIN;
107     UPDATE t1 SET b=randomblob(100);
108   ROLLBACK;
111 do_execsql_test 4.1.3 {
112   CREATE TEMP TABLE t2(a, b);
113   CREATE INDEX i2 ON t2(a, b);
114   WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
115   INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x;
117   SELECT count(*) FROM t2;
118   SELECT count(*) FROM t1;
119 } {500 10}
121 do_test 4.1.4 {
122   set n [db one { PRAGMA temp.page_count }]
123   expr ($n >280 && $n < 300) 
124 } 1
126 do_execsql_test 4.1.4 { PRAGMA temp.integrity_check } {ok}
128 #-------------------------------------------------------------------------
130 reset_db
131 do_execsql_test 5.1.1 {
132   PRAGMA main.cache_size = 10;
133   PRAGMA temp.cache_size = 10;
135   CREATE TEMP TABLE t2(a, b);
136   CREATE INDEX i2 ON t2(a, b);
137   WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
138   INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x;
140   CREATE TEMP TABLE t1(a, b);
141   CREATE INDEX i1 ON t1(a, b);
142   INSERT INTO t1 VALUES(1, 2);
145 # Test that the temp database is now much bigger than the configured
146 # cache size (10 pages).
147 do_test 5.1.2 {
148   set n [db one { PRAGMA temp.page_count }]
149   expr ($n > 270 && $n < 290)
150 } {1}
152 do_execsql_test 5.1.3 {
153   BEGIN;
154     UPDATE t1 SET a=2;
155     UPDATE t2 SET a=randomblob(100);
156     SELECT count(*) FROM t1;
157   ROLLBACK;
158 } {1}
160 do_execsql_test 5.1.4 {
161   UPDATE t2 SET a=randomblob(100);
163   SELECT * FROM t1;
164 } {1 2}
166 do_execsql_test 5.1.5 { PRAGMA temp.integrity_check } {ok}
168 #-------------------------------------------------------------------------
169 # Test this:
171 #   1. Page is DIRTY at the start of a transaction.
172 #   2. Page is written out as part of the transaction.
173 #   3. Page is then read back in.
174 #   4. Transaction is rolled back. Is the page now clean or dirty?
176 # This actually does work. Step 4 marks the page as clean. But it also
177 # writes to the database file itself. So marking it clean is correct - 
178 # the page does match the contents of the db file.
180 reset_db
182 do_execsql_test 6.1 {
183   PRAGMA main.cache_size = 10;
184   PRAGMA temp.cache_size = 10;
186   CREATE TEMP TABLE t1(x);
187   INSERT INTO t1 VALUES('one');
189   CREATE TEMP TABLE t2(a, b);
190   CREATE INDEX i2 ON t2(a, b);
191   WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
192   INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x;
195 do_execsql_test 6.2 {
196   UPDATE t1 SET x='two';             -- step 1
197   BEGIN;
198     UPDATE t2 SET a=randomblob(100); -- step 2
199     SELECT * FROM t1;                -- step 3
200   ROLLBACK;                          -- step 4
202   SELECT count(*) FROM t2;
203   SELECT * FROM t1;
204 } {two 500 two}
206 #-------------------------------------------------------------------------
208 reset_db
209 sqlite3 db ""
210 do_execsql_test 7.1 {
211   PRAGMA auto_vacuum=INCREMENTAL;
212   CREATE TABLE t1(x);
213   INSERT INTO t1 VALUES(zeroblob(900));
214   INSERT INTO t1 VALUES(zeroblob(900));
215   INSERT INTO t1 SELECT x FROM t1;
216   INSERT INTO t1 SELECT x FROM t1;
217   INSERT INTO t1 SELECT x FROM t1;
218   INSERT INTO t1 SELECT x FROM t1;
219   BEGIN;
220   DELETE FROM t1 WHERE rowid%2;
221   PRAGMA incremental_vacuum(4);
222   ROLLBACK;
223   PRAGMA integrity_check;
224 } {ok}
226 #-------------------------------------------------------------------------
227 # Try changing the page size using a backup operation when pages are
228 # stored in main-memory only.
230 reset_db
231 do_execsql_test 8.1 {
232   PRAGMA auto_vacuum = OFF;
233   CREATE TABLE t2(a, b);
234   CREATE INDEX i2 ON t2(a, b);
235   WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<20 )
236   INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x ORDER BY 1, 2;
237   PRAGMA page_count;
238 } {13}
240 do_test 8.2 {
241   sqlite3 tmp ""
242   execsql {
243     PRAGMA auto_vacuum = OFF;
244     PRAGMA page_size = 8192;
245     CREATE TABLE t1(a, b);
246     CREATE INDEX i1 ON t1(a, b);
247     WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100 )
248     INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x ORDER BY 1, 2;
249     PRAGMA page_count;
250   } tmp
251 } {10}
253 do_test 8.3 {
254   sqlite3_backup B tmp main db main
255   B step 5
256   B finish
257 } {SQLITE_READONLY}
259 do_test 8.4 {
260   execsql {
261     SELECT count(*) FROM t1;
262     PRAGMA integrity_check;
263     PRAGMA page_size;
264   } tmp
265 } {100 ok 8192}
267 do_test 8.5 { 
268   tmp eval { UPDATE t1 SET a=randomblob(100) }
269 } {}
271 do_test 8.6 {
272   sqlite3_backup B tmp main db main
273   B step 1000
274   B finish
275 } {SQLITE_READONLY}
277 tmp close
279 #-------------------------------------------------------------------------
280 # Try inserts and deletes with a large db in auto-vacuum mode. Check
282 foreach {tn mode} {
283   1 delete
284   2 wal
285 } {
286   reset_db
287   sqlite3 db ""
288   do_execsql_test 9.$tn.1.1 {
289     PRAGMA cache_size = 15;
290     PRAGMA auto_vacuum = 1;
291   }
292   execsql "PRAGMA journal_mode = $mode"
294   do_execsql_test 9.$tn.1.2 {
295     CREATE TABLE tx(a, b);
296     CREATE INDEX i1 ON tx(a);
297     CREATE INDEX i2 ON tx(b);
298     WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 )
299       INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x;
300   }
302   for {set i 2} {$i<20} {incr i} {
303     do_execsql_test 9.$tn.$i.1 { DELETE FROM tx WHERE (random()%3)==0 }
305     do_execsql_test 9.$tn.$i.2 { PRAGMA integrity_check } ok
307       do_execsql_test 9.$tn.$i.3 { 
308         WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<400 )
309           INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x;
310       }
312     do_execsql_test 9.$tn.$i.4 { PRAGMA integrity_check } ok
314     do_execsql_test 9.$tn.$i.5 { 
315       BEGIN;
316       DELETE FROM tx WHERE (random()%3)==0;
317       WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
318         INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x;
319       COMMIT;
320     }
322     do_execsql_test 9.$tn.$i.6 { PRAGMA integrity_check } ok
323   }
326 #-------------------------------------------------------------------------
327 # When using mmap mode with a temp file, SQLite must search the cache 
328 # before using a mapped page even when there is no write transaction
329 # open. For a temp file, the on-disk version may not be up to date.
331 sqlite3 db ""
332 do_execsql_test 10.0 {
333   PRAGMA cache_size = 50;
334   PRAGMA page_size = 1024;
335   CREATE TABLE t1(a, b, PRIMARY KEY(a)) WITHOUT ROWID;
336   CREATE INDEX i1 ON t1(a);
337   CREATE TABLE t2(x, y);
338   INSERT INTO t2 VALUES(1, 2);
341 do_execsql_test 10.1 {
342   BEGIN;
343     WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
344       INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
345   COMMIT;
346   INSERT INTO t2 VALUES(3, 4);
349 ifcapable mmap {
350   if {[permutation]!="journaltest" && $::TEMP_STORE<2} {
351     # The journaltest permutation does not support mmap, so this part of
352     # the test is omitted.
353     do_execsql_test 10.2 { PRAGMA mmap_size = 512000 } 512000
354   }
357 do_execsql_test 10.3 { SELECT * FROM t2 } {1 2 3 4}
358 do_execsql_test 10.4 { PRAGMA integrity_check } ok
360 finish_test