github-actions[bot] commented on code in PR #67172:
URL: https://github.com/apache/doris/pull/67172#discussion_r3877915219
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java:
##########
@@ -471,6 +470,58 @@ protected List<Plan> doRewrite(StructInfo queryStructInfo,
CascadesContext casca
return rewriteResults;
}
+ // Partition compensation only supports one global limit/topN in each
plan. When this invariant
+ // is not met, return null so the caller skips the rewrite instead of
changing query semantics.
+ Plan buildPartitionCompensationPlan(Plan rewrittenPlan, Plan
baseTablePlan, Plan queryPlan) {
+ List<Plan> queryGlobalLimits = queryPlan.collectToList(node ->
isGlobalLimitOrTopN((Plan) node));
+ List<Plan> rewrittenGlobalLimits = rewrittenPlan.collectToList(
+ node -> isGlobalLimitOrTopN((Plan) node));
+ List<Plan> baseTableGlobalLimits = baseTablePlan.collectToList(
+ node -> isGlobalLimitOrTopN((Plan) node));
+ if (queryGlobalLimits.isEmpty()) {
+ return rewrittenGlobalLimits.isEmpty() &&
baseTableGlobalLimits.isEmpty()
+ ? buildCompensationUnion(queryPlan,
Lists.newArrayList(rewrittenPlan, baseTablePlan)) : null;
+ }
+ if (queryGlobalLimits.size() != 1
+ || rewrittenGlobalLimits.size() != 1 ||
baseTableGlobalLimits.size() != 1) {
+ return null;
+ }
+ Plan queryGlobalLimit = queryGlobalLimits.get(0);
+ Plan rewrittenGlobalLimit = rewrittenGlobalLimits.get(0);
+ Plan baseTableGlobalLimit = baseTableGlobalLimits.get(0);
+ // Rewriting can change the limit value and order-key expressions, but
preserves the outer
+ // operator kind. The offset must still match because it cannot be
safely adjusted after UNION.
+ if (rewrittenGlobalLimit.getType() != queryGlobalLimit.getType()
+ || baseTableGlobalLimit.getType() != queryGlobalLimit.getType()
+ || getOffset(rewrittenGlobalLimit) !=
getOffset(queryGlobalLimit)
+ || getOffset(baseTableGlobalLimit) !=
getOffset(queryGlobalLimit)) {
+ return null;
+ }
+ Plan compensationUnion =
buildCompensationUnion(queryGlobalLimit.child(0), Lists.newArrayList(
Review Comment:
[P1] Preserve branch expression semantics before unioning TopN children
With the default TopN expression pull-up, these are both accepted shapes for
a query/MV selecting `d, k, v + 1 AS x ORDER BY k LIMIT ...`:
```text
query/base: rewritten MV:
Project(v + 1 AS x) TopN(k_mv)
TopN(k) Project(x_mv)
Project(v) MVScan(x)
```
Taking only the two TopN children here maps `x_mv` by ordinal onto the UNION
output slot named as query `v`; grafting the query tree back then evaluates `v
+ 1` again. MV-backed rows therefore return `v + 2` while compensated base rows
return `v + 1` (using BIGINT keeps the types identical, so the current
count/type/offset and final-output checks all pass). The same invariant is
required for forwarding reorders and hidden columns, so rejecting only
non-forwarding aliases is insufficient. Please either normalize each branch to
a proven common semantic schema before UNION, or reject this asymmetric project
shape, and cover it with a stale-partition regression.
--
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]