| OLD | NEW |
| (Empty) |
| 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.18 2007/10/09 08:29:32 danielk1977 Exp $ | |
| 16 # | |
| 17 | |
| 18 set testdir [file dirname $argv0] | |
| 19 source $testdir/tester.tcl | |
| 20 | |
| 21 ifcapable !attach { | |
| 22 finish_test | |
| 23 return | |
| 24 } | |
| 25 | |
| 26 # The tests in this file were written before SQLite supported recursive | |
| 27 # trigger invocation, and some tests depend on that to pass. So disable | |
| 28 # recursive triggers for this file. | |
| 29 catchsql { pragma recursive_triggers = off } | |
| 30 | |
| 31 # Create tables t1 and t2 in the main database | |
| 32 execsql { | |
| 33 CREATE TABLE t1(a, b); | |
| 34 CREATE TABLE t2(c, d); | |
| 35 } | |
| 36 | |
| 37 # Create tables t1 and t2 in database file test2.db | |
| 38 file delete -force test2.db | |
| 39 file delete -force test2.db-journal | |
| 40 sqlite3 db2 test2.db | |
| 41 execsql { | |
| 42 CREATE TABLE t1(a, b); | |
| 43 CREATE TABLE t2(c, d); | |
| 44 } db2 | |
| 45 db2 close | |
| 46 | |
| 47 # Create a table in the auxilary database. | |
| 48 do_test attach3-1.1 { | |
| 49 execsql { | |
| 50 ATTACH 'test2.db' AS aux; | |
| 51 } | |
| 52 } {} | |
| 53 do_test attach3-1.2 { | |
| 54 execsql { | |
| 55 CREATE TABLE aux.t3(e, f); | |
| 56 } | |
| 57 } {} | |
| 58 do_test attach3-1.3 { | |
| 59 execsql { | |
| 60 SELECT * FROM sqlite_master WHERE name = 't3'; | |
| 61 } | |
| 62 } {} | |
| 63 do_test attach3-1.4 { | |
| 64 execsql { | |
| 65 SELECT * FROM aux.sqlite_master WHERE name = 't3'; | |
| 66 } | |
| 67 } "table t3 t3 [expr $AUTOVACUUM?5:4] {CREATE TABLE t3(e, f)}" | |
| 68 do_test attach3-1.5 { | |
| 69 execsql { | |
| 70 INSERT INTO t3 VALUES(1, 2); | |
| 71 SELECT * FROM t3; | |
| 72 } | |
| 73 } {1 2} | |
| 74 | |
| 75 # Create an index on the auxilary database table. | |
| 76 do_test attach3-2.1 { | |
| 77 execsql { | |
| 78 CREATE INDEX aux.i1 on t3(e); | |
| 79 } | |
| 80 } {} | |
| 81 do_test attach3-2.2 { | |
| 82 execsql { | |
| 83 SELECT * FROM sqlite_master WHERE name = 'i1'; | |
| 84 } | |
| 85 } {} | |
| 86 do_test attach3-2.3 { | |
| 87 execsql { | |
| 88 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; | |
| 89 } | |
| 90 } "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}" | |
| 91 | |
| 92 # Drop the index on the aux database table. | |
| 93 do_test attach3-3.1 { | |
| 94 execsql { | |
| 95 DROP INDEX aux.i1; | |
| 96 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; | |
| 97 } | |
| 98 } {} | |
| 99 do_test attach3-3.2 { | |
| 100 execsql { | |
| 101 CREATE INDEX aux.i1 on t3(e); | |
| 102 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; | |
| 103 } | |
| 104 } "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}" | |
| 105 do_test attach3-3.3 { | |
| 106 execsql { | |
| 107 DROP INDEX i1; | |
| 108 SELECT * FROM aux.sqlite_master WHERE name = 'i1'; | |
| 109 } | |
| 110 } {} | |
| 111 | |
| 112 # Drop tables t1 and t2 in the auxilary database. | |
| 113 do_test attach3-4.1 { | |
| 114 execsql { | |
| 115 DROP TABLE aux.t1; | |
| 116 SELECT name FROM aux.sqlite_master; | |
| 117 } | |
| 118 } {t2 t3} | |
| 119 do_test attach3-4.2 { | |
| 120 # This will drop main.t2 | |
| 121 execsql { | |
| 122 DROP TABLE t2; | |
| 123 SELECT name FROM aux.sqlite_master; | |
| 124 } | |
| 125 } {t2 t3} | |
| 126 do_test attach3-4.3 { | |
| 127 execsql { | |
| 128 DROP TABLE t2; | |
| 129 SELECT name FROM aux.sqlite_master; | |
| 130 } | |
| 131 } {t3} | |
| 132 | |
| 133 # Create a view in the auxilary database. | |
| 134 ifcapable view { | |
| 135 do_test attach3-5.1 { | |
| 136 execsql { | |
| 137 CREATE VIEW aux.v1 AS SELECT * FROM t3; | |
| 138 } | |
| 139 } {} | |
| 140 do_test attach3-5.2 { | |
| 141 execsql { | |
| 142 SELECT * FROM aux.sqlite_master WHERE name = 'v1'; | |
| 143 } | |
| 144 } {view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t3}} | |
| 145 do_test attach3-5.3 { | |
| 146 execsql { | |
| 147 INSERT INTO aux.t3 VALUES('hello', 'world'); | |
| 148 SELECT * FROM v1; | |
| 149 } | |
| 150 } {1 2 hello world} | |
| 151 | |
| 152 # Drop the view | |
| 153 do_test attach3-6.1 { | |
| 154 execsql { | |
| 155 DROP VIEW aux.v1; | |
| 156 } | |
| 157 } {} | |
| 158 do_test attach3-6.2 { | |
| 159 execsql { | |
| 160 SELECT * FROM aux.sqlite_master WHERE name = 'v1'; | |
| 161 } | |
| 162 } {} | |
| 163 } ;# ifcapable view | |
| 164 | |
| 165 ifcapable {trigger} { | |
| 166 # Create a trigger in the auxilary database. | |
| 167 do_test attach3-7.1 { | |
| 168 execsql { | |
| 169 CREATE TRIGGER aux.tr1 AFTER INSERT ON t3 BEGIN | |
| 170 INSERT INTO t3 VALUES(new.e*2, new.f*2); | |
| 171 END; | |
| 172 } | |
| 173 } {} | |
| 174 do_test attach3-7.2 { | |
| 175 execsql { | |
| 176 DELETE FROM t3; | |
| 177 INSERT INTO t3 VALUES(10, 20); | |
| 178 SELECT * FROM t3; | |
| 179 } | |
| 180 } {10 20 20 40} | |
| 181 do_test attach3-5.3 { | |
| 182 execsql { | |
| 183 SELECT * FROM aux.sqlite_master WHERE name = 'tr1'; | |
| 184 } | |
| 185 } {trigger tr1 t3 0 {CREATE TRIGGER tr1 AFTER INSERT ON t3 BEGIN | |
| 186 INSERT INTO t3 VALUES(new.e*2, new.f*2); | |
| 187 END}} | |
| 188 | |
| 189 # Drop the trigger | |
| 190 do_test attach3-8.1 { | |
| 191 execsql { | |
| 192 DROP TRIGGER aux.tr1; | |
| 193 } | |
| 194 } {} | |
| 195 do_test attach3-8.2 { | |
| 196 execsql { | |
| 197 SELECT * FROM aux.sqlite_master WHERE name = 'tr1'; | |
| 198 } | |
| 199 } {} | |
| 200 | |
| 201 ifcapable tempdb { | |
| 202 # Try to trick SQLite into dropping the wrong temp trigger. | |
| 203 do_test attach3-9.0 { | |
| 204 execsql { | |
| 205 CREATE TABLE main.t4(a, b, c); | |
| 206 CREATE TABLE aux.t4(a, b, c); | |
| 207 CREATE TEMP TRIGGER tst_trigger BEFORE INSERT ON aux.t4 BEGIN | |
| 208 SELECT 'hello world'; | |
| 209 END; | |
| 210 SELECT count(*) FROM sqlite_temp_master; | |
| 211 } | |
| 212 } {1} | |
| 213 do_test attach3-9.1 { | |
| 214 execsql { | |
| 215 DROP TABLE main.t4; | |
| 216 SELECT count(*) FROM sqlite_temp_master; | |
| 217 } | |
| 218 } {1} | |
| 219 do_test attach3-9.2 { | |
| 220 execsql { | |
| 221 DROP TABLE aux.t4; | |
| 222 SELECT count(*) FROM sqlite_temp_master; | |
| 223 } | |
| 224 } {0} | |
| 225 } | |
| 226 } ;# endif trigger | |
| 227 | |
| 228 # Make sure the aux.sqlite_master table is read-only | |
| 229 do_test attach3-10.0 { | |
| 230 catchsql { | |
| 231 INSERT INTO aux.sqlite_master VALUES(1, 2, 3, 4, 5); | |
| 232 } | |
| 233 } {1 {table sqlite_master may not be modified}} | |
| 234 | |
| 235 # Failure to attach leaves us in a workable state. | |
| 236 # Ticket #811 | |
| 237 # | |
| 238 do_test attach3-11.0 { | |
| 239 catchsql { | |
| 240 ATTACH DATABASE '/nodir/nofile.x' AS notadb; | |
| 241 } | |
| 242 } {1 {unable to open database: /nodir/nofile.x}} | |
| 243 do_test attach3-11.1 { | |
| 244 catchsql { | |
| 245 ATTACH DATABASE ':memory:' AS notadb; | |
| 246 } | |
| 247 } {0 {}} | |
| 248 do_test attach3-11.2 { | |
| 249 catchsql { | |
| 250 DETACH DATABASE notadb; | |
| 251 } | |
| 252 } {0 {}} | |
| 253 | |
| 254 # Return a list of attached databases | |
| 255 # | |
| 256 proc db_list {} { | |
| 257 set x [execsql { | |
| 258 PRAGMA database_list; | |
| 259 }] | |
| 260 set y {} | |
| 261 foreach {n id file} $x {lappend y $id} | |
| 262 return $y | |
| 263 } | |
| 264 | |
| 265 ifcapable schema_pragmas&&tempdb { | |
| 266 | |
| 267 ifcapable !trigger { | |
| 268 execsql {create temp table dummy(dummy)} | |
| 269 } | |
| 270 | |
| 271 # Ticket #1825 | |
| 272 # | |
| 273 do_test attach3-12.1 { | |
| 274 db_list | |
| 275 } {main temp aux} | |
| 276 do_test attach3-12.2 { | |
| 277 execsql { | |
| 278 ATTACH DATABASE ? AS ? | |
| 279 } | |
| 280 db_list | |
| 281 } {main temp aux {}} | |
| 282 do_test attach3-12.3 { | |
| 283 execsql { | |
| 284 DETACH aux | |
| 285 } | |
| 286 db_list | |
| 287 } {main temp {}} | |
| 288 do_test attach3-12.4 { | |
| 289 execsql { | |
| 290 DETACH ? | |
| 291 } | |
| 292 db_list | |
| 293 } {main temp} | |
| 294 do_test attach3-12.5 { | |
| 295 execsql { | |
| 296 ATTACH DATABASE '' AS '' | |
| 297 } | |
| 298 db_list | |
| 299 } {main temp {}} | |
| 300 do_test attach3-12.6 { | |
| 301 execsql { | |
| 302 DETACH '' | |
| 303 } | |
| 304 db_list | |
| 305 } {main temp} | |
| 306 do_test attach3-12.7 { | |
| 307 execsql { | |
| 308 ATTACH DATABASE '' AS ? | |
| 309 } | |
| 310 db_list | |
| 311 } {main temp {}} | |
| 312 do_test attach3-12.8 { | |
| 313 execsql { | |
| 314 DETACH '' | |
| 315 } | |
| 316 db_list | |
| 317 } {main temp} | |
| 318 do_test attach3-12.9 { | |
| 319 execsql { | |
| 320 ATTACH DATABASE '' AS NULL | |
| 321 } | |
| 322 db_list | |
| 323 } {main temp {}} | |
| 324 do_test attach3-12.10 { | |
| 325 breakpoint | |
| 326 execsql { | |
| 327 DETACH ? | |
| 328 } | |
| 329 db_list | |
| 330 } {main temp} | |
| 331 do_test attach3-12.11 { | |
| 332 catchsql { | |
| 333 DETACH NULL | |
| 334 } | |
| 335 } {1 {no such database: }} | |
| 336 do_test attach3-12.12 { | |
| 337 catchsql { | |
| 338 ATTACH null AS null; | |
| 339 ATTACH '' AS ''; | |
| 340 } | |
| 341 } {1 {database is already in use}} | |
| 342 do_test attach3-12.13 { | |
| 343 db_list | |
| 344 } {main temp {}} | |
| 345 do_test attach3-12.14 { | |
| 346 execsql { | |
| 347 DETACH ''; | |
| 348 } | |
| 349 db_list | |
| 350 } {main temp} | |
| 351 | |
| 352 } ;# ifcapable pragma | |
| 353 | |
| 354 finish_test | |
| OLD | NEW |