xref: /sqlite-3.40.0/test/attach3.test (revision e0a04a36)
1cbb18d22Sdanielk1977# 2003 July 1
2cbb18d22Sdanielk1977#
3cbb18d22Sdanielk1977# The author disclaims copyright to this source code.  In place of
4cbb18d22Sdanielk1977# a legal notice, here is a blessing:
5cbb18d22Sdanielk1977#
6cbb18d22Sdanielk1977#    May you do good and not evil.
7cbb18d22Sdanielk1977#    May you find forgiveness for yourself and forgive others.
8cbb18d22Sdanielk1977#    May you share freely, never taking more than you give.
9cbb18d22Sdanielk1977#
10cbb18d22Sdanielk1977#***********************************************************************
11cbb18d22Sdanielk1977# This file implements regression tests for SQLite library.  The
12cbb18d22Sdanielk1977# focus of this script is testing the ATTACH and DETACH commands
13cbb18d22Sdanielk1977# and schema changes to attached databases.
14cbb18d22Sdanielk1977#
155a8f9374Sdanielk1977# $Id: attach3.test,v 1.18 2007/10/09 08:29:32 danielk1977 Exp $
16cbb18d22Sdanielk1977#
17cbb18d22Sdanielk1977
18cbb18d22Sdanielk1977set testdir [file dirname $argv0]
19cbb18d22Sdanielk1977source $testdir/tester.tcl
20cbb18d22Sdanielk1977
215a8f9374Sdanielk1977ifcapable !attach {
225a8f9374Sdanielk1977  finish_test
235a8f9374Sdanielk1977  return
245a8f9374Sdanielk1977}
255a8f9374Sdanielk1977
26523a087bSdan# The tests in this file were written before SQLite supported recursive
27523a087bSdan# trigger invocation, and some tests depend on that to pass. So disable
28523a087bSdan# recursive triggers for this file.
295bde73c4Sdancatchsql { pragma recursive_triggers = off }
30523a087bSdan
31cbb18d22Sdanielk1977# Create tables t1 and t2 in the main database
32cbb18d22Sdanielk1977execsql {
33cbb18d22Sdanielk1977  CREATE TABLE t1(a, b);
34cbb18d22Sdanielk1977  CREATE TABLE t2(c, d);
35cbb18d22Sdanielk1977}
36cbb18d22Sdanielk1977
37cbb18d22Sdanielk1977# Create tables t1 and t2 in database file test2.db
38fda06befSmistachkinforcedelete test2.db
39fda06befSmistachkinforcedelete test2.db-journal
40ef4ac8f9Sdrhsqlite3 db2 test2.db
41cbb18d22Sdanielk1977execsql {
42cbb18d22Sdanielk1977  CREATE TABLE t1(a, b);
43cbb18d22Sdanielk1977  CREATE TABLE t2(c, d);
44cbb18d22Sdanielk1977} db2
45cbb18d22Sdanielk1977db2 close
46cbb18d22Sdanielk1977
47cbb18d22Sdanielk1977# Create a table in the auxilary database.
48a8858103Sdanielk1977do_test attach3-1.1 {
49cbb18d22Sdanielk1977  execsql {
50cbb18d22Sdanielk1977    ATTACH 'test2.db' AS aux;
51cbb18d22Sdanielk1977  }
52cbb18d22Sdanielk1977} {}
53a8858103Sdanielk1977do_test attach3-1.2 {
54cbb18d22Sdanielk1977  execsql {
55cbb18d22Sdanielk1977    CREATE TABLE aux.t3(e, f);
56cbb18d22Sdanielk1977  }
57cbb18d22Sdanielk1977} {}
58a8858103Sdanielk1977do_test attach3-1.3 {
59cbb18d22Sdanielk1977  execsql {
60cbb18d22Sdanielk1977    SELECT * FROM sqlite_master WHERE name = 't3';
61cbb18d22Sdanielk1977  }
62cbb18d22Sdanielk1977} {}
63a8858103Sdanielk1977do_test attach3-1.4 {
64cbb18d22Sdanielk1977  execsql {
65cbb18d22Sdanielk1977    SELECT * FROM aux.sqlite_master WHERE name = 't3';
66cbb18d22Sdanielk1977  }
6745901d62Sdanielk1977} "table t3 t3 [expr $AUTOVACUUM?5:4] {CREATE TABLE t3(e, f)}"
68a8858103Sdanielk1977do_test attach3-1.5 {
69cbb18d22Sdanielk1977  execsql {
70cbb18d22Sdanielk1977    INSERT INTO t3 VALUES(1, 2);
71cbb18d22Sdanielk1977    SELECT * FROM t3;
72cbb18d22Sdanielk1977  }
73cbb18d22Sdanielk1977} {1 2}
74cbb18d22Sdanielk1977
75cbb18d22Sdanielk1977# Create an index on the auxilary database table.
76ef2cb63eSdanielk1977do_test attach3-2.1 {
77cbb18d22Sdanielk1977  execsql {
78cbb18d22Sdanielk1977    CREATE INDEX aux.i1 on t3(e);
79cbb18d22Sdanielk1977  }
80cbb18d22Sdanielk1977} {}
81ef2cb63eSdanielk1977do_test attach3-2.2 {
82cbb18d22Sdanielk1977  execsql {
83cbb18d22Sdanielk1977    SELECT * FROM sqlite_master WHERE name = 'i1';
84cbb18d22Sdanielk1977  }
85cbb18d22Sdanielk1977} {}
86ef2cb63eSdanielk1977do_test attach3-2.3 {
87cbb18d22Sdanielk1977  execsql {
88cbb18d22Sdanielk1977    SELECT * FROM aux.sqlite_master WHERE name = 'i1';
89cbb18d22Sdanielk1977  }
9045901d62Sdanielk1977} "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}"
91cbb18d22Sdanielk1977
92a8858103Sdanielk1977# Drop the index on the aux database table.
93ef2cb63eSdanielk1977do_test attach3-3.1 {
94a8858103Sdanielk1977  execsql {
95a8858103Sdanielk1977    DROP INDEX aux.i1;
96a8858103Sdanielk1977    SELECT * FROM aux.sqlite_master WHERE name = 'i1';
97a8858103Sdanielk1977  }
98a8858103Sdanielk1977} {}
99ef2cb63eSdanielk1977do_test attach3-3.2 {
100a8858103Sdanielk1977  execsql {
101a8858103Sdanielk1977    CREATE INDEX aux.i1 on t3(e);
102a8858103Sdanielk1977    SELECT * FROM aux.sqlite_master WHERE name = 'i1';
103a8858103Sdanielk1977  }
10445901d62Sdanielk1977} "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}"
105ef2cb63eSdanielk1977do_test attach3-3.3 {
106a8858103Sdanielk1977  execsql {
107a8858103Sdanielk1977    DROP INDEX i1;
108a8858103Sdanielk1977    SELECT * FROM aux.sqlite_master WHERE name = 'i1';
109a8858103Sdanielk1977  }
110a8858103Sdanielk1977} {}
111a8858103Sdanielk1977
11248dec7e2Sdanielk1977# Drop tables t1 and t2 in the auxilary database.
113ef2cb63eSdanielk1977do_test attach3-4.1 {
114a8858103Sdanielk1977  execsql {
115a8858103Sdanielk1977    DROP TABLE aux.t1;
116a8858103Sdanielk1977    SELECT name FROM aux.sqlite_master;
117a8858103Sdanielk1977  }
118a8858103Sdanielk1977} {t2 t3}
119ef2cb63eSdanielk1977do_test attach3-4.2 {
120a8858103Sdanielk1977  # This will drop main.t2
121a8858103Sdanielk1977  execsql {
122a8858103Sdanielk1977    DROP TABLE t2;
123a8858103Sdanielk1977    SELECT name FROM aux.sqlite_master;
124a8858103Sdanielk1977  }
125a8858103Sdanielk1977} {t2 t3}
126ef2cb63eSdanielk1977do_test attach3-4.3 {
127a8858103Sdanielk1977  execsql {
128a8858103Sdanielk1977    DROP TABLE t2;
129a8858103Sdanielk1977    SELECT name FROM aux.sqlite_master;
130a8858103Sdanielk1977  }
131a8858103Sdanielk1977} {t3}
13248dec7e2Sdanielk1977
13348dec7e2Sdanielk1977# Create a view in the auxilary database.
1340fa8ddbdSdanielk1977ifcapable view {
135ef2cb63eSdanielk1977do_test attach3-5.1 {
136a8858103Sdanielk1977  execsql {
13748dec7e2Sdanielk1977    CREATE VIEW aux.v1 AS SELECT * FROM t3;
13848dec7e2Sdanielk1977  }
13948dec7e2Sdanielk1977} {}
140ef2cb63eSdanielk1977do_test attach3-5.2 {
14148dec7e2Sdanielk1977  execsql {
14248dec7e2Sdanielk1977    SELECT * FROM aux.sqlite_master WHERE name = 'v1';
14348dec7e2Sdanielk1977  }
14448dec7e2Sdanielk1977} {view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t3}}
145ef2cb63eSdanielk1977do_test attach3-5.3 {
14648dec7e2Sdanielk1977  execsql {
14748dec7e2Sdanielk1977    INSERT INTO aux.t3 VALUES('hello', 'world');
14848dec7e2Sdanielk1977    SELECT * FROM v1;
14948dec7e2Sdanielk1977  }
15048dec7e2Sdanielk1977} {1 2 hello world}
15148dec7e2Sdanielk1977
15248dec7e2Sdanielk1977# Drop the view
153ef2cb63eSdanielk1977do_test attach3-6.1 {
15448dec7e2Sdanielk1977  execsql {
15548dec7e2Sdanielk1977    DROP VIEW aux.v1;
15648dec7e2Sdanielk1977  }
15748dec7e2Sdanielk1977} {}
158ef2cb63eSdanielk1977do_test attach3-6.2 {
15948dec7e2Sdanielk1977  execsql {
16048dec7e2Sdanielk1977    SELECT * FROM aux.sqlite_master WHERE name = 'v1';
161a8858103Sdanielk1977  }
162a8858103Sdanielk1977} {}
1630fa8ddbdSdanielk1977} ;# ifcapable view
164a8858103Sdanielk1977
165798da52cSdrhifcapable {trigger} {
166ef2cb63eSdanielk1977# Create a trigger in the auxilary database.
167ef2cb63eSdanielk1977do_test attach3-7.1 {
168ef2cb63eSdanielk1977  execsql {
169ef2cb63eSdanielk1977    CREATE TRIGGER aux.tr1 AFTER INSERT ON t3 BEGIN
170ef2cb63eSdanielk1977      INSERT INTO t3 VALUES(new.e*2, new.f*2);
171ef2cb63eSdanielk1977    END;
172ef2cb63eSdanielk1977  }
173ef2cb63eSdanielk1977} {}
174ef2cb63eSdanielk1977do_test attach3-7.2 {
175ef2cb63eSdanielk1977  execsql {
176ef2cb63eSdanielk1977    DELETE FROM t3;
177ef2cb63eSdanielk1977    INSERT INTO t3 VALUES(10, 20);
178ef2cb63eSdanielk1977    SELECT * FROM t3;
179ef2cb63eSdanielk1977  }
180ef2cb63eSdanielk1977} {10 20 20 40}
181ef2cb63eSdanielk1977do_test attach3-5.3 {
182ef2cb63eSdanielk1977  execsql {
183ef2cb63eSdanielk1977    SELECT * FROM aux.sqlite_master WHERE name = 'tr1';
184ef2cb63eSdanielk1977  }
1853df6b257Sdanielk1977} {trigger tr1 t3 0 {CREATE TRIGGER tr1 AFTER INSERT ON t3 BEGIN
186ef2cb63eSdanielk1977      INSERT INTO t3 VALUES(new.e*2, new.f*2);
187ef2cb63eSdanielk1977    END}}
188ef2cb63eSdanielk1977
189ef2cb63eSdanielk1977# Drop the trigger
190ef2cb63eSdanielk1977do_test attach3-8.1 {
191ef2cb63eSdanielk1977  execsql {
192ef2cb63eSdanielk1977    DROP TRIGGER aux.tr1;
193ef2cb63eSdanielk1977  }
194ef2cb63eSdanielk1977} {}
195ef2cb63eSdanielk1977do_test attach3-8.2 {
196ef2cb63eSdanielk1977  execsql {
197ef2cb63eSdanielk1977    SELECT * FROM aux.sqlite_master WHERE name = 'tr1';
198ef2cb63eSdanielk1977  }
199ef2cb63eSdanielk1977} {}
200ef2cb63eSdanielk1977
20153c0f748Sdanielk1977ifcapable tempdb {
2028e227875Sdanielk1977  # Try to trick SQLite into dropping the wrong temp trigger.
2038e227875Sdanielk1977  do_test attach3-9.0 {
2048e227875Sdanielk1977    execsql {
2058e227875Sdanielk1977      CREATE TABLE main.t4(a, b, c);
2068e227875Sdanielk1977      CREATE TABLE aux.t4(a, b, c);
2078e227875Sdanielk1977      CREATE TEMP TRIGGER tst_trigger BEFORE INSERT ON aux.t4 BEGIN
2088e227875Sdanielk1977        SELECT 'hello world';
2098e227875Sdanielk1977      END;
210*e0a04a36Sdrh      SELECT count(*) FROM temp.sqlite_master;
2118e227875Sdanielk1977    }
2128e227875Sdanielk1977  } {1}
2138e227875Sdanielk1977  do_test attach3-9.1 {
2148e227875Sdanielk1977    execsql {
2158e227875Sdanielk1977      DROP TABLE main.t4;
2168e227875Sdanielk1977      SELECT count(*) FROM sqlite_temp_master;
2178e227875Sdanielk1977    }
2188e227875Sdanielk1977  } {1}
2198e227875Sdanielk1977  do_test attach3-9.2 {
2208e227875Sdanielk1977    execsql {
2218e227875Sdanielk1977      DROP TABLE aux.t4;
222*e0a04a36Sdrh      SELECT count(*) FROM temp.sqlite_master;
2238e227875Sdanielk1977    }
2248e227875Sdanielk1977  } {0}
22553c0f748Sdanielk1977}
226798da52cSdrh} ;# endif trigger
2278e227875Sdanielk1977
228d008cfe3Sdanielk1977# Make sure the aux.sqlite_master table is read-only
229d008cfe3Sdanielk1977do_test attach3-10.0 {
230d008cfe3Sdanielk1977  catchsql {
231d008cfe3Sdanielk1977    INSERT INTO aux.sqlite_master VALUES(1, 2, 3, 4, 5);
232d008cfe3Sdanielk1977  }
233d008cfe3Sdanielk1977} {1 {table sqlite_master may not be modified}}
234d008cfe3Sdanielk1977
235755b6ba9Sdrh# Failure to attach leaves us in a workable state.
236755b6ba9Sdrh# Ticket #811
237755b6ba9Sdrh#
238755b6ba9Sdrhdo_test attach3-11.0 {
239755b6ba9Sdrh  catchsql {
240755b6ba9Sdrh    ATTACH DATABASE '/nodir/nofile.x' AS notadb;
241755b6ba9Sdrh  }
242755b6ba9Sdrh} {1 {unable to open database: /nodir/nofile.x}}
243755b6ba9Sdrhdo_test attach3-11.1 {
244755b6ba9Sdrh  catchsql {
245755b6ba9Sdrh    ATTACH DATABASE ':memory:' AS notadb;
246755b6ba9Sdrh  }
247755b6ba9Sdrh} {0 {}}
248755b6ba9Sdrhdo_test attach3-11.2 {
249755b6ba9Sdrh  catchsql {
250755b6ba9Sdrh    DETACH DATABASE notadb;
251755b6ba9Sdrh  }
252755b6ba9Sdrh} {0 {}}
253d008cfe3Sdanielk1977
254ea063f5bSdrh# Return a list of attached databases
255ea063f5bSdrh#
256ea063f5bSdrhproc db_list {} {
257ea063f5bSdrh  set x [execsql {
258ea063f5bSdrh    PRAGMA database_list;
259ea063f5bSdrh  }]
260ea063f5bSdrh  set y {}
261ea063f5bSdrh  foreach {n id file} $x {lappend y $id}
262ea063f5bSdrh  return $y
263ea063f5bSdrh}
264ea063f5bSdrh
2654b2688abSdanielk1977ifcapable schema_pragmas&&tempdb {
2664b2688abSdanielk1977
2674b2688abSdanielk1977ifcapable !trigger {
2684b2688abSdanielk1977  execsql {create temp table dummy(dummy)}
2694b2688abSdanielk1977}
2704b2688abSdanielk1977
271ea063f5bSdrh# Ticket #1825
272ea063f5bSdrh#
273ea063f5bSdrhdo_test attach3-12.1 {
274ea063f5bSdrh  db_list
275ea063f5bSdrh} {main temp aux}
276ea063f5bSdrhdo_test attach3-12.2 {
277ea063f5bSdrh  execsql {
278ea063f5bSdrh    ATTACH DATABASE ? AS ?
279ea063f5bSdrh  }
280ea063f5bSdrh  db_list
281ea063f5bSdrh} {main temp aux {}}
282ea063f5bSdrhdo_test attach3-12.3 {
283ea063f5bSdrh  execsql {
284ea063f5bSdrh    DETACH aux
285ea063f5bSdrh  }
286ea063f5bSdrh  db_list
287ea063f5bSdrh} {main temp {}}
288ea063f5bSdrhdo_test attach3-12.4 {
289ea063f5bSdrh  execsql {
290ea063f5bSdrh    DETACH ?
291ea063f5bSdrh  }
292ea063f5bSdrh  db_list
293ea063f5bSdrh} {main temp}
294ea063f5bSdrhdo_test attach3-12.5 {
295ea063f5bSdrh  execsql {
296ea063f5bSdrh    ATTACH DATABASE '' AS ''
297ea063f5bSdrh  }
298ea063f5bSdrh  db_list
299ea063f5bSdrh} {main temp {}}
300ea063f5bSdrhdo_test attach3-12.6 {
301ea063f5bSdrh  execsql {
302ea063f5bSdrh    DETACH ''
303ea063f5bSdrh  }
304ea063f5bSdrh  db_list
305ea063f5bSdrh} {main temp}
306ea063f5bSdrhdo_test attach3-12.7 {
307ea063f5bSdrh  execsql {
308ea063f5bSdrh    ATTACH DATABASE '' AS ?
309ea063f5bSdrh  }
310ea063f5bSdrh  db_list
311ea063f5bSdrh} {main temp {}}
312ea063f5bSdrhdo_test attach3-12.8 {
313ea063f5bSdrh  execsql {
314ea063f5bSdrh    DETACH ''
315ea063f5bSdrh  }
316ea063f5bSdrh  db_list
317ea063f5bSdrh} {main temp}
318ea063f5bSdrhdo_test attach3-12.9 {
319ea063f5bSdrh  execsql {
320ea063f5bSdrh    ATTACH DATABASE '' AS NULL
321ea063f5bSdrh  }
322ea063f5bSdrh  db_list
323ea063f5bSdrh} {main temp {}}
324ea063f5bSdrhdo_test attach3-12.10 {
325ea063f5bSdrh  execsql {
326ea063f5bSdrh    DETACH ?
327ea063f5bSdrh  }
328ea063f5bSdrh  db_list
329ea063f5bSdrh} {main temp}
330ea063f5bSdrhdo_test attach3-12.11 {
331ea063f5bSdrh  catchsql {
332ea063f5bSdrh    DETACH NULL
333ea063f5bSdrh  }
334ea063f5bSdrh} {1 {no such database: }}
335ea063f5bSdrhdo_test attach3-12.12 {
336ea063f5bSdrh  catchsql {
337ea063f5bSdrh    ATTACH null AS null;
338ea063f5bSdrh    ATTACH '' AS '';
339ea063f5bSdrh  }
340ea063f5bSdrh} {1 {database  is already in use}}
341ea063f5bSdrhdo_test attach3-12.13 {
342ea063f5bSdrh  db_list
343ea063f5bSdrh} {main temp {}}
344ea063f5bSdrhdo_test attach3-12.14 {
345ea063f5bSdrh  execsql {
346ea063f5bSdrh    DETACH '';
347ea063f5bSdrh  }
348ea063f5bSdrh  db_list
349ea063f5bSdrh} {main temp}
350ea063f5bSdrh
3514b2688abSdanielk1977} ;# ifcapable pragma
3524b2688abSdanielk1977
353cbb18d22Sdanielk1977finish_test
354