blob: 1c8601c7b35472b8139a5a1d0b1d8d7848f94ebe [file] [log] [blame]
danielk1977cbb18d22004-05-28 11:37:27 +00001# 2003 July 1
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 schema changes to attached databases.
14#
danielk19775a8f9372007-10-09 08:29:32 +000015# $Id: attach3.test,v 1.18 2007/10/09 08:29:32 danielk1977 Exp $
danielk1977cbb18d22004-05-28 11:37:27 +000016#
17
danielk1977cbb18d22004-05-28 11:37:27 +000018set testdir [file dirname $argv0]
19source $testdir/tester.tcl
20
danielk19775a8f9372007-10-09 08:29:32 +000021ifcapable !attach {
22 finish_test
23 return
24}
25
dan523a0872009-08-31 05:23:32 +000026# The tests in this file were written before SQLite supported recursive
27# trigger invocation, and some tests depend on that to pass. So disable
28# recursive triggers for this file.
dan5bde73c2009-09-01 17:11:07 +000029catchsql { pragma recursive_triggers = off }
dan523a0872009-08-31 05:23:32 +000030
danielk1977cbb18d22004-05-28 11:37:27 +000031# Create tables t1 and t2 in the main database
32execsql {
33 CREATE TABLE t1(a, b);
34 CREATE TABLE t2(c, d);
35}
36
37# Create tables t1 and t2 in database file test2.db
mistachkinfda06be2011-08-02 00:57:34 +000038forcedelete test2.db
39forcedelete test2.db-journal
drhef4ac8f2004-06-19 00:16:31 +000040sqlite3 db2 test2.db
danielk1977cbb18d22004-05-28 11:37:27 +000041execsql {
42 CREATE TABLE t1(a, b);
43 CREATE TABLE t2(c, d);
44} db2
45db2 close
46
47# Create a table in the auxilary database.
danielk1977a8858102004-05-28 12:11:21 +000048do_test attach3-1.1 {
danielk1977cbb18d22004-05-28 11:37:27 +000049 execsql {
50 ATTACH 'test2.db' AS aux;
51 }
52} {}
danielk1977a8858102004-05-28 12:11:21 +000053do_test attach3-1.2 {
danielk1977cbb18d22004-05-28 11:37:27 +000054 execsql {
55 CREATE TABLE aux.t3(e, f);
56 }
57} {}
danielk1977a8858102004-05-28 12:11:21 +000058do_test attach3-1.3 {
danielk1977cbb18d22004-05-28 11:37:27 +000059 execsql {
60 SELECT * FROM sqlite_master WHERE name = 't3';
61 }
62} {}
danielk1977a8858102004-05-28 12:11:21 +000063do_test attach3-1.4 {
danielk1977cbb18d22004-05-28 11:37:27 +000064 execsql {
65 SELECT * FROM aux.sqlite_master WHERE name = 't3';
66 }
danielk197745901d62004-11-10 15:27:38 +000067} "table t3 t3 [expr $AUTOVACUUM?5:4] {CREATE TABLE t3(e, f)}"
danielk1977a8858102004-05-28 12:11:21 +000068do_test attach3-1.5 {
danielk1977cbb18d22004-05-28 11:37:27 +000069 execsql {
70 INSERT INTO t3 VALUES(1, 2);
71 SELECT * FROM t3;
72 }
73} {1 2}
74
75# Create an index on the auxilary database table.
danielk1977ef2cb632004-05-29 02:37:19 +000076do_test attach3-2.1 {
danielk1977cbb18d22004-05-28 11:37:27 +000077 execsql {
78 CREATE INDEX aux.i1 on t3(e);
79 }
80} {}
danielk1977ef2cb632004-05-29 02:37:19 +000081do_test attach3-2.2 {
danielk1977cbb18d22004-05-28 11:37:27 +000082 execsql {
83 SELECT * FROM sqlite_master WHERE name = 'i1';
84 }
85} {}
danielk1977ef2cb632004-05-29 02:37:19 +000086do_test attach3-2.3 {
danielk1977cbb18d22004-05-28 11:37:27 +000087 execsql {
88 SELECT * FROM aux.sqlite_master WHERE name = 'i1';
89 }
danielk197745901d62004-11-10 15:27:38 +000090} "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}"
danielk1977cbb18d22004-05-28 11:37:27 +000091
danielk1977a8858102004-05-28 12:11:21 +000092# Drop the index on the aux database table.
danielk1977ef2cb632004-05-29 02:37:19 +000093do_test attach3-3.1 {
danielk1977a8858102004-05-28 12:11:21 +000094 execsql {
95 DROP INDEX aux.i1;
96 SELECT * FROM aux.sqlite_master WHERE name = 'i1';
97 }
98} {}
danielk1977ef2cb632004-05-29 02:37:19 +000099do_test attach3-3.2 {
danielk1977a8858102004-05-28 12:11:21 +0000100 execsql {
101 CREATE INDEX aux.i1 on t3(e);
102 SELECT * FROM aux.sqlite_master WHERE name = 'i1';
103 }
danielk197745901d62004-11-10 15:27:38 +0000104} "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}"
danielk1977ef2cb632004-05-29 02:37:19 +0000105do_test attach3-3.3 {
danielk1977a8858102004-05-28 12:11:21 +0000106 execsql {
107 DROP INDEX i1;
108 SELECT * FROM aux.sqlite_master WHERE name = 'i1';
109 }
110} {}
111
danielk197748dec7e2004-05-28 12:33:30 +0000112# Drop tables t1 and t2 in the auxilary database.
danielk1977ef2cb632004-05-29 02:37:19 +0000113do_test attach3-4.1 {
danielk1977a8858102004-05-28 12:11:21 +0000114 execsql {
115 DROP TABLE aux.t1;
116 SELECT name FROM aux.sqlite_master;
117 }
118} {t2 t3}
danielk1977ef2cb632004-05-29 02:37:19 +0000119do_test attach3-4.2 {
danielk1977a8858102004-05-28 12:11:21 +0000120 # This will drop main.t2
121 execsql {
122 DROP TABLE t2;
123 SELECT name FROM aux.sqlite_master;
124 }
125} {t2 t3}
danielk1977ef2cb632004-05-29 02:37:19 +0000126do_test attach3-4.3 {
danielk1977a8858102004-05-28 12:11:21 +0000127 execsql {
128 DROP TABLE t2;
129 SELECT name FROM aux.sqlite_master;
130 }
131} {t3}
danielk197748dec7e2004-05-28 12:33:30 +0000132
133# Create a view in the auxilary database.
danielk19770fa8ddb2004-11-22 08:43:32 +0000134ifcapable view {
danielk1977ef2cb632004-05-29 02:37:19 +0000135do_test attach3-5.1 {
danielk1977a8858102004-05-28 12:11:21 +0000136 execsql {
danielk197748dec7e2004-05-28 12:33:30 +0000137 CREATE VIEW aux.v1 AS SELECT * FROM t3;
138 }
139} {}
danielk1977ef2cb632004-05-29 02:37:19 +0000140do_test attach3-5.2 {
danielk197748dec7e2004-05-28 12:33:30 +0000141 execsql {
142 SELECT * FROM aux.sqlite_master WHERE name = 'v1';
143 }
144} {view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t3}}
danielk1977ef2cb632004-05-29 02:37:19 +0000145do_test attach3-5.3 {
danielk197748dec7e2004-05-28 12:33:30 +0000146 execsql {
147 INSERT INTO aux.t3 VALUES('hello', 'world');
148 SELECT * FROM v1;
149 }
150} {1 2 hello world}
151
152# Drop the view
danielk1977ef2cb632004-05-29 02:37:19 +0000153do_test attach3-6.1 {
danielk197748dec7e2004-05-28 12:33:30 +0000154 execsql {
155 DROP VIEW aux.v1;
156 }
157} {}
danielk1977ef2cb632004-05-29 02:37:19 +0000158do_test attach3-6.2 {
danielk197748dec7e2004-05-28 12:33:30 +0000159 execsql {
160 SELECT * FROM aux.sqlite_master WHERE name = 'v1';
danielk1977a8858102004-05-28 12:11:21 +0000161 }
162} {}
danielk19770fa8ddb2004-11-22 08:43:32 +0000163} ;# ifcapable view
danielk1977a8858102004-05-28 12:11:21 +0000164
drh798da522004-11-04 04:42:28 +0000165ifcapable {trigger} {
danielk1977ef2cb632004-05-29 02:37:19 +0000166# Create a trigger in the auxilary database.
167do_test attach3-7.1 {
168 execsql {
169 CREATE TRIGGER aux.tr1 AFTER INSERT ON t3 BEGIN
170 INSERT INTO t3 VALUES(new.e*2, new.f*2);
171 END;
172 }
173} {}
174do_test attach3-7.2 {
175 execsql {
176 DELETE FROM t3;
177 INSERT INTO t3 VALUES(10, 20);
178 SELECT * FROM t3;
179 }
180} {10 20 20 40}
181do_test attach3-5.3 {
182 execsql {
183 SELECT * FROM aux.sqlite_master WHERE name = 'tr1';
184 }
danielk19773df6b252004-05-29 10:23:19 +0000185} {trigger tr1 t3 0 {CREATE TRIGGER tr1 AFTER INSERT ON t3 BEGIN
danielk1977ef2cb632004-05-29 02:37:19 +0000186 INSERT INTO t3 VALUES(new.e*2, new.f*2);
187 END}}
188
189# Drop the trigger
190do_test attach3-8.1 {
191 execsql {
192 DROP TRIGGER aux.tr1;
193 }
194} {}
195do_test attach3-8.2 {
196 execsql {
197 SELECT * FROM aux.sqlite_master WHERE name = 'tr1';
198 }
199} {}
200
danielk197753c0f742005-03-29 03:10:59 +0000201ifcapable tempdb {
202 # Try to trick SQLite into dropping the wrong temp trigger.
203 do_test attach3-9.0 {
204 execsql {
205 CREATE TABLE main.t4(a, b, c);
206 CREATE TABLE aux.t4(a, b, c);
207 CREATE TEMP TRIGGER tst_trigger BEFORE INSERT ON aux.t4 BEGIN
208 SELECT 'hello world';
209 END;
drhe0a04a32016-12-16 01:00:21 +0000210 SELECT count(*) FROM temp.sqlite_master;
danielk197753c0f742005-03-29 03:10:59 +0000211 }
212 } {1}
213 do_test attach3-9.1 {
214 execsql {
215 DROP TABLE main.t4;
216 SELECT count(*) FROM sqlite_temp_master;
217 }
218 } {1}
219 do_test attach3-9.2 {
220 execsql {
221 DROP TABLE aux.t4;
drhe0a04a32016-12-16 01:00:21 +0000222 SELECT count(*) FROM temp.sqlite_master;
danielk197753c0f742005-03-29 03:10:59 +0000223 }
224 } {0}
225}
drh798da522004-11-04 04:42:28 +0000226} ;# endif trigger
danielk19778e227872004-06-07 07:52:17 +0000227
danielk1977d008cfe2004-06-19 02:22:10 +0000228# Make sure the aux.sqlite_master table is read-only
229do_test attach3-10.0 {
230 catchsql {
231 INSERT INTO aux.sqlite_master VALUES(1, 2, 3, 4, 5);
232 }
233} {1 {table sqlite_master may not be modified}}
234
drh755b6ba2004-07-19 00:56:23 +0000235# Failure to attach leaves us in a workable state.
236# Ticket #811
237#
238do_test attach3-11.0 {
239 catchsql {
240 ATTACH DATABASE '/nodir/nofile.x' AS notadb;
241 }
242} {1 {unable to open database: /nodir/nofile.x}}
243do_test attach3-11.1 {
244 catchsql {
245 ATTACH DATABASE ':memory:' AS notadb;
246 }
247} {0 {}}
248do_test attach3-11.2 {
249 catchsql {
250 DETACH DATABASE notadb;
251 }
252} {0 {}}
danielk1977d008cfe2004-06-19 02:22:10 +0000253
drhea063f52006-05-25 11:52:37 +0000254# Return a list of attached databases
255#
256proc db_list {} {
257 set x [execsql {
258 PRAGMA database_list;
259 }]
260 set y {}
261 foreach {n id file} $x {lappend y $id}
262 return $y
263}
264
danielk19774b2688a2006-06-20 11:01:07 +0000265ifcapable schema_pragmas&&tempdb {
266
267ifcapable !trigger {
268 execsql {create temp table dummy(dummy)}
269}
270
drhea063f52006-05-25 11:52:37 +0000271# Ticket #1825
272#
273do_test attach3-12.1 {
274 db_list
275} {main temp aux}
276do_test attach3-12.2 {
277 execsql {
278 ATTACH DATABASE ? AS ?
279 }
280 db_list
281} {main temp aux {}}
282do_test attach3-12.3 {
283 execsql {
284 DETACH aux
285 }
286 db_list
287} {main temp {}}
288do_test attach3-12.4 {
289 execsql {
290 DETACH ?
291 }
292 db_list
293} {main temp}
294do_test attach3-12.5 {
295 execsql {
296 ATTACH DATABASE '' AS ''
297 }
298 db_list
299} {main temp {}}
300do_test attach3-12.6 {
301 execsql {
302 DETACH ''
303 }
304 db_list
305} {main temp}
306do_test attach3-12.7 {
307 execsql {
308 ATTACH DATABASE '' AS ?
309 }
310 db_list
311} {main temp {}}
312do_test attach3-12.8 {
313 execsql {
314 DETACH ''
315 }
316 db_list
317} {main temp}
318do_test attach3-12.9 {
319 execsql {
320 ATTACH DATABASE '' AS NULL
321 }
322 db_list
323} {main temp {}}
324do_test attach3-12.10 {
325 execsql {
326 DETACH ?
327 }
328 db_list
329} {main temp}
330do_test attach3-12.11 {
331 catchsql {
332 DETACH NULL
333 }
334} {1 {no such database: }}
335do_test attach3-12.12 {
336 catchsql {
337 ATTACH null AS null;
338 ATTACH '' AS '';
339 }
340} {1 {database is already in use}}
341do_test attach3-12.13 {
342 db_list
343} {main temp {}}
344do_test attach3-12.14 {
345 execsql {
346 DETACH '';
347 }
348 db_list
349} {main temp}
350
danielk19774b2688a2006-06-20 11:01:07 +0000351} ;# ifcapable pragma
352
danielk1977cbb18d22004-05-28 11:37:27 +0000353finish_test