| OLD | NEW |
| (Empty) |
| 1 # 2004 November 10 | |
| 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 ALTER TABLE statement. | |
| 13 # | |
| 14 # $Id: alter.test,v 1.32 2009/03/24 15:08:10 drh Exp $ | |
| 15 # | |
| 16 | |
| 17 set testdir [file dirname $argv0] | |
| 18 source $testdir/tester.tcl | |
| 19 | |
| 20 # If SQLITE_OMIT_ALTERTABLE is defined, omit this file. | |
| 21 ifcapable !altertable { | |
| 22 finish_test | |
| 23 return | |
| 24 } | |
| 25 | |
| 26 #---------------------------------------------------------------------- | |
| 27 # Test organization: | |
| 28 # | |
| 29 # alter-1.1.* - alter-1.7.*: Basic tests of ALTER TABLE, including tables | |
| 30 # with implicit and explicit indices. These tests came from an earlier | |
| 31 # fork of SQLite that also supported ALTER TABLE. | |
| 32 # alter-1.8.*: Tests for ALTER TABLE when the table resides in an | |
| 33 # attached database. | |
| 34 # alter-1.9.*: Tests for ALTER TABLE when their is whitespace between the | |
| 35 # table name and left parenthesis token. i.e: | |
| 36 # "CREATE TABLE abc (a, b, c);" | |
| 37 # alter-2.*: Test error conditions and messages. | |
| 38 # alter-3.*: Test ALTER TABLE on tables that have TRIGGERs attached to them. | |
| 39 # alter-4.*: Test ALTER TABLE on tables that have AUTOINCREMENT fields. | |
| 40 # ... | |
| 41 # alter-12.*: Test ALTER TABLE on views. | |
| 42 # | |
| 43 | |
| 44 # Create some tables to rename. Be sure to include some TEMP tables | |
| 45 # and some tables with odd names. | |
| 46 # | |
| 47 do_test alter-1.1 { | |
| 48 ifcapable tempdb { | |
| 49 set ::temp TEMP | |
| 50 } else { | |
| 51 set ::temp {} | |
| 52 } | |
| 53 execsql [subst -nocommands { | |
| 54 CREATE TABLE t1(a,b); | |
| 55 INSERT INTO t1 VALUES(1,2); | |
| 56 CREATE TABLE [t1'x1](c UNIQUE, b PRIMARY KEY); | |
| 57 INSERT INTO [t1'x1] VALUES(3,4); | |
| 58 CREATE INDEX t1i1 ON T1(B); | |
| 59 CREATE INDEX t1i2 ON t1(a,b); | |
| 60 CREATE INDEX i3 ON [t1'x1](b,c); | |
| 61 CREATE $::temp TABLE "temp table"(e,f,g UNIQUE); | |
| 62 CREATE INDEX i2 ON [temp table](f); | |
| 63 INSERT INTO [temp table] VALUES(5,6,7); | |
| 64 }] | |
| 65 execsql { | |
| 66 SELECT 't1', * FROM t1; | |
| 67 SELECT 't1''x1', * FROM "t1'x1"; | |
| 68 SELECT * FROM [temp table]; | |
| 69 } | |
| 70 } {t1 1 2 t1'x1 3 4 5 6 7} | |
| 71 do_test alter-1.2 { | |
| 72 execsql [subst { | |
| 73 CREATE $::temp TABLE objlist(type, name, tbl_name); | |
| 74 INSERT INTO objlist SELECT type, name, tbl_name | |
| 75 FROM sqlite_master WHERE NAME!='objlist'; | |
| 76 }] | |
| 77 ifcapable tempdb { | |
| 78 execsql { | |
| 79 INSERT INTO objlist SELECT type, name, tbl_name | |
| 80 FROM sqlite_temp_master WHERE NAME!='objlist'; | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 execsql { | |
| 85 SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name; | |
| 86 } | |
| 87 } [list \ | |
| 88 table t1 t1 \ | |
| 89 index t1i1 t1 \ | |
| 90 index t1i2 t1 \ | |
| 91 table t1'x1 t1'x1 \ | |
| 92 index i3 t1'x1 \ | |
| 93 index {sqlite_autoindex_t1'x1_1} t1'x1 \ | |
| 94 index {sqlite_autoindex_t1'x1_2} t1'x1 \ | |
| 95 table {temp table} {temp table} \ | |
| 96 index i2 {temp table} \ | |
| 97 index {sqlite_autoindex_temp table_1} {temp table} \ | |
| 98 ] | |
| 99 | |
| 100 # Make some changes | |
| 101 # | |
| 102 integrity_check alter-1.3.0 | |
| 103 do_test alter-1.3 { | |
| 104 execsql { | |
| 105 ALTER TABLE [T1] RENAME to [-t1-]; | |
| 106 ALTER TABLE "t1'x1" RENAME TO T2; | |
| 107 ALTER TABLE [temp table] RENAME to TempTab; | |
| 108 } | |
| 109 } {} | |
| 110 integrity_check alter-1.3.1 | |
| 111 do_test alter-1.4 { | |
| 112 execsql { | |
| 113 SELECT 't1', * FROM [-t1-]; | |
| 114 SELECT 't2', * FROM t2; | |
| 115 SELECT * FROM temptab; | |
| 116 } | |
| 117 } {t1 1 2 t2 3 4 5 6 7} | |
| 118 do_test alter-1.5 { | |
| 119 execsql { | |
| 120 DELETE FROM objlist; | |
| 121 INSERT INTO objlist SELECT type, name, tbl_name | |
| 122 FROM sqlite_master WHERE NAME!='objlist'; | |
| 123 } | |
| 124 catchsql { | |
| 125 INSERT INTO objlist SELECT type, name, tbl_name | |
| 126 FROM sqlite_temp_master WHERE NAME!='objlist'; | |
| 127 } | |
| 128 execsql { | |
| 129 SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name; | |
| 130 } | |
| 131 } [list \ | |
| 132 table -t1- -t1- \ | |
| 133 index t1i1 -t1- \ | |
| 134 index t1i2 -t1- \ | |
| 135 table T2 T2 \ | |
| 136 index i3 T2 \ | |
| 137 index {sqlite_autoindex_T2_1} T2 \ | |
| 138 index {sqlite_autoindex_T2_2} T2 \ | |
| 139 table {TempTab} {TempTab} \ | |
| 140 index i2 {TempTab} \ | |
| 141 index {sqlite_autoindex_TempTab_1} {TempTab} \ | |
| 142 ] | |
| 143 | |
| 144 # Make sure the changes persist after restarting the database. | |
| 145 # (The TEMP table will not persist, of course.) | |
| 146 # | |
| 147 ifcapable tempdb { | |
| 148 do_test alter-1.6 { | |
| 149 db close | |
| 150 sqlite3 db test.db | |
| 151 set DB [sqlite3_connection_pointer db] | |
| 152 execsql { | |
| 153 CREATE TEMP TABLE objlist(type, name, tbl_name); | |
| 154 INSERT INTO objlist SELECT type, name, tbl_name FROM sqlite_master; | |
| 155 INSERT INTO objlist | |
| 156 SELECT type, name, tbl_name FROM sqlite_temp_master | |
| 157 WHERE NAME!='objlist'; | |
| 158 SELECT type, name, tbl_name FROM objlist | |
| 159 ORDER BY tbl_name, type desc, name; | |
| 160 } | |
| 161 } [list \ | |
| 162 table -t1- -t1- \ | |
| 163 index t1i1 -t1- \ | |
| 164 index t1i2 -t1- \ | |
| 165 table T2 T2 \ | |
| 166 index i3 T2 \ | |
| 167 index {sqlite_autoindex_T2_1} T2 \ | |
| 168 index {sqlite_autoindex_T2_2} T2 \ | |
| 169 ] | |
| 170 } else { | |
| 171 execsql { | |
| 172 DROP TABLE TempTab; | |
| 173 } | |
| 174 } | |
| 175 | |
| 176 # Make sure the ALTER TABLE statements work with the | |
| 177 # non-callback API | |
| 178 # | |
| 179 do_test alter-1.7 { | |
| 180 stepsql $DB { | |
| 181 ALTER TABLE [-t1-] RENAME to [*t1*]; | |
| 182 ALTER TABLE T2 RENAME TO [<t2>]; | |
| 183 } | |
| 184 execsql { | |
| 185 DELETE FROM objlist; | |
| 186 INSERT INTO objlist SELECT type, name, tbl_name | |
| 187 FROM sqlite_master WHERE NAME!='objlist'; | |
| 188 } | |
| 189 catchsql { | |
| 190 INSERT INTO objlist SELECT type, name, tbl_name | |
| 191 FROM sqlite_temp_master WHERE NAME!='objlist'; | |
| 192 } | |
| 193 execsql { | |
| 194 SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name; | |
| 195 } | |
| 196 } [list \ | |
| 197 table *t1* *t1* \ | |
| 198 index t1i1 *t1* \ | |
| 199 index t1i2 *t1* \ | |
| 200 table <t2> <t2> \ | |
| 201 index i3 <t2> \ | |
| 202 index {sqlite_autoindex_<t2>_1} <t2> \ | |
| 203 index {sqlite_autoindex_<t2>_2} <t2> \ | |
| 204 ] | |
| 205 | |
| 206 # Check that ALTER TABLE works on attached databases. | |
| 207 # | |
| 208 ifcapable attach { | |
| 209 do_test alter-1.8.1 { | |
| 210 file delete -force test2.db | |
| 211 file delete -force test2.db-journal | |
| 212 execsql { | |
| 213 ATTACH 'test2.db' AS aux; | |
| 214 } | |
| 215 } {} | |
| 216 do_test alter-1.8.2 { | |
| 217 execsql { | |
| 218 CREATE TABLE t4(a PRIMARY KEY, b, c); | |
| 219 CREATE TABLE aux.t4(a PRIMARY KEY, b, c); | |
| 220 CREATE INDEX i4 ON t4(b); | |
| 221 CREATE INDEX aux.i4 ON t4(b); | |
| 222 } | |
| 223 } {} | |
| 224 do_test alter-1.8.3 { | |
| 225 execsql { | |
| 226 INSERT INTO t4 VALUES('main', 'main', 'main'); | |
| 227 INSERT INTO aux.t4 VALUES('aux', 'aux', 'aux'); | |
| 228 SELECT * FROM t4 WHERE a = 'main'; | |
| 229 } | |
| 230 } {main main main} | |
| 231 do_test alter-1.8.4 { | |
| 232 execsql { | |
| 233 ALTER TABLE t4 RENAME TO t5; | |
| 234 SELECT * FROM t4 WHERE a = 'aux'; | |
| 235 } | |
| 236 } {aux aux aux} | |
| 237 do_test alter-1.8.5 { | |
| 238 execsql { | |
| 239 SELECT * FROM t5; | |
| 240 } | |
| 241 } {main main main} | |
| 242 do_test alter-1.8.6 { | |
| 243 execsql { | |
| 244 SELECT * FROM t5 WHERE b = 'main'; | |
| 245 } | |
| 246 } {main main main} | |
| 247 do_test alter-1.8.7 { | |
| 248 execsql { | |
| 249 ALTER TABLE aux.t4 RENAME TO t5; | |
| 250 SELECT * FROM aux.t5 WHERE b = 'aux'; | |
| 251 } | |
| 252 } {aux aux aux} | |
| 253 } | |
| 254 | |
| 255 do_test alter-1.9.1 { | |
| 256 execsql { | |
| 257 CREATE TABLE tbl1 (a, b, c); | |
| 258 INSERT INTO tbl1 VALUES(1, 2, 3); | |
| 259 } | |
| 260 } {} | |
| 261 do_test alter-1.9.2 { | |
| 262 execsql { | |
| 263 SELECT * FROM tbl1; | |
| 264 } | |
| 265 } {1 2 3} | |
| 266 do_test alter-1.9.3 { | |
| 267 execsql { | |
| 268 ALTER TABLE tbl1 RENAME TO tbl2; | |
| 269 SELECT * FROM tbl2; | |
| 270 } | |
| 271 } {1 2 3} | |
| 272 do_test alter-1.9.4 { | |
| 273 execsql { | |
| 274 DROP TABLE tbl2; | |
| 275 } | |
| 276 } {} | |
| 277 | |
| 278 # Test error messages | |
| 279 # | |
| 280 do_test alter-2.1 { | |
| 281 catchsql { | |
| 282 ALTER TABLE none RENAME TO hi; | |
| 283 } | |
| 284 } {1 {no such table: none}} | |
| 285 do_test alter-2.2 { | |
| 286 execsql { | |
| 287 CREATE TABLE t3(p,q,r); | |
| 288 } | |
| 289 catchsql { | |
| 290 ALTER TABLE [<t2>] RENAME TO t3; | |
| 291 } | |
| 292 } {1 {there is already another table or index with this name: t3}} | |
| 293 do_test alter-2.3 { | |
| 294 catchsql { | |
| 295 ALTER TABLE [<t2>] RENAME TO i3; | |
| 296 } | |
| 297 } {1 {there is already another table or index with this name: i3}} | |
| 298 do_test alter-2.4 { | |
| 299 catchsql { | |
| 300 ALTER TABLE SqLiTe_master RENAME TO master; | |
| 301 } | |
| 302 } {1 {table sqlite_master may not be altered}} | |
| 303 do_test alter-2.5 { | |
| 304 catchsql { | |
| 305 ALTER TABLE t3 RENAME TO sqlite_t3; | |
| 306 } | |
| 307 } {1 {object name reserved for internal use: sqlite_t3}} | |
| 308 do_test alter-2.6 { | |
| 309 catchsql { | |
| 310 ALTER TABLE t3 ADD COLUMN (ALTER TABLE t3 ADD COLUMN); | |
| 311 } | |
| 312 } {1 {near "(": syntax error}} | |
| 313 | |
| 314 # If this compilation does not include triggers, omit the alter-3.* tests. | |
| 315 ifcapable trigger { | |
| 316 | |
| 317 #----------------------------------------------------------------------- | |
| 318 # Tests alter-3.* test ALTER TABLE on tables that have triggers. | |
| 319 # | |
| 320 # alter-3.1.*: ALTER TABLE with triggers. | |
| 321 # alter-3.2.*: Test that the ON keyword cannot be used as a database, | |
| 322 # table or column name unquoted. This is done because part of the | |
| 323 # ALTER TABLE code (specifically the implementation of SQL function | |
| 324 # "sqlite_alter_trigger") will break in this case. | |
| 325 # alter-3.3.*: ALTER TABLE with TEMP triggers (todo). | |
| 326 # | |
| 327 | |
| 328 # An SQL user-function for triggers to fire, so that we know they | |
| 329 # are working. | |
| 330 proc trigfunc {args} { | |
| 331 set ::TRIGGER $args | |
| 332 } | |
| 333 db func trigfunc trigfunc | |
| 334 | |
| 335 do_test alter-3.1.0 { | |
| 336 execsql { | |
| 337 CREATE TABLE t6(a, b, c); | |
| 338 CREATE TRIGGER trig1 AFTER INSERT ON t6 BEGIN | |
| 339 SELECT trigfunc('trig1', new.a, new.b, new.c); | |
| 340 END; | |
| 341 } | |
| 342 } {} | |
| 343 do_test alter-3.1.1 { | |
| 344 execsql { | |
| 345 INSERT INTO t6 VALUES(1, 2, 3); | |
| 346 } | |
| 347 set ::TRIGGER | |
| 348 } {trig1 1 2 3} | |
| 349 do_test alter-3.1.2 { | |
| 350 execsql { | |
| 351 ALTER TABLE t6 RENAME TO t7; | |
| 352 INSERT INTO t7 VALUES(4, 5, 6); | |
| 353 } | |
| 354 set ::TRIGGER | |
| 355 } {trig1 4 5 6} | |
| 356 do_test alter-3.1.3 { | |
| 357 execsql { | |
| 358 DROP TRIGGER trig1; | |
| 359 } | |
| 360 } {} | |
| 361 do_test alter-3.1.4 { | |
| 362 execsql { | |
| 363 CREATE TRIGGER trig2 AFTER INSERT ON main.t7 BEGIN | |
| 364 SELECT trigfunc('trig2', new.a, new.b, new.c); | |
| 365 END; | |
| 366 INSERT INTO t7 VALUES(1, 2, 3); | |
| 367 } | |
| 368 set ::TRIGGER | |
| 369 } {trig2 1 2 3} | |
| 370 do_test alter-3.1.5 { | |
| 371 execsql { | |
| 372 ALTER TABLE t7 RENAME TO t8; | |
| 373 INSERT INTO t8 VALUES(4, 5, 6); | |
| 374 } | |
| 375 set ::TRIGGER | |
| 376 } {trig2 4 5 6} | |
| 377 do_test alter-3.1.6 { | |
| 378 execsql { | |
| 379 DROP TRIGGER trig2; | |
| 380 } | |
| 381 } {} | |
| 382 do_test alter-3.1.7 { | |
| 383 execsql { | |
| 384 CREATE TRIGGER trig3 AFTER INSERT ON main.'t8'BEGIN | |
| 385 SELECT trigfunc('trig3', new.a, new.b, new.c); | |
| 386 END; | |
| 387 INSERT INTO t8 VALUES(1, 2, 3); | |
| 388 } | |
| 389 set ::TRIGGER | |
| 390 } {trig3 1 2 3} | |
| 391 do_test alter-3.1.8 { | |
| 392 execsql { | |
| 393 ALTER TABLE t8 RENAME TO t9; | |
| 394 INSERT INTO t9 VALUES(4, 5, 6); | |
| 395 } | |
| 396 set ::TRIGGER | |
| 397 } {trig3 4 5 6} | |
| 398 | |
| 399 # Make sure "ON" cannot be used as a database, table or column name without | |
| 400 # quoting. Otherwise the sqlite_alter_trigger() function might not work. | |
| 401 file delete -force test3.db | |
| 402 file delete -force test3.db-journal | |
| 403 ifcapable attach { | |
| 404 do_test alter-3.2.1 { | |
| 405 catchsql { | |
| 406 ATTACH 'test3.db' AS ON; | |
| 407 } | |
| 408 } {1 {near "ON": syntax error}} | |
| 409 do_test alter-3.2.2 { | |
| 410 catchsql { | |
| 411 ATTACH 'test3.db' AS 'ON'; | |
| 412 } | |
| 413 } {0 {}} | |
| 414 do_test alter-3.2.3 { | |
| 415 catchsql { | |
| 416 CREATE TABLE ON.t1(a, b, c); | |
| 417 } | |
| 418 } {1 {near "ON": syntax error}} | |
| 419 do_test alter-3.2.4 { | |
| 420 catchsql { | |
| 421 CREATE TABLE 'ON'.t1(a, b, c); | |
| 422 } | |
| 423 } {0 {}} | |
| 424 do_test alter-3.2.4 { | |
| 425 catchsql { | |
| 426 CREATE TABLE 'ON'.ON(a, b, c); | |
| 427 } | |
| 428 } {1 {near "ON": syntax error}} | |
| 429 do_test alter-3.2.5 { | |
| 430 catchsql { | |
| 431 CREATE TABLE 'ON'.'ON'(a, b, c); | |
| 432 } | |
| 433 } {0 {}} | |
| 434 } | |
| 435 do_test alter-3.2.6 { | |
| 436 catchsql { | |
| 437 CREATE TABLE t10(a, ON, c); | |
| 438 } | |
| 439 } {1 {near "ON": syntax error}} | |
| 440 do_test alter-3.2.7 { | |
| 441 catchsql { | |
| 442 CREATE TABLE t10(a, 'ON', c); | |
| 443 } | |
| 444 } {0 {}} | |
| 445 do_test alter-3.2.8 { | |
| 446 catchsql { | |
| 447 CREATE TRIGGER trig4 AFTER INSERT ON ON BEGIN SELECT 1; END; | |
| 448 } | |
| 449 } {1 {near "ON": syntax error}} | |
| 450 ifcapable attach { | |
| 451 do_test alter-3.2.9 { | |
| 452 catchsql { | |
| 453 CREATE TRIGGER 'on'.trig4 AFTER INSERT ON 'ON' BEGIN SELECT 1; END; | |
| 454 } | |
| 455 } {0 {}} | |
| 456 } | |
| 457 do_test alter-3.2.10 { | |
| 458 execsql { | |
| 459 DROP TABLE t10; | |
| 460 } | |
| 461 } {} | |
| 462 | |
| 463 do_test alter-3.3.1 { | |
| 464 execsql [subst { | |
| 465 CREATE TABLE tbl1(a, b, c); | |
| 466 CREATE $::temp TRIGGER trig1 AFTER INSERT ON tbl1 BEGIN | |
| 467 SELECT trigfunc('trig1', new.a, new.b, new.c); | |
| 468 END; | |
| 469 }] | |
| 470 } {} | |
| 471 do_test alter-3.3.2 { | |
| 472 execsql { | |
| 473 INSERT INTO tbl1 VALUES('a', 'b', 'c'); | |
| 474 } | |
| 475 set ::TRIGGER | |
| 476 } {trig1 a b c} | |
| 477 do_test alter-3.3.3 { | |
| 478 execsql { | |
| 479 ALTER TABLE tbl1 RENAME TO tbl2; | |
| 480 INSERT INTO tbl2 VALUES('d', 'e', 'f'); | |
| 481 } | |
| 482 set ::TRIGGER | |
| 483 } {trig1 d e f} | |
| 484 do_test alter-3.3.4 { | |
| 485 execsql [subst { | |
| 486 CREATE $::temp TRIGGER trig2 AFTER UPDATE ON tbl2 BEGIN | |
| 487 SELECT trigfunc('trig2', new.a, new.b, new.c); | |
| 488 END; | |
| 489 }] | |
| 490 } {} | |
| 491 do_test alter-3.3.5 { | |
| 492 execsql { | |
| 493 ALTER TABLE tbl2 RENAME TO tbl3; | |
| 494 INSERT INTO tbl3 VALUES('g', 'h', 'i'); | |
| 495 } | |
| 496 set ::TRIGGER | |
| 497 } {trig1 g h i} | |
| 498 do_test alter-3.3.6 { | |
| 499 execsql { | |
| 500 UPDATE tbl3 SET a = 'G' where a = 'g'; | |
| 501 } | |
| 502 set ::TRIGGER | |
| 503 } {trig2 G h i} | |
| 504 do_test alter-3.3.7 { | |
| 505 execsql { | |
| 506 DROP TABLE tbl3; | |
| 507 } | |
| 508 } {} | |
| 509 ifcapable tempdb { | |
| 510 do_test alter-3.3.8 { | |
| 511 execsql { | |
| 512 SELECT * FROM sqlite_temp_master WHERE type = 'trigger'; | |
| 513 } | |
| 514 } {} | |
| 515 } | |
| 516 | |
| 517 } ;# ifcapable trigger | |
| 518 | |
| 519 # If the build does not include AUTOINCREMENT fields, omit alter-4.*. | |
| 520 ifcapable autoinc { | |
| 521 | |
| 522 do_test alter-4.1 { | |
| 523 execsql { | |
| 524 CREATE TABLE tbl1(a INTEGER PRIMARY KEY AUTOINCREMENT); | |
| 525 INSERT INTO tbl1 VALUES(10); | |
| 526 } | |
| 527 } {} | |
| 528 do_test alter-4.2 { | |
| 529 execsql { | |
| 530 INSERT INTO tbl1 VALUES(NULL); | |
| 531 SELECT a FROM tbl1; | |
| 532 } | |
| 533 } {10 11} | |
| 534 do_test alter-4.3 { | |
| 535 execsql { | |
| 536 ALTER TABLE tbl1 RENAME TO tbl2; | |
| 537 DELETE FROM tbl2; | |
| 538 INSERT INTO tbl2 VALUES(NULL); | |
| 539 SELECT a FROM tbl2; | |
| 540 } | |
| 541 } {12} | |
| 542 do_test alter-4.4 { | |
| 543 execsql { | |
| 544 DROP TABLE tbl2; | |
| 545 } | |
| 546 } {} | |
| 547 | |
| 548 } ;# ifcapable autoinc | |
| 549 | |
| 550 # Test that it is Ok to execute an ALTER TABLE immediately after | |
| 551 # opening a database. | |
| 552 do_test alter-5.1 { | |
| 553 execsql { | |
| 554 CREATE TABLE tbl1(a, b, c); | |
| 555 INSERT INTO tbl1 VALUES('x', 'y', 'z'); | |
| 556 } | |
| 557 } {} | |
| 558 do_test alter-5.2 { | |
| 559 sqlite3 db2 test.db | |
| 560 execsql { | |
| 561 ALTER TABLE tbl1 RENAME TO tbl2; | |
| 562 SELECT * FROM tbl2; | |
| 563 } db2 | |
| 564 } {x y z} | |
| 565 do_test alter-5.3 { | |
| 566 db2 close | |
| 567 } {} | |
| 568 | |
| 569 foreach tblname [execsql { | |
| 570 SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite%' | |
| 571 }] { | |
| 572 execsql "DROP TABLE \"$tblname\"" | |
| 573 } | |
| 574 | |
| 575 set ::tbl_name "abc\uABCDdef" | |
| 576 do_test alter-6.1 { | |
| 577 string length $::tbl_name | |
| 578 } {7} | |
| 579 do_test alter-6.2 { | |
| 580 execsql " | |
| 581 CREATE TABLE ${tbl_name}(a, b, c); | |
| 582 " | |
| 583 set ::oid [execsql {SELECT max(oid) FROM sqlite_master}] | |
| 584 execsql " | |
| 585 SELECT sql FROM sqlite_master WHERE oid = $::oid; | |
| 586 " | |
| 587 } "{CREATE TABLE ${::tbl_name}(a, b, c)}" | |
| 588 execsql " | |
| 589 SELECT * FROM ${::tbl_name} | |
| 590 " | |
| 591 set ::tbl_name2 "abcXdef" | |
| 592 do_test alter-6.3 { | |
| 593 execsql " | |
| 594 ALTER TABLE $::tbl_name RENAME TO $::tbl_name2 | |
| 595 " | |
| 596 execsql " | |
| 597 SELECT sql FROM sqlite_master WHERE oid = $::oid | |
| 598 " | |
| 599 } "{CREATE TABLE \"${::tbl_name2}\"(a, b, c)}" | |
| 600 do_test alter-6.4 { | |
| 601 execsql " | |
| 602 ALTER TABLE $::tbl_name2 RENAME TO $::tbl_name | |
| 603 " | |
| 604 execsql " | |
| 605 SELECT sql FROM sqlite_master WHERE oid = $::oid | |
| 606 " | |
| 607 } "{CREATE TABLE \"${::tbl_name}\"(a, b, c)}" | |
| 608 set ::col_name ghi\1234\jkl | |
| 609 do_test alter-6.5 { | |
| 610 execsql " | |
| 611 ALTER TABLE $::tbl_name ADD COLUMN $::col_name VARCHAR | |
| 612 " | |
| 613 execsql " | |
| 614 SELECT sql FROM sqlite_master WHERE oid = $::oid | |
| 615 " | |
| 616 } "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR)}" | |
| 617 set ::col_name2 B\3421\A | |
| 618 do_test alter-6.6 { | |
| 619 db close | |
| 620 sqlite3 db test.db | |
| 621 execsql " | |
| 622 ALTER TABLE $::tbl_name ADD COLUMN $::col_name2 | |
| 623 " | |
| 624 execsql " | |
| 625 SELECT sql FROM sqlite_master WHERE oid = $::oid | |
| 626 " | |
| 627 } "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR, $::col_name2)}" | |
| 628 do_test alter-6.7 { | |
| 629 execsql " | |
| 630 INSERT INTO ${::tbl_name} VALUES(1, 2, 3, 4, 5); | |
| 631 SELECT $::col_name, $::col_name2 FROM $::tbl_name; | |
| 632 " | |
| 633 } {4 5} | |
| 634 | |
| 635 # Ticket #1665: Make sure ALTER TABLE ADD COLUMN works on a table | |
| 636 # that includes a COLLATE clause. | |
| 637 # | |
| 638 do_test alter-7.1 { | |
| 639 execsql { | |
| 640 CREATE TABLE t1(a TEXT COLLATE BINARY); | |
| 641 ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE; | |
| 642 INSERT INTO t1 VALUES(1,'-2'); | |
| 643 INSERT INTO t1 VALUES(5.4e-08,'5.4e-08'); | |
| 644 SELECT typeof(a), a, typeof(b), b FROM t1; | |
| 645 } | |
| 646 } {text 1 integer -2 text 5.4e-08 real 5.4e-08} | |
| 647 | |
| 648 # Make sure that when a column is added by ALTER TABLE ADD COLUMN and has | |
| 649 # a default value that the default value is used by aggregate functions. | |
| 650 # | |
| 651 do_test alter-8.1 { | |
| 652 execsql { | |
| 653 CREATE TABLE t2(a INTEGER); | |
| 654 INSERT INTO t2 VALUES(1); | |
| 655 INSERT INTO t2 VALUES(1); | |
| 656 INSERT INTO t2 VALUES(2); | |
| 657 ALTER TABLE t2 ADD COLUMN b INTEGER DEFAULT 9; | |
| 658 SELECT sum(b) FROM t2; | |
| 659 } | |
| 660 } {27} | |
| 661 do_test alter-8.2 { | |
| 662 execsql { | |
| 663 SELECT a, sum(b) FROM t2 GROUP BY a; | |
| 664 } | |
| 665 } {1 18 2 9} | |
| 666 | |
| 667 #-------------------------------------------------------------------------- | |
| 668 # alter-9.X - Special test: Make sure the sqlite_rename_trigger() and | |
| 669 # rename_table() functions do not crash when handed bad input. | |
| 670 # | |
| 671 ifcapable trigger { | |
| 672 do_test alter-9.1 { | |
| 673 execsql {SELECT SQLITE_RENAME_TRIGGER(0,0)} | |
| 674 } {{}} | |
| 675 } | |
| 676 do_test alter-9.2 { | |
| 677 execsql { | |
| 678 SELECT SQLITE_RENAME_TABLE(0,0); | |
| 679 SELECT SQLITE_RENAME_TABLE(10,20); | |
| 680 SELECT SQLITE_RENAME_TABLE('foo', 'foo'); | |
| 681 } | |
| 682 } {{} {} {}} | |
| 683 | |
| 684 #------------------------------------------------------------------------ | |
| 685 # alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters | |
| 686 # in the names. | |
| 687 # | |
| 688 do_test alter-10.1 { | |
| 689 execsql "CREATE TABLE xyz(x UNIQUE)" | |
| 690 execsql "ALTER TABLE xyz RENAME TO xyz\u1234abc" | |
| 691 execsql {SELECT name FROM sqlite_master WHERE name LIKE 'xyz%'} | |
| 692 } [list xyz\u1234abc] | |
| 693 do_test alter-10.2 { | |
| 694 execsql {SELECT name FROM sqlite_master WHERE name LIKE 'sqlite_autoindex%'} | |
| 695 } [list sqlite_autoindex_xyz\u1234abc_1] | |
| 696 do_test alter-10.3 { | |
| 697 execsql "ALTER TABLE xyz\u1234abc RENAME TO xyzabc" | |
| 698 execsql {SELECT name FROM sqlite_master WHERE name LIKE 'xyz%'} | |
| 699 } [list xyzabc] | |
| 700 do_test alter-10.4 { | |
| 701 execsql {SELECT name FROM sqlite_master WHERE name LIKE 'sqlite_autoindex%'} | |
| 702 } [list sqlite_autoindex_xyzabc_1] | |
| 703 | |
| 704 do_test alter-11.1 { | |
| 705 sqlite3_exec db {CREATE TABLE t11(%c6%c6)} | |
| 706 execsql { | |
| 707 ALTER TABLE t11 ADD COLUMN abc; | |
| 708 } | |
| 709 catchsql { | |
| 710 ALTER TABLE t11 ADD COLUMN abc; | |
| 711 } | |
| 712 } {1 {duplicate column name: abc}} | |
| 713 set isutf16 [regexp 16 [db one {PRAGMA encoding}]] | |
| 714 if {!$isutf16} { | |
| 715 do_test alter-11.2 { | |
| 716 execsql {INSERT INTO t11 VALUES(1,2)} | |
| 717 sqlite3_exec db {SELECT %c6%c6 AS xyz, abc FROM t11} | |
| 718 } {0 {xyz abc 1 2}} | |
| 719 } | |
| 720 do_test alter-11.3 { | |
| 721 sqlite3_exec db {CREATE TABLE t11b("%81%82%83" text)} | |
| 722 execsql { | |
| 723 ALTER TABLE t11b ADD COLUMN abc; | |
| 724 } | |
| 725 catchsql { | |
| 726 ALTER TABLE t11b ADD COLUMN abc; | |
| 727 } | |
| 728 } {1 {duplicate column name: abc}} | |
| 729 if {!$isutf16} { | |
| 730 do_test alter-11.4 { | |
| 731 execsql {INSERT INTO t11b VALUES(3,4)} | |
| 732 sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11b} | |
| 733 } {0 {xyz abc 3 4}} | |
| 734 do_test alter-11.5 { | |
| 735 sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11b} | |
| 736 } {0 {xyz abc 3 4}} | |
| 737 do_test alter-11.6 { | |
| 738 sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11b} | |
| 739 } {0 {xyz abc 3 4}} | |
| 740 } | |
| 741 do_test alter-11.7 { | |
| 742 sqlite3_exec db {CREATE TABLE t11c(%81%82%83 text)} | |
| 743 execsql { | |
| 744 ALTER TABLE t11c ADD COLUMN abc; | |
| 745 } | |
| 746 catchsql { | |
| 747 ALTER TABLE t11c ADD COLUMN abc; | |
| 748 } | |
| 749 } {1 {duplicate column name: abc}} | |
| 750 if {!$isutf16} { | |
| 751 do_test alter-11.8 { | |
| 752 execsql {INSERT INTO t11c VALUES(5,6)} | |
| 753 sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11c} | |
| 754 } {0 {xyz abc 5 6}} | |
| 755 do_test alter-11.9 { | |
| 756 sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11c} | |
| 757 } {0 {xyz abc 5 6}} | |
| 758 do_test alter-11.10 { | |
| 759 sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11c} | |
| 760 } {0 {xyz abc 5 6}} | |
| 761 } | |
| 762 | |
| 763 do_test alter-12.1 { | |
| 764 execsql { | |
| 765 CREATE TABLE t12(a, b, c); | |
| 766 CREATE VIEW v1 AS SELECT * FROM t12; | |
| 767 } | |
| 768 } {} | |
| 769 do_test alter-12.2 { | |
| 770 catchsql { | |
| 771 ALTER TABLE v1 RENAME TO v2; | |
| 772 } | |
| 773 } {1 {view v1 may not be altered}} | |
| 774 do_test alter-12.3 { | |
| 775 execsql { SELECT * FROM v1; } | |
| 776 } {} | |
| 777 do_test alter-12.4 { | |
| 778 db close | |
| 779 sqlite3 db test.db | |
| 780 execsql { SELECT * FROM v1; } | |
| 781 } {} | |
| 782 do_test alter-12.5 { | |
| 783 catchsql { | |
| 784 ALTER TABLE v1 ADD COLUMN new_column; | |
| 785 } | |
| 786 } {1 {Cannot add a column to a view}} | |
| 787 | |
| 788 # Ticket #3102: | |
| 789 # Verify that comments do not interfere with the table rename | |
| 790 # algorithm. | |
| 791 # | |
| 792 do_test alter-13.1 { | |
| 793 execsql { | |
| 794 CREATE TABLE /* hi */ t3102a(x); | |
| 795 CREATE TABLE t3102b -- comment | |
| 796 (y); | |
| 797 CREATE INDEX t3102c ON t3102a(x); | |
| 798 SELECT name FROM sqlite_master WHERE name LIKE 't3102%' ORDER BY 1; | |
| 799 } | |
| 800 } {t3102a t3102b t3102c} | |
| 801 do_test alter-13.2 { | |
| 802 execsql { | |
| 803 ALTER TABLE t3102a RENAME TO t3102a_rename; | |
| 804 SELECT name FROM sqlite_master WHERE name LIKE 't3102%' ORDER BY 1; | |
| 805 } | |
| 806 } {t3102a_rename t3102b t3102c} | |
| 807 do_test alter-13.3 { | |
| 808 execsql { | |
| 809 ALTER TABLE t3102b RENAME TO t3102b_rename; | |
| 810 SELECT name FROM sqlite_master WHERE name LIKE 't3102%' ORDER BY 1; | |
| 811 } | |
| 812 } {t3102a_rename t3102b_rename t3102c} | |
| 813 | |
| 814 # Ticket #3651 | |
| 815 do_test alter-14.1 { | |
| 816 catchsql { | |
| 817 CREATE TABLE t3651(a UNIQUE); | |
| 818 ALTER TABLE t3651 ADD COLUMN b UNIQUE; | |
| 819 } | |
| 820 } {1 {Cannot add a UNIQUE column}} | |
| 821 do_test alter-14.2 { | |
| 822 catchsql { | |
| 823 ALTER TABLE t3651 ADD COLUMN b PRIMARY KEY; | |
| 824 } | |
| 825 } {1 {Cannot add a PRIMARY KEY column}} | |
| 826 | |
| 827 | |
| 828 finish_test | |
| OLD | NEW |