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