webengine/webkitutils/SqliteSymbian/alter.c
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     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 ** $Id: alter.c,v 1.21 2006/06/21 12:36:25 danielk1977 Exp $
       
    16 */
       
    17 #include "sqliteInt.h"
       
    18 #include <ctype.h>
       
    19 
       
    20 /*
       
    21 ** The code in this file only exists if we are not omitting the
       
    22 ** ALTER TABLE logic from the build.
       
    23 */
       
    24 #ifndef SQLITE_OMIT_ALTERTABLE
       
    25 
       
    26 
       
    27 /*
       
    28 ** This function is used by SQL generated to implement the 
       
    29 ** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
       
    30 ** CREATE INDEX command. The second is a table name. The table name in 
       
    31 ** the CREATE TABLE or CREATE INDEX statement is replaced with the second
       
    32 ** argument and the result returned. Examples:
       
    33 **
       
    34 ** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
       
    35 **     -> 'CREATE TABLE def(a, b, c)'
       
    36 **
       
    37 ** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
       
    38 **     -> 'CREATE INDEX i ON def(a, b, c)'
       
    39 */
       
    40 static void renameTableFunc(
       
    41   sqlite3_context *context,
       
    42   int argc,
       
    43   sqlite3_value **argv
       
    44 ){
       
    45   unsigned char const *zSql = sqlite3_value_text(argv[0]);
       
    46   unsigned char const *zTableName = sqlite3_value_text(argv[1]);
       
    47 
       
    48   int token;
       
    49   Token tname;
       
    50   unsigned char const *zCsr = zSql;
       
    51   int len = 0;
       
    52   char *zRet;
       
    53 
       
    54   /* The principle used to locate the table name in the CREATE TABLE 
       
    55   ** statement is that the table name is the first token that is immediatedly
       
    56   ** followed by a left parenthesis - TK_LP.
       
    57   */
       
    58   if( zSql ){
       
    59     do {
       
    60       /* Store the token that zCsr points to in tname. */
       
    61       tname.z = zCsr;
       
    62       tname.n = len;
       
    63 
       
    64       /* Advance zCsr to the next token. Store that token type in 'token',
       
    65       ** and it's length in 'len' (to be used next iteration of this loop).
       
    66       */
       
    67       do {
       
    68         zCsr += len;
       
    69         len = sqlite3GetToken(zCsr, &token);
       
    70       } while( token==TK_SPACE );
       
    71       assert( len>0 );
       
    72     } while( token!=TK_LP );
       
    73 
       
    74     zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql, 
       
    75        zTableName, tname.z+tname.n);
       
    76     sqlite3_result_text(context, zRet, -1, sqlite3FreeX);
       
    77   }
       
    78 }
       
    79 
       
    80 #ifndef SQLITE_OMIT_TRIGGER
       
    81 /* This function is used by SQL generated to implement the ALTER TABLE
       
    82 ** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER 
       
    83 ** statement. The second is a table name. The table name in the CREATE 
       
    84 ** TRIGGER statement is replaced with the second argument and the result 
       
    85 ** returned. This is analagous to renameTableFunc() above, except for CREATE
       
    86 ** TRIGGER, not CREATE INDEX and CREATE TABLE.
       
    87 */
       
    88 static void renameTriggerFunc(
       
    89   sqlite3_context *context,
       
    90   int argc,
       
    91   sqlite3_value **argv
       
    92 ){
       
    93   unsigned char const *zSql = sqlite3_value_text(argv[0]);
       
    94   unsigned char const *zTableName = sqlite3_value_text(argv[1]);
       
    95 
       
    96   int token;
       
    97   Token tname;
       
    98   int dist = 3;
       
    99   unsigned char const *zCsr = zSql;
       
   100   int len = 0;
       
   101   char *zRet;
       
   102 
       
   103   /* The principle used to locate the table name in the CREATE TRIGGER 
       
   104   ** statement is that the table name is the first token that is immediatedly
       
   105   ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
       
   106   ** of TK_WHEN, TK_BEGIN or TK_FOR.
       
   107   */
       
   108   if( zSql ){
       
   109     do {
       
   110       /* Store the token that zCsr points to in tname. */
       
   111       tname.z = zCsr;
       
   112       tname.n = len;
       
   113 
       
   114       /* Advance zCsr to the next token. Store that token type in 'token',
       
   115       ** and it's length in 'len' (to be used next iteration of this loop).
       
   116       */
       
   117       do {
       
   118         zCsr += len;
       
   119         len = sqlite3GetToken(zCsr, &token);
       
   120       }while( token==TK_SPACE );
       
   121       assert( len>0 );
       
   122 
       
   123       /* Variable 'dist' stores the number of tokens read since the most
       
   124       ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN 
       
   125       ** token is read and 'dist' equals 2, the condition stated above
       
   126       ** to be met.
       
   127       **
       
   128       ** Note that ON cannot be a database, table or column name, so
       
   129       ** there is no need to worry about syntax like 
       
   130       ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
       
   131       */
       
   132       dist++;
       
   133       if( token==TK_DOT || token==TK_ON ){
       
   134         dist = 0;
       
   135       }
       
   136     } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
       
   137 
       
   138     /* Variable tname now contains the token that is the old table-name
       
   139     ** in the CREATE TRIGGER statement.
       
   140     */
       
   141     zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql, 
       
   142        zTableName, tname.z+tname.n);
       
   143     sqlite3_result_text(context, zRet, -1, sqlite3FreeX);
       
   144   }
       
   145 }
       
   146 #endif   /* !SQLITE_OMIT_TRIGGER */
       
   147 
       
   148 /*
       
   149 ** Register built-in functions used to help implement ALTER TABLE
       
   150 */
       
   151 void sqlite3AlterFunctions(sqlite3 *db){
       
   152   static const struct {
       
   153      char *zName;
       
   154      signed char nArg;
       
   155      void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
       
   156   } aFuncs[] = {
       
   157     { "sqlite_rename_table",    2, renameTableFunc},
       
   158 #ifndef SQLITE_OMIT_TRIGGER
       
   159     { "sqlite_rename_trigger",  2, renameTriggerFunc},
       
   160 #endif
       
   161   };
       
   162   int i;
       
   163 
       
   164   for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
       
   165     sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
       
   166         SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0);
       
   167   }
       
   168 }
       
   169 
       
   170 /*
       
   171 ** Generate the text of a WHERE expression which can be used to select all
       
   172 ** temporary triggers on table pTab from the sqlite_temp_master table. If
       
   173 ** table pTab has no temporary triggers, or is itself stored in the 
       
   174 ** temporary database, NULL is returned.
       
   175 */
       
   176 static char *whereTempTriggers(Parse *pParse, Table *pTab){
       
   177   Trigger *pTrig;
       
   178   char *zWhere = 0;
       
   179   char *tmp = 0;
       
   180   const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */
       
   181 
       
   182   /* If the table is not located in the temp-db (in which case NULL is 
       
   183   ** returned, loop through the tables list of triggers. For each trigger
       
   184   ** that is not part of the temp-db schema, add a clause to the WHERE 
       
   185   ** expression being built up in zWhere.
       
   186   */
       
   187   if( pTab->pSchema!=pTempSchema ){
       
   188     for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
       
   189       if( pTrig->pSchema==pTempSchema ){
       
   190         if( !zWhere ){
       
   191           zWhere = sqlite3MPrintf("name=%Q", pTrig->name);
       
   192         }else{
       
   193           tmp = zWhere;
       
   194           zWhere = sqlite3MPrintf("%s OR name=%Q", zWhere, pTrig->name);
       
   195           sqliteFree(tmp);
       
   196         }
       
   197       }
       
   198     }
       
   199   }
       
   200   return zWhere;
       
   201 }
       
   202 
       
   203 /*
       
   204 ** Generate code to drop and reload the internal representation of table
       
   205 ** pTab from the database, including triggers and temporary triggers.
       
   206 ** Argument zName is the name of the table in the database schema at
       
   207 ** the time the generated code is executed. This can be different from
       
   208 ** pTab->zName if this function is being called to code part of an 
       
   209 ** "ALTER TABLE RENAME TO" statement.
       
   210 */
       
   211 static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
       
   212   Vdbe *v;
       
   213   char *zWhere;
       
   214   int iDb;                   /* Index of database containing pTab */
       
   215 #ifndef SQLITE_OMIT_TRIGGER
       
   216   Trigger *pTrig;
       
   217 #endif
       
   218 
       
   219   v = sqlite3GetVdbe(pParse);
       
   220   if( !v ) return;
       
   221   iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
       
   222   assert( iDb>=0 );
       
   223 
       
   224 #ifndef SQLITE_OMIT_TRIGGER
       
   225   /* Drop any table triggers from the internal schema. */
       
   226   for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){
       
   227     int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
       
   228     assert( iTrigDb==iDb || iTrigDb==1 );
       
   229     sqlite3VdbeOp3(v, OP_DropTrigger, iTrigDb, 0, pTrig->name, 0);
       
   230   }
       
   231 #endif
       
   232 
       
   233   /* Drop the table and index from the internal schema */
       
   234   sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
       
   235 
       
   236   /* Reload the table, index and permanent trigger schemas. */
       
   237   zWhere = sqlite3MPrintf("tbl_name=%Q", zName);
       
   238   if( !zWhere ) return;
       
   239   sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC);
       
   240 
       
   241 #ifndef SQLITE_OMIT_TRIGGER
       
   242   /* Now, if the table is not stored in the temp database, reload any temp 
       
   243   ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. 
       
   244   */
       
   245   if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
       
   246     sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zWhere, P3_DYNAMIC);
       
   247   }
       
   248 #endif
       
   249 }
       
   250 
       
   251 /*
       
   252 ** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" 
       
   253 ** command. 
       
   254 */
       
   255 void sqlite3AlterRenameTable(
       
   256   Parse *pParse,            /* Parser context. */
       
   257   SrcList *pSrc,            /* The table to rename. */
       
   258   Token *pName              /* The new table name. */
       
   259 ){
       
   260   int iDb;                  /* Database that contains the table */
       
   261   char *zDb;                /* Name of database iDb */
       
   262   Table *pTab;              /* Table being renamed */
       
   263   char *zName = 0;          /* NULL-terminated version of pName */ 
       
   264   sqlite3 *db = pParse->db; /* Database connection */
       
   265   Vdbe *v;
       
   266 #ifndef SQLITE_OMIT_TRIGGER
       
   267   char *zWhere = 0;         /* Where clause to locate temp triggers */
       
   268 #endif
       
   269   
       
   270   if( sqlite3MallocFailed() ) goto exit_rename_table;
       
   271   assert( pSrc->nSrc==1 );
       
   272 
       
   273   pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
       
   274   if( !pTab ) goto exit_rename_table;
       
   275 #ifndef SQLITE_OMIT_VIRTUALTABLE
       
   276   if( IsVirtual(pTab) ){
       
   277     sqlite3ErrorMsg(pParse, "virtual tables may not be altered");
       
   278     goto exit_rename_table;
       
   279   }
       
   280 #endif
       
   281   iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
       
   282   zDb = db->aDb[iDb].zName;
       
   283 
       
   284   /* Get a NULL terminated version of the new table name. */
       
   285   zName = sqlite3NameFromToken(pName);
       
   286   if( !zName ) goto exit_rename_table;
       
   287 
       
   288   /* Check that a table or index named 'zName' does not already exist
       
   289   ** in database iDb. If so, this is an error.
       
   290   */
       
   291   if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
       
   292     sqlite3ErrorMsg(pParse, 
       
   293         "there is already another table or index with this name: %s", zName);
       
   294     goto exit_rename_table;
       
   295   }
       
   296 
       
   297   /* Make sure it is not a system table being altered, or a reserved name
       
   298   ** that the table is being renamed to.
       
   299   */
       
   300   if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){
       
   301     sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
       
   302     goto exit_rename_table;
       
   303   }
       
   304   if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
       
   305     goto exit_rename_table;
       
   306   }
       
   307 
       
   308 #ifndef SQLITE_OMIT_AUTHORIZATION
       
   309   /* Invoke the authorization callback. */
       
   310   if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
       
   311     goto exit_rename_table;
       
   312   }
       
   313 #endif
       
   314 
       
   315   /* Begin a transaction and code the VerifyCookie for database iDb. 
       
   316   ** Then modify the schema cookie (since the ALTER TABLE modifies the
       
   317   ** schema).
       
   318   */
       
   319   v = sqlite3GetVdbe(pParse);
       
   320   if( v==0 ){
       
   321     goto exit_rename_table;
       
   322   }
       
   323   sqlite3BeginWriteOperation(pParse, 0, iDb);
       
   324   sqlite3ChangeCookie(db, v, iDb);
       
   325 
       
   326   /* Modify the sqlite_master table to use the new table name. */
       
   327   sqlite3NestedParse(pParse,
       
   328       "UPDATE %Q.%s SET "
       
   329 #ifdef SQLITE_OMIT_TRIGGER
       
   330           "sql = sqlite_rename_table(sql, %Q), "
       
   331 #else
       
   332           "sql = CASE "
       
   333             "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
       
   334             "ELSE sqlite_rename_table(sql, %Q) END, "
       
   335 #endif
       
   336           "tbl_name = %Q, "
       
   337           "name = CASE "
       
   338             "WHEN type='table' THEN %Q "
       
   339             "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
       
   340               "'sqlite_autoindex_' || %Q || substr(name, %d+18,10) "
       
   341             "ELSE name END "
       
   342       "WHERE tbl_name=%Q AND "
       
   343           "(type='table' OR type='index' OR type='trigger');", 
       
   344       zDb, SCHEMA_TABLE(iDb), zName, zName, zName, 
       
   345 #ifndef SQLITE_OMIT_TRIGGER
       
   346       zName,
       
   347 #endif
       
   348       zName, strlen(pTab->zName), pTab->zName
       
   349   );
       
   350 
       
   351 #ifndef SQLITE_OMIT_AUTOINCREMENT
       
   352   /* If the sqlite_sequence table exists in this database, then update 
       
   353   ** it with the new table name.
       
   354   */
       
   355   if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
       
   356     sqlite3NestedParse(pParse,
       
   357         "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q",
       
   358         zDb, zName, pTab->zName);
       
   359   }
       
   360 #endif
       
   361 
       
   362 #ifndef SQLITE_OMIT_TRIGGER
       
   363   /* If there are TEMP triggers on this table, modify the sqlite_temp_master
       
   364   ** table. Don't do this if the table being ALTERed is itself located in
       
   365   ** the temp database.
       
   366   */
       
   367   if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
       
   368     sqlite3NestedParse(pParse, 
       
   369         "UPDATE sqlite_temp_master SET "
       
   370             "sql = sqlite_rename_trigger(sql, %Q), "
       
   371             "tbl_name = %Q "
       
   372             "WHERE %s;", zName, zName, zWhere);
       
   373     sqliteFree(zWhere);
       
   374   }
       
   375 #endif
       
   376 
       
   377   /* Drop and reload the internal table schema. */
       
   378   reloadTableSchema(pParse, pTab, zName);
       
   379 
       
   380 exit_rename_table:
       
   381   sqlite3SrcListDelete(pSrc);
       
   382   sqliteFree(zName);
       
   383 }
       
   384 
       
   385 
       
   386 /*
       
   387 ** This function is called after an "ALTER TABLE ... ADD" statement
       
   388 ** has been parsed. Argument pColDef contains the text of the new
       
   389 ** column definition.
       
   390 **
       
   391 ** The Table structure pParse->pNewTable was extended to include
       
   392 ** the new column during parsing.
       
   393 */
       
   394 void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
       
   395   Table *pNew;              /* Copy of pParse->pNewTable */
       
   396   Table *pTab;              /* Table being altered */
       
   397   int iDb;                  /* Database number */
       
   398   const char *zDb;          /* Database name */
       
   399   const char *zTab;         /* Table name */
       
   400   char *zCol;               /* Null-terminated column definition */
       
   401   Column *pCol;             /* The new column */
       
   402   Expr *pDflt;              /* Default value for the new column */
       
   403 
       
   404   if( pParse->nErr ) return;
       
   405   pNew = pParse->pNewTable;
       
   406   assert( pNew );
       
   407 
       
   408   iDb = sqlite3SchemaToIndex(pParse->db, pNew->pSchema);
       
   409   zDb = pParse->db->aDb[iDb].zName;
       
   410   zTab = pNew->zName;
       
   411   pCol = &pNew->aCol[pNew->nCol-1];
       
   412   pDflt = pCol->pDflt;
       
   413   pTab = sqlite3FindTable(pParse->db, zTab, zDb);
       
   414   assert( pTab );
       
   415 
       
   416 #ifndef SQLITE_OMIT_AUTHORIZATION
       
   417   /* Invoke the authorization callback. */
       
   418   if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
       
   419     return;
       
   420   }
       
   421 #endif
       
   422 
       
   423   /* If the default value for the new column was specified with a 
       
   424   ** literal NULL, then set pDflt to 0. This simplifies checking
       
   425   ** for an SQL NULL default below.
       
   426   */
       
   427   if( pDflt && pDflt->op==TK_NULL ){
       
   428     pDflt = 0;
       
   429   }
       
   430 
       
   431   /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
       
   432   ** If there is a NOT NULL constraint, then the default value for the
       
   433   ** column must not be NULL.
       
   434   */
       
   435   if( pCol->isPrimKey ){
       
   436     sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
       
   437     return;
       
   438   }
       
   439   if( pNew->pIndex ){
       
   440     sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
       
   441     return;
       
   442   }
       
   443   if( pCol->notNull && !pDflt ){
       
   444     sqlite3ErrorMsg(pParse, 
       
   445         "Cannot add a NOT NULL column with default value NULL");
       
   446     return;
       
   447   }
       
   448 
       
   449   /* Ensure the default expression is something that sqlite3ValueFromExpr()
       
   450   ** can handle (i.e. not CURRENT_TIME etc.)
       
   451   */
       
   452   if( pDflt ){
       
   453     sqlite3_value *pVal;
       
   454     if( sqlite3ValueFromExpr(pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
       
   455       /* malloc() has failed */
       
   456       return;
       
   457     }
       
   458     if( !pVal ){
       
   459       sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
       
   460       return;
       
   461     }
       
   462     sqlite3ValueFree(pVal);
       
   463   }
       
   464 
       
   465   /* Modify the CREATE TABLE statement. */
       
   466   zCol = sqliteStrNDup((char*)pColDef->z, pColDef->n);
       
   467   if( zCol ){
       
   468     char *zEnd = &zCol[pColDef->n-1];
       
   469     while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){
       
   470       *zEnd-- = '\0';
       
   471     }
       
   472     sqlite3NestedParse(pParse, 
       
   473         "UPDATE %Q.%s SET "
       
   474           "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d,length(sql)) "
       
   475         "WHERE type = 'table' AND name = %Q", 
       
   476       zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
       
   477       zTab
       
   478     );
       
   479     sqliteFree(zCol);
       
   480   }
       
   481 
       
   482   /* If the default value of the new column is NULL, then set the file
       
   483   ** format to 2. If the default value of the new column is not NULL,
       
   484   ** the file format becomes 3.
       
   485   */
       
   486   sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);
       
   487 
       
   488   /* Reload the schema of the modified table. */
       
   489   reloadTableSchema(pParse, pTab, pTab->zName);
       
   490 }
       
   491 
       
   492 /*
       
   493 ** This function is called by the parser after the table-name in
       
   494 ** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument 
       
   495 ** pSrc is the full-name of the table being altered.
       
   496 **
       
   497 ** This routine makes a (partial) copy of the Table structure
       
   498 ** for the table being altered and sets Parse.pNewTable to point
       
   499 ** to it. Routines called by the parser as the column definition
       
   500 ** is parsed (i.e. sqlite3AddColumn()) add the new Column data to 
       
   501 ** the copy. The copy of the Table structure is deleted by tokenize.c 
       
   502 ** after parsing is finished.
       
   503 **
       
   504 ** Routine sqlite3AlterFinishAddColumn() will be called to complete
       
   505 ** coding the "ALTER TABLE ... ADD" statement.
       
   506 */
       
   507 void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
       
   508   Table *pNew;
       
   509   Table *pTab;
       
   510   Vdbe *v;
       
   511   int iDb;
       
   512   int i;
       
   513   int nAlloc;
       
   514 
       
   515   /* Look up the table being altered. */
       
   516   assert( pParse->pNewTable==0 );
       
   517   if( sqlite3MallocFailed() ) goto exit_begin_add_column;
       
   518   pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
       
   519   if( !pTab ) goto exit_begin_add_column;
       
   520 
       
   521 #ifndef SQLITE_OMIT_VIRTUALTABLE
       
   522   if( IsVirtual(pTab) ){
       
   523     sqlite3ErrorMsg(pParse, "virtual tables may not be altered");
       
   524     goto exit_begin_add_column;
       
   525   }
       
   526 #endif
       
   527 
       
   528   /* Make sure this is not an attempt to ALTER a view. */
       
   529   if( pTab->pSelect ){
       
   530     sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
       
   531     goto exit_begin_add_column;
       
   532   }
       
   533 
       
   534   assert( pTab->addColOffset>0 );
       
   535   iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
       
   536 
       
   537   /* Put a copy of the Table struct in Parse.pNewTable for the
       
   538   ** sqlite3AddColumn() function and friends to modify.
       
   539   */
       
   540   pNew = (Table *)sqliteMalloc(sizeof(Table));
       
   541   if( !pNew ) goto exit_begin_add_column;
       
   542   pParse->pNewTable = pNew;
       
   543   pNew->nRef = 1;
       
   544   pNew->nCol = pTab->nCol;
       
   545   assert( pNew->nCol>0 );
       
   546   nAlloc = (((pNew->nCol-1)/8)*8)+8;
       
   547   assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
       
   548   pNew->aCol = (Column *)sqliteMalloc(sizeof(Column)*nAlloc);
       
   549   pNew->zName = sqliteStrDup(pTab->zName);
       
   550   if( !pNew->aCol || !pNew->zName ){
       
   551     goto exit_begin_add_column;
       
   552   }
       
   553   memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
       
   554   for(i=0; i<pNew->nCol; i++){
       
   555     Column *pCol = &pNew->aCol[i];
       
   556     pCol->zName = sqliteStrDup(pCol->zName);
       
   557     pCol->zColl = 0;
       
   558     pCol->zType = 0;
       
   559     pCol->pDflt = 0;
       
   560   }
       
   561   pNew->pSchema = pParse->db->aDb[iDb].pSchema;
       
   562   pNew->addColOffset = pTab->addColOffset;
       
   563   pNew->nRef = 1;
       
   564 
       
   565   /* Begin a transaction and increment the schema cookie.  */
       
   566   sqlite3BeginWriteOperation(pParse, 0, iDb);
       
   567   v = sqlite3GetVdbe(pParse);
       
   568   if( !v ) goto exit_begin_add_column;
       
   569   sqlite3ChangeCookie(pParse->db, v, iDb);
       
   570 
       
   571 exit_begin_add_column:
       
   572   sqlite3SrcListDelete(pSrc);
       
   573   return;
       
   574 }
       
   575 #endif  /* SQLITE_ALTER_TABLE */