| OLD | NEW | 
 | (Empty) | 
|    1 # 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 # |  | 
|   15 # $Id: attach3.test,v 1.18 2007/10/09 08:29:32 danielk1977 Exp $ |  | 
|   16 # |  | 
|   17  |  | 
|   18 set testdir [file dirname $argv0] |  | 
|   19 source $testdir/tester.tcl |  | 
|   20  |  | 
|   21 ifcapable !attach { |  | 
|   22   finish_test |  | 
|   23   return |  | 
|   24 } |  | 
|   25  |  | 
|   26 # 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. |  | 
|   29 catchsql { pragma recursive_triggers = off }  |  | 
|   30  |  | 
|   31 # Create tables t1 and t2 in the main database |  | 
|   32 execsql { |  | 
|   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 |  | 
|   38 file delete -force test2.db |  | 
|   39 file delete -force test2.db-journal |  | 
|   40 sqlite3 db2 test2.db |  | 
|   41 execsql { |  | 
|   42   CREATE TABLE t1(a, b); |  | 
|   43   CREATE TABLE t2(c, d); |  | 
|   44 } db2 |  | 
|   45 db2 close |  | 
|   46  |  | 
|   47 # Create a table in the auxilary database. |  | 
|   48 do_test attach3-1.1 { |  | 
|   49   execsql { |  | 
|   50     ATTACH 'test2.db' AS aux; |  | 
|   51   } |  | 
|   52 } {} |  | 
|   53 do_test attach3-1.2 { |  | 
|   54   execsql { |  | 
|   55     CREATE TABLE aux.t3(e, f); |  | 
|   56   } |  | 
|   57 } {} |  | 
|   58 do_test attach3-1.3 { |  | 
|   59   execsql { |  | 
|   60     SELECT * FROM sqlite_master WHERE name = 't3'; |  | 
|   61   } |  | 
|   62 } {} |  | 
|   63 do_test attach3-1.4 { |  | 
|   64   execsql { |  | 
|   65     SELECT * FROM aux.sqlite_master WHERE name = 't3'; |  | 
|   66   } |  | 
|   67 } "table t3 t3 [expr $AUTOVACUUM?5:4] {CREATE TABLE t3(e, f)}" |  | 
|   68 do_test attach3-1.5 { |  | 
|   69   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. |  | 
|   76 do_test attach3-2.1 { |  | 
|   77   execsql { |  | 
|   78     CREATE INDEX aux.i1 on t3(e); |  | 
|   79   } |  | 
|   80 } {} |  | 
|   81 do_test attach3-2.2 { |  | 
|   82   execsql { |  | 
|   83     SELECT * FROM sqlite_master WHERE name = 'i1'; |  | 
|   84   } |  | 
|   85 } {} |  | 
|   86 do_test attach3-2.3 { |  | 
|   87   execsql { |  | 
|   88     SELECT * FROM aux.sqlite_master WHERE name = 'i1'; |  | 
|   89   } |  | 
|   90 } "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}" |  | 
|   91  |  | 
|   92 # Drop the index on the aux database table. |  | 
|   93 do_test attach3-3.1 { |  | 
|   94   execsql { |  | 
|   95     DROP INDEX aux.i1; |  | 
|   96     SELECT * FROM aux.sqlite_master WHERE name = 'i1'; |  | 
|   97   } |  | 
|   98 } {} |  | 
|   99 do_test attach3-3.2 { |  | 
|  100   execsql { |  | 
|  101     CREATE INDEX aux.i1 on t3(e); |  | 
|  102     SELECT * FROM aux.sqlite_master WHERE name = 'i1'; |  | 
|  103   } |  | 
|  104 } "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}" |  | 
|  105 do_test attach3-3.3 { |  | 
|  106   execsql { |  | 
|  107     DROP INDEX i1; |  | 
|  108     SELECT * FROM aux.sqlite_master WHERE name = 'i1'; |  | 
|  109   } |  | 
|  110 } {} |  | 
|  111  |  | 
|  112 # Drop tables t1 and t2 in the auxilary database. |  | 
|  113 do_test attach3-4.1 { |  | 
|  114   execsql { |  | 
|  115     DROP TABLE aux.t1; |  | 
|  116     SELECT name FROM aux.sqlite_master; |  | 
|  117   } |  | 
|  118 } {t2 t3} |  | 
|  119 do_test attach3-4.2 { |  | 
|  120   # This will drop main.t2 |  | 
|  121   execsql { |  | 
|  122     DROP TABLE t2; |  | 
|  123     SELECT name FROM aux.sqlite_master; |  | 
|  124   } |  | 
|  125 } {t2 t3} |  | 
|  126 do_test attach3-4.3 { |  | 
|  127   execsql { |  | 
|  128     DROP TABLE t2; |  | 
|  129     SELECT name FROM aux.sqlite_master; |  | 
|  130   } |  | 
|  131 } {t3} |  | 
|  132  |  | 
|  133 # Create a view in the auxilary database. |  | 
|  134 ifcapable view { |  | 
|  135 do_test attach3-5.1 { |  | 
|  136   execsql { |  | 
|  137     CREATE VIEW aux.v1 AS SELECT * FROM t3; |  | 
|  138   } |  | 
|  139 } {} |  | 
|  140 do_test attach3-5.2 { |  | 
|  141   execsql { |  | 
|  142     SELECT * FROM aux.sqlite_master WHERE name = 'v1'; |  | 
|  143   } |  | 
|  144 } {view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t3}} |  | 
|  145 do_test attach3-5.3 { |  | 
|  146   execsql { |  | 
|  147     INSERT INTO aux.t3 VALUES('hello', 'world'); |  | 
|  148     SELECT * FROM v1; |  | 
|  149   } |  | 
|  150 } {1 2 hello world} |  | 
|  151  |  | 
|  152 # Drop the view  |  | 
|  153 do_test attach3-6.1 { |  | 
|  154   execsql { |  | 
|  155     DROP VIEW aux.v1; |  | 
|  156   } |  | 
|  157 } {} |  | 
|  158 do_test attach3-6.2 { |  | 
|  159   execsql { |  | 
|  160     SELECT * FROM aux.sqlite_master WHERE name = 'v1'; |  | 
|  161   } |  | 
|  162 } {} |  | 
|  163 } ;# ifcapable view |  | 
|  164  |  | 
|  165 ifcapable {trigger} { |  | 
|  166 # Create a trigger in the auxilary database. |  | 
|  167 do_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 } {} |  | 
|  174 do_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} |  | 
|  181 do_test attach3-5.3 { |  | 
|  182   execsql { |  | 
|  183     SELECT * FROM aux.sqlite_master WHERE name = 'tr1'; |  | 
|  184   } |  | 
|  185 } {trigger tr1 t3 0 {CREATE TRIGGER tr1 AFTER INSERT ON t3 BEGIN |  | 
|  186       INSERT INTO t3 VALUES(new.e*2, new.f*2); |  | 
|  187     END}} |  | 
|  188  |  | 
|  189 # Drop the trigger  |  | 
|  190 do_test attach3-8.1 { |  | 
|  191   execsql { |  | 
|  192     DROP TRIGGER aux.tr1; |  | 
|  193   } |  | 
|  194 } {} |  | 
|  195 do_test attach3-8.2 { |  | 
|  196   execsql { |  | 
|  197     SELECT * FROM aux.sqlite_master WHERE name = 'tr1'; |  | 
|  198   } |  | 
|  199 } {} |  | 
|  200  |  | 
|  201 ifcapable 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; |  | 
|  210       SELECT count(*) FROM sqlite_temp_master; |  | 
|  211     } |  | 
|  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; |  | 
|  222       SELECT count(*) FROM sqlite_temp_master; |  | 
|  223     } |  | 
|  224   } {0} |  | 
|  225 } |  | 
|  226 } ;# endif trigger |  | 
|  227  |  | 
|  228 # Make sure the aux.sqlite_master table is read-only |  | 
|  229 do_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  |  | 
|  235 # Failure to attach leaves us in a workable state. |  | 
|  236 # Ticket #811 |  | 
|  237 # |  | 
|  238 do_test attach3-11.0 { |  | 
|  239   catchsql { |  | 
|  240     ATTACH DATABASE '/nodir/nofile.x' AS notadb; |  | 
|  241   } |  | 
|  242 } {1 {unable to open database: /nodir/nofile.x}} |  | 
|  243 do_test attach3-11.1 { |  | 
|  244   catchsql { |  | 
|  245     ATTACH DATABASE ':memory:' AS notadb; |  | 
|  246   } |  | 
|  247 } {0 {}} |  | 
|  248 do_test attach3-11.2 { |  | 
|  249   catchsql { |  | 
|  250     DETACH DATABASE notadb; |  | 
|  251   } |  | 
|  252 } {0 {}} |  | 
|  253  |  | 
|  254 # Return a list of attached databases |  | 
|  255 # |  | 
|  256 proc 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  |  | 
|  265 ifcapable schema_pragmas&&tempdb { |  | 
|  266  |  | 
|  267 ifcapable !trigger { |  | 
|  268   execsql {create temp table dummy(dummy)} |  | 
|  269 } |  | 
|  270  |  | 
|  271 # Ticket #1825 |  | 
|  272 # |  | 
|  273 do_test attach3-12.1 { |  | 
|  274   db_list |  | 
|  275 } {main temp aux} |  | 
|  276 do_test attach3-12.2 { |  | 
|  277   execsql { |  | 
|  278     ATTACH DATABASE ? AS ? |  | 
|  279   } |  | 
|  280   db_list |  | 
|  281 } {main temp aux {}} |  | 
|  282 do_test attach3-12.3 { |  | 
|  283   execsql { |  | 
|  284     DETACH aux |  | 
|  285   } |  | 
|  286   db_list |  | 
|  287 } {main temp {}} |  | 
|  288 do_test attach3-12.4 { |  | 
|  289   execsql { |  | 
|  290     DETACH ? |  | 
|  291   } |  | 
|  292   db_list |  | 
|  293 } {main temp} |  | 
|  294 do_test attach3-12.5 { |  | 
|  295   execsql { |  | 
|  296     ATTACH DATABASE '' AS '' |  | 
|  297   } |  | 
|  298   db_list |  | 
|  299 } {main temp {}} |  | 
|  300 do_test attach3-12.6 { |  | 
|  301   execsql { |  | 
|  302     DETACH '' |  | 
|  303   } |  | 
|  304   db_list |  | 
|  305 } {main temp} |  | 
|  306 do_test attach3-12.7 { |  | 
|  307   execsql { |  | 
|  308     ATTACH DATABASE '' AS ? |  | 
|  309   } |  | 
|  310   db_list |  | 
|  311 } {main temp {}} |  | 
|  312 do_test attach3-12.8 { |  | 
|  313   execsql { |  | 
|  314     DETACH '' |  | 
|  315   } |  | 
|  316   db_list |  | 
|  317 } {main temp} |  | 
|  318 do_test attach3-12.9 { |  | 
|  319   execsql { |  | 
|  320     ATTACH DATABASE '' AS NULL |  | 
|  321   } |  | 
|  322   db_list |  | 
|  323 } {main temp {}} |  | 
|  324 do_test attach3-12.10 { |  | 
|  325 breakpoint |  | 
|  326   execsql { |  | 
|  327     DETACH ? |  | 
|  328   } |  | 
|  329   db_list |  | 
|  330 } {main temp} |  | 
|  331 do_test attach3-12.11 { |  | 
|  332   catchsql { |  | 
|  333     DETACH NULL |  | 
|  334   } |  | 
|  335 } {1 {no such database: }} |  | 
|  336 do_test attach3-12.12 { |  | 
|  337   catchsql { |  | 
|  338     ATTACH null AS null; |  | 
|  339     ATTACH '' AS ''; |  | 
|  340   } |  | 
|  341 } {1 {database  is already in use}} |  | 
|  342 do_test attach3-12.13 { |  | 
|  343   db_list |  | 
|  344 } {main temp {}} |  | 
|  345 do_test attach3-12.14 { |  | 
|  346   execsql { |  | 
|  347     DETACH ''; |  | 
|  348   } |  | 
|  349   db_list |  | 
|  350 } {main temp} |  | 
|  351  |  | 
|  352 } ;# ifcapable pragma |  | 
|  353  |  | 
|  354 finish_test |  | 
| OLD | NEW |