os/persistentdata/persistentstorage/sql/SQLite364/alter.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sql/SQLite364/alter.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,621 @@
     1.4 +/*
     1.5 +** 2005 February 15
     1.6 +**
     1.7 +** The author disclaims copyright to this source code.  In place of
     1.8 +** a legal notice, here is a blessing:
     1.9 +**
    1.10 +**    May you do good and not evil.
    1.11 +**    May you find forgiveness for yourself and forgive others.
    1.12 +**    May you share freely, never taking more than you give.
    1.13 +**
    1.14 +*************************************************************************
    1.15 +** This file contains C code routines that used to generate VDBE code
    1.16 +** that implements the ALTER TABLE command.
    1.17 +**
    1.18 +** $Id: alter.c,v 1.48 2008/08/08 14:19:41 drh Exp $
    1.19 +*/
    1.20 +#include "sqliteInt.h"
    1.21 +#include <ctype.h>
    1.22 +
    1.23 +/*
    1.24 +** The code in this file only exists if we are not omitting the
    1.25 +** ALTER TABLE logic from the build.
    1.26 +*/
    1.27 +#ifndef SQLITE_OMIT_ALTERTABLE
    1.28 +
    1.29 +
    1.30 +/*
    1.31 +** This function is used by SQL generated to implement the 
    1.32 +** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
    1.33 +** CREATE INDEX command. The second is a table name. The table name in 
    1.34 +** the CREATE TABLE or CREATE INDEX statement is replaced with the third
    1.35 +** argument and the result returned. Examples:
    1.36 +**
    1.37 +** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
    1.38 +**     -> 'CREATE TABLE def(a, b, c)'
    1.39 +**
    1.40 +** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
    1.41 +**     -> 'CREATE INDEX i ON def(a, b, c)'
    1.42 +*/
    1.43 +static void renameTableFunc(
    1.44 +  sqlite3_context *context,
    1.45 +  int argc,
    1.46 +  sqlite3_value **argv
    1.47 +){
    1.48 +  unsigned char const *zSql = sqlite3_value_text(argv[0]);
    1.49 +  unsigned char const *zTableName = sqlite3_value_text(argv[1]);
    1.50 +
    1.51 +  int token;
    1.52 +  Token tname;
    1.53 +  unsigned char const *zCsr = zSql;
    1.54 +  int len = 0;
    1.55 +  char *zRet;
    1.56 +
    1.57 +  sqlite3 *db = sqlite3_context_db_handle(context);
    1.58 +
    1.59 +  /* The principle used to locate the table name in the CREATE TABLE 
    1.60 +  ** statement is that the table name is the first non-space token that
    1.61 +  ** is immediately followed by a TK_LP or TK_USING token.
    1.62 +  */
    1.63 +  if( zSql ){
    1.64 +    do {
    1.65 +      if( !*zCsr ){
    1.66 +        /* Ran out of input before finding an opening bracket. Return NULL. */
    1.67 +        return;
    1.68 +      }
    1.69 +
    1.70 +      /* Store the token that zCsr points to in tname. */
    1.71 +      tname.z = zCsr;
    1.72 +      tname.n = len;
    1.73 +
    1.74 +      /* Advance zCsr to the next token. Store that token type in 'token',
    1.75 +      ** and its length in 'len' (to be used next iteration of this loop).
    1.76 +      */
    1.77 +      do {
    1.78 +        zCsr += len;
    1.79 +        len = sqlite3GetToken(zCsr, &token);
    1.80 +      } while( token==TK_SPACE );
    1.81 +      assert( len>0 );
    1.82 +    } while( token!=TK_LP && token!=TK_USING );
    1.83 +
    1.84 +    zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql, 
    1.85 +       zTableName, tname.z+tname.n);
    1.86 +    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
    1.87 +  }
    1.88 +}
    1.89 +
    1.90 +#ifndef SQLITE_OMIT_TRIGGER
    1.91 +/* This function is used by SQL generated to implement the
    1.92 +** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER 
    1.93 +** statement. The second is a table name. The table name in the CREATE 
    1.94 +** TRIGGER statement is replaced with the third argument and the result 
    1.95 +** returned. This is analagous to renameTableFunc() above, except for CREATE
    1.96 +** TRIGGER, not CREATE INDEX and CREATE TABLE.
    1.97 +*/
    1.98 +static void renameTriggerFunc(
    1.99 +  sqlite3_context *context,
   1.100 +  int argc,
   1.101 +  sqlite3_value **argv
   1.102 +){
   1.103 +  unsigned char const *zSql = sqlite3_value_text(argv[0]);
   1.104 +  unsigned char const *zTableName = sqlite3_value_text(argv[1]);
   1.105 +
   1.106 +  int token;
   1.107 +  Token tname;
   1.108 +  int dist = 3;
   1.109 +  unsigned char const *zCsr = zSql;
   1.110 +  int len = 0;
   1.111 +  char *zRet;
   1.112 +
   1.113 +  sqlite3 *db = sqlite3_context_db_handle(context);
   1.114 +
   1.115 +  /* The principle used to locate the table name in the CREATE TRIGGER 
   1.116 +  ** statement is that the table name is the first token that is immediatedly
   1.117 +  ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
   1.118 +  ** of TK_WHEN, TK_BEGIN or TK_FOR.
   1.119 +  */
   1.120 +  if( zSql ){
   1.121 +    do {
   1.122 +
   1.123 +      if( !*zCsr ){
   1.124 +        /* Ran out of input before finding the table name. Return NULL. */
   1.125 +        return;
   1.126 +      }
   1.127 +
   1.128 +      /* Store the token that zCsr points to in tname. */
   1.129 +      tname.z = zCsr;
   1.130 +      tname.n = len;
   1.131 +
   1.132 +      /* Advance zCsr to the next token. Store that token type in 'token',
   1.133 +      ** and its length in 'len' (to be used next iteration of this loop).
   1.134 +      */
   1.135 +      do {
   1.136 +        zCsr += len;
   1.137 +        len = sqlite3GetToken(zCsr, &token);
   1.138 +      }while( token==TK_SPACE );
   1.139 +      assert( len>0 );
   1.140 +
   1.141 +      /* Variable 'dist' stores the number of tokens read since the most
   1.142 +      ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN 
   1.143 +      ** token is read and 'dist' equals 2, the condition stated above
   1.144 +      ** to be met.
   1.145 +      **
   1.146 +      ** Note that ON cannot be a database, table or column name, so
   1.147 +      ** there is no need to worry about syntax like 
   1.148 +      ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
   1.149 +      */
   1.150 +      dist++;
   1.151 +      if( token==TK_DOT || token==TK_ON ){
   1.152 +        dist = 0;
   1.153 +      }
   1.154 +    } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
   1.155 +
   1.156 +    /* Variable tname now contains the token that is the old table-name
   1.157 +    ** in the CREATE TRIGGER statement.
   1.158 +    */
   1.159 +    zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql, 
   1.160 +       zTableName, tname.z+tname.n);
   1.161 +    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
   1.162 +  }
   1.163 +}
   1.164 +#endif   /* !SQLITE_OMIT_TRIGGER */
   1.165 +
   1.166 +/*
   1.167 +** Register built-in functions used to help implement ALTER TABLE
   1.168 +*/
   1.169 +void sqlite3AlterFunctions(sqlite3 *db){
   1.170 +  sqlite3CreateFunc(db, "sqlite_rename_table", 2, SQLITE_UTF8, 0,
   1.171 +                         renameTableFunc, 0, 0);
   1.172 +#ifndef SQLITE_OMIT_TRIGGER
   1.173 +  sqlite3CreateFunc(db, "sqlite_rename_trigger", 2, SQLITE_UTF8, 0,
   1.174 +                         renameTriggerFunc, 0, 0);
   1.175 +#endif
   1.176 +}
   1.177 +
   1.178 +/*
   1.179 +** Generate the text of a WHERE expression which can be used to select all
   1.180 +** temporary triggers on table pTab from the sqlite_temp_master table. If
   1.181 +** table pTab has no temporary triggers, or is itself stored in the 
   1.182 +** temporary database, NULL is returned.
   1.183 +*/
   1.184 +static char *whereTempTriggers(Parse *pParse, Table *pTab){
   1.185 +  Trigger *pTrig;
   1.186 +  char *zWhere = 0;
   1.187 +  char *tmp = 0;
   1.188 +  const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */
   1.189 +
   1.190 +  /* If the table is not located in the temp-db (in which case NULL is 
   1.191 +  ** returned, loop through the tables list of triggers. For each trigger
   1.192 +  ** that is not part of the temp-db schema, add a clause to the WHERE 
   1.193 +  ** expression being built up in zWhere.
   1.194 +  */
   1.195 +  if( pTab->pSchema!=pTempSchema ){
   1.196 +    sqlite3 *db = pParse->db;
   1.197 +    for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
   1.198 +      if( pTrig->pSchema==pTempSchema ){
   1.199 +        if( !zWhere ){
   1.200 +          zWhere = sqlite3MPrintf(db, "name=%Q", pTrig->name);
   1.201 +        }else{
   1.202 +          tmp = zWhere;
   1.203 +          zWhere = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, pTrig->name);
   1.204 +          sqlite3DbFree(db, tmp);
   1.205 +        }
   1.206 +      }
   1.207 +    }
   1.208 +  }
   1.209 +  return zWhere;
   1.210 +}
   1.211 +
   1.212 +/*
   1.213 +** Generate code to drop and reload the internal representation of table
   1.214 +** pTab from the database, including triggers and temporary triggers.
   1.215 +** Argument zName is the name of the table in the database schema at
   1.216 +** the time the generated code is executed. This can be different from
   1.217 +** pTab->zName if this function is being called to code part of an 
   1.218 +** "ALTER TABLE RENAME TO" statement.
   1.219 +*/
   1.220 +static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
   1.221 +  Vdbe *v;
   1.222 +  char *zWhere;
   1.223 +  int iDb;                   /* Index of database containing pTab */
   1.224 +#ifndef SQLITE_OMIT_TRIGGER
   1.225 +  Trigger *pTrig;
   1.226 +#endif
   1.227 +
   1.228 +  v = sqlite3GetVdbe(pParse);
   1.229 +  if( !v ) return;
   1.230 +  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
   1.231 +  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
   1.232 +  assert( iDb>=0 );
   1.233 +
   1.234 +#ifndef SQLITE_OMIT_TRIGGER
   1.235 +  /* Drop any table triggers from the internal schema. */
   1.236 +  for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){
   1.237 +    int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
   1.238 +    assert( iTrigDb==iDb || iTrigDb==1 );
   1.239 +    sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->name, 0);
   1.240 +  }
   1.241 +#endif
   1.242 +
   1.243 +  /* Drop the table and index from the internal schema */
   1.244 +  sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
   1.245 +
   1.246 +  /* Reload the table, index and permanent trigger schemas. */
   1.247 +  zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
   1.248 +  if( !zWhere ) return;
   1.249 +  sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
   1.250 +
   1.251 +#ifndef SQLITE_OMIT_TRIGGER
   1.252 +  /* Now, if the table is not stored in the temp database, reload any temp 
   1.253 +  ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. 
   1.254 +  */
   1.255 +  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
   1.256 +    sqlite3VdbeAddOp4(v, OP_ParseSchema, 1, 0, 0, zWhere, P4_DYNAMIC);
   1.257 +  }
   1.258 +#endif
   1.259 +}
   1.260 +
   1.261 +/*
   1.262 +** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" 
   1.263 +** command. 
   1.264 +*/
   1.265 +void sqlite3AlterRenameTable(
   1.266 +  Parse *pParse,            /* Parser context. */
   1.267 +  SrcList *pSrc,            /* The table to rename. */
   1.268 +  Token *pName              /* The new table name. */
   1.269 +){
   1.270 +  int iDb;                  /* Database that contains the table */
   1.271 +  char *zDb;                /* Name of database iDb */
   1.272 +  Table *pTab;              /* Table being renamed */
   1.273 +  char *zName = 0;          /* NULL-terminated version of pName */ 
   1.274 +  sqlite3 *db = pParse->db; /* Database connection */
   1.275 +  int nTabName;             /* Number of UTF-8 characters in zTabName */
   1.276 +  const char *zTabName;     /* Original name of the table */
   1.277 +  Vdbe *v;
   1.278 +#ifndef SQLITE_OMIT_TRIGGER
   1.279 +  char *zWhere = 0;         /* Where clause to locate temp triggers */
   1.280 +#endif
   1.281 +  int isVirtualRename = 0;  /* True if this is a v-table with an xRename() */
   1.282 +  
   1.283 +  if( db->mallocFailed ) goto exit_rename_table;
   1.284 +  assert( pSrc->nSrc==1 );
   1.285 +  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
   1.286 +
   1.287 +  pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
   1.288 +  if( !pTab ) goto exit_rename_table;
   1.289 +  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
   1.290 +  zDb = db->aDb[iDb].zName;
   1.291 +
   1.292 +  /* Get a NULL terminated version of the new table name. */
   1.293 +  zName = sqlite3NameFromToken(db, pName);
   1.294 +  if( !zName ) goto exit_rename_table;
   1.295 +
   1.296 +  /* Check that a table or index named 'zName' does not already exist
   1.297 +  ** in database iDb. If so, this is an error.
   1.298 +  */
   1.299 +  if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
   1.300 +    sqlite3ErrorMsg(pParse, 
   1.301 +        "there is already another table or index with this name: %s", zName);
   1.302 +    goto exit_rename_table;
   1.303 +  }
   1.304 +
   1.305 +  /* Make sure it is not a system table being altered, or a reserved name
   1.306 +  ** that the table is being renamed to.
   1.307 +  */
   1.308 +  if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){
   1.309 +    sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
   1.310 +    goto exit_rename_table;
   1.311 +  }
   1.312 +  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
   1.313 +    goto exit_rename_table;
   1.314 +  }
   1.315 +
   1.316 +#ifndef SQLITE_OMIT_VIEW
   1.317 +  if( pTab->pSelect ){
   1.318 +    sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName);
   1.319 +    goto exit_rename_table;
   1.320 +  }
   1.321 +#endif
   1.322 +
   1.323 +#ifndef SQLITE_OMIT_AUTHORIZATION
   1.324 +  /* Invoke the authorization callback. */
   1.325 +  if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
   1.326 +    goto exit_rename_table;
   1.327 +  }
   1.328 +#endif
   1.329 +
   1.330 +#ifndef SQLITE_OMIT_VIRTUALTABLE
   1.331 +  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
   1.332 +    goto exit_rename_table;
   1.333 +  }
   1.334 +  if( IsVirtual(pTab) && pTab->pMod->pModule->xRename ){
   1.335 +    isVirtualRename = 1;
   1.336 +  }
   1.337 +#endif
   1.338 +
   1.339 +  /* Begin a transaction and code the VerifyCookie for database iDb. 
   1.340 +  ** Then modify the schema cookie (since the ALTER TABLE modifies the
   1.341 +  ** schema). Open a statement transaction if the table is a virtual
   1.342 +  ** table.
   1.343 +  */
   1.344 +  v = sqlite3GetVdbe(pParse);
   1.345 +  if( v==0 ){
   1.346 +    goto exit_rename_table;
   1.347 +  }
   1.348 +  sqlite3BeginWriteOperation(pParse, isVirtualRename, iDb);
   1.349 +  sqlite3ChangeCookie(pParse, iDb);
   1.350 +
   1.351 +  /* If this is a virtual table, invoke the xRename() function if
   1.352 +  ** one is defined. The xRename() callback will modify the names
   1.353 +  ** of any resources used by the v-table implementation (including other
   1.354 +  ** SQLite tables) that are identified by the name of the virtual table.
   1.355 +  */
   1.356 +#ifndef SQLITE_OMIT_VIRTUALTABLE
   1.357 +  if( isVirtualRename ){
   1.358 +    int i = ++pParse->nMem;
   1.359 +    sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0);
   1.360 +    sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pTab->pVtab, P4_VTAB);
   1.361 +  }
   1.362 +#endif
   1.363 +
   1.364 +  /* figure out how many UTF-8 characters are in zName */
   1.365 +  zTabName = pTab->zName;
   1.366 +  nTabName = sqlite3Utf8CharLen(zTabName, -1);
   1.367 +
   1.368 +  /* Modify the sqlite_master table to use the new table name. */
   1.369 +  sqlite3NestedParse(pParse,
   1.370 +      "UPDATE %Q.%s SET "
   1.371 +#ifdef SQLITE_OMIT_TRIGGER
   1.372 +          "sql = sqlite_rename_table(sql, %Q), "
   1.373 +#else
   1.374 +          "sql = CASE "
   1.375 +            "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
   1.376 +            "ELSE sqlite_rename_table(sql, %Q) END, "
   1.377 +#endif
   1.378 +          "tbl_name = %Q, "
   1.379 +          "name = CASE "
   1.380 +            "WHEN type='table' THEN %Q "
   1.381 +            "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
   1.382 +             "'sqlite_autoindex_' || %Q || substr(name,%d+18) "
   1.383 +            "ELSE name END "
   1.384 +      "WHERE tbl_name=%Q AND "
   1.385 +          "(type='table' OR type='index' OR type='trigger');", 
   1.386 +      zDb, SCHEMA_TABLE(iDb), zName, zName, zName, 
   1.387 +#ifndef SQLITE_OMIT_TRIGGER
   1.388 +      zName,
   1.389 +#endif
   1.390 +      zName, nTabName, zTabName
   1.391 +  );
   1.392 +
   1.393 +#ifndef SQLITE_OMIT_AUTOINCREMENT
   1.394 +  /* If the sqlite_sequence table exists in this database, then update 
   1.395 +  ** it with the new table name.
   1.396 +  */
   1.397 +  if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
   1.398 +    sqlite3NestedParse(pParse,
   1.399 +        "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q",
   1.400 +        zDb, zName, pTab->zName);
   1.401 +  }
   1.402 +#endif
   1.403 +
   1.404 +#ifndef SQLITE_OMIT_TRIGGER
   1.405 +  /* If there are TEMP triggers on this table, modify the sqlite_temp_master
   1.406 +  ** table. Don't do this if the table being ALTERed is itself located in
   1.407 +  ** the temp database.
   1.408 +  */
   1.409 +  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
   1.410 +    sqlite3NestedParse(pParse, 
   1.411 +        "UPDATE sqlite_temp_master SET "
   1.412 +            "sql = sqlite_rename_trigger(sql, %Q), "
   1.413 +            "tbl_name = %Q "
   1.414 +            "WHERE %s;", zName, zName, zWhere);
   1.415 +    sqlite3DbFree(db, zWhere);
   1.416 +  }
   1.417 +#endif
   1.418 +
   1.419 +  /* Drop and reload the internal table schema. */
   1.420 +  reloadTableSchema(pParse, pTab, zName);
   1.421 +
   1.422 +exit_rename_table:
   1.423 +  sqlite3SrcListDelete(db, pSrc);
   1.424 +  sqlite3DbFree(db, zName);
   1.425 +}
   1.426 +
   1.427 +
   1.428 +/*
   1.429 +** This function is called after an "ALTER TABLE ... ADD" statement
   1.430 +** has been parsed. Argument pColDef contains the text of the new
   1.431 +** column definition.
   1.432 +**
   1.433 +** The Table structure pParse->pNewTable was extended to include
   1.434 +** the new column during parsing.
   1.435 +*/
   1.436 +void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
   1.437 +  Table *pNew;              /* Copy of pParse->pNewTable */
   1.438 +  Table *pTab;              /* Table being altered */
   1.439 +  int iDb;                  /* Database number */
   1.440 +  const char *zDb;          /* Database name */
   1.441 +  const char *zTab;         /* Table name */
   1.442 +  char *zCol;               /* Null-terminated column definition */
   1.443 +  Column *pCol;             /* The new column */
   1.444 +  Expr *pDflt;              /* Default value for the new column */
   1.445 +  sqlite3 *db;              /* The database connection; */
   1.446 +
   1.447 +  if( pParse->nErr ) return;
   1.448 +  pNew = pParse->pNewTable;
   1.449 +  assert( pNew );
   1.450 +
   1.451 +  db = pParse->db;
   1.452 +  assert( sqlite3BtreeHoldsAllMutexes(db) );
   1.453 +  iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
   1.454 +  zDb = db->aDb[iDb].zName;
   1.455 +  zTab = pNew->zName;
   1.456 +  pCol = &pNew->aCol[pNew->nCol-1];
   1.457 +  pDflt = pCol->pDflt;
   1.458 +  pTab = sqlite3FindTable(db, zTab, zDb);
   1.459 +  assert( pTab );
   1.460 +
   1.461 +#ifndef SQLITE_OMIT_AUTHORIZATION
   1.462 +  /* Invoke the authorization callback. */
   1.463 +  if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
   1.464 +    return;
   1.465 +  }
   1.466 +#endif
   1.467 +
   1.468 +  /* If the default value for the new column was specified with a 
   1.469 +  ** literal NULL, then set pDflt to 0. This simplifies checking
   1.470 +  ** for an SQL NULL default below.
   1.471 +  */
   1.472 +  if( pDflt && pDflt->op==TK_NULL ){
   1.473 +    pDflt = 0;
   1.474 +  }
   1.475 +
   1.476 +  /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
   1.477 +  ** If there is a NOT NULL constraint, then the default value for the
   1.478 +  ** column must not be NULL.
   1.479 +  */
   1.480 +  if( pCol->isPrimKey ){
   1.481 +    sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
   1.482 +    return;
   1.483 +  }
   1.484 +  if( pNew->pIndex ){
   1.485 +    sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
   1.486 +    return;
   1.487 +  }
   1.488 +  if( pCol->notNull && !pDflt ){
   1.489 +    sqlite3ErrorMsg(pParse, 
   1.490 +        "Cannot add a NOT NULL column with default value NULL");
   1.491 +    return;
   1.492 +  }
   1.493 +
   1.494 +  /* Ensure the default expression is something that sqlite3ValueFromExpr()
   1.495 +  ** can handle (i.e. not CURRENT_TIME etc.)
   1.496 +  */
   1.497 +  if( pDflt ){
   1.498 +    sqlite3_value *pVal;
   1.499 +    if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
   1.500 +      db->mallocFailed = 1;
   1.501 +      return;
   1.502 +    }
   1.503 +    if( !pVal ){
   1.504 +      sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
   1.505 +      return;
   1.506 +    }
   1.507 +    sqlite3ValueFree(pVal);
   1.508 +  }
   1.509 +
   1.510 +  /* Modify the CREATE TABLE statement. */
   1.511 +  zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
   1.512 +  if( zCol ){
   1.513 +    char *zEnd = &zCol[pColDef->n-1];
   1.514 +    while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){
   1.515 +      *zEnd-- = '\0';
   1.516 +    }
   1.517 +    sqlite3NestedParse(pParse, 
   1.518 +        "UPDATE \"%w\".%s SET "
   1.519 +          "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
   1.520 +        "WHERE type = 'table' AND name = %Q", 
   1.521 +      zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
   1.522 +      zTab
   1.523 +    );
   1.524 +    sqlite3DbFree(db, zCol);
   1.525 +  }
   1.526 +
   1.527 +  /* If the default value of the new column is NULL, then set the file
   1.528 +  ** format to 2. If the default value of the new column is not NULL,
   1.529 +  ** the file format becomes 3.
   1.530 +  */
   1.531 +  sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);
   1.532 +
   1.533 +  /* Reload the schema of the modified table. */
   1.534 +  reloadTableSchema(pParse, pTab, pTab->zName);
   1.535 +}
   1.536 +
   1.537 +/*
   1.538 +** This function is called by the parser after the table-name in
   1.539 +** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument 
   1.540 +** pSrc is the full-name of the table being altered.
   1.541 +**
   1.542 +** This routine makes a (partial) copy of the Table structure
   1.543 +** for the table being altered and sets Parse.pNewTable to point
   1.544 +** to it. Routines called by the parser as the column definition
   1.545 +** is parsed (i.e. sqlite3AddColumn()) add the new Column data to 
   1.546 +** the copy. The copy of the Table structure is deleted by tokenize.c 
   1.547 +** after parsing is finished.
   1.548 +**
   1.549 +** Routine sqlite3AlterFinishAddColumn() will be called to complete
   1.550 +** coding the "ALTER TABLE ... ADD" statement.
   1.551 +*/
   1.552 +void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
   1.553 +  Table *pNew;
   1.554 +  Table *pTab;
   1.555 +  Vdbe *v;
   1.556 +  int iDb;
   1.557 +  int i;
   1.558 +  int nAlloc;
   1.559 +  sqlite3 *db = pParse->db;
   1.560 +
   1.561 +  /* Look up the table being altered. */
   1.562 +  assert( pParse->pNewTable==0 );
   1.563 +  assert( sqlite3BtreeHoldsAllMutexes(db) );
   1.564 +  if( db->mallocFailed ) goto exit_begin_add_column;
   1.565 +  pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
   1.566 +  if( !pTab ) goto exit_begin_add_column;
   1.567 +
   1.568 +#ifndef SQLITE_OMIT_VIRTUALTABLE
   1.569 +  if( IsVirtual(pTab) ){
   1.570 +    sqlite3ErrorMsg(pParse, "virtual tables may not be altered");
   1.571 +    goto exit_begin_add_column;
   1.572 +  }
   1.573 +#endif
   1.574 +
   1.575 +  /* Make sure this is not an attempt to ALTER a view. */
   1.576 +  if( pTab->pSelect ){
   1.577 +    sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
   1.578 +    goto exit_begin_add_column;
   1.579 +  }
   1.580 +
   1.581 +  assert( pTab->addColOffset>0 );
   1.582 +  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
   1.583 +
   1.584 +  /* Put a copy of the Table struct in Parse.pNewTable for the
   1.585 +  ** sqlite3AddColumn() function and friends to modify.
   1.586 +  */
   1.587 +  pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table));
   1.588 +  if( !pNew ) goto exit_begin_add_column;
   1.589 +  pParse->pNewTable = pNew;
   1.590 +  pNew->nRef = 1;
   1.591 +  pNew->db = db;
   1.592 +  pNew->nCol = pTab->nCol;
   1.593 +  assert( pNew->nCol>0 );
   1.594 +  nAlloc = (((pNew->nCol-1)/8)*8)+8;
   1.595 +  assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
   1.596 +  pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc);
   1.597 +  pNew->zName = sqlite3DbStrDup(db, pTab->zName);
   1.598 +  if( !pNew->aCol || !pNew->zName ){
   1.599 +    db->mallocFailed = 1;
   1.600 +    goto exit_begin_add_column;
   1.601 +  }
   1.602 +  memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
   1.603 +  for(i=0; i<pNew->nCol; i++){
   1.604 +    Column *pCol = &pNew->aCol[i];
   1.605 +    pCol->zName = sqlite3DbStrDup(db, pCol->zName);
   1.606 +    pCol->zColl = 0;
   1.607 +    pCol->zType = 0;
   1.608 +    pCol->pDflt = 0;
   1.609 +  }
   1.610 +  pNew->pSchema = db->aDb[iDb].pSchema;
   1.611 +  pNew->addColOffset = pTab->addColOffset;
   1.612 +  pNew->nRef = 1;
   1.613 +
   1.614 +  /* Begin a transaction and increment the schema cookie.  */
   1.615 +  sqlite3BeginWriteOperation(pParse, 0, iDb);
   1.616 +  v = sqlite3GetVdbe(pParse);
   1.617 +  if( !v ) goto exit_begin_add_column;
   1.618 +  sqlite3ChangeCookie(pParse, iDb);
   1.619 +
   1.620 +exit_begin_add_column:
   1.621 +  sqlite3SrcListDelete(db, pSrc);
   1.622 +  return;
   1.623 +}
   1.624 +#endif  /* SQLITE_ALTER_TABLE */