Github user manishgupta88 commented on a diff in the pull request: https://github.com/apache/carbondata/pull/2990#discussion_r242871412 --- Diff: integration/spark2/src/main/scala/org/apache/spark/util/AlterTableUtil.scala --- @@ -249,32 +249,99 @@ object AlterTableUtil { * @param timeStamp * @param sparkSession */ - def revertDataTypeChanges(dbName: String, tableName: String, timeStamp: Long) + def revertColumnRenameAndDataTypeChanges(dbName: String, tableName: String, timeStamp: Long) (sparkSession: SparkSession): Unit = { val metastore = CarbonEnv.getInstance(sparkSession).carbonMetaStore val carbonTable = CarbonEnv.getCarbonTable(Some(dbName), tableName)(sparkSession) val thriftTable: TableInfo = metastore.getThriftTableInfo(carbonTable) val evolutionEntryList = thriftTable.fact_table.schema_evolution.schema_evolution_history - val updatedTime = evolutionEntryList.get(evolutionEntryList.size() - 1).time_stamp - if (updatedTime == timeStamp) { - LOGGER.error(s"Reverting changes for $dbName.$tableName") - val removedColumns = evolutionEntryList.get(evolutionEntryList.size() - 1).removed - thriftTable.fact_table.table_columns.asScala.foreach { columnSchema => - removedColumns.asScala.foreach { removedColumn => - if (columnSchema.column_id.equalsIgnoreCase(removedColumn.column_id) && - !columnSchema.isInvisible) { - columnSchema.setData_type(removedColumn.data_type) - columnSchema.setPrecision(removedColumn.precision) - columnSchema.setScale(removedColumn.scale) - } + // here, there can be maximum of two entries for schemaEvolution, when my operation is + // both column rename and datatype change. So check if last two Evolution entry timestamp is + // same, then it is both column rename and datatype change, so revert two entries,else one entry + if (evolutionEntryList.size() > 1 && + (evolutionEntryList.get(evolutionEntryList.size() - 1).time_stamp == timeStamp) && + (evolutionEntryList.get(evolutionEntryList.size() - 2).time_stamp == timeStamp)) { + LOGGER.error(s"Reverting column rename and datatype changes for $dbName.$tableName") + revertColumnSchemaChanges(thriftTable, evolutionEntryList, true) + } else { + if (evolutionEntryList.get(evolutionEntryList.size() - 1).time_stamp == timeStamp) { + LOGGER.error(s"Reverting changes for $dbName.$tableName") + revertColumnSchemaChanges(thriftTable, evolutionEntryList, false) + } + } + metastore + .revertTableSchemaInAlterFailure(carbonTable.getCarbonTableIdentifier, + thriftTable, carbonTable.getAbsoluteTableIdentifier, timeStamp)(sparkSession) + } + + /** + * This method reverts the column schema in case of failure in alter datatype change or col rename + * @param thriftTable thrift table + * @param evolutionEntryList SchemaEvolutionEntry List + * @param isBothColRenameAndDataTypeChange true if operation done is noth rename and datatype chng + */ + private def revertColumnSchemaChanges(thriftTable: TableInfo, + evolutionEntryList: util.List[SchemaEvolutionEntry], + isBothColRenameAndDataTypeChange: Boolean): Unit = { + var removedColumns: mutable.Buffer[org.apache.carbondata.format.ColumnSchema] = null + if (isBothColRenameAndDataTypeChange) { + removedColumns = evolutionEntryList.get(evolutionEntryList.size() - 1).removed.asScala ++ + evolutionEntryList.get(evolutionEntryList.size() - 2).removed.asScala + } else { + removedColumns = evolutionEntryList.get(evolutionEntryList.size() - 1).removed.asScala --- End diff -- I can see the same code in multiple classes. Try and refine the code and move this method at a common place
---