Skip to content

Commit

Permalink
[opt](nereids) explain add materialized view rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
seawinde committed Dec 27, 2023
1 parent a8a86ec commit 3ae2ceb
Show file tree
Hide file tree
Showing 16 changed files with 315 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.apache.doris.nereids.processor.post.PlanPostProcessors;
import org.apache.doris.nereids.processor.pre.PlanPreprocessors;
import org.apache.doris.nereids.properties.PhysicalProperties;
import org.apache.doris.nereids.rules.exploration.mv.MaterializationContext;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
Expand Down Expand Up @@ -399,7 +400,9 @@ public String getExplainString(ExplainOptions explainOptions) {
case MEMO_PLAN:
plan = cascadesContext.getMemo().toString()
+ "\n\n========== OPTIMIZED PLAN ==========\n"
+ optimizedPlan.treeString();
+ optimizedPlan.treeString()
+ "\n\n========== MATERIALIZATIONS ==========\n"
+ MaterializationContext.toString(cascadesContext.getMaterializationContexts());
break;
case ALL_PLAN:
plan = "========== PARSED PLAN ==========\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,22 @@ public Expression getExpression(int i) {
return getExpressions().get(i);
}

public String getTypeName() {
if (this instanceof FilterEdge) {
return "FILTER";
} else {
return ((JoinEdge) this).getJoinType().toString();
}
}

@Override
public String toString() {
return String.format("<%s - %s>", LongBitmap.toString(leftExtendedNodes), LongBitmap.toString(
rightExtendedNodes));
if (!leftRejectEdges.isEmpty() || !rightRejectEdges.isEmpty()) {
return String.format("<%s --%s-- %s>[%s , %s]", LongBitmap.toString(leftExtendedNodes),
this.getTypeName(), LongBitmap.toString(rightExtendedNodes), leftRejectEdges, rightRejectEdges);
}
return String.format("<%s --%s-- %s>", LongBitmap.toString(leftExtendedNodes),
this.getTypeName(), LongBitmap.toString(rightExtendedNodes));
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.doris.nereids.jobs.joinorder.hypergraph.edge.Edge;
import org.apache.doris.nereids.trees.plans.GroupPlan;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.util.Utils;

import com.google.common.collect.ImmutableList;

Expand Down Expand Up @@ -67,4 +68,9 @@ public List<HyperGraph> getGraphs() {
return graphs;
}

@Override
public String toString() {
return Utils.toSqlString("StructInfoNode[" + this.getName() + "]",
"plan", this.plan.treeString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,16 @@ protected Plan rewriteQueryByView(MatchMode matchMode,
// get view and query aggregate and top plan correspondingly
Pair<Plan, LogicalAggregate<Plan>> viewTopPlanAndAggPair = splitToTopPlanAndAggregate(viewStructInfo);
if (viewTopPlanAndAggPair == null) {
logger.warn(currentClassName + " split to view to top plan and agg fail so return null");
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
String.format("view split to top plan and agg fail, view plan = %s\n",
viewStructInfo.getOriginalPlan().treeString()));
return null;
}
Pair<Plan, LogicalAggregate<Plan>> queryTopPlanAndAggPair = splitToTopPlanAndAggregate(queryStructInfo);
if (queryTopPlanAndAggPair == null) {
logger.warn(currentClassName + " split to query to top plan and agg fail so return null");
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
String.format("query split to top plan and agg fail, query plan = %s\n",
queryStructInfo.getOriginalPlan().treeString()));
return null;
}
// Firstly, handle query group by expression rewrite
Expand Down Expand Up @@ -115,7 +119,12 @@ protected Plan rewriteQueryByView(MatchMode matchMode,
true);
if (rewrittenQueryGroupExpr.isEmpty()) {
// can not rewrite, bail out.
logger.debug(currentClassName + " can not rewrite expression when not need roll up");
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
String.format("can not rewrite expression when need no roll up, expressionToWrite = %s,\n"
+ "mvExprToMvScanExprMapping = %s,\n queryToViewSlotMapping = %s",
queryTopPlan.getExpressions(),
materializationContext.getMvExprToMvScanExprMapping(),
queryToViewSlotMapping));
return null;
}
return new LogicalProject<>(
Expand All @@ -130,14 +139,19 @@ protected Plan rewriteQueryByView(MatchMode matchMode,
viewExpr -> viewExpr.anyMatch(expr -> expr instanceof AggregateFunction
&& ((AggregateFunction) expr).isDistinct()))) {
// if mv aggregate function contains distinct, can not roll up, bail out.
logger.debug(currentClassName + " view contains distinct function so can not roll up");
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
String.format("view contains distinct function so can not roll up, view plan = %s",
viewAggregate.getOutputExpressions()));
return null;
}
// split the query top plan expressions to group expressions and functions, if can not, bail out.
Pair<Set<? extends Expression>, Set<? extends Expression>> queryGroupAndFunctionPair
= topPlanSplitToGroupAndFunction(queryTopPlanAndAggPair);
if (queryGroupAndFunctionPair == null) {
logger.warn(currentClassName + " query top plan split to group by and function fail so return null");
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
String.format("query top plan split to group by and function fail,"
+ "queryTopPlan = %s,\n agg = %s",
queryTopPlanAndAggPair.key().treeString(), queryTopPlanAndAggPair.value().treeString()));
return null;
}
// Secondly, try to roll up the agg functions
Expand All @@ -164,18 +178,26 @@ protected Plan rewriteQueryByView(MatchMode matchMode,
Function rollupAggregateFunction = rollup(queryFunction, queryFunctionShuttled,
mvExprToMvScanExprQueryBased);
if (rollupAggregateFunction == null) {
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
String.format("query function roll up fail, queryFunction = %s,\n"
+ "mvExprToMvScanExprQueryBased = %s",
queryFunction, mvExprToMvScanExprQueryBased));
return null;
}
// key is query need roll up expr, value is mv scan based roll up expr
needRollupExprMap.put(queryFunctionShuttled, rollupAggregateFunction);
// rewrite query function expression by mv expression
ExpressionMapping needRollupExprMapping = new ExpressionMapping(needRollupExprMap);
Expression rewrittenFunctionExpression = rewriteExpression(topExpression,
queryTopPlan,
new ExpressionMapping(needRollupExprMap),
needRollupExprMapping,
queryToViewSlotMapping,
false);
if (rewrittenFunctionExpression == null) {
logger.debug(currentClassName + " roll up expression can not rewrite by view so return null");
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
String.format("roll up expression can not rewrite by view, topExpression = %s,\n"
+ "needRollupExprMapping = %s,\n queryToViewSlotMapping = %s",
topExpression, needRollupExprMapping, queryToViewSlotMapping));
return null;
}
finalAggregateExpressions.add((NamedExpression) rewrittenFunctionExpression);
Expand All @@ -185,22 +207,28 @@ protected Plan rewriteQueryByView(MatchMode matchMode,
ExpressionUtils.shuttleExpressionWithLineage(topExpression, queryTopPlan);
if (!mvExprToMvScanExprQueryBased.containsKey(queryGroupShuttledExpr)) {
// group expr can not rewrite by view
logger.debug(currentClassName
+ " view group expressions can not contains the query group by expression so return null");
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
String.format("view group expressions doesn't not contains the query group by expression,"
+ "mvExprToMvScanExprQueryBased is %s,\nqueryGroupShuttledExpr is %s",
mvExprToMvScanExprQueryBased, queryGroupShuttledExpr));
return null;
}
groupRewrittenExprMap.put(queryGroupShuttledExpr,
mvExprToMvScanExprQueryBased.get(queryGroupShuttledExpr));
// rewrite query group expression by mv expression
ExpressionMapping groupRewrittenExprMapping = new ExpressionMapping(groupRewrittenExprMap);
Expression rewrittenGroupExpression = rewriteExpression(
topExpression,
queryTopPlan,
new ExpressionMapping(groupRewrittenExprMap),
groupRewrittenExprMapping,
queryToViewSlotMapping,
true);
if (rewrittenGroupExpression == null) {
logger.debug(currentClassName
+ " query top expression can not be rewritten by view so return null");
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
String.format("query top group expression can not be rewritten by view,"
+ "topExpression is %s,\n groupRewrittenExprMapping is %s,\n"
+ "queryToViewSlotMapping = %s",
topExpression, groupRewrittenExprMapping, queryToViewSlotMapping));
return null;
}
finalAggregateExpressions.add((NamedExpression) rewrittenGroupExpression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ protected Plan rewriteQueryByView(MatchMode matchMode,
// Can not rewrite, bail out
if (expressionsRewritten.isEmpty()
|| expressionsRewritten.stream().anyMatch(expr -> !(expr instanceof NamedExpression))) {
logger.warn(currentClassName + " expression to rewrite is not named expr so return null");
materializationContext.recordFailReason(queryStructInfo.getOriginalPlanId(),
String.format("join rewrite query by view fail, expressionToRewritten is %s,\n"
+ "mvExprToMvScanExprMapping is %s,\n queryToViewSlotMapping = %s",
queryStructInfo.getExpressions(), materializationContext.getMvExprToMvScanExprMapping(),
queryToViewSlotMapping));
return null;
}
// record the group id in materializationContext, and when rewrite again in
Expand Down
Loading

0 comments on commit 3ae2ceb

Please sign in to comment.