This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new 954f120f4b0 branch-4.1: [fix](mv) Avoid unioning query-unused MV 
partitions #63081 (#63706)
954f120f4b0 is described below

commit 954f120f4b0fb3facd1015559ec2abd5c3cfa40d
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed May 27 15:47:47 2026 +0800

    branch-4.1: [fix](mv) Avoid unioning query-unused MV partitions #63081 
(#63706)
    
    Cherry-picked from #63081
    
    Co-authored-by: foxtail463 <[email protected]>
    Co-authored-by: yangtao555 <[email protected]>
---
 .../rules/exploration/mv/PartitionCompensator.java |   3 +-
 .../exploration/mv/PartitionCompensatorTest.java   | 104 +++++++++++++++++++++
 2 files changed, 106 insertions(+), 1 deletion(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/PartitionCompensator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/PartitionCompensator.java
index 4c26ab47cec..fe2e88cd504 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/PartitionCompensator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/PartitionCompensator.java
@@ -198,7 +198,8 @@ public class PartitionCompensator {
                 // Base table partition maybe deleted, need not union
                 continue;
             }
-            baseTableNeedUnionPartitionNameSet.addAll(baseTablePartitions);
+            Sets.intersection(baseTablePartitions, 
queryUsedBaseTablePartitionNameSet)
+                    .copyInto(baseTableNeedUnionPartitionNameSet);
         }
         // If related base table creates partitions or mv is created with ttl, 
need base table union
         Sets.difference(queryUsedBaseTablePartitionNameSet, 
mvValidBaseTablePartitionNameSet)
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/mv/PartitionCompensatorTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/mv/PartitionCompensatorTest.java
index 3c1b2bb9519..1af0b983fee 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/mv/PartitionCompensatorTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/mv/PartitionCompensatorTest.java
@@ -35,6 +35,7 @@ import org.apache.doris.nereids.CascadesContext;
 import org.apache.doris.nereids.StatementContext;
 import org.apache.doris.nereids.trees.plans.Plan;
 import org.apache.doris.nereids.trees.plans.RelationId;
+import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
 import org.apache.doris.nereids.util.PlanChecker;
 import org.apache.doris.utframe.TestWithFeService;
 
@@ -485,6 +486,90 @@ public class PartitionCompensatorTest extends 
TestWithFeService {
                 .forEach(v -> Assertions.assertEquals(expectedUnion, v));
     }
 
+    @SuppressWarnings("unchecked")
+    @Test
+    public void 
testCalcInvalidPartitionsDoesNotCompensateBasePartitionsUnusedByQuery()
+            throws Exception {
+        DatabaseIf<?> baseDb = mockDatabase("cat", 1L, "db", 2L);
+        MTMVRelatedTableIf relatedTable = mockRelatedTableIf(
+                "base_t", 10L, ImmutableList.of("cat", "db", "base_t"), 
baseDb);
+        BaseColInfo colInfo = new BaseColInfo("dt", new 
BaseTableInfo(relatedTable));
+
+        DatabaseIf<?> mvDb = mockDatabase("internal", 3L, "mv_db", 4L);
+        MTMV mtmv = Mockito.mock(MTMV.class);
+        Mockito.when(mtmv.getName()).thenReturn("mv1");
+        Mockito.when(mtmv.getId()).thenReturn(100L);
+        Mockito.when(mtmv.getDatabase()).thenReturn(mvDb);
+        Mockito.when(mtmv.selectNonEmptyPartitionIds(ArgumentMatchers.any()))
+                .thenReturn(ImmutableList.of(1L));
+
+        long mvP20260301Id = 101L;
+        long mvP20260401Id = 102L;
+        long mvP20260402Id = 103L;
+        long mvP20260403Id = 104L;
+        long mvP20260428Id = 105L;
+        Partition mvP20260301 = mockPartition(mvP20260301Id, "mv_p20260301");
+        Partition mvP20260401 = mockPartition(mvP20260401Id, "mv_p20260401");
+        Partition mvP20260402 = mockPartition(mvP20260402Id, "mv_p20260402");
+        Partition mvP20260403 = mockPartition(mvP20260403Id, "mv_p20260403");
+        Partition mvP20260428 = mockPartition(mvP20260428Id, "mv_p20260428");
+        Mockito.when(mtmv.getPartition(mvP20260301Id)).thenReturn(mvP20260301);
+        Mockito.when(mtmv.getPartition(mvP20260401Id)).thenReturn(mvP20260401);
+        Mockito.when(mtmv.getPartition(mvP20260402Id)).thenReturn(mvP20260402);
+        Mockito.when(mtmv.getPartition(mvP20260403Id)).thenReturn(mvP20260403);
+        Mockito.when(mtmv.getPartition(mvP20260428Id)).thenReturn(mvP20260428);
+
+        PartitionInfo mvPartitionInfo = Mockito.mock(PartitionInfo.class);
+        Mockito.when(mtmv.getPartitionInfo()).thenReturn(mvPartitionInfo);
+        
Mockito.when(mvPartitionInfo.getType()).thenReturn(PartitionType.RANGE);
+        MTMVPartitionInfo mvPctInfo = Mockito.mock(MTMVPartitionInfo.class);
+        Mockito.when(mtmv.getMvPartitionInfo()).thenReturn(mvPctInfo);
+        
Mockito.when(mvPctInfo.getPctTables()).thenReturn(ImmutableSet.of(relatedTable));
+        
Mockito.when(mvPctInfo.getPctInfos()).thenReturn(ImmutableList.of(colInfo));
+
+        Map<String, Set<String>> relatedPartitionMapping = new HashMap<>();
+        relatedPartitionMapping.put("mv_p20260301", 
ImmutableSet.of("p20260301"));
+        relatedPartitionMapping.put("mv_p20260401", 
ImmutableSet.of("p20260401"));
+        relatedPartitionMapping.put("mv_p20260402", 
ImmutableSet.of("p20260402"));
+        relatedPartitionMapping.put("mv_p20260403", 
ImmutableSet.of("p20260403"));
+        relatedPartitionMapping.put("mv_p20260428", 
ImmutableSet.of("p20260428"));
+        Map<MTMVRelatedTableIf, Map<String, Set<String>>> partitionMappings = 
new HashMap<>();
+        partitionMappings.put(relatedTable, relatedPartitionMapping);
+
+        AsyncMaterializationContext matCtx = 
Mockito.mock(AsyncMaterializationContext.class);
+        Mockito.when(matCtx.getMtmv()).thenReturn(mtmv);
+        
Mockito.when(matCtx.calculatePartitionMappings()).thenReturn(partitionMappings);
+
+        Map<BaseTableInfo, Collection<Partition>> canRewriteMap = new 
HashMap<>();
+        canRewriteMap.put(new BaseTableInfo(mtmv),
+                ImmutableList.of(mvP20260401, mvP20260402));
+        StatementContext stmtCtx = Mockito.mock(StatementContext.class);
+        
Mockito.when(stmtCtx.getMvCanRewritePartitionsMap()).thenReturn(canRewriteMap);
+        CascadesContext cascadesCtx = Mockito.mock(CascadesContext.class);
+        Mockito.when(cascadesCtx.getStatementContext()).thenReturn(stmtCtx);
+
+        LogicalOlapScan selectedMvScan = Mockito.mock(LogicalOlapScan.class);
+        Mockito.when(selectedMvScan.getTable()).thenReturn(mtmv);
+        Mockito.when(selectedMvScan.getSelectedPartitionIds())
+                .thenReturn(ImmutableList.of(mvP20260301Id, mvP20260401Id, 
mvP20260402Id,
+                        mvP20260403Id, mvP20260428Id));
+        Plan rewrittenPlan = Mockito.mock(Plan.class);
+        Mockito.when(rewrittenPlan.collectToList(ArgumentMatchers.any()))
+                .thenReturn(ImmutableList.of(selectedMvScan));
+
+        Map<List<String>, Set<String>> queryUsedPartitions = new HashMap<>();
+        queryUsedPartitions.put(relatedTable.getFullQualifiers(),
+                ImmutableSet.of("p20260401", "p20260402", "p20260403"));
+
+        Pair<Map<BaseTableInfo, Set<String>>, Map<BaseColInfo, Set<String>>> 
result =
+                
PartitionCompensator.calcInvalidPartitions(queryUsedPartitions, rewrittenPlan, 
matCtx, cascadesCtx);
+
+        Assertions.assertNotNull(result);
+        Assertions.assertEquals(ImmutableSet.of("mv_p20260301", 
"mv_p20260403", "mv_p20260428"),
+                result.key().get(new BaseTableInfo(mtmv)));
+        Assertions.assertEquals(ImmutableSet.of("p20260403"), 
result.value().get(colInfo));
+    }
+
     @SuppressWarnings("unchecked")
     private static MTMVRelatedTableIf mockRelatedTableIf(
             String tableName, long tableId, List<String> qualifiers, 
DatabaseIf<?> db) {
@@ -496,6 +581,25 @@ public class PartitionCompensatorTest extends 
TestWithFeService {
         return table;
     }
 
+    private static DatabaseIf<?> mockDatabase(String catalogName, long 
catalogId, String dbName, long dbId) {
+        CatalogIf<?> catalog = Mockito.mock(CatalogIf.class);
+        Mockito.when(catalog.getId()).thenReturn(catalogId);
+        Mockito.when(catalog.getName()).thenReturn(catalogName);
+
+        DatabaseIf<?> db = Mockito.mock(DatabaseIf.class);
+        Mockito.when(db.getId()).thenReturn(dbId);
+        Mockito.when(db.getFullName()).thenReturn(dbName);
+        Mockito.when(db.getCatalog()).thenReturn(catalog);
+        return db;
+    }
+
+    private static Partition mockPartition(long partitionId, String 
partitionName) {
+        Partition partition = Mockito.mock(Partition.class);
+        Mockito.when(partition.getId()).thenReturn(partitionId);
+        Mockito.when(partition.getName()).thenReturn(partitionName);
+        return partition;
+    }
+
     private static BaseTableInfo newBaseTableInfo() {
         CatalogIf<?> catalog = Mockito.mock(CatalogIf.class);
         Mockito.when(catalog.getId()).thenReturn(1L);


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

Reply via email to