/ Check-in [ca5184a2]
Login

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

Overview
Comment:If the new column name in an ALTER TABLE RENAME COLUMN statement is quoted, then also use quotes for the column name in the edited SQL statements.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | alter-table-rename-column
Files: files | file ages | folders
SHA3-256: ca5184a25f9150540a3e401ef67df0606efa7a294d70e3fa5edad9854003eb36
User & Date: dan 2018-08-11 20:38:33
Context
2018-08-11
20:46
Add the "atrc" test program. "Atrc" is short for "ALTER TABLE RENAME COLUMN". See the header comment on the program itself for further information. check-in: ed64a55a user: drh tags: alter-table-rename-column
20:38
If the new column name in an ALTER TABLE RENAME COLUMN statement is quoted, then also use quotes for the column name in the edited SQL statements. check-in: ca5184a2 user: dan tags: alter-table-rename-column
18:34
Avoid an assert() sometimes triggered by ALTER TABLE RENAME COLUMN in non-debug builds. check-in: 520c1c75 user: dan tags: alter-table-rename-column
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/alter.c.

   799    799     sqlite3 *db = pParse->db;
   800    800     Table *pTab;                    /* Table being updated */
   801    801     int iCol;                       /* Index of column being renamed */
   802    802     char *zOld = 0;
   803    803     char *zNew = 0;
   804    804     const char *zDb;
   805    805     int iSchema;
          806  +  int bQuote;
   806    807   
   807    808     pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
   808    809     if( !pTab ) goto exit_rename_column;
   809    810     if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column;
   810    811     
   811    812     iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
   812    813     assert( iSchema>=0 );
................................................................................
   820    821     if( iCol==pTab->nCol ){
   821    822       sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld);
   822    823       goto exit_rename_column;
   823    824     }
   824    825   
   825    826     zNew = sqlite3NameFromToken(db, pNew);
   826    827     if( !zNew ) goto exit_rename_column;
   827         -
          828  +  assert( pNew->n>0 );
          829  +  bQuote = sqlite3Isquote(pNew->z[0]);
   828    830     sqlite3NestedParse(pParse, 
   829    831         "UPDATE \"%w\".%s SET "
   830         -      "sql = sqlite_rename_column(sql, %d, %Q, %Q, %Q) "
          832  +      "sql = sqlite_rename_column(sql, %d, %d, %Q, %Q, %Q) "
   831    833         "WHERE name NOT LIKE 'sqlite_%%' AND ("
   832    834         "   type = 'table' OR (type='index' AND tbl_name = %Q)"
   833    835         ")",
   834         -      zDb, MASTER_NAME, iCol, zNew, pTab->zName, zOld, pTab->zName
          836  +      zDb, MASTER_NAME, iCol, bQuote, zNew, pTab->zName, zOld, pTab->zName
   835    837     );
   836    838   
   837    839     /* Drop and reload the database schema. */
   838    840     if( pParse->pVdbe ){
   839    841       sqlite3ChangeCookie(pParse, iSchema);
   840    842       sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iSchema, 0);
   841    843     }
................................................................................
   927    929     for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext);
   928    930     *pp = pBest->pNext;
   929    931   
   930    932     return pBest;
   931    933   }
   932    934   
   933    935   /*
   934         -** sqlite_rename_table(SQL, iCol, zNew, zTable, zOld)
          936  +** sqlite_rename_column(SQL, iCol, bQuote, zNew, zTable, zOld)
   935    937   */
   936    938   static void renameColumnFunc(
   937    939     sqlite3_context *context,
   938    940     int NotUsed,
   939    941     sqlite3_value **argv
   940    942   ){
   941    943     sqlite3 *db = sqlite3_context_db_handle(context);
   942    944     struct RenameCtx sCtx;
   943    945     const char *zSql = (const char*)sqlite3_value_text(argv[0]);
   944    946     int nSql = sqlite3_value_bytes(argv[0]);
   945         -  const char *zNew = (const char*)sqlite3_value_text(argv[2]);
   946         -  int nNew = sqlite3_value_bytes(argv[2]);
   947         -  const char *zTable = (const char*)sqlite3_value_text(argv[3]);
   948         -  const char *zOld = (const char*)sqlite3_value_text(argv[4]);
          947  +  int bQuote = sqlite3_value_int(argv[2]);
          948  +  const char *zNew = (const char*)sqlite3_value_text(argv[3]);
          949  +  int nNew = sqlite3_value_bytes(argv[3]);
          950  +  const char *zTable = (const char*)sqlite3_value_text(argv[4]);
          951  +  const char *zOld = (const char*)sqlite3_value_text(argv[5]);
   949    952   
   950    953     int rc;
   951    954     char *zErr = 0;
   952    955     Parse sParse;
   953    956     Walker sWalker;
   954    957     Index *pIdx;
   955    958     char *zOut = 0;
................................................................................
   987    990         sqlite3_result_error_code(context, rc);
   988    991       }
   989    992       sqlite3DbFree(db, zErr);
   990    993       sqlite3_free(zQuot);
   991    994       return;
   992    995     }
   993    996   
   994         -  for(i=0; i<nNew; i++){
   995         -    if( sqlite3IsIdChar(zNew[i])==0 ){
   996         -      zNew = zQuot;
   997         -      nNew = nQuot;
   998         -      break;
   999         -    }
          997  +  if( bQuote ){
          998  +    zNew = zQuot;
          999  +    nNew = nQuot;
  1000   1000     }
  1001   1001   
  1002   1002   #ifdef SQLITE_DEBUG
  1003   1003     assert( sqlite3Strlen30(zSql)==nSql );
  1004   1004     {
  1005   1005       RenameToken *pToken;
  1006   1006       for(pToken=sParse.pRename; pToken; pToken=pToken->pNext){
................................................................................
  1055   1055         }
  1056   1056       }
  1057   1057     }else{
  1058   1058       sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr);
  1059   1059       sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
  1060   1060     }
  1061   1061   
  1062         -  zOut = sqlite3DbMallocZero(db, nSql + sCtx.nList*nNew + 1);
         1062  +  assert( nQuot>=nNew );
         1063  +  zOut = sqlite3DbMallocZero(db, nSql + sCtx.nList*nQuot + 1);
  1063   1064     if( zOut ){
  1064   1065       int nOut = nSql;
  1065   1066       memcpy(zOut, zSql, nSql);
  1066   1067       while( sCtx.pList ){
  1067   1068         int iOff;                   /* Offset of token to replace in zOut */
  1068   1069         RenameToken *pBest = renameColumnTokenNext(&sCtx);
  1069   1070   
................................................................................
  1105   1106   
  1106   1107   /*
  1107   1108   ** Register built-in functions used to help implement ALTER TABLE
  1108   1109   */
  1109   1110   void sqlite3AlterFunctions(void){
  1110   1111     static FuncDef aAlterTableFuncs[] = {
  1111   1112       FUNCTION(sqlite_rename_table,   2, 0, 0, renameTableFunc),
  1112         -    FUNCTION(sqlite_rename_column,   5, 0, 0, renameColumnFunc),
         1113  +    FUNCTION(sqlite_rename_column,   6, 0, 0, renameColumnFunc),
  1113   1114   #ifndef SQLITE_OMIT_TRIGGER
  1114   1115       FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
  1115   1116   #endif
  1116   1117   #ifndef SQLITE_OMIT_FOREIGN_KEY
  1117   1118       FUNCTION(sqlite_rename_parent,  3, 0, 0, renameParentFunc),
  1118   1119   #endif
  1119   1120     };
  1120   1121     sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
  1121   1122   }
  1122   1123   #endif  /* SQLITE_ALTER_TABLE */

Changes to test/altercol.test.

   195    195       CHECK( length(uuid)>=40 AND rid>0 )
   196    196     );
   197    197   }
   198    198   
   199    199   do_execsql_test 6.1 {
   200    200     ALTER TABLE "blob" RENAME COLUMN "rid" TO "a1";
   201    201   }
          202  +
          203  +do_catchsql_test 6.2 {
          204  +  ALTER TABLE "blob" RENAME COLUMN "a1" TO [where];
          205  +} {0 {}}
          206  +
          207  +do_execsql_test 6.3 {
          208  +  SELECT "where" FROM blob;
          209  +} {}
   202    210   
   203    211   finish_test
   204    212