| OLD | NEW | 
 | (Empty) | 
|    1 # 2005 February 19 |  | 
|    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 that SQLite can handle a subtle  |  | 
|   13 # file format change that may be used in the future to implement |  | 
|   14 # "ALTER TABLE ... ADD COLUMN". |  | 
|   15 # |  | 
|   16 # $Id: alter3.test,v 1.11 2008/03/19 00:21:31 drh Exp $ |  | 
|   17 # |  | 
|   18  |  | 
|   19 set testdir [file dirname $argv0] |  | 
|   20  |  | 
|   21 source $testdir/tester.tcl |  | 
|   22  |  | 
|   23 # If SQLITE_OMIT_ALTERTABLE is defined, omit this file. |  | 
|   24 ifcapable !altertable { |  | 
|   25   finish_test |  | 
|   26   return |  | 
|   27 } |  | 
|   28  |  | 
|   29 # Determine if there is a codec available on this test. |  | 
|   30 # |  | 
|   31 if {[catch {sqlite3 -has_codec} r] || $r} { |  | 
|   32   set has_codec 1 |  | 
|   33 } else { |  | 
|   34   set has_codec 0 |  | 
|   35 } |  | 
|   36  |  | 
|   37  |  | 
|   38 # Test Organisation: |  | 
|   39 # ------------------ |  | 
|   40 # |  | 
|   41 # alter3-1.*: Test that ALTER TABLE correctly modifies the CREATE TABLE sql. |  | 
|   42 # alter3-2.*: Test error messages. |  | 
|   43 # alter3-3.*: Test adding columns with default value NULL. |  | 
|   44 # alter3-4.*: Test adding columns with default values other than NULL. |  | 
|   45 # alter3-5.*: Test adding columns to tables in ATTACHed databases. |  | 
|   46 # alter3-6.*: Test that temp triggers are not accidentally dropped. |  | 
|   47 # alter3-7.*: Test that VACUUM resets the file-format. |  | 
|   48 # |  | 
|   49  |  | 
|   50 # This procedure returns the value of the file-format in file 'test.db'. |  | 
|   51 #  |  | 
|   52 proc get_file_format {{fname test.db}} { |  | 
|   53   return [hexio_get_int [hexio_read $fname 44 4]] |  | 
|   54 } |  | 
|   55  |  | 
|   56 do_test alter3-1.1 { |  | 
|   57   execsql { |  | 
|   58     CREATE TABLE abc(a, b, c); |  | 
|   59     SELECT sql FROM sqlite_master; |  | 
|   60   } |  | 
|   61 } {{CREATE TABLE abc(a, b, c)}} |  | 
|   62 do_test alter3-1.2 { |  | 
|   63   execsql {ALTER TABLE abc ADD d INTEGER;} |  | 
|   64   execsql { |  | 
|   65     SELECT sql FROM sqlite_master; |  | 
|   66   } |  | 
|   67 } {{CREATE TABLE abc(a, b, c, d INTEGER)}} |  | 
|   68 do_test alter3-1.3 { |  | 
|   69   execsql {ALTER TABLE abc ADD e} |  | 
|   70   execsql { |  | 
|   71     SELECT sql FROM sqlite_master; |  | 
|   72   } |  | 
|   73 } {{CREATE TABLE abc(a, b, c, d INTEGER, e)}} |  | 
|   74 do_test alter3-1.4 { |  | 
|   75   execsql { |  | 
|   76     CREATE TABLE main.t1(a, b); |  | 
|   77     ALTER TABLE t1 ADD c; |  | 
|   78     SELECT sql FROM sqlite_master WHERE tbl_name = 't1'; |  | 
|   79   } |  | 
|   80 } {{CREATE TABLE t1(a, b, c)}} |  | 
|   81 do_test alter3-1.5 { |  | 
|   82   execsql { |  | 
|   83     ALTER TABLE t1 ADD d CHECK (a>d); |  | 
|   84     SELECT sql FROM sqlite_master WHERE tbl_name = 't1'; |  | 
|   85   } |  | 
|   86 } {{CREATE TABLE t1(a, b, c, d CHECK (a>d))}} |  | 
|   87 ifcapable foreignkey { |  | 
|   88   do_test alter3-1.6 { |  | 
|   89     execsql { |  | 
|   90       CREATE TABLE t2(a, b, UNIQUE(a, b)); |  | 
|   91       ALTER TABLE t2 ADD c REFERENCES t1(c)  ; |  | 
|   92       SELECT sql FROM sqlite_master WHERE tbl_name = 't2' AND type = 'table'; |  | 
|   93     } |  | 
|   94   } {{CREATE TABLE t2(a, b, c REFERENCES t1(c), UNIQUE(a, b))}} |  | 
|   95 } |  | 
|   96 do_test alter3-1.7 { |  | 
|   97   execsql { |  | 
|   98     CREATE TABLE t3(a, b, UNIQUE(a, b)); |  | 
|   99     ALTER TABLE t3 ADD COLUMN c VARCHAR(10, 20); |  | 
|  100     SELECT sql FROM sqlite_master WHERE tbl_name = 't3' AND type = 'table'; |  | 
|  101   } |  | 
|  102 } {{CREATE TABLE t3(a, b, c VARCHAR(10, 20), UNIQUE(a, b))}} |  | 
|  103 do_test alter3-1.99 { |  | 
|  104   catchsql { |  | 
|  105     # May not exist if foriegn-keys are omitted at compile time. |  | 
|  106     DROP TABLE t2;  |  | 
|  107   } |  | 
|  108   execsql { |  | 
|  109     DROP TABLE abc;  |  | 
|  110     DROP TABLE t1;  |  | 
|  111     DROP TABLE t3;  |  | 
|  112   } |  | 
|  113 } {} |  | 
|  114  |  | 
|  115 do_test alter3-2.1 { |  | 
|  116   execsql { |  | 
|  117     CREATE TABLE t1(a, b); |  | 
|  118   } |  | 
|  119   catchsql { |  | 
|  120     ALTER TABLE t1 ADD c PRIMARY KEY; |  | 
|  121   } |  | 
|  122 } {1 {Cannot add a PRIMARY KEY column}} |  | 
|  123 do_test alter3-2.2 { |  | 
|  124   catchsql { |  | 
|  125     ALTER TABLE t1 ADD c UNIQUE |  | 
|  126   } |  | 
|  127 } {1 {Cannot add a UNIQUE column}} |  | 
|  128 do_test alter3-2.3 { |  | 
|  129   catchsql { |  | 
|  130     ALTER TABLE t1 ADD b VARCHAR(10) |  | 
|  131   } |  | 
|  132 } {1 {duplicate column name: b}} |  | 
|  133 do_test alter3-2.3 { |  | 
|  134   catchsql { |  | 
|  135     ALTER TABLE t1 ADD c NOT NULL; |  | 
|  136   } |  | 
|  137 } {1 {Cannot add a NOT NULL column with default value NULL}} |  | 
|  138 do_test alter3-2.4 { |  | 
|  139   catchsql { |  | 
|  140     ALTER TABLE t1 ADD c NOT NULL DEFAULT 10; |  | 
|  141   } |  | 
|  142 } {0 {}} |  | 
|  143 ifcapable view { |  | 
|  144   do_test alter3-2.5 { |  | 
|  145     execsql { |  | 
|  146       CREATE VIEW v1 AS SELECT * FROM t1; |  | 
|  147     } |  | 
|  148     catchsql { |  | 
|  149       alter table v1 add column d; |  | 
|  150     } |  | 
|  151   } {1 {Cannot add a column to a view}} |  | 
|  152 } |  | 
|  153 do_test alter3-2.6 { |  | 
|  154   catchsql { |  | 
|  155     alter table t1 add column d DEFAULT CURRENT_TIME; |  | 
|  156   } |  | 
|  157 } {1 {Cannot add a column with non-constant default}} |  | 
|  158 do_test alter3-2.99 { |  | 
|  159   execsql { |  | 
|  160     DROP TABLE t1; |  | 
|  161   } |  | 
|  162 } {} |  | 
|  163  |  | 
|  164 do_test alter3-3.1 { |  | 
|  165   execsql { |  | 
|  166     CREATE TABLE t1(a, b); |  | 
|  167     INSERT INTO t1 VALUES(1, 100); |  | 
|  168     INSERT INTO t1 VALUES(2, 300); |  | 
|  169     SELECT * FROM t1; |  | 
|  170   } |  | 
|  171 } {1 100 2 300} |  | 
|  172 do_test alter3-3.1 { |  | 
|  173   execsql { |  | 
|  174     PRAGMA schema_version = 10; |  | 
|  175   } |  | 
|  176 } {} |  | 
|  177 do_test alter3-3.2 { |  | 
|  178   execsql { |  | 
|  179     ALTER TABLE t1 ADD c; |  | 
|  180     SELECT * FROM t1; |  | 
|  181   } |  | 
|  182 } {1 100 {} 2 300 {}} |  | 
|  183 if {!$has_codec} { |  | 
|  184   do_test alter3-3.3 { |  | 
|  185     get_file_format |  | 
|  186   } {3} |  | 
|  187 } |  | 
|  188 ifcapable schema_version { |  | 
|  189   do_test alter3-3.4 { |  | 
|  190     execsql { |  | 
|  191       PRAGMA schema_version; |  | 
|  192     } |  | 
|  193   } {11} |  | 
|  194 } |  | 
|  195  |  | 
|  196 do_test alter3-4.1 { |  | 
|  197   db close |  | 
|  198   file delete -force test.db |  | 
|  199   set ::DB [sqlite3 db test.db] |  | 
|  200   execsql { |  | 
|  201     CREATE TABLE t1(a, b); |  | 
|  202     INSERT INTO t1 VALUES(1, 100); |  | 
|  203     INSERT INTO t1 VALUES(2, 300); |  | 
|  204     SELECT * FROM t1; |  | 
|  205   } |  | 
|  206 } {1 100 2 300} |  | 
|  207 do_test alter3-4.1 { |  | 
|  208   execsql { |  | 
|  209     PRAGMA schema_version = 20; |  | 
|  210   } |  | 
|  211 } {} |  | 
|  212 do_test alter3-4.2 { |  | 
|  213   execsql { |  | 
|  214     ALTER TABLE t1 ADD c DEFAULT 'hello world'; |  | 
|  215     SELECT * FROM t1; |  | 
|  216   } |  | 
|  217 } {1 100 {hello world} 2 300 {hello world}} |  | 
|  218 if {!$has_codec} { |  | 
|  219   do_test alter3-4.3 { |  | 
|  220     get_file_format |  | 
|  221   } {3} |  | 
|  222 } |  | 
|  223 ifcapable schema_version { |  | 
|  224   do_test alter3-4.4 { |  | 
|  225     execsql { |  | 
|  226       PRAGMA schema_version; |  | 
|  227     } |  | 
|  228   } {21} |  | 
|  229 } |  | 
|  230 do_test alter3-4.99 { |  | 
|  231   execsql { |  | 
|  232     DROP TABLE t1; |  | 
|  233   } |  | 
|  234 } {} |  | 
|  235  |  | 
|  236 ifcapable attach { |  | 
|  237   do_test alter3-5.1 { |  | 
|  238     file delete -force test2.db |  | 
|  239     file delete -force test2.db-journal |  | 
|  240     execsql { |  | 
|  241       CREATE TABLE t1(a, b); |  | 
|  242       INSERT INTO t1 VALUES(1, 'one'); |  | 
|  243       INSERT INTO t1 VALUES(2, 'two'); |  | 
|  244       ATTACH 'test2.db' AS aux; |  | 
|  245       CREATE TABLE aux.t1 AS SELECT * FROM t1; |  | 
|  246       PRAGMA aux.schema_version = 30; |  | 
|  247       SELECT sql FROM aux.sqlite_master; |  | 
|  248     }  |  | 
|  249   } {{CREATE TABLE t1(a,b)}} |  | 
|  250   do_test alter3-5.2 { |  | 
|  251     execsql { |  | 
|  252       ALTER TABLE aux.t1 ADD COLUMN c VARCHAR(128); |  | 
|  253       SELECT sql FROM aux.sqlite_master; |  | 
|  254     } |  | 
|  255   } {{CREATE TABLE t1(a,b, c VARCHAR(128))}} |  | 
|  256   do_test alter3-5.3 { |  | 
|  257     execsql { |  | 
|  258       SELECT * FROM aux.t1; |  | 
|  259     } |  | 
|  260   } {1 one {} 2 two {}} |  | 
|  261   ifcapable schema_version { |  | 
|  262     do_test alter3-5.4 { |  | 
|  263       execsql { |  | 
|  264         PRAGMA aux.schema_version; |  | 
|  265       } |  | 
|  266     } {31} |  | 
|  267   } |  | 
|  268   if {!$has_codec} { |  | 
|  269     do_test alter3-5.5 { |  | 
|  270       list [get_file_format test2.db] [get_file_format] |  | 
|  271     } {2 3} |  | 
|  272   } |  | 
|  273   do_test alter3-5.6 { |  | 
|  274     execsql { |  | 
|  275       ALTER TABLE aux.t1 ADD COLUMN d DEFAULT 1000; |  | 
|  276       SELECT sql FROM aux.sqlite_master; |  | 
|  277     } |  | 
|  278   } {{CREATE TABLE t1(a,b, c VARCHAR(128), d DEFAULT 1000)}} |  | 
|  279   do_test alter3-5.7 { |  | 
|  280     execsql { |  | 
|  281       SELECT * FROM aux.t1; |  | 
|  282     } |  | 
|  283   } {1 one {} 1000 2 two {} 1000} |  | 
|  284   ifcapable schema_version { |  | 
|  285     do_test alter3-5.8 { |  | 
|  286       execsql { |  | 
|  287         PRAGMA aux.schema_version; |  | 
|  288       } |  | 
|  289     } {32} |  | 
|  290   } |  | 
|  291   do_test alter3-5.9 { |  | 
|  292     execsql { |  | 
|  293       SELECT * FROM t1; |  | 
|  294     } |  | 
|  295   } {1 one 2 two} |  | 
|  296   do_test alter3-5.99 { |  | 
|  297     execsql { |  | 
|  298       DROP TABLE aux.t1; |  | 
|  299       DROP TABLE t1; |  | 
|  300     } |  | 
|  301   } {} |  | 
|  302 } |  | 
|  303  |  | 
|  304 #---------------------------------------------------------------- |  | 
|  305 # Test that the table schema is correctly reloaded when a column |  | 
|  306 # is added to a table. |  | 
|  307 # |  | 
|  308 ifcapable trigger&&tempdb { |  | 
|  309   do_test alter3-6.1 { |  | 
|  310     execsql { |  | 
|  311       CREATE TABLE t1(a, b); |  | 
|  312       CREATE TABLE log(trig, a, b); |  | 
|  313  |  | 
|  314       CREATE TRIGGER t1_a AFTER INSERT ON t1 BEGIN |  | 
|  315         INSERT INTO log VALUES('a', new.a, new.b); |  | 
|  316       END; |  | 
|  317       CREATE TEMP TRIGGER t1_b AFTER INSERT ON t1 BEGIN |  | 
|  318         INSERT INTO log VALUES('b', new.a, new.b); |  | 
|  319       END; |  | 
|  320    |  | 
|  321       INSERT INTO t1 VALUES(1, 2); |  | 
|  322       SELECT * FROM log; |  | 
|  323     } |  | 
|  324   } {b 1 2 a 1 2} |  | 
|  325   do_test alter3-6.2 { |  | 
|  326     execsql { |  | 
|  327       ALTER TABLE t1 ADD COLUMN c DEFAULT 'c'; |  | 
|  328       INSERT INTO t1(a, b) VALUES(3, 4); |  | 
|  329       SELECT * FROM log; |  | 
|  330     } |  | 
|  331   } {b 1 2 a 1 2 b 3 4 a 3 4} |  | 
|  332 } |  | 
|  333  |  | 
|  334 if {!$has_codec} { |  | 
|  335   ifcapable vacuum { |  | 
|  336     do_test alter3-7.1 { |  | 
|  337       execsql { |  | 
|  338         VACUUM; |  | 
|  339       } |  | 
|  340       get_file_format |  | 
|  341     } {1} |  | 
|  342     do_test alter3-7.2 { |  | 
|  343       execsql { |  | 
|  344         CREATE TABLE abc(a, b, c); |  | 
|  345         ALTER TABLE abc ADD d DEFAULT NULL; |  | 
|  346       } |  | 
|  347       get_file_format |  | 
|  348     } {2} |  | 
|  349     do_test alter3-7.3 { |  | 
|  350       execsql { |  | 
|  351         ALTER TABLE abc ADD e DEFAULT 10; |  | 
|  352       } |  | 
|  353       get_file_format |  | 
|  354     } {3} |  | 
|  355     do_test alter3-7.4 { |  | 
|  356       execsql { |  | 
|  357         ALTER TABLE abc ADD f DEFAULT NULL; |  | 
|  358       } |  | 
|  359       get_file_format |  | 
|  360     } {3} |  | 
|  361     do_test alter3-7.5 { |  | 
|  362       execsql { |  | 
|  363         VACUUM; |  | 
|  364       } |  | 
|  365       get_file_format |  | 
|  366     } {1} |  | 
|  367   } |  | 
|  368 } |  | 
|  369  |  | 
|  370 # Ticket #1183 - Make sure adding columns to large tables does not cause |  | 
|  371 # memory corruption (as was the case before this bug was fixed). |  | 
|  372 do_test alter3-8.1 { |  | 
|  373   execsql { |  | 
|  374     CREATE TABLE t4(c1); |  | 
|  375   } |  | 
|  376 } {} |  | 
|  377 set ::sql "" |  | 
|  378 do_test alter3-8.2 { |  | 
|  379   set cols c1 |  | 
|  380   for {set i 2} {$i < 100} {incr i} { |  | 
|  381     execsql " |  | 
|  382       ALTER TABLE t4 ADD c$i |  | 
|  383     " |  | 
|  384     lappend cols c$i |  | 
|  385   } |  | 
|  386   set ::sql "CREATE TABLE t4([join $cols {, }])" |  | 
|  387   list  |  | 
|  388 } {} |  | 
|  389 do_test alter3-8.2 { |  | 
|  390   execsql { |  | 
|  391     SELECT sql FROM sqlite_master WHERE name = 't4'; |  | 
|  392   } |  | 
|  393 } [list $::sql] |  | 
|  394  |  | 
|  395 finish_test |  | 
| OLD | NEW |