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