seawinde commented on code in PR #67172:
URL: https://github.com/apache/doris/pull/67172#discussion_r3869659229


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java:
##########
@@ -471,6 +470,49 @@ protected List<Plan> doRewrite(StructInfo queryStructInfo, 
CascadesContext casca
         return rewriteResults;
     }
 
+    Plan buildPartitionCompensationPlan(Plan rewrittenPlan, Plan 
baseTablePlan, Plan queryPlan) {
+        Plan queryGlobalLimit = queryPlan.<Plan>collectFirst(
+                node -> isGlobalLimitOrTopN((Plan) node)).orElse(null);
+        if (queryGlobalLimit == null) {
+            return buildCompensationUnion(queryPlan, 
Lists.newArrayList(rewrittenPlan, baseTablePlan));
+        }
+        Plan rewrittenGlobalLimit = rewrittenPlan.<Plan>collectFirst(
+                node -> isSameGlobalLimitOrTopN((Plan) node, 
queryGlobalLimit)).orElse(null);
+        Plan baseTableGlobalLimit = baseTablePlan.<Plan>collectFirst(
+                node -> isSameGlobalLimitOrTopN((Plan) node, 
queryGlobalLimit)).orElse(null);
+        if (rewrittenGlobalLimit == null || baseTableGlobalLimit == null
+                || getOffset(rewrittenGlobalLimit) != 
getOffset(queryGlobalLimit)) {
+            return null;

Review Comment:
   已补充注释说明这段判断的前提:rewrite 可能改变 limit 值和 order-key 表达式,但会保留外层算子类型;offset 无法在 
UNION 后安全调整,因此仍要求一致。并新增唯一性校验,前提被破坏时直接放弃 rewrite。Commit: 0358e080fe4



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java:
##########
@@ -471,6 +470,49 @@ protected List<Plan> doRewrite(StructInfo queryStructInfo, 
CascadesContext casca
         return rewriteResults;
     }
 
+    Plan buildPartitionCompensationPlan(Plan rewrittenPlan, Plan 
baseTablePlan, Plan queryPlan) {
+        Plan queryGlobalLimit = queryPlan.<Plan>collectFirst(
+                node -> isGlobalLimitOrTopN((Plan) node)).orElse(null);
+        if (queryGlobalLimit == null) {
+            return buildCompensationUnion(queryPlan, 
Lists.newArrayList(rewrittenPlan, baseTablePlan));
+        }
+        Plan rewrittenGlobalLimit = rewrittenPlan.<Plan>collectFirst(
+                node -> isSameGlobalLimitOrTopN((Plan) node, 
queryGlobalLimit)).orElse(null);
+        Plan baseTableGlobalLimit = baseTablePlan.<Plan>collectFirst(
+                node -> isSameGlobalLimitOrTopN((Plan) node, 
queryGlobalLimit)).orElse(null);
+        if (rewrittenGlobalLimit == null || baseTableGlobalLimit == null
+                || getOffset(rewrittenGlobalLimit) != 
getOffset(queryGlobalLimit)) {
+            return null;
+        }
+        Plan compensationUnion = 
buildCompensationUnion(queryGlobalLimit.child(0), Lists.newArrayList(
+                rewrittenGlobalLimit.child(0), baseTableGlobalLimit.child(0)));
+        return queryPlan.rewriteDownShortCircuit(plan -> plan == 
queryGlobalLimit
+                ? queryGlobalLimit.withChildren(compensationUnion) : plan);
+    }
+
+    private boolean isGlobalLimitOrTopN(Plan plan) {
+        return plan instanceof LogicalTopN
+                || plan instanceof LogicalLimit && ((LogicalLimit<?>) 
plan).getPhase() == LimitPhase.GLOBAL;
+    }
+
+    private boolean isSameGlobalLimitOrTopN(Plan plan, Plan queryGlobalLimit) {
+        return plan.getType() == queryGlobalLimit.getType() && 
isGlobalLimitOrTopN(plan);
+    }

Review Comment:
   已按建议修改:现在会遍历整棵 plan,partition compensation 仅支持唯一一个 Global Limit/TopN;query 
中存在多个,或 rewritten/base 分支无法各自唯一匹配同类型算子时,直接返回 null 放弃 MV 
rewrite,避免隐式选择第一个节点导致语义错误。也补充了前提、失败行为和同类型匹配原因的注释,并增加了 multiple Global Limit 
的单测。Commit: 0358e080fe4



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