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.15 2005/03/29 03:11:00 danielk1977 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 30file delete -force test2.db-journal 31sqlite3 db2 test2.db 32execsql { 33 CREATE TABLE t1(a, b); 34 CREATE TABLE t2(c, d); 35} db2 36db2 close 37 38# Create a table in the auxilary database. 39do_test attach3-1.1 { 40 execsql { 41 ATTACH 'test2.db' AS aux; 42 } 43} {} 44do_test attach3-1.2 { 45 execsql { 46 CREATE TABLE aux.t3(e, f); 47 } 48} {} 49do_test attach3-1.3 { 50 execsql { 51 SELECT * FROM sqlite_master WHERE name = 't3'; 52 } 53} {} 54do_test attach3-1.4 { 55 execsql { 56 SELECT * FROM aux.sqlite_master WHERE name = 't3'; 57 } 58} "table t3 t3 [expr $AUTOVACUUM?5:4] {CREATE TABLE t3(e, f)}" 59do_test attach3-1.5 { 60 execsql { 61 INSERT INTO t3 VALUES(1, 2); 62 SELECT * FROM t3; 63 } 64} {1 2} 65 66# Create an index on the auxilary database table. 67do_test attach3-2.1 { 68 execsql { 69 CREATE INDEX aux.i1 on t3(e); 70 } 71} {} 72do_test attach3-2.2 { 73 execsql { 74 SELECT * FROM sqlite_master WHERE name = 'i1'; 75 } 76} {} 77do_test attach3-2.3 { 78 execsql { 79 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; 80 } 81} "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}" 82 83# Drop the index on the aux database table. 84do_test attach3-3.1 { 85 execsql { 86 DROP INDEX aux.i1; 87 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; 88 } 89} {} 90do_test attach3-3.2 { 91 execsql { 92 CREATE INDEX aux.i1 on t3(e); 93 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; 94 } 95} "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}" 96do_test attach3-3.3 { 97 execsql { 98 DROP INDEX i1; 99 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; 100 } 101} {} 102 103# Drop tables t1 and t2 in the auxilary database. 104do_test attach3-4.1 { 105 execsql { 106 DROP TABLE aux.t1; 107 SELECT name FROM aux.sqlite_master; 108 } 109} {t2 t3} 110do_test attach3-4.2 { 111 # This will drop main.t2 112 execsql { 113 DROP TABLE t2; 114 SELECT name FROM aux.sqlite_master; 115 } 116} {t2 t3} 117do_test attach3-4.3 { 118 execsql { 119 DROP TABLE t2; 120 SELECT name FROM aux.sqlite_master; 121 } 122} {t3} 123 124# Create a view in the auxilary database. 125ifcapable view { 126do_test attach3-5.1 { 127 execsql { 128 CREATE VIEW aux.v1 AS SELECT * FROM t3; 129 } 130} {} 131do_test attach3-5.2 { 132 execsql { 133 SELECT * FROM aux.sqlite_master WHERE name = 'v1'; 134 } 135} {view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t3}} 136do_test attach3-5.3 { 137 execsql { 138 INSERT INTO aux.t3 VALUES('hello', 'world'); 139 SELECT * FROM v1; 140 } 141} {1 2 hello world} 142 143# Drop the view 144do_test attach3-6.1 { 145 execsql { 146 DROP VIEW aux.v1; 147 } 148} {} 149do_test attach3-6.2 { 150 execsql { 151 SELECT * FROM aux.sqlite_master WHERE name = 'v1'; 152 } 153} {} 154} ;# ifcapable view 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 192ifcapable tempdb { 193 # Try to trick SQLite into dropping the wrong temp trigger. 194 do_test attach3-9.0 { 195 execsql { 196 CREATE TABLE main.t4(a, b, c); 197 CREATE TABLE aux.t4(a, b, c); 198 CREATE TEMP TRIGGER tst_trigger BEFORE INSERT ON aux.t4 BEGIN 199 SELECT 'hello world'; 200 END; 201 SELECT count(*) FROM sqlite_temp_master; 202 } 203 } {1} 204 do_test attach3-9.1 { 205 execsql { 206 DROP TABLE main.t4; 207 SELECT count(*) FROM sqlite_temp_master; 208 } 209 } {1} 210 do_test attach3-9.2 { 211 execsql { 212 DROP TABLE aux.t4; 213 SELECT count(*) FROM sqlite_temp_master; 214 } 215 } {0} 216} 217} ;# endif trigger 218 219# Make sure the aux.sqlite_master table is read-only 220do_test attach3-10.0 { 221 catchsql { 222 INSERT INTO aux.sqlite_master VALUES(1, 2, 3, 4, 5); 223 } 224} {1 {table sqlite_master may not be modified}} 225 226# Failure to attach leaves us in a workable state. 227# Ticket #811 228# 229do_test attach3-11.0 { 230 catchsql { 231 ATTACH DATABASE '/nodir/nofile.x' AS notadb; 232 } 233} {1 {unable to open database: /nodir/nofile.x}} 234do_test attach3-11.1 { 235 catchsql { 236 ATTACH DATABASE ':memory:' AS notadb; 237 } 238} {0 {}} 239do_test attach3-11.2 { 240 catchsql { 241 DETACH DATABASE notadb; 242 } 243} {0 {}} 244 245finish_test 246