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