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