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