1# 2003 July 1 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. The 12# focus of this script is testing the ATTACH and DETACH commands 13# and schema changes to attached databases. 14# 15# $Id: attach3.test,v 1.10 2004/11/04 04:42:28 drh Exp $ 16# 17 18 19set testdir [file dirname $argv0] 20source $testdir/tester.tcl 21 22# Create tables t1 and t2 in the main database 23execsql { 24 CREATE TABLE t1(a, b); 25 CREATE TABLE t2(c, d); 26} 27 28# Create tables t1 and t2 in database file test2.db 29file delete -force test2.db 30sqlite3 db2 test2.db 31execsql { 32 CREATE TABLE t1(a, b); 33 CREATE TABLE t2(c, d); 34} db2 35db2 close 36 37# Create a table in the auxilary database. 38do_test attach3-1.1 { 39 execsql { 40 ATTACH 'test2.db' AS aux; 41 } 42} {} 43do_test attach3-1.2 { 44 execsql { 45 CREATE TABLE aux.t3(e, f); 46 } 47} {} 48do_test attach3-1.3 { 49 execsql { 50 SELECT * FROM sqlite_master WHERE name = 't3'; 51 } 52} {} 53do_test attach3-1.4 { 54 execsql { 55 SELECT * FROM aux.sqlite_master WHERE name = 't3'; 56 } 57} {table t3 t3 4 {CREATE TABLE t3(e, f)}} 58do_test attach3-1.5 { 59 execsql { 60 INSERT INTO t3 VALUES(1, 2); 61 SELECT * FROM t3; 62 } 63} {1 2} 64 65# Create an index on the auxilary database table. 66do_test attach3-2.1 { 67 execsql { 68 CREATE INDEX aux.i1 on t3(e); 69 } 70} {} 71execsql { 72 pragma vdbe_trace = off; 73} 74do_test attach3-2.2 { 75 execsql { 76 SELECT * FROM sqlite_master WHERE name = 'i1'; 77 } 78} {} 79do_test attach3-2.3 { 80 execsql { 81 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; 82 } 83} {index i1 t3 5 {CREATE INDEX i1 on t3(e)}} 84 85# Drop the index on the aux database table. 86do_test attach3-3.1 { 87 execsql { 88 DROP INDEX aux.i1; 89 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; 90 } 91} {} 92do_test attach3-3.2 { 93 execsql { 94 CREATE INDEX aux.i1 on t3(e); 95 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; 96 } 97} {index i1 t3 5 {CREATE INDEX i1 on t3(e)}} 98do_test attach3-3.3 { 99 execsql { 100 DROP INDEX i1; 101 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; 102 } 103} {} 104 105# Drop tables t1 and t2 in the auxilary database. 106do_test attach3-4.1 { 107 execsql { 108 DROP TABLE aux.t1; 109 SELECT name FROM aux.sqlite_master; 110 } 111} {t2 t3} 112do_test attach3-4.2 { 113 # This will drop main.t2 114 execsql { 115 DROP TABLE t2; 116 SELECT name FROM aux.sqlite_master; 117 } 118} {t2 t3} 119do_test attach3-4.3 { 120 execsql { 121 DROP TABLE t2; 122 SELECT name FROM aux.sqlite_master; 123 } 124} {t3} 125 126# Create a view in the auxilary database. 127do_test attach3-5.1 { 128 execsql { 129 CREATE VIEW aux.v1 AS SELECT * FROM t3; 130 } 131} {} 132do_test attach3-5.2 { 133 execsql { 134 SELECT * FROM aux.sqlite_master WHERE name = 'v1'; 135 } 136} {view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t3}} 137do_test attach3-5.3 { 138 execsql { 139 INSERT INTO aux.t3 VALUES('hello', 'world'); 140 SELECT * FROM v1; 141 } 142} {1 2 hello world} 143 144# Drop the view 145do_test attach3-6.1 { 146 execsql { 147 DROP VIEW aux.v1; 148 } 149} {} 150do_test attach3-6.2 { 151 execsql { 152 SELECT * FROM aux.sqlite_master WHERE name = 'v1'; 153 } 154} {} 155 156ifcapable {trigger} { 157# Create a trigger in the auxilary database. 158do_test attach3-7.1 { 159 execsql { 160 CREATE TRIGGER aux.tr1 AFTER INSERT ON t3 BEGIN 161 INSERT INTO t3 VALUES(new.e*2, new.f*2); 162 END; 163 } 164} {} 165do_test attach3-7.2 { 166 execsql { 167 DELETE FROM t3; 168 INSERT INTO t3 VALUES(10, 20); 169 SELECT * FROM t3; 170 } 171} {10 20 20 40} 172do_test attach3-5.3 { 173 execsql { 174 SELECT * FROM aux.sqlite_master WHERE name = 'tr1'; 175 } 176} {trigger tr1 t3 0 {CREATE TRIGGER tr1 AFTER INSERT ON t3 BEGIN 177 INSERT INTO t3 VALUES(new.e*2, new.f*2); 178 END}} 179 180# Drop the trigger 181do_test attach3-8.1 { 182 execsql { 183 DROP TRIGGER aux.tr1; 184 } 185} {} 186do_test attach3-8.2 { 187 execsql { 188 SELECT * FROM aux.sqlite_master WHERE name = 'tr1'; 189 } 190} {} 191 192# Try to trick SQLite into dropping the wrong temp trigger. 193do_test attach3-9.0 { 194 execsql { 195 CREATE TABLE main.t4(a, b, c); 196 CREATE TABLE aux.t4(a, b, c); 197 CREATE TEMP TRIGGER tst_trigger BEFORE INSERT ON aux.t4 BEGIN 198 SELECT 'hello world'; 199 END; 200 SELECT count(*) FROM sqlite_temp_master; 201 } 202} {1} 203do_test attach3-9.1 { 204 execsql { 205 DROP TABLE main.t4; 206 SELECT count(*) FROM sqlite_temp_master; 207 } 208} {1} 209do_test attach3-9.2 { 210 execsql { 211 DROP TABLE aux.t4; 212 SELECT count(*) FROM sqlite_temp_master; 213 } 214} {0} 215} ;# endif trigger 216 217# Make sure the aux.sqlite_master table is read-only 218do_test attach3-10.0 { 219 catchsql { 220 INSERT INTO aux.sqlite_master VALUES(1, 2, 3, 4, 5); 221 } 222} {1 {table sqlite_master may not be modified}} 223 224# Failure to attach leaves us in a workable state. 225# Ticket #811 226# 227do_test attach3-11.0 { 228 catchsql { 229 ATTACH DATABASE '/nodir/nofile.x' AS notadb; 230 } 231} {1 {unable to open database: /nodir/nofile.x}} 232do_test attach3-11.1 { 233 catchsql { 234 ATTACH DATABASE ':memory:' AS notadb; 235 } 236} {0 {}} 237do_test attach3-11.2 { 238 catchsql { 239 DETACH DATABASE notadb; 240 } 241} {0 {}} 242 243finish_test 244