| # 2003 July 1 | |
| # | |
| # The author disclaims copyright to this source code. In place of | |
| # a legal notice, here is a blessing: | |
| # | |
| # May you do good and not evil. | |
| # May you find forgiveness for yourself and forgive others. | |
| # May you share freely, never taking more than you give. | |
| # | |
| #*********************************************************************** | |
| # This file implements regression tests for SQLite library. The | |
| # focus of this script is testing the ATTACH and DETACH commands | |
| # and schema changes to attached databases. | |
| # | |
| # $Id: attach3.test,v 1.18 2007/10/09 08:29:32 danielk1977 Exp $ | |
| # | |
| set testdir [file dirname $argv0] | |
| source $testdir/tester.tcl | |
| ifcapable !attach { | |
| finish_test | |
| return | |
| } | |
| # The tests in this file were written before SQLite supported recursive | |
| # trigger invocation, and some tests depend on that to pass. So disable | |
| # recursive triggers for this file. | |
| catchsql { pragma recursive_triggers = off } | |
| # Create tables t1 and t2 in the main database | |
| execsql { | |
| CREATE TABLE t1(a, b); | |
| CREATE TABLE t2(c, d); | |
| } | |
| # Create tables t1 and t2 in database file test2.db | |
| forcedelete test2.db | |
| forcedelete test2.db-journal | |
| sqlite3 db2 test2.db | |
| execsql { | |
| CREATE TABLE t1(a, b); | |
| CREATE TABLE t2(c, d); | |
| } db2 | |
| db2 close | |
| # Create a table in the auxilary database. | |
| do_test attach3-1.1 { | |
| execsql { | |
| ATTACH 'test2.db' AS aux; | |
| } | |
| } {} | |
| do_test attach3-1.2 { | |
| execsql { | |
| CREATE TABLE aux.t3(e, f); | |
| } | |
| } {} | |
| do_test attach3-1.3 { | |
| execsql { | |
| SELECT * FROM sqlite_master WHERE name = 't3'; | |
| } | |
| } {} | |
| do_test attach3-1.4 { | |
| execsql { | |
| SELECT * FROM aux.sqlite_master WHERE name = 't3'; | |
| } | |
| } "table t3 t3 [expr $AUTOVACUUM?5:4] {CREATE TABLE t3(e, f)}" | |
| do_test attach3-1.5 { | |
| execsql { | |
| INSERT INTO t3 VALUES(1, 2); | |
| SELECT * FROM t3; | |
| } | |
| } {1 2} | |
| # Create an index on the auxilary database table. | |
| do_test attach3-2.1 { | |
| execsql { | |
| CREATE INDEX aux.i1 on t3(e); | |
| } | |
| } {} | |
| do_test attach3-2.2 { | |
| execsql { | |
| SELECT * FROM sqlite_master WHERE name = 'i1'; | |
| } | |
| } {} | |
| do_test attach3-2.3 { | |
| execsql { | |
| SELECT * FROM aux.sqlite_master WHERE name = 'i1'; | |
| } | |
| } "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}" | |
| # Drop the index on the aux database table. | |
| do_test attach3-3.1 { | |
| execsql { | |
| DROP INDEX aux.i1; | |
| SELECT * FROM aux.sqlite_master WHERE name = 'i1'; | |
| } | |
| } {} | |
| do_test attach3-3.2 { | |
| execsql { | |
| CREATE INDEX aux.i1 on t3(e); | |
| SELECT * FROM aux.sqlite_master WHERE name = 'i1'; | |
| } | |
| } "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}" | |
| do_test attach3-3.3 { | |
| execsql { | |
| DROP INDEX i1; | |
| SELECT * FROM aux.sqlite_master WHERE name = 'i1'; | |
| } | |
| } {} | |
| # Drop tables t1 and t2 in the auxilary database. | |
| do_test attach3-4.1 { | |
| execsql { | |
| DROP TABLE aux.t1; | |
| SELECT name FROM aux.sqlite_master; | |
| } | |
| } {t2 t3} | |
| do_test attach3-4.2 { | |
| # This will drop main.t2 | |
| execsql { | |
| DROP TABLE t2; | |
| SELECT name FROM aux.sqlite_master; | |
| } | |
| } {t2 t3} | |
| do_test attach3-4.3 { | |
| execsql { | |
| DROP TABLE t2; | |
| SELECT name FROM aux.sqlite_master; | |
| } | |
| } {t3} | |
| # Create a view in the auxilary database. | |
| ifcapable view { | |
| do_test attach3-5.1 { | |
| execsql { | |
| CREATE VIEW aux.v1 AS SELECT * FROM t3; | |
| } | |
| } {} | |
| do_test attach3-5.2 { | |
| execsql { | |
| SELECT * FROM aux.sqlite_master WHERE name = 'v1'; | |
| } | |
| } {view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t3}} | |
| do_test attach3-5.3 { | |
| execsql { | |
| INSERT INTO aux.t3 VALUES('hello', 'world'); | |
| SELECT * FROM v1; | |
| } | |
| } {1 2 hello world} | |
| # Drop the view | |
| do_test attach3-6.1 { | |
| execsql { | |
| DROP VIEW aux.v1; | |
| } | |
| } {} | |
| do_test attach3-6.2 { | |
| execsql { | |
| SELECT * FROM aux.sqlite_master WHERE name = 'v1'; | |
| } | |
| } {} | |
| } ;# ifcapable view | |
| ifcapable {trigger} { | |
| # Create a trigger in the auxilary database. | |
| do_test attach3-7.1 { | |
| execsql { | |
| CREATE TRIGGER aux.tr1 AFTER INSERT ON t3 BEGIN | |
| INSERT INTO t3 VALUES(new.e*2, new.f*2); | |
| END; | |
| } | |
| } {} | |
| do_test attach3-7.2 { | |
| execsql { | |
| DELETE FROM t3; | |
| INSERT INTO t3 VALUES(10, 20); | |
| SELECT * FROM t3; | |
| } | |
| } {10 20 20 40} | |
| do_test attach3-5.3 { | |
| execsql { | |
| SELECT * FROM aux.sqlite_master WHERE name = 'tr1'; | |
| } | |
| } {trigger tr1 t3 0 {CREATE TRIGGER tr1 AFTER INSERT ON t3 BEGIN | |
| INSERT INTO t3 VALUES(new.e*2, new.f*2); | |
| END}} | |
| # Drop the trigger | |
| do_test attach3-8.1 { | |
| execsql { | |
| DROP TRIGGER aux.tr1; | |
| } | |
| } {} | |
| do_test attach3-8.2 { | |
| execsql { | |
| SELECT * FROM aux.sqlite_master WHERE name = 'tr1'; | |
| } | |
| } {} | |
| ifcapable tempdb { | |
| # Try to trick SQLite into dropping the wrong temp trigger. | |
| do_test attach3-9.0 { | |
| execsql { | |
| CREATE TABLE main.t4(a, b, c); | |
| CREATE TABLE aux.t4(a, b, c); | |
| CREATE TEMP TRIGGER tst_trigger BEFORE INSERT ON aux.t4 BEGIN | |
| SELECT 'hello world'; | |
| END; | |
| SELECT count(*) FROM temp.sqlite_master; | |
| } | |
| } {1} | |
| do_test attach3-9.1 { | |
| execsql { | |
| DROP TABLE main.t4; | |
| SELECT count(*) FROM sqlite_temp_master; | |
| } | |
| } {1} | |
| do_test attach3-9.2 { | |
| execsql { | |
| DROP TABLE aux.t4; | |
| SELECT count(*) FROM temp.sqlite_master; | |
| } | |
| } {0} | |
| } | |
| } ;# endif trigger | |
| # Make sure the aux.sqlite_master table is read-only | |
| do_test attach3-10.0 { | |
| catchsql { | |
| INSERT INTO aux.sqlite_master VALUES(1, 2, 3, 4, 5); | |
| } | |
| } {1 {table sqlite_master may not be modified}} | |
| # Failure to attach leaves us in a workable state. | |
| # Ticket #811 | |
| # | |
| do_test attach3-11.0 { | |
| catchsql { | |
| ATTACH DATABASE '/nodir/nofile.x' AS notadb; | |
| } | |
| } {1 {unable to open database: /nodir/nofile.x}} | |
| do_test attach3-11.1 { | |
| catchsql { | |
| ATTACH DATABASE ':memory:' AS notadb; | |
| } | |
| } {0 {}} | |
| do_test attach3-11.2 { | |
| catchsql { | |
| DETACH DATABASE notadb; | |
| } | |
| } {0 {}} | |
| # Return a list of attached databases | |
| # | |
| proc db_list {} { | |
| set x [execsql { | |
| PRAGMA database_list; | |
| }] | |
| set y {} | |
| foreach {n id file} $x {lappend y $id} | |
| return $y | |
| } | |
| ifcapable schema_pragmas&&tempdb { | |
| ifcapable !trigger { | |
| execsql {create temp table dummy(dummy)} | |
| } | |
| # Ticket #1825 | |
| # | |
| do_test attach3-12.1 { | |
| db_list | |
| } {main temp aux} | |
| do_test attach3-12.2 { | |
| execsql { | |
| ATTACH DATABASE ? AS ? | |
| } | |
| db_list | |
| } {main temp aux {}} | |
| do_test attach3-12.3 { | |
| execsql { | |
| DETACH aux | |
| } | |
| db_list | |
| } {main temp {}} | |
| do_test attach3-12.4 { | |
| execsql { | |
| DETACH ? | |
| } | |
| db_list | |
| } {main temp} | |
| do_test attach3-12.5 { | |
| execsql { | |
| ATTACH DATABASE '' AS '' | |
| } | |
| db_list | |
| } {main temp {}} | |
| do_test attach3-12.6 { | |
| execsql { | |
| DETACH '' | |
| } | |
| db_list | |
| } {main temp} | |
| do_test attach3-12.7 { | |
| execsql { | |
| ATTACH DATABASE '' AS ? | |
| } | |
| db_list | |
| } {main temp {}} | |
| do_test attach3-12.8 { | |
| execsql { | |
| DETACH '' | |
| } | |
| db_list | |
| } {main temp} | |
| do_test attach3-12.9 { | |
| execsql { | |
| ATTACH DATABASE '' AS NULL | |
| } | |
| db_list | |
| } {main temp {}} | |
| do_test attach3-12.10 { | |
| execsql { | |
| DETACH ? | |
| } | |
| db_list | |
| } {main temp} | |
| do_test attach3-12.11 { | |
| catchsql { | |
| DETACH NULL | |
| } | |
| } {1 {no such database: }} | |
| do_test attach3-12.12 { | |
| catchsql { | |
| ATTACH null AS null; | |
| ATTACH '' AS ''; | |
| } | |
| } {1 {database is already in use}} | |
| do_test attach3-12.13 { | |
| db_list | |
| } {main temp {}} | |
| do_test attach3-12.14 { | |
| execsql { | |
| DETACH ''; | |
| } | |
| db_list | |
| } {main temp} | |
| } ;# ifcapable pragma | |
| finish_test |