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