xref: /sqlite-3.40.0/test/temptable2.test (revision cf2ad7ae)
1# 2016 March 3
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# TESTRUNNER: slow
13#
14
15set testdir [file dirname $argv0]
16source $testdir/tester.tcl
17set testprefix temptable2
18
19do_execsql_test 1.1 {
20  CREATE TEMP TABLE t1(a, b);
21  CREATE INDEX i1 ON t1(a, b);
22}
23
24do_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} {}
28
29do_execsql_test 1.3 {
30  PRAGMA temp.integrity_check;
31} {ok}
32
33#-------------------------------------------------------------------------
34#
35reset_db
36do_execsql_test 2.1 {
37  CREATE TEMP TABLE t2(a, b);
38  INSERT INTO t2 VALUES(1, 2);
39} {}
40
41do_execsql_test 2.2 {
42  BEGIN;
43    INSERT INTO t2 VALUES(3, 4);
44    SELECT * FROM t2;
45} {1 2 3 4}
46
47do_execsql_test 2.3 {
48  ROLLBACK;
49  SELECT * FROM t2;
50} {1 2}
51
52#-------------------------------------------------------------------------
53#
54reset_db
55do_execsql_test 3.1.1 {
56  PRAGMA main.cache_size = 10;
57  PRAGMA temp.cache_size = 10;
58
59  CREATE TEMP TABLE t1(a, b);
60  CREATE INDEX i1 ON t1(a, b);
61
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;
64
65  SELECT count(*) FROM t1;
66} {1000}
67do_execsql_test 3.1.2 {
68  BEGIN;
69    UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==0;
70  ROLLBACK;
71}
72do_execsql_test 3.1.3 {
73  SELECT count(*) FROM t1;
74} {1000}
75do_execsql_test 3.1.4 { PRAGMA temp.integrity_check } {ok}
76
77do_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;
85}
86do_execsql_test 3.2.2 { PRAGMA temp.integrity_check } {ok}
87
88#-------------------------------------------------------------------------
89#
90reset_db
91do_execsql_test 4.1.1 {
92  PRAGMA main.cache_size = 10;
93  PRAGMA temp.cache_size = 10;
94
95  CREATE TEMP TABLE t1(a, b);
96  CREATE INDEX i1 ON t1(a, b);
97
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;
100
101  SELECT count(*) FROM t1;
102  PRAGMA temp.page_count;
103} {10 9}
104
105do_execsql_test 4.1.2 {
106  BEGIN;
107    UPDATE t1 SET b=randomblob(100);
108  ROLLBACK;
109}
110
111do_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;
116
117  SELECT count(*) FROM t2;
118  SELECT count(*) FROM t1;
119} {500 10}
120
121do_test 4.1.4 {
122  set n [db one { PRAGMA temp.page_count }]
123  expr ($n >280 && $n < 300)
124} 1
125
126do_execsql_test 4.1.4 { PRAGMA temp.integrity_check } {ok}
127
128#-------------------------------------------------------------------------
129#
130reset_db
131do_execsql_test 5.1.1 {
132  PRAGMA main.cache_size = 10;
133  PRAGMA temp.cache_size = 10;
134
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;
139
140  CREATE TEMP TABLE t1(a, b);
141  CREATE INDEX i1 ON t1(a, b);
142  INSERT INTO t1 VALUES(1, 2);
143}
144
145# Test that the temp database is now much bigger than the configured
146# cache size (10 pages).
147do_test 5.1.2 {
148  set n [db one { PRAGMA temp.page_count }]
149  expr ($n > 270 && $n < 290)
150} {1}
151
152do_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}
159
160do_execsql_test 5.1.4 {
161  UPDATE t2 SET a=randomblob(100);
162
163  SELECT * FROM t1;
164} {1 2}
165
166do_execsql_test 5.1.5 { PRAGMA temp.integrity_check } {ok}
167
168#-------------------------------------------------------------------------
169# Test this:
170#
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?
175#
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.
179#
180reset_db
181
182do_execsql_test 6.1 {
183  PRAGMA main.cache_size = 10;
184  PRAGMA temp.cache_size = 10;
185
186  CREATE TEMP TABLE t1(x);
187  INSERT INTO t1 VALUES('one');
188
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;
193}
194
195do_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
201
202  SELECT count(*) FROM t2;
203  SELECT * FROM t1;
204} {two 500 two}
205
206#-------------------------------------------------------------------------
207#
208reset_db
209sqlite3 db ""
210do_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}
225
226#-------------------------------------------------------------------------
227# Try changing the page size using a backup operation when pages are
228# stored in main-memory only.
229#
230reset_db
231do_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}
239
240do_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}
252
253do_test 8.3 {
254  sqlite3_backup B tmp main db main
255  B step 5
256  B finish
257} {SQLITE_READONLY}
258
259do_test 8.4 {
260  execsql {
261    SELECT count(*) FROM t1;
262    PRAGMA integrity_check;
263    PRAGMA page_size;
264  } tmp
265} {100 ok 8192}
266
267do_test 8.5 {
268  tmp eval { UPDATE t1 SET a=randomblob(100) }
269} {}
270
271do_test 8.6 {
272  sqlite3_backup B tmp main db main
273  B step 1000
274  B finish
275} {SQLITE_READONLY}
276
277tmp close
278
279#-------------------------------------------------------------------------
280# Try inserts and deletes with a large db in auto-vacuum mode. Check
281#
282foreach {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"
293
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  }
301
302  for {set i 2} {$i<20} {incr i} {
303    do_execsql_test 9.$tn.$i.1 { DELETE FROM tx WHERE (random()%3)==0 }
304
305    do_execsql_test 9.$tn.$i.2 { PRAGMA integrity_check } ok
306
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      }
311
312    do_execsql_test 9.$tn.$i.4 { PRAGMA integrity_check } ok
313
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    }
321
322    do_execsql_test 9.$tn.$i.6 { PRAGMA integrity_check } ok
323  }
324}
325
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.
330#
331sqlite3 db ""
332do_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);
339}
340
341do_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);
347}
348
349ifcapable 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  }
355}
356
357do_execsql_test 10.3 { SELECT * FROM t2 } {1 2 3 4}
358do_execsql_test 10.4 { PRAGMA integrity_check } ok
359
360finish_test
361