diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java index ed2bc775e259c81..a937472c862fbc4 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java @@ -40,6 +40,8 @@ import org.apache.doris.nereids.rules.exploration.join.PushDownProjectThroughSemiJoin; import org.apache.doris.nereids.rules.exploration.join.SemiJoinSemiJoinTranspose; import org.apache.doris.nereids.rules.exploration.join.SemiJoinSemiJoinTransposeProject; +import org.apache.doris.nereids.rules.exploration.mv.MaterializedViewAggregateRule; +import org.apache.doris.nereids.rules.exploration.mv.MaterializedViewProjectAggregateRule; import org.apache.doris.nereids.rules.exploration.mv.MaterializedViewProjectJoinRule; import org.apache.doris.nereids.rules.implementation.AggregateStrategies; import org.apache.doris.nereids.rules.implementation.LogicalAssertNumRowsToPhysicalAssertNumRows; @@ -223,6 +225,8 @@ public class RuleSet { public static final List MATERIALIZED_VIEW_RULES = planRuleFactories() .add(MaterializedViewProjectJoinRule.INSTANCE) + .add(MaterializedViewAggregateRule.INSTANCE) + .add(MaterializedViewProjectAggregateRule.INSTANCE) .build(); public List getDPHypReorderRules() { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewAggregateRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewAggregateRule.java index a9a8b754d33648b..9fd388a843709fe 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewAggregateRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewAggregateRule.java @@ -17,9 +17,87 @@ package org.apache.doris.nereids.rules.exploration.mv; +import org.apache.doris.nereids.jobs.joinorder.hypergraph.Edge; +import org.apache.doris.nereids.jobs.joinorder.hypergraph.HyperGraph; +import org.apache.doris.nereids.jobs.joinorder.hypergraph.node.AbstractNode; +import org.apache.doris.nereids.jobs.joinorder.hypergraph.node.StructInfoNode; +import org.apache.doris.nereids.rules.exploration.mv.StructInfo.PlanSplitContext; +import org.apache.doris.nereids.rules.exploration.mv.mapping.ExpressionMapping; +import org.apache.doris.nereids.rules.exploration.mv.mapping.SlotMapping; +import org.apache.doris.nereids.trees.expressions.Slot; +import org.apache.doris.nereids.trees.plans.JoinType; +import org.apache.doris.nereids.trees.plans.Plan; +import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.Sets; +import static org.apache.doris.nereids.rules.exploration.mv.StructInfo.AGGREGATE_PATTERN_CHECKER; + +import java.util.HashSet; +import java.util.List; + /** * AbstractMaterializedViewAggregateRule * This is responsible for common aggregate rewriting * */ public abstract class AbstractMaterializedViewAggregateRule extends AbstractMaterializedViewRule { + + @Override + protected Plan rewriteQueryByView(MatchMode matchMode, + StructInfo queryStructInfo, + StructInfo viewStructInfo, + SlotMapping queryToViewSlotMappings, + Plan tempRewritedPlan, + MaterializationContext materializationContext) { + + PlanSplitContext planSplitContext = new PlanSplitContext(Sets.newHashSet(LogicalAggregate.class)); + viewStructInfo.getTopPlan().accept(StructInfo.PLAN_SPLITTER, planSplitContext); + + LogicalAggregate bottomAggregate = (LogicalAggregate) planSplitContext.getBottomPlan().get(0); + Plan topPlan = planSplitContext.getTopPlan(); + ExpressionMapping aggregateToTopExpressionMapping = generateAggregateToTopMapping(bottomAggregate, topPlan); + return null; + } + + private ExpressionMapping generateAggregateToTopMapping(Plan source, Plan target) { + ImmutableMultimap.Builder expressionMappingBuilder = ImmutableMultimap.builder(); + List sourceOutput = source.getOutput(); + List targetOutputOutput = target.getOutput(); + for (Slot sourceSlot : sourceOutput) { + for (Slot targetSlot : targetOutputOutput) { + if (sourceSlot.equals(targetSlot)) { + expressionMappingBuilder.put(targetSlot, sourceSlot); + } + } + } + return new ExpressionMapping(expressionMappingBuilder.build()); + } + + // Check Aggregate is simple or not and check join is whether valid or not. + // Support join's input can not contain aggregate Only support project, filter, join, logical relation node and + // join condition should be slot reference equals currently + @Override + protected boolean checkPattern(StructInfo structInfo) { + + Plan topPlan = structInfo.getTopPlan(); + Boolean valid = topPlan.accept(AGGREGATE_PATTERN_CHECKER, null); + if (!valid) { + return false; + } + HyperGraph hyperGraph = structInfo.getHyperGraph(); + HashSet requiredJoinType = Sets.newHashSet(JoinType.INNER_JOIN, JoinType.LEFT_OUTER_JOIN); + for (AbstractNode node : hyperGraph.getNodes()) { + StructInfoNode structInfoNode = (StructInfoNode) node; + if (!structInfoNode.getPlan().accept(StructInfo.JOIN_PATTERN_CHECKER, + requiredJoinType)) { + return false; + } + for (Edge edge : hyperGraph.getEdges()) { + if (!edge.getJoin().accept(StructInfo.JOIN_PATTERN_CHECKER, requiredJoinType)) { + return false; + } + } + } + return true; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewAggregateRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewAggregateRule.java index ce9c208e5f5d160..3bd0b1080cc9fe8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewAggregateRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewAggregateRule.java @@ -18,7 +18,13 @@ package org.apache.doris.nereids.rules.exploration.mv; import org.apache.doris.nereids.rules.Rule; +import org.apache.doris.nereids.rules.RulePromise; +import org.apache.doris.nereids.rules.RuleType; import org.apache.doris.nereids.rules.rewrite.RewriteRuleFactory; +import org.apache.doris.nereids.trees.plans.Plan; +import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate; + +import com.google.common.collect.ImmutableList; import java.util.List; @@ -26,8 +32,15 @@ * This is responsible for aggregate rewriting according to different pattern * */ public class MaterializedViewAggregateRule extends AbstractMaterializedViewAggregateRule implements RewriteRuleFactory { + + public static final MaterializedViewAggregateRule INSTANCE = new MaterializedViewAggregateRule(); + @Override public List buildRules() { - return null; + return ImmutableList.of( + logicalAggregate(any()).thenApplyMulti(ctx -> { + LogicalAggregate root = ctx.root; + return rewrite(root, ctx.cascadesContext); + }).toRule(RuleType.MATERIALIZED_VIEW_ONLY_AGGREGATE, RulePromise.EXPLORE)); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewProjectAggregateRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewProjectAggregateRule.java new file mode 100644 index 000000000000000..787a8cb7d9556a5 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewProjectAggregateRule.java @@ -0,0 +1,45 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.rules.exploration.mv; + +import org.apache.doris.nereids.rules.Rule; +import org.apache.doris.nereids.rules.RulePromise; +import org.apache.doris.nereids.rules.RuleType; +import org.apache.doris.nereids.rules.rewrite.RewriteRuleFactory; +import org.apache.doris.nereids.trees.plans.Plan; +import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate; + +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/**MaterializedViewProjectAggregateRule*/ +public class MaterializedViewProjectAggregateRule extends AbstractMaterializedViewAggregateRule implements + RewriteRuleFactory { + + public static final MaterializedViewProjectAggregateRule INSTANCE = new MaterializedViewProjectAggregateRule(); + + @Override + public List buildRules() { + return ImmutableList.of( + logicalAggregate(any()).thenApplyMulti(ctx -> { + LogicalAggregate root = ctx.root; + return rewrite(root, ctx.cascadesContext); + }).toRule(RuleType.MATERIALIZED_VIEW_PROJECT_AGGREGATE, RulePromise.EXPLORE)); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewProjectJoinRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewProjectJoinRule.java index 92f102dc1dece39..456d1ce24a05192 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewProjectJoinRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewProjectJoinRule.java @@ -42,6 +42,6 @@ public List buildRules() { logicalProject(logicalJoin(any(), any())).thenApplyMulti(ctx -> { LogicalProject> root = ctx.root; return rewrite(root, ctx.cascadesContext); - }).toRule(RuleType.MATERIALIZED_VIEW_ONLY_JOIN, RulePromise.EXPLORE)); + }).toRule(RuleType.MATERIALIZED_VIEW_PROJECT_JOIN, RulePromise.EXPLORE)); } }