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