blob: 6a1e2b9867901100d83b59f05cc40f9ab90e2238 [file] [log] [blame]
drhf57b3392001-10-08 13:22:32 +00001# 2001 October 7
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# This file implements regression tests for SQLite library.
12#
13# This file implements tests for temporary tables and indices.
14#
drh9da742f2009-06-16 17:49:36 +000015# $Id: temptable.test,v 1.21 2009/06/16 17:49:36 drh Exp $
drhf57b3392001-10-08 13:22:32 +000016
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
danielk197753c0f742005-03-29 03:10:59 +000020ifcapable !tempdb {
21 finish_test
22 return
23}
24
drhf57b3392001-10-08 13:22:32 +000025# Create an alternative connection to the database
26#
27do_test temptable-1.0 {
drhef4ac8f2004-06-19 00:16:31 +000028 sqlite3 db2 ./test.db
drhc22bd472002-05-10 13:14:07 +000029 set dummy {}
drhf57b3392001-10-08 13:22:32 +000030} {}
31
32# Create a permanent table.
33#
34do_test temptable-1.1 {
35 execsql {CREATE TABLE t1(a,b,c);}
36 execsql {INSERT INTO t1 VALUES(1,2,3);}
37 execsql {SELECT * FROM t1}
38} {1 2 3}
39do_test temptable-1.2 {
40 catch {db2 eval {SELECT * FROM sqlite_master}}
41 db2 eval {SELECT * FROM t1}
42} {1 2 3}
drhad75e982001-10-09 04:19:46 +000043do_test temptable-1.3 {
drhf57b3392001-10-08 13:22:32 +000044 execsql {SELECT name FROM sqlite_master}
45} {t1}
drhad75e982001-10-09 04:19:46 +000046do_test temptable-1.4 {
drhf57b3392001-10-08 13:22:32 +000047 db2 eval {SELECT name FROM sqlite_master}
48} {t1}
49
50# Create a temporary table. Verify that only one of the two
51# processes can see it.
52#
drhad75e982001-10-09 04:19:46 +000053do_test temptable-1.5 {
drhf57b3392001-10-08 13:22:32 +000054 db2 eval {
55 CREATE TEMP TABLE t2(x,y,z);
56 INSERT INTO t2 VALUES(4,5,6);
57 }
58 db2 eval {SELECT * FROM t2}
59} {4 5 6}
drhad75e982001-10-09 04:19:46 +000060do_test temptable-1.6 {
drhf57b3392001-10-08 13:22:32 +000061 catch {execsql {SELECT * FROM sqlite_master}}
62 catchsql {SELECT * FROM t2}
63} {1 {no such table: t2}}
drhad75e982001-10-09 04:19:46 +000064do_test temptable-1.7 {
drhf57b3392001-10-08 13:22:32 +000065 catchsql {INSERT INTO t2 VALUES(8,9,0);}
66} {1 {no such table: t2}}
drhad75e982001-10-09 04:19:46 +000067do_test temptable-1.8 {
drhf57b3392001-10-08 13:22:32 +000068 db2 eval {INSERT INTO t2 VALUES(8,9,0);}
69 db2 eval {SELECT * FROM t2 ORDER BY x}
70} {4 5 6 8 9 0}
drhad75e982001-10-09 04:19:46 +000071do_test temptable-1.9 {
drhf57b3392001-10-08 13:22:32 +000072 db2 eval {DELETE FROM t2 WHERE x==8}
73 db2 eval {SELECT * FROM t2 ORDER BY x}
74} {4 5 6}
drhad75e982001-10-09 04:19:46 +000075do_test temptable-1.10 {
drhf57b3392001-10-08 13:22:32 +000076 db2 eval {DELETE FROM t2}
77 db2 eval {SELECT * FROM t2}
78} {}
drhad75e982001-10-09 04:19:46 +000079do_test temptable-1.11 {
drhf57b3392001-10-08 13:22:32 +000080 db2 eval {
81 INSERT INTO t2 VALUES(7,6,5);
82 INSERT INTO t2 VALUES(4,3,2);
83 SELECT * FROM t2 ORDER BY x;
84 }
85} {4 3 2 7 6 5}
drhad75e982001-10-09 04:19:46 +000086do_test temptable-1.12 {
drhf57b3392001-10-08 13:22:32 +000087 db2 eval {DROP TABLE t2;}
88 set r [catch {db2 eval {SELECT * FROM t2}} msg]
89 lappend r $msg
90} {1 {no such table: t2}}
91
92# Make sure temporary tables work with transactions
93#
drhad75e982001-10-09 04:19:46 +000094do_test temptable-2.1 {
drhf57b3392001-10-08 13:22:32 +000095 execsql {
96 BEGIN TRANSACTION;
97 CREATE TEMPORARY TABLE t2(x,y);
98 INSERT INTO t2 VALUES(1,2);
99 SELECT * FROM t2;
100 }
101} {1 2}
drhad75e982001-10-09 04:19:46 +0000102do_test temptable-2.2 {
drhf57b3392001-10-08 13:22:32 +0000103 execsql {ROLLBACK}
104 catchsql {SELECT * FROM t2}
105} {1 {no such table: t2}}
drhad75e982001-10-09 04:19:46 +0000106do_test temptable-2.3 {
drhf57b3392001-10-08 13:22:32 +0000107 execsql {
108 BEGIN TRANSACTION;
109 CREATE TEMPORARY TABLE t2(x,y);
110 INSERT INTO t2 VALUES(1,2);
111 SELECT * FROM t2;
112 }
113} {1 2}
drhad75e982001-10-09 04:19:46 +0000114do_test temptable-2.4 {
drhf57b3392001-10-08 13:22:32 +0000115 execsql {COMMIT}
116 catchsql {SELECT * FROM t2}
117} {0 {1 2}}
drhad75e982001-10-09 04:19:46 +0000118do_test temptable-2.5 {
drhf57b3392001-10-08 13:22:32 +0000119 set r [catch {db2 eval {SELECT * FROM t2}} msg]
120 lappend r $msg
121} {1 {no such table: t2}}
122
drhad75e982001-10-09 04:19:46 +0000123# Make sure indices on temporary tables are also temporary.
124#
125do_test temptable-3.1 {
126 execsql {
127 CREATE INDEX i2 ON t2(x);
128 SELECT name FROM sqlite_master WHERE type='index';
129 }
130} {}
131do_test temptable-3.2 {
132 execsql {
133 SELECT y FROM t2 WHERE x=1;
134 }
135} {2}
136do_test temptable-3.3 {
137 execsql {
138 DROP INDEX i2;
139 SELECT y FROM t2 WHERE x=1;
140 }
141} {2}
142do_test temptable-3.4 {
143 execsql {
144 CREATE INDEX i2 ON t2(x);
145 DROP TABLE t2;
146 }
147 catchsql {DROP INDEX i2}
148} {1 {no such index: i2}}
149
drhf57b3392001-10-08 13:22:32 +0000150# Check for correct name collision processing. A name collision can
151# occur when process A creates a temporary table T then process B
152# creates a permanent table also named T. The temp table in process A
mistachkin48864df2013-03-21 21:20:32 +0000153# hides the existence of the permanent table.
drhf57b3392001-10-08 13:22:32 +0000154#
drhad75e982001-10-09 04:19:46 +0000155do_test temptable-4.1 {
drhda9e0342002-01-10 14:31:48 +0000156 execsql {
drhad75e982001-10-09 04:19:46 +0000157 CREATE TEMP TABLE t2(x,y);
158 INSERT INTO t2 VALUES(10,20);
159 SELECT * FROM t2;
drhda9e0342002-01-10 14:31:48 +0000160 } db2
drhad75e982001-10-09 04:19:46 +0000161} {10 20}
162do_test temptable-4.2 {
163 execsql {
164 CREATE TABLE t2(x,y,z);
165 INSERT INTO t2 VALUES(9,8,7);
166 SELECT * FROM t2;
167 }
168} {9 8 7}
169do_test temptable-4.3 {
drhda9e0342002-01-10 14:31:48 +0000170 catchsql {
171 SELECT * FROM t2;
172 } db2
drh8bf8dc92003-05-17 17:35:10 +0000173} {0 {10 20}}
drh0be9df02003-03-30 00:19:49 +0000174do_test temptable-4.4.1 {
175 catchsql {
176 SELECT * FROM temp.t2;
177 } db2
178} {0 {10 20}}
179do_test temptable-4.4.2 {
180 catchsql {
181 SELECT * FROM main.t2;
182 } db2
drh9da742f2009-06-16 17:49:36 +0000183} {0 {9 8 7}}
drha1f9b5e2004-02-14 16:31:02 +0000184#do_test temptable-4.4.3 {
185# catchsql {
186# SELECT name FROM main.sqlite_master WHERE type='table';
187# } db2
188#} {1 {database schema has changed}}
drh8bf8dc92003-05-17 17:35:10 +0000189do_test temptable-4.4.4 {
190 catchsql {
191 SELECT name FROM main.sqlite_master WHERE type='table';
192 } db2
193} {0 {t1 t2}}
194do_test temptable-4.4.5 {
195 catchsql {
196 SELECT * FROM main.t2;
197 } db2
198} {0 {9 8 7}}
199do_test temptable-4.4.6 {
drh0be9df02003-03-30 00:19:49 +0000200 # TEMP takes precedence over MAIN
drhda9e0342002-01-10 14:31:48 +0000201 catchsql {
202 SELECT * FROM t2;
203 } db2
drhad75e982001-10-09 04:19:46 +0000204} {0 {10 20}}
205do_test temptable-4.5 {
drhda9e0342002-01-10 14:31:48 +0000206 catchsql {
drh0be9df02003-03-30 00:19:49 +0000207 DROP TABLE t2; -- should drop TEMP
208 SELECT * FROM t2; -- data should be from MAIN
drhda9e0342002-01-10 14:31:48 +0000209 } db2
drh0be9df02003-03-30 00:19:49 +0000210} {0 {9 8 7}}
drhad75e982001-10-09 04:19:46 +0000211do_test temptable-4.6 {
212 db2 close
drhef4ac8f2004-06-19 00:16:31 +0000213 sqlite3 db2 ./test.db
drhda9e0342002-01-10 14:31:48 +0000214 catchsql {
215 SELECT * FROM t2;
216 } db2
drhad75e982001-10-09 04:19:46 +0000217} {0 {9 8 7}}
drhda9e0342002-01-10 14:31:48 +0000218do_test temptable-4.7 {
219 catchsql {
220 DROP TABLE t2;
221 SELECT * FROM t2;
222 }
223} {1 {no such table: t2}}
224do_test temptable-4.8 {
225 db2 close
drhef4ac8f2004-06-19 00:16:31 +0000226 sqlite3 db2 ./test.db
drhda9e0342002-01-10 14:31:48 +0000227 execsql {
228 CREATE TEMP TABLE t2(x unique,y);
229 INSERT INTO t2 VALUES(1,2);
230 SELECT * FROM t2;
231 } db2
232} {1 2}
233do_test temptable-4.9 {
234 execsql {
235 CREATE TABLE t2(x unique, y);
236 INSERT INTO t2 VALUES(3,4);
237 SELECT * FROM t2;
238 }
239} {3 4}
drh8bf8dc92003-05-17 17:35:10 +0000240do_test temptable-4.10.1 {
drhda9e0342002-01-10 14:31:48 +0000241 catchsql {
242 SELECT * FROM t2;
243 } db2
drh8bf8dc92003-05-17 17:35:10 +0000244} {0 {1 2}}
danielk1977f9d19a62004-06-14 08:26:35 +0000245# Update: The schema is reloaded in test temptable-4.10.1. And tclsqlite.c
246# handles it and retries the query anyway.
247# do_test temptable-4.10.2 {
248# catchsql {
249# SELECT name FROM sqlite_master WHERE type='table'
250# } db2
251# } {1 {database schema has changed}}
drh8bf8dc92003-05-17 17:35:10 +0000252do_test temptable-4.10.3 {
253 catchsql {
254 SELECT name FROM sqlite_master WHERE type='table'
255 } db2
256} {0 {t1 t2}}
drhda9e0342002-01-10 14:31:48 +0000257do_test temptable-4.11 {
258 execsql {
259 SELECT * FROM t2;
260 } db2
261} {1 2}
262do_test temptable-4.12 {
263 execsql {
264 SELECT * FROM t2;
265 }
266} {3 4}
267do_test temptable-4.13 {
268 catchsql {
drh0be9df02003-03-30 00:19:49 +0000269 DROP TABLE t2; -- drops TEMP.T2
270 SELECT * FROM t2; -- uses MAIN.T2
drhda9e0342002-01-10 14:31:48 +0000271 } db2
drh0be9df02003-03-30 00:19:49 +0000272} {0 {3 4}}
drhda9e0342002-01-10 14:31:48 +0000273do_test temptable-4.14 {
274 execsql {
275 SELECT * FROM t2;
276 }
277} {3 4}
278do_test temptable-4.15 {
279 db2 close
drhef4ac8f2004-06-19 00:16:31 +0000280 sqlite3 db2 ./test.db
drhda9e0342002-01-10 14:31:48 +0000281 execsql {
282 SELECT * FROM t2;
283 } db2
284} {3 4}
drhad75e982001-10-09 04:19:46 +0000285
286# Now create a temporary table in db2 and a permanent index in db. The
287# temporary table in db2 should mask the name of the permanent index,
288# but the permanent index should still be accessible and should still
drhda9e0342002-01-10 14:31:48 +0000289# be updated when its corresponding table changes.
drhad75e982001-10-09 04:19:46 +0000290#
291do_test temptable-5.1 {
drhda9e0342002-01-10 14:31:48 +0000292 execsql {
293 CREATE TEMP TABLE mask(a,b,c)
294 } db2
danc431fd52011-06-27 16:55:50 +0000295 if {[permutation]=="prepare"} { db2 cache flush }
drhad75e982001-10-09 04:19:46 +0000296 execsql {
297 CREATE INDEX mask ON t2(x);
298 SELECT * FROM t2;
299 }
drhda9e0342002-01-10 14:31:48 +0000300} {3 4}
drha1f9b5e2004-02-14 16:31:02 +0000301#do_test temptable-5.2 {
302# catchsql {
303# SELECT * FROM t2;
304# } db2
305#} {1 {database schema has changed}}
drhad75e982001-10-09 04:19:46 +0000306do_test temptable-5.3 {
drhda9e0342002-01-10 14:31:48 +0000307 catchsql {
308 SELECT * FROM t2;
309 } db2
310} {0 {3 4}}
drhad75e982001-10-09 04:19:46 +0000311do_test temptable-5.4 {
drhda9e0342002-01-10 14:31:48 +0000312 execsql {
313 SELECT y FROM t2 WHERE x=3
drhad75e982001-10-09 04:19:46 +0000314 }
drhda9e0342002-01-10 14:31:48 +0000315} {4}
316do_test temptable-5.5 {
317 execsql {
318 SELECT y FROM t2 WHERE x=3
319 } db2
320} {4}
321do_test temptable-5.6 {
322 execsql {
323 INSERT INTO t2 VALUES(1,2);
324 SELECT y FROM t2 WHERE x=1;
325 } db2
drhad75e982001-10-09 04:19:46 +0000326} {2}
327do_test temptable-5.7 {
drhda9e0342002-01-10 14:31:48 +0000328 execsql {
329 SELECT y FROM t2 WHERE x=3
330 } db2
331} {4}
drhad75e982001-10-09 04:19:46 +0000332do_test temptable-5.8 {
333 execsql {
334 SELECT y FROM t2 WHERE x=1;
335 }
336} {2}
337do_test temptable-5.9 {
drhda9e0342002-01-10 14:31:48 +0000338 execsql {
339 SELECT y FROM t2 WHERE x=3
340 }
341} {4}
drhf57b3392001-10-08 13:22:32 +0000342
drhff0839c2001-10-09 12:39:24 +0000343db2 close
344
drh5df72a52002-06-06 23:16:05 +0000345# Test for correct operation of read-only databases
346#
347do_test temptable-6.1 {
348 execsql {
349 CREATE TABLE t8(x);
350 INSERT INTO t8 VALUES('xyzzy');
351 SELECT * FROM t8;
352 }
353} {xyzzy}
354do_test temptable-6.2 {
355 db close
356 catch {file attributes test.db -permissions 0444}
357 catch {file attributes test.db -readonly 1}
drhef4ac8f2004-06-19 00:16:31 +0000358 sqlite3 db test.db
drh0e1cfb82002-09-02 12:14:50 +0000359 if {[file writable test.db]} {
360 error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
361 }
drh5df72a52002-06-06 23:16:05 +0000362 execsql {
363 SELECT * FROM t8;
364 }
365} {xyzzy}
366do_test temptable-6.3 {
drh0e1cfb82002-09-02 12:14:50 +0000367 if {[file writable test.db]} {
368 error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
369 }
drh5df72a52002-06-06 23:16:05 +0000370 catchsql {
371 CREATE TABLE t9(x,y);
372 }
373} {1 {attempt to write a readonly database}}
374do_test temptable-6.4 {
375 catchsql {
376 CREATE TEMP TABLE t9(x,y);
377 }
378} {0 {}}
379do_test temptable-6.5 {
380 catchsql {
381 INSERT INTO t9 VALUES(1,2);
382 SELECT * FROM t9;
383 }
384} {0 {1 2}}
385do_test temptable-6.6 {
drh0e1cfb82002-09-02 12:14:50 +0000386 if {[file writable test.db]} {
387 error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
388 }
drh5df72a52002-06-06 23:16:05 +0000389 catchsql {
390 INSERT INTO t8 VALUES('hello');
391 SELECT * FROM t8;
392 }
393} {1 {attempt to write a readonly database}}
394do_test temptable-6.7 {
395 catchsql {
396 SELECT * FROM t8,t9;
397 }
398} {0 {xyzzy 1 2}}
399do_test temptable-6.8 {
400 db close
drhef4ac8f2004-06-19 00:16:31 +0000401 sqlite3 db test.db
drh5df72a52002-06-06 23:16:05 +0000402 catchsql {
403 SELECT * FROM t8,t9;
404 }
405} {1 {no such table: t9}}
406
mistachkinfda06be2011-08-02 00:57:34 +0000407forcedelete test2.db test2.db-journal
danielk19775a8f9372007-10-09 08:29:32 +0000408ifcapable attach {
409 do_test temptable-7.1 {
410 catchsql {
411 ATTACH 'test2.db' AS two;
412 CREATE TEMP TABLE two.abc(x,y);
413 }
414 } {1 {temporary table name must be unqualified}}
415}
drh85c23c62005-08-20 03:03:04 +0000416
danielk1977382e28f2007-10-05 15:53:29 +0000417# Need to do the following for tcl 8.5 on mac. On that configuration, the
mistachkinfda06be2011-08-02 00:57:34 +0000418# -readonly flag is taken so seriously that a subsequent [forcedelete]
danielk1977382e28f2007-10-05 15:53:29 +0000419# (required before the next test file can be executed) will fail.
420#
421catch {file attributes test.db -readonly 0}
422
danielk1977cd503d62009-02-10 11:17:43 +0000423do_test temptable-8.0 {
424 db close
mistachkinfda06be2011-08-02 00:57:34 +0000425 catch {forcedelete test.db}
danielk1977cd503d62009-02-10 11:17:43 +0000426 sqlite3 db test.db
427} {}
428do_test temptable-8.1 {
429 execsql { CREATE TEMP TABLE tbl2(a, b); }
430 execsql {
431 CREATE TABLE tbl(a, b);
432 INSERT INTO tbl VALUES(1, 2);
433 }
434 execsql {SELECT * FROM tbl}
435} {1 2}
436do_test temptable-8.2 {
437 execsql { CREATE TEMP TABLE tbl(a, b); }
438 execsql {SELECT * FROM tbl}
439} {}
440
drhf57b3392001-10-08 13:22:32 +0000441finish_test