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


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewWindowRule.java:
##########
@@ -96,28 +113,291 @@ protected Plan rewriteQueryByView(MatchMode matchMode, 
StructInfo queryStructInf
                             viewToQuerySlotMapping, 
tempRewrittenPlan.treeString()));
             return null;
         }
+        Map<Expression, Expression> mvExprToMvScanExprQueryBased =
+                
materializationContext.getShuttledExprToScanExprMapping().keyPermute(viewToQuerySlotMapping)
+                        .flattenMap().get(0);
+        List<? extends Expression> expressionsToRewrite = 
getWindowRewriteExpressions(queryStructInfo);
+        if (expressionsToRewrite.isEmpty()) {
+            materializationContext.recordFailReason(queryStructInfo,
+                    "Rewrite expressions by view in window scan fail, no 
expressions to rewrite",
+                    () -> String.format("topPlan = %s", 
queryStructInfo.getTopPlan().treeString()));
+            return null;
+        }
+        Plan expressionSourcePlan = queryStructInfo.getOriginalPlan();
         // Rewrite top projects, represent the query projects by view
         List<Expression> expressionsRewritten = rewriteExpression(
-                queryStructInfo.getExpressions(),
-                queryStructInfo.getTopPlan(),
+                expressionsToRewrite,
+                expressionSourcePlan,
                 materializationContext.getShuttledExprToScanExprMapping(),
                 viewToQuerySlotMapping,
                 ImmutableMap.of(), cascadesContext
         );
-        // Can not rewrite, bail out
+        // If generic rewrite fails, try roll up from query expressions.
         if (expressionsRewritten.isEmpty()) {
-            materializationContext.recordFailReason(queryStructInfo,
-                    "Rewrite expressions by view in window scan fail",
-                    () -> String.format("expressionToRewritten is %s,\n 
mvExprToMvScanExprMapping is %s,\n"
-                                    + "targetToSourceMapping = %s", 
queryStructInfo.getExpressions(),
-                            
materializationContext.getShuttledExprToScanExprMapping(),
-                            viewToQuerySlotMapping));
-            return null;
+            expressionsRewritten = 
rollupWindowAggregateFunctions(expressionsToRewrite,
+                    expressionSourcePlan, mvExprToMvScanExprQueryBased, true, 
false);
+            if (expressionsRewritten.isEmpty()) {
+                materializationContext.recordFailReason(queryStructInfo,
+                        "Rewrite expressions by view in window scan fail",
+                        () -> String.format("expressionToRewritten is %s,\n 
mvExprToMvScanExprMapping is %s,\n"
+                                        + "targetToSourceMapping = %s", 
expressionsToRewrite,
+                                
materializationContext.getShuttledExprToScanExprMapping(),
+                                viewToQuerySlotMapping));
+                return null;
+            }
+        }
+        return buildRewrittenPlanFromExpressions(expressionsRewritten, 
tempRewrittenPlan);
+    }
+
+    private static Plan buildRewrittenPlanFromExpressions(List<Expression> 
expressionsRewritten, Plan mvScan) {
+        boolean hasAggregateFunction = expressionsRewritten.stream()
+                .anyMatch(expression -> 
expression.containsType(AggregateFunction.class));
+        if (!hasAggregateFunction) {
+            return new 
LogicalProject<>(toNamedExpressions(expressionsRewritten), mvScan);
+        }
+        List<Expression> groupByExpressions = new ArrayList<>();
+        List<NamedExpression> aggregateOutputExpressions = new ArrayList<>();
+        for (Expression expression : expressionsRewritten) {
+            if (expression.containsType(AggregateFunction.class)) {
+                aggregateOutputExpressions.add(toNamedExpression(expression));
+            } else if (!(expression instanceof Literal)) {
+                if (!groupByExpressions.contains(expression)) {
+                    groupByExpressions.add(expression);
+                    
aggregateOutputExpressions.add(toNamedExpression(expression));
+                }
+            }
+        }
+        LogicalAggregate<Plan> aggregate = new 
LogicalAggregate<>(groupByExpressions, aggregateOutputExpressions,
+                mvScan);
+        List<Slot> aggregateOutput = aggregate.getOutput();
+        int groupByOutputSize = groupByExpressions.size();
+        int groupByOutputIndex = 0;
+        int aggregateFunctionOutputIndex = 0;
+        List<NamedExpression> projectExpressions = new 
ArrayList<>(expressionsRewritten.size());
+        for (Expression expression : expressionsRewritten) {
+            if (expression instanceof Literal) {
+                projectExpressions.add(toNamedExpression(expression));
+            } else if (expression.containsType(AggregateFunction.class)) {
+                projectExpressions.add(new 
Alias(aggregateOutput.get(groupByOutputSize
+                        + aggregateFunctionOutputIndex++)));

Review Comment:
   `LogicalAggregate.computeOutput()` preserves `aggregateOutputExpressions` 
order, but the projection below assumes the output is laid out as all group-by 
slots first and aggregate-function slots after them. When the rewritten select 
list starts with the rollup aggregate, e.g. `SELECT bitmap_union_count(...) 
OVER (...), dt ...`, `aggregateOutputExpressions` is `[agg, dt]` while 
`groupByOutputSize` is 1, so this reads slot 1 for the aggregate and slot 0 for 
`dt`. That swaps outputs or causes a type mismatch for valid projection orders. 
Please build the aggregate outputs in the same grouped order the projection 
assumes, or keep an explicit expression-to-output mapping.



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