Annotation of embedaddon/sqlite3/src/alter.c, revision 1.1

1.1     ! misho       1: /*
        !             2: ** 2005 February 15
        !             3: **
        !             4: ** The author disclaims copyright to this source code.  In place of
        !             5: ** a legal notice, here is a blessing:
        !             6: **
        !             7: **    May you do good and not evil.
        !             8: **    May you find forgiveness for yourself and forgive others.
        !             9: **    May you share freely, never taking more than you give.
        !            10: **
        !            11: *************************************************************************
        !            12: ** This file contains C code routines that used to generate VDBE code
        !            13: ** that implements the ALTER TABLE command.
        !            14: */
        !            15: #include "sqliteInt.h"
        !            16: 
        !            17: /*
        !            18: ** The code in this file only exists if we are not omitting the
        !            19: ** ALTER TABLE logic from the build.
        !            20: */
        !            21: #ifndef SQLITE_OMIT_ALTERTABLE
        !            22: 
        !            23: 
        !            24: /*
        !            25: ** This function is used by SQL generated to implement the 
        !            26: ** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
        !            27: ** CREATE INDEX command. The second is a table name. The table name in 
        !            28: ** the CREATE TABLE or CREATE INDEX statement is replaced with the third
        !            29: ** argument and the result returned. Examples:
        !            30: **
        !            31: ** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
        !            32: **     -> 'CREATE TABLE def(a, b, c)'
        !            33: **
        !            34: ** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
        !            35: **     -> 'CREATE INDEX i ON def(a, b, c)'
        !            36: */
        !            37: static void renameTableFunc(
        !            38:   sqlite3_context *context,
        !            39:   int NotUsed,
        !            40:   sqlite3_value **argv
        !            41: ){
        !            42:   unsigned char const *zSql = sqlite3_value_text(argv[0]);
        !            43:   unsigned char const *zTableName = sqlite3_value_text(argv[1]);
        !            44: 
        !            45:   int token;
        !            46:   Token tname;
        !            47:   unsigned char const *zCsr = zSql;
        !            48:   int len = 0;
        !            49:   char *zRet;
        !            50: 
        !            51:   sqlite3 *db = sqlite3_context_db_handle(context);
        !            52: 
        !            53:   UNUSED_PARAMETER(NotUsed);
        !            54: 
        !            55:   /* The principle used to locate the table name in the CREATE TABLE 
        !            56:   ** statement is that the table name is the first non-space token that
        !            57:   ** is immediately followed by a TK_LP or TK_USING token.
        !            58:   */
        !            59:   if( zSql ){
        !            60:     do {
        !            61:       if( !*zCsr ){
        !            62:         /* Ran out of input before finding an opening bracket. Return NULL. */
        !            63:         return;
        !            64:       }
        !            65: 
        !            66:       /* Store the token that zCsr points to in tname. */
        !            67:       tname.z = (char*)zCsr;
        !            68:       tname.n = len;
        !            69: 
        !            70:       /* Advance zCsr to the next token. Store that token type in 'token',
        !            71:       ** and its length in 'len' (to be used next iteration of this loop).
        !            72:       */
        !            73:       do {
        !            74:         zCsr += len;
        !            75:         len = sqlite3GetToken(zCsr, &token);
        !            76:       } while( token==TK_SPACE );
        !            77:       assert( len>0 );
        !            78:     } while( token!=TK_LP && token!=TK_USING );
        !            79: 
        !            80:     zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, 
        !            81:        zTableName, tname.z+tname.n);
        !            82:     sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
        !            83:   }
        !            84: }
        !            85: 
        !            86: /*
        !            87: ** This C function implements an SQL user function that is used by SQL code
        !            88: ** generated by the ALTER TABLE ... RENAME command to modify the definition
        !            89: ** of any foreign key constraints that use the table being renamed as the 
        !            90: ** parent table. It is passed three arguments:
        !            91: **
        !            92: **   1) The complete text of the CREATE TABLE statement being modified,
        !            93: **   2) The old name of the table being renamed, and
        !            94: **   3) The new name of the table being renamed.
        !            95: **
        !            96: ** It returns the new CREATE TABLE statement. For example:
        !            97: **
        !            98: **   sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3')
        !            99: **       -> 'CREATE TABLE t1(a REFERENCES t3)'
        !           100: */
        !           101: #ifndef SQLITE_OMIT_FOREIGN_KEY
        !           102: static void renameParentFunc(
        !           103:   sqlite3_context *context,
        !           104:   int NotUsed,
        !           105:   sqlite3_value **argv
        !           106: ){
        !           107:   sqlite3 *db = sqlite3_context_db_handle(context);
        !           108:   char *zOutput = 0;
        !           109:   char *zResult;
        !           110:   unsigned char const *zInput = sqlite3_value_text(argv[0]);
        !           111:   unsigned char const *zOld = sqlite3_value_text(argv[1]);
        !           112:   unsigned char const *zNew = sqlite3_value_text(argv[2]);
        !           113: 
        !           114:   unsigned const char *z;         /* Pointer to token */
        !           115:   int n;                          /* Length of token z */
        !           116:   int token;                      /* Type of token */
        !           117: 
        !           118:   UNUSED_PARAMETER(NotUsed);
        !           119:   for(z=zInput; *z; z=z+n){
        !           120:     n = sqlite3GetToken(z, &token);
        !           121:     if( token==TK_REFERENCES ){
        !           122:       char *zParent;
        !           123:       do {
        !           124:         z += n;
        !           125:         n = sqlite3GetToken(z, &token);
        !           126:       }while( token==TK_SPACE );
        !           127: 
        !           128:       zParent = sqlite3DbStrNDup(db, (const char *)z, n);
        !           129:       if( zParent==0 ) break;
        !           130:       sqlite3Dequote(zParent);
        !           131:       if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
        !           132:         char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", 
        !           133:             (zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew
        !           134:         );
        !           135:         sqlite3DbFree(db, zOutput);
        !           136:         zOutput = zOut;
        !           137:         zInput = &z[n];
        !           138:       }
        !           139:       sqlite3DbFree(db, zParent);
        !           140:     }
        !           141:   }
        !           142: 
        !           143:   zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), 
        !           144:   sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC);
        !           145:   sqlite3DbFree(db, zOutput);
        !           146: }
        !           147: #endif
        !           148: 
        !           149: #ifndef SQLITE_OMIT_TRIGGER
        !           150: /* This function is used by SQL generated to implement the
        !           151: ** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER 
        !           152: ** statement. The second is a table name. The table name in the CREATE 
        !           153: ** TRIGGER statement is replaced with the third argument and the result 
        !           154: ** returned. This is analagous to renameTableFunc() above, except for CREATE
        !           155: ** TRIGGER, not CREATE INDEX and CREATE TABLE.
        !           156: */
        !           157: static void renameTriggerFunc(
        !           158:   sqlite3_context *context,
        !           159:   int NotUsed,
        !           160:   sqlite3_value **argv
        !           161: ){
        !           162:   unsigned char const *zSql = sqlite3_value_text(argv[0]);
        !           163:   unsigned char const *zTableName = sqlite3_value_text(argv[1]);
        !           164: 
        !           165:   int token;
        !           166:   Token tname;
        !           167:   int dist = 3;
        !           168:   unsigned char const *zCsr = zSql;
        !           169:   int len = 0;
        !           170:   char *zRet;
        !           171:   sqlite3 *db = sqlite3_context_db_handle(context);
        !           172: 
        !           173:   UNUSED_PARAMETER(NotUsed);
        !           174: 
        !           175:   /* The principle used to locate the table name in the CREATE TRIGGER 
        !           176:   ** statement is that the table name is the first token that is immediatedly
        !           177:   ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
        !           178:   ** of TK_WHEN, TK_BEGIN or TK_FOR.
        !           179:   */
        !           180:   if( zSql ){
        !           181:     do {
        !           182: 
        !           183:       if( !*zCsr ){
        !           184:         /* Ran out of input before finding the table name. Return NULL. */
        !           185:         return;
        !           186:       }
        !           187: 
        !           188:       /* Store the token that zCsr points to in tname. */
        !           189:       tname.z = (char*)zCsr;
        !           190:       tname.n = len;
        !           191: 
        !           192:       /* Advance zCsr to the next token. Store that token type in 'token',
        !           193:       ** and its length in 'len' (to be used next iteration of this loop).
        !           194:       */
        !           195:       do {
        !           196:         zCsr += len;
        !           197:         len = sqlite3GetToken(zCsr, &token);
        !           198:       }while( token==TK_SPACE );
        !           199:       assert( len>0 );
        !           200: 
        !           201:       /* Variable 'dist' stores the number of tokens read since the most
        !           202:       ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN 
        !           203:       ** token is read and 'dist' equals 2, the condition stated above
        !           204:       ** to be met.
        !           205:       **
        !           206:       ** Note that ON cannot be a database, table or column name, so
        !           207:       ** there is no need to worry about syntax like 
        !           208:       ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
        !           209:       */
        !           210:       dist++;
        !           211:       if( token==TK_DOT || token==TK_ON ){
        !           212:         dist = 0;
        !           213:       }
        !           214:     } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
        !           215: 
        !           216:     /* Variable tname now contains the token that is the old table-name
        !           217:     ** in the CREATE TRIGGER statement.
        !           218:     */
        !           219:     zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, 
        !           220:        zTableName, tname.z+tname.n);
        !           221:     sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
        !           222:   }
        !           223: }
        !           224: #endif   /* !SQLITE_OMIT_TRIGGER */
        !           225: 
        !           226: /*
        !           227: ** Register built-in functions used to help implement ALTER TABLE
        !           228: */
        !           229: void sqlite3AlterFunctions(void){
        !           230:   static SQLITE_WSD FuncDef aAlterTableFuncs[] = {
        !           231:     FUNCTION(sqlite_rename_table,   2, 0, 0, renameTableFunc),
        !           232: #ifndef SQLITE_OMIT_TRIGGER
        !           233:     FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
        !           234: #endif
        !           235: #ifndef SQLITE_OMIT_FOREIGN_KEY
        !           236:     FUNCTION(sqlite_rename_parent,  3, 0, 0, renameParentFunc),
        !           237: #endif
        !           238:   };
        !           239:   int i;
        !           240:   FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
        !           241:   FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs);
        !           242: 
        !           243:   for(i=0; i<ArraySize(aAlterTableFuncs); i++){
        !           244:     sqlite3FuncDefInsert(pHash, &aFunc[i]);
        !           245:   }
        !           246: }
        !           247: 
        !           248: /*
        !           249: ** This function is used to create the text of expressions of the form:
        !           250: **
        !           251: **   name=<constant1> OR name=<constant2> OR ...
        !           252: **
        !           253: ** If argument zWhere is NULL, then a pointer string containing the text 
        !           254: ** "name=<constant>" is returned, where <constant> is the quoted version
        !           255: ** of the string passed as argument zConstant. The returned buffer is
        !           256: ** allocated using sqlite3DbMalloc(). It is the responsibility of the
        !           257: ** caller to ensure that it is eventually freed.
        !           258: **
        !           259: ** If argument zWhere is not NULL, then the string returned is 
        !           260: ** "<where> OR name=<constant>", where <where> is the contents of zWhere.
        !           261: ** In this case zWhere is passed to sqlite3DbFree() before returning.
        !           262: ** 
        !           263: */
        !           264: static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){
        !           265:   char *zNew;
        !           266:   if( !zWhere ){
        !           267:     zNew = sqlite3MPrintf(db, "name=%Q", zConstant);
        !           268:   }else{
        !           269:     zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant);
        !           270:     sqlite3DbFree(db, zWhere);
        !           271:   }
        !           272:   return zNew;
        !           273: }
        !           274: 
        !           275: #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
        !           276: /*
        !           277: ** Generate the text of a WHERE expression which can be used to select all
        !           278: ** tables that have foreign key constraints that refer to table pTab (i.e.
        !           279: ** constraints for which pTab is the parent table) from the sqlite_master
        !           280: ** table.
        !           281: */
        !           282: static char *whereForeignKeys(Parse *pParse, Table *pTab){
        !           283:   FKey *p;
        !           284:   char *zWhere = 0;
        !           285:   for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
        !           286:     zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName);
        !           287:   }
        !           288:   return zWhere;
        !           289: }
        !           290: #endif
        !           291: 
        !           292: /*
        !           293: ** Generate the text of a WHERE expression which can be used to select all
        !           294: ** temporary triggers on table pTab from the sqlite_temp_master table. If
        !           295: ** table pTab has no temporary triggers, or is itself stored in the 
        !           296: ** temporary database, NULL is returned.
        !           297: */
        !           298: static char *whereTempTriggers(Parse *pParse, Table *pTab){
        !           299:   Trigger *pTrig;
        !           300:   char *zWhere = 0;
        !           301:   const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */
        !           302: 
        !           303:   /* If the table is not located in the temp-db (in which case NULL is 
        !           304:   ** returned, loop through the tables list of triggers. For each trigger
        !           305:   ** that is not part of the temp-db schema, add a clause to the WHERE 
        !           306:   ** expression being built up in zWhere.
        !           307:   */
        !           308:   if( pTab->pSchema!=pTempSchema ){
        !           309:     sqlite3 *db = pParse->db;
        !           310:     for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
        !           311:       if( pTrig->pSchema==pTempSchema ){
        !           312:         zWhere = whereOrName(db, zWhere, pTrig->zName);
        !           313:       }
        !           314:     }
        !           315:   }
        !           316:   if( zWhere ){
        !           317:     char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere);
        !           318:     sqlite3DbFree(pParse->db, zWhere);
        !           319:     zWhere = zNew;
        !           320:   }
        !           321:   return zWhere;
        !           322: }
        !           323: 
        !           324: /*
        !           325: ** Generate code to drop and reload the internal representation of table
        !           326: ** pTab from the database, including triggers and temporary triggers.
        !           327: ** Argument zName is the name of the table in the database schema at
        !           328: ** the time the generated code is executed. This can be different from
        !           329: ** pTab->zName if this function is being called to code part of an 
        !           330: ** "ALTER TABLE RENAME TO" statement.
        !           331: */
        !           332: static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
        !           333:   Vdbe *v;
        !           334:   char *zWhere;
        !           335:   int iDb;                   /* Index of database containing pTab */
        !           336: #ifndef SQLITE_OMIT_TRIGGER
        !           337:   Trigger *pTrig;
        !           338: #endif
        !           339: 
        !           340:   v = sqlite3GetVdbe(pParse);
        !           341:   if( NEVER(v==0) ) return;
        !           342:   assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
        !           343:   iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
        !           344:   assert( iDb>=0 );
        !           345: 
        !           346: #ifndef SQLITE_OMIT_TRIGGER
        !           347:   /* Drop any table triggers from the internal schema. */
        !           348:   for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
        !           349:     int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
        !           350:     assert( iTrigDb==iDb || iTrigDb==1 );
        !           351:     sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0);
        !           352:   }
        !           353: #endif
        !           354: 
        !           355:   /* Drop the table and index from the internal schema.  */
        !           356:   sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
        !           357: 
        !           358:   /* Reload the table, index and permanent trigger schemas. */
        !           359:   zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
        !           360:   if( !zWhere ) return;
        !           361:   sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
        !           362: 
        !           363: #ifndef SQLITE_OMIT_TRIGGER
        !           364:   /* Now, if the table is not stored in the temp database, reload any temp 
        !           365:   ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. 
        !           366:   */
        !           367:   if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
        !           368:     sqlite3VdbeAddParseSchemaOp(v, 1, zWhere);
        !           369:   }
        !           370: #endif
        !           371: }
        !           372: 
        !           373: /*
        !           374: ** Parameter zName is the name of a table that is about to be altered
        !           375: ** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
        !           376: ** If the table is a system table, this function leaves an error message
        !           377: ** in pParse->zErr (system tables may not be altered) and returns non-zero.
        !           378: **
        !           379: ** Or, if zName is not a system table, zero is returned.
        !           380: */
        !           381: static int isSystemTable(Parse *pParse, const char *zName){
        !           382:   if( sqlite3Strlen30(zName)>6 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
        !           383:     sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
        !           384:     return 1;
        !           385:   }
        !           386:   return 0;
        !           387: }
        !           388: 
        !           389: /*
        !           390: ** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" 
        !           391: ** command. 
        !           392: */
        !           393: void sqlite3AlterRenameTable(
        !           394:   Parse *pParse,            /* Parser context. */
        !           395:   SrcList *pSrc,            /* The table to rename. */
        !           396:   Token *pName              /* The new table name. */
        !           397: ){
        !           398:   int iDb;                  /* Database that contains the table */
        !           399:   char *zDb;                /* Name of database iDb */
        !           400:   Table *pTab;              /* Table being renamed */
        !           401:   char *zName = 0;          /* NULL-terminated version of pName */ 
        !           402:   sqlite3 *db = pParse->db; /* Database connection */
        !           403:   int nTabName;             /* Number of UTF-8 characters in zTabName */
        !           404:   const char *zTabName;     /* Original name of the table */
        !           405:   Vdbe *v;
        !           406: #ifndef SQLITE_OMIT_TRIGGER
        !           407:   char *zWhere = 0;         /* Where clause to locate temp triggers */
        !           408: #endif
        !           409:   VTable *pVTab = 0;        /* Non-zero if this is a v-tab with an xRename() */
        !           410:   int savedDbFlags;         /* Saved value of db->flags */
        !           411: 
        !           412:   savedDbFlags = db->flags;  
        !           413:   if( NEVER(db->mallocFailed) ) goto exit_rename_table;
        !           414:   assert( pSrc->nSrc==1 );
        !           415:   assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
        !           416: 
        !           417:   pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
        !           418:   if( !pTab ) goto exit_rename_table;
        !           419:   iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
        !           420:   zDb = db->aDb[iDb].zName;
        !           421:   db->flags |= SQLITE_PreferBuiltin;
        !           422: 
        !           423:   /* Get a NULL terminated version of the new table name. */
        !           424:   zName = sqlite3NameFromToken(db, pName);
        !           425:   if( !zName ) goto exit_rename_table;
        !           426: 
        !           427:   /* Check that a table or index named 'zName' does not already exist
        !           428:   ** in database iDb. If so, this is an error.
        !           429:   */
        !           430:   if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
        !           431:     sqlite3ErrorMsg(pParse, 
        !           432:         "there is already another table or index with this name: %s", zName);
        !           433:     goto exit_rename_table;
        !           434:   }
        !           435: 
        !           436:   /* Make sure it is not a system table being altered, or a reserved name
        !           437:   ** that the table is being renamed to.
        !           438:   */
        !           439:   if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
        !           440:     goto exit_rename_table;
        !           441:   }
        !           442:   if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto
        !           443:     exit_rename_table;
        !           444:   }
        !           445: 
        !           446: #ifndef SQLITE_OMIT_VIEW
        !           447:   if( pTab->pSelect ){
        !           448:     sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName);
        !           449:     goto exit_rename_table;
        !           450:   }
        !           451: #endif
        !           452: 
        !           453: #ifndef SQLITE_OMIT_AUTHORIZATION
        !           454:   /* Invoke the authorization callback. */
        !           455:   if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
        !           456:     goto exit_rename_table;
        !           457:   }
        !           458: #endif
        !           459: 
        !           460: #ifndef SQLITE_OMIT_VIRTUALTABLE
        !           461:   if( sqlite3ViewGetColumnNames(pParse, pTab) ){
        !           462:     goto exit_rename_table;
        !           463:   }
        !           464:   if( IsVirtual(pTab) ){
        !           465:     pVTab = sqlite3GetVTable(db, pTab);
        !           466:     if( pVTab->pVtab->pModule->xRename==0 ){
        !           467:       pVTab = 0;
        !           468:     }
        !           469:   }
        !           470: #endif
        !           471: 
        !           472:   /* Begin a transaction and code the VerifyCookie for database iDb. 
        !           473:   ** Then modify the schema cookie (since the ALTER TABLE modifies the
        !           474:   ** schema). Open a statement transaction if the table is a virtual
        !           475:   ** table.
        !           476:   */
        !           477:   v = sqlite3GetVdbe(pParse);
        !           478:   if( v==0 ){
        !           479:     goto exit_rename_table;
        !           480:   }
        !           481:   sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb);
        !           482:   sqlite3ChangeCookie(pParse, iDb);
        !           483: 
        !           484:   /* If this is a virtual table, invoke the xRename() function if
        !           485:   ** one is defined. The xRename() callback will modify the names
        !           486:   ** of any resources used by the v-table implementation (including other
        !           487:   ** SQLite tables) that are identified by the name of the virtual table.
        !           488:   */
        !           489: #ifndef SQLITE_OMIT_VIRTUALTABLE
        !           490:   if( pVTab ){
        !           491:     int i = ++pParse->nMem;
        !           492:     sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0);
        !           493:     sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
        !           494:     sqlite3MayAbort(pParse);
        !           495:   }
        !           496: #endif
        !           497: 
        !           498:   /* figure out how many UTF-8 characters are in zName */
        !           499:   zTabName = pTab->zName;
        !           500:   nTabName = sqlite3Utf8CharLen(zTabName, -1);
        !           501: 
        !           502: #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
        !           503:   if( db->flags&SQLITE_ForeignKeys ){
        !           504:     /* If foreign-key support is enabled, rewrite the CREATE TABLE 
        !           505:     ** statements corresponding to all child tables of foreign key constraints
        !           506:     ** for which the renamed table is the parent table.  */
        !           507:     if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){
        !           508:       sqlite3NestedParse(pParse, 
        !           509:           "UPDATE \"%w\".%s SET "
        !           510:               "sql = sqlite_rename_parent(sql, %Q, %Q) "
        !           511:               "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere);
        !           512:       sqlite3DbFree(db, zWhere);
        !           513:     }
        !           514:   }
        !           515: #endif
        !           516: 
        !           517:   /* Modify the sqlite_master table to use the new table name. */
        !           518:   sqlite3NestedParse(pParse,
        !           519:       "UPDATE %Q.%s SET "
        !           520: #ifdef SQLITE_OMIT_TRIGGER
        !           521:           "sql = sqlite_rename_table(sql, %Q), "
        !           522: #else
        !           523:           "sql = CASE "
        !           524:             "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
        !           525:             "ELSE sqlite_rename_table(sql, %Q) END, "
        !           526: #endif
        !           527:           "tbl_name = %Q, "
        !           528:           "name = CASE "
        !           529:             "WHEN type='table' THEN %Q "
        !           530:             "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
        !           531:              "'sqlite_autoindex_' || %Q || substr(name,%d+18) "
        !           532:             "ELSE name END "
        !           533:       "WHERE tbl_name=%Q AND "
        !           534:           "(type='table' OR type='index' OR type='trigger');", 
        !           535:       zDb, SCHEMA_TABLE(iDb), zName, zName, zName, 
        !           536: #ifndef SQLITE_OMIT_TRIGGER
        !           537:       zName,
        !           538: #endif
        !           539:       zName, nTabName, zTabName
        !           540:   );
        !           541: 
        !           542: #ifndef SQLITE_OMIT_AUTOINCREMENT
        !           543:   /* If the sqlite_sequence table exists in this database, then update 
        !           544:   ** it with the new table name.
        !           545:   */
        !           546:   if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
        !           547:     sqlite3NestedParse(pParse,
        !           548:         "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q",
        !           549:         zDb, zName, pTab->zName);
        !           550:   }
        !           551: #endif
        !           552: 
        !           553: #ifndef SQLITE_OMIT_TRIGGER
        !           554:   /* If there are TEMP triggers on this table, modify the sqlite_temp_master
        !           555:   ** table. Don't do this if the table being ALTERed is itself located in
        !           556:   ** the temp database.
        !           557:   */
        !           558:   if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
        !           559:     sqlite3NestedParse(pParse, 
        !           560:         "UPDATE sqlite_temp_master SET "
        !           561:             "sql = sqlite_rename_trigger(sql, %Q), "
        !           562:             "tbl_name = %Q "
        !           563:             "WHERE %s;", zName, zName, zWhere);
        !           564:     sqlite3DbFree(db, zWhere);
        !           565:   }
        !           566: #endif
        !           567: 
        !           568: #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
        !           569:   if( db->flags&SQLITE_ForeignKeys ){
        !           570:     FKey *p;
        !           571:     for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
        !           572:       Table *pFrom = p->pFrom;
        !           573:       if( pFrom!=pTab ){
        !           574:         reloadTableSchema(pParse, p->pFrom, pFrom->zName);
        !           575:       }
        !           576:     }
        !           577:   }
        !           578: #endif
        !           579: 
        !           580:   /* Drop and reload the internal table schema. */
        !           581:   reloadTableSchema(pParse, pTab, zName);
        !           582: 
        !           583: exit_rename_table:
        !           584:   sqlite3SrcListDelete(db, pSrc);
        !           585:   sqlite3DbFree(db, zName);
        !           586:   db->flags = savedDbFlags;
        !           587: }
        !           588: 
        !           589: 
        !           590: /*
        !           591: ** Generate code to make sure the file format number is at least minFormat.
        !           592: ** The generated code will increase the file format number if necessary.
        !           593: */
        !           594: void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
        !           595:   Vdbe *v;
        !           596:   v = sqlite3GetVdbe(pParse);
        !           597:   /* The VDBE should have been allocated before this routine is called.
        !           598:   ** If that allocation failed, we would have quit before reaching this
        !           599:   ** point */
        !           600:   if( ALWAYS(v) ){
        !           601:     int r1 = sqlite3GetTempReg(pParse);
        !           602:     int r2 = sqlite3GetTempReg(pParse);
        !           603:     int j1;
        !           604:     sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
        !           605:     sqlite3VdbeUsesBtree(v, iDb);
        !           606:     sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
        !           607:     j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
        !           608:     sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
        !           609:     sqlite3VdbeJumpHere(v, j1);
        !           610:     sqlite3ReleaseTempReg(pParse, r1);
        !           611:     sqlite3ReleaseTempReg(pParse, r2);
        !           612:   }
        !           613: }
        !           614: 
        !           615: /*
        !           616: ** This function is called after an "ALTER TABLE ... ADD" statement
        !           617: ** has been parsed. Argument pColDef contains the text of the new
        !           618: ** column definition.
        !           619: **
        !           620: ** The Table structure pParse->pNewTable was extended to include
        !           621: ** the new column during parsing.
        !           622: */
        !           623: void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
        !           624:   Table *pNew;              /* Copy of pParse->pNewTable */
        !           625:   Table *pTab;              /* Table being altered */
        !           626:   int iDb;                  /* Database number */
        !           627:   const char *zDb;          /* Database name */
        !           628:   const char *zTab;         /* Table name */
        !           629:   char *zCol;               /* Null-terminated column definition */
        !           630:   Column *pCol;             /* The new column */
        !           631:   Expr *pDflt;              /* Default value for the new column */
        !           632:   sqlite3 *db;              /* The database connection; */
        !           633: 
        !           634:   db = pParse->db;
        !           635:   if( pParse->nErr || db->mallocFailed ) return;
        !           636:   pNew = pParse->pNewTable;
        !           637:   assert( pNew );
        !           638: 
        !           639:   assert( sqlite3BtreeHoldsAllMutexes(db) );
        !           640:   iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
        !           641:   zDb = db->aDb[iDb].zName;
        !           642:   zTab = &pNew->zName[16];  /* Skip the "sqlite_altertab_" prefix on the name */
        !           643:   pCol = &pNew->aCol[pNew->nCol-1];
        !           644:   pDflt = pCol->pDflt;
        !           645:   pTab = sqlite3FindTable(db, zTab, zDb);
        !           646:   assert( pTab );
        !           647: 
        !           648: #ifndef SQLITE_OMIT_AUTHORIZATION
        !           649:   /* Invoke the authorization callback. */
        !           650:   if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
        !           651:     return;
        !           652:   }
        !           653: #endif
        !           654: 
        !           655:   /* If the default value for the new column was specified with a 
        !           656:   ** literal NULL, then set pDflt to 0. This simplifies checking
        !           657:   ** for an SQL NULL default below.
        !           658:   */
        !           659:   if( pDflt && pDflt->op==TK_NULL ){
        !           660:     pDflt = 0;
        !           661:   }
        !           662: 
        !           663:   /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
        !           664:   ** If there is a NOT NULL constraint, then the default value for the
        !           665:   ** column must not be NULL.
        !           666:   */
        !           667:   if( pCol->isPrimKey ){
        !           668:     sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
        !           669:     return;
        !           670:   }
        !           671:   if( pNew->pIndex ){
        !           672:     sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
        !           673:     return;
        !           674:   }
        !           675:   if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
        !           676:     sqlite3ErrorMsg(pParse, 
        !           677:         "Cannot add a REFERENCES column with non-NULL default value");
        !           678:     return;
        !           679:   }
        !           680:   if( pCol->notNull && !pDflt ){
        !           681:     sqlite3ErrorMsg(pParse, 
        !           682:         "Cannot add a NOT NULL column with default value NULL");
        !           683:     return;
        !           684:   }
        !           685: 
        !           686:   /* Ensure the default expression is something that sqlite3ValueFromExpr()
        !           687:   ** can handle (i.e. not CURRENT_TIME etc.)
        !           688:   */
        !           689:   if( pDflt ){
        !           690:     sqlite3_value *pVal;
        !           691:     if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
        !           692:       db->mallocFailed = 1;
        !           693:       return;
        !           694:     }
        !           695:     if( !pVal ){
        !           696:       sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
        !           697:       return;
        !           698:     }
        !           699:     sqlite3ValueFree(pVal);
        !           700:   }
        !           701: 
        !           702:   /* Modify the CREATE TABLE statement. */
        !           703:   zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
        !           704:   if( zCol ){
        !           705:     char *zEnd = &zCol[pColDef->n-1];
        !           706:     int savedDbFlags = db->flags;
        !           707:     while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
        !           708:       *zEnd-- = '\0';
        !           709:     }
        !           710:     db->flags |= SQLITE_PreferBuiltin;
        !           711:     sqlite3NestedParse(pParse, 
        !           712:         "UPDATE \"%w\".%s SET "
        !           713:           "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
        !           714:         "WHERE type = 'table' AND name = %Q", 
        !           715:       zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
        !           716:       zTab
        !           717:     );
        !           718:     sqlite3DbFree(db, zCol);
        !           719:     db->flags = savedDbFlags;
        !           720:   }
        !           721: 
        !           722:   /* If the default value of the new column is NULL, then set the file
        !           723:   ** format to 2. If the default value of the new column is not NULL,
        !           724:   ** the file format becomes 3.
        !           725:   */
        !           726:   sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);
        !           727: 
        !           728:   /* Reload the schema of the modified table. */
        !           729:   reloadTableSchema(pParse, pTab, pTab->zName);
        !           730: }
        !           731: 
        !           732: /*
        !           733: ** This function is called by the parser after the table-name in
        !           734: ** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument 
        !           735: ** pSrc is the full-name of the table being altered.
        !           736: **
        !           737: ** This routine makes a (partial) copy of the Table structure
        !           738: ** for the table being altered and sets Parse.pNewTable to point
        !           739: ** to it. Routines called by the parser as the column definition
        !           740: ** is parsed (i.e. sqlite3AddColumn()) add the new Column data to 
        !           741: ** the copy. The copy of the Table structure is deleted by tokenize.c 
        !           742: ** after parsing is finished.
        !           743: **
        !           744: ** Routine sqlite3AlterFinishAddColumn() will be called to complete
        !           745: ** coding the "ALTER TABLE ... ADD" statement.
        !           746: */
        !           747: void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
        !           748:   Table *pNew;
        !           749:   Table *pTab;
        !           750:   Vdbe *v;
        !           751:   int iDb;
        !           752:   int i;
        !           753:   int nAlloc;
        !           754:   sqlite3 *db = pParse->db;
        !           755: 
        !           756:   /* Look up the table being altered. */
        !           757:   assert( pParse->pNewTable==0 );
        !           758:   assert( sqlite3BtreeHoldsAllMutexes(db) );
        !           759:   if( db->mallocFailed ) goto exit_begin_add_column;
        !           760:   pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
        !           761:   if( !pTab ) goto exit_begin_add_column;
        !           762: 
        !           763: #ifndef SQLITE_OMIT_VIRTUALTABLE
        !           764:   if( IsVirtual(pTab) ){
        !           765:     sqlite3ErrorMsg(pParse, "virtual tables may not be altered");
        !           766:     goto exit_begin_add_column;
        !           767:   }
        !           768: #endif
        !           769: 
        !           770:   /* Make sure this is not an attempt to ALTER a view. */
        !           771:   if( pTab->pSelect ){
        !           772:     sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
        !           773:     goto exit_begin_add_column;
        !           774:   }
        !           775:   if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
        !           776:     goto exit_begin_add_column;
        !           777:   }
        !           778: 
        !           779:   assert( pTab->addColOffset>0 );
        !           780:   iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
        !           781: 
        !           782:   /* Put a copy of the Table struct in Parse.pNewTable for the
        !           783:   ** sqlite3AddColumn() function and friends to modify.  But modify
        !           784:   ** the name by adding an "sqlite_altertab_" prefix.  By adding this
        !           785:   ** prefix, we insure that the name will not collide with an existing
        !           786:   ** table because user table are not allowed to have the "sqlite_"
        !           787:   ** prefix on their name.
        !           788:   */
        !           789:   pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table));
        !           790:   if( !pNew ) goto exit_begin_add_column;
        !           791:   pParse->pNewTable = pNew;
        !           792:   pNew->nRef = 1;
        !           793:   pNew->nCol = pTab->nCol;
        !           794:   assert( pNew->nCol>0 );
        !           795:   nAlloc = (((pNew->nCol-1)/8)*8)+8;
        !           796:   assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
        !           797:   pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc);
        !           798:   pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName);
        !           799:   if( !pNew->aCol || !pNew->zName ){
        !           800:     db->mallocFailed = 1;
        !           801:     goto exit_begin_add_column;
        !           802:   }
        !           803:   memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
        !           804:   for(i=0; i<pNew->nCol; i++){
        !           805:     Column *pCol = &pNew->aCol[i];
        !           806:     pCol->zName = sqlite3DbStrDup(db, pCol->zName);
        !           807:     pCol->zColl = 0;
        !           808:     pCol->zType = 0;
        !           809:     pCol->pDflt = 0;
        !           810:     pCol->zDflt = 0;
        !           811:   }
        !           812:   pNew->pSchema = db->aDb[iDb].pSchema;
        !           813:   pNew->addColOffset = pTab->addColOffset;
        !           814:   pNew->nRef = 1;
        !           815: 
        !           816:   /* Begin a transaction and increment the schema cookie.  */
        !           817:   sqlite3BeginWriteOperation(pParse, 0, iDb);
        !           818:   v = sqlite3GetVdbe(pParse);
        !           819:   if( !v ) goto exit_begin_add_column;
        !           820:   sqlite3ChangeCookie(pParse, iDb);
        !           821: 
        !           822: exit_begin_add_column:
        !           823:   sqlite3SrcListDelete(db, pSrc);
        !           824:   return;
        !           825: }
        !           826: #endif  /* SQLITE_ALTER_TABLE */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>