1bdb339ffSdrh# 2009 February 2 2bdb339ffSdrh# 3bdb339ffSdrh# The author disclaims copyright to this source code. In place of 4bdb339ffSdrh# a legal notice, here is a blessing: 5bdb339ffSdrh# 6bdb339ffSdrh# May you do good and not evil. 7bdb339ffSdrh# May you find forgiveness for yourself and forgive others. 8bdb339ffSdrh# May you share freely, never taking more than you give. 9bdb339ffSdrh# 10bdb339ffSdrh#************************************************************************* 11bdb339ffSdrh# This file implements regression tests for SQLite library. The 12bdb339ffSdrh# focus of this script is testing that SQLite can handle a subtle 13bdb339ffSdrh# file format change that may be used in the future to implement 14bdb339ffSdrh# "ALTER TABLE ... ADD COLUMN". 15bdb339ffSdrh# 16bdb339ffSdrh# $Id: alter4.test,v 1.1 2009/02/02 18:03:22 drh Exp $ 17bdb339ffSdrh# 18bdb339ffSdrh 19bdb339ffSdrhset testdir [file dirname $argv0] 20bdb339ffSdrh 21bdb339ffSdrhsource $testdir/tester.tcl 22bdb339ffSdrh 23bdb339ffSdrh# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. 24bdb339ffSdrhifcapable !altertable { 25bdb339ffSdrh finish_test 26bdb339ffSdrh return 27bdb339ffSdrh} 28bdb339ffSdrh 29bdb339ffSdrh 30bdb339ffSdrh# Test Organisation: 31bdb339ffSdrh# ------------------ 32bdb339ffSdrh# 33bdb339ffSdrh# alter4-1.*: Test that ALTER TABLE correctly modifies the CREATE TABLE sql. 34bdb339ffSdrh# alter4-2.*: Test error messages. 35bdb339ffSdrh# alter4-3.*: Test adding columns with default value NULL. 36bdb339ffSdrh# alter4-4.*: Test adding columns with default values other than NULL. 37bdb339ffSdrh# alter4-5.*: Test adding columns to tables in ATTACHed databases. 38bdb339ffSdrh# alter4-6.*: Test that temp triggers are not accidentally dropped. 39bdb339ffSdrh# alter4-7.*: Test that VACUUM resets the file-format. 40bdb339ffSdrh# 41bdb339ffSdrh 42bdb339ffSdrhdo_test alter4-1.1 { 43bdb339ffSdrh execsql { 44bdb339ffSdrh CREATE TEMP TABLE abc(a, b, c); 45bdb339ffSdrh SELECT sql FROM sqlite_temp_master; 46bdb339ffSdrh } 47bdb339ffSdrh} {{CREATE TABLE abc(a, b, c)}} 48e0a04a36Sdrhdo_test alter4-1.1b { 49e0a04a36Sdrh execsql { 50e0a04a36Sdrh SELECT sql FROM temp.sqlite_master; 51e0a04a36Sdrh } 52e0a04a36Sdrh} {{CREATE TABLE abc(a, b, c)}} 53bdb339ffSdrhdo_test alter4-1.2 { 54bdb339ffSdrh execsql {ALTER TABLE abc ADD d INTEGER;} 55bdb339ffSdrh execsql { 56bdb339ffSdrh SELECT sql FROM sqlite_temp_master; 57bdb339ffSdrh } 58bdb339ffSdrh} {{CREATE TABLE abc(a, b, c, d INTEGER)}} 59e0a04a36Sdrhdo_test alter4-1.2b { 60e0a04a36Sdrh execsql { 61e0a04a36Sdrh SELECT sql FROM temp.sqlite_master; 62e0a04a36Sdrh } 63e0a04a36Sdrh} {{CREATE TABLE abc(a, b, c, d INTEGER)}} 64bdb339ffSdrhdo_test alter4-1.3 { 65bdb339ffSdrh execsql {ALTER TABLE abc ADD e} 66bdb339ffSdrh execsql { 67bdb339ffSdrh SELECT sql FROM sqlite_temp_master; 68bdb339ffSdrh } 69bdb339ffSdrh} {{CREATE TABLE abc(a, b, c, d INTEGER, e)}} 70e0a04a36Sdrhdo_test alter4-1.3b { 71e0a04a36Sdrh execsql { 72e0a04a36Sdrh SELECT sql FROM temp.sqlite_master; 73e0a04a36Sdrh } 74e0a04a36Sdrh} {{CREATE TABLE abc(a, b, c, d INTEGER, e)}} 75bdb339ffSdrhdo_test alter4-1.4 { 76bdb339ffSdrh execsql { 77bdb339ffSdrh CREATE TABLE temp.t1(a, b); 78bdb339ffSdrh ALTER TABLE t1 ADD c; 79bdb339ffSdrh SELECT sql FROM sqlite_temp_master WHERE tbl_name = 't1'; 80bdb339ffSdrh } 81bdb339ffSdrh} {{CREATE TABLE t1(a, b, c)}} 82e0a04a36Sdrhdo_test alter4-1.4b { 83e0a04a36Sdrh execsql { 84e0a04a36Sdrh SELECT sql FROM temp.sqlite_master WHERE tbl_name = 't1'; 85e0a04a36Sdrh } 86e0a04a36Sdrh} {{CREATE TABLE t1(a, b, c)}} 87bdb339ffSdrhdo_test alter4-1.5 { 88bdb339ffSdrh execsql { 89bdb339ffSdrh ALTER TABLE t1 ADD d CHECK (a>d); 90bdb339ffSdrh SELECT sql FROM sqlite_temp_master WHERE tbl_name = 't1'; 91bdb339ffSdrh } 92bdb339ffSdrh} {{CREATE TABLE t1(a, b, c, d CHECK (a>d))}} 93bdb339ffSdrhifcapable foreignkey { 94bdb339ffSdrh do_test alter4-1.6 { 95bdb339ffSdrh execsql { 96bdb339ffSdrh CREATE TEMP TABLE t2(a, b, UNIQUE(a, b)); 97bdb339ffSdrh ALTER TABLE t2 ADD c REFERENCES t1(c) ; 98bdb339ffSdrh SELECT sql FROM sqlite_temp_master 99bdb339ffSdrh WHERE tbl_name = 't2' AND type = 'table'; 100bdb339ffSdrh } 101bdb339ffSdrh } {{CREATE TABLE t2(a, b, c REFERENCES t1(c), UNIQUE(a, b))}} 102bdb339ffSdrh} 103bdb339ffSdrhdo_test alter4-1.7 { 104bdb339ffSdrh execsql { 105bdb339ffSdrh CREATE TEMPORARY TABLE t3(a, b, UNIQUE(a, b)); 106bdb339ffSdrh ALTER TABLE t3 ADD COLUMN c VARCHAR(10, 20); 107bdb339ffSdrh SELECT sql FROM sqlite_temp_master 108bdb339ffSdrh WHERE tbl_name = 't3' AND type = 'table'; 109bdb339ffSdrh } 110bdb339ffSdrh} {{CREATE TABLE t3(a, b, c VARCHAR(10, 20), UNIQUE(a, b))}} 111bdb339ffSdrhdo_test alter4-1.99 { 112bdb339ffSdrh catchsql { 113bdb339ffSdrh # May not exist if foriegn-keys are omitted at compile time. 114bdb339ffSdrh DROP TABLE t2; 115bdb339ffSdrh } 116bdb339ffSdrh execsql { 117bdb339ffSdrh DROP TABLE abc; 118bdb339ffSdrh DROP TABLE t1; 119bdb339ffSdrh DROP TABLE t3; 120bdb339ffSdrh } 121bdb339ffSdrh} {} 122bdb339ffSdrh 123bdb339ffSdrhdo_test alter4-2.1 { 124bdb339ffSdrh execsql { 125bdb339ffSdrh CREATE TABLE temp.t1(a, b); 1269e5fdc41Sdrh INSERT INTO t1 VALUES(1,2); 127bdb339ffSdrh } 128bdb339ffSdrh catchsql { 129bdb339ffSdrh ALTER TABLE t1 ADD c PRIMARY KEY; 130bdb339ffSdrh } 131bdb339ffSdrh} {1 {Cannot add a PRIMARY KEY column}} 132bdb339ffSdrhdo_test alter4-2.2 { 133bdb339ffSdrh catchsql { 134bdb339ffSdrh ALTER TABLE t1 ADD c UNIQUE 135bdb339ffSdrh } 136bdb339ffSdrh} {1 {Cannot add a UNIQUE column}} 137bdb339ffSdrhdo_test alter4-2.3 { 138bdb339ffSdrh catchsql { 139bdb339ffSdrh ALTER TABLE t1 ADD b VARCHAR(10) 140bdb339ffSdrh } 141bdb339ffSdrh} {1 {duplicate column name: b}} 142bdb339ffSdrhdo_test alter4-2.3 { 143bdb339ffSdrh catchsql { 144bdb339ffSdrh ALTER TABLE t1 ADD c NOT NULL; 145bdb339ffSdrh } 146bdb339ffSdrh} {1 {Cannot add a NOT NULL column with default value NULL}} 147bdb339ffSdrhdo_test alter4-2.4 { 148bdb339ffSdrh catchsql { 149bdb339ffSdrh ALTER TABLE t1 ADD c NOT NULL DEFAULT 10; 150bdb339ffSdrh } 151bdb339ffSdrh} {0 {}} 152bdb339ffSdrhifcapable view { 153bdb339ffSdrh do_test alter4-2.5 { 154bdb339ffSdrh execsql { 155bdb339ffSdrh CREATE TEMPORARY VIEW v1 AS SELECT * FROM t1; 156bdb339ffSdrh } 157bdb339ffSdrh catchsql { 158bdb339ffSdrh alter table v1 add column d; 159bdb339ffSdrh } 160bdb339ffSdrh } {1 {Cannot add a column to a view}} 161bdb339ffSdrh} 162bdb339ffSdrhdo_test alter4-2.6 { 163bdb339ffSdrh catchsql { 164bdb339ffSdrh alter table t1 add column d DEFAULT CURRENT_TIME; 165bdb339ffSdrh } 166bdb339ffSdrh} {1 {Cannot add a column with non-constant default}} 167ad45ed74Sdando_test alter4-2.7 { 168ad45ed74Sdan catchsql { 1694169e430Sdrh alter table t1 add column d default (-5+1); 170ad45ed74Sdan } 171ad45ed74Sdan} {1 {Cannot add a column with non-constant default}} 172bdb339ffSdrhdo_test alter4-2.99 { 173bdb339ffSdrh execsql { 174bdb339ffSdrh DROP TABLE t1; 175bdb339ffSdrh } 176bdb339ffSdrh} {} 177bdb339ffSdrh 178bdb339ffSdrhdo_test alter4-3.1 { 179bdb339ffSdrh execsql { 180bdb339ffSdrh CREATE TEMP TABLE t1(a, b); 181bdb339ffSdrh INSERT INTO t1 VALUES(1, 100); 182bdb339ffSdrh INSERT INTO t1 VALUES(2, 300); 183bdb339ffSdrh SELECT * FROM t1; 184bdb339ffSdrh } 185bdb339ffSdrh} {1 100 2 300} 186bdb339ffSdrhdo_test alter4-3.1 { 187bdb339ffSdrh execsql { 188bdb339ffSdrh PRAGMA schema_version = 10; 189bdb339ffSdrh } 190bdb339ffSdrh} {} 191bdb339ffSdrhdo_test alter4-3.2 { 192bdb339ffSdrh execsql { 193bdb339ffSdrh ALTER TABLE t1 ADD c; 194bdb339ffSdrh SELECT * FROM t1; 195bdb339ffSdrh } 196bdb339ffSdrh} {1 100 {} 2 300 {}} 197bdb339ffSdrhifcapable schema_version { 198bdb339ffSdrh do_test alter4-3.4 { 199bdb339ffSdrh execsql { 200bdb339ffSdrh PRAGMA schema_version; 201bdb339ffSdrh } 202bdb339ffSdrh } {10} 203bdb339ffSdrh} 204bdb339ffSdrh 205bdb339ffSdrhdo_test alter4-4.1 { 206bdb339ffSdrh db close 207fda06befSmistachkin forcedelete test.db 208bdb339ffSdrh set ::DB [sqlite3 db test.db] 209bdb339ffSdrh execsql { 210bdb339ffSdrh CREATE TEMP TABLE t1(a, b); 211bdb339ffSdrh INSERT INTO t1 VALUES(1, 100); 212bdb339ffSdrh INSERT INTO t1 VALUES(2, 300); 213bdb339ffSdrh SELECT * FROM t1; 214bdb339ffSdrh } 215bdb339ffSdrh} {1 100 2 300} 216bdb339ffSdrhdo_test alter4-4.1 { 217bdb339ffSdrh execsql { 218bdb339ffSdrh PRAGMA schema_version = 20; 219bdb339ffSdrh } 220bdb339ffSdrh} {} 221bdb339ffSdrhdo_test alter4-4.2 { 222bdb339ffSdrh execsql { 223bdb339ffSdrh ALTER TABLE t1 ADD c DEFAULT 'hello world'; 224bdb339ffSdrh SELECT * FROM t1; 225bdb339ffSdrh } 226bdb339ffSdrh} {1 100 {hello world} 2 300 {hello world}} 227bdb339ffSdrhifcapable schema_version { 228bdb339ffSdrh do_test alter4-4.4 { 229bdb339ffSdrh execsql { 230bdb339ffSdrh PRAGMA schema_version; 231bdb339ffSdrh } 232bdb339ffSdrh } {20} 233bdb339ffSdrh} 234bdb339ffSdrhdo_test alter4-4.99 { 235bdb339ffSdrh execsql { 236bdb339ffSdrh DROP TABLE t1; 237bdb339ffSdrh } 238bdb339ffSdrh} {} 239bdb339ffSdrh 240bdb339ffSdrhifcapable attach { 241bdb339ffSdrh do_test alter4-5.1 { 242fda06befSmistachkin forcedelete test2.db 243fda06befSmistachkin forcedelete test2.db-journal 244bdb339ffSdrh execsql { 245bdb339ffSdrh CREATE TEMP TABLE t1(a, b); 246bdb339ffSdrh INSERT INTO t1 VALUES(1, 'one'); 247bdb339ffSdrh INSERT INTO t1 VALUES(2, 'two'); 248bdb339ffSdrh ATTACH 'test2.db' AS aux; 249bdb339ffSdrh CREATE TABLE aux.t1 AS SELECT * FROM t1; 250bdb339ffSdrh PRAGMA aux.schema_version = 30; 251bdb339ffSdrh SELECT sql FROM aux.sqlite_master; 252bdb339ffSdrh } 253bdb339ffSdrh } {{CREATE TABLE t1(a,b)}} 254bdb339ffSdrh do_test alter4-5.2 { 255bdb339ffSdrh execsql { 256bdb339ffSdrh ALTER TABLE aux.t1 ADD COLUMN c VARCHAR(128); 257bdb339ffSdrh SELECT sql FROM aux.sqlite_master; 258bdb339ffSdrh } 259bdb339ffSdrh } {{CREATE TABLE t1(a,b, c VARCHAR(128))}} 260bdb339ffSdrh do_test alter4-5.3 { 261bdb339ffSdrh execsql { 262bdb339ffSdrh SELECT * FROM aux.t1; 263bdb339ffSdrh } 264bdb339ffSdrh } {1 one {} 2 two {}} 265bdb339ffSdrh ifcapable schema_version { 266bdb339ffSdrh do_test alter4-5.4 { 267bdb339ffSdrh execsql { 268bdb339ffSdrh PRAGMA aux.schema_version; 269bdb339ffSdrh } 270bdb339ffSdrh } {31} 271bdb339ffSdrh } 272bdb339ffSdrh do_test alter4-5.6 { 273bdb339ffSdrh execsql { 274bdb339ffSdrh ALTER TABLE aux.t1 ADD COLUMN d DEFAULT 1000; 275bdb339ffSdrh SELECT sql FROM aux.sqlite_master; 276bdb339ffSdrh } 277bdb339ffSdrh } {{CREATE TABLE t1(a,b, c VARCHAR(128), d DEFAULT 1000)}} 278bdb339ffSdrh do_test alter4-5.7 { 279bdb339ffSdrh execsql { 280bdb339ffSdrh SELECT * FROM aux.t1; 281bdb339ffSdrh } 282bdb339ffSdrh } {1 one {} 1000 2 two {} 1000} 283bdb339ffSdrh ifcapable schema_version { 284bdb339ffSdrh do_test alter4-5.8 { 285bdb339ffSdrh execsql { 286bdb339ffSdrh PRAGMA aux.schema_version; 287bdb339ffSdrh } 288bdb339ffSdrh } {32} 289bdb339ffSdrh } 290bdb339ffSdrh do_test alter4-5.9 { 291bdb339ffSdrh execsql { 292bdb339ffSdrh SELECT * FROM t1; 293bdb339ffSdrh } 294bdb339ffSdrh } {1 one 2 two} 295bdb339ffSdrh do_test alter4-5.99 { 296bdb339ffSdrh execsql { 297bdb339ffSdrh DROP TABLE aux.t1; 298bdb339ffSdrh DROP TABLE t1; 299bdb339ffSdrh } 300bdb339ffSdrh } {} 301bdb339ffSdrh} 302bdb339ffSdrh 303bdb339ffSdrh#---------------------------------------------------------------- 304bdb339ffSdrh# Test that the table schema is correctly reloaded when a column 305bdb339ffSdrh# is added to a table. 306bdb339ffSdrh# 307bdb339ffSdrhifcapable trigger&&tempdb { 308bdb339ffSdrh do_test alter4-6.1 { 309bdb339ffSdrh execsql { 310bdb339ffSdrh CREATE TEMP TABLE t1(a, b); 311bdb339ffSdrh CREATE TEMP TABLE log(trig, a, b); 312bdb339ffSdrh 313bdb339ffSdrh CREATE TRIGGER t1_a AFTER INSERT ON t1 BEGIN 314bdb339ffSdrh INSERT INTO log VALUES('a', new.a, new.b); 315bdb339ffSdrh END; 316bdb339ffSdrh CREATE TEMP TRIGGER t1_b AFTER INSERT ON t1 BEGIN 317bdb339ffSdrh INSERT INTO log VALUES('b', new.a, new.b); 318bdb339ffSdrh END; 319bdb339ffSdrh 320bdb339ffSdrh INSERT INTO t1 VALUES(1, 2); 321*a4767683Sdrh SELECT * FROM log ORDER BY trig, a, b; 322bdb339ffSdrh } 323*a4767683Sdrh } {a 1 2 b 1 2} 324bdb339ffSdrh do_test alter4-6.2 { 325bdb339ffSdrh execsql { 326bdb339ffSdrh ALTER TABLE t1 ADD COLUMN c DEFAULT 'c'; 327bdb339ffSdrh INSERT INTO t1(a, b) VALUES(3, 4); 328*a4767683Sdrh SELECT * FROM log ORDER BY trig, a, b; 329bdb339ffSdrh } 330*a4767683Sdrh } {a 1 2 a 3 4 b 1 2 b 3 4} 331bdb339ffSdrh} 332bdb339ffSdrh 333bdb339ffSdrh# Ticket #1183 - Make sure adding columns to large tables does not cause 334bdb339ffSdrh# memory corruption (as was the case before this bug was fixed). 335bdb339ffSdrhdo_test alter4-8.1 { 336bdb339ffSdrh execsql { 337bdb339ffSdrh CREATE TEMP TABLE t4(c1); 338bdb339ffSdrh } 339bdb339ffSdrh} {} 340bdb339ffSdrhset ::sql "" 341bdb339ffSdrhdo_test alter4-8.2 { 342bdb339ffSdrh set cols c1 343bdb339ffSdrh for {set i 2} {$i < 100} {incr i} { 344bdb339ffSdrh execsql " 345bdb339ffSdrh ALTER TABLE t4 ADD c$i 346bdb339ffSdrh " 347bdb339ffSdrh lappend cols c$i 348bdb339ffSdrh } 349bdb339ffSdrh set ::sql "CREATE TABLE t4([join $cols {, }])" 350bdb339ffSdrh list 351bdb339ffSdrh} {} 352bdb339ffSdrhdo_test alter4-8.2 { 353bdb339ffSdrh execsql { 354bdb339ffSdrh SELECT sql FROM sqlite_temp_master WHERE name = 't4'; 355bdb339ffSdrh } 356bdb339ffSdrh} [list $::sql] 357bdb339ffSdrh 358052c6784Sdan 359052c6784Sdan# Test that a default value equal to -1 multipied by the smallest possible 360052c6784Sdan# 64-bit integer is correctly converted to a real. 361052c6784Sdando_execsql_test alter4-9.1 { 362052c6784Sdan CREATE TABLE t5( 363052c6784Sdan a INTEGER DEFAULT -9223372036854775808, 364052c6784Sdan b INTEGER DEFAULT (-(-9223372036854775808)) 365052c6784Sdan ); 366052c6784Sdan INSERT INTO t5 DEFAULT VALUES; 367052c6784Sdan} 368052c6784Sdan 369052c6784Sdando_execsql_test alter4-9.2 { SELECT typeof(a), a, typeof(b), b FROM t5; } { 370052c6784Sdan integer -9223372036854775808 371052c6784Sdan real 9.22337203685478e+18 372052c6784Sdan} 373052c6784Sdan 374052c6784Sdando_execsql_test alter4-9.3 { 375052c6784Sdan ALTER TABLE t5 ADD COLUMN c INTEGER DEFAULT (-(-9223372036854775808)); 376052c6784Sdan SELECT typeof(c), c FROM t5; 377052c6784Sdan} {real 9.22337203685478e+18} 378052c6784Sdan 37986396219Sdrh# Confirm that doing an ALTER TABLE on a legacy format database 38086396219Sdrh# does not corrupt DESC indexes. 38186396219Sdrh# 38286396219Sdrh# Ticket https://www.sqlite.org/src/tktview/f68bf68513a1c 38386396219Sdrh# 38486396219Sdrhdo_test alter4-10.1 { 38586396219Sdrh db close 38686396219Sdrh sqlite3 db :memory: 38766c48907Sdrh sqlite3_db_config db LEGACY_FILE_FORMAT 1 38886396219Sdrh db eval { 38986396219Sdrh CREATE TABLE t1(a,b,c); 39086396219Sdrh CREATE INDEX t1a ON t1(a DESC); 39186396219Sdrh INSERT INTO t1 VALUES(1,2,3); 39286396219Sdrh INSERT INTO t1 VALUES(2,3,4); 39386396219Sdrh ALTER TABLE t1 ADD COLUMN d; 39486396219Sdrh PRAGMA integrity_check; 39586396219Sdrh } 39686396219Sdrh} {ok} 39786396219Sdrh 398b87a9a8aSdanreset_db 399b87a9a8aSdando_execsql_test alter4-11.0 { 400b87a9a8aSdan CREATE TABLE t1(c INTEGER PRIMARY KEY, d); 4019e5fdc41Sdrh INSERT INTO t1(c,d) VALUES(1,2); 402b87a9a8aSdan PRAGMA foreign_keys = on; 403b87a9a8aSdan ALTER TABLE t1 ADD COLUMN e; 404b87a9a8aSdan} 405b87a9a8aSdan 406b87a9a8aSdando_execsql_test alter4-11.1 { 407b87a9a8aSdan ALTER TABLE t1 ADD COLUMN f REFERENCES t1; 408b87a9a8aSdan} 409b87a9a8aSdan 410b87a9a8aSdando_catchsql_test alter4-11.2 { 411b87a9a8aSdan ALTER TABLE t1 ADD COLUMN g REFERENCES t1 DEFAULT 4; 412b87a9a8aSdan} {1 {Cannot add a REFERENCES column with non-NULL default value}} 413b87a9a8aSdan 414b87a9a8aSdando_catchsql_test alter4-11.3 { 415b87a9a8aSdan ALTER TABLE t2 ADD COLUMN g; 416b87a9a8aSdan} {1 {no such table: t2}} 417b87a9a8aSdan 418b87a9a8aSdanifcapable fts5 { 419b87a9a8aSdan do_execsql_test alter4-11.4 { 420b87a9a8aSdan CREATE VIRTUAL TABLE fff USING fts5(f); 421b87a9a8aSdan } 422b87a9a8aSdan do_catchsql_test alter4-11.2 { 423b87a9a8aSdan ALTER TABLE fff ADD COLUMN g; 424b87a9a8aSdan } {1 {virtual tables may not be altered}} 425b87a9a8aSdan} 426b87a9a8aSdan 427bdb339ffSdrhfinish_test 428