1: # 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: #
15: # $Id: temptable.test,v 1.1.1.1 2012/02/21 17:04:16 misho Exp $
16:
17: set testdir [file dirname $argv0]
18: source $testdir/tester.tcl
19:
20: ifcapable !tempdb {
21: finish_test
22: return
23: }
24:
25: # Create an alternative connection to the database
26: #
27: do_test temptable-1.0 {
28: sqlite3 db2 ./test.db
29: set dummy {}
30: } {}
31:
32: # Create a permanent table.
33: #
34: do_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}
39: do_test temptable-1.2 {
40: catch {db2 eval {SELECT * FROM sqlite_master}}
41: db2 eval {SELECT * FROM t1}
42: } {1 2 3}
43: do_test temptable-1.3 {
44: execsql {SELECT name FROM sqlite_master}
45: } {t1}
46: do_test temptable-1.4 {
47: 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: #
53: do_test temptable-1.5 {
54: 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}
60: do_test temptable-1.6 {
61: catch {execsql {SELECT * FROM sqlite_master}}
62: catchsql {SELECT * FROM t2}
63: } {1 {no such table: t2}}
64: do_test temptable-1.7 {
65: catchsql {INSERT INTO t2 VALUES(8,9,0);}
66: } {1 {no such table: t2}}
67: do_test temptable-1.8 {
68: 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}
71: do_test temptable-1.9 {
72: db2 eval {DELETE FROM t2 WHERE x==8}
73: db2 eval {SELECT * FROM t2 ORDER BY x}
74: } {4 5 6}
75: do_test temptable-1.10 {
76: db2 eval {DELETE FROM t2}
77: db2 eval {SELECT * FROM t2}
78: } {}
79: do_test temptable-1.11 {
80: 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}
86: do_test temptable-1.12 {
87: 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: #
94: do_test temptable-2.1 {
95: 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}
102: do_test temptable-2.2 {
103: execsql {ROLLBACK}
104: catchsql {SELECT * FROM t2}
105: } {1 {no such table: t2}}
106: do_test temptable-2.3 {
107: 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}
114: do_test temptable-2.4 {
115: execsql {COMMIT}
116: catchsql {SELECT * FROM t2}
117: } {0 {1 2}}
118: do_test temptable-2.5 {
119: set r [catch {db2 eval {SELECT * FROM t2}} msg]
120: lappend r $msg
121: } {1 {no such table: t2}}
122:
123: # Make sure indices on temporary tables are also temporary.
124: #
125: do_test temptable-3.1 {
126: execsql {
127: CREATE INDEX i2 ON t2(x);
128: SELECT name FROM sqlite_master WHERE type='index';
129: }
130: } {}
131: do_test temptable-3.2 {
132: execsql {
133: SELECT y FROM t2 WHERE x=1;
134: }
135: } {2}
136: do_test temptable-3.3 {
137: execsql {
138: DROP INDEX i2;
139: SELECT y FROM t2 WHERE x=1;
140: }
141: } {2}
142: do_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:
150: # 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
153: # hides the existance of the permanent table.
154: #
155: do_test temptable-4.1 {
156: execsql {
157: CREATE TEMP TABLE t2(x,y);
158: INSERT INTO t2 VALUES(10,20);
159: SELECT * FROM t2;
160: } db2
161: } {10 20}
162: do_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}
169: do_test temptable-4.3 {
170: catchsql {
171: SELECT * FROM t2;
172: } db2
173: } {0 {10 20}}
174: do_test temptable-4.4.1 {
175: catchsql {
176: SELECT * FROM temp.t2;
177: } db2
178: } {0 {10 20}}
179: do_test temptable-4.4.2 {
180: catchsql {
181: SELECT * FROM main.t2;
182: } db2
183: } {0 {9 8 7}}
184: #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}}
189: do_test temptable-4.4.4 {
190: catchsql {
191: SELECT name FROM main.sqlite_master WHERE type='table';
192: } db2
193: } {0 {t1 t2}}
194: do_test temptable-4.4.5 {
195: catchsql {
196: SELECT * FROM main.t2;
197: } db2
198: } {0 {9 8 7}}
199: do_test temptable-4.4.6 {
200: # TEMP takes precedence over MAIN
201: catchsql {
202: SELECT * FROM t2;
203: } db2
204: } {0 {10 20}}
205: do_test temptable-4.5 {
206: catchsql {
207: DROP TABLE t2; -- should drop TEMP
208: SELECT * FROM t2; -- data should be from MAIN
209: } db2
210: } {0 {9 8 7}}
211: do_test temptable-4.6 {
212: db2 close
213: sqlite3 db2 ./test.db
214: catchsql {
215: SELECT * FROM t2;
216: } db2
217: } {0 {9 8 7}}
218: do_test temptable-4.7 {
219: catchsql {
220: DROP TABLE t2;
221: SELECT * FROM t2;
222: }
223: } {1 {no such table: t2}}
224: do_test temptable-4.8 {
225: db2 close
226: sqlite3 db2 ./test.db
227: 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}
233: do_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}
240: do_test temptable-4.10.1 {
241: catchsql {
242: SELECT * FROM t2;
243: } db2
244: } {0 {1 2}}
245: # 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}}
252: do_test temptable-4.10.3 {
253: catchsql {
254: SELECT name FROM sqlite_master WHERE type='table'
255: } db2
256: } {0 {t1 t2}}
257: do_test temptable-4.11 {
258: execsql {
259: SELECT * FROM t2;
260: } db2
261: } {1 2}
262: do_test temptable-4.12 {
263: execsql {
264: SELECT * FROM t2;
265: }
266: } {3 4}
267: do_test temptable-4.13 {
268: catchsql {
269: DROP TABLE t2; -- drops TEMP.T2
270: SELECT * FROM t2; -- uses MAIN.T2
271: } db2
272: } {0 {3 4}}
273: do_test temptable-4.14 {
274: execsql {
275: SELECT * FROM t2;
276: }
277: } {3 4}
278: do_test temptable-4.15 {
279: db2 close
280: sqlite3 db2 ./test.db
281: execsql {
282: SELECT * FROM t2;
283: } db2
284: } {3 4}
285:
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
289: # be updated when its corresponding table changes.
290: #
291: do_test temptable-5.1 {
292: execsql {
293: CREATE TEMP TABLE mask(a,b,c)
294: } db2
295: if {[permutation]=="prepare"} { db2 cache flush }
296: execsql {
297: CREATE INDEX mask ON t2(x);
298: SELECT * FROM t2;
299: }
300: } {3 4}
301: #do_test temptable-5.2 {
302: # catchsql {
303: # SELECT * FROM t2;
304: # } db2
305: #} {1 {database schema has changed}}
306: do_test temptable-5.3 {
307: catchsql {
308: SELECT * FROM t2;
309: } db2
310: } {0 {3 4}}
311: do_test temptable-5.4 {
312: execsql {
313: SELECT y FROM t2 WHERE x=3
314: }
315: } {4}
316: do_test temptable-5.5 {
317: execsql {
318: SELECT y FROM t2 WHERE x=3
319: } db2
320: } {4}
321: do_test temptable-5.6 {
322: execsql {
323: INSERT INTO t2 VALUES(1,2);
324: SELECT y FROM t2 WHERE x=1;
325: } db2
326: } {2}
327: do_test temptable-5.7 {
328: execsql {
329: SELECT y FROM t2 WHERE x=3
330: } db2
331: } {4}
332: do_test temptable-5.8 {
333: execsql {
334: SELECT y FROM t2 WHERE x=1;
335: }
336: } {2}
337: do_test temptable-5.9 {
338: execsql {
339: SELECT y FROM t2 WHERE x=3
340: }
341: } {4}
342:
343: db2 close
344:
345: # Test for correct operation of read-only databases
346: #
347: do_test temptable-6.1 {
348: execsql {
349: CREATE TABLE t8(x);
350: INSERT INTO t8 VALUES('xyzzy');
351: SELECT * FROM t8;
352: }
353: } {xyzzy}
354: do_test temptable-6.2 {
355: db close
356: catch {file attributes test.db -permissions 0444}
357: catch {file attributes test.db -readonly 1}
358: sqlite3 db test.db
359: if {[file writable test.db]} {
360: error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
361: }
362: execsql {
363: SELECT * FROM t8;
364: }
365: } {xyzzy}
366: do_test temptable-6.3 {
367: if {[file writable test.db]} {
368: error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
369: }
370: catchsql {
371: CREATE TABLE t9(x,y);
372: }
373: } {1 {attempt to write a readonly database}}
374: do_test temptable-6.4 {
375: catchsql {
376: CREATE TEMP TABLE t9(x,y);
377: }
378: } {0 {}}
379: do_test temptable-6.5 {
380: catchsql {
381: INSERT INTO t9 VALUES(1,2);
382: SELECT * FROM t9;
383: }
384: } {0 {1 2}}
385: do_test temptable-6.6 {
386: if {[file writable test.db]} {
387: error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
388: }
389: catchsql {
390: INSERT INTO t8 VALUES('hello');
391: SELECT * FROM t8;
392: }
393: } {1 {attempt to write a readonly database}}
394: do_test temptable-6.7 {
395: catchsql {
396: SELECT * FROM t8,t9;
397: }
398: } {0 {xyzzy 1 2}}
399: do_test temptable-6.8 {
400: db close
401: sqlite3 db test.db
402: catchsql {
403: SELECT * FROM t8,t9;
404: }
405: } {1 {no such table: t9}}
406:
407: forcedelete test2.db test2.db-journal
408: ifcapable 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: }
416:
417: # Need to do the following for tcl 8.5 on mac. On that configuration, the
418: # -readonly flag is taken so seriously that a subsequent [forcedelete]
419: # (required before the next test file can be executed) will fail.
420: #
421: catch {file attributes test.db -readonly 0}
422:
423: do_test temptable-8.0 {
424: db close
425: catch {forcedelete test.db}
426: sqlite3 db test.db
427: } {}
428: do_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}
436: do_test temptable-8.2 {
437: execsql { CREATE TEMP TABLE tbl(a, b); }
438: execsql {SELECT * FROM tbl}
439: } {}
440:
441: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>