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