/ Check-in [5d2163c734]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Rationalize some duplicated code in alter.c. Also improve error messages for ALTER TABLE RENAME COLUMN in some cases.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | alter-table-rename-column
Files: files | file ages | folders
SHA3-256: 5d2163c734aea8c0e1611af1161734bf141e7bd02c08f0b5f2e7bac3c7dfd2a5
User & Date: dan 2018-08-21 15:06:59
Context
2018-08-21
16:32
Rename internal function sqlite3RenameToken() to sqlite3RenameTokenMap() and sqlite3MoveRenameToken() to sqlite3RenameTokenRemap(). check-in: b9ae9a0a18 user: dan tags: alter-table-rename-column
15:06
Rationalize some duplicated code in alter.c. Also improve error messages for ALTER TABLE RENAME COLUMN in some cases. check-in: 5d2163c734 user: dan tags: alter-table-rename-column
08:29
Minor changes to function tokenExpr() in order to claw back cycles lost to the rename-column change. check-in: 479976955e user: dan tags: alter-table-rename-column
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/alter.c.

  1075   1075     const char *zN = sqlite3_value_text(pObject);
  1076   1076     char *zErr;
  1077   1077   
  1078   1078     zErr = sqlite3_mprintf("error processing %s %s: %s", zT, zN, pParse->zErrMsg);
  1079   1079     sqlite3_result_error(pCtx, zErr, -1);
  1080   1080     sqlite3_free(zErr);
  1081   1081   }
         1082  +
         1083  +/*
         1084  +** For each name in the the expression-list pEList (i.e. each
         1085  +** pEList->a[i].zName) that matches the string in zOld, extract the 
         1086  +** corresponding rename-token from Parse object pParse and add it
         1087  +** to the RenameCtx pCtx.
         1088  +*/
         1089  +static void renameColumnElistNames(
         1090  +  Parse *pParse, 
         1091  +  RenameCtx *pCtx, 
         1092  +  ExprList *pEList, 
         1093  +  const char *zOld
         1094  +){
         1095  +  if( pEList ){
         1096  +    int i;
         1097  +    for(i=0; i<pEList->nExpr; i++){
         1098  +      char *zName = pEList->a[i].zName;
         1099  +      if( 0==sqlite3_stricmp(zName, zOld) ){
         1100  +        renameTokenFind(pParse, pCtx, (void*)zName);
         1101  +      }
         1102  +    }
         1103  +  }
         1104  +}
         1105  +
         1106  +/*
         1107  +** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) 
         1108  +** that matches the string in zOld, extract the corresponding rename-token 
         1109  +** from Parse object pParse and add it to the RenameCtx pCtx.
         1110  +*/
         1111  +static void renameColumnIdlistNames(
         1112  +  Parse *pParse, 
         1113  +  RenameCtx *pCtx, 
         1114  +  IdList *pIdList, 
         1115  +  const char *zOld
         1116  +){
         1117  +  if( pIdList ){
         1118  +    int i;
         1119  +    for(i=0; i<pIdList->nId; i++){
         1120  +      char *zName = pIdList->a[i].zName;
         1121  +      if( 0==sqlite3_stricmp(zName, zOld) ){
         1122  +        renameTokenFind(pParse, pCtx, (void*)zName);
         1123  +      }
         1124  +    }
         1125  +  }
         1126  +}
  1082   1127   
  1083   1128   /*
  1084   1129   ** SQL function:
  1085   1130   **
  1086   1131   **     sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld)
  1087   1132   **
  1088   1133   **   0. zSql:     SQL statement to rewrite
................................................................................
  1271   1316           pStep=pStep->pNext
  1272   1317       ){
  1273   1318         if( pStep->pSelect ){
  1274   1319           sqlite3SelectPrep(&sParse, pStep->pSelect, &sNC);
  1275   1320           if( sParse.nErr ) rc = sParse.rc;
  1276   1321         }
  1277   1322         if( rc==SQLITE_OK && pStep->zTarget ){ 
  1278         -        Table *pTarget = sqlite3FindTable(db, pStep->zTarget, zDb);
         1323  +        Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb);
  1279   1324           if( pTarget==0 ){
  1280   1325             rc = SQLITE_ERROR;
  1281   1326           }else{
  1282   1327             SrcList sSrc;
  1283   1328             memset(&sSrc, 0, sizeof(sSrc));
  1284   1329             sSrc.nSrc = 1;
  1285   1330             sSrc.a[0].zName = pStep->zTarget;
................................................................................
  1292   1337               rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
  1293   1338             }
  1294   1339             assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) );
  1295   1340             if( pStep->pUpsert ){
  1296   1341               Upsert *pUpsert = pStep->pUpsert;
  1297   1342               assert( rc==SQLITE_OK );
  1298   1343               rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
  1299         -            if( rc==SQLITE_OK && pUpsert->pUpsertSet){
         1344  +            if( rc==SQLITE_OK ){
  1300   1345                 ExprList *pUpsertSet = pUpsert->pUpsertSet;
  1301         -              rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet);
  1302         -              if( rc==SQLITE_OK && pTarget==pTab ){
  1303         -                for(i=0; i<pUpsertSet->nExpr; i++){
  1304         -                  char *zName = pUpsertSet->a[i].zName;
  1305         -                  if( 0==sqlite3_stricmp(zName, zOld) ){
  1306         -                    renameTokenFind(&sParse, &sCtx, (void*)zName);
  1307         -                  }
  1308         -                }
         1346  +              if( pTarget==pTab ){
         1347  +                renameColumnElistNames(&sParse, &sCtx, pUpsertSet, zOld);
  1309   1348                 }
         1349  +              rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet);
  1310   1350               }
  1311   1351               if( rc==SQLITE_OK ){
  1312   1352                 rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere);
  1313   1353               }
  1314   1354               if( rc==SQLITE_OK ){
  1315   1355                 rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
  1316   1356               }
  1317   1357             }
  1318   1358   
  1319   1359             if( rc==SQLITE_OK && pTarget==pTab ){
  1320         -            if( pStep->pIdList ){
  1321         -              for(i=0; i<pStep->pIdList->nId; i++){
  1322         -                char *zName = pStep->pIdList->a[i].zName;
  1323         -                if( 0==sqlite3_stricmp(zName, zOld) ){
  1324         -                  renameTokenFind(&sParse, &sCtx, (void*)zName);
  1325         -                }
  1326         -              }
  1327         -            }
  1328         -            if( pStep->op==TK_UPDATE ){
  1329         -              assert( pStep->pExprList );
  1330         -              for(i=0; i<pStep->pExprList->nExpr; i++){
  1331         -                char *zName = pStep->pExprList->a[i].zName;
  1332         -                if( 0==sqlite3_stricmp(zName, zOld) ){
  1333         -                  renameTokenFind(&sParse, &sCtx, (void*)zName);
  1334         -                }
  1335         -              }
  1336         -            }
         1360  +            renameColumnIdlistNames(&sParse, &sCtx, pStep->pIdList, zOld);
         1361  +            renameColumnElistNames(&sParse, &sCtx, pStep->pExprList, zOld);
  1337   1362             }
  1338   1363           }
  1339   1364         }
  1340   1365       }
  1341   1366   
  1342   1367       if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
  1343   1368   
  1344   1369       /* Find tokens to edit in UPDATE OF clause */
  1345         -    if( sParse.pTriggerTab==pTab && sParse.pNewTrigger->pColumns ){
  1346         -      for(i=0; i<sParse.pNewTrigger->pColumns->nId; i++){
  1347         -        char *zName = sParse.pNewTrigger->pColumns->a[i].zName;
  1348         -        if( 0==sqlite3_stricmp(zName, zOld) ){
  1349         -          renameTokenFind(&sParse, &sCtx, (void*)zName);
  1350         -        }
  1351         -      }
         1370  +    if( sParse.pTriggerTab==pTab ){
         1371  +      renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld);
  1352   1372       }
  1353   1373   
  1354   1374       /* Find tokens to edit in WHEN clause */
  1355   1375       sqlite3WalkExpr(&sWalker, sParse.pNewTrigger->pWhen);
  1356   1376   
  1357   1377       /* Find tokens to edit in trigger steps */
  1358   1378       for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){
................................................................................
  1435   1455   
  1436   1456   /*
  1437   1457   ** Register built-in functions used to help implement ALTER TABLE
  1438   1458   */
  1439   1459   void sqlite3AlterFunctions(void){
  1440   1460     static FuncDef aAlterTableFuncs[] = {
  1441   1461       FUNCTION(sqlite_rename_table,   2, 0, 0, renameTableFunc),
  1442         -    FUNCTION(sqlite_rename_column,   8, 0, 0, renameColumnFunc),
         1462  +    FUNCTION(sqlite_rename_column,  8, 0, 0, renameColumnFunc),
  1443   1463   #ifndef SQLITE_OMIT_TRIGGER
  1444   1464       FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
  1445   1465   #endif
  1446   1466   #ifndef SQLITE_OMIT_FOREIGN_KEY
  1447   1467       FUNCTION(sqlite_rename_parent,  3, 0, 0, renameParentFunc),
  1448   1468   #endif
  1449   1469     };
  1450   1470     sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
  1451   1471   }
  1452   1472   #endif  /* SQLITE_ALTER_TABLE */

Changes to test/altercol.test.

   590    590     3 {
   591    591       CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN
   592    592         INSERT INTO x1(i, t) VALUES(new.i+1, new.t||'1') 
   593    593           ON CONFLICT (tttttt) DO UPDATE SET t=i+1;
   594    594       END;
   595    595     } {no such column: tttttt}
   596    596   
   597         -
          597  +  4 {
          598  +    CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN
          599  +      INSERT INTO nosuchtable VALUES(new.i, new.t);
          600  +    END;
          601  +  } {no such table: main.nosuchtable}
   598    602   } {
   599    603     do_execsql_test 13.2.$tn.1 "
   600    604       DROP TRIGGER IF EXISTS tr1;
   601    605       $trigger
   602    606     "
   603    607   
   604    608     do_catchsql_test 13.2.$tn.2 {