Annotation of embedaddon/sqlite3/test/alter.test, revision 1.1
1.1 ! misho 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: # Create bogus application-defined functions for functions used
! 177: # internally by ALTER TABLE, to ensure that ALTER TABLE falls back
! 178: # to the built-in functions.
! 179: #
! 180: proc failing_app_func {args} {error "bad function"}
! 181: do_test alter-1.7-prep {
! 182: db func substr failing_app_func
! 183: db func like failing_app_func
! 184: db func sqlite_rename_table failing_app_func
! 185: db func sqlite_rename_trigger failing_app_func
! 186: db func sqlite_rename_parent failing_app_func
! 187: catchsql {SELECT substr(name,1,3) FROM sqlite_master}
! 188: } {1 {bad function}}
! 189:
! 190: # Make sure the ALTER TABLE statements work with the
! 191: # non-callback API
! 192: #
! 193: do_test alter-1.7 {
! 194: stepsql $DB {
! 195: ALTER TABLE [-t1-] RENAME to [*t1*];
! 196: ALTER TABLE T2 RENAME TO [<t2>];
! 197: }
! 198: execsql {
! 199: DELETE FROM objlist;
! 200: INSERT INTO objlist SELECT type, name, tbl_name
! 201: FROM sqlite_master WHERE NAME!='objlist';
! 202: }
! 203: catchsql {
! 204: INSERT INTO objlist SELECT type, name, tbl_name
! 205: FROM sqlite_temp_master WHERE NAME!='objlist';
! 206: }
! 207: execsql {
! 208: SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name;
! 209: }
! 210: } [list \
! 211: table *t1* *t1* \
! 212: index t1i1 *t1* \
! 213: index t1i2 *t1* \
! 214: table <t2> <t2> \
! 215: index i3 <t2> \
! 216: index {sqlite_autoindex_<t2>_1} <t2> \
! 217: index {sqlite_autoindex_<t2>_2} <t2> \
! 218: ]
! 219:
! 220: # Check that ALTER TABLE works on attached databases.
! 221: #
! 222: ifcapable attach {
! 223: do_test alter-1.8.1 {
! 224: forcedelete test2.db
! 225: forcedelete test2.db-journal
! 226: execsql {
! 227: ATTACH 'test2.db' AS aux;
! 228: }
! 229: } {}
! 230: do_test alter-1.8.2 {
! 231: execsql {
! 232: CREATE TABLE t4(a PRIMARY KEY, b, c);
! 233: CREATE TABLE aux.t4(a PRIMARY KEY, b, c);
! 234: CREATE INDEX i4 ON t4(b);
! 235: CREATE INDEX aux.i4 ON t4(b);
! 236: }
! 237: } {}
! 238: do_test alter-1.8.3 {
! 239: execsql {
! 240: INSERT INTO t4 VALUES('main', 'main', 'main');
! 241: INSERT INTO aux.t4 VALUES('aux', 'aux', 'aux');
! 242: SELECT * FROM t4 WHERE a = 'main';
! 243: }
! 244: } {main main main}
! 245: do_test alter-1.8.4 {
! 246: execsql {
! 247: ALTER TABLE t4 RENAME TO t5;
! 248: SELECT * FROM t4 WHERE a = 'aux';
! 249: }
! 250: } {aux aux aux}
! 251: do_test alter-1.8.5 {
! 252: execsql {
! 253: SELECT * FROM t5;
! 254: }
! 255: } {main main main}
! 256: do_test alter-1.8.6 {
! 257: execsql {
! 258: SELECT * FROM t5 WHERE b = 'main';
! 259: }
! 260: } {main main main}
! 261: do_test alter-1.8.7 {
! 262: execsql {
! 263: ALTER TABLE aux.t4 RENAME TO t5;
! 264: SELECT * FROM aux.t5 WHERE b = 'aux';
! 265: }
! 266: } {aux aux aux}
! 267: }
! 268:
! 269: do_test alter-1.9.1 {
! 270: execsql {
! 271: CREATE TABLE tbl1 (a, b, c);
! 272: INSERT INTO tbl1 VALUES(1, 2, 3);
! 273: }
! 274: } {}
! 275: do_test alter-1.9.2 {
! 276: execsql {
! 277: SELECT * FROM tbl1;
! 278: }
! 279: } {1 2 3}
! 280: do_test alter-1.9.3 {
! 281: execsql {
! 282: ALTER TABLE tbl1 RENAME TO tbl2;
! 283: SELECT * FROM tbl2;
! 284: }
! 285: } {1 2 3}
! 286: do_test alter-1.9.4 {
! 287: execsql {
! 288: DROP TABLE tbl2;
! 289: }
! 290: } {}
! 291:
! 292: # Test error messages
! 293: #
! 294: do_test alter-2.1 {
! 295: catchsql {
! 296: ALTER TABLE none RENAME TO hi;
! 297: }
! 298: } {1 {no such table: none}}
! 299: do_test alter-2.2 {
! 300: execsql {
! 301: CREATE TABLE t3(p,q,r);
! 302: }
! 303: catchsql {
! 304: ALTER TABLE [<t2>] RENAME TO t3;
! 305: }
! 306: } {1 {there is already another table or index with this name: t3}}
! 307: do_test alter-2.3 {
! 308: catchsql {
! 309: ALTER TABLE [<t2>] RENAME TO i3;
! 310: }
! 311: } {1 {there is already another table or index with this name: i3}}
! 312: do_test alter-2.4 {
! 313: catchsql {
! 314: ALTER TABLE SqLiTe_master RENAME TO master;
! 315: }
! 316: } {1 {table sqlite_master may not be altered}}
! 317: do_test alter-2.5 {
! 318: catchsql {
! 319: ALTER TABLE t3 RENAME TO sqlite_t3;
! 320: }
! 321: } {1 {object name reserved for internal use: sqlite_t3}}
! 322: do_test alter-2.6 {
! 323: catchsql {
! 324: ALTER TABLE t3 ADD COLUMN (ALTER TABLE t3 ADD COLUMN);
! 325: }
! 326: } {1 {near "(": syntax error}}
! 327:
! 328: # If this compilation does not include triggers, omit the alter-3.* tests.
! 329: ifcapable trigger {
! 330:
! 331: #-----------------------------------------------------------------------
! 332: # Tests alter-3.* test ALTER TABLE on tables that have triggers.
! 333: #
! 334: # alter-3.1.*: ALTER TABLE with triggers.
! 335: # alter-3.2.*: Test that the ON keyword cannot be used as a database,
! 336: # table or column name unquoted. This is done because part of the
! 337: # ALTER TABLE code (specifically the implementation of SQL function
! 338: # "sqlite_alter_trigger") will break in this case.
! 339: # alter-3.3.*: ALTER TABLE with TEMP triggers (todo).
! 340: #
! 341:
! 342: # An SQL user-function for triggers to fire, so that we know they
! 343: # are working.
! 344: proc trigfunc {args} {
! 345: set ::TRIGGER $args
! 346: }
! 347: db func trigfunc trigfunc
! 348:
! 349: do_test alter-3.1.0 {
! 350: execsql {
! 351: CREATE TABLE t6(a, b, c);
! 352: CREATE TRIGGER trig1 AFTER INSERT ON t6 BEGIN
! 353: SELECT trigfunc('trig1', new.a, new.b, new.c);
! 354: END;
! 355: }
! 356: } {}
! 357: do_test alter-3.1.1 {
! 358: execsql {
! 359: INSERT INTO t6 VALUES(1, 2, 3);
! 360: }
! 361: set ::TRIGGER
! 362: } {trig1 1 2 3}
! 363: do_test alter-3.1.2 {
! 364: execsql {
! 365: ALTER TABLE t6 RENAME TO t7;
! 366: INSERT INTO t7 VALUES(4, 5, 6);
! 367: }
! 368: set ::TRIGGER
! 369: } {trig1 4 5 6}
! 370: do_test alter-3.1.3 {
! 371: execsql {
! 372: DROP TRIGGER trig1;
! 373: }
! 374: } {}
! 375: do_test alter-3.1.4 {
! 376: execsql {
! 377: CREATE TRIGGER trig2 AFTER INSERT ON main.t7 BEGIN
! 378: SELECT trigfunc('trig2', new.a, new.b, new.c);
! 379: END;
! 380: INSERT INTO t7 VALUES(1, 2, 3);
! 381: }
! 382: set ::TRIGGER
! 383: } {trig2 1 2 3}
! 384: do_test alter-3.1.5 {
! 385: execsql {
! 386: ALTER TABLE t7 RENAME TO t8;
! 387: INSERT INTO t8 VALUES(4, 5, 6);
! 388: }
! 389: set ::TRIGGER
! 390: } {trig2 4 5 6}
! 391: do_test alter-3.1.6 {
! 392: execsql {
! 393: DROP TRIGGER trig2;
! 394: }
! 395: } {}
! 396: do_test alter-3.1.7 {
! 397: execsql {
! 398: CREATE TRIGGER trig3 AFTER INSERT ON main.'t8'BEGIN
! 399: SELECT trigfunc('trig3', new.a, new.b, new.c);
! 400: END;
! 401: INSERT INTO t8 VALUES(1, 2, 3);
! 402: }
! 403: set ::TRIGGER
! 404: } {trig3 1 2 3}
! 405: do_test alter-3.1.8 {
! 406: execsql {
! 407: ALTER TABLE t8 RENAME TO t9;
! 408: INSERT INTO t9 VALUES(4, 5, 6);
! 409: }
! 410: set ::TRIGGER
! 411: } {trig3 4 5 6}
! 412:
! 413: # Make sure "ON" cannot be used as a database, table or column name without
! 414: # quoting. Otherwise the sqlite_alter_trigger() function might not work.
! 415: forcedelete test3.db
! 416: forcedelete test3.db-journal
! 417: ifcapable attach {
! 418: do_test alter-3.2.1 {
! 419: catchsql {
! 420: ATTACH 'test3.db' AS ON;
! 421: }
! 422: } {1 {near "ON": syntax error}}
! 423: do_test alter-3.2.2 {
! 424: catchsql {
! 425: ATTACH 'test3.db' AS 'ON';
! 426: }
! 427: } {0 {}}
! 428: do_test alter-3.2.3 {
! 429: catchsql {
! 430: CREATE TABLE ON.t1(a, b, c);
! 431: }
! 432: } {1 {near "ON": syntax error}}
! 433: do_test alter-3.2.4 {
! 434: catchsql {
! 435: CREATE TABLE 'ON'.t1(a, b, c);
! 436: }
! 437: } {0 {}}
! 438: do_test alter-3.2.4 {
! 439: catchsql {
! 440: CREATE TABLE 'ON'.ON(a, b, c);
! 441: }
! 442: } {1 {near "ON": syntax error}}
! 443: do_test alter-3.2.5 {
! 444: catchsql {
! 445: CREATE TABLE 'ON'.'ON'(a, b, c);
! 446: }
! 447: } {0 {}}
! 448: }
! 449: do_test alter-3.2.6 {
! 450: catchsql {
! 451: CREATE TABLE t10(a, ON, c);
! 452: }
! 453: } {1 {near "ON": syntax error}}
! 454: do_test alter-3.2.7 {
! 455: catchsql {
! 456: CREATE TABLE t10(a, 'ON', c);
! 457: }
! 458: } {0 {}}
! 459: do_test alter-3.2.8 {
! 460: catchsql {
! 461: CREATE TRIGGER trig4 AFTER INSERT ON ON BEGIN SELECT 1; END;
! 462: }
! 463: } {1 {near "ON": syntax error}}
! 464: ifcapable attach {
! 465: do_test alter-3.2.9 {
! 466: catchsql {
! 467: CREATE TRIGGER 'on'.trig4 AFTER INSERT ON 'ON' BEGIN SELECT 1; END;
! 468: }
! 469: } {0 {}}
! 470: }
! 471: do_test alter-3.2.10 {
! 472: execsql {
! 473: DROP TABLE t10;
! 474: }
! 475: } {}
! 476:
! 477: do_test alter-3.3.1 {
! 478: execsql [subst {
! 479: CREATE TABLE tbl1(a, b, c);
! 480: CREATE $::temp TRIGGER trig1 AFTER INSERT ON tbl1 BEGIN
! 481: SELECT trigfunc('trig1', new.a, new.b, new.c);
! 482: END;
! 483: }]
! 484: } {}
! 485: do_test alter-3.3.2 {
! 486: execsql {
! 487: INSERT INTO tbl1 VALUES('a', 'b', 'c');
! 488: }
! 489: set ::TRIGGER
! 490: } {trig1 a b c}
! 491: do_test alter-3.3.3 {
! 492: execsql {
! 493: ALTER TABLE tbl1 RENAME TO tbl2;
! 494: INSERT INTO tbl2 VALUES('d', 'e', 'f');
! 495: }
! 496: set ::TRIGGER
! 497: } {trig1 d e f}
! 498: do_test alter-3.3.4 {
! 499: execsql [subst {
! 500: CREATE $::temp TRIGGER trig2 AFTER UPDATE ON tbl2 BEGIN
! 501: SELECT trigfunc('trig2', new.a, new.b, new.c);
! 502: END;
! 503: }]
! 504: } {}
! 505: do_test alter-3.3.5 {
! 506: execsql {
! 507: ALTER TABLE tbl2 RENAME TO tbl3;
! 508: INSERT INTO tbl3 VALUES('g', 'h', 'i');
! 509: }
! 510: set ::TRIGGER
! 511: } {trig1 g h i}
! 512: do_test alter-3.3.6 {
! 513: execsql {
! 514: UPDATE tbl3 SET a = 'G' where a = 'g';
! 515: }
! 516: set ::TRIGGER
! 517: } {trig2 G h i}
! 518: do_test alter-3.3.7 {
! 519: execsql {
! 520: DROP TABLE tbl3;
! 521: }
! 522: } {}
! 523: ifcapable tempdb {
! 524: do_test alter-3.3.8 {
! 525: execsql {
! 526: SELECT * FROM sqlite_temp_master WHERE type = 'trigger';
! 527: }
! 528: } {}
! 529: }
! 530:
! 531: } ;# ifcapable trigger
! 532:
! 533: # If the build does not include AUTOINCREMENT fields, omit alter-4.*.
! 534: ifcapable autoinc {
! 535:
! 536: do_test alter-4.1 {
! 537: execsql {
! 538: CREATE TABLE tbl1(a INTEGER PRIMARY KEY AUTOINCREMENT);
! 539: INSERT INTO tbl1 VALUES(10);
! 540: }
! 541: } {}
! 542: do_test alter-4.2 {
! 543: execsql {
! 544: INSERT INTO tbl1 VALUES(NULL);
! 545: SELECT a FROM tbl1;
! 546: }
! 547: } {10 11}
! 548: do_test alter-4.3 {
! 549: execsql {
! 550: ALTER TABLE tbl1 RENAME TO tbl2;
! 551: DELETE FROM tbl2;
! 552: INSERT INTO tbl2 VALUES(NULL);
! 553: SELECT a FROM tbl2;
! 554: }
! 555: } {12}
! 556: do_test alter-4.4 {
! 557: execsql {
! 558: DROP TABLE tbl2;
! 559: }
! 560: } {}
! 561:
! 562: } ;# ifcapable autoinc
! 563:
! 564: # Test that it is Ok to execute an ALTER TABLE immediately after
! 565: # opening a database.
! 566: do_test alter-5.1 {
! 567: execsql {
! 568: CREATE TABLE tbl1(a, b, c);
! 569: INSERT INTO tbl1 VALUES('x', 'y', 'z');
! 570: }
! 571: } {}
! 572: do_test alter-5.2 {
! 573: sqlite3 db2 test.db
! 574: execsql {
! 575: ALTER TABLE tbl1 RENAME TO tbl2;
! 576: SELECT * FROM tbl2;
! 577: } db2
! 578: } {x y z}
! 579: do_test alter-5.3 {
! 580: db2 close
! 581: } {}
! 582:
! 583: foreach tblname [execsql {
! 584: SELECT name FROM sqlite_master
! 585: WHERE type='table' AND name NOT GLOB 'sqlite*'
! 586: }] {
! 587: execsql "DROP TABLE \"$tblname\""
! 588: }
! 589:
! 590: set ::tbl_name "abc\uABCDdef"
! 591: do_test alter-6.1 {
! 592: string length $::tbl_name
! 593: } {7}
! 594: do_test alter-6.2 {
! 595: execsql "
! 596: CREATE TABLE ${tbl_name}(a, b, c);
! 597: "
! 598: set ::oid [execsql {SELECT max(oid) FROM sqlite_master}]
! 599: execsql "
! 600: SELECT sql FROM sqlite_master WHERE oid = $::oid;
! 601: "
! 602: } "{CREATE TABLE ${::tbl_name}(a, b, c)}"
! 603: execsql "
! 604: SELECT * FROM ${::tbl_name}
! 605: "
! 606: set ::tbl_name2 "abcXdef"
! 607: do_test alter-6.3 {
! 608: execsql "
! 609: ALTER TABLE $::tbl_name RENAME TO $::tbl_name2
! 610: "
! 611: execsql "
! 612: SELECT sql FROM sqlite_master WHERE oid = $::oid
! 613: "
! 614: } "{CREATE TABLE \"${::tbl_name2}\"(a, b, c)}"
! 615: do_test alter-6.4 {
! 616: execsql "
! 617: ALTER TABLE $::tbl_name2 RENAME TO $::tbl_name
! 618: "
! 619: execsql "
! 620: SELECT sql FROM sqlite_master WHERE oid = $::oid
! 621: "
! 622: } "{CREATE TABLE \"${::tbl_name}\"(a, b, c)}"
! 623: set ::col_name ghi\1234\jkl
! 624: do_test alter-6.5 {
! 625: execsql "
! 626: ALTER TABLE $::tbl_name ADD COLUMN $::col_name VARCHAR
! 627: "
! 628: execsql "
! 629: SELECT sql FROM sqlite_master WHERE oid = $::oid
! 630: "
! 631: } "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR)}"
! 632: set ::col_name2 B\3421\A
! 633: do_test alter-6.6 {
! 634: db close
! 635: sqlite3 db test.db
! 636: execsql "
! 637: ALTER TABLE $::tbl_name ADD COLUMN $::col_name2
! 638: "
! 639: execsql "
! 640: SELECT sql FROM sqlite_master WHERE oid = $::oid
! 641: "
! 642: } "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR, $::col_name2)}"
! 643: do_test alter-6.7 {
! 644: execsql "
! 645: INSERT INTO ${::tbl_name} VALUES(1, 2, 3, 4, 5);
! 646: SELECT $::col_name, $::col_name2 FROM $::tbl_name;
! 647: "
! 648: } {4 5}
! 649:
! 650: # Ticket #1665: Make sure ALTER TABLE ADD COLUMN works on a table
! 651: # that includes a COLLATE clause.
! 652: #
! 653: do_realnum_test alter-7.1 {
! 654: execsql {
! 655: CREATE TABLE t1(a TEXT COLLATE BINARY);
! 656: ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE;
! 657: INSERT INTO t1 VALUES(1,'-2');
! 658: INSERT INTO t1 VALUES(5.4e-08,'5.4e-08');
! 659: SELECT typeof(a), a, typeof(b), b FROM t1;
! 660: }
! 661: } {text 1 integer -2 text 5.4e-08 real 5.4e-08}
! 662:
! 663: # Make sure that when a column is added by ALTER TABLE ADD COLUMN and has
! 664: # a default value that the default value is used by aggregate functions.
! 665: #
! 666: do_test alter-8.1 {
! 667: execsql {
! 668: CREATE TABLE t2(a INTEGER);
! 669: INSERT INTO t2 VALUES(1);
! 670: INSERT INTO t2 VALUES(1);
! 671: INSERT INTO t2 VALUES(2);
! 672: ALTER TABLE t2 ADD COLUMN b INTEGER DEFAULT 9;
! 673: SELECT sum(b) FROM t2;
! 674: }
! 675: } {27}
! 676: do_test alter-8.2 {
! 677: execsql {
! 678: SELECT a, sum(b) FROM t2 GROUP BY a;
! 679: }
! 680: } {1 18 2 9}
! 681:
! 682: #--------------------------------------------------------------------------
! 683: # alter-9.X - Special test: Make sure the sqlite_rename_trigger() and
! 684: # rename_table() functions do not crash when handed bad input.
! 685: #
! 686: ifcapable trigger {
! 687: do_test alter-9.1 {
! 688: execsql {SELECT SQLITE_RENAME_TRIGGER(0,0)}
! 689: } {{}}
! 690: }
! 691: do_test alter-9.2 {
! 692: execsql {
! 693: SELECT SQLITE_RENAME_TABLE(0,0);
! 694: SELECT SQLITE_RENAME_TABLE(10,20);
! 695: SELECT SQLITE_RENAME_TABLE('foo', 'foo');
! 696: }
! 697: } {{} {} {}}
! 698:
! 699: #------------------------------------------------------------------------
! 700: # alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters
! 701: # in the names.
! 702: #
! 703: do_test alter-10.1 {
! 704: execsql "CREATE TABLE xyz(x UNIQUE)"
! 705: execsql "ALTER TABLE xyz RENAME TO xyz\u1234abc"
! 706: execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
! 707: } [list xyz\u1234abc]
! 708: do_test alter-10.2 {
! 709: execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
! 710: } [list sqlite_autoindex_xyz\u1234abc_1]
! 711: do_test alter-10.3 {
! 712: execsql "ALTER TABLE xyz\u1234abc RENAME TO xyzabc"
! 713: execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
! 714: } [list xyzabc]
! 715: do_test alter-10.4 {
! 716: execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
! 717: } [list sqlite_autoindex_xyzabc_1]
! 718:
! 719: do_test alter-11.1 {
! 720: sqlite3_exec db {CREATE TABLE t11(%c6%c6)}
! 721: execsql {
! 722: ALTER TABLE t11 ADD COLUMN abc;
! 723: }
! 724: catchsql {
! 725: ALTER TABLE t11 ADD COLUMN abc;
! 726: }
! 727: } {1 {duplicate column name: abc}}
! 728: set isutf16 [regexp 16 [db one {PRAGMA encoding}]]
! 729: if {!$isutf16} {
! 730: do_test alter-11.2 {
! 731: execsql {INSERT INTO t11 VALUES(1,2)}
! 732: sqlite3_exec db {SELECT %c6%c6 AS xyz, abc FROM t11}
! 733: } {0 {xyz abc 1 2}}
! 734: }
! 735: do_test alter-11.3 {
! 736: sqlite3_exec db {CREATE TABLE t11b("%81%82%83" text)}
! 737: execsql {
! 738: ALTER TABLE t11b ADD COLUMN abc;
! 739: }
! 740: catchsql {
! 741: ALTER TABLE t11b ADD COLUMN abc;
! 742: }
! 743: } {1 {duplicate column name: abc}}
! 744: if {!$isutf16} {
! 745: do_test alter-11.4 {
! 746: execsql {INSERT INTO t11b VALUES(3,4)}
! 747: sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11b}
! 748: } {0 {xyz abc 3 4}}
! 749: do_test alter-11.5 {
! 750: sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11b}
! 751: } {0 {xyz abc 3 4}}
! 752: do_test alter-11.6 {
! 753: sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11b}
! 754: } {0 {xyz abc 3 4}}
! 755: }
! 756: do_test alter-11.7 {
! 757: sqlite3_exec db {CREATE TABLE t11c(%81%82%83 text)}
! 758: execsql {
! 759: ALTER TABLE t11c ADD COLUMN abc;
! 760: }
! 761: catchsql {
! 762: ALTER TABLE t11c ADD COLUMN abc;
! 763: }
! 764: } {1 {duplicate column name: abc}}
! 765: if {!$isutf16} {
! 766: do_test alter-11.8 {
! 767: execsql {INSERT INTO t11c VALUES(5,6)}
! 768: sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11c}
! 769: } {0 {xyz abc 5 6}}
! 770: do_test alter-11.9 {
! 771: sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11c}
! 772: } {0 {xyz abc 5 6}}
! 773: do_test alter-11.10 {
! 774: sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11c}
! 775: } {0 {xyz abc 5 6}}
! 776: }
! 777:
! 778: do_test alter-12.1 {
! 779: execsql {
! 780: CREATE TABLE t12(a, b, c);
! 781: CREATE VIEW v1 AS SELECT * FROM t12;
! 782: }
! 783: } {}
! 784: do_test alter-12.2 {
! 785: catchsql {
! 786: ALTER TABLE v1 RENAME TO v2;
! 787: }
! 788: } {1 {view v1 may not be altered}}
! 789: do_test alter-12.3 {
! 790: execsql { SELECT * FROM v1; }
! 791: } {}
! 792: do_test alter-12.4 {
! 793: db close
! 794: sqlite3 db test.db
! 795: execsql { SELECT * FROM v1; }
! 796: } {}
! 797: do_test alter-12.5 {
! 798: catchsql {
! 799: ALTER TABLE v1 ADD COLUMN new_column;
! 800: }
! 801: } {1 {Cannot add a column to a view}}
! 802:
! 803: # Ticket #3102:
! 804: # Verify that comments do not interfere with the table rename
! 805: # algorithm.
! 806: #
! 807: do_test alter-13.1 {
! 808: execsql {
! 809: CREATE TABLE /* hi */ t3102a(x);
! 810: CREATE TABLE t3102b -- comment
! 811: (y);
! 812: CREATE INDEX t3102c ON t3102a(x);
! 813: SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
! 814: }
! 815: } {t3102a t3102b t3102c}
! 816: do_test alter-13.2 {
! 817: execsql {
! 818: ALTER TABLE t3102a RENAME TO t3102a_rename;
! 819: SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
! 820: }
! 821: } {t3102a_rename t3102b t3102c}
! 822: do_test alter-13.3 {
! 823: execsql {
! 824: ALTER TABLE t3102b RENAME TO t3102b_rename;
! 825: SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
! 826: }
! 827: } {t3102a_rename t3102b_rename t3102c}
! 828:
! 829: # Ticket #3651
! 830: do_test alter-14.1 {
! 831: catchsql {
! 832: CREATE TABLE t3651(a UNIQUE);
! 833: ALTER TABLE t3651 ADD COLUMN b UNIQUE;
! 834: }
! 835: } {1 {Cannot add a UNIQUE column}}
! 836: do_test alter-14.2 {
! 837: catchsql {
! 838: ALTER TABLE t3651 ADD COLUMN b PRIMARY KEY;
! 839: }
! 840: } {1 {Cannot add a PRIMARY KEY column}}
! 841:
! 842:
! 843: #-------------------------------------------------------------------------
! 844: # Test that it is not possible to use ALTER TABLE on any system table.
! 845: #
! 846: set system_table_list {1 sqlite_master}
! 847: catchsql ANALYZE
! 848: ifcapable analyze { lappend system_table_list 2 sqlite_stat1 }
! 849: ifcapable stat3 { lappend system_table_list 4 sqlite_stat3 }
! 850:
! 851: foreach {tn tbl} $system_table_list {
! 852: do_test alter-15.$tn.1 {
! 853: catchsql "ALTER TABLE $tbl RENAME TO xyz"
! 854: } [list 1 "table $tbl may not be altered"]
! 855:
! 856: do_test alter-15.$tn.2 {
! 857: catchsql "ALTER TABLE $tbl ADD COLUMN xyz"
! 858: } [list 1 "table $tbl may not be altered"]
! 859: }
! 860:
! 861:
! 862: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>