Copilot commented on code in PR #6198:
URL: https://github.com/apache/hive/pull/6198#discussion_r2986611108


##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/cache/CachedStore.java:
##########
@@ -2169,15 +2169,23 @@ private static void 
updateTableColumnsStatsInternal(Configuration conf, ColumnSt
       throw new RuntimeException("CachedStore can only be enabled for Hive 
engine");
     }
     boolean succ = rawStore.deleteTableColumnStatistics(catName, dbName, 
tblName, colNames, engine);
+    catName = normalizeIdentifier(catName);
+    dbName = normalizeIdentifier(dbName);
+    tblName = normalizeIdentifier(tblName);
+    if (!shouldCacheTable(catName, dbName, tblName)) {
+      return succ;
+    }
+    Table cachedTable = sharedCache.getTableFromCache(catName, dbName, 
tblName);
+    if (cachedTable != null) {

Review Comment:
   The cache metadata is updated even when `succ` is `false` (e.g., txn/commit 
failure). That can leave `sharedCache` inconsistent with the backing store. 
Consider gating the cache mutation on `succ`.
   ```suggestion
       if (succ && cachedTable != null) {
   ```



##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java:
##########
@@ -10016,21 +10013,23 @@ public boolean deletePartitionColumnStatistics(String 
catName, String dbName, St
     }
     dbName = org.apache.commons.lang3.StringUtils.defaultString(dbName, 
Warehouse.DEFAULT_DATABASE_NAME);
     catName = normalizeIdentifier(catName);
+    List<String> cols = normalizeIdentifiers(colNames);
     return new GetHelper<Boolean>(catName, dbName, tableName, true, true) {
       @Override
       protected String describeResult() {
         return "delete partition column stats";
       }
       @Override
       protected Boolean getSqlResult(GetHelper<Boolean> ctx) throws 
MetaException {
-        return directSql.deletePartitionColumnStats(catName, dbName, 
tableName, partNames, colNames, engine);
+        DirectSqlDeleteStats deleteStats = new DirectSqlDeleteStats(directSql, 
pm);
+        return deleteStats.deletePartitionColumnStats(catName, dbName, 
tableName, partNames, cols, engine);
       }
       @Override
       protected Boolean getJdoResult(GetHelper<Boolean> ctx)
               throws MetaException, NoSuchObjectException, 
InvalidObjectException, InvalidInputException {
-        return deletePartitionColumnStatisticsViaJdo(catName, dbName, 
tableName, partNames, colNames, engine);
+        return deletePartitionColumnStatisticsViaJdo(catName, dbName, 
tableName, partNames, cols, engine);
       }
-    }.run(false);
+    }.run(true);

Review Comment:
   `deletePartitionColumnStatistics` now uses `.run(true)`, which forces 
`GetHelper` to call `ensureGetTable(...)` before executing. The implementations 
here don't appear to use `ctx.getTable()`, so this adds an extra table read. 
Consider switching back to `.run(false)` unless table initialization is 
actually required.
   ```suggestion
       }.run(false);
   ```



##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java:
##########
@@ -10170,6 +10188,19 @@ private boolean 
deleteTableColumnStatisticsViaJdo(String catName, String dbName,
       } else {
         throw new NoSuchObjectException("Column stats doesn't exist for db=" + 
dbName + " table="
             + tableName + " col=" + String.join(", ", colNames));
+      }
+        // get the persistent object MTable
+      MTable mTable = getMTable(catName, dbName, tableName);
+      if (mTable != null) {
+        Map<String, String> tableParams = mTable.getParameters();
+        if (tableParams != null) {
+          if (colNames == null || colNames.isEmpty()) {
+            StatsSetupConst.clearColumnStatsState(tableParams);
+          } else {
+            StatsSetupConst.removeColumnStatsState(tableParams, colNames);

Review Comment:
   In the JDO path, `removeColumnStatsState`/`clearColumnStatsState` is applied 
as long as `mTable.getParameters()` is non-null, even if the 
`COLUMN_STATS_ACCURATE` key itself is missing. Because `removeColumnStatsState` 
will serialize a new default value when the key is absent, this can create a 
previously-nonexistent `COLUMN_STATS_ACCURATE` parameter. Consider skipping the 
mutation unless `tableParams.get(COLUMN_STATS_ACCURATE)` is non-null (to match 
the direct-SQL path).



##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/directsql/DirectSqlDeleteStats.java:
##########
@@ -0,0 +1,242 @@
+/*
+ * 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.directsql;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.datastore.JDOConnection;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.hadoop.hive.common.StatsSetupConst;
+import org.apache.hadoop.hive.metastore.Batchable;
+import org.apache.hadoop.hive.metastore.QueryWrapper;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static 
org.apache.hadoop.hive.metastore.directsql.MetaStoreDirectSql.getIdListForIn;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.closeDbConn;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.executeWithArray;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.extractSqlClob;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.makeParams;
+
+public class DirectSqlDeleteStats {
+  private static final Logger LOG = 
LoggerFactory.getLogger(DirectSqlDeleteStats.class);
+  private final MetaStoreDirectSql directSql;
+  private final PersistenceManager pm;
+  private final int batchSize;
+
+  public DirectSqlDeleteStats(MetaStoreDirectSql directSql, PersistenceManager 
pm) {
+    this.directSql = directSql;
+    this.pm = pm;
+    this.batchSize = directSql.getDirectSqlBatchSize();
+  }
+
+  public boolean deletePartitionColumnStats(String catName, String dbName, 
String tblName,
+      List<String> partNames, List<String> colNames, String engine) throws 
MetaException {
+    List<Long> partIds = Batchable.runBatched(batchSize, partNames, new 
Batchable<String, Long>() {
+      @Override
+      public List<Long> run(List<String> input) throws Exception {
+        String sqlFilter = "\"PARTITIONS\".\"PART_NAME\" in  (" + 
makeParams(input.size()) + ")";
+        List<Long> partitionIds = 
directSql.getPartitionIdsViaSqlFilter(catName, dbName, tblName, sqlFilter,
+            input, Collections.emptyList(), -1);
+        if (!partitionIds.isEmpty()) {
+          String deleteSql = "delete from \"PART_COL_STATS\" where \"PART_ID\" 
in ( " + getIdListForIn(partitionIds) + ")";
+          List<Object> params = new ArrayList<>(colNames == null ? 1 : 
colNames.size() + 1);
+
+          if (colNames != null && !colNames.isEmpty()) {
+            deleteSql += " and \"COLUMN_NAME\" in (" + 
makeParams(colNames.size()) + ")";
+            params.addAll(colNames);
+          }
+
+          if (engine != null) {
+            deleteSql += " and \"ENGINE\" = ?";
+            params.add(engine);
+          }
+          try (QueryWrapper queryParams = new 
QueryWrapper(pm.newQuery("javax.jdo.query.SQL", deleteSql))) {
+            executeWithArray(queryParams.getInnerQuery(), params.toArray(), 
deleteSql);
+          }
+        }
+        return partitionIds;
+      }
+    });
+    try {
+      return updateColumnStatsAccurateForPartitions(partIds, colNames);
+    } catch (SQLException e) {
+      String errorMsg = String.format(
+          "Failed to update partitions' COLUMN_STATS_ACCURATE for catalog 
'%s', database '%s', table '%s' "
+              + "(partitionCount=%d, columnCount=%d)",
+          catName, dbName, tblName,
+          partIds == null ? 0 : partIds.size(),
+          colNames == null ? 0 : colNames.size());
+      LOG.error(errorMsg, e);
+      MetaException metaException = new MetaException(errorMsg + ": " + 
e.getMessage());
+      metaException.initCause(e);
+      throw metaException;
+    }
+  }
+
+  /**
+   * A helper function which will get the current COLUMN_STATS_ACCURATE 
parameter on table level
+   * and update the COLUMN_STATS_ACCURATE parameter with the new value on 
table level using directSql
+   */
+  private long updateColumnStatsAccurateForTable(Table table, List<String> 
droppedCols) throws MetaException {
+    Map<String, String> params = table.getParameters();
+    // get the current COLUMN_STATS_ACCURATE
+    String currentValue;
+    if (params == null || (currentValue = 
params.get(StatsSetupConst.COLUMN_STATS_ACCURATE)) == null) {
+      return 0;
+    }
+    // if the dropping columns is empty, that means we delete all the columns
+    if (droppedCols == null || droppedCols.isEmpty()) {
+      StatsSetupConst.clearColumnStatsState(params);
+    } else {
+      StatsSetupConst.removeColumnStatsState(params, droppedCols);
+    }
+
+    String updatedValue = params.get(StatsSetupConst.COLUMN_STATS_ACCURATE);
+    // if the COL_STATS_ACCURATE has changed, then update it using directSql
+    if (currentValue.equals(updatedValue)) {
+      return 0;
+    }
+    return directSql.updateTableParam(table, 
StatsSetupConst.COLUMN_STATS_ACCURATE, currentValue, updatedValue);
+  }
+
+  private boolean updateColumnStatsAccurateForPartitions(List<Long> partIds, 
List<String> colNames)
+      throws MetaException, SQLException {
+    // Get the list of params that need to be updated
+    List<Pair<Long, String>> updates = getPartColAccuToUpdate(partIds, 
colNames);
+    if (updates.isEmpty()) {
+      // Nothing to update: treat as successful completion
+      return true;
+    }
+    JDOConnection jdoConn = null;
+    try {
+      jdoConn = pm.getDataStoreConnection();
+      Connection dbConn = (Connection) jdoConn.getNativeConnection();
+      String update = "UPDATE \"PARTITION_PARAMS\" SET " + " \"PARAM_VALUE\" = 
?" +
+          " WHERE \"PART_ID\" = ? AND \"PARAM_KEY\" = ?";
+      try (PreparedStatement pst = dbConn.prepareStatement(update)) {
+        List<Long> updated = new ArrayList<>();
+        for (Pair<Long, String> accurate : updates) {
+          pst.setString(1, accurate.getRight());
+          pst.setLong(2, accurate.getLeft());
+          pst.setString(3, StatsSetupConst.COLUMN_STATS_ACCURATE);
+          pst.addBatch();
+          updated.add(accurate.getLeft());
+          if (updated.size() == batchSize) {
+            LOG.debug("Execute updates on part: {}", updated);
+            verifyUpdates(pst.executeBatch(), updated);
+            updated = new ArrayList<>();
+          }
+        }
+        if (!updated.isEmpty()) {
+          verifyUpdates(pst.executeBatch(), updated);
+        }
+      }
+      return true;
+    } finally {
+      closeDbConn(jdoConn);
+    }
+  }
+
+  private void verifyUpdates(int[] numUpdates, List<Long> partIds) throws 
MetaException {
+    for (int i = 0; i < numUpdates.length; i++) {
+      if (numUpdates[i] != 1) {
+        throw new MetaException("Invalid state of PARTITION_PARAMS ("
+            + StatsSetupConst.COLUMN_STATS_ACCURATE + ") for PART_ID " + 
partIds.get(i));
+      }

Review Comment:
   `verifyUpdates` treats any batch update count other than `1` as failure. 
JDBC allows `executeBatch()` to return `Statement.SUCCESS_NO_INFO` for 
successful updates, which would make this throw even though the update 
succeeded. Consider treating `SUCCESS_NO_INFO` as success (while still flagging 
`0` updates).



##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java:
##########
@@ -10094,6 +10085,33 @@ public List<Void> run(List<String> input) throws 
Exception {
       } finally {
         b.closeAllQueries();
       }
+
+      Batchable.runBatched(batchSize, partNames, new Batchable<String, Void>() 
{
+        @Override
+        public List<Void> run(List<String> input) throws MetaException {
+          Pair<Query, Map<String, String>> queryWithParams = 
getPartQueryWithParams(catalog, database, tableName,
+              input);
+          try (QueryWrapper qw = new QueryWrapper(queryWithParams.getLeft())) {
+            qw.setResultClass(MPartition.class);
+            qw.setClass(MPartition.class);
+            qw.setOrdering("partitionName ascending");
+            List<MPartition> mparts = (List<MPartition>) 
qw.executeWithMap(queryWithParams.getRight());
+            for (MPartition mPart : mparts) {
+              Map<String, String> partitionParams = mPart.getParameters();
+              if (partitionParams != null) {
+                // In-place update the COLUMN_STATS_ACCURATE
+                if (colNames == null || colNames.isEmpty()) {
+                  StatsSetupConst.clearColumnStatsState(partitionParams);
+                } else {
+                  StatsSetupConst.removeColumnStatsState(partitionParams, 
colNames);
+                }
+                mPart.setParameters(partitionParams);

Review Comment:
   This new partition-parameter update mutates `partitionParams` whenever the 
map is non-null, without checking whether `COLUMN_STATS_ACCURATE` is present. 
Because `removeColumnStatsState` can create the key when missing, this may 
introduce new `COLUMN_STATS_ACCURATE` metadata on partitions unexpectedly. 
Consider only clearing/removing when 
`partitionParams.get(COLUMN_STATS_ACCURATE)` is non-null (aligning with the 
direct-SQL path).
   ```suggestion
                   // Only update COLUMN_STATS_ACCURATE if it is already 
present, to avoid
                   // introducing new COLUMN_STATS_ACCURATE metadata 
unexpectedly.
                   if 
(partitionParams.get(StatsSetupConst.COLUMN_STATS_ACCURATE) != null) {
                     // In-place update the COLUMN_STATS_ACCURATE
                     if (colNames == null || colNames.isEmpty()) {
                       StatsSetupConst.clearColumnStatsState(partitionParams);
                     } else {
                       StatsSetupConst.removeColumnStatsState(partitionParams, 
colNames);
                     }
                     mPart.setParameters(partitionParams);
                   }
   ```



##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/directsql/DirectSqlDeleteStats.java:
##########
@@ -0,0 +1,242 @@
+/*
+ * 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.directsql;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.datastore.JDOConnection;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.hadoop.hive.common.StatsSetupConst;
+import org.apache.hadoop.hive.metastore.Batchable;
+import org.apache.hadoop.hive.metastore.QueryWrapper;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static 
org.apache.hadoop.hive.metastore.directsql.MetaStoreDirectSql.getIdListForIn;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.closeDbConn;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.executeWithArray;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.extractSqlClob;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.makeParams;
+
+public class DirectSqlDeleteStats {
+  private static final Logger LOG = 
LoggerFactory.getLogger(DirectSqlDeleteStats.class);
+  private final MetaStoreDirectSql directSql;
+  private final PersistenceManager pm;
+  private final int batchSize;
+
+  public DirectSqlDeleteStats(MetaStoreDirectSql directSql, PersistenceManager 
pm) {
+    this.directSql = directSql;
+    this.pm = pm;
+    this.batchSize = directSql.getDirectSqlBatchSize();
+  }
+
+  public boolean deletePartitionColumnStats(String catName, String dbName, 
String tblName,
+      List<String> partNames, List<String> colNames, String engine) throws 
MetaException {
+    List<Long> partIds = Batchable.runBatched(batchSize, partNames, new 
Batchable<String, Long>() {
+      @Override
+      public List<Long> run(List<String> input) throws Exception {
+        String sqlFilter = "\"PARTITIONS\".\"PART_NAME\" in  (" + 
makeParams(input.size()) + ")";
+        List<Long> partitionIds = 
directSql.getPartitionIdsViaSqlFilter(catName, dbName, tblName, sqlFilter,
+            input, Collections.emptyList(), -1);
+        if (!partitionIds.isEmpty()) {
+          String deleteSql = "delete from \"PART_COL_STATS\" where \"PART_ID\" 
in ( " + getIdListForIn(partitionIds) + ")";

Review Comment:
   `sqlFilter` is hard-coded to use `"PARTITIONS"."PART_NAME" ...`. In 
`MetaStoreDirectSql`, table names are schema-qualified via 
`getFullyQualifiedName(schema, ...)` (e.g., `schema."PARTITIONS"`), and 
`getPartitionIdsViaSqlFilter` builds the FROM/JOINs using that qualified 
`PARTITIONS` string. Using an unqualified/hard-coded table reference here can 
break for non-default schemas and may not match the identifier used in the 
generated query. Consider building the filter using the same qualified 
`PARTITIONS` identifier (e.g., by exposing it from `MetaStoreDirectSql`, or by 
using an unqualified column reference like `"PART_NAME"` if unambiguous).



##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/cache/CachedStore.java:
##########
@@ -2169,15 +2169,23 @@ private static void 
updateTableColumnsStatsInternal(Configuration conf, ColumnSt
       throw new RuntimeException("CachedStore can only be enabled for Hive 
engine");
     }
     boolean succ = rawStore.deleteTableColumnStatistics(catName, dbName, 
tblName, colNames, engine);
+    catName = normalizeIdentifier(catName);
+    dbName = normalizeIdentifier(dbName);
+    tblName = normalizeIdentifier(tblName);
+    if (!shouldCacheTable(catName, dbName, tblName)) {
+      return succ;
+    }
+    Table cachedTable = sharedCache.getTableFromCache(catName, dbName, 
tblName);
+    if (cachedTable != null) {
+      if (colNames == null || colNames.isEmpty()) {
+        StatsSetupConst.clearColumnStatsState(cachedTable.getParameters());
+      } else {
+        StatsSetupConst.removeColumnStatsState(cachedTable.getParameters(), 
colNames);

Review Comment:
   Calling `removeColumnStatsState(...)`/`clearColumnStatsState(...)` 
unconditionally here can introduce a new `COLUMN_STATS_ACCURATE` key into 
`cachedTable.getParameters()` when it was previously absent (because the helper 
serializes a default object for null values). Consider checking that 
`COLUMN_STATS_ACCURATE` exists before mutating, to avoid creating unexpected 
metadata in cache and to align with the direct-SQL behavior.
   ```suggestion
         Map<String, String> params = cachedTable.getParameters();
         if (params != null && 
params.containsKey(StatsSetupConst.COLUMN_STATS_ACCURATE)) {
           if (colNames == null || colNames.isEmpty()) {
             StatsSetupConst.clearColumnStatsState(params);
           } else {
             StatsSetupConst.removeColumnStatsState(params, colNames);
           }
   ```



##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/directsql/DirectSqlDeleteStats.java:
##########
@@ -0,0 +1,242 @@
+/*
+ * 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.directsql;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.datastore.JDOConnection;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.hadoop.hive.common.StatsSetupConst;
+import org.apache.hadoop.hive.metastore.Batchable;
+import org.apache.hadoop.hive.metastore.QueryWrapper;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static 
org.apache.hadoop.hive.metastore.directsql.MetaStoreDirectSql.getIdListForIn;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.closeDbConn;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.executeWithArray;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.extractSqlClob;
+import static 
org.apache.hadoop.hive.metastore.directsql.MetastoreDirectSqlUtils.makeParams;
+
+public class DirectSqlDeleteStats {
+  private static final Logger LOG = 
LoggerFactory.getLogger(DirectSqlDeleteStats.class);
+  private final MetaStoreDirectSql directSql;
+  private final PersistenceManager pm;
+  private final int batchSize;
+
+  public DirectSqlDeleteStats(MetaStoreDirectSql directSql, PersistenceManager 
pm) {
+    this.directSql = directSql;
+    this.pm = pm;
+    this.batchSize = directSql.getDirectSqlBatchSize();
+  }
+
+  public boolean deletePartitionColumnStats(String catName, String dbName, 
String tblName,
+      List<String> partNames, List<String> colNames, String engine) throws 
MetaException {
+    List<Long> partIds = Batchable.runBatched(batchSize, partNames, new 
Batchable<String, Long>() {
+      @Override
+      public List<Long> run(List<String> input) throws Exception {
+        String sqlFilter = "\"PARTITIONS\".\"PART_NAME\" in  (" + 
makeParams(input.size()) + ")";
+        List<Long> partitionIds = 
directSql.getPartitionIdsViaSqlFilter(catName, dbName, tblName, sqlFilter,
+            input, Collections.emptyList(), -1);
+        if (!partitionIds.isEmpty()) {
+          String deleteSql = "delete from \"PART_COL_STATS\" where \"PART_ID\" 
in ( " + getIdListForIn(partitionIds) + ")";
+          List<Object> params = new ArrayList<>(colNames == null ? 1 : 
colNames.size() + 1);
+
+          if (colNames != null && !colNames.isEmpty()) {
+            deleteSql += " and \"COLUMN_NAME\" in (" + 
makeParams(colNames.size()) + ")";

Review Comment:
   This class hard-codes metastore table names in SQL strings (e.g., 
`"PART_COL_STATS"`, `"TAB_COL_STATS"`, `"PARTITION_PARAMS"`). 
`MetaStoreDirectSql` schema-qualifies these identifiers via 
`getFullyQualifiedName(schema, ...)` based on `javax.jdo.mapping.Schema`. If a 
schema is configured, these statements will hit the wrong table names. Consider 
obtaining the qualified table identifiers from `MetaStoreDirectSql` (or passing 
`schema` in and using `getFullyQualifiedName`) instead of embedding raw names.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to