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


##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/tools/ColumnDeduplicator.java:
##########
@@ -119,6 +132,32 @@ MetaToolObjectStore.DedupColumnsResult run(String 
catalogFilter, String dbFilter
     return result;
   }
 
+  private TableInfo getTable(long tableId) {
+    MTable table = pm.getObjectById(MTable.class, new MTable.PK(tableId));
+    if (table == null) {
+      return null;
+    }
+    Map<String, String> params = table.getParameters() == null ?
+        new HashMap<>() : table.getParameters();
+    // This table has been processed early
+    if (params.containsKey(COLUMN_DEDUPLICATOR_MARKER)) {
+      if (clearMarker) {
+        params.remove(COLUMN_DEDUPLICATOR_MARKER);
+        table.setParameters(params);
+      }
+      return null;
+    }
+
+    if (!isDryRun) {
+      params.put(COLUMN_DEDUPLICATOR_MARKER, "" + System.currentTimeMillis() / 
1000);
+      table.setParameters(params);
+    }

Review Comment:
   `-clearMarker` is described as clearing an existing marker, but when 
`clearMarker == true` and a table *doesn’t* already have the marker, this code 
will still add the marker (and then proceed to deduplicate). That can 
unintentionally mark previously-unprocessed tables as processed, causing future 
runs to skip them. Fix by making `clearMarker` a true “cleanup-only” mode: if 
`clearMarker` is set, do not add markers (and ideally do not deduplicate); only 
remove the marker when present and otherwise no-op for that table.



##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/tools/ColumnDeduplicator.java:
##########
@@ -56,43 +57,55 @@
  * the same CD, reducing metadata bloat that can accumulate during replication.
  */
 public final class ColumnDeduplicator {
+  public static final String COLUMN_DEDUPLICATOR_MARKER = 
"__metatool_column_deduplication__";
   private final RawStore store;
   private final PersistenceManager pm;
   private final AtomicReference<String> progress;
   private final boolean isDryRun;
   private final boolean isVerbose;
+  private final boolean clearMarker;
 
   public ColumnDeduplicator(RawStoreBundle bundle, AtomicReference<String> 
progress,
-      boolean isDryRun, boolean isVerbose) {
+      boolean isDryRun, boolean isVerbose, boolean clearMarker) {
     this.store = bundle.getBaseStore();
     this.pm = bundle.getPersistentManager();
     this.progress = progress;
     this.isDryRun = isDryRun;
     this.isVerbose = isVerbose;
+    this.clearMarker = clearMarker;
   }
 
   MetaToolObjectStore.DedupColumnsResult run(String catalogFilter, String 
dbFilter, String tableFilter) {
-    List<TableInfo> tables = findPartitionedTables(catalogFilter, dbFilter, 
tableFilter);
+    List<Long> tables = findPartitionedTables(catalogFilter, dbFilter, 
tableFilter);
     MetaToolObjectStore.DedupColumnsResult result = new 
MetaToolObjectStore.DedupColumnsResult(tables.size());
 
     long start = System.currentTimeMillis();
     for (int i = 0; i < tables.size() && result.getException() == null; i++) {
       boolean committed = false;
-      TableInfo table = tables.get(i);
+      long tableId = tables.get(i);
       PostCommitValidation validation = null;
+      TableInfo table = null;
       store.openTransaction();
       try {
         Deadline.checkTimeout();
-        validation = deduplicateTable(table, result);
+        table = getTable(tableId);
+        // This target table might be dropped or deduplicated, ignore
+        // If this is the stage to clean up the marker, ignore
+        if (table != null) {
+          validation = deduplicateTable(table, result);
+        }
         committed = store.commitTransaction();
-      } catch (Exception ex) {
+      } catch (Throwable ex) {
+        System.err.println("Failed to deduplicate the column in this table: " 
+ (table == null ? tableId : table));
+        ex.printStackTrace(System.err);
         result.catchException(ex);

Review Comment:
   Catching `Throwable` will also catch serious `Error`s (e.g., 
`OutOfMemoryError`, `StackOverflowError`) that typically should not be 
swallowed and converted into a normal tool failure. Prefer catching `Exception` 
(or a narrower set) here; if you must catch `Throwable` for logging, rethrow 
when `ex instanceof Error` after logging so the process can fail fast in 
unrecoverable situations.



##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/tools/MetaToolObjectStore.java:
##########
@@ -977,7 +977,7 @@ public static final class DedupColumnsResult {
     private int columnDescriptorsRemoved;
     private int tablesValidated;
     private final List<String> details = new ArrayList<>();
-    private Exception exception;
+    private Throwable exception;

Review Comment:
   Changing `DedupColumnsResult` to store/return `Throwable` broadens the 
contract to include `Error`s, which generally aren’t meant to be treated as 
reportable/handled outcomes. Consider keeping the result API typed to 
`Exception` (or a project-specific checked/unchecked exception type) and handle 
`Error`s separately (log + rethrow) to avoid encouraging callers to treat 
JVM-fatal conditions as routine results.



##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/tools/MetaToolObjectStore.java:
##########
@@ -1025,18 +1025,18 @@ void addDetail(String detail) {
       details.add(detail);
     }
 
-    void catchException(Exception exception) {
+    void catchException(Throwable exception) {
       this.exception = exception;
     }
 
-    public Exception getException() {
+    public Throwable getException() {
       return exception;
     }

Review Comment:
   Changing `DedupColumnsResult` to store/return `Throwable` broadens the 
contract to include `Error`s, which generally aren’t meant to be treated as 
reportable/handled outcomes. Consider keeping the result API typed to 
`Exception` (or a project-specific checked/unchecked exception type) and handle 
`Error`s separately (log + rethrow) to avoid encouraging callers to treat 
JVM-fatal conditions as routine results.



##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/tools/ColumnDeduplicator.java:
##########
@@ -119,6 +132,32 @@ MetaToolObjectStore.DedupColumnsResult run(String 
catalogFilter, String dbFilter
     return result;
   }
 
+  private TableInfo getTable(long tableId) {
+    MTable table = pm.getObjectById(MTable.class, new MTable.PK(tableId));
+    if (table == null) {
+      return null;
+    }

Review Comment:
   `PersistenceManager.getObjectById(...)` commonly throws (e.g., 
`JDOObjectNotFoundException`) when the row doesn’t exist rather than returning 
`null`. Since the intent is to ignore dropped tables, this should explicitly 
handle the not-found case (catch the specific exception and return null, or use 
an API variant that doesn’t throw) to avoid aborting the whole run when a table 
disappears mid-scan.



-- 
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