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>