ds@1952: /* ds@1952: ** 2005 February 15 ds@1952: ** ds@1952: ** The author disclaims copyright to this source code. In place of ds@1952: ** a legal notice, here is a blessing: ds@1952: ** ds@1952: ** May you do good and not evil. ds@1952: ** May you find forgiveness for yourself and forgive others. ds@1952: ** May you share freely, never taking more than you give. ds@1952: ** ds@1952: ************************************************************************* ds@1952: ** This file contains C code routines that used to generate VDBE code ds@1952: ** that implements the ALTER TABLE command. ds@1952: ** ds@1952: ** $Id$ ds@1952: */ ds@1952: #include "sqliteInt.h" ds@1952: #include ds@1952: ds@1952: /* ds@1952: ** The code in this file only exists if we are not omitting the ds@1952: ** ALTER TABLE logic from the build. ds@1952: */ ds@1952: #ifndef SQLITE_OMIT_ALTERTABLE ds@1952: ds@1952: ds@1952: /* ds@1952: ** This function is used by SQL generated to implement the ds@1952: ** ALTER TABLE command. The first argument is the text of a CREATE TABLE or ds@1952: ** CREATE INDEX command. The second is a table name. The table name in ds@1952: ** the CREATE TABLE or CREATE INDEX statement is replaced with the third ds@1952: ** argument and the result returned. Examples: ds@1952: ** ds@1952: ** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def') ds@1952: ** -> 'CREATE TABLE def(a, b, c)' ds@1952: ** ds@1952: ** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def') ds@1952: ** -> 'CREATE INDEX i ON def(a, b, c)' ds@1952: */ ds@1952: static void renameTableFunc( ds@1952: sqlite3_context *context, ds@1952: int argc, ds@1952: sqlite3_value **argv ds@1952: ){ ds@1952: unsigned char const *zSql = sqlite3_value_text(argv[0]); ds@1952: unsigned char const *zTableName = sqlite3_value_text(argv[1]); ds@1952: ds@1952: int token; ds@1952: Token tname; ds@1952: unsigned char const *zCsr = zSql; ds@1952: int len = 0; ds@1952: char *zRet; ds@1952: ds@1952: sqlite3 *db = sqlite3_user_data(context); ds@1952: ds@1952: /* The principle used to locate the table name in the CREATE TABLE ds@1952: ** statement is that the table name is the first token that is immediatedly ds@1952: ** followed by a left parenthesis - TK_LP - or "USING" TK_USING. ds@1952: */ ds@1952: if( zSql ){ ds@1952: do { ds@1952: if( !*zCsr ){ ds@1952: /* Ran out of input before finding an opening bracket. Return NULL. */ ds@1952: return; ds@1952: } ds@1952: ds@1952: /* Store the token that zCsr points to in tname. */ ds@1952: tname.z = zCsr; ds@1952: tname.n = len; ds@1952: ds@1952: /* Advance zCsr to the next token. Store that token type in 'token', ds@1952: ** and it's length in 'len' (to be used next iteration of this loop). ds@1952: */ ds@1952: do { ds@1952: zCsr += len; ds@1952: len = sqlite3GetToken(zCsr, &token); ds@1952: } while( token==TK_SPACE ); ds@1952: assert( len>0 ); ds@1952: } while( token!=TK_LP && token!=TK_USING ); ds@1952: ds@1952: zRet = sqlite3MPrintf(db, "%.*s%Q%s", tname.z - zSql, zSql, ds@1952: zTableName, tname.z+tname.n); ds@1952: sqlite3_result_text(context, zRet, -1, sqlite3_free); ds@1952: } ds@1952: } ds@1952: ds@1952: #ifndef SQLITE_OMIT_TRIGGER ds@1952: /* This function is used by SQL generated to implement the ds@1952: ** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER ds@1952: ** statement. The second is a table name. The table name in the CREATE ds@1952: ** TRIGGER statement is replaced with the third argument and the result ds@1952: ** returned. This is analagous to renameTableFunc() above, except for CREATE ds@1952: ** TRIGGER, not CREATE INDEX and CREATE TABLE. ds@1952: */ ds@1952: static void renameTriggerFunc( ds@1952: sqlite3_context *context, ds@1952: int argc, ds@1952: sqlite3_value **argv ds@1952: ){ ds@1952: unsigned char const *zSql = sqlite3_value_text(argv[0]); ds@1952: unsigned char const *zTableName = sqlite3_value_text(argv[1]); ds@1952: ds@1952: int token; ds@1952: Token tname; ds@1952: int dist = 3; ds@1952: unsigned char const *zCsr = zSql; ds@1952: int len = 0; ds@1952: char *zRet; ds@1952: ds@1952: sqlite3 *db = sqlite3_user_data(context); ds@1952: ds@1952: /* The principle used to locate the table name in the CREATE TRIGGER ds@1952: ** statement is that the table name is the first token that is immediatedly ds@1952: ** preceded by either TK_ON or TK_DOT and immediatedly followed by one ds@1952: ** of TK_WHEN, TK_BEGIN or TK_FOR. ds@1952: */ ds@1952: if( zSql ){ ds@1952: do { ds@1952: ds@1952: if( !*zCsr ){ ds@1952: /* Ran out of input before finding the table name. Return NULL. */ ds@1952: return; ds@1952: } ds@1952: ds@1952: /* Store the token that zCsr points to in tname. */ ds@1952: tname.z = zCsr; ds@1952: tname.n = len; ds@1952: ds@1952: /* Advance zCsr to the next token. Store that token type in 'token', ds@1952: ** and it's length in 'len' (to be used next iteration of this loop). ds@1952: */ ds@1952: do { ds@1952: zCsr += len; ds@1952: len = sqlite3GetToken(zCsr, &token); ds@1952: }while( token==TK_SPACE ); ds@1952: assert( len>0 ); ds@1952: ds@1952: /* Variable 'dist' stores the number of tokens read since the most ds@1952: ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN ds@1952: ** token is read and 'dist' equals 2, the condition stated above ds@1952: ** to be met. ds@1952: ** ds@1952: ** Note that ON cannot be a database, table or column name, so ds@1952: ** there is no need to worry about syntax like ds@1952: ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. ds@1952: */ ds@1952: dist++; ds@1952: if( token==TK_DOT || token==TK_ON ){ ds@1952: dist = 0; ds@1952: } ds@1952: } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); ds@1952: ds@1952: /* Variable tname now contains the token that is the old table-name ds@1952: ** in the CREATE TRIGGER statement. ds@1952: */ ds@1952: zRet = sqlite3MPrintf(db, "%.*s%Q%s", tname.z - zSql, zSql, ds@1952: zTableName, tname.z+tname.n); ds@1952: sqlite3_result_text(context, zRet, -1, sqlite3_free); ds@1952: } ds@1952: } ds@1952: #endif /* !SQLITE_OMIT_TRIGGER */ ds@1952: ds@1952: /* ds@1952: ** Register built-in functions used to help implement ALTER TABLE ds@1952: */ ds@1952: void sqlite3AlterFunctions(sqlite3 *db){ ds@1952: static const struct { ds@1952: char *zName; ds@1952: signed char nArg; ds@1952: void (*xFunc)(sqlite3_context*,int,sqlite3_value **); ds@1952: } aFuncs[] = { ds@1952: { "sqlite_rename_table", 2, renameTableFunc}, ds@1952: #ifndef SQLITE_OMIT_TRIGGER ds@1952: { "sqlite_rename_trigger", 2, renameTriggerFunc}, ds@1952: #endif ds@1952: }; ds@1952: int i; ds@1952: ds@1952: for(i=0; idb->aDb[1].pSchema; /* Temp db schema */ ds@1952: ds@1952: /* If the table is not located in the temp-db (in which case NULL is ds@1952: ** returned, loop through the tables list of triggers. For each trigger ds@1952: ** that is not part of the temp-db schema, add a clause to the WHERE ds@1952: ** expression being built up in zWhere. ds@1952: */ ds@1952: if( pTab->pSchema!=pTempSchema ){ ds@1952: sqlite3 *db = pParse->db; ds@1952: for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){ ds@1952: if( pTrig->pSchema==pTempSchema ){ ds@1952: if( !zWhere ){ ds@1952: zWhere = sqlite3MPrintf(db, "name=%Q", pTrig->name); ds@1952: }else{ ds@1952: tmp = zWhere; ds@1952: zWhere = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, pTrig->name); ds@1952: sqlite3_free(tmp); ds@1952: } ds@1952: } ds@1952: } ds@1952: } ds@1952: return zWhere; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** Generate code to drop and reload the internal representation of table ds@1952: ** pTab from the database, including triggers and temporary triggers. ds@1952: ** Argument zName is the name of the table in the database schema at ds@1952: ** the time the generated code is executed. This can be different from ds@1952: ** pTab->zName if this function is being called to code part of an ds@1952: ** "ALTER TABLE RENAME TO" statement. ds@1952: */ ds@1952: static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ ds@1952: Vdbe *v; ds@1952: char *zWhere; ds@1952: int iDb; /* Index of database containing pTab */ ds@1952: #ifndef SQLITE_OMIT_TRIGGER ds@1952: Trigger *pTrig; ds@1952: #endif ds@1952: ds@1952: v = sqlite3GetVdbe(pParse); ds@1952: if( !v ) return; ds@1952: assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); ds@1952: iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); ds@1952: assert( iDb>=0 ); ds@1952: ds@1952: #ifndef SQLITE_OMIT_TRIGGER ds@1952: /* Drop any table triggers from the internal schema. */ ds@1952: for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){ ds@1952: int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); ds@1952: assert( iTrigDb==iDb || iTrigDb==1 ); ds@1952: sqlite3VdbeOp3(v, OP_DropTrigger, iTrigDb, 0, pTrig->name, 0); ds@1952: } ds@1952: #endif ds@1952: ds@1952: /* Drop the table and index from the internal schema */ ds@1952: sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0); ds@1952: ds@1952: /* Reload the table, index and permanent trigger schemas. */ ds@1952: zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); ds@1952: if( !zWhere ) return; ds@1952: sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC); ds@1952: ds@1952: #ifndef SQLITE_OMIT_TRIGGER ds@1952: /* Now, if the table is not stored in the temp database, reload any temp ds@1952: ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. ds@1952: */ ds@1952: if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ ds@1952: sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zWhere, P3_DYNAMIC); ds@1952: } ds@1952: #endif ds@1952: } ds@1952: ds@1952: /* ds@1952: ** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" ds@1952: ** command. ds@1952: */ ds@1952: void sqlite3AlterRenameTable( ds@1952: Parse *pParse, /* Parser context. */ ds@1952: SrcList *pSrc, /* The table to rename. */ ds@1952: Token *pName /* The new table name. */ ds@1952: ){ ds@1952: int iDb; /* Database that contains the table */ ds@1952: char *zDb; /* Name of database iDb */ ds@1952: Table *pTab; /* Table being renamed */ ds@1952: char *zName = 0; /* NULL-terminated version of pName */ ds@1952: sqlite3 *db = pParse->db; /* Database connection */ ds@1952: int nTabName; /* Number of UTF-8 characters in zTabName */ ds@1952: const char *zTabName; /* Original name of the table */ ds@1952: Vdbe *v; ds@1952: #ifndef SQLITE_OMIT_TRIGGER ds@1952: char *zWhere = 0; /* Where clause to locate temp triggers */ ds@1952: #endif ds@1952: int isVirtualRename = 0; /* True if this is a v-table with an xRename() */ ds@1952: ds@1952: if( db->mallocFailed ) goto exit_rename_table; ds@1952: assert( pSrc->nSrc==1 ); ds@1952: assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); ds@1952: ds@1952: pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); ds@1952: if( !pTab ) goto exit_rename_table; ds@1952: iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); ds@1952: zDb = db->aDb[iDb].zName; ds@1952: ds@1952: /* Get a NULL terminated version of the new table name. */ ds@1952: zName = sqlite3NameFromToken(db, pName); ds@1952: if( !zName ) goto exit_rename_table; ds@1952: ds@1952: /* Check that a table or index named 'zName' does not already exist ds@1952: ** in database iDb. If so, this is an error. ds@1952: */ ds@1952: if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ ds@1952: sqlite3ErrorMsg(pParse, ds@1952: "there is already another table or index with this name: %s", zName); ds@1952: goto exit_rename_table; ds@1952: } ds@1952: ds@1952: /* Make sure it is not a system table being altered, or a reserved name ds@1952: ** that the table is being renamed to. ds@1952: */ ds@1952: if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){ ds@1952: sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName); ds@1952: goto exit_rename_table; ds@1952: } ds@1952: if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ ds@1952: goto exit_rename_table; ds@1952: } ds@1952: ds@1952: #ifndef SQLITE_OMIT_AUTHORIZATION ds@1952: /* Invoke the authorization callback. */ ds@1952: if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ ds@1952: goto exit_rename_table; ds@1952: } ds@1952: #endif ds@1952: ds@1952: #ifndef SQLITE_OMIT_VIRTUALTABLE ds@1952: if( sqlite3ViewGetColumnNames(pParse, pTab) ){ ds@1952: goto exit_rename_table; ds@1952: } ds@1952: if( IsVirtual(pTab) && pTab->pMod->pModule->xRename ){ ds@1952: isVirtualRename = 1; ds@1952: } ds@1952: #endif ds@1952: ds@1952: /* Begin a transaction and code the VerifyCookie for database iDb. ds@1952: ** Then modify the schema cookie (since the ALTER TABLE modifies the ds@1952: ** schema). Open a statement transaction if the table is a virtual ds@1952: ** table. ds@1952: */ ds@1952: v = sqlite3GetVdbe(pParse); ds@1952: if( v==0 ){ ds@1952: goto exit_rename_table; ds@1952: } ds@1952: sqlite3BeginWriteOperation(pParse, isVirtualRename, iDb); ds@1952: sqlite3ChangeCookie(db, v, iDb); ds@1952: ds@1952: /* If this is a virtual table, invoke the xRename() function if ds@1952: ** one is defined. The xRename() callback will modify the names ds@1952: ** of any resources used by the v-table implementation (including other ds@1952: ** SQLite tables) that are identified by the name of the virtual table. ds@1952: */ ds@1952: #ifndef SQLITE_OMIT_VIRTUALTABLE ds@1952: if( isVirtualRename ){ ds@1952: sqlite3VdbeOp3(v, OP_String8, 0, 0, zName, 0); ds@1952: sqlite3VdbeOp3(v, OP_VRename, 0, 0, (const char*)pTab->pVtab, P3_VTAB); ds@1952: } ds@1952: #endif ds@1952: ds@1952: /* figure out how many UTF-8 characters are in zName */ ds@1952: zTabName = pTab->zName; ds@1952: nTabName = sqlite3Utf8CharLen(zTabName, -1); ds@1952: ds@1952: /* Modify the sqlite_master table to use the new table name. */ ds@1952: sqlite3NestedParse(pParse, ds@1952: "UPDATE %Q.%s SET " ds@1952: #ifdef SQLITE_OMIT_TRIGGER ds@1952: "sql = sqlite_rename_table(sql, %Q), " ds@1952: #else ds@1952: "sql = CASE " ds@1952: "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" ds@1952: "ELSE sqlite_rename_table(sql, %Q) END, " ds@1952: #endif ds@1952: "tbl_name = %Q, " ds@1952: "name = CASE " ds@1952: "WHEN type='table' THEN %Q " ds@1952: "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " ds@1952: "'sqlite_autoindex_' || %Q || substr(name,%d+18,10) " ds@1952: "ELSE name END " ds@1952: "WHERE tbl_name=%Q AND " ds@1952: "(type='table' OR type='index' OR type='trigger');", ds@1952: zDb, SCHEMA_TABLE(iDb), zName, zName, zName, ds@1952: #ifndef SQLITE_OMIT_TRIGGER ds@1952: zName, ds@1952: #endif ds@1952: zName, nTabName, zTabName ds@1952: ); ds@1952: ds@1952: #ifndef SQLITE_OMIT_AUTOINCREMENT ds@1952: /* If the sqlite_sequence table exists in this database, then update ds@1952: ** it with the new table name. ds@1952: */ ds@1952: if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ ds@1952: sqlite3NestedParse(pParse, ds@1952: "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q", ds@1952: zDb, zName, pTab->zName); ds@1952: } ds@1952: #endif ds@1952: ds@1952: #ifndef SQLITE_OMIT_TRIGGER ds@1952: /* If there are TEMP triggers on this table, modify the sqlite_temp_master ds@1952: ** table. Don't do this if the table being ALTERed is itself located in ds@1952: ** the temp database. ds@1952: */ ds@1952: if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ ds@1952: sqlite3NestedParse(pParse, ds@1952: "UPDATE sqlite_temp_master SET " ds@1952: "sql = sqlite_rename_trigger(sql, %Q), " ds@1952: "tbl_name = %Q " ds@1952: "WHERE %s;", zName, zName, zWhere); ds@1952: sqlite3_free(zWhere); ds@1952: } ds@1952: #endif ds@1952: ds@1952: /* Drop and reload the internal table schema. */ ds@1952: reloadTableSchema(pParse, pTab, zName); ds@1952: ds@1952: exit_rename_table: ds@1952: sqlite3SrcListDelete(pSrc); ds@1952: sqlite3_free(zName); ds@1952: } ds@1952: ds@1952: ds@1952: /* ds@1952: ** This function is called after an "ALTER TABLE ... ADD" statement ds@1952: ** has been parsed. Argument pColDef contains the text of the new ds@1952: ** column definition. ds@1952: ** ds@1952: ** The Table structure pParse->pNewTable was extended to include ds@1952: ** the new column during parsing. ds@1952: */ ds@1952: void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ ds@1952: Table *pNew; /* Copy of pParse->pNewTable */ ds@1952: Table *pTab; /* Table being altered */ ds@1952: int iDb; /* Database number */ ds@1952: const char *zDb; /* Database name */ ds@1952: const char *zTab; /* Table name */ ds@1952: char *zCol; /* Null-terminated column definition */ ds@1952: Column *pCol; /* The new column */ ds@1952: Expr *pDflt; /* Default value for the new column */ ds@1952: sqlite3 *db; /* The database connection; */ ds@1952: ds@1952: if( pParse->nErr ) return; ds@1952: pNew = pParse->pNewTable; ds@1952: assert( pNew ); ds@1952: ds@1952: db = pParse->db; ds@1952: assert( sqlite3BtreeHoldsAllMutexes(db) ); ds@1952: iDb = sqlite3SchemaToIndex(db, pNew->pSchema); ds@1952: zDb = db->aDb[iDb].zName; ds@1952: zTab = pNew->zName; ds@1952: pCol = &pNew->aCol[pNew->nCol-1]; ds@1952: pDflt = pCol->pDflt; ds@1952: pTab = sqlite3FindTable(db, zTab, zDb); ds@1952: assert( pTab ); ds@1952: ds@1952: #ifndef SQLITE_OMIT_AUTHORIZATION ds@1952: /* Invoke the authorization callback. */ ds@1952: if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ ds@1952: return; ds@1952: } ds@1952: #endif ds@1952: ds@1952: /* If the default value for the new column was specified with a ds@1952: ** literal NULL, then set pDflt to 0. This simplifies checking ds@1952: ** for an SQL NULL default below. ds@1952: */ ds@1952: if( pDflt && pDflt->op==TK_NULL ){ ds@1952: pDflt = 0; ds@1952: } ds@1952: ds@1952: /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. ds@1952: ** If there is a NOT NULL constraint, then the default value for the ds@1952: ** column must not be NULL. ds@1952: */ ds@1952: if( pCol->isPrimKey ){ ds@1952: sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); ds@1952: return; ds@1952: } ds@1952: if( pNew->pIndex ){ ds@1952: sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); ds@1952: return; ds@1952: } ds@1952: if( pCol->notNull && !pDflt ){ ds@1952: sqlite3ErrorMsg(pParse, ds@1952: "Cannot add a NOT NULL column with default value NULL"); ds@1952: return; ds@1952: } ds@1952: ds@1952: /* Ensure the default expression is something that sqlite3ValueFromExpr() ds@1952: ** can handle (i.e. not CURRENT_TIME etc.) ds@1952: */ ds@1952: if( pDflt ){ ds@1952: sqlite3_value *pVal; ds@1952: if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ ds@1952: db->mallocFailed = 1; ds@1952: return; ds@1952: } ds@1952: if( !pVal ){ ds@1952: sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); ds@1952: return; ds@1952: } ds@1952: sqlite3ValueFree(pVal); ds@1952: } ds@1952: ds@1952: /* Modify the CREATE TABLE statement. */ ds@1952: zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); ds@1952: if( zCol ){ ds@1952: char *zEnd = &zCol[pColDef->n-1]; ds@1952: while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){ ds@1952: *zEnd-- = '\0'; ds@1952: } ds@1952: sqlite3NestedParse(pParse, ds@1952: "UPDATE %Q.%s SET " ds@1952: "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d,length(sql)) " ds@1952: "WHERE type = 'table' AND name = %Q", ds@1952: zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, ds@1952: zTab ds@1952: ); ds@1952: sqlite3_free(zCol); ds@1952: } ds@1952: ds@1952: /* If the default value of the new column is NULL, then set the file ds@1952: ** format to 2. If the default value of the new column is not NULL, ds@1952: ** the file format becomes 3. ds@1952: */ ds@1952: sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2); ds@1952: ds@1952: /* Reload the schema of the modified table. */ ds@1952: reloadTableSchema(pParse, pTab, pTab->zName); ds@1952: } ds@1952: ds@1952: /* ds@1952: ** This function is called by the parser after the table-name in ds@1952: ** an "ALTER TABLE ADD" statement is parsed. Argument ds@1952: ** pSrc is the full-name of the table being altered. ds@1952: ** ds@1952: ** This routine makes a (partial) copy of the Table structure ds@1952: ** for the table being altered and sets Parse.pNewTable to point ds@1952: ** to it. Routines called by the parser as the column definition ds@1952: ** is parsed (i.e. sqlite3AddColumn()) add the new Column data to ds@1952: ** the copy. The copy of the Table structure is deleted by tokenize.c ds@1952: ** after parsing is finished. ds@1952: ** ds@1952: ** Routine sqlite3AlterFinishAddColumn() will be called to complete ds@1952: ** coding the "ALTER TABLE ... ADD" statement. ds@1952: */ ds@1952: void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ ds@1952: Table *pNew; ds@1952: Table *pTab; ds@1952: Vdbe *v; ds@1952: int iDb; ds@1952: int i; ds@1952: int nAlloc; ds@1952: sqlite3 *db = pParse->db; ds@1952: ds@1952: /* Look up the table being altered. */ ds@1952: assert( pParse->pNewTable==0 ); ds@1952: assert( sqlite3BtreeHoldsAllMutexes(db) ); ds@1952: if( db->mallocFailed ) goto exit_begin_add_column; ds@1952: pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); ds@1952: if( !pTab ) goto exit_begin_add_column; ds@1952: ds@1952: #ifndef SQLITE_OMIT_VIRTUALTABLE ds@1952: if( IsVirtual(pTab) ){ ds@1952: sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); ds@1952: goto exit_begin_add_column; ds@1952: } ds@1952: #endif ds@1952: ds@1952: /* Make sure this is not an attempt to ALTER a view. */ ds@1952: if( pTab->pSelect ){ ds@1952: sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); ds@1952: goto exit_begin_add_column; ds@1952: } ds@1952: ds@1952: assert( pTab->addColOffset>0 ); ds@1952: iDb = sqlite3SchemaToIndex(db, pTab->pSchema); ds@1952: ds@1952: /* Put a copy of the Table struct in Parse.pNewTable for the ds@1952: ** sqlite3AddColumn() function and friends to modify. ds@1952: */ ds@1952: pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table)); ds@1952: if( !pNew ) goto exit_begin_add_column; ds@1952: pParse->pNewTable = pNew; ds@1952: pNew->nRef = 1; ds@1952: pNew->nCol = pTab->nCol; ds@1952: assert( pNew->nCol>0 ); ds@1952: nAlloc = (((pNew->nCol-1)/8)*8)+8; ds@1952: assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); ds@1952: pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); ds@1952: pNew->zName = sqlite3DbStrDup(db, pTab->zName); ds@1952: if( !pNew->aCol || !pNew->zName ){ ds@1952: db->mallocFailed = 1; ds@1952: goto exit_begin_add_column; ds@1952: } ds@1952: memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); ds@1952: for(i=0; inCol; i++){ ds@1952: Column *pCol = &pNew->aCol[i]; ds@1952: pCol->zName = sqlite3DbStrDup(db, pCol->zName); ds@1952: pCol->zColl = 0; ds@1952: pCol->zType = 0; ds@1952: pCol->pDflt = 0; ds@1952: } ds@1952: pNew->pSchema = db->aDb[iDb].pSchema; ds@1952: pNew->addColOffset = pTab->addColOffset; ds@1952: pNew->nRef = 1; ds@1952: ds@1952: /* Begin a transaction and increment the schema cookie. */ ds@1952: sqlite3BeginWriteOperation(pParse, 0, iDb); ds@1952: v = sqlite3GetVdbe(pParse); ds@1952: if( !v ) goto exit_begin_add_column; ds@1952: sqlite3ChangeCookie(db, v, iDb); ds@1952: ds@1952: exit_begin_add_column: ds@1952: sqlite3SrcListDelete(pSrc); ds@1952: return; ds@1952: } ds@1952: #endif /* SQLITE_ALTER_TABLE */