This is an automated email from the ASF dual-hosted git repository.
dengzhhu653 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new b38a4e94c33 HIVE-29423: Move delete_column_statistics_req out from
HMSHandler (#6661)
b38a4e94c33 is described below
commit b38a4e94c33fc92daad0c659b26714c853f82bc8
Author: rtrivedi12 <[email protected]>
AuthorDate: Tue Aug 4 20:02:30 2026 -0500
HIVE-29423: Move delete_column_statistics_req out from HMSHandler (#6661)
---
.../apache/hadoop/hive/metastore/HMSHandler.java | 74 ++-------
.../handler/DeleteColumnStatisticsHandler.java | 168 +++++++++++++++++++++
2 files changed, 177 insertions(+), 65 deletions(-)
diff --git
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
index 76eedeadb61..9ca06eb78a0 100644
---
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
+++
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
@@ -2552,73 +2552,17 @@ public boolean
delete_column_statistics_req(DeleteColumnStatisticsRequest req) t
startFunction("delete_column_statistics_req", ": table=" +
TableName.getQualified(parsedDbName[CAT_NAME], parsedDbName[DB_NAME],
tableName) +
" partitions=" + req.getPart_names() + " column=" + colNames + "
engine=" + engine);
- boolean ret = false, committed = false;
- List<ListenerEvent> events = new ArrayList<>();
- EventType eventType = null;
- final RawStore rawStore = getMS();
- rawStore.openTransaction();
- try {
- Table table = rawStore.getTable(parsedDbName[CAT_NAME],
parsedDbName[DB_NAME], tableName);
- boolean isPartitioned = table.getPartitionKeysSize() > 0;
- if (TxnUtils.isTransactionalTable(table)) {
- throw new MetaException("Cannot delete stats via this API for a
transactional table");
- }
- if (!isPartitioned || req.isTableLevel()) {
- ret = rawStore.deleteTableColumnStatistics(parsedDbName[CAT_NAME],
parsedDbName[DB_NAME], tableName, colNames, engine);
- if (ret) {
- eventType = EventType.DELETE_TABLE_COLUMN_STAT;
- for (String colName : colNames == null || colNames.isEmpty() ?
-
table.getSd().getCols().stream().map(FieldSchema::getName).toList() : colNames)
{
- if (transactionalListeners != null &&
!transactionalListeners.isEmpty()) {
- MetaStoreListenerNotifier.notifyEvent(transactionalListeners,
eventType,
- new DeleteTableColumnStatEvent(parsedDbName[CAT_NAME],
parsedDbName[DB_NAME], tableName, colName, engine, this));
- }
- events.add(new DeleteTableColumnStatEvent(parsedDbName[CAT_NAME],
parsedDbName[DB_NAME], tableName, colName, engine, this));
- }
- }
- } else {
- List<String> partNames = new ArrayList<>();
- if (req.getPart_namesSize() > 0) {
- partNames.addAll(req.getPart_names());
- } else {
- partNames.addAll(rawStore.listPartitionNames(parsedDbName[CAT_NAME],
parsedDbName[DB_NAME], tableName, (short) -1));
- }
- if (partNames.isEmpty()) {
- // no partition found, bail out early
- return true;
- }
- ret = rawStore.deletePartitionColumnStatistics(parsedDbName[CAT_NAME],
parsedDbName[DB_NAME], tableName,
- partNames, colNames, engine);
- if (ret) {
- eventType = EventType.DELETE_PARTITION_COLUMN_STAT;
- for (String colName : colNames == null || colNames.isEmpty() ?
-
table.getSd().getCols().stream().map(FieldSchema::getName).toList() : colNames)
{
- for (String partName : partNames) {
- List<String> partVals = getPartValsFromName(table, partName);
- if (transactionalListeners != null &&
!transactionalListeners.isEmpty()) {
- MetaStoreListenerNotifier.notifyEvent(transactionalListeners,
eventType,
- new DeletePartitionColumnStatEvent(parsedDbName[CAT_NAME],
parsedDbName[DB_NAME], tableName,
- partName, partVals, colName, engine, this));
- }
- events.add(new
DeletePartitionColumnStatEvent(parsedDbName[CAT_NAME], parsedDbName[DB_NAME],
tableName,
- partName, partVals, colName, engine, this));
- }
- }
- }
- }
- committed = rawStore.commitTransaction();
+ Exception ex = null;
+ boolean ret = false;
+ try {
+ ret = AbstractRequestHandler.offer(this, req).success();
+ return ret;
+ } catch (Exception e) {
+ ex = e;
+ throw handleException(e).defaultTException();
} finally {
- if (!committed) {
- rawStore.rollbackTransaction();
- }
- if (!listeners.isEmpty()) {
- for (ListenerEvent event : events) {
- MetaStoreListenerNotifier.notifyEvent(transactionalListeners,
eventType, event);
- }
- }
- endFunction("delete_column_statistics_req", ret, null, tableName);
+ endFunction("delete_column_statistics_req", ret, ex, tableName);
}
- return ret;
}
@Override
diff --git
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/handler/DeleteColumnStatisticsHandler.java
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/handler/DeleteColumnStatisticsHandler.java
new file mode 100644
index 00000000000..3f8fa4a14aa
--- /dev/null
+++
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/handler/DeleteColumnStatisticsHandler.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.handler;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.common.TableName;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+import org.apache.hadoop.hive.metastore.MetaStoreListenerNotifier;
+import org.apache.hadoop.hive.metastore.RawStore;
+import org.apache.hadoop.hive.metastore.api.DeleteColumnStatisticsRequest;
+import org.apache.hadoop.hive.metastore.api.FieldSchema;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.hadoop.hive.metastore.events.DeletePartitionColumnStatEvent;
+import org.apache.hadoop.hive.metastore.events.DeleteTableColumnStatEvent;
+import org.apache.hadoop.hive.metastore.events.ListenerEvent;
+import org.apache.hadoop.hive.metastore.messaging.EventMessage.EventType;
+import org.apache.hadoop.hive.metastore.txn.TxnUtils;
+import org.apache.thrift.TException;
+
+import static
org.apache.hadoop.hive.metastore.utils.MetaStoreServerUtils.getPartValsFromName;
+import static org.apache.hadoop.hive.metastore.utils.MetaStoreUtils.CAT_NAME;
+import static org.apache.hadoop.hive.metastore.utils.MetaStoreUtils.DB_NAME;
+import static
org.apache.hadoop.hive.metastore.utils.MetaStoreUtils.parseDbName;
+import static
org.apache.hadoop.hive.metastore.utils.StringUtils.normalizeIdentifier;
+
+@SuppressWarnings("unused")
+@RequestHandler(requestBody = DeleteColumnStatisticsRequest.class)
+public class DeleteColumnStatisticsHandler
+ extends AbstractRequestHandler<DeleteColumnStatisticsRequest,
+ DeleteColumnStatisticsHandler.DeleteColumnStatisticsResult> {
+ private RawStore ms;
+ private Configuration conf;
+ private String catName;
+ private String dbName;
+ private String tableName;
+ private List<String> colNames;
+ private String engine;
+ private List<ListenerEvent> events;
+ private EventType eventType;
+
+ DeleteColumnStatisticsHandler(IHMSHandler handler,
DeleteColumnStatisticsRequest request) {
+ super(handler, false, request);
+ }
+
+ @Override
+ protected void beforeExecute() throws TException, IOException {
+ this.conf = handler.getConf();
+ this.ms = handler.getMS();
+ this.colNames = request.getCol_names();
+ this.engine = request.getEngine();
+ String normalizedDbName = normalizeIdentifier(request.getDb_name());
+ this.tableName = normalizeIdentifier(request.getTbl_name());
+ String[] parsedDbName = parseDbName(normalizedDbName, conf);
+ if (request.getCat_name() != null) {
+ parsedDbName[CAT_NAME] = normalizeIdentifier(request.getCat_name());
+ }
+ this.catName = parsedDbName[CAT_NAME];
+ this.dbName = parsedDbName[DB_NAME];
+ this.events = new ArrayList<>();
+ }
+
+ @Override
+ protected DeleteColumnStatisticsResult execute() throws TException,
IOException {
+ boolean ret = false;
+ boolean committed = false;
+ ms.openTransaction();
+ try {
+ Table table = ms.getTable(catName, dbName, tableName);
+ boolean isPartitioned = table.getPartitionKeysSize() > 0;
+ if (TxnUtils.isTransactionalTable(table)) {
+ throw new MetaException("Cannot delete stats via this API for a
transactional table");
+ }
+ if (!isPartitioned || request.isTableLevel()) {
+ ret = ms.deleteTableColumnStatistics(catName, dbName, tableName,
colNames, engine);
+ if (ret) {
+ eventType = EventType.DELETE_TABLE_COLUMN_STAT;
+ for (String colName : colNames == null || colNames.isEmpty() ?
+
table.getSd().getCols().stream().map(FieldSchema::getName).collect(Collectors.toList())
+ : colNames) {
+ if (!handler.getTransactionalListeners().isEmpty()) {
+
MetaStoreListenerNotifier.notifyEvent(handler.getTransactionalListeners(),
eventType,
+ new DeleteTableColumnStatEvent(catName, dbName, tableName,
colName, engine, handler));
+ }
+ events.add(new DeleteTableColumnStatEvent(catName, dbName,
tableName, colName, engine, handler));
+ }
+ }
+ } else {
+ List<String> partNames = new ArrayList<>();
+ if (request.getPart_namesSize() > 0) {
+ partNames.addAll(request.getPart_names());
+ } else {
+ partNames.addAll(ms.listPartitionNames(catName, dbName, tableName,
(short) -1));
+ }
+ if (partNames.isEmpty()) {
+ // no partition found, bail out early
+ return new DeleteColumnStatisticsResult(true, events, eventType);
+ }
+ ret = ms.deletePartitionColumnStatistics(catName, dbName, tableName,
partNames, colNames, engine);
+ if (ret) {
+ eventType = EventType.DELETE_PARTITION_COLUMN_STAT;
+ for (String colName : colNames == null || colNames.isEmpty() ?
+
table.getSd().getCols().stream().map(FieldSchema::getName).collect(Collectors.toList())
+ : colNames) {
+ for (String partName : partNames) {
+ List<String> partVals = getPartValsFromName(table, partName);
+ if (!handler.getTransactionalListeners().isEmpty()) {
+
MetaStoreListenerNotifier.notifyEvent(handler.getTransactionalListeners(),
eventType,
+ new DeletePartitionColumnStatEvent(catName, dbName,
tableName,
+ partName, partVals, colName, engine, handler));
+ }
+ events.add(new DeletePartitionColumnStatEvent(catName, dbName,
tableName,
+ partName, partVals, colName, engine, handler));
+ }
+ }
+ }
+ }
+ committed = ms.commitTransaction();
+ } finally {
+ if (!committed) {
+ ms.rollbackTransaction();
+ }
+ }
+ return new DeleteColumnStatisticsResult(ret, events, eventType);
+ }
+
+ @Override
+ protected void afterExecute(DeleteColumnStatisticsResult result) throws
TException, IOException {
+ if (result != null && !handler.getListeners().isEmpty()) {
+ for (ListenerEvent event : result.events()) {
+ MetaStoreListenerNotifier.notifyEvent(handler.getListeners(),
result.eventType(), event);
+ }
+ }
+ super.afterExecute(result);
+ }
+
+ @Override
+ public String toString() {
+ return "DeleteColumnStatisticsHandler [" + id + "] - delete column stats
for " +
+ TableName.getQualified(catName, dbName, tableName) + ":";
+ }
+
+ public record DeleteColumnStatisticsResult(boolean success,
List<ListenerEvent> events, EventType eventType)
+ implements Result {
+
+ }
+}