github-actions[bot] commented on code in PR #67186:
URL: https://github.com/apache/doris/pull/67186#discussion_r3891887506


##########
fe/fe-connector/fe-connector-hive/src/main/java/org/apache/doris/connector/hive/HiveConnectorMetadata.java:
##########
@@ -1182,17 +1183,19 @@ public 
Optional<FilterApplicationResult<ConnectorTableHandle>> applyFilter(
             return Optional.empty();
         }
 
-        List<HmsPartitionInfo> prunedPartitions = matchedPartNames.isEmpty()
-                ? Collections.emptyList()
-                : hmsClient.getPartitions(hiveHandle.getDbName(),
-                        hiveHandle.getTableName(), matchedPartNames);
+        HmsPartitionBatchResult pruningResult = matchedPartNames.isEmpty()
+                ? null : hmsClient.getPartitionsWithStats(

Review Comment:
   [P1] Keep list-derived scan lookups tolerant of vanished partitions. The 
names here come from `listPartitionNames` (and can remain cached for the 
24-hour default TTL), but this new exact-result call rejects an HMS response 
that omits a partition dropped after that listing. The same list-derived exact 
flow remains in ordinary/batch scan planning and write-plan discovery, so an 
external drop can turn formerly omission-tolerant reads into repeatedly failing 
queries until the name cache refreshes. Please use an omission-tolerant 
result-with-stats path for identities derived from a prior listing, while 
keeping caller-owned transaction identities exact, and cover cached 
list-then-drop scans.



##########
fe/fe-connector/fe-connector-hms/src/main/java/org/apache/doris/connector/hms/ThriftHmsClient.java:
##########
@@ -909,6 +997,38 @@ public void close() throws Exception {
         }
     }
 
+    /** Reuses one temporary client across successful chunks when catalog 
pooling is disabled. */
+    private final class UnpooledPartitionTransport implements 
HmsPartitionTransport, AutoCloseable {
+        private PooledHmsClient current;
+
+        @Override
+        public List<HmsPartitionInfo> getPartitionsByNames(
+                String dbName, String tableName, List<String> partitionNames) {
+            if (closed) {
+                throw new HmsClientException("HMS client is closed");
+            }
+            if (current == null) {
+                current = createFreshClient();
+            }
+            try {
+                return executePartitionCall(current,
+                        client -> loadPartitionsByNames(client, dbName, 
tableName, partitionNames));
+            } catch (RuntimeException e) {
+                current.destroy();

Review Comment:
   [P2] Preserve the remote failure when destroying the unpooled client. If 
`current.destroy()` throws from `IMetaStoreClient.close()`, control never 
reaches `current = null` or `throw e`; the executor sees the cleanup exception 
instead of the explicit size-limit `RemoteCallException`, so it does not 
halve/retry. The pooled try-with-resources path keeps the remote error primary 
and suppresses cleanup failure. Please detach the failed client first and add 
any destroy failure as suppressed to `e`, then test pool-size-zero fallback 
with a throwing close.



##########
fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshContext.java:
##########
@@ -59,12 +76,103 @@ public Map<BaseTableInfo, MTMVSnapshotIf> 
getBaseTableSnapshotCache() {
         return baseTableSnapshotCache;
     }
 
+    /** Loads the union of mapped base partitions once per related table. */
+    public PreparedPartitionSnapshots preparePartitionSnapshots(Set<String> 
mtmvPartitionNames)
+            throws AnalysisException {
+        return preparePartitionSnapshots(mtmvPartitionNames, false);
+    }
+
+    /** Loads only mappings whose persisted partition-name set still matches 
and needs version comparison. */
+    public PreparedPartitionSnapshots 
prepareComparablePartitionSnapshots(Set<String> mtmvPartitionNames)
+            throws AnalysisException {
+        return preparePartitionSnapshots(mtmvPartitionNames, true);
+    }
+
+    private PreparedPartitionSnapshots preparePartitionSnapshots(
+            Set<String> mtmvPartitionNames, boolean comparableOnly)
+            throws AnalysisException {
+        Map<MTMVRelatedTableIf, Set<String>> namesByTable = new 
LinkedHashMap<>();
+        Map<MTMVRelatedTableIf, BaseTableInfo> tableInfos = comparableOnly
+                ? new LinkedHashMap<>() : Collections.emptyMap();
+        for (String mtmvPartitionName : mtmvPartitionNames) {
+            for (Map.Entry<MTMVRelatedTableIf, Set<String>> entry
+                    : getByPartitionName(mtmvPartitionName).entrySet()) {
+                if (!entry.getKey().needAutoRefresh()) {
+                    continue;
+                }
+                if (comparableOnly) {
+                    BaseTableInfo tableInfo = 
tableInfos.computeIfAbsent(entry.getKey(), BaseTableInfo::new);
+                    if (!Objects.equals(entry.getValue(), 
mtmv.getRefreshSnapshot()
+                            .getPctSnapshots(mtmvPartitionName, tableInfo))) {
+                        continue;
+                    }
+                }
+                namesByTable.computeIfAbsent(entry.getKey(), ignored -> new 
LinkedHashSet<>())
+                        .addAll(entry.getValue());
+            }
+        }
+        for (Map.Entry<MTMVRelatedTableIf, Set<String>> entry : 
namesByTable.entrySet()) {
+            loadSnapshots(entry.getKey(), entry.getValue());
+        }
+        return new PreparedPartitionSnapshots(this);
+    }
+
+    private void loadSnapshots(MTMVRelatedTableIf table, Set<String> 
partitionNames) throws AnalysisException {
+        Map<String, MTMVSnapshotIf> cached = 
partitionSnapshotCache.computeIfAbsent(
+                table, ignored -> new LinkedHashMap<>());
+        Set<String> missing = new LinkedHashSet<>(partitionNames);
+        missing.removeAll(cached.keySet());
+        if (missing.isEmpty()) {
+            return;
+        }
+        Map<String, MTMVSnapshotIf> loaded = table.getPartitionSnapshots(
+                missing, this, snapshotResolver.apply(table));
+        if (loaded == null || loaded.containsKey(null) || 
loaded.containsValue(null)
+                || !missing.equals(loaded.keySet())) {
+            throw new AnalysisException("Invalid partition snapshot result for 
table " + table.getName()
+                    + ": requestedCount=" + missing.size() + ", returnedCount="
+                    + (loaded == null ? "null" : loaded.size()));
+        }
+        cached.putAll(loaded);
+    }
+
     public static MTMVRefreshContext buildContext(MTMV mtmv, Map<List<String>, 
Set<String>> queryUsedPartitions)
             throws AnalysisException {
-        MTMVRefreshContext context = new MTMVRefreshContext(mtmv);
+        return buildContext(mtmv, queryUsedPartitions, 
MvccUtil::getSnapshotFromContext);
+    }
+
+    public static MTMVRefreshContext buildContext(MTMV mtmv, Map<List<String>, 
Set<String>> queryUsedPartitions,
+            Map<MvccTableInfo, MvccSnapshot> pinnedSnapshots) throws 
AnalysisException {
+        Map<MvccTableInfo, MvccSnapshot> snapshotCopy = new 
LinkedHashMap<>(pinnedSnapshots);
+        return buildContext(mtmv, queryUsedPartitions,
+                table -> Optional.ofNullable(snapshotCopy.get(new 
MvccTableInfo(table))));
+    }
+
+    private static MTMVRefreshContext buildContext(MTMV mtmv,
+            Map<List<String>, Set<String>> queryUsedPartitions,
+            Function<MTMVRelatedTableIf, Optional<MvccSnapshot>> 
snapshotResolver) throws AnalysisException {
+        MTMVRefreshContext context = new MTMVRefreshContext(mtmv, 
snapshotResolver);

Review Comment:
   [P1] Build the partition mapping from the same pin as this context's bulk 
loader. The new resolver makes `loadSnapshots` read S1, but 
`calculatePartitionMappings` still reaches `MvccUtil.getSnapshotFromContext` 
through its generators after the task's temporary `StatementContext` has been 
restored. If a PCT partition is added after S1, the mapping can include that 
S2-only name and the newly S1-pinned bulk load then rejects it as absent, 
aborting refresh; before this change both mapping and scalar snapshot loading 
used the same unpinned generation. Route mapping/align generation through this 
resolver (or install the task pins before building it) and add an 
add-between-capture-and-mapping test.



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