xref: /sqlite-3.40.0/test/attach.test (revision 5d00d0a8)
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