in fe/src/main/java/org/apache/impala/service/CatalogOpExecutor.java [3154:3305]
private void dropTableOrViewInternal(TDropTableOrViewParams params,
TableName tableName, TDdlExecResponse resp, int kudu_table_reserve_seconds,
EventSequence catalogTimeline) throws ImpalaException {
TCatalogObject removedObject = new TCatalogObject();
acquireMetastoreDdlLock(catalogTimeline);
try {
Db db = catalog_.getDb(params.getTable_name().db_name);
if (db == null) {
String dbNotExist = "Database does not exist: " + params.getTable_name().db_name;
if (params.if_exists) {
addSummary(resp, dbNotExist);
return;
}
throw new CatalogException(dbNotExist);
}
Table existingTbl = db.getTable(params.getTable_name().table_name);
if (existingTbl == null) {
if (params.if_exists) {
addSummary(resp, (params.is_table ? "Table " : "View ") + "does not exist.");
return;
}
throw new CatalogException("Table/View does not exist.");
}
// Check to make sure we don't drop a view with "drop table" statement and
// vice versa. is_table field is marked optional in TDropTableOrViewParams to
// maintain catalog api compatibility.
// TODO: Remove params.isSetIs_table() check once catalog api compatibility is
// fixed.
if (params.isSetIs_table() && ((params.is_table && existingTbl instanceof View)
|| (!params.is_table && !(existingTbl instanceof View)))) {
String errorMsg = "DROP " + (params.is_table ? "TABLE " : "VIEW ") +
"not allowed on a " + (params.is_table ? "view: " : "table: ") + tableName;
if (params.if_exists) {
addSummary(resp, "Drop " + (params.is_table ? "table " : "view ") +
"is not allowed on a " + (params.is_table ? "view." : "table."));
return;
}
throw new CatalogException(errorMsg);
}
// Retrieve the HMS table to determine if this is a Kudu or Iceberg table.
org.apache.hadoop.hive.metastore.api.Table msTbl = existingTbl.getMetaStoreTable();
if (msTbl == null) {
Preconditions.checkState(existingTbl instanceof IncompleteTable);
Stopwatch hmsLoadSW = Stopwatch.createStarted();
long hmsLoadTime;
try (MetaStoreClient msClient = catalog_.getMetaStoreClient(catalogTimeline)) {
msTbl = msClient.getHiveClient().getTable(tableName.getDb(),
tableName.getTbl());
catalogTimeline.markEvent(FETCHED_HMS_TABLE);
} catch (TException e) {
LOG.error(String.format(HMS_RPC_ERROR_FORMAT_STR, "getTable") + e.getMessage());
} finally {
hmsLoadTime = hmsLoadSW.elapsed(TimeUnit.NANOSECONDS);
}
existingTbl.updateHMSLoadTableSchemaTime(hmsLoadTime);
}
boolean isSynchronizedKuduTable = msTbl != null &&
KuduTable.isKuduTable(msTbl) && KuduTable.isSynchronizedTable(msTbl);
if (isSynchronizedKuduTable) {
KuduCatalogOpExecutor.dropTable(
msTbl, /* if exists */ true, kudu_table_reserve_seconds, catalogTimeline);
}
long eventId;
try (MetaStoreClient msClient = catalog_.getMetaStoreClient(catalogTimeline)) {
eventId = getCurrentEventId(msClient, catalogTimeline);
}
boolean isSynchronizedIcebergTable = msTbl != null &&
IcebergTable.isIcebergTable(msTbl) &&
IcebergTable.isSynchronizedTable(msTbl);
// When HMS integration is automatic, the table is dropped automatically. In all
// other cases, we need to drop the HMS table entry ourselves.
boolean isSynchronizedTable = isSynchronizedKuduTable || isSynchronizedIcebergTable;
boolean needsHmsDropTable =
(existingTbl instanceof IncompleteTable && isSynchronizedIcebergTable) ||
!isSynchronizedTable ||
!isHmsIntegrationAutomatic(msTbl);
if (!(existingTbl instanceof IncompleteTable) && isSynchronizedIcebergTable) {
Preconditions.checkState(existingTbl instanceof IcebergTable);
try {
IcebergCatalogOpExecutor.dropTable((IcebergTable)existingTbl, params.if_exists);
catalogTimeline.markEvent("Dropped table using Iceberg");
} catch (TableNotFoundException e) {
// This is unusual as normally this would have already shown up as
// (existingTbl instanceof IncompleteTable), but this can happen if
// for example the Iceberg metadata is removed.
if (!needsHmsDropTable) {
// There is no more work to be done, so throw exception.
throw e;
}
// Although dropTable() failed in Iceberg we need to also drop the table in
// HMS, so we continue here.
LOG.warn(String.format("Could not drop Iceberg table %s.%s " +
"proceeding to drop table in HMS", tableName.getDb(),
tableName.getTbl()), e);
}
}
if (needsHmsDropTable) {
try (MetaStoreClient msClient = catalog_.getMetaStoreClient(catalogTimeline)) {
msClient.getHiveClient().dropTable(
tableName.getDb(), tableName.getTbl(), true,
params.if_exists, params.purge);
catalogTimeline.markEvent("Dropped table in Metastore");
} catch (NoSuchObjectException e) {
throw new ImpalaRuntimeException(String.format("Table %s no longer exists " +
"in the Hive MetaStore. Run 'invalidate metadata %s' to update the " +
"Impala catalog.", tableName, tableName));
} catch (TException e) {
throw new ImpalaRuntimeException(
String.format(HMS_RPC_ERROR_FORMAT_STR, "dropTable"), e);
}
}
List<NotificationEvent> events = getNextMetastoreEventsForTableIfEnabled(
catalogTimeline, eventId, tableName.getDb(), tableName.getTbl(),
DropTableEvent.EVENT_TYPE);
addSummary(resp, (params.is_table ? "Table " : "View ") + "has been dropped.");
addToDeleteEventLog(events);
Table table = catalog_.removeTable(params.getTable_name().db_name,
params.getTable_name().table_name);
catalogTimeline.markEvent("Deleted table in catalog cache");
if (table == null) {
// Nothing was removed from the catalogd's cache.
resp.result.setVersion(catalog_.getCatalogVersion());
return;
}
resp.result.setVersion(table.getCatalogVersion());
uncacheTable(table, catalogTimeline);
if (table.getMetaStoreTable() != null) {
if (authzConfig_.isEnabled()) {
authzManager_.updateTableOwnerPrivilege(params.server_name,
table.getDb().getName(), table.getName(),
table.getMetaStoreTable().getOwner(),
table.getMetaStoreTable().getOwnerType(), /* newOwner */ null,
/* newOwnerType */ null, resp);
}
}
} finally {
getMetastoreDdlLock().unlock();
}
removedObject.setType(params.is_table ?
TCatalogObjectType.TABLE : TCatalogObjectType.VIEW);
removedObject.setTable(new TTable());
removedObject.getTable().setTbl_name(tableName.getTbl());
removedObject.getTable().setDb_name(tableName.getDb());
removedObject.setCatalog_version(resp.result.getVersion());
resp.result.addToRemoved_catalog_objects(removedObject);
}