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

morrysnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new b06a37ee5a7 [Fix](nereids) Fix partition check failure (#29642)
b06a37ee5a7 is described below

commit b06a37ee5a70f78e9ebc0a1275f1731c6e81215c
Author: seawinde <[email protected]>
AuthorDate: Tue Jan 9 11:55:44 2024 +0800

    [Fix](nereids) Fix partition check failure (#29642)
    
    Optimize mv rewrite partition check logic and fix check failure and
    add more relevant explain info.
---
 .../mv/AbstractMaterializedViewRule.java           | 89 ++++++++--------------
 1 file changed, 32 insertions(+), 57 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
index 39807a8ce2a..0bc6746674e 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
@@ -18,13 +18,10 @@
 package org.apache.doris.nereids.rules.exploration.mv;
 
 import org.apache.doris.catalog.MTMV;
-import org.apache.doris.catalog.OlapTable;
 import org.apache.doris.catalog.Partition;
 import org.apache.doris.catalog.PartitionInfo;
-import org.apache.doris.catalog.PartitionItem;
 import org.apache.doris.catalog.PartitionType;
 import org.apache.doris.catalog.TableIf;
-import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.Pair;
 import org.apache.doris.mtmv.BaseTableInfo;
 import org.apache.doris.mtmv.MTMVPartitionInfo;
@@ -55,9 +52,8 @@ import 
org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
 import org.apache.doris.nereids.util.ExpressionUtils;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -65,7 +61,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
+import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -75,8 +71,6 @@ import java.util.stream.Collectors;
 public abstract class AbstractMaterializedViewRule implements 
ExplorationRuleFactory {
     public static final HashSet<JoinType> SUPPORTED_JOIN_TYPE_SET = 
Sets.newHashSet(JoinType.INNER_JOIN,
             JoinType.LEFT_OUTER_JOIN);
-    protected final String currentClassName = this.getClass().getSimpleName();
-    private final Logger logger = LogManager.getLogger(this.getClass());
 
     /**
      * The abstract template method for query rewrite, it contains the main 
logic and different query
@@ -195,12 +189,7 @@ public abstract class AbstractMaterializedViewRule 
implements ExplorationRuleFac
                 if (rewrittenPlan == null) {
                     continue;
                 }
-                if (!checkPartitionIsValid(queryStructInfo, 
materializationContext, cascadesContext)) {
-                    
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
-                            Pair.of("Check partition validation fail",
-                                    "the partition used by query is invalid in 
materialized view"));
-                    continue;
-                }
+                // checkout the output logical properties is the same with 
query
                 if (!checkOutput(queryPlan, rewrittenPlan, 
materializationContext)) {
                     continue;
                 }
@@ -210,6 +199,20 @@ public abstract class AbstractMaterializedViewRule 
implements ExplorationRuleFac
                         
cascadesContext.getCurrentJobContext().getRequiredProperties());
                 Rewriter.getWholeTreeRewriter(rewrittenPlanContext).execute();
                 rewrittenPlan = rewrittenPlanContext.getRewritePlan();
+                // check the partitions used by rewritten plan is valid or not
+                Set<Long> invalidPartitionsQueryUsed =
+                        calcInvalidPartitions(rewrittenPlan, 
materializationContext, cascadesContext);
+                if (!invalidPartitionsQueryUsed.isEmpty()) {
+                    
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
+                            Pair.of("Check partition query used validation 
fail",
+                                    String.format("the partition used by query 
is invalid by materialized view,"
+                                                    + "invalid partition info 
query used is %s",
+                                            
materializationContext.getMTMV().getPartitions().stream()
+                                                    .filter(partition ->
+                                                            
invalidPartitionsQueryUsed.contains(partition.getId()))
+                                                    
.collect(Collectors.toSet()))));
+                    continue;
+                }
                 materializationContext.setSuccess(true);
                 recordIfRewritten(queryPlan, materializationContext);
                 rewriteResults.add(rewrittenPlan);
@@ -239,62 +242,34 @@ public abstract class AbstractMaterializedViewRule 
implements ExplorationRuleFac
      * Maybe only just some partitions is valid in materialized view, so we 
should check if the mv can
      * offer the partitions which query used or not.
      */
-    protected boolean checkPartitionIsValid(StructInfo queryInfo, 
MaterializationContext materializationContext,
+    protected Set<Long> calcInvalidPartitions(Plan rewrittenPlan, 
MaterializationContext materializationContext,
             CascadesContext cascadesContext) {
         // check partition is valid or not
         MTMV mtmv = materializationContext.getMTMV();
         PartitionInfo mvPartitionInfo = mtmv.getPartitionInfo();
         if (PartitionType.UNPARTITIONED.equals(mvPartitionInfo.getType())) {
             // if not partition, if rewrite success, it means mv is available
-            return true;
+            return ImmutableSet.of();
         }
         // check mv related table partition is valid or not
         MTMVPartitionInfo mvCustomPartitionInfo = mtmv.getMvPartitionInfo();
         BaseTableInfo relatedPartitionTable = 
mvCustomPartitionInfo.getRelatedTable();
         if (relatedPartitionTable == null) {
-            return true;
-        }
-        Optional<LogicalOlapScan> relatedTableRelation = 
queryInfo.getRelations().stream()
-                .filter(LogicalOlapScan.class::isInstance)
-                .filter(relation -> relatedPartitionTable.equals(new 
BaseTableInfo(relation.getTable())))
-                .map(LogicalOlapScan.class::cast).findFirst();
-        if (!relatedTableRelation.isPresent()) {
-            logger.warn("mv is partition update, but related table relation is 
null");
-            return false;
-        }
-        OlapTable relatedTable = relatedTableRelation.get().getTable();
-        Map<Long, Set<Long>> mvToBasePartitionMap;
-        try {
-            mvToBasePartitionMap = MTMVUtil.getMvToBasePartitions(mtmv, 
relatedTable);
-        } catch (AnalysisException e) {
-            logger.warn("mvRewriteSuccess getMvToBasePartitions fail", e);
-            return false;
+            return ImmutableSet.of();
         }
         // get mv valid partitions
-        Collection<Partition> mvDataValidPartitions = 
MTMVUtil.getMTMVCanRewritePartitions(mtmv,
-                cascadesContext.getConnectContext());
-        Map<Long, PartitionItem> allPartitions = 
mvPartitionInfo.getAllPartitions();
-        if (!allPartitions.isEmpty() && mvDataValidPartitions.isEmpty()) {
-            // do not have valid partition
-            return false;
-        }
-        // get mv related table valid partitions
-        Set<Long> relatedTalbeValidSet = 
mvDataValidPartitions.stream().map(partition -> {
-            Set<Long> relatedBaseTablePartitions = 
mvToBasePartitionMap.get(partition.getId());
-            if (relatedBaseTablePartitions == null || 
relatedBaseTablePartitions.isEmpty()) {
-                return ImmutableList.of();
-            } else {
-                return relatedBaseTablePartitions;
-            }
-        
}).flatMap(Collection::stream).map(Long.class::cast).collect(Collectors.toSet());
-        // get query selected partitions to make the partitions is valid or not
-        Set<Long> relatedTableSelectedPartitionToCheck = new HashSet<>(
-                relatedTableRelation.get().getSelectedPartitionIds());
-        if (relatedTableSelectedPartitionToCheck.isEmpty()) {
-            
relatedTableSelectedPartitionToCheck.addAll(relatedTable.getPartitionIds());
-        }
-        return !relatedTalbeValidSet.isEmpty() && 
relatedTalbeValidSet.containsAll(
-                relatedTableSelectedPartitionToCheck);
+        Set<Long> mvDataValidPartitionIdSet = 
MTMVUtil.getMTMVCanRewritePartitions(mtmv,
+                        cascadesContext.getConnectContext()).stream()
+                .map(Partition::getId)
+                .collect(Collectors.toSet());
+        Set<Long> queryUsedPartitionIdSet = rewrittenPlan.collectToList(node 
-> node instanceof LogicalOlapScan
+                        && Objects.equals(((CatalogRelation) 
node).getTable().getName(), mtmv.getName()))
+                .stream()
+                .map(node -> ((LogicalOlapScan) 
node).getSelectedPartitionIds())
+                .flatMap(Collection::stream)
+                .collect(Collectors.toSet());
+        queryUsedPartitionIdSet.removeAll(mvDataValidPartitionIdSet);
+        return queryUsedPartitionIdSet;
     }
 
     /**


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

Reply via email to