private void alterTable()

in fe/src/main/java/org/apache/impala/service/CatalogOpExecutor.java [1188:1457]


  private void alterTable(TAlterTableParams params, @Nullable String debugAction,
      boolean wantMinimalResult, TDdlExecResponse response, EventSequence catalogTimeline)
      throws ImpalaException {
    // When true, loads the file/block metadata.
    boolean reloadFileMetadata = false;
    // When true, loads the table schema and the column stats from the Hive Metastore.
    boolean reloadTableSchema = false;

    Reference<Long> numUpdatedPartitions = new Reference<>(0L);

    TableName tableName = TableName.fromThrift(params.getTable_name());
    Table tbl = getExistingTable(tableName.getDb(), tableName.getTbl(),
        "Load for ALTER TABLE", catalogTimeline);
    if (params.getAlter_type() == TAlterTableType.RENAME_VIEW
        || params.getAlter_type() == TAlterTableType.RENAME_TABLE) {
      TableName newTableName = TableName.fromThrift(
          params.getRename_params().getNew_table_name());
      Preconditions.checkState(!catalog_.isBlacklistedTable(newTableName),
          String.format("Can't rename to blacklisted table name: %s. %s", newTableName,
              BLACKLISTED_TABLES_INCONSISTENT_ERR_STR));
    }
    tryWriteLock(tbl, catalogTimeline);
    // get table's catalogVersion before altering it
    long oldCatalogVersion = tbl.getCatalogVersion();
    // Get a new catalog version, wrap it in InProgressTableModification, and assign new
    // version to the table being altered.
    InProgressTableModification modification =
        new InProgressTableModification(catalog_, tbl);
    catalog_.getLock().writeLock().unlock();
    modification.addCatalogServiceIdentifiersToTable();
    final Timer.Context context
        = tbl.getMetrics().getTimer(Table.ALTER_DURATION_METRIC).time();
    try {
      if (params.getAlter_type() == TAlterTableType.RENAME_VIEW
          || params.getAlter_type() == TAlterTableType.RENAME_TABLE) {
        alterTableOrViewRename(tbl,
            TableName.fromThrift(params.getRename_params().getNew_table_name()),
            modification, wantMinimalResult, response, catalogTimeline, debugAction);
        modification.validateInProgressModificationComplete();
        return;
      }

      String responseSummaryMsg = null;

      if (tbl instanceof KuduTable && altersKuduTable(params.getAlter_type())) {
        alterKuduTable(params, response, (KuduTable) tbl, modification, wantMinimalResult,
            catalogTimeline, debugAction);
        modification.validateInProgressModificationComplete();
        return;
      } else if (tbl instanceof IcebergTable &&
          altersIcebergTable(params.getAlter_type())) {
        boolean needToUpdateHms = alterIcebergTable(params, response, (IcebergTable) tbl,
            wantMinimalResult, debugAction, catalogTimeline, modification);
        if (!needToUpdateHms) {
          modification.validateInProgressModificationComplete();
          return;
        }
      }

      boolean reloadMetadata = true;
      switch (params.getAlter_type()) {
        case ADD_COLUMNS:
          boolean added = false;
          // Columns could be ignored/cleared in AlterTableAddColsStmt,
          // that may cause columns to be empty.
          if (params.getAdd_cols_params() != null
              && params.getAdd_cols_params().getColumnsSize() != 0) {
            TAlterTableAddColsParams addColParams = params.getAdd_cols_params();
            added = alterTableAddCols(tbl, addColParams.getColumns(),
                addColParams.isIf_not_exists(), catalogTimeline, modification);
            reloadTableSchema = true;
          }
          if (added) {
            responseSummaryMsg = "New column(s) have been added to the table.";
          } else {
            responseSummaryMsg = "No new column(s) have been added to the table.";
          }
          break;
        case REPLACE_COLUMNS:
          TAlterTableReplaceColsParams replaceColParams = params.getReplace_cols_params();
          alterTableReplaceCols(
              tbl, replaceColParams.getColumns(), catalogTimeline, modification);
          reloadTableSchema = true;
          responseSummaryMsg = "Table columns have been replaced.";
          break;
        case ADD_PARTITION:
          // Create and add HdfsPartition objects to the corresponding HdfsTable and load
          // their block metadata. Update the table object with the new catalog version.
          THdfsFileFormat format = null;
          if(params.isSetSet_file_format_params()) {
            format = params.getSet_file_format_params().file_format;
          }
          alterTableAddPartitions(tbl, params.getAdd_partition_params(), format,
              catalogTimeline, modification, debugAction);
          reloadMetadata = false;
          responseSummaryMsg = "New partition has been added to the table.";
          break;
        case DROP_COLUMN:
          TAlterTableDropColParams dropColParams = params.getDrop_col_params();
          alterTableDropCol(
              tbl, dropColParams.getCol_name(), catalogTimeline, modification);
          reloadTableSchema = true;
          responseSummaryMsg = "Column has been dropped.";
          break;
        case ALTER_COLUMN:
          TAlterTableAlterColParams alterColParams = params.getAlter_col_params();
          alterTableAlterCol(tbl, alterColParams.getCol_name(),
              alterColParams.getNew_col_def(), catalogTimeline, modification);
          reloadTableSchema = true;
          responseSummaryMsg = "Column has been altered.";
          break;
        case DROP_PARTITION:
          TAlterTableDropPartitionParams dropPartParams =
              params.getDrop_partition_params();
          // Drop the partition from the corresponding table. If "purge" option is
          // specified partition data is purged by skipping Trash, if configured.
          alterTableDropPartition(tbl, dropPartParams.getPartition_set(),
              dropPartParams.isIf_exists(), dropPartParams.isPurge(),
              numUpdatedPartitions, catalogTimeline, modification);
          responseSummaryMsg =
              "Dropped " + numUpdatedPartitions.getRef() + " partition(s).";
          reloadMetadata = false;
          break;
        case RENAME_TABLE:
        case RENAME_VIEW:
          Preconditions.checkState(false,
              "RENAME TABLE/VIEW operation has been processed");
          break;
        case SET_FILE_FORMAT:
          TAlterTableSetFileFormatParams fileFormatParams =
              params.getSet_file_format_params();
          reloadFileMetadata = alterTableSetFileFormat(tbl,
              fileFormatParams.getPartition_set(), fileFormatParams.getFile_format(),
              numUpdatedPartitions, catalogTimeline, modification);

          if (fileFormatParams.isSetPartition_set()) {
            responseSummaryMsg =
                "Updated " + numUpdatedPartitions.getRef() + " partition(s).";
          } else {
            responseSummaryMsg = "Updated table.";
          }
          break;
        case SET_ROW_FORMAT:
          TAlterTableSetRowFormatParams rowFormatParams =
              params.getSet_row_format_params();
          reloadFileMetadata = alterTableSetRowFormat(tbl,
              rowFormatParams.getPartition_set(), rowFormatParams.getRow_format(),
              numUpdatedPartitions, catalogTimeline, modification);
          if (rowFormatParams.isSetPartition_set()) {
            responseSummaryMsg =
                "Updated " + numUpdatedPartitions.getRef() + " partition(s).";
          } else {
            responseSummaryMsg = "Updated table.";
          }
          break;
        case SET_LOCATION:
          TAlterTableSetLocationParams setLocationParams =
              params.getSet_location_params();
          List<TPartitionKeyValue> partitionSpec = setLocationParams.getPartition_spec();
          reloadFileMetadata = alterTableSetLocation(tbl, partitionSpec,
              setLocationParams.getLocation(), catalogTimeline, modification);
          if (partitionSpec == null) {
            responseSummaryMsg = "New location has been set.";
          } else {
            responseSummaryMsg = "New location has been set for the specified partition.";
          }
          break;
        case SET_TBL_PROPERTIES:
          alterTableSetTblProperties(tbl, params.getSet_tbl_properties_params(),
              numUpdatedPartitions, catalogTimeline, modification);
          reloadTableSchema = true;
          if (params.getSet_tbl_properties_params().isSetPartition_set()) {
            responseSummaryMsg =
                "Updated " + numUpdatedPartitions.getRef() + " partition(s).";
          } else {
            responseSummaryMsg = "Updated table.";
          }
          break;
        case UNSET_TBL_PROPERTIES:
          alterTableUnSetTblProperties(tbl, params.getUnset_tbl_properties_params(),
              numUpdatedPartitions, catalogTimeline, modification);
          reloadTableSchema = true;
          if (params.getUnset_tbl_properties_params().isSetPartition_set()) {
            responseSummaryMsg =
                "Updated " + numUpdatedPartitions.getRef() + " partition(s).";
          } else {
            responseSummaryMsg = "Updated table.";
          }
          break;
        case SET_VIEW_PROPERTIES:
          alterViewSetTblProperties(
              tbl, params.getSet_tbl_properties_params(), catalogTimeline, modification);
          reloadTableSchema = true;
          responseSummaryMsg = "Updated view.";
          break;
        case UNSET_VIEW_PROPERTIES:
          alterViewUnSetTblProperties(tbl, params.getUnset_tbl_properties_params(),
              catalogTimeline, modification);
          reloadTableSchema = true;
          responseSummaryMsg = "Updated view.";
          break;
        case UPDATE_STATS:
          Preconditions.checkState(params.isSetUpdate_stats_params());
          Reference<Long> numUpdatedColumns = new Reference<>(0L);
          alterTableUpdateStats(tbl, params.getUpdate_stats_params(),
              numUpdatedPartitions, numUpdatedColumns, debugAction, catalogTimeline,
              modification);
          reloadTableSchema = true;
          responseSummaryMsg = "Updated " + numUpdatedPartitions.getRef() +
              " partition(s) and " + numUpdatedColumns.getRef() + " column(s).";
          break;
        case SET_CACHED:
          Preconditions.checkState(params.isSetSet_cached_params());
          String op = params.getSet_cached_params().getCache_op().isSet_cached() ?
              "Cached " : "Uncached ";
          if (params.getSet_cached_params().getPartition_set() == null) {
            reloadFileMetadata = alterTableSetCached(
                tbl, params.getSet_cached_params(), catalogTimeline, modification);
            responseSummaryMsg = op + "table.";
          } else {
            alterPartitionSetCached(tbl, params.getSet_cached_params(),
                numUpdatedPartitions, catalogTimeline, modification);
            responseSummaryMsg = op + numUpdatedPartitions.getRef() + " partition(s).";
          }
          break;
        case RECOVER_PARTITIONS:
          alterTableRecoverPartitions(tbl, debugAction, catalogTimeline, modification);
          responseSummaryMsg = "Partitions have been recovered.";
          break;
        case SET_OWNER:
          Preconditions.checkState(params.isSetSet_owner_params());
          alterTableOrViewSetOwner(
              tbl, params.getSet_owner_params(), response, catalogTimeline, modification);
          responseSummaryMsg = "Updated table/view.";
          break;
        default:
          throw new UnsupportedOperationException(
              "Unknown ALTER TABLE operation type: " + params.getAlter_type());
      }

      // Make sure we won't forget finalizing the modification.
      if (modification.isInProgress()) {
        Preconditions.checkState(reloadMetadata,
            "In-progress modification of table %s must be followed by metadata reload.",
            tbl.getFullName());
      }
      if (reloadMetadata) {
        loadTableMetadata(tbl, modification.newVersionNumber(), reloadFileMetadata,
            reloadTableSchema, "ALTER TABLE " + params.getAlter_type().name(),
            debugAction, catalogTimeline);
        modification.markInflightEventRegistrationComplete();
      }
      addSummary(response, responseSummaryMsg);
      // add table to catalog update if its old and existing versions do not match
      if (tbl.getCatalogVersion() != oldCatalogVersion) {
        addTableToCatalogUpdate(tbl, wantMinimalResult, response.result);
      }
      // Make sure all the modifications are done.
      modification.validateInProgressModificationComplete();
    } catch (Exception ex) {
      modification.cancelInflightEventIfExist();
      throw ex;
    } finally {
      context.stop();
      UnlockWriteLockIfErronouslyLocked();
      // Clear in-progress modifications in case of exceptions.
      tbl.resetInProgressModification();
      tbl.releaseWriteLock();
    }
  }