xref: /onnv-gate/usr/src/lib/libsqlite/test/temptable.test (revision 4520:7dbeadedd7fe)
1*4520Snw141292
2*4520Snw141292#pragma ident	"%Z%%M%	%I%	%E% SMI"
3*4520Snw141292
4*4520Snw141292# 2001 October 7
5*4520Snw141292#
6*4520Snw141292# The author disclaims copyright to this source code.  In place of
7*4520Snw141292# a legal notice, here is a blessing:
8*4520Snw141292#
9*4520Snw141292#    May you do good and not evil.
10*4520Snw141292#    May you find forgiveness for yourself and forgive others.
11*4520Snw141292#    May you share freely, never taking more than you give.
12*4520Snw141292#
13*4520Snw141292#***********************************************************************
14*4520Snw141292# This file implements regression tests for SQLite library.
15*4520Snw141292#
16*4520Snw141292# This file implements tests for temporary tables and indices.
17*4520Snw141292#
18*4520Snw141292# $Id: temptable.test,v 1.11 2004/02/14 16:31:04 drh Exp $
19*4520Snw141292
20*4520Snw141292set testdir [file dirname $argv0]
21*4520Snw141292source $testdir/tester.tcl
22*4520Snw141292
23*4520Snw141292# Create an alternative connection to the database
24*4520Snw141292#
25*4520Snw141292do_test temptable-1.0 {
26*4520Snw141292  sqlite db2 ./test.db
27*4520Snw141292  set dummy {}
28*4520Snw141292} {}
29*4520Snw141292
30*4520Snw141292# Create a permanent table.
31*4520Snw141292#
32*4520Snw141292do_test temptable-1.1 {
33*4520Snw141292  execsql {CREATE TABLE t1(a,b,c);}
34*4520Snw141292  execsql {INSERT INTO t1 VALUES(1,2,3);}
35*4520Snw141292  execsql {SELECT * FROM t1}
36*4520Snw141292} {1 2 3}
37*4520Snw141292do_test temptable-1.2 {
38*4520Snw141292  catch {db2 eval {SELECT * FROM sqlite_master}}
39*4520Snw141292  db2 eval {SELECT * FROM t1}
40*4520Snw141292} {1 2 3}
41*4520Snw141292do_test temptable-1.3 {
42*4520Snw141292  execsql {SELECT name FROM sqlite_master}
43*4520Snw141292} {t1}
44*4520Snw141292do_test temptable-1.4 {
45*4520Snw141292  db2 eval {SELECT name FROM sqlite_master}
46*4520Snw141292} {t1}
47*4520Snw141292
48*4520Snw141292# Create a temporary table.  Verify that only one of the two
49*4520Snw141292# processes can see it.
50*4520Snw141292#
51*4520Snw141292do_test temptable-1.5 {
52*4520Snw141292  db2 eval {
53*4520Snw141292    CREATE TEMP TABLE t2(x,y,z);
54*4520Snw141292    INSERT INTO t2 VALUES(4,5,6);
55*4520Snw141292  }
56*4520Snw141292  db2 eval {SELECT * FROM t2}
57*4520Snw141292} {4 5 6}
58*4520Snw141292do_test temptable-1.6 {
59*4520Snw141292  catch {execsql {SELECT * FROM sqlite_master}}
60*4520Snw141292  catchsql {SELECT * FROM t2}
61*4520Snw141292} {1 {no such table: t2}}
62*4520Snw141292do_test temptable-1.7 {
63*4520Snw141292  catchsql {INSERT INTO t2 VALUES(8,9,0);}
64*4520Snw141292} {1 {no such table: t2}}
65*4520Snw141292do_test temptable-1.8 {
66*4520Snw141292  db2 eval {INSERT INTO t2 VALUES(8,9,0);}
67*4520Snw141292  db2 eval {SELECT * FROM t2 ORDER BY x}
68*4520Snw141292} {4 5 6 8 9 0}
69*4520Snw141292do_test temptable-1.9 {
70*4520Snw141292  db2 eval {DELETE FROM t2 WHERE x==8}
71*4520Snw141292  db2 eval {SELECT * FROM t2 ORDER BY x}
72*4520Snw141292} {4 5 6}
73*4520Snw141292do_test temptable-1.10 {
74*4520Snw141292  db2 eval {DELETE FROM t2}
75*4520Snw141292  db2 eval {SELECT * FROM t2}
76*4520Snw141292} {}
77*4520Snw141292do_test temptable-1.11 {
78*4520Snw141292  db2 eval {
79*4520Snw141292     INSERT INTO t2 VALUES(7,6,5);
80*4520Snw141292     INSERT INTO t2 VALUES(4,3,2);
81*4520Snw141292     SELECT * FROM t2 ORDER BY x;
82*4520Snw141292  }
83*4520Snw141292} {4 3 2 7 6 5}
84*4520Snw141292do_test temptable-1.12 {
85*4520Snw141292  db2 eval {DROP TABLE t2;}
86*4520Snw141292  set r [catch {db2 eval {SELECT * FROM t2}} msg]
87*4520Snw141292  lappend r $msg
88*4520Snw141292} {1 {no such table: t2}}
89*4520Snw141292
90*4520Snw141292# Make sure temporary tables work with transactions
91*4520Snw141292#
92*4520Snw141292do_test temptable-2.1 {
93*4520Snw141292  execsql {
94*4520Snw141292    BEGIN TRANSACTION;
95*4520Snw141292    CREATE TEMPORARY TABLE t2(x,y);
96*4520Snw141292    INSERT INTO t2 VALUES(1,2);
97*4520Snw141292    SELECT * FROM t2;
98*4520Snw141292  }
99*4520Snw141292} {1 2}
100*4520Snw141292do_test temptable-2.2 {
101*4520Snw141292  execsql {ROLLBACK}
102*4520Snw141292  catchsql {SELECT * FROM t2}
103*4520Snw141292} {1 {no such table: t2}}
104*4520Snw141292do_test temptable-2.3 {
105*4520Snw141292  execsql {
106*4520Snw141292    BEGIN TRANSACTION;
107*4520Snw141292    CREATE TEMPORARY TABLE t2(x,y);
108*4520Snw141292    INSERT INTO t2 VALUES(1,2);
109*4520Snw141292    SELECT * FROM t2;
110*4520Snw141292  }
111*4520Snw141292} {1 2}
112*4520Snw141292do_test temptable-2.4 {
113*4520Snw141292  execsql {COMMIT}
114*4520Snw141292  catchsql {SELECT * FROM t2}
115*4520Snw141292} {0 {1 2}}
116*4520Snw141292do_test temptable-2.5 {
117*4520Snw141292  set r [catch {db2 eval {SELECT * FROM t2}} msg]
118*4520Snw141292  lappend r $msg
119*4520Snw141292} {1 {no such table: t2}}
120*4520Snw141292
121*4520Snw141292# Make sure indices on temporary tables are also temporary.
122*4520Snw141292#
123*4520Snw141292do_test temptable-3.1 {
124*4520Snw141292  execsql {
125*4520Snw141292    CREATE INDEX i2 ON t2(x);
126*4520Snw141292    SELECT name FROM sqlite_master WHERE type='index';
127*4520Snw141292  }
128*4520Snw141292} {}
129*4520Snw141292do_test temptable-3.2 {
130*4520Snw141292  execsql {
131*4520Snw141292    SELECT y FROM t2 WHERE x=1;
132*4520Snw141292  }
133*4520Snw141292} {2}
134*4520Snw141292do_test temptable-3.3 {
135*4520Snw141292  execsql {
136*4520Snw141292    DROP INDEX i2;
137*4520Snw141292    SELECT y FROM t2 WHERE x=1;
138*4520Snw141292  }
139*4520Snw141292} {2}
140*4520Snw141292do_test temptable-3.4 {
141*4520Snw141292  execsql {
142*4520Snw141292    CREATE INDEX i2 ON t2(x);
143*4520Snw141292    DROP TABLE t2;
144*4520Snw141292  }
145*4520Snw141292  catchsql {DROP INDEX i2}
146*4520Snw141292} {1 {no such index: i2}}
147*4520Snw141292
148*4520Snw141292# Check for correct name collision processing. A name collision can
149*4520Snw141292# occur when process A creates a temporary table T then process B
150*4520Snw141292# creates a permanent table also named T.  The temp table in process A
151*4520Snw141292# hides the existance of the permanent table.
152*4520Snw141292#
153*4520Snw141292do_test temptable-4.1 {
154*4520Snw141292  execsql {
155*4520Snw141292    CREATE TEMP TABLE t2(x,y);
156*4520Snw141292    INSERT INTO t2 VALUES(10,20);
157*4520Snw141292    SELECT * FROM t2;
158*4520Snw141292  } db2
159*4520Snw141292} {10 20}
160*4520Snw141292do_test temptable-4.2 {
161*4520Snw141292  execsql {
162*4520Snw141292    CREATE TABLE t2(x,y,z);
163*4520Snw141292    INSERT INTO t2 VALUES(9,8,7);
164*4520Snw141292    SELECT * FROM t2;
165*4520Snw141292  }
166*4520Snw141292} {9 8 7}
167*4520Snw141292do_test temptable-4.3 {
168*4520Snw141292  catchsql {
169*4520Snw141292    SELECT * FROM t2;
170*4520Snw141292  } db2
171*4520Snw141292} {0 {10 20}}
172*4520Snw141292do_test temptable-4.4.1 {
173*4520Snw141292  catchsql {
174*4520Snw141292    SELECT * FROM temp.t2;
175*4520Snw141292  } db2
176*4520Snw141292} {0 {10 20}}
177*4520Snw141292do_test temptable-4.4.2 {
178*4520Snw141292  catchsql {
179*4520Snw141292    SELECT * FROM main.t2;
180*4520Snw141292  } db2
181*4520Snw141292} {1 {no such table: main.t2}}
182*4520Snw141292#do_test temptable-4.4.3 {
183*4520Snw141292#  catchsql {
184*4520Snw141292#    SELECT name FROM main.sqlite_master WHERE type='table';
185*4520Snw141292#  } db2
186*4520Snw141292#} {1 {database schema has changed}}
187*4520Snw141292do_test temptable-4.4.4 {
188*4520Snw141292  catchsql {
189*4520Snw141292    SELECT name FROM main.sqlite_master WHERE type='table';
190*4520Snw141292  } db2
191*4520Snw141292} {0 {t1 t2}}
192*4520Snw141292do_test temptable-4.4.5 {
193*4520Snw141292  catchsql {
194*4520Snw141292    SELECT * FROM main.t2;
195*4520Snw141292  } db2
196*4520Snw141292} {0 {9 8 7}}
197*4520Snw141292do_test temptable-4.4.6 {
198*4520Snw141292  # TEMP takes precedence over MAIN
199*4520Snw141292  catchsql {
200*4520Snw141292    SELECT * FROM t2;
201*4520Snw141292  } db2
202*4520Snw141292} {0 {10 20}}
203*4520Snw141292do_test temptable-4.5 {
204*4520Snw141292  catchsql {
205*4520Snw141292    DROP TABLE t2;     -- should drop TEMP
206*4520Snw141292    SELECT * FROM t2;  -- data should be from MAIN
207*4520Snw141292  } db2
208*4520Snw141292} {0 {9 8 7}}
209*4520Snw141292do_test temptable-4.6 {
210*4520Snw141292  db2 close
211*4520Snw141292  sqlite db2 ./test.db
212*4520Snw141292  catchsql {
213*4520Snw141292    SELECT * FROM t2;
214*4520Snw141292  } db2
215*4520Snw141292} {0 {9 8 7}}
216*4520Snw141292do_test temptable-4.7 {
217*4520Snw141292  catchsql {
218*4520Snw141292    DROP TABLE t2;
219*4520Snw141292    SELECT * FROM t2;
220*4520Snw141292  }
221*4520Snw141292} {1 {no such table: t2}}
222*4520Snw141292do_test temptable-4.8 {
223*4520Snw141292  db2 close
224*4520Snw141292  sqlite db2 ./test.db
225*4520Snw141292  execsql {
226*4520Snw141292    CREATE TEMP TABLE t2(x unique,y);
227*4520Snw141292    INSERT INTO t2 VALUES(1,2);
228*4520Snw141292    SELECT * FROM t2;
229*4520Snw141292  } db2
230*4520Snw141292} {1 2}
231*4520Snw141292do_test temptable-4.9 {
232*4520Snw141292  execsql {
233*4520Snw141292    CREATE TABLE t2(x unique, y);
234*4520Snw141292    INSERT INTO t2 VALUES(3,4);
235*4520Snw141292    SELECT * FROM t2;
236*4520Snw141292  }
237*4520Snw141292} {3 4}
238*4520Snw141292do_test temptable-4.10.1 {
239*4520Snw141292  catchsql {
240*4520Snw141292    SELECT * FROM t2;
241*4520Snw141292  } db2
242*4520Snw141292} {0 {1 2}}
243*4520Snw141292#do_test temptable-4.10.2 {
244*4520Snw141292#  catchsql {
245*4520Snw141292#    SELECT name FROM sqlite_master WHERE type='table'
246*4520Snw141292#  } db2
247*4520Snw141292#} {1 {database schema has changed}}
248*4520Snw141292do_test temptable-4.10.3 {
249*4520Snw141292  catchsql {
250*4520Snw141292    SELECT name FROM sqlite_master WHERE type='table'
251*4520Snw141292  } db2
252*4520Snw141292} {0 {t1 t2}}
253*4520Snw141292do_test temptable-4.11 {
254*4520Snw141292  execsql {
255*4520Snw141292    SELECT * FROM t2;
256*4520Snw141292  } db2
257*4520Snw141292} {1 2}
258*4520Snw141292do_test temptable-4.12 {
259*4520Snw141292  execsql {
260*4520Snw141292    SELECT * FROM t2;
261*4520Snw141292  }
262*4520Snw141292} {3 4}
263*4520Snw141292do_test temptable-4.13 {
264*4520Snw141292  catchsql {
265*4520Snw141292    DROP TABLE t2;     -- drops TEMP.T2
266*4520Snw141292    SELECT * FROM t2;  -- uses MAIN.T2
267*4520Snw141292  } db2
268*4520Snw141292} {0 {3 4}}
269*4520Snw141292do_test temptable-4.14 {
270*4520Snw141292  execsql {
271*4520Snw141292    SELECT * FROM t2;
272*4520Snw141292  }
273*4520Snw141292} {3 4}
274*4520Snw141292do_test temptable-4.15 {
275*4520Snw141292  db2 close
276*4520Snw141292  sqlite db2 ./test.db
277*4520Snw141292  execsql {
278*4520Snw141292    SELECT * FROM t2;
279*4520Snw141292  } db2
280*4520Snw141292} {3 4}
281*4520Snw141292
282*4520Snw141292# Now create a temporary table in db2 and a permanent index in db.  The
283*4520Snw141292# temporary table in db2 should mask the name of the permanent index,
284*4520Snw141292# but the permanent index should still be accessible and should still
285*4520Snw141292# be updated when its corresponding table changes.
286*4520Snw141292#
287*4520Snw141292do_test temptable-5.1 {
288*4520Snw141292  execsql {
289*4520Snw141292    CREATE TEMP TABLE mask(a,b,c)
290*4520Snw141292  } db2
291*4520Snw141292  execsql {
292*4520Snw141292    CREATE INDEX mask ON t2(x);
293*4520Snw141292    SELECT * FROM t2;
294*4520Snw141292  }
295*4520Snw141292} {3 4}
296*4520Snw141292#do_test temptable-5.2 {
297*4520Snw141292#  catchsql {
298*4520Snw141292#    SELECT * FROM t2;
299*4520Snw141292#  } db2
300*4520Snw141292#} {1 {database schema has changed}}
301*4520Snw141292do_test temptable-5.3 {
302*4520Snw141292  catchsql {
303*4520Snw141292    SELECT * FROM t2;
304*4520Snw141292  } db2
305*4520Snw141292} {0 {3 4}}
306*4520Snw141292do_test temptable-5.4 {
307*4520Snw141292  execsql {
308*4520Snw141292    SELECT y FROM t2 WHERE x=3
309*4520Snw141292  }
310*4520Snw141292} {4}
311*4520Snw141292do_test temptable-5.5 {
312*4520Snw141292  execsql {
313*4520Snw141292    SELECT y FROM t2 WHERE x=3
314*4520Snw141292  } db2
315*4520Snw141292} {4}
316*4520Snw141292do_test temptable-5.6 {
317*4520Snw141292  execsql {
318*4520Snw141292    INSERT INTO t2 VALUES(1,2);
319*4520Snw141292    SELECT y FROM t2 WHERE x=1;
320*4520Snw141292  } db2
321*4520Snw141292} {2}
322*4520Snw141292do_test temptable-5.7 {
323*4520Snw141292  execsql {
324*4520Snw141292    SELECT y FROM t2 WHERE x=3
325*4520Snw141292  } db2
326*4520Snw141292} {4}
327*4520Snw141292do_test temptable-5.8 {
328*4520Snw141292  execsql {
329*4520Snw141292    SELECT y FROM t2 WHERE x=1;
330*4520Snw141292  }
331*4520Snw141292} {2}
332*4520Snw141292do_test temptable-5.9 {
333*4520Snw141292  execsql {
334*4520Snw141292    SELECT y FROM t2 WHERE x=3
335*4520Snw141292  }
336*4520Snw141292} {4}
337*4520Snw141292
338*4520Snw141292db2 close
339*4520Snw141292
340*4520Snw141292# Test for correct operation of read-only databases
341*4520Snw141292#
342*4520Snw141292do_test temptable-6.1 {
343*4520Snw141292  execsql {
344*4520Snw141292    CREATE TABLE t8(x);
345*4520Snw141292    INSERT INTO t8 VALUES('xyzzy');
346*4520Snw141292    SELECT * FROM t8;
347*4520Snw141292  }
348*4520Snw141292} {xyzzy}
349*4520Snw141292do_test temptable-6.2 {
350*4520Snw141292  db close
351*4520Snw141292  catch {file attributes test.db -permissions 0444}
352*4520Snw141292  catch {file attributes test.db -readonly 1}
353*4520Snw141292  sqlite db test.db
354*4520Snw141292  if {[file writable test.db]} {
355*4520Snw141292    error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
356*4520Snw141292  }
357*4520Snw141292  execsql {
358*4520Snw141292    SELECT * FROM t8;
359*4520Snw141292  }
360*4520Snw141292} {xyzzy}
361*4520Snw141292do_test temptable-6.3 {
362*4520Snw141292  if {[file writable test.db]} {
363*4520Snw141292    error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
364*4520Snw141292  }
365*4520Snw141292  catchsql {
366*4520Snw141292    CREATE TABLE t9(x,y);
367*4520Snw141292  }
368*4520Snw141292} {1 {attempt to write a readonly database}}
369*4520Snw141292do_test temptable-6.4 {
370*4520Snw141292  catchsql {
371*4520Snw141292    CREATE TEMP TABLE t9(x,y);
372*4520Snw141292  }
373*4520Snw141292} {0 {}}
374*4520Snw141292do_test temptable-6.5 {
375*4520Snw141292  catchsql {
376*4520Snw141292    INSERT INTO t9 VALUES(1,2);
377*4520Snw141292    SELECT * FROM t9;
378*4520Snw141292  }
379*4520Snw141292} {0 {1 2}}
380*4520Snw141292do_test temptable-6.6 {
381*4520Snw141292  if {[file writable test.db]} {
382*4520Snw141292    error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
383*4520Snw141292  }
384*4520Snw141292  catchsql {
385*4520Snw141292    INSERT INTO t8 VALUES('hello');
386*4520Snw141292    SELECT * FROM t8;
387*4520Snw141292  }
388*4520Snw141292} {1 {attempt to write a readonly database}}
389*4520Snw141292do_test temptable-6.7 {
390*4520Snw141292  catchsql {
391*4520Snw141292    SELECT * FROM t8,t9;
392*4520Snw141292  }
393*4520Snw141292} {0 {xyzzy 1 2}}
394*4520Snw141292do_test temptable-6.8 {
395*4520Snw141292  db close
396*4520Snw141292  sqlite db test.db
397*4520Snw141292  catchsql {
398*4520Snw141292    SELECT * FROM t8,t9;
399*4520Snw141292  }
400*4520Snw141292} {1 {no such table: t9}}
401*4520Snw141292
402*4520Snw141292finish_test
403