This is an automated email from the ASF dual-hosted git repository.
jakevin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new fde474609e [feature](Nereids) Add dphyp job (#14485)
fde474609e is described below
commit fde474609efc4108af2af45f316cb5de5aefe4c9
Author: 谢健 <[email protected]>
AuthorDate: Thu Nov 24 15:50:05 2022 +0800
[feature](Nereids) Add dphyp job (#14485)
---
.../org/apache/doris/nereids/NereidsPlanner.java | 7 -
.../org/apache/doris/nereids/jobs/JobType.java | 4 +-
.../doris/nereids/jobs/joinorder/JoinOrderJob.java | 98 ++++++++++++
.../joinorder}/hypergraph/CircleDetector.java | 9 +-
.../joinorder}/hypergraph/Edge.java | 4 +-
.../joinorder}/hypergraph/GraphSimplifier.java | 164 +++++++++++++++++----
.../joinorder}/hypergraph/HyperGraph.java | 115 ++++-----------
.../joinorder}/hypergraph/Node.java | 42 +++---
.../joinorder}/hypergraph/SubgraphEnumerator.java | 56 ++++---
.../hypergraph/bitmap/BitSetIterator.java | 2 +-
.../joinorder}/hypergraph/bitmap/Bitmap.java | 2 +-
.../hypergraph/bitmap/ReverseBitSetIterator.java | 2 +-
.../hypergraph/bitmap/SubsetIterator.java | 2 +-
.../hypergraph/receiver/AbstractReceiver.java | 12 +-
.../joinorder}/hypergraph/receiver/Counter.java | 33 ++++-
.../hypergraph/receiver/PlanReceiver.java | 140 ++++++++++++++++++
.../java/org/apache/doris/nereids/memo/Group.java | 5 +
.../apache/doris/nereids/memo/GroupExpression.java | 5 +
.../rules/joinreorder/HyperGraphJoinReorder.java | 48 ------
.../HyperGraphJoinReorderGroupLeft.java | 48 ------
.../HyperGraphJoinReorderGroupRight.java | 47 ------
.../joinreorder/hypergraph/receiver/PlanTable.java | 57 -------
.../joinorder/JoinOrderJobTest.java} | 22 +--
.../joinorder}/hypergraph/BitSetTest.java | 6 +-
.../joinorder}/hypergraph/CircleDetectorTest.java | 2 +-
.../joinorder}/hypergraph/GraphSimplifierTest.java | 41 ++++--
.../joinorder}/hypergraph/HyperGraphTest.java | 2 +-
.../hypergraph/SubgraphEnumeratorTest.java | 8 +-
.../HyperGraphJoinReorderGroupRightTest.java | 52 -------
.../joinreorder/HyperGraphJoinReorderTest.java | 56 -------
.../doris/nereids/util/HyperGraphBuilder.java | 75 ++++------
.../org/apache/doris/nereids/util/PlanChecker.java | 37 +++--
32 files changed, 628 insertions(+), 575 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java
index 34a088d799..acaf27ddb1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java
@@ -28,13 +28,11 @@ import
org.apache.doris.nereids.glue.translator.PlanTranslatorContext;
import org.apache.doris.nereids.jobs.batch.NereidsRewriteJobExecutor;
import org.apache.doris.nereids.jobs.batch.OptimizeRulesJob;
import org.apache.doris.nereids.jobs.cascades.DeriveStatsJob;
-import org.apache.doris.nereids.jobs.rewrite.RewriteTopDownJob;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.memo.GroupExpression;
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.joinreorder.HyperGraphJoinReorder;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.plans.Plan;
import
org.apache.doris.nereids.trees.plans.commands.ExplainCommand.ExplainLevel;
@@ -213,11 +211,6 @@ public class NereidsPlanner extends Planner {
}
private void joinReorder() {
- new RewriteTopDownJob(
- getRoot(),
- (new HyperGraphJoinReorder()).buildRules(),
- cascadesContext.getCurrentJobContext()
- ).execute();
}
/**
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/JobType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/JobType.java
index 528109babb..03681c58ee 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/JobType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/JobType.java
@@ -30,6 +30,6 @@ public enum JobType {
DERIVE_STATS,
TOP_DOWN_REWRITE,
VISITOR_REWRITE,
- BOTTOM_UP_REWRITE
- ;
+ BOTTOM_UP_REWRITE,
+ JOIN_ORDER;
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/JoinOrderJob.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/JoinOrderJob.java
new file mode 100644
index 0000000000..4b5e20ad0d
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/JoinOrderJob.java
@@ -0,0 +1,98 @@
+// 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.jobs.joinorder;
+
+import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.nereids.jobs.Job;
+import org.apache.doris.nereids.jobs.JobContext;
+import org.apache.doris.nereids.jobs.JobType;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.GraphSimplifier;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.HyperGraph;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.SubgraphEnumerator;
+import
org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver.PlanReceiver;
+import org.apache.doris.nereids.memo.Group;
+import org.apache.doris.nereids.memo.GroupExpression;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Join Order job with DPHyp
+ */
+public class JoinOrderJob extends Job {
+ private final Group group;
+
+ public JoinOrderJob(Group group, JobContext context) {
+ super(JobType.JOIN_ORDER, context);
+ this.group = group;
+ }
+
+ @Override
+ public void execute() throws AnalysisException {
+ Preconditions.checkArgument(!group.isJoinGroup());
+ GroupExpression rootExpr = group.getLogicalExpression();
+ int arity = rootExpr.arity();
+ for (int i = 0; i < arity; i++) {
+ rootExpr.setChild(i, optimizePlan(rootExpr.child(i)));
+ }
+ }
+
+ private Group optimizePlan(Group group) {
+ if (group.isJoinGroup()) {
+ return optimizeJoin(group);
+ }
+ GroupExpression rootExpr = group.getLogicalExpression();
+ int arity = rootExpr.arity();
+ for (int i = 0; i < arity; i++) {
+ rootExpr.setChild(i, optimizePlan(rootExpr.child(i)));
+ }
+ return group;
+ }
+
+ private Group optimizeJoin(Group group) {
+ HyperGraph hyperGraph = new HyperGraph();
+ buildGraph(group, hyperGraph);
+ // Right now, we just hardcode the limit with 10000, maybe we need a
better way to set it
+ int limit = 10000;
+ PlanReceiver planReceiver = new PlanReceiver(limit);
+ SubgraphEnumerator subgraphEnumerator = new
SubgraphEnumerator(planReceiver, hyperGraph);
+ if (!subgraphEnumerator.enumerate()) {
+ GraphSimplifier graphSimplifier = new GraphSimplifier(hyperGraph);
+ graphSimplifier.simplifyGraph(limit);
+ if (!subgraphEnumerator.enumerate()) {
+ throw new RuntimeException("DPHyp can not enumerate all sub
graphs with limit=" + limit);
+ }
+ }
+ return planReceiver.getBestPlan(hyperGraph.getNodesMap());
+ }
+
+ /**
+ * build a hyperGraph for the root group
+ *
+ * @param group root group, should be join type
+ * @param hyperGraph build hyperGraph
+ */
+ public void buildGraph(Group group, HyperGraph hyperGraph) {
+ if (!group.isJoinGroup()) {
+ hyperGraph.addNode(optimizePlan(group));
+ return;
+ }
+ buildGraph(group.getLogicalExpression().child(0), hyperGraph);
+ buildGraph(group.getLogicalExpression().child(1), hyperGraph);
+ hyperGraph.addEdge(group);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/CircleDetector.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/CircleDetector.java
similarity index 94%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/CircleDetector.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/CircleDetector.java
index 7cdcb16073..7f97904cf6 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/CircleDetector.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/CircleDetector.java
@@ -15,9 +15,9 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
import com.google.common.base.Preconditions;
@@ -39,8 +39,8 @@ public class CircleDetector {
List<Integer> nodes = new ArrayList<>();
// stored the dependency of each node
List<BitSet> directedEdges = new ArrayList<>();
+ // the nodes are after than this node
List<BitSet> subNodes = new ArrayList<>();
- // whether the node has been visited in dfs
CircleDetector(int size) {
for (int i = 0; i < size; i++) {
@@ -67,9 +67,10 @@ public class CircleDetector {
int order1 = orders.get(node1);
int order2 = orders.get(node2);
if (order1 >= order2) {
- shift(order2, order1 + 1, subNodes.get(order2));
+ shift(order2, order1 + 1, subNodes.get(node2));
}
for (BitSet nodes : subNodes) {
+ // add all subNodes which contains node1 into subNodes of node2.
if (Bitmap.get(nodes, node1)) {
Bitmap.or(nodes, subNodes.get(node2));
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/Edge.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Edge.java
similarity index 96%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/Edge.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Edge.java
index 835f599751..576e7910c6 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/Edge.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Edge.java
@@ -15,9 +15,9 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
import org.apache.doris.nereids.trees.plans.GroupPlan;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/GraphSimplifier.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifier.java
similarity index 76%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/GraphSimplifier.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifier.java
index b341289ae0..88c35d479c 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/GraphSimplifier.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifier.java
@@ -15,12 +15,13 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver.Counter;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.memo.GroupExpression;
import org.apache.doris.nereids.properties.PhysicalProperties;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.Bitmap;
import org.apache.doris.nereids.stats.StatsCalculator;
import org.apache.doris.nereids.trees.plans.GroupPlan;
import org.apache.doris.nereids.trees.plans.Plan;
@@ -34,6 +35,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.PriorityQueue;
+import java.util.Stack;
+import javax.annotation.Nullable;
/**
* GraphSimplifier is used to simplify HyperGraph {@link HyperGraph}
@@ -41,6 +44,8 @@ import java.util.PriorityQueue;
public class GraphSimplifier {
// Note that each index in the graph simplifier is the half of the actual
index
private final int edgeSize;
+ // Detect the circle when order join
+ private CircleDetector circleDetector;
// This is used for cache the intermediate results when calculate the
benefit
// Note that we store it for the after. Because if we put B after A (t1
Join_A t2 Join_B t3),
// B is changed. Therefore, Any step that involves B need to be
recalculated.
@@ -48,14 +53,20 @@ public class GraphSimplifier {
private PriorityQueue<BestSimplification> priorityQueue = new
PriorityQueue<>();
// The graph we are simplifying
private HyperGraph graph;
- // Detect the circle when order join
- private CircleDetector circleDetector;
// It cached the plan in simplification. we don't store it in hyper graph,
// because it's just used for simulating join. In fact, the graph
simplifier
// just generate the partial order of join operator.
private HashMap<BitSet, Plan> cachePlan = new HashMap<>();
- GraphSimplifier(HyperGraph graph) {
+ private Stack<SimplificationStep> appliedSteps = new
Stack<SimplificationStep>();
+ private Stack<SimplificationStep> unAppliedSteps = new
Stack<SimplificationStep>();
+
+ /**
+ * Create a graph simplifier
+ *
+ * @param graph create a graph simplifier to simplify the graph
+ */
+ public GraphSimplifier(HyperGraph graph) {
this.graph = graph;
edgeSize = graph.getEdges().size();
for (int i = 0; i < edgeSize; i++) {
@@ -78,6 +89,30 @@ public class GraphSimplifier {
}
}
+ /**
+ * Check whether all edge has been ordered
+ *
+ * @return if true, all edges has a total order
+ */
+ public boolean isTotalOrder() {
+ for (int i = 0; i < edgeSize; i++) {
+ for (int j = i + 1; j < edgeSize; j++) {
+ Edge edge1 = graph.getEdge(i);
+ Edge edge2 = graph.getEdge(j);
+ List<BitSet> superset = new ArrayList<>();
+ tryGetSuperset(edge1.getLeft(), edge2.getLeft(), superset);
+ tryGetSuperset(edge1.getLeft(), edge2.getRight(), superset);
+ tryGetSuperset(edge1.getRight(), edge2.getLeft(), superset);
+ tryGetSuperset(edge1.getRight(), edge2.getRight(), superset);
+ if (!circleDetector.checkCircleWithEdge(i, j) &&
!circleDetector.checkCircleWithEdge(j, i)
+ && !edge2.isSub(edge1) && !edge1.isSub(edge2) &&
!superset.isEmpty()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
/**
* This function will repeatedly apply simplification steps util the
number of csg-cmp pair
* is under the limit.
@@ -87,10 +122,45 @@ public class GraphSimplifier {
* @param limit the limit number of the csg-cmp pair
*/
public boolean simplifyGraph(int limit) {
- // Now we only support simplify graph until the hyperGraph only
contains one plan
- Preconditions.checkArgument(limit == 1);
- while (applySimplificationStep()) {
+ Preconditions.checkArgument(limit >= 1);
+ initFirstStep();
+ int lowerBound = 0;
+ int upperBound = 1;
+
+ // Try to probe the largest number of steps to satisfy the limit
+ int numApplySteps = 0;
+ Counter counter = new Counter(limit);
+ SubgraphEnumerator enumerator = new SubgraphEnumerator(counter, graph);
+ while (true) {
+ while (numApplySteps < upperBound) {
+ if (!applySimplificationStep()) {
+ // If we have done all steps but still has more sub graphs
+ // Just return
+ if (!enumerator.enumerate()) {
+ return false;
+ }
+ break;
+ }
+ numApplySteps += 1;
+ }
+ if (numApplySteps < upperBound || enumerator.enumerate()) {
+ break;
+ }
+ upperBound *= 2;
}
+
+ // Try to search the lowest number of steps to satisfy the limit
+ upperBound = numApplySteps + 1;
+ while (lowerBound < upperBound) {
+ int mid = lowerBound + (upperBound - lowerBound) / 2;
+ applyStepsWithNum(mid);
+ if (enumerator.enumerate()) {
+ upperBound = mid;
+ } else {
+ lowerBound = mid + 1;
+ }
+ }
+ applyStepsWithNum(upperBound);
return true;
}
@@ -100,26 +170,62 @@ public class GraphSimplifier {
* @return If there is no other steps, return false.
*/
public boolean applySimplificationStep() {
- if (priorityQueue.isEmpty()) {
+ boolean needProcessNeighbor = unAppliedSteps.isEmpty();
+ SimplificationStep bestStep = fetchSimplificationStep();
+ if (bestStep == null) {
return false;
}
+ appliedSteps.push(bestStep);
+ Preconditions.checkArgument(
+ cachePlan.containsKey(bestStep.newLeft) &&
cachePlan.containsKey(bestStep.newRight),
+ String.format("%s - %s", bestStep.newLeft, bestStep.newRight));
+ graph.modifyEdge(bestStep.afterIndex, bestStep.newLeft,
bestStep.newRight);
+ if (needProcessNeighbor) {
+ processNeighbors(bestStep.afterIndex, 0, edgeSize);
+ }
+ return true;
+ }
+
+ private boolean unApplySimplificationStep() {
+ Preconditions.checkArgument(appliedSteps.size() > 0);
+ SimplificationStep bestStep = appliedSteps.pop();
+ unAppliedSteps.push(bestStep);
+ graph.modifyEdge(bestStep.afterIndex, bestStep.oldLeft,
bestStep.oldRight);
+ // Note we don't need to delete this edge in circleDetector, because
we don't need to
+ // recalculate neighbors until all steps applied
+ return true;
+ }
+
+ private @Nullable SimplificationStep fetchSimplificationStep() {
+ if (!unAppliedSteps.isEmpty()) {
+ return unAppliedSteps.pop();
+ }
+ if (priorityQueue.isEmpty()) {
+ return null;
+ }
BestSimplification bestSimplification = priorityQueue.poll();
bestSimplification.isInQueue = false;
SimplificationStep bestStep = bestSimplification.getStep();
- while (!circleDetector.tryAddDirectedEdge(bestStep.beforeIndex,
bestStep.afterIndex)) {
+ while (bestSimplification.bestNeighbor == -1 ||
!circleDetector.tryAddDirectedEdge(bestStep.beforeIndex,
+ bestStep.afterIndex)) {
if (priorityQueue.isEmpty()) {
- return false;
+ return null;
}
bestSimplification = priorityQueue.poll();
bestSimplification.isInQueue = false;
+ processNeighbors(bestStep.afterIndex, 0, edgeSize);
bestStep = bestSimplification.getStep();
}
- Preconditions.checkArgument(
- cachePlan.containsKey(bestStep.newLeft) &&
cachePlan.containsKey(bestStep.newRight),
- String.format("%s - %s", bestStep.newLeft, bestStep.newRight));
- graph.modifyEdge(bestStep.afterIndex, bestStep.newLeft,
bestStep.newRight);
- processNeighbors(bestStep.afterIndex, 0, edgeSize);
- return true;
+ return bestStep;
+ }
+
+ private void applyStepsWithNum(int num) {
+ while (appliedSteps.size() < num) {
+ applySimplificationStep();
+ }
+ while (appliedSteps.size() > num) {
+ unApplySimplificationStep();
+ }
}
/**
@@ -148,11 +254,11 @@ public class GraphSimplifier {
}
// Go through the neighbors with higher index, we only need to
recalculate all related steps
+ BestSimplification bestSimplification =
simplifications.get(edgeIndex1);
+ bestSimplification.bestNeighbor = -1;
for (int edgeIndex2 = Integer.max(beginIndex, edgeIndex1 + 1);
edgeIndex2 < endIndex; edgeIndex2 += 1) {
- BestSimplification bestSimplification =
simplifications.get(edgeIndex1);
Optional<SimplificationStep> optionalStep =
makeSimplificationStep(edgeIndex1, edgeIndex2);
if (optionalStep.isPresent()) {
- bestSimplification.bestNeighbor = -1;
trySetSimplificationStep(optionalStep.get(),
bestSimplification, edgeIndex1, edgeIndex2);
}
}
@@ -160,7 +266,8 @@ public class GraphSimplifier {
private boolean trySetSimplificationStep(SimplificationStep step,
BestSimplification bestSimplification,
int index, int neighborIndex) {
- if (bestSimplification.bestNeighbor == -1 ||
bestSimplification.getBenefit() <= step.getBenefit()) {
+ if (bestSimplification.bestNeighbor == -1 ||
bestSimplification.isInQueue == false
+ || bestSimplification.getBenefit() <= step.getBenefit()) {
bestSimplification.bestNeighbor = neighborIndex;
bestSimplification.setStep(step);
updatePriorityQueue(index);
@@ -284,14 +391,14 @@ public class GraphSimplifier {
}
// choose edge1Before2
step = new SimplificationStep(benefit, edgeIndex1, edgeIndex2,
edge1Before2.getLeft(),
- edge1Before2.getRight());
+ edge1Before2.getRight(),
graph.getEdge(edgeIndex2).getLeft(), graph.getEdge(edgeIndex2).getRight());
} else {
if (cost2Before1 != 0) {
benefit = cost1Before2 / cost2Before1;
}
// choose edge2Before1
step = new SimplificationStep(benefit, edgeIndex2, edgeIndex1,
edge2Before1.getLeft(),
- edge2Before1.getRight());
+ edge2Before1.getRight(),
graph.getEdge(edgeIndex1).getLeft(), graph.getEdge(edgeIndex1).getRight());
}
return step;
}
@@ -308,8 +415,8 @@ public class GraphSimplifier {
}
private double getSimpleCost(Plan plan) {
- if (plan instanceof GroupPlan) {
- return ((GroupPlan) plan).getGroup().getStatistics().getRowCount();
+ if (!(plan instanceof LogicalJoin)) {
+ return
plan.getGroupExpression().get().getOwnerGroup().getStatistics().getRowCount();
}
return
plan.getGroupExpression().get().getCostByProperties(PhysicalProperties.ANY);
}
@@ -360,11 +467,16 @@ public class GraphSimplifier {
int afterIndex;
BitSet newLeft;
BitSet newRight;
+ BitSet oldLeft;
+ BitSet oldRight;
- SimplificationStep(double benefit, int beforeIndex, int afterIndex,
BitSet newLeft, BitSet newRight) {
+ SimplificationStep(double benefit, int beforeIndex, int afterIndex,
BitSet newLeft, BitSet newRight,
+ BitSet oldLeft, BitSet oldRight) {
this.afterIndex = afterIndex;
this.beforeIndex = beforeIndex;
this.benefit = benefit;
+ this.oldLeft = oldLeft;
+ this.oldRight = oldRight;
this.newLeft = newLeft;
this.newRight = newRight;
}
@@ -381,7 +493,7 @@ public class GraphSimplifier {
@Override
public String toString() {
- return String.format("%d -> %d %.2f : %s-%s", beforeIndex,
afterIndex, benefit, newLeft, newRight);
+ return String.format("%d -> %d", beforeIndex, afterIndex);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/HyperGraph.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraph.java
similarity index 76%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/HyperGraph.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraph.java
index 15f00a3bf6..3155bfec9a 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/HyperGraph.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraph.java
@@ -15,16 +15,15 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.Slot;
-import org.apache.doris.nereids.trees.plans.GroupPlan;
import org.apache.doris.nereids.trees.plans.JoinType;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
-import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -41,13 +40,6 @@ import java.util.Set;
public class HyperGraph {
private List<Edge> edges = new ArrayList<>();
private List<Node> nodes = new ArrayList<>();
- private Plan bestPlan;
-
- public static HyperGraph fromPlan(Plan plan) {
- HyperGraph graph = new HyperGraph();
- graph.buildGraph(plan);
- return graph;
- }
public List<Edge> getEdges() {
return edges;
@@ -57,6 +49,10 @@ public class HyperGraph {
return nodes;
}
+ public BitSet getNodesMap() {
+ return Bitmap.newBitmapBetween(0, nodes.size());
+ }
+
public Edge getEdge(int index) {
return edges.get(index);
}
@@ -65,86 +61,26 @@ public class HyperGraph {
return nodes.get(index);
}
- /**
- * Extract the best plan of HyperGraph
- *
- * @return return the best plan
- */
- public Plan toPlan() {
- return bestPlan;
- }
-
- public boolean simplify() {
- GraphSimplifier graphSimplifier = new GraphSimplifier(this);
- graphSimplifier.initFirstStep();
- return graphSimplifier.simplifyGraph(1);
- }
-
- /**
- * Try to enumerate all csg-cmp pairs and get the best plan
- *
- * @return whether enumerate successfully
- */
- public boolean emitPlan() {
- return false;
- }
-
- public boolean optimize() {
- return simplify() && emitPlan();
- }
-
public void splitEdgesForNodes() {
for (Node node : nodes) {
node.splitEdges();
}
}
- private void buildGraph(Plan plan) {
- if ((plan instanceof LogicalProject && plan.child(0) instanceof
GroupPlan)
- || plan instanceof GroupPlan) {
- nodes.add(new Node(nodes.size(), plan));
- return;
- }
-
- LogicalJoin<? extends Plan, ? extends Plan> join;
- if (plan instanceof LogicalProject) {
- LogicalProject<? extends Plan> project = (LogicalProject<? extends
Plan>) plan;
- join = (LogicalJoin<? extends Plan, ? extends Plan>)
project.child();
-
- // Handle project
- // Ignore the projection expression just using for selection
column.
- // TODO: how to handle Alias and complex project expression
- } else {
- join = (LogicalJoin<? extends Plan, ? extends Plan>) plan;
- }
-
- // Now we only support inner join with Inside-Project
- // TODO: Other joins can be added according CD-C algorithm
- if (join.getJoinType() != JoinType.INNER_JOIN) {
- Node node = new Node(nodes.size(), plan);
- nodes.add(node);
- return;
- }
-
- buildGraph(join.left());
- buildGraph(join.right());
- addEdge(join);
- }
-
- private BitSet findNodes(Set<Slot> slots) {
- BitSet bitSet = Bitmap.newBitmap();
- for (Node node : nodes) {
- for (Slot slot : node.getPlan().getOutput()) {
- if (slots.contains(slot)) {
- Bitmap.set(bitSet, node.getIndex());
- break;
- }
- }
- }
- return bitSet;
+ public void addNode(Group group) {
+ Preconditions.checkArgument(!group.isJoinGroup());
+ // TODO: replace plan with group expression or others
+ nodes.add(new Node(nodes.size(), group));
}
- private void addEdge(LogicalJoin<? extends Plan, ? extends Plan> join) {
+ /**
+ * try to add edge for join group
+ *
+ * @param group The join group
+ */
+ public void addEdge(Group group) {
+ Preconditions.checkArgument(group.isJoinGroup());
+ LogicalJoin<? extends Plan, ? extends Plan> join = (LogicalJoin)
group.getLogicalExpression().getPlan();
for (Expression expression : join.getExpressions()) {
LogicalJoin singleJoin = new LogicalJoin(join.getJoinType(),
ImmutableList.of(expression), join.left(),
join.right());
@@ -165,6 +101,19 @@ public class HyperGraph {
// We don't implement this trick now.
}
+ private BitSet findNodes(Set<Slot> slots) {
+ BitSet bitSet = Bitmap.newBitmap();
+ for (Node node : nodes) {
+ for (Slot slot : node.getPlan().getOutput()) {
+ if (slots.contains(slot)) {
+ Bitmap.set(bitSet, node.getIndex());
+ break;
+ }
+ }
+ }
+ return bitSet;
+ }
+
/**
* Graph simplifier need to update the edge for join ordering
*
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/Node.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Node.java
similarity index 79%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/Node.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Node.java
index 51712e24f2..8eb4bb843e 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/Node.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Node.java
@@ -15,14 +15,12 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.Bitmap;
-import org.apache.doris.nereids.trees.plans.GroupPlan;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.trees.plans.Plan;
-import com.google.common.base.Preconditions;
-
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
@@ -33,7 +31,7 @@ import javax.annotation.Nullable;
*/
public class Node {
private final int index;
- private Plan plan;
+ private Group group;
private List<Edge> edges = new ArrayList<>();
// We split these into simple edges (only one node on each side) and
complex edges (others)
// because we can often quickly discard all simple edges by testing the
set of interesting nodes
@@ -43,8 +41,8 @@ public class Node {
private List<Edge> simpleEdges = new ArrayList<>();
private BitSet complexNeighborhood = new BitSet();
- public Node(int index, Plan plan) {
- this.plan = plan;
+ public Node(int index, Group group) {
+ this.group = group;
this.index = index;
}
@@ -65,7 +63,11 @@ public class Node {
throw new RuntimeException(String.format("There is no simple Edge
<%d - %s>", index, nodes));
} else if (Bitmap.isOverlap(complexNeighborhood, nodes)) {
for (Edge edge : complexEdges) {
- if (Bitmap.isSubset(edge.getLeft(), nodes) ||
Bitmap.isSubset(edge.getRight(), nodes)) {
+ // TODO: Right now we check all edges. But due to the simple
cmp, we can only check that the edge with
+ // one side that equal to this node
+ if ((Bitmap.isSubset(edge.getLeft(), nodes) &&
Bitmap.isSubset(edge.getRight(),
+ Bitmap.newBitmap(index))) ||
(Bitmap.isSubset(edge.getRight(), nodes) && Bitmap.isSubset(
+ edge.getLeft(), Bitmap.newBitmap(index)))) {
return edge;
}
}
@@ -82,12 +84,12 @@ public class Node {
}
public Plan getPlan() {
- return plan;
+ return group.getLogicalExpression().getPlan();
}
- public void setPlan(Plan plan) {
- this.plan = plan;
- }
+ // public void setPlan(Plan plan) {
+ // this.plan = plan;
+ // }
public List<Edge> getComplexEdges() {
return complexEdges;
@@ -137,6 +139,10 @@ public class Node {
* by graph simplifier.
*/
public void splitEdges() {
+ simpleEdges.clear();
+ Bitmap.clear(simpleNeighborhood);
+ complexEdges.clear();
+ Bitmap.clear(complexNeighborhood);
for (Edge edge : edges) {
if (edge.isSimple()) {
simpleEdges.add(edge);
@@ -153,12 +159,14 @@ public class Node {
}
public String getName() {
- Preconditions.checkArgument(plan instanceof GroupPlan, "Each node is a
group plan in child");
- return ((GroupPlan)
plan).getGroup().getLogicalExpression().getPlan().getType().name() + index;
+ return getPlan().getType().name() + index;
}
public double getRowCount() {
- Preconditions.checkArgument(plan instanceof GroupPlan, "Each node is a
group plan in child");
- return ((GroupPlan) plan).getGroup().getStatistics().getRowCount();
+ return group.getStatistics().getRowCount();
+ }
+
+ public Group getGroup() {
+ return group;
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/SubgraphEnumerator.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumerator.java
similarity index 80%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/SubgraphEnumerator.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumerator.java
index d17cd06f1c..03be7bf34c 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/SubgraphEnumerator.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumerator.java
@@ -15,11 +15,11 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.Bitmap;
-import
org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.SubsetIterator;
-import
org.apache.doris.nereids.rules.joinreorder.hypergraph.receiver.AbstractReceiver;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.SubsetIterator;
+import
org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver.AbstractReceiver;
import java.util.BitSet;
import java.util.List;
@@ -35,7 +35,7 @@ public class SubgraphEnumerator {
//The enumerated hyperGraph
HyperGraph hyperGraph;
- SubgraphEnumerator(AbstractReceiver receiver, HyperGraph hyperGraph) {
+ public SubgraphEnumerator(AbstractReceiver receiver, HyperGraph
hyperGraph) {
this.receiver = receiver;
this.hyperGraph = hyperGraph;
}
@@ -46,10 +46,11 @@ public class SubgraphEnumerator {
* @return whether the hyperGraph is enumerated successfully
*/
public boolean enumerate() {
+ receiver.reset();
List<Node> nodes = hyperGraph.getNodes();
// Init all nodes in Receiver
for (Node node : nodes) {
- receiver.addPlan(node.getBitSet(), node.getPlan());
+ receiver.addGroup(node.getBitSet(), node.getGroup());
}
hyperGraph.splitEdgesForNodes();
int size = nodes.size();
@@ -59,32 +60,38 @@ public class SubgraphEnumerator {
for (int i = size - 2; i >= 0; i--) {
BitSet csg = Bitmap.newBitmap(i);
Bitmap.unset(forbiddenNodes, i);
- emitCsg(csg);
- enumerateCsgRec(csg, Bitmap.newBitmap(forbiddenNodes));
+ if (!emitCsg(csg) || !enumerateCsgRec(csg,
Bitmap.newBitmap(forbiddenNodes))) {
+ return false;
+ }
}
return true;
}
// The general purpose of EnumerateCsgRec is to extend a given set csg,
which
// induces a connected subgraph of G to a larger set with the same
property.
- private void enumerateCsgRec(BitSet csg, BitSet forbiddenNodes) {
+ private boolean enumerateCsgRec(BitSet csg, BitSet forbiddenNodes) {
BitSet neighborhood = calcNeighborhood(csg, forbiddenNodes);
SubsetIterator subsetIterator = Bitmap.getSubsetIterator(neighborhood);
for (BitSet subset : subsetIterator) {
BitSet newCsg = Bitmap.newBitmapUnion(csg, subset);
if (receiver.contain(newCsg)) {
- emitCsg(newCsg);
+ if (!emitCsg(newCsg)) {
+ return false;
+ }
}
}
Bitmap.or(forbiddenNodes, neighborhood);
subsetIterator.reset();
for (BitSet subset : subsetIterator) {
BitSet newCsg = Bitmap.newBitmapUnion(csg, subset);
- enumerateCsgRec(newCsg, Bitmap.newBitmap(forbiddenNodes));
+ if (!enumerateCsgRec(newCsg, Bitmap.newBitmap(forbiddenNodes))) {
+ return false;
+ }
}
+ return true;
}
- private void enumerateCmpRec(BitSet csg, BitSet cmp, BitSet
forbiddenNodes) {
+ private boolean enumerateCmpRec(BitSet csg, BitSet cmp, BitSet
forbiddenNodes) {
BitSet neighborhood = calcNeighborhood(cmp, forbiddenNodes);
SubsetIterator subsetIterator = new SubsetIterator(neighborhood);
for (BitSet subset : subsetIterator) {
@@ -96,7 +103,9 @@ public class SubgraphEnumerator {
for (Edge edge : hyperGraph.getEdges()) {
if (Bitmap.isSubset(edge.getLeft(), csg) &&
Bitmap.isSubset(edge.getRight(), newCmp) || (
Bitmap.isSubset(edge.getLeft(), newCmp) &&
Bitmap.isSubset(edge.getRight(), csg))) {
- receiver.emitCsgCmp(csg, newCmp, edge);
+ if (!receiver.emitCsgCmp(csg, newCmp, edge)) {
+ return false;
+ }
break;
}
}
@@ -106,24 +115,30 @@ public class SubgraphEnumerator {
subsetIterator.reset();
for (BitSet subset : subsetIterator) {
BitSet newCmp = Bitmap.newBitmapUnion(cmp, subset);
- enumerateCmpRec(csg, newCmp, Bitmap.newBitmap(forbiddenNodes));
+ if (!enumerateCmpRec(csg, newCmp,
Bitmap.newBitmap(forbiddenNodes))) {
+ return false;
+ }
}
+ return true;
}
// EmitCsg takes as an argument a non-empty, proper subset csg of
HyperGraph , which
// induces a connected subgraph. It is then responsible to generate the
seeds for
// all cmp such that (csg, cmp) becomes a csg-cmp-pair.
- private void emitCsg(BitSet csg) {
+ private boolean emitCsg(BitSet csg) {
BitSet forbiddenNodes = Bitmap.newBitmapBetween(0,
Bitmap.nextSetBit(csg, 0));
Bitmap.or(forbiddenNodes, csg);
BitSet neighborhoods = calcNeighborhood(csg,
Bitmap.newBitmap(forbiddenNodes));
+
for (int nodeIndex : Bitmap.getReverseIterator(neighborhoods)) {
BitSet cmp = Bitmap.newBitmap(nodeIndex);
// whether there is an edge between csg and cmp
Node cmpNode = hyperGraph.getNode(nodeIndex);
Edge edge = cmpNode.tryGetEdgeWith(csg);
if (edge != null) {
- receiver.emitCsgCmp(csg, cmp, edge);
+ if (!receiver.emitCsgCmp(csg, cmp, edge)) {
+ return false;
+ }
}
// In order to avoid enumerate repeated cmp, e.g.,
@@ -138,8 +153,11 @@ public class SubgraphEnumerator {
BitSet newForbiddenNodes = Bitmap.newBitmapBetween(0, nodeIndex +
1);
Bitmap.and(newForbiddenNodes, neighborhoods);
Bitmap.or(newForbiddenNodes, forbiddenNodes);
- enumerateCmpRec(csg, cmp, newForbiddenNodes);
+ if (!enumerateCmpRec(csg, cmp, newForbiddenNodes)) {
+ return false;
+ }
}
+ return true;
}
// This function is used to calculate neighborhoods of given subgraph.
@@ -163,9 +181,9 @@ public class SubgraphEnumerator {
for (Edge edge : hyperGraph.getEdges()) {
BitSet left = edge.getLeft();
BitSet right = edge.getRight();
- if (Bitmap.isSubset(left, subGraph) && !Bitmap.isOverlap(left,
forbiddenNodes)) {
+ if (Bitmap.isSubset(left, subGraph) && !Bitmap.isOverlap(right,
forbiddenNodes)) {
Bitmap.set(neighborhoods, right.nextSetBit(0));
- } else if (Bitmap.isSubset(right, subGraph) &&
!Bitmap.isOverlap(right, forbiddenNodes)) {
+ } else if (Bitmap.isSubset(right, subGraph) &&
!Bitmap.isOverlap(left, forbiddenNodes)) {
Bitmap.set(neighborhoods, left.nextSetBit(0));
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/BitSetIterator.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/BitSetIterator.java
similarity index 96%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/BitSetIterator.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/BitSetIterator.java
index 1c1af0b1f1..77d55da361 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/BitSetIterator.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/BitSetIterator.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap;
import org.jetbrains.annotations.NotNull;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/Bitmap.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/Bitmap.java
similarity index 98%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/Bitmap.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/Bitmap.java
index 27ba8d5994..619a9edf62 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/Bitmap.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/Bitmap.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap;
import java.util.BitSet;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/ReverseBitSetIterator.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/ReverseBitSetIterator.java
similarity index 96%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/ReverseBitSetIterator.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/ReverseBitSetIterator.java
index b039fbed9d..125f05dc1c 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/ReverseBitSetIterator.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/ReverseBitSetIterator.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap;
import org.jetbrains.annotations.NotNull;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/SubsetIterator.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/SubsetIterator.java
similarity index 97%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/SubsetIterator.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/SubsetIterator.java
index 0f48b3ad2f..8b7c2921df 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/bitmap/SubsetIterator.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/SubsetIterator.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap;
import org.jetbrains.annotations.NotNull;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/receiver/AbstractReceiver.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/AbstractReceiver.java
similarity index 77%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/receiver/AbstractReceiver.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/AbstractReceiver.java
index 1d6da72803..13c85595d1 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/receiver/AbstractReceiver.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/AbstractReceiver.java
@@ -15,10 +15,10 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph.receiver;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.Edge;
-import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.Edge;
+import org.apache.doris.nereids.memo.Group;
import java.util.BitSet;
@@ -28,9 +28,11 @@ import java.util.BitSet;
public interface AbstractReceiver {
public boolean emitCsgCmp(BitSet csg, BitSet cmp, Edge edge);
- public void addPlan(BitSet bitSet, Plan plan);
+ public void addGroup(BitSet bitSet, Group group);
public boolean contain(BitSet bitSet);
- public Plan getBestPlan(BitSet bitSet);
+ public void reset();
+
+ public Group getBestPlan(BitSet bitSet);
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/receiver/Counter.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/Counter.java
similarity index 77%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/receiver/Counter.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/Counter.java
index 5633d1b9c9..b3bba9a2e8 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/receiver/Counter.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/Counter.java
@@ -15,10 +15,10 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph.receiver;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.Edge;
-import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.Edge;
+import org.apache.doris.nereids.memo.Group;
import com.google.common.base.Preconditions;
@@ -30,8 +30,18 @@ import java.util.HashMap;
*/
public class Counter implements AbstractReceiver {
// limit define the max number of csg-cmp pair in this Receiver
+ private int limit;
+ private int emitCount = 0;
private HashMap<BitSet, Integer> counter = new HashMap<>();
+ public Counter() {
+ this.limit = Integer.MAX_VALUE;
+ }
+
+ public Counter(int limit) {
+ this.limit = limit;
+ }
+
/**
* Emit a new plan from bottom to top
*
@@ -43,6 +53,10 @@ public class Counter implements AbstractReceiver {
public boolean emitCsgCmp(BitSet left, BitSet right, Edge edge) {
Preconditions.checkArgument(counter.containsKey(left));
Preconditions.checkArgument(counter.containsKey(right));
+ emitCount += 1;
+ if (emitCount > limit) {
+ return false;
+ }
BitSet bitSet = new BitSet();
bitSet.or(left);
bitSet.or(right);
@@ -54,7 +68,7 @@ public class Counter implements AbstractReceiver {
return true;
}
- public void addPlan(BitSet bitSet, Plan plan) {
+ public void addGroup(BitSet bitSet, Group group) {
counter.put(bitSet, 1);
}
@@ -62,7 +76,12 @@ public class Counter implements AbstractReceiver {
return counter.containsKey(bitSet);
}
- public Plan getBestPlan(BitSet bitSet) {
+ public void reset() {
+ this.counter.clear();
+ emitCount = 0;
+ }
+
+ public Group getBestPlan(BitSet bitSet) {
throw new RuntimeException("Counter does not support getBestPlan()");
}
@@ -73,4 +92,8 @@ public class Counter implements AbstractReceiver {
public HashMap<BitSet, Integer> getAllCount() {
return counter;
}
+
+ public int getLimit() {
+ return limit;
+ }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/PlanReceiver.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/PlanReceiver.java
new file mode 100644
index 0000000000..be708902a9
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/PlanReceiver.java
@@ -0,0 +1,140 @@
+// 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.jobs.joinorder.hypergraph.receiver;
+
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.Edge;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.memo.Group;
+import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.properties.PhysicalProperties;
+import org.apache.doris.nereids.stats.StatsCalculator;
+import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
+import java.util.BitSet;
+import java.util.HashMap;
+
+/**
+ * The Receiver is used for cached the plan that has been emitted and build
the new plan
+ */
+public class PlanReceiver implements AbstractReceiver {
+ // limit define the max number of csg-cmp pair in this Receiver
+ HashMap<BitSet, Group> planTable = new HashMap<>();
+ int limit;
+ int emitCount = 0;
+
+ public PlanReceiver() {
+ limit = Integer.MAX_VALUE;
+ }
+
+ public PlanReceiver(int limit) {
+ this.limit = limit;
+ }
+
+ /**
+ * Emit a new plan from bottom to top
+ *
+ * @param left the bitmap of left child tree
+ * @param right the bitmap of the right child tree
+ * @param edge the join operator
+ * @return the left and the right can be connected by the edge
+ */
+ @Override
+ public boolean emitCsgCmp(BitSet left, BitSet right, Edge edge) {
+ Preconditions.checkArgument(planTable.containsKey(left));
+ Preconditions.checkArgument(planTable.containsKey(right));
+ emitCount += 1;
+ if (emitCount > limit) {
+ return false;
+ }
+ BitSet fullKey = Bitmap.newBitmapUnion(left, right);
+ Group group1 = constructGroup(left, right, edge);
+ Group group2 = constructGroup(right, left, edge);
+ Group winnerGroup;
+ if
(group1.getLogicalExpression().getCostByProperties(PhysicalProperties.ANY) <
group2.getLogicalExpression()
+ .getCostByProperties(PhysicalProperties.ANY)) {
+ winnerGroup = group1;
+ } else {
+ winnerGroup = group2;
+ }
+
+ if (!planTable.containsKey(fullKey)
+ ||
planTable.get(fullKey).getLogicalExpression().getCostByProperties(PhysicalProperties.ANY)
+ >
winnerGroup.getLogicalExpression().getCostByProperties(PhysicalProperties.ANY))
{
+ planTable.put(fullKey, winnerGroup);
+ }
+ return true;
+ }
+
+ @Override
+ public void addGroup(BitSet bitSet, Group group) {
+ planTable.put(bitSet, group);
+ }
+
+ @Override
+ public boolean contain(BitSet bitSet) {
+ return planTable.containsKey(bitSet);
+ }
+
+ @Override
+ public void reset() {
+ planTable.clear();
+ emitCount = 0;
+ }
+
+ @Override
+ public Group getBestPlan(BitSet bitSet) {
+ Preconditions.checkArgument(planTable.containsKey(bitSet));
+ return planTable.get(bitSet);
+ }
+
+ private double getSimpleCost(Plan plan) {
+ if (!(plan instanceof LogicalJoin)) {
+ return
plan.getGroupExpression().get().getOwnerGroup().getStatistics().getRowCount();
+ }
+ return
plan.getGroupExpression().get().getCostByProperties(PhysicalProperties.ANY);
+ }
+
+ private Group constructGroup(BitSet left, BitSet right, Edge edge) {
+ Preconditions.checkArgument(planTable.containsKey(left));
+ Preconditions.checkArgument(planTable.containsKey(right));
+ Group leftGroup = planTable.get(left);
+ Group rightGroup = planTable.get(right);
+ Plan leftPlan = leftGroup.getLogicalExpression().getPlan();
+ Plan rightPlan = rightGroup.getLogicalExpression().getPlan();
+
+ double cost = getSimpleCost(leftPlan) + getSimpleCost(rightPlan);
+ LogicalJoin newJoin = new LogicalJoin(edge.getJoin().getJoinType(),
edge.getJoin().getExpressions(),
+ leftGroup.getLogicalExpression().getPlan(),
+ rightGroup.getLogicalExpression().getPlan());
+
+ GroupExpression groupExpression = new GroupExpression(newJoin,
Lists.newArrayList(leftGroup, rightGroup));
+ Group group = new Group();
+ group.addGroupExpression(groupExpression);
+ StatsCalculator.estimate(groupExpression);
+ cost += group.getStatistics().getRowCount();
+
+ groupExpression.updateLowestCostTable(PhysicalProperties.ANY,
+ Lists.newArrayList(PhysicalProperties.ANY,
PhysicalProperties.ANY), cost);
+ return group;
+ }
+}
+
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Group.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Group.java
index e699e74eb3..ca7e47a0f9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Group.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Group.java
@@ -20,6 +20,7 @@ package org.apache.doris.nereids.memo;
import org.apache.doris.common.Pair;
import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.properties.PhysicalProperties;
+import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.util.TreeStringUtils;
import org.apache.doris.statistics.StatsDeriveResult;
@@ -316,6 +317,10 @@ public class Group {
lowestCostPlans.clear();
}
+ public boolean isJoinGroup() {
+ return getLogicalExpression().getPlan() instanceof LogicalJoin;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/GroupExpression.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/GroupExpression.java
index d7cf89ed3b..da5b65f1c0 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/GroupExpression.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/GroupExpression.java
@@ -105,6 +105,11 @@ public class GroupExpression {
return children.get(i);
}
+ public void setChild(int i, Group group) {
+ children.set(i, group);
+ group.addParentExpression(this);
+ }
+
public List<Group> children() {
return children;
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorder.java
deleted file mode 100644
index 52d1609b9c..0000000000
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorder.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.joinreorder;
-
-import org.apache.doris.nereids.rules.Rule;
-import org.apache.doris.nereids.rules.RuleType;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.HyperGraph;
-import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory;
-import org.apache.doris.nereids.trees.plans.Plan;
-import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
-import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
-
-/**
- * This rule is for Join Reorder (non Cascades Transfrom Join Reorder).
- */
-public class HyperGraphJoinReorder extends OneRewriteRuleFactory {
- @Override
- public Rule build() {
- // TODO: we need a pattern to match a subtree of join and mark the
node in this tree ordered
- return logicalJoin(
- subTree(LogicalJoin.class, LogicalProject.class),
- subTree(LogicalJoin.class, LogicalProject.class))
- .thenApply(ctx -> {
- LogicalJoin<? extends Plan, ? extends Plan> rootJoin =
ctx.root;
- // TODO: check mark.
- HyperGraph graph = HyperGraph.fromPlan(rootJoin);
- if (graph.optimize()) {
- return graph.toPlan();
- }
- return null;
- }).toRule(RuleType.JOIN_REORDER);
- }
-}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupLeft.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupLeft.java
deleted file mode 100644
index 56aa07a0fc..0000000000
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupLeft.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.joinreorder;
-
-import org.apache.doris.nereids.rules.Rule;
-import org.apache.doris.nereids.rules.RuleType;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.HyperGraph;
-import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory;
-import org.apache.doris.nereids.trees.plans.Plan;
-import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
-import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
-
-/**
- * This rule is for Join Reorder (non Cascades Transfrom Join Reorder).
- */
-public class HyperGraphJoinReorderGroupLeft extends OneRewriteRuleFactory {
- @Override
- public Rule build() {
- // TODO: we need a pattern to match a subtree of join and mark the
node in this tree ordered
- return logicalJoin(
- group(),
- subTree(LogicalJoin.class, LogicalProject.class))
- .thenApply(ctx -> {
- LogicalJoin<? extends Plan, ? extends Plan> rootJoin =
ctx.root;
- HyperGraph graph = HyperGraph.fromPlan(rootJoin);
- System.out.println(graph.toDottyHyperGraph());
- if (graph.optimize()) {
- return graph.toPlan();
- }
- return null;
- }).toRule(RuleType.JOIN_REORDER);
- }
-}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupRight.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupRight.java
deleted file mode 100644
index c1f3d1e16c..0000000000
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupRight.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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.joinreorder;
-
-import org.apache.doris.nereids.rules.Rule;
-import org.apache.doris.nereids.rules.RuleType;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.HyperGraph;
-import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory;
-import org.apache.doris.nereids.trees.plans.Plan;
-import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
-import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
-
-/**
- * This rule is for Join Reorder (non Cascades Transfrom Join Reorder).
- */
-public class HyperGraphJoinReorderGroupRight extends OneRewriteRuleFactory {
- @Override
- public Rule build() {
- // TODO: we need a pattern to match a subtree of join and mark the
node in this tree ordered
- return logicalJoin(
- subTree(LogicalJoin.class, LogicalProject.class),
- group())
- .thenApply(ctx -> {
- LogicalJoin<? extends Plan, ? extends Plan> rootJoin =
ctx.root;
- HyperGraph graph = HyperGraph.fromPlan(rootJoin);
- if (graph.optimize()) {
- return graph.toPlan();
- }
- return null;
- }).toRule(RuleType.JOIN_REORDER);
- }
-}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/receiver/PlanTable.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/receiver/PlanTable.java
deleted file mode 100644
index 2cb9b62d23..0000000000
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/receiver/PlanTable.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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.joinreorder.hypergraph.receiver;
-
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.Edge;
-import org.apache.doris.nereids.trees.plans.Plan;
-
-import java.util.BitSet;
-import java.util.HashMap;
-
-/**
- * The Receiver is used for cached the plan that has been emitted and build
the new plan
- */
-public class PlanTable implements AbstractReceiver {
- // limit define the max number of csg-cmp pair in this Receiver
- HashMap<BitSet, Integer> counter;
-
- /**
- * Emit a new plan from bottom to top
- *
- * @param left the bitmap of left child tree
- * @param right the bitmap of the right child tree
- * @param edge the join operator
- * @return the left and the right can be connected by the edge
- */
- public boolean emitCsgCmp(BitSet left, BitSet right, Edge edge) {
- throw new RuntimeException("PlanTable does not support emitCsgCmp()");
- }
-
- public void addPlan(BitSet bitSet, Plan plan) {
- throw new RuntimeException("PlanTable does not support addPlan()");
- }
-
- public boolean contain(BitSet bitSet) {
- throw new RuntimeException("PlanTable does not support contain()");
- }
-
- public Plan getBestPlan(BitSet bitSet) {
- throw new RuntimeException("PlanTable does not support getBestPlan()");
- }
-}
-
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupLeftTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/JoinOrderJobTest.java
similarity index 85%
rename from
fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupLeftTest.java
rename to
fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/JoinOrderJobTest.java
index b8d74d555b..93edf18663 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupLeftTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/JoinOrderJobTest.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder;
+package org.apache.doris.nereids.jobs.joinorder;
import org.apache.doris.common.Pair;
import org.apache.doris.nereids.trees.plans.JoinType;
@@ -26,17 +26,18 @@ import org.apache.doris.nereids.util.MemoTestUtils;
import org.apache.doris.nereids.util.PlanChecker;
import org.apache.doris.nereids.util.PlanConstructor;
+import com.google.common.collect.Lists;
import org.junit.jupiter.api.Test;
-class HyperGraphJoinReorderGroupLeftTest {
- private final LogicalOlapScan scan1 =
PlanConstructor.newLogicalOlapScan(0, "t1", 0);
- private final LogicalOlapScan scan2 =
PlanConstructor.newLogicalOlapScan(1, "t2", 0);
- private final LogicalOlapScan scan3 =
PlanConstructor.newLogicalOlapScan(2, "t3", 0);
- private final LogicalOlapScan scan4 =
PlanConstructor.newLogicalOlapScan(3, "t4", 0);
- private final LogicalOlapScan scan5 =
PlanConstructor.newLogicalOlapScan(4, "t5", 0);
+public class JoinOrderJobTest {
+ private final LogicalOlapScan scan1 =
PlanConstructor.newLogicalOlapScan(1, "t1", 0);
+ private final LogicalOlapScan scan2 =
PlanConstructor.newLogicalOlapScan(2, "t2", 0);
+ private final LogicalOlapScan scan3 =
PlanConstructor.newLogicalOlapScan(3, "t3", 0);
+ private final LogicalOlapScan scan4 =
PlanConstructor.newLogicalOlapScan(4, "t4", 0);
+ private final LogicalOlapScan scan5 =
PlanConstructor.newLogicalOlapScan(5, "t5", 0);
@Test
- void test() {
+ void testJoinOrderJob() {
LogicalPlan plan = new LogicalPlanBuilder(scan1)
.hashJoinUsing(
new LogicalPlanBuilder(scan2)
@@ -46,11 +47,12 @@ class HyperGraphJoinReorderGroupLeftTest {
.build(),
JoinType.INNER_JOIN, Pair.of(0, 1)
)
+ .project(Lists.newArrayList(1))
.build();
-
+ System.out.println(plan.treeString());
PlanChecker.from(MemoTestUtils.createConnectContext(), plan)
.deriveStats()
- .applyTopDown(new HyperGraphJoinReorderGroupLeft())
+ .orderJoin()
.printlnTree();
}
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/BitSetTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/BitSetTest.java
similarity index 86%
rename from
fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/BitSetTest.java
rename to
fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/BitSetTest.java
index 8a40a0a534..20b69583ac 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/BitSetTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/BitSetTest.java
@@ -15,10 +15,10 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.Bitmap;
-import
org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.SubsetIterator;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.SubsetIterator;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/CircleDetectorTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/CircleDetectorTest.java
similarity index 96%
rename from
fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/CircleDetectorTest.java
rename to
fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/CircleDetectorTest.java
index de654924ea..bee8b56059 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/CircleDetectorTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/CircleDetectorTest.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
import com.google.common.collect.ImmutableList;
import org.junit.jupiter.api.Assertions;
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/GraphSimplifierTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifierTest.java
similarity index 81%
rename from
fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/GraphSimplifierTest.java
rename to
fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifierTest.java
index d0365615ca..ec6790f41d 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/GraphSimplifierTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifierTest.java
@@ -15,9 +15,9 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.receiver.Counter;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver.Counter;
import org.apache.doris.nereids.trees.plans.JoinType;
import org.apache.doris.nereids.util.HyperGraphBuilder;
@@ -33,7 +33,7 @@ public class GraphSimplifierTest {
// |
// t2
HyperGraph hyperGraph = new HyperGraphBuilder()
- .init(10, 20, 30, 40, 50)
+ .init(10, 30, 20, 40, 50)
.addEdge(JoinType.INNER_JOIN, 0, 1)
.addEdge(JoinType.INNER_JOIN, 0, 2)
.addEdge(JoinType.INNER_JOIN, 0, 3)
@@ -47,8 +47,9 @@ public class GraphSimplifierTest {
SubgraphEnumerator subgraphEnumerator = new
SubgraphEnumerator(counter, hyperGraph);
subgraphEnumerator.enumerate();
for (int count : counter.getAllCount().values()) {
- Assertions.assertEquals(count, 1);
+ Assertions.assertTrue(count < 10);
}
+ Assertions.assertTrue(graphSimplifier.isTotalOrder());
}
@Test
@@ -74,8 +75,9 @@ public class GraphSimplifierTest {
SubgraphEnumerator subgraphEnumerator = new
SubgraphEnumerator(counter, hyperGraph);
subgraphEnumerator.enumerate();
for (int count : counter.getAllCount().values()) {
- Assertions.assertEquals(count, 1);
+ Assertions.assertTrue(count < 10);
}
+ Assertions.assertTrue(graphSimplifier.isTotalOrder());
}
@Test
@@ -102,8 +104,9 @@ public class GraphSimplifierTest {
SubgraphEnumerator subgraphEnumerator = new
SubgraphEnumerator(counter, hyperGraph);
subgraphEnumerator.enumerate();
for (int count : counter.getAllCount().values()) {
- Assertions.assertEquals(count, 1);
+ Assertions.assertTrue(count < 10);
}
+ Assertions.assertTrue(graphSimplifier.isTotalOrder());
}
@Test
@@ -135,8 +138,9 @@ public class GraphSimplifierTest {
SubgraphEnumerator subgraphEnumerator = new
SubgraphEnumerator(counter, hyperGraph);
subgraphEnumerator.enumerate();
for (int count : counter.getAllCount().values()) {
- Assertions.assertEquals(count, 1);
+ Assertions.assertTrue(count < 10);
}
+ Assertions.assertTrue(graphSimplifier.isTotalOrder());
}
@Test
@@ -160,8 +164,8 @@ public class GraphSimplifierTest {
@Test
void testRandomQuery() {
- for (int i = 0; i < 10; i++) {
- HyperGraph hyperGraph = new
HyperGraphBuilder().randomBuildWith(10, 40);
+ for (int i = 0; i < 100; i++) {
+ HyperGraph hyperGraph = new
HyperGraphBuilder().randomBuildWith(20, 40);
GraphSimplifier graphSimplifier = new GraphSimplifier(hyperGraph);
graphSimplifier.initFirstStep();
while (graphSimplifier.applySimplificationStep()) {
@@ -170,8 +174,25 @@ public class GraphSimplifierTest {
SubgraphEnumerator subgraphEnumerator = new
SubgraphEnumerator(counter, hyperGraph);
subgraphEnumerator.enumerate();
for (int count : counter.getAllCount().values()) {
- Assertions.assertEquals(count, 1);
+ Assertions.assertTrue(count < 1000);
}
+ Assertions.assertTrue(graphSimplifier.isTotalOrder());
}
}
+
+ @Test
+ void testLimit() {
+ int tableNum = 10;
+ int edgeNum = 20;
+ for (int limit = 1000; limit < 10000; limit += 100) {
+ HyperGraph hyperGraph = new
HyperGraphBuilder().randomBuildWith(tableNum, edgeNum);
+ GraphSimplifier graphSimplifier = new GraphSimplifier(hyperGraph);
+ graphSimplifier.simplifyGraph(limit);
+ Counter counter = new Counter();
+ SubgraphEnumerator subgraphEnumerator = new
SubgraphEnumerator(counter, hyperGraph);
+ subgraphEnumerator.enumerate();
+ Assertions.assertTrue(counter.getLimit() >= 0);
+ }
+
+ }
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/HyperGraphTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraphTest.java
similarity index 98%
rename from
fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/HyperGraphTest.java
rename to
fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraphTest.java
index df7cf69852..113a8db93d 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/HyperGraphTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraphTest.java
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
import org.apache.doris.nereids.trees.plans.JoinType;
import org.apache.doris.nereids.util.HyperGraphBuilder;
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/SubgraphEnumeratorTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumeratorTest.java
similarity index 95%
rename from
fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/SubgraphEnumeratorTest.java
rename to
fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumeratorTest.java
index 7f1bd8ec11..1b4e1fb306 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/hypergraph/SubgraphEnumeratorTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumeratorTest.java
@@ -15,11 +15,11 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.joinreorder.hypergraph;
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.Bitmap;
-import
org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.SubsetIterator;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.receiver.Counter;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.SubsetIterator;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver.Counter;
import org.apache.doris.nereids.trees.plans.JoinType;
import org.apache.doris.nereids.util.HyperGraphBuilder;
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupRightTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupRightTest.java
deleted file mode 100644
index e9ee1d1542..0000000000
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderGroupRightTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// 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.joinreorder;
-
-import org.apache.doris.common.Pair;
-import org.apache.doris.nereids.trees.plans.JoinType;
-import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
-import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
-import org.apache.doris.nereids.util.LogicalPlanBuilder;
-import org.apache.doris.nereids.util.MemoTestUtils;
-import org.apache.doris.nereids.util.PlanChecker;
-import org.apache.doris.nereids.util.PlanConstructor;
-
-import org.junit.jupiter.api.Test;
-
-class HyperGraphJoinReorderGroupRightTest {
- private final LogicalOlapScan scan1 =
PlanConstructor.newLogicalOlapScan(0, "t1", 0);
- private final LogicalOlapScan scan2 =
PlanConstructor.newLogicalOlapScan(1, "t2", 0);
- private final LogicalOlapScan scan3 =
PlanConstructor.newLogicalOlapScan(2, "t3", 0);
- private final LogicalOlapScan scan4 =
PlanConstructor.newLogicalOlapScan(3, "t4", 0);
- private final LogicalOlapScan scan5 =
PlanConstructor.newLogicalOlapScan(4, "t5", 0);
-
- @Test
- void test() {
- LogicalPlan plan = new LogicalPlanBuilder(scan1)
- .hashJoinUsing(scan2, JoinType.INNER_JOIN, Pair.of(0, 1))
- .hashJoinUsing(scan3, JoinType.INNER_JOIN, Pair.of(0, 1))
- .hashJoinUsing(scan4, JoinType.INNER_JOIN, Pair.of(0, 1))
- .hashJoinUsing(scan5, JoinType.INNER_JOIN, Pair.of(0, 1))
- .build();
-
- PlanChecker.from(MemoTestUtils.createConnectContext(), plan)
- .deriveStats()
- .applyTopDown(new HyperGraphJoinReorderGroupRight())
- .printlnTree();
- }
-}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderTest.java
deleted file mode 100644
index d707722014..0000000000
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/joinreorder/HyperGraphJoinReorderTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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.joinreorder;
-
-import org.apache.doris.common.Pair;
-import org.apache.doris.nereids.trees.plans.JoinType;
-import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
-import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
-import org.apache.doris.nereids.util.LogicalPlanBuilder;
-import org.apache.doris.nereids.util.MemoTestUtils;
-import org.apache.doris.nereids.util.PlanChecker;
-import org.apache.doris.nereids.util.PlanConstructor;
-
-import org.junit.jupiter.api.Test;
-
-class HyperGraphJoinReorderTest {
- private final LogicalOlapScan scan1 =
PlanConstructor.newLogicalOlapScan(0, "t1", 0);
- private final LogicalOlapScan scan2 =
PlanConstructor.newLogicalOlapScan(1, "t2", 0);
- private final LogicalOlapScan scan3 =
PlanConstructor.newLogicalOlapScan(2, "t3", 0);
- private final LogicalOlapScan scan4 =
PlanConstructor.newLogicalOlapScan(3, "t4", 0);
- private final LogicalOlapScan scan5 =
PlanConstructor.newLogicalOlapScan(4, "t5", 0);
-
- @Test
- void test() {
- LogicalPlan plan = new LogicalPlanBuilder(scan1)
- .hashJoinUsing(scan2, JoinType.INNER_JOIN, Pair.of(0, 1))
- .hashJoinUsing(scan3, JoinType.INNER_JOIN, Pair.of(0, 1))
- .hashJoinUsing(
- new LogicalPlanBuilder(scan4)
- .hashJoinUsing(scan5, JoinType.INNER_JOIN,
Pair.of(0, 1))
- .build(),
- JoinType.INNER_JOIN, Pair.of(0, 1)
- )
- .build();
-
- PlanChecker.from(MemoTestUtils.createConnectContext(), plan)
- .deriveStats()
- .applyTopDown(new HyperGraphJoinReorder())
- .printlnTree();
- }
-}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/HyperGraphBuilder.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/HyperGraphBuilder.java
index 65750c9140..66db0bd490 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/HyperGraphBuilder.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/HyperGraphBuilder.java
@@ -19,17 +19,13 @@ package org.apache.doris.nereids.util;
import org.apache.doris.common.Pair;
import org.apache.doris.nereids.CascadesContext;
-import org.apache.doris.nereids.pattern.GroupExpressionMatching;
-import org.apache.doris.nereids.rules.Rule;
-import org.apache.doris.nereids.rules.joinreorder.HyperGraphJoinReorder;
-import
org.apache.doris.nereids.rules.joinreorder.HyperGraphJoinReorderGroupLeft;
-import
org.apache.doris.nereids.rules.joinreorder.HyperGraphJoinReorderGroupRight;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.HyperGraph;
-import org.apache.doris.nereids.rules.joinreorder.hypergraph.bitmap.Bitmap;
-import org.apache.doris.nereids.stats.StatsCalculator;
+import org.apache.doris.nereids.jobs.cascades.DeriveStatsJob;
+import org.apache.doris.nereids.jobs.joinorder.JoinOrderJob;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.HyperGraph;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.trees.expressions.EqualTo;
import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.plans.GroupPlan;
import org.apache.doris.nereids.trees.plans.JoinType;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
@@ -38,7 +34,6 @@ import
org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.statistics.StatsDeriveResult;
import com.google.common.base.Preconditions;
-import org.junit.jupiter.api.Assertions;
import java.util.ArrayList;
import java.util.BitSet;
@@ -54,9 +49,7 @@ public class HyperGraphBuilder {
public HyperGraph build() {
assert plans.size() == 1 : "there are cross join";
Plan plan = plans.values().iterator().next();
- Plan planWithStats = extractJoinCluster(plan);
- HyperGraph graph = HyperGraph.fromPlan(planWithStats);
- return graph;
+ return buildHyperGraph(plan);
}
public HyperGraph randomBuildWith(int tableNum, int edgeNum) {
@@ -168,49 +161,31 @@ public class HyperGraphBuilder {
return bitSet.equals(bitSet2);
}
- private Rule selectRuleForPlan(Plan plan) {
- Assertions.assertTrue(plan instanceof LogicalJoin);
- LogicalJoin join = (LogicalJoin) plan;
- if (!(join.left() instanceof LogicalJoin)) {
- return new HyperGraphJoinReorderGroupLeft().build();
- } else if (!(join.right() instanceof LogicalJoin)) {
- return new HyperGraphJoinReorderGroupRight().build();
- }
- return new HyperGraphJoinReorder().build();
- }
-
- private Plan extractJoinCluster(Plan plan) {
- Rule rule = selectRuleForPlan(plan);
+ private HyperGraph buildHyperGraph(Plan plan) {
CascadesContext cascadesContext =
MemoTestUtils.createCascadesContext(MemoTestUtils.createConnectContext(),
plan);
- GroupExpressionMatching groupExpressionMatching
- = new GroupExpressionMatching(rule.getPattern(),
- cascadesContext.getMemo().getRoot().getLogicalExpression());
- List<Plan> planList = new ArrayList<>();
- for (Plan matchingPlan : groupExpressionMatching) {
- planList.add(matchingPlan);
- }
- assert planList.size() == 1 : "Now we only support one join cluster";
- injectRowcount(planList.get(0));
- return planList.get(0);
+ JoinOrderJob joinOrderJob = new
JoinOrderJob(cascadesContext.getMemo().getRoot(),
+ cascadesContext.getCurrentJobContext());
+ cascadesContext.pushJob(
+ new
DeriveStatsJob(cascadesContext.getMemo().getRoot().getLogicalExpression(),
+ cascadesContext.getCurrentJobContext()));
+ cascadesContext.getJobScheduler().executeJobPool(cascadesContext);
+ injectRowcount(cascadesContext.getMemo().getRoot());
+ HyperGraph hyperGraph = new HyperGraph();
+ joinOrderJob.buildGraph(cascadesContext.getMemo().getRoot(),
hyperGraph);
+ return hyperGraph;
}
- private void injectRowcount(Plan plan) {
- if (plan instanceof GroupPlan) {
- GroupPlan olapGroupPlan = (GroupPlan) plan;
-
StatsCalculator.estimate(olapGroupPlan.getGroup().getLogicalExpression());
- LogicalOlapScan scanPlan = (LogicalOlapScan)
olapGroupPlan.getGroup().getLogicalExpression().getPlan();
- StatsDeriveResult stats = olapGroupPlan.getGroup().getStatistics();
- olapGroupPlan.getGroup()
- .setStatistics(stats
-
.updateRowCount(rowCounts.get(Integer.parseInt(scanPlan.getTable().getName()))));
+ private void injectRowcount(Group group) {
+ if (!group.isJoinGroup()) {
+ StatsDeriveResult stats = group.getStatistics();
+ LogicalOlapScan scanPlan = (LogicalOlapScan)
group.getLogicalExpression().getPlan();
+ int rowCount =
rowCounts.get(Integer.parseInt(scanPlan.getTable().getName()));
+ group.setStatistics(stats.updateRowCount(rowCount));
return;
}
- LogicalJoin join = (LogicalJoin) plan;
- injectRowcount(join.left());
- injectRowcount(join.right());
- // Because the children stats has been changed, so we need to
recalculate it
- StatsCalculator.estimate(join.getGroupExpression().get());
+ injectRowcount(group.getLogicalExpression().child(0));
+ injectRowcount(group.getLogicalExpression().child(1));
}
private void addCondition(int node1, int node2, BitSet key) {
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
index d6b92578f6..a86ce9ed6c 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
@@ -24,6 +24,7 @@ import org.apache.doris.nereids.glue.LogicalPlanAdapter;
import org.apache.doris.nereids.jobs.JobContext;
import org.apache.doris.nereids.jobs.batch.NereidsRewriteJobExecutor;
import org.apache.doris.nereids.jobs.cascades.DeriveStatsJob;
+import org.apache.doris.nereids.jobs.joinorder.JoinOrderJob;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.memo.GroupExpression;
import org.apache.doris.nereids.memo.Memo;
@@ -71,6 +72,19 @@ public class PlanChecker {
this.cascadesContext = cascadesContext;
}
+ public static PlanChecker from(ConnectContext connectContext) {
+ return new PlanChecker(connectContext);
+ }
+
+ public static PlanChecker from(ConnectContext connectContext, Plan
initPlan) {
+ CascadesContext cascadesContext =
MemoTestUtils.createCascadesContext(connectContext, initPlan);
+ return new PlanChecker(cascadesContext);
+ }
+
+ public static PlanChecker from(CascadesContext cascadesContext) {
+ return new PlanChecker(cascadesContext);
+ }
+
public PlanChecker checkParse(String sql, Consumer<PlanParseChecker>
consumer) {
PlanParseChecker checker = new PlanParseChecker(sql);
consumer.accept(checker);
@@ -248,7 +262,15 @@ public class PlanChecker {
public PlanChecker deriveStats() {
cascadesContext.pushJob(
- new
DeriveStatsJob(cascadesContext.getMemo().getRoot().getLogicalExpression(),
cascadesContext.getCurrentJobContext()));
+ new
DeriveStatsJob(cascadesContext.getMemo().getRoot().getLogicalExpression(),
+ cascadesContext.getCurrentJobContext()));
+ cascadesContext.getJobScheduler().executeJobPool(cascadesContext);
+ return this;
+ }
+
+ public PlanChecker orderJoin() {
+ cascadesContext.pushJob(
+ new JoinOrderJob(cascadesContext.getMemo().getRoot(),
cascadesContext.getCurrentJobContext()));
cascadesContext.getJobScheduler().executeJobPool(cascadesContext);
return this;
}
@@ -348,19 +370,6 @@ public class PlanChecker {
});
}
- public static PlanChecker from(ConnectContext connectContext) {
- return new PlanChecker(connectContext);
- }
-
- public static PlanChecker from(ConnectContext connectContext, Plan
initPlan) {
- CascadesContext cascadesContext =
MemoTestUtils.createCascadesContext(connectContext, initPlan);
- return new PlanChecker(cascadesContext);
- }
-
- public static PlanChecker from(CascadesContext cascadesContext) {
- return new PlanChecker(cascadesContext);
- }
-
public CascadesContext getCascadesContext() {
return cascadesContext;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]