AryaWu/sqlite
0
1/*2** 2005 February 153**4** The author disclaims copyright to this source code. In place of5** 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 code13** that implements the ALTER TABLE command.14*/15#include "sqliteInt.h"16 17/*18** The code in this file only exists if we are not omitting the19** ALTER TABLE logic from the build.20*/21#ifndef SQLITE_OMIT_ALTERTABLE22 23/*24** Parameter zName is the name of a table that is about to be altered25** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).26** If the table is a system table, this function leaves an error message27** in pParse->zErr (system tables may not be altered) and returns non-zero.28**29** Or, if zName is not a system table, zero is returned.30*/31static int isAlterableTable(Parse *pParse, Table *pTab){32 if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7)33#ifndef SQLITE_OMIT_VIRTUALTABLE34 || (pTab->tabFlags & TF_Eponymous)!=035 || ( (pTab->tabFlags & TF_Shadow)!=036 && sqlite3ReadOnlyShadowTables(pParse->db)37 )38#endif39 ){40 sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);41 return 1;42 }43 return 0;44}45 46/*47** Generate code to verify that the schemas of database zDb and, if48** bTemp is not true, database "temp", can still be parsed. This is49** called at the end of the generation of an ALTER TABLE ... RENAME ...50** statement to ensure that the operation has not rendered any schema51** objects unusable.52*/53static void renameTestSchema(54 Parse *pParse, /* Parse context */55 const char *zDb, /* Name of db to verify schema of */56 int bTemp, /* True if this is the temp db */57 const char *zWhen, /* "when" part of error message */58 int bNoDQS /* Do not allow DQS in the schema */59){60 pParse->colNamesSet = 1;61 sqlite3NestedParse(pParse,62 "SELECT 1 "63 "FROM \"%w\"." LEGACY_SCHEMA_TABLE " "64 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"65 " AND sql NOT LIKE 'create virtual%%'"66 " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ",67 zDb,68 zDb, bTemp, zWhen, bNoDQS69 );70 71 if( bTemp==0 ){72 sqlite3NestedParse(pParse,73 "SELECT 1 "74 "FROM temp." LEGACY_SCHEMA_TABLE " "75 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"76 " AND sql NOT LIKE 'create virtual%%'"77 " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ",78 zDb, zWhen, bNoDQS79 );80 }81}82 83/*84** Generate VM code to replace any double-quoted strings (but not double-quoted85** identifiers) within the "sql" column of the sqlite_schema table in86** database zDb with their single-quoted equivalents. If argument bTemp is87** not true, similarly update all SQL statements in the sqlite_schema table88** of the temp db.89*/90static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){91 sqlite3NestedParse(pParse,92 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE93 " SET sql = sqlite_rename_quotefix(%Q, sql)"94 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"95 " AND sql NOT LIKE 'create virtual%%'" , zDb, zDb96 );97 if( bTemp==0 ){98 sqlite3NestedParse(pParse,99 "UPDATE temp." LEGACY_SCHEMA_TABLE100 " SET sql = sqlite_rename_quotefix('temp', sql)"101 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"102 " AND sql NOT LIKE 'create virtual%%'"103 );104 }105}106 107/*108** Generate code to reload the schema for database iDb. And, if iDb!=1, for109** the temp database as well.110*/111static void renameReloadSchema(Parse *pParse, int iDb, u16 p5){112 Vdbe *v = pParse->pVdbe;113 if( v ){114 sqlite3ChangeCookie(pParse, iDb);115 sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0, p5);116 if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0, p5);117 }118}119 120/*121** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy"122** command.123*/124void sqlite3AlterRenameTable(125 Parse *pParse, /* Parser context. */126 SrcList *pSrc, /* The table to rename. */127 Token *pName /* The new table name. */128){129 int iDb; /* Database that contains the table */130 char *zDb; /* Name of database iDb */131 Table *pTab; /* Table being renamed */132 char *zName = 0; /* NULL-terminated version of pName */133 sqlite3 *db = pParse->db; /* Database connection */134 int nTabName; /* Number of UTF-8 characters in zTabName */135 const char *zTabName; /* Original name of the table */136 Vdbe *v;137 VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */138 139 if( NEVER(db->mallocFailed) ) goto exit_rename_table;140 assert( pSrc->nSrc==1 );141 assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );142 143 pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);144 if( !pTab ) goto exit_rename_table;145 iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);146 zDb = db->aDb[iDb].zDbSName;147 148 /* Get a NULL terminated version of the new table name. */149 zName = sqlite3NameFromToken(db, pName);150 if( !zName ) goto exit_rename_table;151 152 /* Check that a table or index named 'zName' does not already exist153 ** in database iDb. If so, this is an error.154 */155 if( sqlite3FindTable(db, zName, zDb)156 || sqlite3FindIndex(db, zName, zDb)157 || sqlite3IsShadowTableOf(db, pTab, zName)158 ){159 sqlite3ErrorMsg(pParse,160 "there is already another table or index with this name: %s", zName);161 goto exit_rename_table;162 }163 164 /* Make sure it is not a system table being altered, or a reserved name165 ** that the table is being renamed to.166 */167 if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){168 goto exit_rename_table;169 }170 if( SQLITE_OK!=sqlite3CheckObjectName(pParse,zName,"table",zName) ){171 goto exit_rename_table;172 }173 174#ifndef SQLITE_OMIT_VIEW175 if( IsView(pTab) ){176 sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName);177 goto exit_rename_table;178 }179#endif180 181#ifndef SQLITE_OMIT_AUTHORIZATION182 /* Invoke the authorization callback. */183 if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){184 goto exit_rename_table;185 }186#endif187 188#ifndef SQLITE_OMIT_VIRTUALTABLE189 if( sqlite3ViewGetColumnNames(pParse, pTab) ){190 goto exit_rename_table;191 }192 if( IsVirtual(pTab) ){193 pVTab = sqlite3GetVTable(db, pTab);194 if( pVTab->pVtab->pModule->xRename==0 ){195 pVTab = 0;196 }197 }198#endif199 200 /* Begin a transaction for database iDb. Then modify the schema cookie201 ** (since the ALTER TABLE modifies the schema). Call sqlite3MayAbort(),202 ** as the scalar functions (e.g. sqlite_rename_table()) invoked by the203 ** nested SQL may raise an exception. */204 v = sqlite3GetVdbe(pParse);205 if( v==0 ){206 goto exit_rename_table;207 }208 sqlite3MayAbort(pParse);209 210 /* figure out how many UTF-8 characters are in zName */211 zTabName = pTab->zName;212 nTabName = sqlite3Utf8CharLen(zTabName, -1);213 214 /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in215 ** the schema to use the new table name. */216 sqlite3NestedParse(pParse,217 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "218 "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "219 "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"220 "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"221 , zDb, zDb, zTabName, zName, (iDb==1), zTabName222 );223 224 /* Update the tbl_name and name columns of the sqlite_schema table225 ** as required. */226 sqlite3NestedParse(pParse,227 "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET "228 "tbl_name = %Q, "229 "name = CASE "230 "WHEN type='table' THEN %Q "231 "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "232 " AND type='index' THEN "233 "'sqlite_autoindex_' || %Q || substr(name,%d+18) "234 "ELSE name END "235 "WHERE tbl_name=%Q COLLATE nocase AND "236 "(type='table' OR type='index' OR type='trigger');",237 zDb,238 zName, zName, zName,239 nTabName, zTabName240 );241 242#ifndef SQLITE_OMIT_AUTOINCREMENT243 /* If the sqlite_sequence table exists in this database, then update244 ** it with the new table name.245 */246 if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){247 sqlite3NestedParse(pParse,248 "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q",249 zDb, zName, pTab->zName);250 }251#endif252 253 /* If the table being renamed is not itself part of the temp database,254 ** edit view and trigger definitions within the temp database255 ** as required. */256 if( iDb!=1 ){257 sqlite3NestedParse(pParse,258 "UPDATE sqlite_temp_schema SET "259 "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), "260 "tbl_name = "261 "CASE WHEN tbl_name=%Q COLLATE nocase AND "262 " sqlite_rename_test(%Q, sql, type, name, 1, 'after rename', 0) "263 "THEN %Q ELSE tbl_name END "264 "WHERE type IN ('view', 'trigger')"265 , zDb, zTabName, zName, zTabName, zDb, zName);266 }267 268 /* If this is a virtual table, invoke the xRename() function if269 ** one is defined. The xRename() callback will modify the names270 ** of any resources used by the v-table implementation (including other271 ** SQLite tables) that are identified by the name of the virtual table.272 */273#ifndef SQLITE_OMIT_VIRTUALTABLE274 if( pVTab ){275 int i = ++pParse->nMem;276 sqlite3VdbeLoadString(v, i, zName);277 sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);278 }279#endif280 281 renameReloadSchema(pParse, iDb, INITFLAG_AlterRename);282 renameTestSchema(pParse, zDb, iDb==1, "after rename", 0);283 284exit_rename_table:285 sqlite3SrcListDelete(db, pSrc);286 sqlite3DbFree(db, zName);287}288 289/*290** Write code that will raise an error if the table described by291** zDb and zTab is not empty.292*/293static void sqlite3ErrorIfNotEmpty(294 Parse *pParse, /* Parsing context */295 const char *zDb, /* Schema holding the table */296 const char *zTab, /* Table to check for empty */297 const char *zErr /* Error message text */298){299 sqlite3NestedParse(pParse,300 "SELECT raise(ABORT,%Q) FROM \"%w\".\"%w\"",301 zErr, zDb, zTab302 );303}304 305/*306** This function is called after an "ALTER TABLE ... ADD" statement307** has been parsed. Argument pColDef contains the text of the new308** column definition.309**310** The Table structure pParse->pNewTable was extended to include311** the new column during parsing.312*/313void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){314 Table *pNew; /* Copy of pParse->pNewTable */315 Table *pTab; /* Table being altered */316 int iDb; /* Database number */317 const char *zDb; /* Database name */318 const char *zTab; /* Table name */319 char *zCol; /* Null-terminated column definition */320 Column *pCol; /* The new column */321 Expr *pDflt; /* Default value for the new column */322 sqlite3 *db; /* The database connection; */323 Vdbe *v; /* The prepared statement under construction */324 int r1; /* Temporary registers */325 326 db = pParse->db;327 assert( db->pParse==pParse );328 if( pParse->nErr ) return;329 assert( db->mallocFailed==0 );330 pNew = pParse->pNewTable;331 assert( pNew );332 333 assert( sqlite3BtreeHoldsAllMutexes(db) );334 iDb = sqlite3SchemaToIndex(db, pNew->pSchema);335 zDb = db->aDb[iDb].zDbSName;336 zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */337 pCol = &pNew->aCol[pNew->nCol-1];338 pDflt = sqlite3ColumnExpr(pNew, pCol);339 pTab = sqlite3FindTable(db, zTab, zDb);340 assert( pTab );341 342#ifndef SQLITE_OMIT_AUTHORIZATION343 /* Invoke the authorization callback. */344 if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){345 return;346 }347#endif348 349 350 /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.351 ** If there is a NOT NULL constraint, then the default value for the352 ** column must not be NULL.353 */354 if( pCol->colFlags & COLFLAG_PRIMKEY ){355 sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");356 return;357 }358 if( pNew->pIndex ){359 sqlite3ErrorMsg(pParse,360 "Cannot add a UNIQUE column");361 return;362 }363 if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){364 /* If the default value for the new column was specified with a365 ** literal NULL, then set pDflt to 0. This simplifies checking366 ** for an SQL NULL default below.367 */368 assert( pDflt==0 || pDflt->op==TK_SPAN );369 if( pDflt && pDflt->pLeft->op==TK_NULL ){370 pDflt = 0;371 }372 assert( IsOrdinaryTable(pNew) );373 if( (db->flags&SQLITE_ForeignKeys) && pNew->u.tab.pFKey && pDflt ){374 sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,375 "Cannot add a REFERENCES column with non-NULL default value");376 }377 if( pCol->notNull && !pDflt ){378 sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,379 "Cannot add a NOT NULL column with default value NULL");380 }381 382 383 /* Ensure the default expression is something that sqlite3ValueFromExpr()384 ** can handle (i.e. not CURRENT_TIME etc.)385 */386 if( pDflt ){387 sqlite3_value *pVal = 0;388 int rc;389 rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);390 assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );391 if( rc!=SQLITE_OK ){392 assert( db->mallocFailed == 1 );393 return;394 }395 if( !pVal ){396 sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,397 "Cannot add a column with non-constant default");398 }399 sqlite3ValueFree(pVal);400 }401 }else if( pCol->colFlags & COLFLAG_STORED ){402 sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "cannot add a STORED column");403 }404 405 406 /* Modify the CREATE TABLE statement. */407 zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);408 if( zCol ){409 char *zEnd = &zCol[pColDef->n-1];410 while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){411 *zEnd-- = '\0';412 }413 /* substr() operations on characters, but addColOffset is in bytes. So we414 ** have to use printf() to translate between these units: */415 assert( IsOrdinaryTable(pTab) );416 assert( IsOrdinaryTable(pNew) );417 sqlite3NestedParse(pParse,418 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "419 "sql = printf('%%.%ds, ',sql) || %Q"420 " || substr(sql,1+length(printf('%%.%ds',sql))) "421 "WHERE type = 'table' AND name = %Q",422 zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset,423 zTab424 );425 sqlite3DbFree(db, zCol);426 }427 428 v = sqlite3GetVdbe(pParse);429 if( v ){430 /* Make sure the schema version is at least 3. But do not upgrade431 ** from less than 3 to 4, as that will corrupt any preexisting DESC432 ** index.433 */434 r1 = sqlite3GetTempReg(pParse);435 sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);436 sqlite3VdbeUsesBtree(v, iDb);437 sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2);438 sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);439 VdbeCoverage(v);440 sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);441 sqlite3ReleaseTempReg(pParse, r1);442 443 /* Reload the table definition */444 renameReloadSchema(pParse, iDb, INITFLAG_AlterAdd);445 446 /* Verify that constraints are still satisfied */447 if( pNew->pCheck!=0448 || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0)449 || (pTab->tabFlags & TF_Strict)!=0450 ){451 sqlite3NestedParse(pParse,452 "SELECT CASE WHEN quick_check GLOB 'CHECK*'"453 " THEN raise(ABORT,'CHECK constraint failed')"454 " WHEN quick_check GLOB 'non-* value in*'"455 " THEN raise(ABORT,'type mismatch on DEFAULT')"456 " ELSE raise(ABORT,'NOT NULL constraint failed')"457 " END"458 " FROM pragma_quick_check(%Q,%Q)"459 " WHERE quick_check GLOB 'CHECK*'"460 " OR quick_check GLOB 'NULL*'"461 " OR quick_check GLOB 'non-* value in*'",462 zTab, zDb463 );464 }465 }466}467 468/*469** This function is called by the parser after the table-name in470** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument471** pSrc is the full-name of the table being altered.472**473** This routine makes a (partial) copy of the Table structure474** for the table being altered and sets Parse.pNewTable to point475** to it. Routines called by the parser as the column definition476** is parsed (i.e. sqlite3AddColumn()) add the new Column data to477** the copy. The copy of the Table structure is deleted by tokenize.c478** after parsing is finished.479**480** Routine sqlite3AlterFinishAddColumn() will be called to complete481** coding the "ALTER TABLE ... ADD" statement.482*/483void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){484 Table *pNew;485 Table *pTab;486 int iDb;487 int i;488 int nAlloc;489 sqlite3 *db = pParse->db;490 491 /* Look up the table being altered. */492 assert( pParse->pNewTable==0 );493 assert( sqlite3BtreeHoldsAllMutexes(db) );494 if( NEVER(db->mallocFailed) ) goto exit_begin_add_column;495 pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);496 if( !pTab ) goto exit_begin_add_column;497 498#ifndef SQLITE_OMIT_VIRTUALTABLE499 if( IsVirtual(pTab) ){500 sqlite3ErrorMsg(pParse, "virtual tables may not be altered");501 goto exit_begin_add_column;502 }503#endif504 505 /* Make sure this is not an attempt to ALTER a view. */506 if( IsView(pTab) ){507 sqlite3ErrorMsg(pParse, "Cannot add a column to a view");508 goto exit_begin_add_column;509 }510 if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){511 goto exit_begin_add_column;512 }513 514 sqlite3MayAbort(pParse);515 assert( IsOrdinaryTable(pTab) );516 assert( pTab->u.tab.addColOffset>0 );517 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);518 519 /* Put a copy of the Table struct in Parse.pNewTable for the520 ** sqlite3AddColumn() function and friends to modify. But modify521 ** the name by adding an "sqlite_altertab_" prefix. By adding this522 ** prefix, we insure that the name will not collide with an existing523 ** table because user table are not allowed to have the "sqlite_"524 ** prefix on their name.525 */526 pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table));527 if( !pNew ) goto exit_begin_add_column;528 pParse->pNewTable = pNew;529 pNew->nTabRef = 1;530 pNew->nCol = pTab->nCol;531 assert( pNew->nCol>0 );532 nAlloc = (((pNew->nCol-1)/8)*8)+8;533 assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );534 pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*(u32)nAlloc);535 pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName);536 if( !pNew->aCol || !pNew->zName ){537 assert( db->mallocFailed );538 goto exit_begin_add_column;539 }540 memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*(size_t)pNew->nCol);541 for(i=0; i<pNew->nCol; i++){542 Column *pCol = &pNew->aCol[i];543 pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName);544 pCol->hName = sqlite3StrIHash(pCol->zCnName);545 }546 assert( IsOrdinaryTable(pNew) );547 pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0);548 pNew->pSchema = db->aDb[iDb].pSchema;549 pNew->u.tab.addColOffset = pTab->u.tab.addColOffset;550 assert( pNew->nTabRef==1 );551 552exit_begin_add_column:553 sqlite3SrcListDelete(db, pSrc);554 return;555}556 557/*558** Parameter pTab is the subject of an ALTER TABLE ... RENAME COLUMN559** command. This function checks if the table is a view or virtual560** table (columns of views or virtual tables may not be renamed). If so,561** it loads an error message into pParse and returns non-zero.562**563** Or, if pTab is not a view or virtual table, zero is returned.564*/565#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)566static int isRealTable(Parse *pParse, Table *pTab, int iOp){567 const char *zType = 0;568#ifndef SQLITE_OMIT_VIEW569 if( IsView(pTab) ){570 zType = "view";571 }572#endif573#ifndef SQLITE_OMIT_VIRTUALTABLE574 if( IsVirtual(pTab) ){575 zType = "virtual table";576 }577#endif578 if( zType ){579 const char *azMsg[] = {580 "rename columns of", "drop column from", "edit constraints of"581 };582 assert( iOp>=0 && iOp<ArraySize(azMsg) );583 sqlite3ErrorMsg(pParse, "cannot %s %s \"%s\"",584 azMsg[iOp], zType, pTab->zName585 );586 return 1;587 }588 return 0;589}590#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */591# define isRealTable(x,y,z) (0)592#endif593 594/*595** Handles the following parser reduction:596**597** cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew598*/599void sqlite3AlterRenameColumn(600 Parse *pParse, /* Parsing context */601 SrcList *pSrc, /* Table being altered. pSrc->nSrc==1 */602 Token *pOld, /* Name of column being changed */603 Token *pNew /* New column name */604){605 sqlite3 *db = pParse->db; /* Database connection */606 Table *pTab; /* Table being updated */607 int iCol; /* Index of column being renamed */608 char *zOld = 0; /* Old column name */609 char *zNew = 0; /* New column name */610 const char *zDb; /* Name of schema containing the table */611 int iSchema; /* Index of the schema */612 int bQuote; /* True to quote the new name */613 614 /* Locate the table to be altered */615 pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);616 if( !pTab ) goto exit_rename_column;617 618 /* Cannot alter a system table */619 if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column;620 if( SQLITE_OK!=isRealTable(pParse, pTab, 0) ) goto exit_rename_column;621 622 /* Which schema holds the table to be altered */ 623 iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);624 assert( iSchema>=0 );625 zDb = db->aDb[iSchema].zDbSName;626 627#ifndef SQLITE_OMIT_AUTHORIZATION628 /* Invoke the authorization callback. */629 if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){630 goto exit_rename_column;631 }632#endif633 634 /* Make sure the old name really is a column name in the table to be635 ** altered. Set iCol to be the index of the column being renamed */636 zOld = sqlite3NameFromToken(db, pOld);637 if( !zOld ) goto exit_rename_column;638 iCol = sqlite3ColumnIndex(pTab, zOld);639 if( iCol<0 ){640 sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld);641 goto exit_rename_column;642 }643 644 /* Ensure the schema contains no double-quoted strings */645 renameTestSchema(pParse, zDb, iSchema==1, "", 0);646 renameFixQuotes(pParse, zDb, iSchema==1);647 648 /* Do the rename operation using a recursive UPDATE statement that649 ** uses the sqlite_rename_column() SQL function to compute the new650 ** CREATE statement text for the sqlite_schema table.651 */652 sqlite3MayAbort(pParse);653 zNew = sqlite3NameFromToken(db, pNew);654 if( !zNew ) goto exit_rename_column;655 assert( pNew->n>0 );656 bQuote = sqlite3Isquote(pNew->z[0]);657 sqlite3NestedParse(pParse,658 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "659 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "660 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "661 " AND (type != 'index' OR tbl_name = %Q)",662 zDb,663 zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,664 pTab->zName665 );666 667 sqlite3NestedParse(pParse,668 "UPDATE temp." LEGACY_SCHEMA_TABLE " SET "669 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "670 "WHERE type IN ('trigger', 'view')",671 zDb, pTab->zName, iCol, zNew, bQuote672 );673 674 /* Drop and reload the database schema. */675 renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename);676 renameTestSchema(pParse, zDb, iSchema==1, "after rename", 1);677 678 exit_rename_column:679 sqlite3SrcListDelete(db, pSrc);680 sqlite3DbFree(db, zOld);681 sqlite3DbFree(db, zNew);682 return;683}684 685/*686** Each RenameToken object maps an element of the parse tree into687** the token that generated that element. The parse tree element688** might be one of:689**690** * A pointer to an Expr that represents an ID691** * The name of a table column in Column.zName692**693** A list of RenameToken objects can be constructed during parsing.694** Each new object is created by sqlite3RenameTokenMap().695** As the parse tree is transformed, the sqlite3RenameTokenRemap()696** routine is used to keep the mapping current.697**698** After the parse finishes, renameTokenFind() routine can be used699** to look up the actual token value that created some element in700** the parse tree.701*/702struct RenameToken {703 const void *p; /* Parse tree element created by token t */704 Token t; /* The token that created parse tree element p */705 RenameToken *pNext; /* Next is a list of all RenameToken objects */706};707 708/*709** The context of an ALTER TABLE RENAME COLUMN operation that gets passed710** down into the Walker.711*/712typedef struct RenameCtx RenameCtx;713struct RenameCtx {714 RenameToken *pList; /* List of tokens to overwrite */715 int nList; /* Number of tokens in pList */716 int iCol; /* Index of column being renamed */717 Table *pTab; /* Table being ALTERed */718 const char *zOld; /* Old column name */719};720 721#ifdef SQLITE_DEBUG722/*723** This function is only for debugging. It performs two tasks:724**725** 1. Checks that pointer pPtr does not already appear in the726** rename-token list.727**728** 2. Dereferences each pointer in the rename-token list.729**730** The second is most effective when debugging under valgrind or731** address-sanitizer or similar. If any of these pointers no longer732** point to valid objects, an exception is raised by the memory-checking733** tool.734**735** The point of this is to prevent comparisons of invalid pointer values.736** Even though this always seems to work, it is undefined according to the737** C standard. Example of undefined comparison:738**739** sqlite3_free(x);740** if( x==y ) ...741**742** Technically, as x no longer points into a valid object or to the byte743** following a valid object, it may not be used in comparison operations.744*/745static void renameTokenCheckAll(Parse *pParse, const void *pPtr){746 assert( pParse==pParse->db->pParse );747 assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );748 if( pParse->nErr==0 ){749 const RenameToken *p;750 u32 i = 1;751 for(p=pParse->pRename; p; p=p->pNext){752 if( p->p ){753 assert( p->p!=pPtr );754 i += *(u8*)(p->p) | 1;755 }756 }757 assert( i>0 );758 }759}760#else761# define renameTokenCheckAll(x,y)762#endif763 764/*765** Remember that the parser tree element pPtr was created using766** the token pToken.767**768** In other words, construct a new RenameToken object and add it769** to the list of RenameToken objects currently being built up770** in pParse->pRename.771**772** The pPtr argument is returned so that this routine can be used773** with tail recursion in tokenExpr() routine, for a small performance774** improvement.775*/776const void *sqlite3RenameTokenMap(777 Parse *pParse,778 const void *pPtr,779 const Token *pToken780){781 RenameToken *pNew;782 assert( pPtr || pParse->db->mallocFailed );783 renameTokenCheckAll(pParse, pPtr);784 if( ALWAYS(pParse->eParseMode!=PARSE_MODE_UNMAP) ){785 pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));786 if( pNew ){787 pNew->p = pPtr;788 pNew->t = *pToken;789 pNew->pNext = pParse->pRename;790 pParse->pRename = pNew;791 }792 }793 794 return pPtr;795}796 797/*798** It is assumed that there is already a RenameToken object associated799** with parse tree element pFrom. This function remaps the associated token800** to parse tree element pTo.801*/802void sqlite3RenameTokenRemap(Parse *pParse, const void *pTo, const void *pFrom){803 RenameToken *p;804 renameTokenCheckAll(pParse, pTo);805 for(p=pParse->pRename; p; p=p->pNext){806 if( p->p==pFrom ){807 p->p = pTo;808 break;809 }810 }811}812 813/*814** Walker callback used by sqlite3RenameExprUnmap().815*/816static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){817 Parse *pParse = pWalker->pParse;818 sqlite3RenameTokenRemap(pParse, 0, (const void*)pExpr);819 if( ExprUseYTab(pExpr) ){820 sqlite3RenameTokenRemap(pParse, 0, (const void*)&pExpr->y.pTab);821 }822 return WRC_Continue;823}824 825/*826** Iterate through the Select objects that are part of WITH clauses attached827** to select statement pSelect.828*/829static void renameWalkWith(Walker *pWalker, Select *pSelect){830 With *pWith = pSelect->pWith;831 if( pWith ){832 Parse *pParse = pWalker->pParse;833 int i;834 With *pCopy = 0;835 assert( pWith->nCte>0 );836 if( (pWith->a[0].pSelect->selFlags & SF_Expanded)==0 ){837 /* Push a copy of the With object onto the with-stack. We use a copy838 ** here as the original will be expanded and resolved (flags SF_Expanded839 ** and SF_Resolved) below. And the parser code that uses the with-stack840 ** fails if the Select objects on it have already been expanded and841 ** resolved. */842 pCopy = sqlite3WithDup(pParse->db, pWith);843 pCopy = sqlite3WithPush(pParse, pCopy, 1);844 }845 for(i=0; i<pWith->nCte; i++){846 Select *p = pWith->a[i].pSelect;847 NameContext sNC;848 memset(&sNC, 0, sizeof(sNC));849 sNC.pParse = pParse;850 if( pCopy ) sqlite3SelectPrep(sNC.pParse, p, &sNC);851 if( sNC.pParse->db->mallocFailed ) return;852 sqlite3WalkSelect(pWalker, p);853 sqlite3RenameExprlistUnmap(pParse, pWith->a[i].pCols);854 }855 if( pCopy && pParse->pWith==pCopy ){856 pParse->pWith = pCopy->pOuter;857 }858 }859}860 861/*862** Unmap all tokens in the IdList object passed as the second argument.863*/864static void unmapColumnIdlistNames(865 Parse *pParse,866 const IdList *pIdList867){868 int ii;869 assert( pIdList!=0 );870 for(ii=0; ii<pIdList->nId; ii++){871 sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName);872 }873}874 875/*876** Walker callback used by sqlite3RenameExprUnmap().877*/878static int renameUnmapSelectCb(Walker *pWalker, Select *p){879 Parse *pParse = pWalker->pParse;880 int i;881 if( pParse->nErr ) return WRC_Abort;882 testcase( p->selFlags & SF_View );883 testcase( p->selFlags & SF_CopyCte );884 if( p->selFlags & (SF_View|SF_CopyCte) ){885 return WRC_Prune;886 }887 if( ALWAYS(p->pEList) ){888 ExprList *pList = p->pEList;889 for(i=0; i<pList->nExpr; i++){890 if( pList->a[i].zEName && pList->a[i].fg.eEName==ENAME_NAME ){891 sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName);892 }893 }894 }895 if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */896 SrcList *pSrc = p->pSrc;897 for(i=0; i<pSrc->nSrc; i++){898 sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);899 if( pSrc->a[i].fg.isUsing==0 ){900 sqlite3WalkExpr(pWalker, pSrc->a[i].u3.pOn);901 }else{902 unmapColumnIdlistNames(pParse, pSrc->a[i].u3.pUsing);903 }904 }905 }906 907 renameWalkWith(pWalker, p);908 return WRC_Continue;909}910 911/*912** Remove all nodes that are part of expression pExpr from the rename list.913*/914void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){915 u8 eMode = pParse->eParseMode;916 Walker sWalker;917 memset(&sWalker, 0, sizeof(Walker));918 sWalker.pParse = pParse;919 sWalker.xExprCallback = renameUnmapExprCb;920 sWalker.xSelectCallback = renameUnmapSelectCb;921 pParse->eParseMode = PARSE_MODE_UNMAP;922 sqlite3WalkExpr(&sWalker, pExpr);923 pParse->eParseMode = eMode;924}925 926/*927** Remove all nodes that are part of expression-list pEList from the928** rename list.929*/930void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){931 if( pEList ){932 int i;933 Walker sWalker;934 memset(&sWalker, 0, sizeof(Walker));935 sWalker.pParse = pParse;936 sWalker.xExprCallback = renameUnmapExprCb;937 sqlite3WalkExprList(&sWalker, pEList);938 for(i=0; i<pEList->nExpr; i++){939 if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME) ){940 sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName);941 }942 }943 }944}945 946/*947** Free the list of RenameToken objects given in the second argument948*/949static void renameTokenFree(sqlite3 *db, RenameToken *pToken){950 RenameToken *pNext;951 RenameToken *p;952 for(p=pToken; p; p=pNext){953 pNext = p->pNext;954 sqlite3DbFree(db, p);955 }956}957 958/*959** Search the Parse object passed as the first argument for a RenameToken960** object associated with parse tree element pPtr. If found, return a pointer961** to it. Otherwise, return NULL.962**963** If the second argument passed to this function is not NULL and a matching964** RenameToken object is found, remove it from the Parse object and add it to965** the list maintained by the RenameCtx object.966*/967static RenameToken *renameTokenFind(968 Parse *pParse,969 struct RenameCtx *pCtx,970 const void *pPtr971){972 RenameToken **pp;973 if( NEVER(pPtr==0) ){974 return 0;975 }976 for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){977 if( (*pp)->p==pPtr ){978 RenameToken *pToken = *pp;979 if( pCtx ){980 *pp = pToken->pNext;981 pToken->pNext = pCtx->pList;982 pCtx->pList = pToken;983 pCtx->nList++;984 }985 return pToken;986 }987 }988 return 0;989}990 991/*992** This is a Walker select callback. It does nothing. It is only required993** because without a dummy callback, sqlite3WalkExpr() and similar do not994** descend into sub-select statements.995*/996static int renameColumnSelectCb(Walker *pWalker, Select *p){997 if( p->selFlags & (SF_View|SF_CopyCte) ){998 testcase( p->selFlags & SF_View );999 testcase( p->selFlags & SF_CopyCte );1000 return WRC_Prune;1001 }1002 renameWalkWith(pWalker, p);1003 return WRC_Continue;1004}1005 1006/*1007** This is a Walker expression callback.1008**1009** For every TK_COLUMN node in the expression tree, search to see1010** if the column being references is the column being renamed by an1011** ALTER TABLE statement. If it is, then attach its associated1012** RenameToken object to the list of RenameToken objects being1013** constructed in RenameCtx object at pWalker->u.pRename.1014*/1015static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){1016 RenameCtx *p = pWalker->u.pRename;1017 if( pExpr->op==TK_TRIGGER1018 && pExpr->iColumn==p->iCol1019 && pWalker->pParse->pTriggerTab==p->pTab1020 ){1021 renameTokenFind(pWalker->pParse, p, (void*)pExpr);1022 }else if( pExpr->op==TK_COLUMN1023 && pExpr->iColumn==p->iCol1024 && ALWAYS(ExprUseYTab(pExpr))1025 && p->pTab==pExpr->y.pTab1026 ){1027 renameTokenFind(pWalker->pParse, p, (void*)pExpr);1028 }1029 return WRC_Continue;1030}1031 1032/*1033** The RenameCtx contains a list of tokens that reference a column that1034** is being renamed by an ALTER TABLE statement. Return the "last"1035** RenameToken in the RenameCtx and remove that RenameToken from the1036** RenameContext. "Last" means the last RenameToken encountered when1037** the input SQL is parsed from left to right. Repeated calls to this routine1038** return all column name tokens in the order that they are encountered1039** in the SQL statement.1040*/1041static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){1042 RenameToken *pBest = pCtx->pList;1043 RenameToken *pToken;1044 RenameToken **pp;1045 1046 for(pToken=pBest->pNext; pToken; pToken=pToken->pNext){1047 if( pToken->t.z>pBest->t.z ) pBest = pToken;1048 }1049 for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext);1050 *pp = pBest->pNext;1051 1052 return pBest;1053}1054 1055/*1056** Set the error message of the context passed as the first argument to1057** the result of formatting zFmt using printf() style formatting.1058*/1059static void errorMPrintf(sqlite3_context *pCtx, const char *zFmt, ...){1060 sqlite3 *db = sqlite3_context_db_handle(pCtx);1061 char *zErr = 0;1062 va_list ap;1063 va_start(ap, zFmt);1064 zErr = sqlite3VMPrintf(db, zFmt, ap);1065 va_end(ap);1066 if( zErr ){1067 sqlite3_result_error(pCtx, zErr, -1);1068 sqlite3DbFree(db, zErr);1069 }else{1070 sqlite3_result_error_nomem(pCtx);1071 }1072}1073 1074/*1075** An error occurred while parsing or otherwise processing a database1076** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an1077** ALTER TABLE RENAME COLUMN program. The error message emitted by the1078** sub-routine is currently stored in pParse->zErrMsg. This function1079** adds context to the error message and then stores it in pCtx.1080*/1081static void renameColumnParseError(1082 sqlite3_context *pCtx,1083 const char *zWhen,1084 sqlite3_value *pType,1085 sqlite3_value *pObject,1086 Parse *pParse1087){1088 const char *zT = (const char*)sqlite3_value_text(pType);1089 const char *zN = (const char*)sqlite3_value_text(pObject);1090 char *zErr;1091 1092 zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s",1093 zT, zN, (zWhen[0] ? " " : ""), zWhen,1094 pParse->zErrMsg1095 );1096 sqlite3_result_error(pCtx, zErr, -1);1097 sqlite3DbFree(pParse->db, zErr);1098}1099 1100/*1101** For each name in the the expression-list pEList (i.e. each1102** pEList->a[i].zName) that matches the string in zOld, extract the1103** corresponding rename-token from Parse object pParse and add it1104** to the RenameCtx pCtx.1105*/1106static void renameColumnElistNames(1107 Parse *pParse,1108 RenameCtx *pCtx,1109 const ExprList *pEList,1110 const char *zOld1111){1112 if( pEList ){1113 int i;1114 for(i=0; i<pEList->nExpr; i++){1115 const char *zName = pEList->a[i].zEName;1116 if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME)1117 && ALWAYS(zName!=0)1118 && 0==sqlite3_stricmp(zName, zOld)1119 ){1120 renameTokenFind(pParse, pCtx, (const void*)zName);1121 }1122 }1123 }1124}1125 1126/*1127** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName)1128** that matches the string in zOld, extract the corresponding rename-token1129** from Parse object pParse and add it to the RenameCtx pCtx.1130*/1131static void renameColumnIdlistNames(1132 Parse *pParse,1133 RenameCtx *pCtx,1134 const IdList *pIdList,1135 const char *zOld1136){1137 if( pIdList ){1138 int i;1139 for(i=0; i<pIdList->nId; i++){1140 const char *zName = pIdList->a[i].zName;1141 if( 0==sqlite3_stricmp(zName, zOld) ){1142 renameTokenFind(pParse, pCtx, (const void*)zName);1143 }1144 }1145 }1146}1147 1148 1149/*1150** Parse the SQL statement zSql using Parse object (*p). The Parse object1151** is initialized by this function before it is used.1152*/1153static int renameParseSql(1154 Parse *p, /* Memory to use for Parse object */1155 const char *zDb, /* Name of schema SQL belongs to */1156 sqlite3 *db, /* Database handle */1157 const char *zSql, /* SQL to parse */1158 int bTemp /* True if SQL is from temp schema */1159){1160 int rc;1161 u64 flags;1162 1163 sqlite3ParseObjectInit(p, db);1164 if( zSql==0 ){1165 return SQLITE_NOMEM;1166 }1167 if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){1168 return SQLITE_CORRUPT_BKPT;1169 }1170 if( bTemp ){1171 db->init.iDb = 1;1172 }else{1173 int iDb = sqlite3FindDbName(db, zDb);1174 assert( iDb>=0 && iDb<=0xff );1175 db->init.iDb = (u8)iDb;1176 }1177 p->eParseMode = PARSE_MODE_RENAME;1178 p->db = db;1179 p->nQueryLoop = 1;1180 flags = db->flags;1181 testcase( (db->flags & SQLITE_Comments)==0 && strstr(zSql," /* ")!=0 );1182 db->flags |= SQLITE_Comments;1183 rc = sqlite3RunParser(p, zSql);1184 db->flags = flags;1185 if( db->mallocFailed ) rc = SQLITE_NOMEM;1186 if( rc==SQLITE_OK1187 && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0)1188 ){1189 rc = SQLITE_CORRUPT_BKPT;1190 }1191 1192#ifdef SQLITE_DEBUG1193 /* Ensure that all mappings in the Parse.pRename list really do map to1194 ** a part of the input string. */1195 if( rc==SQLITE_OK ){1196 int nSql = sqlite3Strlen30(zSql);1197 RenameToken *pToken;1198 for(pToken=p->pRename; pToken; pToken=pToken->pNext){1199 assert( pToken->t.z>=zSql && &pToken->t.z[pToken->t.n]<=&zSql[nSql] );1200 }