SQLite

Check-in [ca5184a25f]
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
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.809
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: ed64a55a22 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: ca5184a25f 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: 520c1c75da user: dan tags: alter-table-rename-column)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/alter.c.
799
800
801
802
803
804
805

806
807
808
809
810
811
812
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813







+







  sqlite3 *db = pParse->db;
  Table *pTab;                    /* Table being updated */
  int iCol;                       /* Index of column being renamed */
  char *zOld = 0;
  char *zNew = 0;
  const char *zDb;
  int iSchema;
  int bQuote;

  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
  if( !pTab ) goto exit_rename_column;
  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column;
  
  iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iSchema>=0 );
820
821
822
823
824
825
826
827


828
829
830

831
832
833
834

835
836
837
838
839
840
841
821
822
823
824
825
826
827

828
829
830
831

832
833
834
835

836
837
838
839
840
841
842
843







-
+
+


-
+



-
+







  if( iCol==pTab->nCol ){
    sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld);
    goto exit_rename_column;
  }

  zNew = sqlite3NameFromToken(db, pNew);
  if( !zNew ) goto exit_rename_column;

  assert( pNew->n>0 );
  bQuote = sqlite3Isquote(pNew->z[0]);
  sqlite3NestedParse(pParse, 
      "UPDATE \"%w\".%s SET "
      "sql = sqlite_rename_column(sql, %d, %Q, %Q, %Q) "
      "sql = sqlite_rename_column(sql, %d, %d, %Q, %Q, %Q) "
      "WHERE name NOT LIKE 'sqlite_%%' AND ("
      "   type = 'table' OR (type='index' AND tbl_name = %Q)"
      ")",
      zDb, MASTER_NAME, iCol, zNew, pTab->zName, zOld, pTab->zName
      zDb, MASTER_NAME, iCol, bQuote, zNew, pTab->zName, zOld, pTab->zName
  );

  /* Drop and reload the database schema. */
  if( pParse->pVdbe ){
    sqlite3ChangeCookie(pParse, iSchema);
    sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iSchema, 0);
  }
927
928
929
930
931
932
933
934

935
936
937
938
939
940
941
942
943
944

945
946
947
948




949
950
951
952
953
954
955
929
930
931
932
933
934
935

936
937
938
939
940
941
942
943
944
945
946
947




948
949
950
951
952
953
954
955
956
957
958







-
+










+
-
-
-
-
+
+
+
+







  for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext);
  *pp = pBest->pNext;

  return pBest;
}

/*
** sqlite_rename_table(SQL, iCol, zNew, zTable, zOld)
** sqlite_rename_column(SQL, iCol, bQuote, zNew, zTable, zOld)
*/
static void renameColumnFunc(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  struct RenameCtx sCtx;
  const char *zSql = (const char*)sqlite3_value_text(argv[0]);
  int nSql = sqlite3_value_bytes(argv[0]);
  int bQuote = sqlite3_value_int(argv[2]);
  const char *zNew = (const char*)sqlite3_value_text(argv[2]);
  int nNew = sqlite3_value_bytes(argv[2]);
  const char *zTable = (const char*)sqlite3_value_text(argv[3]);
  const char *zOld = (const char*)sqlite3_value_text(argv[4]);
  const char *zNew = (const char*)sqlite3_value_text(argv[3]);
  int nNew = sqlite3_value_bytes(argv[3]);
  const char *zTable = (const char*)sqlite3_value_text(argv[4]);
  const char *zOld = (const char*)sqlite3_value_text(argv[5]);

  int rc;
  char *zErr = 0;
  Parse sParse;
  Walker sWalker;
  Index *pIdx;
  char *zOut = 0;
987
988
989
990
991
992
993
994
995
996
997



998
999
1000
1001
1002
1003
1004
1005
1006
990
991
992
993
994
995
996




997
998
999


1000
1001
1002
1003
1004
1005
1006







-
-
-
-
+
+
+
-
-







      sqlite3_result_error_code(context, rc);
    }
    sqlite3DbFree(db, zErr);
    sqlite3_free(zQuot);
    return;
  }

  for(i=0; i<nNew; i++){
    if( sqlite3IsIdChar(zNew[i])==0 ){
      zNew = zQuot;
      nNew = nQuot;
  if( bQuote ){
    zNew = zQuot;
    nNew = nQuot;
      break;
    }
  }

#ifdef SQLITE_DEBUG
  assert( sqlite3Strlen30(zSql)==nSql );
  {
    RenameToken *pToken;
    for(pToken=sParse.pRename; pToken; pToken=pToken->pNext){
1055
1056
1057
1058
1059
1060
1061

1062

1063
1064
1065
1066
1067
1068
1069
1055
1056
1057
1058
1059
1060
1061
1062

1063
1064
1065
1066
1067
1068
1069
1070







+
-
+







      }
    }
  }else{
    sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr);
    sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
  }

  assert( nQuot>=nNew );
  zOut = sqlite3DbMallocZero(db, nSql + sCtx.nList*nNew + 1);
  zOut = sqlite3DbMallocZero(db, nSql + sCtx.nList*nQuot + 1);
  if( zOut ){
    int nOut = nSql;
    memcpy(zOut, zSql, nSql);
    while( sCtx.pList ){
      int iOff;                   /* Offset of token to replace in zOut */
      RenameToken *pBest = renameColumnTokenNext(&sCtx);

1105
1106
1107
1108
1109
1110
1111
1112

1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1106
1107
1108
1109
1110
1111
1112

1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123







-
+











/*
** Register built-in functions used to help implement ALTER TABLE
*/
void sqlite3AlterFunctions(void){
  static FuncDef aAlterTableFuncs[] = {
    FUNCTION(sqlite_rename_table,   2, 0, 0, renameTableFunc),
    FUNCTION(sqlite_rename_column,   5, 0, 0, renameColumnFunc),
    FUNCTION(sqlite_rename_column,   6, 0, 0, renameColumnFunc),
#ifndef SQLITE_OMIT_TRIGGER
    FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
    FUNCTION(sqlite_rename_parent,  3, 0, 0, renameParentFunc),
#endif
  };
  sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
}
#endif  /* SQLITE_ALTER_TABLE */
Changes to test/altercol.test.
195
196
197
198
199
200
201








202
203
204
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212







+
+
+
+
+
+
+
+



    CHECK( length(uuid)>=40 AND rid>0 )
  );
}

do_execsql_test 6.1 {
  ALTER TABLE "blob" RENAME COLUMN "rid" TO "a1";
}

do_catchsql_test 6.2 {
  ALTER TABLE "blob" RENAME COLUMN "a1" TO [where];
} {0 {}}

do_execsql_test 6.3 {
  SELECT "where" FROM blob;
} {}

finish_test