1# 2003 April 4 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 related functionality. 14# 15# $Id: attach.test,v 1.52 2009/05/29 14:39:08 drh Exp $ 16# 17 18set testdir [file dirname $argv0] 19source $testdir/tester.tcl 20 21ifcapable !attach { 22 finish_test 23 return 24} 25 26for {set i 2} {$i<=15} {incr i} { 27 file delete -force test$i.db 28 file delete -force test$i.db-journal 29} 30 31do_test attach-1.1 { 32 execsql { 33 CREATE TABLE t1(a,b); 34 INSERT INTO t1 VALUES(1,2); 35 INSERT INTO t1 VALUES(3,4); 36 SELECT * FROM t1; 37 } 38} {1 2 3 4} 39do_test attach-1.2 { 40 sqlite3 db2 test2.db 41 execsql { 42 CREATE TABLE t2(x,y); 43 INSERT INTO t2 VALUES(1,'x'); 44 INSERT INTO t2 VALUES(2,'y'); 45 SELECT * FROM t2; 46 } db2 47} {1 x 2 y} 48do_test attach-1.3 { 49 execsql { 50 ATTACH DATABASE 'test2.db' AS two; 51 SELECT * FROM two.t2; 52 } 53} {1 x 2 y} 54do_test attach-1.4 { 55 execsql { 56 SELECT * FROM t2; 57 } 58} {1 x 2 y} 59do_test attach-1.5 { 60 execsql { 61 DETACH DATABASE two; 62 SELECT * FROM t1; 63 } 64} {1 2 3 4} 65do_test attach-1.6 { 66 catchsql { 67 SELECT * FROM t2; 68 } 69} {1 {no such table: t2}} 70do_test attach-1.7 { 71 catchsql { 72 SELECT * FROM two.t2; 73 } 74} {1 {no such table: two.t2}} 75do_test attach-1.8 { 76 catchsql { 77 ATTACH DATABASE 'test3.db' AS three; 78 } 79} {0 {}} 80do_test attach-1.9 { 81 catchsql { 82 SELECT * FROM three.sqlite_master; 83 } 84} {0 {}} 85do_test attach-1.10 { 86 catchsql { 87 DETACH DATABASE [three]; 88 } 89} {0 {}} 90do_test attach-1.11 { 91 execsql { 92 ATTACH 'test.db' AS db2; 93 ATTACH 'test.db' AS db3; 94 ATTACH 'test.db' AS db4; 95 ATTACH 'test.db' AS db5; 96 ATTACH 'test.db' AS db6; 97 ATTACH 'test.db' AS db7; 98 ATTACH 'test.db' AS db8; 99 ATTACH 'test.db' AS db9; 100 } 101} {} 102proc db_list {db} { 103 set list {} 104 foreach {idx name file} [execsql {PRAGMA database_list} $db] { 105 lappend list $idx $name 106 } 107 return $list 108} 109ifcapable schema_pragmas { 110do_test attach-1.11b { 111 db_list db 112} {0 main 2 db2 3 db3 4 db4 5 db5 6 db6 7 db7 8 db8 9 db9} 113} ;# ifcapable schema_pragmas 114do_test attach-1.12 { 115 catchsql { 116 ATTACH 'test.db' as db2; 117 } 118} {1 {database db2 is already in use}} 119do_test attach-1.12.2 { 120 db errorcode 121} {1} 122do_test attach-1.13 { 123 catchsql { 124 ATTACH 'test.db' as db5; 125 } 126} {1 {database db5 is already in use}} 127do_test attach-1.14 { 128 catchsql { 129 ATTACH 'test.db' as db9; 130 } 131} {1 {database db9 is already in use}} 132do_test attach-1.15 { 133 catchsql { 134 ATTACH 'test.db' as main; 135 } 136} {1 {database main is already in use}} 137ifcapable tempdb { 138 do_test attach-1.16 { 139 catchsql { 140 ATTACH 'test.db' as temp; 141 } 142 } {1 {database temp is already in use}} 143} 144do_test attach-1.17 { 145 catchsql { 146 ATTACH 'test.db' as MAIN; 147 } 148} {1 {database MAIN is already in use}} 149do_test attach-1.18 { 150 catchsql { 151 ATTACH 'test.db' as db10; 152 ATTACH 'test.db' as db11; 153 } 154} {0 {}} 155do_test attach-1.19 { 156 catchsql { 157 ATTACH 'test.db' as db12; 158 } 159} {1 {too many attached databases - max 10}} 160do_test attach-1.19.1 { 161 db errorcode 162} {1} 163do_test attach-1.20.1 { 164 execsql { 165 DETACH db5; 166 } 167} {} 168ifcapable schema_pragmas { 169do_test attach-1.20.2 { 170 db_list db 171} {0 main 2 db2 3 db3 4 db4 5 db6 6 db7 7 db8 8 db9 9 db10 10 db11} 172} ;# ifcapable schema_pragmas 173integrity_check attach-1.20.3 174ifcapable tempdb { 175 execsql {select * from sqlite_temp_master} 176} 177do_test attach-1.21 { 178 catchsql { 179 ATTACH 'test.db' as db12; 180 } 181} {0 {}} 182do_test attach-1.22 { 183 catchsql { 184 ATTACH 'test.db' as db13; 185 } 186} {1 {too many attached databases - max 10}} 187do_test attach-1.22.1 { 188 db errorcode 189} {1} 190do_test attach-1.23 { 191 catchsql { 192 DETACH "db14"; 193 } 194} {1 {no such database: db14}} 195do_test attach-1.24 { 196 catchsql { 197 DETACH db12; 198 } 199} {0 {}} 200do_test attach-1.25 { 201 catchsql { 202 DETACH db12; 203 } 204} {1 {no such database: db12}} 205do_test attach-1.26 { 206 catchsql { 207 DETACH main; 208 } 209} {1 {cannot detach database main}} 210 211ifcapable tempdb { 212 do_test attach-1.27 { 213 catchsql { 214 DETACH Temp; 215 } 216 } {1 {cannot detach database Temp}} 217} else { 218 do_test attach-1.27 { 219 catchsql { 220 DETACH Temp; 221 } 222 } {1 {no such database: Temp}} 223} 224 225do_test attach-1.28 { 226 catchsql { 227 DETACH db11; 228 DETACH db10; 229 DETACH db9; 230 DETACH db8; 231 DETACH db7; 232 DETACH db6; 233 DETACH db4; 234 DETACH db3; 235 DETACH db2; 236 } 237} {0 {}} 238ifcapable schema_pragmas { 239 ifcapable tempdb { 240 do_test attach-1.29 { 241 db_list db 242 } {0 main 1 temp} 243 } else { 244 do_test attach-1.29 { 245 db_list db 246 } {0 main} 247 } 248} ;# ifcapable schema_pragmas 249 250ifcapable {trigger} { # Only do the following tests if triggers are enabled 251do_test attach-2.1 { 252 execsql { 253 CREATE TABLE tx(x1,x2,y1,y2); 254 CREATE TRIGGER r1 AFTER UPDATE ON t2 FOR EACH ROW BEGIN 255 INSERT INTO tx(x1,x2,y1,y2) VALUES(OLD.x,NEW.x,OLD.y,NEW.y); 256 END; 257 SELECT * FROM tx; 258 } db2; 259} {} 260do_test attach-2.2 { 261 execsql { 262 UPDATE t2 SET x=x+10; 263 SELECT * FROM tx; 264 } db2; 265} {1 11 x x 2 12 y y} 266do_test attach-2.3 { 267 execsql { 268 CREATE TABLE tx(x1,x2,y1,y2); 269 SELECT * FROM tx; 270 } 271} {} 272do_test attach-2.4 { 273 execsql { 274 ATTACH 'test2.db' AS db2; 275 } 276} {} 277do_test attach-2.5 { 278 execsql { 279 UPDATE db2.t2 SET x=x+10; 280 SELECT * FROM db2.tx; 281 } 282} {1 11 x x 2 12 y y 11 21 x x 12 22 y y} 283do_test attach-2.6 { 284 execsql { 285 SELECT * FROM main.tx; 286 } 287} {} 288do_test attach-2.7 { 289 execsql { 290 SELECT type, name, tbl_name FROM db2.sqlite_master; 291 } 292} {table t2 t2 table tx tx trigger r1 t2} 293 294ifcapable schema_pragmas&&tempdb { 295 do_test attach-2.8 { 296 db_list db 297 } {0 main 1 temp 2 db2} 298} ;# ifcapable schema_pragmas&&tempdb 299ifcapable schema_pragmas&&!tempdb { 300 do_test attach-2.8 { 301 db_list db 302 } {0 main 2 db2} 303} ;# ifcapable schema_pragmas&&!tempdb 304 305do_test attach-2.9 { 306 execsql { 307 CREATE INDEX i2 ON t2(x); 308 SELECT * FROM t2 WHERE x>5; 309 } db2 310} {21 x 22 y} 311do_test attach-2.10 { 312 execsql { 313 SELECT type, name, tbl_name FROM sqlite_master; 314 } db2 315} {table t2 t2 table tx tx trigger r1 t2 index i2 t2} 316#do_test attach-2.11 { 317# catchsql { 318# SELECT * FROM t2 WHERE x>5; 319# } 320#} {1 {database schema has changed}} 321ifcapable schema_pragmas { 322 ifcapable tempdb { 323 do_test attach-2.12 { 324 db_list db 325 } {0 main 1 temp 2 db2} 326 } else { 327 do_test attach-2.12 { 328 db_list db 329 } {0 main 2 db2} 330 } 331} ;# ifcapable schema_pragmas 332do_test attach-2.13 { 333 catchsql { 334 SELECT * FROM t2 WHERE x>5; 335 } 336} {0 {21 x 22 y}} 337do_test attach-2.14 { 338 execsql { 339 SELECT type, name, tbl_name FROM sqlite_master; 340 } 341} {table t1 t1 table tx tx} 342do_test attach-2.15 { 343 execsql { 344 SELECT type, name, tbl_name FROM db2.sqlite_master; 345 } 346} {table t2 t2 table tx tx trigger r1 t2 index i2 t2} 347do_test attach-2.16 { 348 db close 349 sqlite3 db test.db 350 execsql { 351 ATTACH 'test2.db' AS db2; 352 SELECT type, name, tbl_name FROM db2.sqlite_master; 353 } 354} {table t2 t2 table tx tx trigger r1 t2 index i2 t2} 355} ;# End of ifcapable {trigger} 356 357do_test attach-3.1 { 358 db close 359 db2 close 360 sqlite3 db test.db 361 sqlite3 db2 test2.db 362 execsql { 363 SELECT * FROM t1 364 } 365} {1 2 3 4} 366 367# If we are testing a version of the code that lacks trigger support, 368# adjust the database contents so that they are the same if triggers 369# had been enabled. 370ifcapable {!trigger} { 371 db2 eval { 372 DELETE FROM t2; 373 INSERT INTO t2 VALUES(21, 'x'); 374 INSERT INTO t2 VALUES(22, 'y'); 375 CREATE TABLE tx(x1,x2,y1,y2); 376 INSERT INTO tx VALUES(1, 11, 'x', 'x'); 377 INSERT INTO tx VALUES(2, 12, 'y', 'y'); 378 INSERT INTO tx VALUES(11, 21, 'x', 'x'); 379 INSERT INTO tx VALUES(12, 22, 'y', 'y'); 380 CREATE INDEX i2 ON t2(x); 381 } 382} 383 384do_test attach-3.2 { 385 catchsql { 386 SELECT * FROM t2 387 } 388} {1 {no such table: t2}} 389do_test attach-3.3 { 390 catchsql { 391 ATTACH DATABASE 'test2.db' AS db2; 392 SELECT * FROM t2 393 } 394} {0 {21 x 22 y}} 395 396# Even though 'db' has started a transaction, it should not yet have 397# a lock on test2.db so 'db2' should be readable. 398do_test attach-3.4 { 399 execsql BEGIN 400 catchsql { 401 SELECT * FROM t2; 402 } db2; 403} {0 {21 x 22 y}} 404 405# Reading from test2.db from db within a transaction should not 406# prevent test2.db from being read by db2. 407do_test attach-3.5 { 408 execsql {SELECT * FROM t2} 409 catchsql { 410 SELECT * FROM t2; 411 } db2; 412} {0 {21 x 22 y}} 413 414# Making a change to test2.db through db causes test2.db to get 415# a reserved lock. It should still be accessible through db2. 416do_test attach-3.6 { 417 execsql { 418 UPDATE t2 SET x=x+1 WHERE x=50; 419 } 420 catchsql { 421 SELECT * FROM t2; 422 } db2; 423} {0 {21 x 22 y}} 424 425do_test attach-3.7 { 426 execsql ROLLBACK 427 execsql {SELECT * FROM t2} db2 428} {21 x 22 y} 429 430# Start transactions on both db and db2. Once again, just because 431# we make a change to test2.db using db2, only a RESERVED lock is 432# obtained, so test2.db should still be readable using db. 433# 434do_test attach-3.8 { 435 execsql BEGIN 436 execsql BEGIN db2 437 execsql {UPDATE t2 SET x=0 WHERE 0} db2 438 catchsql {SELECT * FROM t2} 439} {0 {21 x 22 y}} 440 441# It is also still accessible from db2. 442do_test attach-3.9 { 443 catchsql {SELECT * FROM t2} db2 444} {0 {21 x 22 y}} 445 446do_test attach-3.10 { 447 execsql {SELECT * FROM t1} 448} {1 2 3 4} 449 450do_test attach-3.11 { 451 catchsql {UPDATE t1 SET a=a+1} 452} {0 {}} 453do_test attach-3.12 { 454 execsql {SELECT * FROM t1} 455} {2 2 4 4} 456 457# db2 has a RESERVED lock on test2.db, so db cannot write to any tables 458# in test2.db. 459do_test attach-3.13 { 460 catchsql {UPDATE t2 SET x=x+1 WHERE x=50} 461} {1 {database is locked}} 462 463# Change for version 3. Transaction is no longer rolled back 464# for a locked database. 465execsql {ROLLBACK} 466 467# db is able to reread its schema because db2 still only holds a 468# reserved lock. 469do_test attach-3.14 { 470 catchsql {SELECT * FROM t1} 471} {0 {1 2 3 4}} 472do_test attach-3.15 { 473 execsql COMMIT db2 474 execsql {SELECT * FROM t1} 475} {1 2 3 4} 476 477# Ticket #323 478do_test attach-4.1 { 479 execsql {DETACH db2} 480 db2 close 481 sqlite3 db2 test2.db 482 execsql { 483 CREATE TABLE t3(x,y); 484 CREATE UNIQUE INDEX t3i1 ON t3(x); 485 INSERT INTO t3 VALUES(1,2); 486 SELECT * FROM t3; 487 } db2; 488} {1 2} 489do_test attach-4.2 { 490 execsql { 491 CREATE TABLE t3(a,b); 492 CREATE UNIQUE INDEX t3i1b ON t3(a); 493 INSERT INTO t3 VALUES(9,10); 494 SELECT * FROM t3; 495 } 496} {9 10} 497do_test attach-4.3 { 498 execsql { 499 ATTACH DATABASE 'test2.db' AS db2; 500 SELECT * FROM db2.t3; 501 } 502} {1 2} 503do_test attach-4.4 { 504 execsql { 505 SELECT * FROM main.t3; 506 } 507} {9 10} 508do_test attach-4.5 { 509 execsql { 510 INSERT INTO db2.t3 VALUES(9,10); 511 SELECT * FROM db2.t3; 512 } 513} {1 2 9 10} 514execsql { 515 DETACH db2; 516} 517ifcapable {trigger} { 518 do_test attach-4.6 { 519 execsql { 520 CREATE TABLE t4(x); 521 CREATE TRIGGER t3r3 AFTER INSERT ON t3 BEGIN 522 INSERT INTO t4 VALUES('db2.' || NEW.x); 523 END; 524 INSERT INTO t3 VALUES(6,7); 525 SELECT * FROM t4; 526 } db2 527 } {db2.6} 528 do_test attach-4.7 { 529 execsql { 530 CREATE TABLE t4(y); 531 CREATE TRIGGER t3r3 AFTER INSERT ON t3 BEGIN 532 INSERT INTO t4 VALUES('main.' || NEW.a); 533 END; 534 INSERT INTO main.t3 VALUES(11,12); 535 SELECT * FROM main.t4; 536 } 537 } {main.11} 538} 539ifcapable {!trigger} { 540 # When we do not have trigger support, set up the table like they 541 # would have been had triggers been there. The tests that follow need 542 # this setup. 543 execsql { 544 CREATE TABLE t4(x); 545 INSERT INTO t3 VALUES(6,7); 546 INSERT INTO t4 VALUES('db2.6'); 547 INSERT INTO t4 VALUES('db2.13'); 548 } db2 549 execsql { 550 CREATE TABLE t4(y); 551 INSERT INTO main.t3 VALUES(11,12); 552 INSERT INTO t4 VALUES('main.11'); 553 } 554} 555 556 557# This one is tricky. On the UNION ALL select, we have to make sure 558# the schema for both main and db2 is valid before starting to execute 559# the first query of the UNION ALL. If we wait to test the validity of 560# the schema for main until after the first query has run, that test will 561# fail and the query will abort but we will have already output some 562# results. When the query is retried, the results will be repeated. 563# 564ifcapable compound { 565do_test attach-4.8 { 566 execsql { 567 ATTACH DATABASE 'test2.db' AS db2; 568 INSERT INTO db2.t3 VALUES(13,14); 569 SELECT * FROM db2.t4 UNION ALL SELECT * FROM main.t4; 570 } 571} {db2.6 db2.13 main.11} 572 573do_test attach-4.9 { 574 ifcapable {!trigger} {execsql {INSERT INTO main.t4 VALUES('main.15')}} 575 execsql { 576 INSERT INTO main.t3 VALUES(15,16); 577 SELECT * FROM db2.t4 UNION ALL SELECT * FROM main.t4; 578 } 579} {db2.6 db2.13 main.11 main.15} 580} ;# ifcapable compound 581 582ifcapable !compound { 583 ifcapable {!trigger} {execsql {INSERT INTO main.t4 VALUES('main.15')}} 584 execsql { 585 ATTACH DATABASE 'test2.db' AS db2; 586 INSERT INTO db2.t3 VALUES(13,14); 587 INSERT INTO main.t3 VALUES(15,16); 588 } 589} ;# ifcapable !compound 590 591ifcapable view { 592do_test attach-4.10 { 593 execsql { 594 DETACH DATABASE db2; 595 } 596 execsql { 597 CREATE VIEW v3 AS SELECT x*100+y FROM t3; 598 SELECT * FROM v3; 599 } db2 600} {102 910 607 1314} 601do_test attach-4.11 { 602 execsql { 603 CREATE VIEW v3 AS SELECT a*100+b FROM t3; 604 SELECT * FROM v3; 605 } 606} {910 1112 1516} 607do_test attach-4.12 { 608 execsql { 609 ATTACH DATABASE 'test2.db' AS db2; 610 SELECT * FROM db2.v3; 611 } 612} {102 910 607 1314} 613do_test attach-4.13 { 614 execsql { 615 SELECT * FROM main.v3; 616 } 617} {910 1112 1516} 618} ;# ifcapable view 619 620# Tests for the sqliteFix...() routines in attach.c 621# 622ifcapable {trigger} { 623do_test attach-5.1 { 624 db close 625 sqlite3 db test.db 626 db2 close 627 file delete -force test2.db 628 sqlite3 db2 test2.db 629 catchsql { 630 ATTACH DATABASE 'test.db' AS orig; 631 CREATE TRIGGER r1 AFTER INSERT ON orig.t1 BEGIN 632 SELECT 'no-op'; 633 END; 634 } db2 635} {1 {trigger r1 cannot reference objects in database orig}} 636do_test attach-5.2 { 637 catchsql { 638 CREATE TABLE t5(x,y); 639 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN 640 SELECT 'no-op'; 641 END; 642 } db2 643} {0 {}} 644do_test attach-5.3 { 645 catchsql { 646 DROP TRIGGER r5; 647 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN 648 SELECT 'no-op' FROM orig.t1; 649 END; 650 } db2 651} {1 {trigger r5 cannot reference objects in database orig}} 652ifcapable tempdb { 653 do_test attach-5.4 { 654 catchsql { 655 CREATE TEMP TABLE t6(p,q,r); 656 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN 657 SELECT 'no-op' FROM temp.t6; 658 END; 659 } db2 660 } {1 {trigger r5 cannot reference objects in database temp}} 661} 662ifcapable subquery { 663 do_test attach-5.5 { 664 catchsql { 665 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN 666 SELECT 'no-op' || (SELECT * FROM temp.t6); 667 END; 668 } db2 669 } {1 {trigger r5 cannot reference objects in database temp}} 670 do_test attach-5.6 { 671 catchsql { 672 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN 673 SELECT 'no-op' FROM t1 WHERE x<(SELECT min(x) FROM temp.t6); 674 END; 675 } db2 676 } {1 {trigger r5 cannot reference objects in database temp}} 677 do_test attach-5.7 { 678 catchsql { 679 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN 680 SELECT 'no-op' FROM t1 GROUP BY 1 HAVING x<(SELECT min(x) FROM temp.t6); 681 END; 682 } db2 683 } {1 {trigger r5 cannot reference objects in database temp}} 684 do_test attach-5.7 { 685 catchsql { 686 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN 687 SELECT max(1,x,(SELECT min(x) FROM temp.t6)) FROM t1; 688 END; 689 } db2 690 } {1 {trigger r5 cannot reference objects in database temp}} 691 do_test attach-5.8 { 692 catchsql { 693 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN 694 INSERT INTO t1 VALUES((SELECT min(x) FROM temp.t6),5); 695 END; 696 } db2 697 } {1 {trigger r5 cannot reference objects in database temp}} 698 do_test attach-5.9 { 699 catchsql { 700 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN 701 DELETE FROM t1 WHERE x<(SELECT min(x) FROM temp.t6); 702 END; 703 } db2 704 } {1 {trigger r5 cannot reference objects in database temp}} 705} ;# endif subquery 706} ;# endif trigger 707 708# Check to make sure we get a sensible error if unable to open 709# the file that we are trying to attach. 710# 711do_test attach-6.1 { 712 catchsql { 713 ATTACH DATABASE 'no-such-file' AS nosuch; 714 } 715} {0 {}} 716if {$tcl_platform(platform)=="unix"} { 717 do_test attach-6.2 { 718 sqlite3 dbx cannot-read 719 dbx eval {CREATE TABLE t1(a,b,c)} 720 dbx close 721 file attributes cannot-read -permission 0000 722 if {[file writable cannot-read]} { 723 puts "\n**** Tests do not work when run as root ****" 724 file delete -force cannot-read 725 exit 1 726 } 727 catchsql { 728 ATTACH DATABASE 'cannot-read' AS noread; 729 } 730 } {1 {unable to open database: cannot-read}} 731 do_test attach-6.2.2 { 732 db errorcode 733 } {14} 734 file delete -force cannot-read 735} 736 737# Check the error message if we try to access a database that has 738# not been attached. 739do_test attach-6.3 { 740 catchsql { 741 CREATE TABLE no_such_db.t1(a, b, c); 742 } 743} {1 {unknown database no_such_db}} 744for {set i 2} {$i<=15} {incr i} { 745 catch {db$i close} 746} 747db close 748file delete -force test2.db 749file delete -force no-such-file 750 751ifcapable subquery { 752 do_test attach-7.1 { 753 file delete -force test.db test.db-journal 754 sqlite3 db test.db 755 catchsql { 756 DETACH RAISE ( IGNORE ) IN ( SELECT "AAAAAA" . * ORDER BY 757 REGISTER LIMIT "AAAAAA" . "AAAAAA" OFFSET RAISE ( IGNORE ) NOT NULL ) 758 } 759 } {1 {no such table: AAAAAA}} 760} 761 762# Create a malformed file (a file that is not a valid database) 763# and try to attach it 764# 765do_test attach-8.1 { 766 set fd [open test2.db w] 767 puts $fd "This file is not a valid SQLite database" 768 close $fd 769 catchsql { 770 ATTACH 'test2.db' AS t2; 771 } 772} {1 {file is encrypted or is not a database}} 773do_test attach-8.2 { 774 db errorcode 775} {26} 776file delete -force test2.db 777do_test attach-8.3 { 778 sqlite3 db2 test2.db 779 db2 eval {CREATE TABLE t1(x); BEGIN EXCLUSIVE} 780 catchsql { 781 ATTACH 'test2.db' AS t2; 782 } 783} {1 {database is locked}} 784do_test attach-8.4 { 785 db errorcode 786} {5} 787db2 close 788file delete -force test2.db 789 790 791finish_test 792