AryaWu/sqlite
0
1# 2003 April 42#3# The author disclaims copyright to this source code. In place of4# 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. The12# focus of this script is testing the ATTACH and DETACH commands13# 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.tcl20 21ifcapable !attach {22 finish_test23 return24}25 26for {set i 2} {$i<=15} {incr i} {27 forcedelete test$i.db28 forcedelete test$i.db-journal29}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.db41 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 } db247} {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 interface56#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 73do_test attach-1.4 {74 execsql {75 SELECT * FROM t2;76 }77} {1 x 2 y}78do_test attach-1.5 {79 execsql {80 DETACH DATABASE two;81 SELECT * FROM t1;82 }83} {1 2 3 4}84do_test attach-1.6 {85 catchsql {86 SELECT * FROM t2;87 }88} {1 {no such table: t2}}89do_test attach-1.7 {90 catchsql {91 SELECT * FROM two.t2;92 }93} {1 {no such table: two.t2}}94do_test attach-1.8 {95 catchsql {96 ATTACH DATABASE 'test3.db' AS three;97 }98} {0 {}}99do_test attach-1.9 {100 catchsql {101 SELECT * FROM three.sqlite_master;102 }103} {0 {}}104do_test attach-1.10 {105 catchsql {106 DETACH DATABASE [three];107 }108} {0 {}}109do_test attach-1.11 {110 execsql {111 ATTACH 'test.db' AS db2;112 ATTACH 'test.db' AS db3;113 ATTACH 'test.db' AS db4;114 ATTACH 'test.db' AS db5;115 ATTACH 'test.db' AS db6;116 ATTACH 'test.db' AS db7;117 ATTACH 'test.db' AS db8;118 ATTACH 'test.db' AS db9;119 }120} {}121proc db_list {db} {122 set list {}123 foreach {idx name file} [execsql {PRAGMA database_list} $db] {124 lappend list $idx $name125 }126 return $list127}128ifcapable schema_pragmas {129do_test attach-1.11b {130 db_list db131} {0 main 2 db2 3 db3 4 db4 5 db5 6 db6 7 db7 8 db8 9 db9}132} ;# ifcapable schema_pragmas 133do_test attach-1.12 {134 catchsql {135 ATTACH 'test.db' as db2;136 }137} {1 {database db2 is already in use}}138do_test attach-1.12.2 {139 db errorcode140} {1}141do_test attach-1.13 {142 catchsql {143 ATTACH 'test.db' as db5;144 }145} {1 {database db5 is already in use}}146do_test attach-1.14 {147 catchsql {148 ATTACH 'test.db' as db9;149 }150} {1 {database db9 is already in use}}151do_catchsql_test attach-1.15 {152 ATTACH 'test.db' as main;153} {1 {database main is already in use}}154ifcapable tempdb {155 do_test attach-1.16 {156 catchsql {157 ATTACH 'test.db' as temp;158 }159 } {1 {database temp is already in use}}160}161do_catchsql_test attach-1.17 {162 ATTACH 'test.db' as MAIN;163} {1 {database MAIN is already in use}}164do_test attach-1.18 {165 catchsql {166 ATTACH 'test.db' as db10;167 ATTACH 'test.db' as db11;168 }169} {0 {}}170if {$SQLITE_MAX_ATTACHED==10} {171 do_test attach-1.19 {172 catchsql {173 ATTACH 'test.db' as db12;174 }175 } {1 {too many attached databases - max 10}}176 do_test attach-1.19.1 {177 db errorcode178 } {1}179}180do_test attach-1.20.1 {181 execsql {182 DETACH db5;183 }184} {}185ifcapable schema_pragmas {186do_test attach-1.20.2 {187 db_list db188} {0 main 2 db2 3 db3 4 db4 5 db6 6 db7 7 db8 8 db9 9 db10 10 db11}189} ;# ifcapable schema_pragmas190integrity_check attach-1.20.3191ifcapable tempdb {192 execsql {select * from temp.sqlite_master}193}194do_test attach-1.21 {195 catchsql {196 ATTACH 'test.db' as db12;197 }198} {0 {}}199if {$SQLITE_MAX_ATTACHED==10} {200 do_test attach-1.22 {201 catchsql {202 ATTACH 'test.db' as db13;203 }204 } {1 {too many attached databases - max 10}}205 do_test attach-1.22.1 {206 db errorcode207 } {1}208}209do_test attach-1.23 {210 catchsql {211 DETACH "db14";212 }213} {1 {no such database: db14}}214do_test attach-1.24 {215 catchsql {216 DETACH db12;217 }218} {0 {}}219do_test attach-1.25 {220 catchsql {221 DETACH db12;222 }223} {1 {no such database: db12}}224do_test attach-1.26 {225 catchsql {226 DETACH main;227 }228} {1 {cannot detach database main}}229 230 231ifcapable tempdb {232 do_test attach-1.27 {233 catchsql {234 DETACH Temp;235 }236 } {1 {cannot detach database Temp}}237} else {238 do_test attach-1.27 {239 catchsql {240 DETACH Temp;241 }242 } {1 {no such database: Temp}}243}244 245do_test attach-1.28 {246 catchsql {247 DETACH db11;248 DETACH db10;249 DETACH db9;250 DETACH db8;251 DETACH db7;252 DETACH db6;253 DETACH db4;254 DETACH db3;255 DETACH db2;256 }257} {0 {}}258ifcapable schema_pragmas {259 ifcapable tempdb {260 do_test attach-1.29 {261 db_list db262 } {0 main 1 temp}263 } else {264 do_test attach-1.29 {265 db_list db266 } {0 main}267 }268} ;# ifcapable schema_pragmas269 270ifcapable {trigger} { # Only do the following tests if triggers are enabled271do_test attach-2.1 {272 execsql {273 CREATE TABLE tx(x1,x2,y1,y2);274 CREATE TRIGGER r1 AFTER UPDATE ON t2 FOR EACH ROW BEGIN275 INSERT INTO tx(x1,x2,y1,y2) VALUES(OLD.x,NEW.x,OLD.y,NEW.y);276 END;277 SELECT * FROM tx;278 } db2;279} {}280do_test attach-2.2 {281 execsql {282 UPDATE t2 SET x=x+10;283 SELECT * FROM tx;284 } db2;285} {1 11 x x 2 12 y y}286do_test attach-2.3 {287 execsql {288 CREATE TABLE tx(x1,x2,y1,y2);289 SELECT * FROM tx;290 }291} {}292do_test attach-2.4 {293 execsql {294 ATTACH 'test2.db' AS db2;295 }296} {}297do_test attach-2.5 {298 execsql {299 UPDATE db2.t2 SET x=x+10;300 SELECT * FROM db2.tx;301 }302} {1 11 x x 2 12 y y 11 21 x x 12 22 y y}303do_test attach-2.6 {304 execsql {305 SELECT * FROM main.tx;306 }307} {}308do_test attach-2.7 {309 execsql {310 SELECT type, name, tbl_name FROM db2.sqlite_master;311 }312} {table t2 t2 table tx tx trigger r1 t2}313 314ifcapable schema_pragmas&&tempdb {315 do_test attach-2.8 {316 db_list db317 } {0 main 1 temp 2 db2}318} ;# ifcapable schema_pragmas&&tempdb319ifcapable schema_pragmas&&!tempdb {320 do_test attach-2.8 {321 db_list db322 } {0 main 2 db2}323} ;# ifcapable schema_pragmas&&!tempdb324 325do_test attach-2.9 {326 execsql {327 CREATE INDEX i2 ON t2(x);328 SELECT * FROM t2 WHERE x>5;329 } db2330} {21 x 22 y}331do_test attach-2.10 {332 execsql {333 SELECT type, name, tbl_name FROM sqlite_master;334 } db2335} {table t2 t2 table tx tx trigger r1 t2 index i2 t2}336#do_test attach-2.11 {337# catchsql { 338# SELECT * FROM t2 WHERE x>5;339# }340#} {1 {database schema has changed}}341ifcapable schema_pragmas {342 ifcapable tempdb {343 do_test attach-2.12 {344 db_list db345 } {0 main 1 temp 2 db2}346 } else {347 do_test attach-2.12 {348 db_list db349 } {0 main 2 db2}350 }351} ;# ifcapable schema_pragmas352do_test attach-2.13 {353 catchsql {354 SELECT * FROM t2 WHERE x>5;355 }356} {0 {21 x 22 y}}357do_test attach-2.14 {358 execsql {359 SELECT type, name, tbl_name FROM sqlite_master;360 }361} {table t1 t1 table tx tx}362do_test attach-2.15 {363 execsql {364 SELECT type, name, tbl_name FROM db2.sqlite_master;365 }366} {table t2 t2 table tx tx trigger r1 t2 index i2 t2}367do_test attach-2.16 {368 db close369 sqlite3 db test.db370 execsql {371 ATTACH 'test2.db' AS db2;372 SELECT type, name, tbl_name FROM db2.sqlite_master;373 }374} {table t2 t2 table tx tx trigger r1 t2 index i2 t2}375} ;# End of ifcapable {trigger}376 377do_test attach-3.1 {378 db close379 db2 close380 sqlite3 db test.db381 sqlite3 db2 test2.db382 execsql {383 SELECT * FROM t1384 }385} {1 2 3 4}386 387# If we are testing a version of the code that lacks trigger support,388# adjust the database contents so that they are the same if triggers389# had been enabled.390ifcapable {!trigger} {391 db2 eval {392 DELETE FROM t2;393 INSERT INTO t2 VALUES(21, 'x');394 INSERT INTO t2 VALUES(22, 'y');395 CREATE TABLE tx(x1,x2,y1,y2);396 INSERT INTO tx VALUES(1, 11, 'x', 'x');397 INSERT INTO tx VALUES(2, 12, 'y', 'y');398 INSERT INTO tx VALUES(11, 21, 'x', 'x');399 INSERT INTO tx VALUES(12, 22, 'y', 'y');400 CREATE INDEX i2 ON t2(x);401 }402}403 404do_test attach-3.2 {405 catchsql {406 SELECT * FROM t2407 }408} {1 {no such table: t2}}409do_test attach-3.3 {410 catchsql {411 ATTACH DATABASE 'test2.db' AS db2;412 SELECT * FROM t2413 }414} {0 {21 x 22 y}}415 416# Even though 'db' has started a transaction, it should not yet have417# a lock on test2.db so 'db2' should be readable.418do_test attach-3.4 {419 execsql BEGIN420 catchsql {421 SELECT * FROM t2;422 } db2;423} {0 {21 x 22 y}}424 425# Reading from test2.db from db within a transaction should not426# prevent test2.db from being read by db2.427do_test attach-3.5 {428 execsql {SELECT * FROM t2}429 catchsql {430 SELECT * FROM t2;431 } db2;432} {0 {21 x 22 y}}433 434# Making a change to test2.db through db causes test2.db to get435# a reserved lock. It should still be accessible through db2.436do_test attach-3.6 {437 execsql {438 UPDATE t2 SET x=x+1 WHERE x=50;439 }440 catchsql {441 SELECT * FROM t2;442 } db2;443} {0 {21 x 22 y}}444 445do_test attach-3.7 {446 execsql ROLLBACK447 execsql {SELECT * FROM t2} db2448} {21 x 22 y}449 450# Start transactions on both db and db2. Once again, just because451# we make a change to test2.db using db2, only a RESERVED lock is452# obtained, so test2.db should still be readable using db.453#454do_test attach-3.8 {455 execsql BEGIN456 execsql BEGIN db2457 execsql {UPDATE t2 SET x=0 WHERE 0} db2458 catchsql {SELECT * FROM t2}459} {0 {21 x 22 y}}460 461# It is also still accessible from db2.462do_test attach-3.9 {463 catchsql {SELECT * FROM t2} db2464} {0 {21 x 22 y}}465 466do_test attach-3.10 {467 execsql {SELECT * FROM t1}468} {1 2 3 4}469 470do_test attach-3.11 {471 catchsql {UPDATE t1 SET a=a+1}472} {0 {}}473do_test attach-3.12 {474 execsql {SELECT * FROM t1}475} {2 2 4 4}476 477# db2 has a RESERVED lock on test2.db, so db cannot write to any tables478# in test2.db.479do_test attach-3.13 {480 catchsql {UPDATE t2 SET x=x+1 WHERE x=50}481} {1 {database is locked}}482 483# Change for version 3. Transaction is no longer rolled back484# for a locked database.485execsql {ROLLBACK}486 487# db is able to reread its schema because db2 still only holds a488# reserved lock.489do_test attach-3.14 {490 catchsql {SELECT * FROM t1}491} {0 {1 2 3 4}}492do_test attach-3.15 {493 execsql COMMIT db2494 execsql {SELECT * FROM t1}495} {1 2 3 4}496 497# Ticket #323498do_test attach-4.1 {499 execsql {DETACH db2}500 db2 close501 sqlite3 db2 test2.db502 execsql {503 CREATE TABLE t3(x,y);504 CREATE UNIQUE INDEX t3i1 ON t3(x);505 INSERT INTO t3 VALUES(1,2);506 SELECT * FROM t3;507 } db2;508} {1 2}509do_test attach-4.2 {510 execsql {511 CREATE TABLE t3(a,b);512 CREATE UNIQUE INDEX t3i1b ON t3(a);513 INSERT INTO t3 VALUES(9,10);514 SELECT * FROM t3;515 }516} {9 10}517do_test attach-4.3 {518 execsql {519 ATTACH DATABASE 'test2.db' AS db2;520 SELECT * FROM db2.t3;521 }522} {1 2}523do_test attach-4.4 {524 execsql {525 SELECT * FROM main.t3;526 }527} {9 10}528do_test attach-4.5 {529 execsql {530 INSERT INTO db2.t3 VALUES(9,10);531 SELECT * FROM db2.t3;532 }533} {1 2 9 10}534execsql {535 DETACH db2;536}537ifcapable {trigger} {538 do_test attach-4.6 {539 execsql {540 CREATE TABLE t4(x);541 CREATE TRIGGER t3r3 AFTER INSERT ON t3 BEGIN542 INSERT INTO t4 VALUES('db2.' || NEW.x);543 END;544 INSERT INTO t3 VALUES(6,7);545 SELECT * FROM t4;546 } db2547 } {db2.6}548 do_test attach-4.7 {549 execsql {550 CREATE TABLE t4(y);551 CREATE TRIGGER t3r3 AFTER INSERT ON t3 BEGIN552 INSERT INTO t4 VALUES('main.' || NEW.a);553 END;554 INSERT INTO main.t3 VALUES(11,12);555 SELECT * FROM main.t4;556 }557 } {main.11}558}559ifcapable {!trigger} {560 # When we do not have trigger support, set up the table like they561 # would have been had triggers been there. The tests that follow need562 # this setup.563 execsql {564 CREATE TABLE t4(x);565 INSERT INTO t3 VALUES(6,7);566 INSERT INTO t4 VALUES('db2.6');567 INSERT INTO t4 VALUES('db2.13');568 } db2569 execsql {570 CREATE TABLE t4(y);571 INSERT INTO main.t3 VALUES(11,12);572 INSERT INTO t4 VALUES('main.11');573 }574}575 576 577# This one is tricky. On the UNION ALL select, we have to make sure578# the schema for both main and db2 is valid before starting to execute579# the first query of the UNION ALL. If we wait to test the validity of580# the schema for main until after the first query has run, that test will581# fail and the query will abort but we will have already output some582# results. When the query is retried, the results will be repeated.583#584ifcapable compound {585do_test attach-4.8 {586 execsql {587 ATTACH DATABASE 'test2.db' AS db2;588 INSERT INTO db2.t3 VALUES(13,14);589 SELECT * FROM db2.t4 UNION ALL SELECT * FROM main.t4;590 }591} {db2.6 db2.13 main.11}592 593do_test attach-4.9 {594 ifcapable {!trigger} {execsql {INSERT INTO main.t4 VALUES('main.15')}}595 execsql {596 INSERT INTO main.t3 VALUES(15,16);597 SELECT * FROM db2.t4 UNION ALL SELECT * FROM main.t4;598 }599} {db2.6 db2.13 main.11 main.15}600} ;# ifcapable compound601 602ifcapable !compound {603 ifcapable {!trigger} {execsql {INSERT INTO main.t4 VALUES('main.15')}}604 execsql {605 ATTACH DATABASE 'test2.db' AS db2;606 INSERT INTO db2.t3 VALUES(13,14);607 INSERT INTO main.t3 VALUES(15,16);608 } 609} ;# ifcapable !compound610 611ifcapable view {612do_test attach-4.10 {613 execsql {614 DETACH DATABASE db2;615 }616 execsql {617 CREATE VIEW v3 AS SELECT x*100+y FROM t3;618 SELECT * FROM v3;619 } db2620} {102 910 607 1314}621do_test attach-4.11 {622 execsql {623 CREATE VIEW v3 AS SELECT a*100+b FROM t3;624 SELECT * FROM v3;625 }626} {910 1112 1516}627do_test attach-4.12 {628 execsql {629 ATTACH DATABASE 'test2.db' AS db2;630 SELECT * FROM db2.v3;631 }632} {102 910 607 1314}633do_test attach-4.13 {634 execsql {635 SELECT * FROM main.v3;636 }637} {910 1112 1516}638} ;# ifcapable view639 640# Tests for the sqliteFix...() routines in attach.c641#642ifcapable {trigger} {643do_test attach-5.1 {644 db close645 sqlite3 db test.db646 db2 close647 forcedelete test2.db648 sqlite3 db2 test2.db649 catchsql {650 ATTACH DATABASE 'test.db' AS orig;651 CREATE TRIGGER r1 AFTER INSERT ON orig.t1 BEGIN652 SELECT 'no-op';653 END;654 } db2655} {1 {trigger r1 cannot reference objects in database orig}}656do_test attach-5.2 {657 catchsql {658 CREATE TABLE t5(x,y);659 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN660 SELECT 'no-op';661 END;662 } db2663} {0 {}}664do_test attach-5.3 {665 catchsql {666 DROP TRIGGER r5;667 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN668 SELECT 'no-op' FROM orig.t1;669 END;670 } db2671} {1 {trigger r5 cannot reference objects in database orig}}672ifcapable tempdb {673 do_test attach-5.4 {674 catchsql {675 CREATE TEMP TABLE t6(p,q,r);676 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN677 SELECT 'no-op' FROM temp.t6;678 END;679 } db2680 } {1 {trigger r5 cannot reference objects in database temp}}681}682ifcapable subquery {683 do_test attach-5.5 {684 catchsql {685 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN686 SELECT 'no-op' || (SELECT * FROM temp.t6);687 END;688 } db2689 } {1 {trigger r5 cannot reference objects in database temp}}690 do_test attach-5.6 {691 catchsql {692 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN693 SELECT 'no-op' FROM t1 WHERE x<(SELECT min(x) FROM temp.t6);694 END;695 } db2696 } {1 {trigger r5 cannot reference objects in database temp}}697 do_test attach-5.7 {698 catchsql {699 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN700 SELECT 'no-op' FROM t1 GROUP BY 1 HAVING x<(SELECT min(x) FROM temp.t6);701 END;702 } db2703 } {1 {trigger r5 cannot reference objects in database temp}}704 do_test attach-5.7 {705 catchsql {706 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN707 SELECT max(1,x,(SELECT min(x) FROM temp.t6)) FROM t1;708 END;709 } db2710 } {1 {trigger r5 cannot reference objects in database temp}}711 do_test attach-5.8 {712 catchsql {713 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN714 INSERT INTO t1 VALUES((SELECT min(x) FROM temp.t6),5);715 END;716 } db2717 } {1 {trigger r5 cannot reference objects in database temp}}718 do_test attach-5.9 {719 catchsql {720 CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN721 DELETE FROM t1 WHERE x<(SELECT min(x) FROM temp.t6);722 END;723 } db2724 } {1 {trigger r5 cannot reference objects in database temp}}725} ;# endif subquery726ifcapable json1&&vtab {727 do_test attach-5.10 {728 db close729 catch {db2 close}730 forcedelete test.db731 sqlite3 db test.db732 db eval {733 CREATE TABLE t1(x);734 CREATE TABLE t2(a,b);735 CREATE TRIGGER x1 AFTER INSERT ON t1 BEGIN736 INSERT INTO t2(a,b) SELECT key, value FROM json_each(NEW.x);737 END;738 INSERT INTO t1(x) VALUES('{"a":1}');739 SELECT * FROM t2;740 }741 } {a 1}742 do_test attach-5.11 {743 sqlite3 db2 :memory:744 db2 eval {745 CREATE TABLE t3(y);746 ATTACH 'test.db' AS aux;747 INSERT INTO aux.t1(x) VALUES('{"b":2}');748 SELECT * FROM aux.t2;749 }750 } {a 1 b 2}751} ;# endif json1752} ;# endif trigger753 754# Check to make sure we get a sensible error if unable to open755# the file that we are trying to attach.756#757do_test attach-6.1 {758 catchsql {759 ATTACH DATABASE 'no-such-file' AS nosuch;760 }761} {0 {}}762if {$tcl_platform(platform) eq "unix"} {763 do_test attach-6.2 {764 sqlite3 dbx cannot-read765 dbx eval {CREATE TABLE t1(a,b,c)}766 dbx close767 file attributes cannot-read -permission 0000768 if {[file writable cannot-read]} {769 puts "\n**** Tests do not work when run as root ****"770 forcedelete cannot-read771 exit 1772 }773 catchsql {774 ATTACH DATABASE 'cannot-read' AS noread;775 }776 } {1 {unable to open database: cannot-read}}777 do_test attach-6.2.2 {778 db errorcode779 } {14}780 forcedelete cannot-read781}782 783# Check the error message if we try to access a database that has784# not been attached.785do_test attach-6.3 {786 catchsql {787 CREATE TABLE no_such_db.t1(a, b, c);788 }789} {1 {unknown database no_such_db}}790for {set i 2} {$i<=15} {incr i} {791 catch {db$i close}792}793db close794forcedelete test2.db795forcedelete no-such-file796 797ifcapable subquery {798 do_test attach-7.1 {799 forcedelete test.db test.db-journal800 sqlite3 db test.db801 catchsql {802 DETACH RAISE ( IGNORE ) IN ( SELECT "AAAAAA" . * ORDER BY 803 REGISTER LIMIT "AAAAAA" . "AAAAAA" OFFSET RAISE ( IGNORE ) NOT NULL )804 }805 } {1 {no such table: AAAAAA}}806}807 808# Create a malformed file (a file that is not a valid database)809# and try to attach it810#811do_test attach-8.1 {812 set fd [open test2.db w]813 puts $fd "This file is not a valid SQLite database"814 close $fd815 catchsql {816 ATTACH 'test2.db' AS t2;817 }818} {1 {file is not a database}}819do_test attach-8.2 {820 db errorcode821} {26}822forcedelete test2.db823do_test attach-8.3 {824 sqlite3 db2 test2.db825 db2 eval {CREATE TABLE t1(x); BEGIN EXCLUSIVE}826 catchsql {827 ATTACH 'test2.db' AS t2;828 }829} {1 {database is locked}}830do_test attach-8.4 {831 db errorcode832} {5}833db2 close834forcedelete test2.db835 836# Test that it is possible to attach the same database more than837# once when not in shared-cache mode. That this is not possible in838# shared-cache mode is tested in shared7.test.839do_test attach-9.1 {840 forcedelete test4.db841 execsql {842 ATTACH 'test4.db' AS aux1;843 CREATE TABLE aux1.t1(a, b);844 INSERT INTO aux1.t1 VALUES(1, 2);845 ATTACH 'test4.db' AS aux2;846 SELECT * FROM aux2.t1;847 }848} {1 2}849do_test attach-9.2 {850 catchsql {851 BEGIN;852 INSERT INTO aux1.t1 VALUES(3, 4);853 INSERT INTO aux2.t1 VALUES(5, 6);854 }855} {1 {database is locked}}856do_test attach-9.3 {857 execsql {858 COMMIT;859 SELECT * FROM aux2.t1;860 }861} {1 2 3 4}862 863# Ticket [abe728bbc311d81334dae9762f0db87c07a98f79].864# Multi-database commit on an attached TEMP database.865#866do_test attach-10.1 {867 execsql {868 ATTACH '' AS noname;869 ATTACH ':memory:' AS inmem;870 BEGIN;871 CREATE TABLE noname.noname(x);872 CREATE TABLE inmem.inmem(y);873 CREATE TABLE main.main(z);874 COMMIT;875 SELECT name FROM noname.sqlite_master;876 SELECT name FROM inmem.sqlite_master;877 }878} {noname inmem}879do_test attach-10.2 {880 lrange [execsql {881 PRAGMA database_list;882 }] 9 end883} {4 noname {} 5 inmem {}}884 885# Attach with a very long URI filename.886#887db close888sqlite3 db test.db -uri 1889do_execsql_test attach-11.1 {890 ATTACH printf('file:%09000x/x.db?mode=memory&cache=shared',1) AS aux1;891 CREATE TABLE aux1.t1(x,y);892 INSERT INTO aux1.t1(x,y) VALUES(1,2),(3,4);893 SELECT * FROM aux1.t1;894} {1 2 3 4}895 896# Ticket https://sqlite.org/src/tktview/a4e06e75a9ab61a1 2017-07-15897# False positive when running integrity_check on a connection with898# attached databases. 899#900db close901sqlite3 db :memory:902do_execsql_test attach-12.1 {903 CREATE TABLE Table1 (col TEXT NOT NULL PRIMARY KEY);904 ATTACH ':memory:' AS db2;905 CREATE TABLE db2.Table2(col1 INTEGER, col2 INTEGER, col3 INTEGER, col4);906 CREATE UNIQUE INDEX db2.idx_col1_unique ON Table2 (col1);907 CREATE UNIQUE INDEX db2.idx_col23_unique ON Table2 (col2, col3);908 CREATE INDEX db2.idx_col2 ON Table2 (col2);909 INSERT INTO Table2 VALUES(1,2,3,4);910 PRAGMA integrity_check;911} {ok}912 913# 2021-03-10 Forum post https://sqlite.org/forum/forumpost/a006d86f72914#915reset_db916do_test attach-13.1 {917 sqlite3 db :memory:918 db eval {CREATE TABLE base(x);}919 for {set i 0} {$i<$SQLITE_MAX_ATTACHED} {incr i} {920 db eval "ATTACH ':memory:' AS a$i"921 }922 set m "a[expr {$SQLITE_MAX_ATTACHED-1}]"923 db eval "CREATE TABLE $m.t1(a INTEGER PRIMARY KEY, b);"924 db eval "CREATE TABLE $m.t2(a INTEGER PRIMARY KEY, b);"925 db eval {SELECT a FROM t1 WHERE b IN (SELECT a FROM t2);}926} {}927 928finish_test929 