private void handleChangeColumn(org.apache.hadoop.hive.metastore.api.Table hmsTable) throws MetaException {
    List<FieldSchema> hmsCols = hmsTable.getSd().getCols();
    List<FieldSchema> icebergCols = HiveSchemaUtil.convert(icebergTable.schema());
    // compute schema difference for renames, type/comment changes
    HiveSchemaUtil.SchemaDifference schemaDifference = HiveSchemaUtil.getSchemaDiff(hmsCols, icebergCols, true);
    // check column reorder (which could happen even in the absence of any rename, type or comment change)
    Map<String, String> renameMapping = ImmutableMap.of();
    if (!schemaDifference.getMissingFromSecond().isEmpty()) {
      renameMapping = ImmutableMap.of(
          schemaDifference.getMissingFromSecond().get(0).getName(),
          schemaDifference.getMissingFromFirst().get(0).getName());
    }
    Pair<String, Optional<String>> outOfOrder = HiveSchemaUtil.getReorderedColumn(hmsCols, icebergCols, renameMapping);

    if (!schemaDifference.isEmpty() || outOfOrder != null) {
      transaction = icebergTable.newTransaction();
      updateSchema = transaction.updateSchema();
    } else {
      // we should get here if the user didn't change anything about the column
      // i.e. no changes to the name, type, comment or order
      LOG.info("Found no difference between new and old schema for ALTER TABLE CHANGE COLUMN for" +
          " table: {}. There will be no Iceberg commit.", hmsTable.getTableName());
      return;
    }

    // case 1: column name has been renamed
    if (!schemaDifference.getMissingFromSecond().isEmpty()) {
      FieldSchema updatedField = schemaDifference.getMissingFromSecond().get(0);
      FieldSchema oldField = schemaDifference.getMissingFromFirst().get(0);
      updateSchema.renameColumn(oldField.getName(), updatedField.getName());

      // check if type/comment changed too
      if (!Objects.equals(oldField.getType(), updatedField.getType())) {
        updateSchema.updateColumn(oldField.getName(), getPrimitiveTypeOrThrow(updatedField), updatedField.getComment());
      } else if (!Objects.equals(oldField.getComment(), updatedField.getComment())) {
        updateSchema.updateColumnDoc(oldField.getName(), updatedField.getComment());
      }

    // case 2: only column type and/or comment changed
    } else if (!schemaDifference.getTypeChanged().isEmpty()) {
      FieldSchema updatedField = schemaDifference.getTypeChanged().get(0);
      updateSchema.updateColumn(updatedField.getName(), getPrimitiveTypeOrThrow(updatedField),
          updatedField.getComment());

    // case 3: only comment changed
    } else if (!schemaDifference.getCommentChanged().isEmpty()) {
      FieldSchema updatedField = schemaDifference.getCommentChanged().get(0);
      updateSchema.updateColumnDoc(updatedField.getName(), updatedField.getComment());
    }

    // case 4: handle any order change
    if (outOfOrder != null) {
      if (outOfOrder.second().isPresent()) {
        updateSchema.moveAfter(outOfOrder.first(), outOfOrder.second().get());
      } else {
        updateSchema.moveFirst(outOfOrder.first());
      }
    }
    updateSchema.commit();

    handlePartitionRename(schemaDifference);
  }
Calculates the properties we would like to send to the catalog.
<ul>
<li>The base of the properties is the properties stored at the Hive Metastore for the given table
<li>We add the {@link Catalogs#LOCATION} as the table location
<li>We add the {@link Catalogs#NAME} as TableIdentifier defined by the database name and table name
<li>We add the serdeProperties of the HMS table
<li>We remove some parameters that we don't want to push down to the Iceberg table props
</ul>
@param hmsTable Table for which we are calculating the properties
@return The properties we can provide for Iceberg functions, like {@link Catalogs}
iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergMetaHook.java