[Feat](Nereids) add distribute hint to leading hint (#28562)
add distribute hint to leading hint, we can use leading like:
/*+ leading(t1 broadcase{t2 t3}) */ after this commit
This commit is contained in:
@ -29,6 +29,7 @@ import org.apache.doris.nereids.exceptions.AnalysisException;
|
||||
import org.apache.doris.nereids.glue.LogicalPlanAdapter;
|
||||
import org.apache.doris.nereids.glue.translator.PhysicalPlanTranslator;
|
||||
import org.apache.doris.nereids.glue.translator.PlanTranslatorContext;
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.hint.Hint;
|
||||
import org.apache.doris.nereids.jobs.executor.Optimizer;
|
||||
import org.apache.doris.nereids.jobs.executor.Rewriter;
|
||||
@ -357,17 +358,25 @@ public class NereidsPlanner extends Planner {
|
||||
String used = "";
|
||||
String unUsed = "";
|
||||
String syntaxError = "";
|
||||
int distributeHintIndex = 1;
|
||||
for (Hint hint : hints) {
|
||||
String distributeIndex = "";
|
||||
if (hint instanceof DistributeHint) {
|
||||
distributeHintIndex++;
|
||||
if (!hint.getExplainString().equals("")) {
|
||||
distributeIndex = "_" + String.valueOf(distributeHintIndex);
|
||||
}
|
||||
}
|
||||
switch (hint.getStatus()) {
|
||||
case UNUSED:
|
||||
unUsed = unUsed + " " + hint.getExplainString();
|
||||
unUsed = unUsed + " " + hint.getExplainString() + distributeIndex;
|
||||
break;
|
||||
case SYNTAX_ERROR:
|
||||
syntaxError = syntaxError + " " + hint.getExplainString()
|
||||
syntaxError = syntaxError + " " + hint.getExplainString() + distributeIndex
|
||||
+ " Msg:" + hint.getErrorMessage();
|
||||
break;
|
||||
case SUCCESS:
|
||||
used = used + " " + hint.getExplainString();
|
||||
used = used + " " + hint.getExplainString() + distributeIndex;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
// 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.hint;
|
||||
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
|
||||
/**
|
||||
* Hints for join.
|
||||
* <p>
|
||||
* Hints for the right child of join are supported currently.
|
||||
* Left input and right input of join could have different hints for further extension.
|
||||
*/
|
||||
public class DistributeHint extends Hint {
|
||||
public DistributeType distributeType;
|
||||
|
||||
private boolean isSuccessInLeading = false;
|
||||
|
||||
public DistributeHint(DistributeType distributeType) {
|
||||
super("Distribute");
|
||||
this.distributeType = distributeType;
|
||||
}
|
||||
|
||||
public void setSuccessInLeading(boolean successInLeading) {
|
||||
isSuccessInLeading = successInLeading;
|
||||
}
|
||||
|
||||
/**
|
||||
* get explain string of distribute hint, when distribute hint success in leading, it would not show
|
||||
* @return explain string of distribute hint
|
||||
*/
|
||||
public String getExplainString() {
|
||||
if (this.isSuccessInLeading) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder out = new StringBuilder();
|
||||
switch (this.distributeType) {
|
||||
case NONE:
|
||||
break;
|
||||
case SHUFFLE_RIGHT:
|
||||
out.append("[shuffle]");
|
||||
break;
|
||||
case BROADCAST_RIGHT:
|
||||
out.append("[broadcast]");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
return this.distributeType == ((DistributeHint) o).distributeType;
|
||||
}
|
||||
}
|
||||
@ -65,6 +65,10 @@ public class Hint {
|
||||
return getStatus() == HintStatus.SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
public boolean isUnUsed() {
|
||||
return getStatus() == HintStatus.UNUSED;
|
||||
}
|
||||
|
||||
public String getHintName() {
|
||||
return hintName;
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ import org.apache.doris.common.Pair;
|
||||
import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
|
||||
import org.apache.doris.nereids.trees.expressions.ExprId;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
@ -33,11 +33,13 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalRelation;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalSubQueryAlias;
|
||||
import org.apache.doris.nereids.util.JoinUtils;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -51,9 +53,13 @@ import java.util.Stack;
|
||||
*/
|
||||
public class LeadingHint extends Hint {
|
||||
private String originalString = "";
|
||||
|
||||
private List<String> parameters;
|
||||
private final List<String> tablelist = new ArrayList<>();
|
||||
private final List<Integer> levellist = new ArrayList<>();
|
||||
|
||||
private final Map<Integer, DistributeHint> distributeHints = new HashMap<>();
|
||||
|
||||
private final Map<RelationId, LogicalPlan> relationIdToScanMap = Maps.newLinkedHashMap();
|
||||
|
||||
private final List<Pair<RelationId, String>> relationIdAndTableName = new ArrayList<>();
|
||||
@ -82,6 +88,7 @@ public class LeadingHint extends Hint {
|
||||
public LeadingHint(String hintName, List<String> parameters, String originalString) {
|
||||
super(hintName);
|
||||
this.originalString = originalString;
|
||||
this.parameters = parameters;
|
||||
int level = 0;
|
||||
Stack<Boolean> brace = new Stack<>();
|
||||
String lastParameter = "";
|
||||
@ -100,6 +107,18 @@ public class LeadingHint extends Hint {
|
||||
} else {
|
||||
level--;
|
||||
}
|
||||
} else if (parameter.equals("shuffle")) {
|
||||
DistributeHint distributeHint = new DistributeHint(DistributeType.SHUFFLE_RIGHT);
|
||||
distributeHints.put(tablelist.size(), distributeHint);
|
||||
if (!ConnectContext.get().getStatementContext().getHints().contains(distributeHint)) {
|
||||
ConnectContext.get().getStatementContext().addHint(distributeHint);
|
||||
}
|
||||
} else if (parameter.equals("broadcast")) {
|
||||
DistributeHint distributeHint = new DistributeHint(DistributeType.BROADCAST_RIGHT);
|
||||
distributeHints.put(tablelist.size(), distributeHint);
|
||||
if (!ConnectContext.get().getStatementContext().getHints().contains(distributeHint)) {
|
||||
ConnectContext.get().getStatementContext().addHint(distributeHint);
|
||||
}
|
||||
} else {
|
||||
tablelist.add(parameter);
|
||||
levellist.add(level);
|
||||
@ -122,9 +141,25 @@ public class LeadingHint extends Hint {
|
||||
|
||||
@Override
|
||||
public String getExplainString() {
|
||||
if (!this.isSuccess()) {
|
||||
return originalString;
|
||||
}
|
||||
StringBuilder out = new StringBuilder();
|
||||
out.append(originalString);
|
||||
return out.toString();
|
||||
int tableIndex = 0;
|
||||
for (String parameter : parameters) {
|
||||
if (parameter.equals("{") || parameter.equals("}") || parameter.equals("[") || parameter.equals("]")) {
|
||||
out.append(parameter + " ");
|
||||
} else if (parameter.equals("shuffle") || parameter.equals("broadcast")) {
|
||||
DistributeHint distributeHint = distributeHints.get(tableIndex);
|
||||
if (distributeHint.isSuccess()) {
|
||||
out.append(parameter + " ");
|
||||
}
|
||||
} else {
|
||||
out.append(parameter + " ");
|
||||
tableIndex++;
|
||||
}
|
||||
}
|
||||
return "leading(" + out.toString() + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -420,7 +455,7 @@ public class LeadingHint extends Hint {
|
||||
* @return plan
|
||||
*/
|
||||
public Plan generateLeadingJoinPlan() {
|
||||
Stack<Pair<Integer, LogicalPlan>> stack = new Stack<>();
|
||||
Stack<Pair<Integer, Pair<LogicalPlan, Integer>>> stack = new Stack<>();
|
||||
int index = 0;
|
||||
LogicalPlan logicalPlan = getLogicalPlanByName(getTablelist().get(index));
|
||||
if (logicalPlan == null) {
|
||||
@ -428,27 +463,28 @@ public class LeadingHint extends Hint {
|
||||
}
|
||||
logicalPlan = makeFilterPlanIfExist(getFilters(), logicalPlan);
|
||||
assert (logicalPlan != null);
|
||||
stack.push(Pair.of(getLevellist().get(index), logicalPlan));
|
||||
stack.push(Pair.of(getLevellist().get(index), Pair.of(logicalPlan, index)));
|
||||
int stackTopLevel = getLevellist().get(index++);
|
||||
while (index < getTablelist().size()) {
|
||||
int currentLevel = getLevellist().get(index);
|
||||
if (currentLevel == stackTopLevel) {
|
||||
// should return error if can not found table
|
||||
logicalPlan = getLogicalPlanByName(getTablelist().get(index++));
|
||||
int distributeIndex = index - 1;
|
||||
if (logicalPlan == null) {
|
||||
return null;
|
||||
}
|
||||
logicalPlan = makeFilterPlanIfExist(getFilters(), logicalPlan);
|
||||
Pair<Integer, LogicalPlan> newStackTop = stack.peek();
|
||||
Pair<Integer, Pair<LogicalPlan, Integer>> newStackTop = stack.peek();
|
||||
while (!(stack.isEmpty() || stackTopLevel != newStackTop.first)) {
|
||||
// check join is legal and get join type
|
||||
newStackTop = stack.pop();
|
||||
List<Expression> conditions = getJoinConditions(
|
||||
getFilters(), newStackTop.second, logicalPlan);
|
||||
getFilters(), newStackTop.second.first, logicalPlan);
|
||||
Pair<List<Expression>, List<Expression>> pair = JoinUtils.extractExpressionForHashTable(
|
||||
newStackTop.second.getOutput(), logicalPlan.getOutput(), conditions);
|
||||
newStackTop.second.first.getOutput(), logicalPlan.getOutput(), conditions);
|
||||
// leading hint would set status inside if not success
|
||||
JoinType joinType = computeJoinType(getBitmap(newStackTop.second),
|
||||
JoinType joinType = computeJoinType(getBitmap(newStackTop.second.first),
|
||||
getBitmap(logicalPlan), conditions);
|
||||
if (joinType == null) {
|
||||
this.setStatus(HintStatus.SYNTAX_ERROR);
|
||||
@ -461,13 +497,15 @@ public class LeadingHint extends Hint {
|
||||
return null;
|
||||
}
|
||||
// get joinType
|
||||
DistributeHint distributeHint = getJoinHint(distributeIndex);
|
||||
LogicalJoin logicalJoin = new LogicalJoin<>(joinType, pair.first,
|
||||
pair.second,
|
||||
JoinHint.NONE,
|
||||
distributeHint,
|
||||
Optional.empty(),
|
||||
newStackTop.second,
|
||||
newStackTop.second.first,
|
||||
logicalPlan);
|
||||
logicalJoin.setBitmap(LongBitmap.or(getBitmap(newStackTop.second), getBitmap(logicalPlan)));
|
||||
distributeIndex = newStackTop.second.second;
|
||||
logicalJoin.setBitmap(LongBitmap.or(getBitmap(newStackTop.second.first), getBitmap(logicalPlan)));
|
||||
if (stackTopLevel > 0) {
|
||||
if (index < getTablelist().size()) {
|
||||
if (stackTopLevel > getLevellist().get(index)) {
|
||||
@ -482,7 +520,7 @@ public class LeadingHint extends Hint {
|
||||
}
|
||||
logicalPlan = logicalJoin;
|
||||
}
|
||||
stack.push(Pair.of(stackTopLevel, logicalPlan));
|
||||
stack.push(Pair.of(stackTopLevel, Pair.of(logicalPlan, distributeIndex)));
|
||||
} else {
|
||||
// push
|
||||
logicalPlan = getLogicalPlanByName(getTablelist().get(index++));
|
||||
@ -490,12 +528,12 @@ public class LeadingHint extends Hint {
|
||||
return null;
|
||||
}
|
||||
logicalPlan = makeFilterPlanIfExist(getFilters(), logicalPlan);
|
||||
stack.push(Pair.of(currentLevel, logicalPlan));
|
||||
stack.push(Pair.of(currentLevel, Pair.of(logicalPlan, index)));
|
||||
stackTopLevel = currentLevel;
|
||||
}
|
||||
}
|
||||
|
||||
LogicalJoin finalJoin = (LogicalJoin) stack.pop().second;
|
||||
LogicalJoin finalJoin = (LogicalJoin) stack.pop().second.first;
|
||||
// we want all filters been remove
|
||||
assert (filters.isEmpty());
|
||||
if (finalJoin != null) {
|
||||
@ -504,6 +542,14 @@ public class LeadingHint extends Hint {
|
||||
return finalJoin;
|
||||
}
|
||||
|
||||
private DistributeHint getJoinHint(Integer index) {
|
||||
if (distributeHints.get(index) == null) {
|
||||
return new DistributeHint(DistributeType.NONE);
|
||||
}
|
||||
distributeHints.get(index).setSuccessInLeading(true);
|
||||
return distributeHints.get(index);
|
||||
}
|
||||
|
||||
private List<Expression> getJoinConditions(List<Pair<Long, Expression>> filters,
|
||||
LogicalPlan left, LogicalPlan right) {
|
||||
List<Expression> joinConditions = new ArrayList<>();
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
package org.apache.doris.nereids.jobs.joinorder.hypergraph;
|
||||
|
||||
import org.apache.doris.common.Pair;
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
|
||||
import org.apache.doris.nereids.jobs.joinorder.hypergraph.edge.Edge;
|
||||
import org.apache.doris.nereids.jobs.joinorder.hypergraph.edge.FilterEdge;
|
||||
@ -32,8 +33,8 @@ import org.apache.doris.nereids.trees.expressions.Alias;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.GroupPlan;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
@ -230,7 +231,8 @@ public class HyperGraph {
|
||||
for (Map.Entry<Pair<Long, Long>, Pair<List<Expression>, List<Expression>>> entry : conjuncts
|
||||
.entrySet()) {
|
||||
LogicalJoin<?, ?> singleJoin = new LogicalJoin<>(join.getJoinType(), entry.getValue().first,
|
||||
entry.getValue().second, JoinHint.NONE, join.getMarkJoinSlotReference(),
|
||||
entry.getValue().second,
|
||||
new DistributeHint(DistributeType.NONE), join.getMarkJoinSlotReference(),
|
||||
Lists.newArrayList(join.left(), join.right()));
|
||||
Pair<Long, Long> ends = entry.getKey();
|
||||
JoinEdge edge = new JoinEdge(singleJoin, joinEdges.size(), leftEdgeNodes.first, rightEdgeNodes.first,
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver;
|
||||
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.jobs.JobContext;
|
||||
import org.apache.doris.nereids.jobs.cascades.CostAndEnforcerJob;
|
||||
import org.apache.doris.nereids.jobs.cascades.DeriveStatsJob;
|
||||
@ -34,8 +35,8 @@ import org.apache.doris.nereids.properties.PhysicalProperties;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.GroupPlan;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
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;
|
||||
@ -228,11 +229,13 @@ public class PlanReceiver implements AbstractReceiver {
|
||||
right, left));
|
||||
}
|
||||
} else {
|
||||
plans.add(new PhysicalHashJoin<>(joinType, hashConjuncts, otherConjuncts, JoinHint.NONE, Optional.empty(),
|
||||
plans.add(new PhysicalHashJoin<>(joinType, hashConjuncts, otherConjuncts,
|
||||
new DistributeHint(DistributeType.NONE), Optional.empty(),
|
||||
joinProperties,
|
||||
left, right));
|
||||
if (joinType.isSwapJoinType()) {
|
||||
plans.add(new PhysicalHashJoin<>(joinType.swap(), hashConjuncts, otherConjuncts, JoinHint.NONE,
|
||||
plans.add(new PhysicalHashJoin<>(joinType.swap(), hashConjuncts, otherConjuncts,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
Optional.empty(),
|
||||
joinProperties,
|
||||
right, left));
|
||||
@ -310,7 +313,8 @@ public class PlanReceiver implements AbstractReceiver {
|
||||
} else if (physicalPlan instanceof AbstractPhysicalJoin) {
|
||||
AbstractPhysicalJoin physicalJoin = (AbstractPhysicalJoin) physicalPlan;
|
||||
logicalPlan = new LogicalJoin<>(physicalJoin.getJoinType(), physicalJoin.getHashJoinConjuncts(),
|
||||
physicalJoin.getOtherJoinConjuncts(), JoinHint.NONE, physicalJoin.getMarkJoinSlotReference(),
|
||||
physicalJoin.getOtherJoinConjuncts(),
|
||||
new DistributeHint(DistributeType.NONE), physicalJoin.getMarkJoinSlotReference(),
|
||||
groupExpression.children().stream().map(g -> new GroupPlan(g)).collect(Collectors.toList()));
|
||||
} else {
|
||||
throw new RuntimeException("DPhyp can only handle join and project operator");
|
||||
|
||||
@ -51,7 +51,7 @@ import org.apache.doris.nereids.DorisParser.ArraySliceContext;
|
||||
import org.apache.doris.nereids.DorisParser.BitOperationContext;
|
||||
import org.apache.doris.nereids.DorisParser.BooleanExpressionContext;
|
||||
import org.apache.doris.nereids.DorisParser.BooleanLiteralContext;
|
||||
import org.apache.doris.nereids.DorisParser.BracketJoinHintContext;
|
||||
import org.apache.doris.nereids.DorisParser.BracketDistributeTypeContext;
|
||||
import org.apache.doris.nereids.DorisParser.BracketRelationHintContext;
|
||||
import org.apache.doris.nereids.DorisParser.BuildModeContext;
|
||||
import org.apache.doris.nereids.DorisParser.CallProcedureContext;
|
||||
@ -60,7 +60,7 @@ import org.apache.doris.nereids.DorisParser.CollateContext;
|
||||
import org.apache.doris.nereids.DorisParser.ColumnDefContext;
|
||||
import org.apache.doris.nereids.DorisParser.ColumnDefsContext;
|
||||
import org.apache.doris.nereids.DorisParser.ColumnReferenceContext;
|
||||
import org.apache.doris.nereids.DorisParser.CommentJoinHintContext;
|
||||
import org.apache.doris.nereids.DorisParser.CommentDistributeTypeContext;
|
||||
import org.apache.doris.nereids.DorisParser.CommentRelationHintContext;
|
||||
import org.apache.doris.nereids.DorisParser.ComparisonContext;
|
||||
import org.apache.doris.nereids.DorisParser.ComplexColTypeContext;
|
||||
@ -201,6 +201,7 @@ import org.apache.doris.nereids.analyzer.UnboundVariable.VariableType;
|
||||
import org.apache.doris.nereids.exceptions.AnalysisException;
|
||||
import org.apache.doris.nereids.exceptions.NotSupportedException;
|
||||
import org.apache.doris.nereids.exceptions.ParseException;
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.properties.OrderKey;
|
||||
import org.apache.doris.nereids.properties.SelectHint;
|
||||
import org.apache.doris.nereids.properties.SelectHintLeading;
|
||||
@ -317,7 +318,7 @@ import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.StructLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.LimitPhase;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
@ -2726,16 +2727,17 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
|
||||
} else {
|
||||
joinType = JoinType.CROSS_JOIN;
|
||||
}
|
||||
JoinHint joinHint = Optional.ofNullable(join.joinHint()).map(hintCtx -> {
|
||||
String hint = typedVisit(join.joinHint());
|
||||
if (JoinHint.JoinHintType.SHUFFLE.toString().equalsIgnoreCase(hint)) {
|
||||
return JoinHint.SHUFFLE_RIGHT;
|
||||
} else if (JoinHint.JoinHintType.BROADCAST.toString().equalsIgnoreCase(hint)) {
|
||||
return JoinHint.BROADCAST_RIGHT;
|
||||
DistributeType distributeType = Optional.ofNullable(join.distributeType()).map(hintCtx -> {
|
||||
String hint = typedVisit(join.distributeType());
|
||||
if (DistributeType.JoinDistributeType.SHUFFLE.toString().equalsIgnoreCase(hint)) {
|
||||
return DistributeType.SHUFFLE_RIGHT;
|
||||
} else if (DistributeType.JoinDistributeType.BROADCAST.toString().equalsIgnoreCase(hint)) {
|
||||
return DistributeType.BROADCAST_RIGHT;
|
||||
} else {
|
||||
throw new ParseException("Invalid join hint: " + hint, hintCtx);
|
||||
}
|
||||
}).orElse(JoinHint.NONE);
|
||||
}).orElse(DistributeType.NONE);
|
||||
DistributeHint distributeHint = new DistributeHint(distributeType);
|
||||
// TODO: natural join, lateral join, union join
|
||||
JoinCriteriaContext joinCriteria = join.joinCriteria();
|
||||
Optional<Expression> condition = Optional.empty();
|
||||
@ -2761,15 +2763,19 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
|
||||
last = new LogicalJoin<>(joinType, ExpressionUtils.EMPTY_CONDITION,
|
||||
condition.map(ExpressionUtils::extractConjunction)
|
||||
.orElse(ExpressionUtils.EMPTY_CONDITION),
|
||||
joinHint,
|
||||
distributeHint,
|
||||
Optional.empty(),
|
||||
last,
|
||||
plan(join.relationPrimary()));
|
||||
} else {
|
||||
last = new UsingJoin<>(joinType, last,
|
||||
plan(join.relationPrimary()), ImmutableList.of(), ids, joinHint);
|
||||
plan(join.relationPrimary()), ImmutableList.of(), ids, distributeHint);
|
||||
|
||||
}
|
||||
if (distributeHint.distributeType != DistributeType.NONE
|
||||
&& !ConnectContext.get().getStatementContext().getHints().contains(distributeHint)) {
|
||||
ConnectContext.get().getStatementContext().addHint(distributeHint);
|
||||
}
|
||||
}
|
||||
return last;
|
||||
}
|
||||
@ -2817,12 +2823,12 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitBracketJoinHint(BracketJoinHintContext ctx) {
|
||||
public String visitBracketDistributeType(BracketDistributeTypeContext ctx) {
|
||||
return ctx.identifier().getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitCommentJoinHint(CommentJoinHintContext ctx) {
|
||||
public String visitCommentDistributeType(CommentDistributeTypeContext ctx) {
|
||||
return ctx.identifier().getText();
|
||||
}
|
||||
|
||||
@ -2874,7 +2880,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
|
||||
JoinType.CROSS_JOIN,
|
||||
ExpressionUtils.EMPTY_CONDITION,
|
||||
ExpressionUtils.EMPTY_CONDITION,
|
||||
JoinHint.NONE,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
Optional.empty(),
|
||||
left,
|
||||
right);
|
||||
|
||||
@ -53,6 +53,10 @@ public abstract class DistributionSpec {
|
||||
return this.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
public String shapeInfo() {
|
||||
return this.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
|
||||
@ -19,6 +19,8 @@ package org.apache.doris.nereids.properties;
|
||||
|
||||
import org.apache.doris.common.Pair;
|
||||
import org.apache.doris.nereids.PlanContext;
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.hint.Hint;
|
||||
import org.apache.doris.nereids.jobs.JobContext;
|
||||
import org.apache.doris.nereids.memo.GroupExpression;
|
||||
import org.apache.doris.nereids.properties.DistributionSpecHash.ShuffleType;
|
||||
@ -26,7 +28,7 @@ import org.apache.doris.nereids.trees.expressions.Alias;
|
||||
import org.apache.doris.nereids.trees.expressions.ExprId;
|
||||
import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.expressions.SlotReference;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.algebra.SetOperation;
|
||||
import org.apache.doris.nereids.trees.plans.physical.AbstractPhysicalSort;
|
||||
@ -160,13 +162,15 @@ public class RequestPropertyDeriver extends PlanVisitor<Void, PlanContext> {
|
||||
|
||||
@Override
|
||||
public Void visitPhysicalHashJoin(PhysicalHashJoin<? extends Plan, ? extends Plan> hashJoin, PlanContext context) {
|
||||
JoinHint hint = hashJoin.getHint();
|
||||
if (hint == JoinHint.BROADCAST_RIGHT && JoinUtils.couldBroadcast(hashJoin)) {
|
||||
DistributeHint hint = hashJoin.getDistributeHint();
|
||||
if (hint.distributeType == DistributeType.BROADCAST_RIGHT && JoinUtils.couldBroadcast(hashJoin)) {
|
||||
addBroadcastJoinRequestProperty();
|
||||
hint.setStatus(Hint.HintStatus.SUCCESS);
|
||||
return null;
|
||||
}
|
||||
if (hint == JoinHint.SHUFFLE_RIGHT && JoinUtils.couldShuffle(hashJoin)) {
|
||||
if (hint.distributeType == DistributeType.SHUFFLE_RIGHT && JoinUtils.couldShuffle(hashJoin)) {
|
||||
addShuffleJoinRequestProperty(hashJoin);
|
||||
hint.setStatus(Hint.HintStatus.SUCCESS);
|
||||
return null;
|
||||
}
|
||||
// for shuffle join
|
||||
|
||||
@ -177,7 +177,7 @@ public class BindExpression implements AnalysisRuleFactory {
|
||||
LogicalJoin<Plan, Plan> lj = new LogicalJoin<>(using.getJoinType() == JoinType.CROSS_JOIN
|
||||
? JoinType.INNER_JOIN : using.getJoinType(),
|
||||
using.getHashJoinConjuncts(),
|
||||
using.getOtherJoinConjuncts(), using.getHint(), using.getMarkJoinSlotReference(),
|
||||
using.getOtherJoinConjuncts(), using.getDistributeHint(), using.getMarkJoinSlotReference(),
|
||||
using.children());
|
||||
List<Expression> unboundSlots = lj.getHashJoinConjuncts();
|
||||
Set<String> slotNames = new HashSet<>();
|
||||
@ -227,7 +227,7 @@ public class BindExpression implements AnalysisRuleFactory {
|
||||
.map(expr -> TypeCoercionUtils.castIfNotSameType(expr, BooleanType.INSTANCE))
|
||||
.collect(Collectors.toList());
|
||||
return new LogicalJoin<>(join.getJoinType(),
|
||||
hashJoinConjuncts, cond, join.getHint(), join.getMarkJoinSlotReference(),
|
||||
hashJoinConjuncts, cond, join.getDistributeHint(), join.getMarkJoinSlotReference(),
|
||||
join.children());
|
||||
})
|
||||
),
|
||||
|
||||
@ -121,7 +121,9 @@ public class EliminateLogicalSelectHint extends OneRewriteRuleFactory {
|
||||
context.setLeadingJoin(false);
|
||||
return;
|
||||
}
|
||||
hint.setStatus(Hint.HintStatus.SUCCESS);
|
||||
if (!hint.isSyntaxError()) {
|
||||
hint.setStatus(Hint.HintStatus.SUCCESS);
|
||||
}
|
||||
statementContext.addHint(hint);
|
||||
context.getHintMap().put("Leading", hint);
|
||||
if (hints.get("ordered") != null || ConnectContext.get().getSessionVariable().isDisableJoinReorder()) {
|
||||
|
||||
@ -55,7 +55,7 @@ public class InnerJoinLAsscom extends OneExplorationRuleFactory {
|
||||
public Rule build() {
|
||||
return innerLogicalJoin(innerLogicalJoin(), group())
|
||||
.when(topJoin -> checkReorder(topJoin, topJoin.left(), leftZigZag))
|
||||
.whenNot(join -> join.hasJoinHint() || join.left().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.left().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().isMarkJoin())
|
||||
.then(topJoin -> {
|
||||
LogicalJoin<GroupPlan, GroupPlan> bottomJoin = topJoin.left();
|
||||
|
||||
@ -61,7 +61,7 @@ public class InnerJoinLAsscomProject extends OneExplorationRuleFactory {
|
||||
public Rule build() {
|
||||
return innerLogicalJoin(logicalProject(innerLogicalJoin()), group())
|
||||
.when(topJoin -> InnerJoinLAsscom.checkReorder(topJoin, topJoin.left().child(), enableLeftZigZag))
|
||||
.whenNot(join -> join.hasJoinHint() || join.left().child().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.left().child().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().child().isMarkJoin())
|
||||
.when(join -> join.left().isAllSlots())
|
||||
.then(topJoin -> {
|
||||
|
||||
@ -50,7 +50,7 @@ public class InnerJoinLeftAssociate extends OneExplorationRuleFactory {
|
||||
public Rule build() {
|
||||
return innerLogicalJoin(group(), innerLogicalJoin())
|
||||
.when(InnerJoinLeftAssociate::checkReorder)
|
||||
.whenNot(join -> join.hasJoinHint() || join.right().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.right().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.right().isMarkJoin())
|
||||
.then(topJoin -> {
|
||||
LogicalJoin<GroupPlan, GroupPlan> bottomJoin = topJoin.right();
|
||||
|
||||
@ -51,7 +51,7 @@ public class InnerJoinLeftAssociateProject extends OneExplorationRuleFactory {
|
||||
public Rule build() {
|
||||
return innerLogicalJoin(group(), logicalProject(innerLogicalJoin()))
|
||||
.when(InnerJoinLeftAssociate::checkReorder)
|
||||
.whenNot(join -> join.hasJoinHint() || join.right().child().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.right().child().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.right().child().isMarkJoin())
|
||||
.when(join -> join.right().isAllSlots())
|
||||
.then(topJoin -> {
|
||||
|
||||
@ -48,7 +48,7 @@ public class InnerJoinRightAssociate extends OneExplorationRuleFactory {
|
||||
public Rule build() {
|
||||
return innerLogicalJoin(innerLogicalJoin(), group())
|
||||
.when(InnerJoinRightAssociate::checkReorder)
|
||||
.whenNot(join -> join.hasJoinHint() || join.left().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.left().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().isMarkJoin())
|
||||
.then(topJoin -> {
|
||||
LogicalJoin<GroupPlan, GroupPlan> bottomJoin = topJoin.left();
|
||||
|
||||
@ -49,7 +49,7 @@ public class InnerJoinRightAssociateProject extends OneExplorationRuleFactory {
|
||||
public Rule build() {
|
||||
return innerLogicalJoin(logicalProject(innerLogicalJoin()), group())
|
||||
.when(InnerJoinRightAssociate::checkReorder)
|
||||
.whenNot(join -> join.hasJoinHint() || join.left().child().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.left().child().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().child().isMarkJoin())
|
||||
.when(join -> join.left().isAllSlots())
|
||||
.then(topJoin -> {
|
||||
|
||||
@ -57,7 +57,7 @@ public class JoinCommute extends OneExplorationRuleFactory {
|
||||
.when(join -> !justNonInner || !join.getJoinType().isInnerJoin())
|
||||
.when(join -> checkReorder(join))
|
||||
.when(join -> check(swapType, join))
|
||||
.whenNot(LogicalJoin::hasJoinHint)
|
||||
.whenNot(LogicalJoin::hasDistributeHint)
|
||||
.whenNot(join -> joinOrderMatchBitmapRuntimeFilterOrder(join))
|
||||
.whenNot(LogicalJoin::isMarkJoin)
|
||||
.then(join -> {
|
||||
|
||||
@ -17,13 +17,14 @@
|
||||
|
||||
package org.apache.doris.nereids.rules.exploration.join;
|
||||
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.rules.exploration.OneExplorationRuleFactory;
|
||||
import org.apache.doris.nereids.trees.expressions.ExprId;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.GroupPlan;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
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;
|
||||
@ -52,7 +53,8 @@ public class JoinExchange extends OneExplorationRuleFactory {
|
||||
public Rule build() {
|
||||
return innerLogicalJoin(innerLogicalJoin(), innerLogicalJoin())
|
||||
.when(JoinExchange::checkReorder)
|
||||
.whenNot(join -> join.hasJoinHint() || join.left().hasJoinHint() || join.right().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint()
|
||||
|| join.left().hasDistributeHint() || join.right().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().isMarkJoin() || join.right().isMarkJoin())
|
||||
.then(topJoin -> {
|
||||
LogicalJoin<GroupPlan, GroupPlan> leftJoin = topJoin.left();
|
||||
@ -85,11 +87,14 @@ public class JoinExchange extends OneExplorationRuleFactory {
|
||||
}
|
||||
|
||||
LogicalJoin<GroupPlan, GroupPlan> newLeftJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts, JoinHint.NONE, a, c);
|
||||
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE), a, c);
|
||||
LogicalJoin<GroupPlan, GroupPlan> newRightJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts, JoinHint.NONE, b, d);
|
||||
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE), b, d);
|
||||
LogicalJoin newTopJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts, JoinHint.NONE,
|
||||
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
newLeftJoin, newRightJoin);
|
||||
newTopJoin.getJoinReorderContext().setHasExchange(true);
|
||||
|
||||
|
||||
@ -17,14 +17,15 @@
|
||||
|
||||
package org.apache.doris.nereids.rules.exploration.join;
|
||||
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.rules.exploration.CBOUtils;
|
||||
import org.apache.doris.nereids.rules.exploration.OneExplorationRuleFactory;
|
||||
import org.apache.doris.nereids.trees.expressions.ExprId;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.GroupPlan;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
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;
|
||||
@ -56,8 +57,8 @@ public class JoinExchangeBothProject extends OneExplorationRuleFactory {
|
||||
return innerLogicalJoin(logicalProject(innerLogicalJoin()), logicalProject(innerLogicalJoin()))
|
||||
.when(JoinExchange::checkReorder)
|
||||
.when(join -> join.left().isAllSlots() && join.right().isAllSlots())
|
||||
.whenNot(join -> join.hasJoinHint()
|
||||
|| join.left().child().hasJoinHint() || join.right().child().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint()
|
||||
|| join.left().child().hasDistributeHint() || join.right().child().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().child().isMarkJoin() || join.right().child().isMarkJoin())
|
||||
.then(topJoin -> {
|
||||
LogicalJoin<GroupPlan, GroupPlan> leftJoin = topJoin.left().child();
|
||||
@ -90,16 +91,19 @@ public class JoinExchangeBothProject extends OneExplorationRuleFactory {
|
||||
}
|
||||
|
||||
LogicalJoin<GroupPlan, GroupPlan> newLeftJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts, JoinHint.NONE, a, c);
|
||||
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE), a, c);
|
||||
LogicalJoin<GroupPlan, GroupPlan> newRightJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts, JoinHint.NONE, b, d);
|
||||
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE), b, d);
|
||||
Set<ExprId> topUsedExprIds = new HashSet<>(topJoin.getOutputExprIdSet());
|
||||
newTopJoinHashJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
|
||||
newTopJoinOtherJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
|
||||
Plan left = CBOUtils.newProject(topUsedExprIds, newLeftJoin);
|
||||
Plan right = CBOUtils.newProject(topUsedExprIds, newRightJoin);
|
||||
LogicalJoin newTopJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts, JoinHint.NONE,
|
||||
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
left, right);
|
||||
newTopJoin.getJoinReorderContext().setHasExchange(true);
|
||||
|
||||
|
||||
@ -17,14 +17,15 @@
|
||||
|
||||
package org.apache.doris.nereids.rules.exploration.join;
|
||||
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.rules.exploration.CBOUtils;
|
||||
import org.apache.doris.nereids.rules.exploration.OneExplorationRuleFactory;
|
||||
import org.apache.doris.nereids.trees.expressions.ExprId;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.GroupPlan;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
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;
|
||||
@ -56,8 +57,8 @@ public class JoinExchangeLeftProject extends OneExplorationRuleFactory {
|
||||
return innerLogicalJoin(logicalProject(innerLogicalJoin()), innerLogicalJoin())
|
||||
.when(JoinExchange::checkReorder)
|
||||
.when(join -> join.left().isAllSlots())
|
||||
.whenNot(join -> join.hasJoinHint()
|
||||
|| join.left().child().hasJoinHint() || join.right().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint()
|
||||
|| join.left().child().hasDistributeHint() || join.right().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().child().isMarkJoin() || join.right().isMarkJoin())
|
||||
.then(topJoin -> {
|
||||
LogicalJoin<GroupPlan, GroupPlan> leftJoin = topJoin.left().child();
|
||||
@ -90,16 +91,19 @@ public class JoinExchangeLeftProject extends OneExplorationRuleFactory {
|
||||
}
|
||||
|
||||
LogicalJoin<GroupPlan, GroupPlan> newLeftJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts, JoinHint.NONE, a, c);
|
||||
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE), a, c);
|
||||
LogicalJoin<GroupPlan, GroupPlan> newRightJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts, JoinHint.NONE, b, d);
|
||||
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE), b, d);
|
||||
Set<ExprId> topUsedExprIds = new HashSet<>(topJoin.getOutputExprIdSet());
|
||||
newTopJoinHashJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
|
||||
newTopJoinOtherJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
|
||||
Plan left = CBOUtils.newProject(topUsedExprIds, newLeftJoin);
|
||||
Plan right = CBOUtils.newProject(topUsedExprIds, newRightJoin);
|
||||
LogicalJoin newTopJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts, JoinHint.NONE,
|
||||
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
left, right);
|
||||
newTopJoin.getJoinReorderContext().setHasExchange(true);
|
||||
|
||||
|
||||
@ -17,14 +17,15 @@
|
||||
|
||||
package org.apache.doris.nereids.rules.exploration.join;
|
||||
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.rules.exploration.CBOUtils;
|
||||
import org.apache.doris.nereids.rules.exploration.OneExplorationRuleFactory;
|
||||
import org.apache.doris.nereids.trees.expressions.ExprId;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.GroupPlan;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
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;
|
||||
@ -56,8 +57,8 @@ public class JoinExchangeRightProject extends OneExplorationRuleFactory {
|
||||
return innerLogicalJoin(innerLogicalJoin(), logicalProject(innerLogicalJoin()))
|
||||
.when(JoinExchange::checkReorder)
|
||||
.when(join -> join.right().isAllSlots())
|
||||
.whenNot(join -> join.hasJoinHint()
|
||||
|| join.left().hasJoinHint() || join.right().child().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint()
|
||||
|| join.left().hasDistributeHint() || join.right().child().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().isMarkJoin() || join.right().child().isMarkJoin())
|
||||
.then(topJoin -> {
|
||||
LogicalJoin<GroupPlan, GroupPlan> leftJoin = topJoin.left();
|
||||
@ -90,16 +91,19 @@ public class JoinExchangeRightProject extends OneExplorationRuleFactory {
|
||||
}
|
||||
|
||||
LogicalJoin<GroupPlan, GroupPlan> newLeftJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts, JoinHint.NONE, a, c);
|
||||
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE), a, c);
|
||||
LogicalJoin<GroupPlan, GroupPlan> newRightJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts, JoinHint.NONE, b, d);
|
||||
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE), b, d);
|
||||
Set<ExprId> topUsedExprIds = new HashSet<>(topJoin.getOutputExprIdSet());
|
||||
newTopJoinHashJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
|
||||
newTopJoinOtherJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
|
||||
Plan left = CBOUtils.newProject(topUsedExprIds, newLeftJoin);
|
||||
Plan right = CBOUtils.newProject(topUsedExprIds, newRightJoin);
|
||||
LogicalJoin newTopJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts, JoinHint.NONE,
|
||||
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
left, right);
|
||||
newTopJoin.getJoinReorderContext().setHasExchange(true);
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ public class LogicalJoinSemiJoinTranspose implements ExplorationRuleFactory {
|
||||
.when(topJoin -> (topJoin.left().getJoinType().isLeftSemiOrAntiJoin()
|
||||
&& (topJoin.getJoinType().isInnerJoin()
|
||||
|| topJoin.getJoinType().isLeftOuterJoin())))
|
||||
.whenNot(topJoin -> topJoin.hasJoinHint() || topJoin.left().hasJoinHint()
|
||||
.whenNot(topJoin -> topJoin.hasDistributeHint() || topJoin.left().hasDistributeHint()
|
||||
|| topJoin.left().isMarkJoin())
|
||||
.whenNot(LogicalJoin::isMarkJoin)
|
||||
.then(topJoin -> {
|
||||
@ -60,7 +60,7 @@ public class LogicalJoinSemiJoinTranspose implements ExplorationRuleFactory {
|
||||
.when(topJoin -> (topJoin.right().getJoinType().isLeftSemiOrAntiJoin()
|
||||
&& (topJoin.getJoinType().isInnerJoin()
|
||||
|| topJoin.getJoinType().isRightOuterJoin())))
|
||||
.whenNot(topJoin -> topJoin.hasJoinHint() || topJoin.right().hasJoinHint()
|
||||
.whenNot(topJoin -> topJoin.hasDistributeHint() || topJoin.right().hasDistributeHint()
|
||||
|| topJoin.right().isMarkJoin())
|
||||
.whenNot(LogicalJoin::isMarkJoin)
|
||||
.then(topJoin -> {
|
||||
|
||||
@ -43,8 +43,8 @@ public class LogicalJoinSemiJoinTransposeProject implements ExplorationRuleFacto
|
||||
.when(topJoin -> (topJoin.left().child().getJoinType().isLeftSemiOrAntiJoin()
|
||||
&& (topJoin.getJoinType().isInnerJoin()
|
||||
|| topJoin.getJoinType().isLeftOuterJoin())))
|
||||
.whenNot(topJoin -> topJoin.hasJoinHint()
|
||||
|| topJoin.left().child().hasJoinHint()
|
||||
.whenNot(topJoin -> topJoin.hasDistributeHint()
|
||||
|| topJoin.left().child().hasDistributeHint()
|
||||
|| topJoin.left().child().isMarkJoin())
|
||||
.whenNot(LogicalJoin::isMarkJoin)
|
||||
.when(join -> join.left().isAllSlots())
|
||||
@ -65,8 +65,8 @@ public class LogicalJoinSemiJoinTransposeProject implements ExplorationRuleFacto
|
||||
.when(topJoin -> (topJoin.right().child().getJoinType().isLeftSemiOrAntiJoin()
|
||||
&& (topJoin.getJoinType().isInnerJoin()
|
||||
|| topJoin.getJoinType().isRightOuterJoin())))
|
||||
.whenNot(topJoin -> topJoin.hasJoinHint()
|
||||
|| topJoin.right().child().hasJoinHint()
|
||||
.whenNot(topJoin -> topJoin.hasDistributeHint()
|
||||
|| topJoin.right().child().hasDistributeHint()
|
||||
|| topJoin.right().child().isMarkJoin())
|
||||
.when(join -> join.right().isAllSlots())
|
||||
.then(topJoin -> {
|
||||
|
||||
@ -56,7 +56,7 @@ public class OuterJoinAssocProject extends OneExplorationRuleFactory {
|
||||
.when(join -> OuterJoinAssoc.VALID_TYPE_PAIR_SET.contains(
|
||||
Pair.of(join.left().child().getJoinType(), join.getJoinType())))
|
||||
.when(topJoin -> OuterJoinLAsscom.checkReorder(topJoin, topJoin.left().child()))
|
||||
.whenNot(join -> join.hasJoinHint() || join.left().child().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.left().child().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().child().isMarkJoin())
|
||||
.when(join -> OuterJoinAssoc.checkCondition(join, join.left().child().left().getOutputSet()))
|
||||
.when(join -> join.left().isAllSlots())
|
||||
|
||||
@ -62,7 +62,7 @@ public class OuterJoinLAsscom extends OneExplorationRuleFactory {
|
||||
return logicalJoin(logicalJoin(), group())
|
||||
.when(join -> VALID_TYPE_PAIR_SET.contains(Pair.of(join.left().getJoinType(), join.getJoinType())))
|
||||
.when(topJoin -> checkReorder(topJoin, topJoin.left()))
|
||||
.whenNot(join -> join.hasJoinHint() || join.left().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.left().hasDistributeHint())
|
||||
.when(topJoin -> checkCondition(topJoin, topJoin.left().right().getOutputExprIdSet()))
|
||||
.whenNot(LogicalJoin::isMarkJoin)
|
||||
.then(topJoin -> {
|
||||
|
||||
@ -53,7 +53,7 @@ public class OuterJoinLAsscomProject extends OneExplorationRuleFactory {
|
||||
.when(join -> OuterJoinLAsscom.VALID_TYPE_PAIR_SET.contains(
|
||||
Pair.of(join.left().child().getJoinType(), join.getJoinType())))
|
||||
.when(topJoin -> OuterJoinLAsscom.checkReorder(topJoin, topJoin.left().child()))
|
||||
.whenNot(join -> join.hasJoinHint() || join.left().child().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.left().child().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().child().isMarkJoin())
|
||||
.when(topJoin -> OuterJoinLAsscom.checkCondition(topJoin,
|
||||
topJoin.left().child().right().getOutputExprIdSet()))
|
||||
|
||||
@ -61,7 +61,7 @@ public class PushDownProjectThroughInnerOuterJoin implements ExplorationRuleFact
|
||||
|| j.left().child().getJoinType().isInnerJoin())
|
||||
// Just pushdown project with non-column expr like (t.id + 1)
|
||||
.whenNot(j -> j.left().isAllSlots())
|
||||
.whenNot(j -> j.left().child().hasJoinHint())
|
||||
.whenNot(j -> j.left().child().hasDistributeHint())
|
||||
.then(topJoin -> {
|
||||
LogicalProject<LogicalJoin<GroupPlan, GroupPlan>> project = topJoin.left();
|
||||
Plan newLeft = pushdownProject(project);
|
||||
@ -75,7 +75,7 @@ public class PushDownProjectThroughInnerOuterJoin implements ExplorationRuleFact
|
||||
|| j.right().child().getJoinType().isInnerJoin())
|
||||
// Just pushdown project with non-column expr like (t.id + 1)
|
||||
.whenNot(j -> j.right().isAllSlots())
|
||||
.whenNot(j -> j.right().child().hasJoinHint())
|
||||
.whenNot(j -> j.right().child().hasDistributeHint())
|
||||
.then(topJoin -> {
|
||||
LogicalProject<LogicalJoin<GroupPlan, GroupPlan>> project = topJoin.right();
|
||||
Plan newRight = pushdownProject(project);
|
||||
|
||||
@ -58,7 +58,7 @@ public class PushDownProjectThroughSemiJoin implements ExplorationRuleFactory {
|
||||
.when(j -> j.left().child().getJoinType().isLeftSemiOrAntiJoin())
|
||||
// Just pushdown project with non-column expr like (t.id + 1)
|
||||
.whenNot(j -> j.left().isAllSlots())
|
||||
.whenNot(j -> j.left().child().hasJoinHint())
|
||||
.whenNot(j -> j.left().child().hasDistributeHint())
|
||||
.then(topJoin -> {
|
||||
LogicalProject<LogicalJoin<GroupPlan, GroupPlan>> project = topJoin.left();
|
||||
Plan newLeft = pushdownProject(project);
|
||||
@ -69,7 +69,7 @@ public class PushDownProjectThroughSemiJoin implements ExplorationRuleFactory {
|
||||
.when(j -> j.right().child().getJoinType().isLeftSemiOrAntiJoin())
|
||||
// Just pushdown project with non-column expr like (t.id + 1)
|
||||
.whenNot(j -> j.right().isAllSlots())
|
||||
.whenNot(j -> j.right().child().hasJoinHint())
|
||||
.whenNot(j -> j.right().child().hasDistributeHint())
|
||||
.then(topJoin -> {
|
||||
LogicalProject<LogicalJoin<GroupPlan, GroupPlan>> project = topJoin.right();
|
||||
Plan newRight = pushdownProject(project);
|
||||
|
||||
@ -62,7 +62,7 @@ public class SemiJoinSemiJoinTranspose extends OneExplorationRuleFactory {
|
||||
public Rule build() {
|
||||
return logicalJoin(logicalJoin(), group())
|
||||
.when(this::typeChecker)
|
||||
.whenNot(join -> join.hasJoinHint() || join.left().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.left().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().isMarkJoin())
|
||||
.then(topJoin -> {
|
||||
LogicalJoin<GroupPlan, GroupPlan> bottomJoin = topJoin.left();
|
||||
|
||||
@ -54,7 +54,7 @@ public class SemiJoinSemiJoinTransposeProject extends OneExplorationRuleFactory
|
||||
return logicalJoin(logicalProject(logicalJoin()), group())
|
||||
.when(this::typeChecker)
|
||||
.when(topSemi -> InnerJoinLAsscom.checkReorder(topSemi, topSemi.left().child(), false))
|
||||
.whenNot(join -> join.hasJoinHint() || join.left().child().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.left().child().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().child().isMarkJoin())
|
||||
.when(join -> join.left().isAllSlots())
|
||||
.then(topSemi -> {
|
||||
|
||||
@ -203,7 +203,7 @@ public class ExpressionRewrite implements RewriteRuleFactory {
|
||||
return join;
|
||||
}
|
||||
return new LogicalJoin<>(join.getJoinType(), rewriteHashJoinConjuncts,
|
||||
rewriteOtherJoinConjuncts, join.getHint(), join.getMarkJoinSlotReference(),
|
||||
rewriteOtherJoinConjuncts, join.getDistributeHint(), join.getMarkJoinSlotReference(),
|
||||
join.children());
|
||||
}).toRule(RuleType.REWRITE_JOIN_EXPRESSION);
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ public class LogicalJoinToHashJoin extends OneImplementationRuleFactory {
|
||||
join.getJoinType(),
|
||||
join.getHashJoinConjuncts(),
|
||||
join.getOtherJoinConjuncts(),
|
||||
join.getHint(),
|
||||
join.getDistributeHint(),
|
||||
join.getMarkJoinSlotReference(),
|
||||
join.getLogicalProperties(),
|
||||
join.left(),
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.doris.nereids.rules.rewrite;
|
||||
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.trees.expressions.Alias;
|
||||
@ -25,7 +26,7 @@ import org.apache.doris.nereids.trees.expressions.Exists;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.LimitPhase;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
@ -96,7 +97,7 @@ public class ExistsApplyToJoin extends OneRewriteRuleFactory {
|
||||
predicate != null
|
||||
? ExpressionUtils.extractConjunction(predicate)
|
||||
: ExpressionUtils.EMPTY_CONDITION,
|
||||
JoinHint.NONE,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
apply.getMarkJoinSlotReference(),
|
||||
apply.children());
|
||||
} else {
|
||||
@ -104,7 +105,7 @@ public class ExistsApplyToJoin extends OneRewriteRuleFactory {
|
||||
predicate != null
|
||||
? ExpressionUtils.extractConjunction(predicate)
|
||||
: ExpressionUtils.EMPTY_CONDITION,
|
||||
JoinHint.NONE,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
apply.getMarkJoinSlotReference(),
|
||||
apply.children());
|
||||
}
|
||||
@ -124,7 +125,8 @@ public class ExistsApplyToJoin extends OneRewriteRuleFactory {
|
||||
LogicalAggregate newAgg = new LogicalAggregate<>(new ArrayList<>(),
|
||||
ImmutableList.of(alias), newLimit);
|
||||
LogicalJoin newJoin = new LogicalJoin<>(JoinType.CROSS_JOIN, ExpressionUtils.EMPTY_CONDITION,
|
||||
ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, unapply.getMarkJoinSlotReference(),
|
||||
ExpressionUtils.EMPTY_CONDITION,
|
||||
new DistributeHint(DistributeType.NONE), unapply.getMarkJoinSlotReference(),
|
||||
(LogicalPlan) unapply.left(), newAgg);
|
||||
return new LogicalFilter<>(ImmutableSet.of(new EqualTo(newAgg.getOutput().get(0),
|
||||
new IntegerLiteral(0))), newJoin);
|
||||
@ -134,6 +136,7 @@ public class ExistsApplyToJoin extends OneRewriteRuleFactory {
|
||||
LogicalLimit newLimit = new LogicalLimit<>(1, 0, LimitPhase.ORIGIN, (LogicalPlan) unapply.right());
|
||||
return new LogicalJoin<>(JoinType.CROSS_JOIN, ExpressionUtils.EMPTY_CONDITION,
|
||||
ExpressionUtils.EMPTY_CONDITION,
|
||||
JoinHint.NONE, unapply.getMarkJoinSlotReference(), (LogicalPlan) unapply.left(), newLimit);
|
||||
new DistributeHint(DistributeType.NONE), unapply.getMarkJoinSlotReference(),
|
||||
(LogicalPlan) unapply.left(), newLimit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ public class ExtractFilterFromCrossJoin extends OneRewriteRuleFactory {
|
||||
return crossLogicalJoin()
|
||||
.then(join -> {
|
||||
LogicalJoin<Plan, Plan> newJoin = new LogicalJoin<>(JoinType.CROSS_JOIN,
|
||||
ExpressionUtils.EMPTY_CONDITION, ExpressionUtils.EMPTY_CONDITION, join.getHint(),
|
||||
ExpressionUtils.EMPTY_CONDITION, ExpressionUtils.EMPTY_CONDITION, join.getDistributeHint(),
|
||||
join.getMarkJoinSlotReference(), join.children());
|
||||
Set<Expression> predicates = Stream.concat(join.getHashJoinConjuncts().stream(),
|
||||
join.getOtherJoinConjuncts().stream())
|
||||
|
||||
@ -72,7 +72,7 @@ public class FindHashConditionForJoin extends OneRewriteRuleFactory {
|
||||
return new LogicalJoin<>(joinType,
|
||||
combinedHashJoinConjuncts,
|
||||
remainedNonHashJoinConjuncts,
|
||||
join.getHint(),
|
||||
join.getDistributeHint(),
|
||||
join.getMarkJoinSlotReference(),
|
||||
join.children());
|
||||
}).toRule(RuleType.FIND_HASH_CONDITION_FOR_JOIN);
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
package org.apache.doris.nereids.rules.rewrite;
|
||||
|
||||
import org.apache.doris.nereids.exceptions.AnalysisException;
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.trees.expressions.Alias;
|
||||
@ -29,7 +30,7 @@ import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.expressions.Not;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.agg.BitmapUnion;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapContains;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
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;
|
||||
@ -88,7 +89,7 @@ public class InApplyToJoin extends OneRewriteRuleFactory {
|
||||
}
|
||||
return new LogicalJoin<>(JoinType.LEFT_SEMI_JOIN, Lists.newArrayList(),
|
||||
Lists.newArrayList(expr),
|
||||
JoinHint.NONE,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
apply.left(), agg);
|
||||
}
|
||||
|
||||
@ -118,12 +119,12 @@ public class InApplyToJoin extends OneRewriteRuleFactory {
|
||||
predicate.nullable() && !apply.isCorrelated()
|
||||
? JoinType.NULL_AWARE_LEFT_ANTI_JOIN
|
||||
: JoinType.LEFT_ANTI_JOIN,
|
||||
Lists.newArrayList(), conjuncts, JoinHint.NONE,
|
||||
Lists.newArrayList(), conjuncts, new DistributeHint(DistributeType.NONE),
|
||||
apply.getMarkJoinSlotReference(), apply.children());
|
||||
} else {
|
||||
return new LogicalJoin<>(JoinType.LEFT_SEMI_JOIN, Lists.newArrayList(),
|
||||
conjuncts,
|
||||
JoinHint.NONE, apply.getMarkJoinSlotReference(),
|
||||
new DistributeHint(DistributeType.NONE), apply.getMarkJoinSlotReference(),
|
||||
apply.children());
|
||||
}
|
||||
}).toRule(RuleType.IN_APPLY_TO_JOIN);
|
||||
|
||||
@ -176,7 +176,7 @@ public class OrExpansion extends OneExplorationRuleFactory {
|
||||
Expression hashCond = disjunctions.get(0);
|
||||
hashCond = hashCond.rewriteUp(s -> replaced.containsKey(s) ? replaced.get(s) : s);
|
||||
Plan newPlan = new LogicalJoin<>(JoinType.LEFT_ANTI_JOIN, Lists.newArrayList(hashCond),
|
||||
otherConditions, originJoin.getHint(),
|
||||
otherConditions, originJoin.getDistributeHint(),
|
||||
originJoin.getMarkJoinSlotReference(), left, right);
|
||||
if (hashCond.children().stream().anyMatch(e -> !(e instanceof Slot))) {
|
||||
Plan normalizedPlan = PushDownExpressionsInHashCondition.pushDownHashExpression(
|
||||
@ -193,7 +193,7 @@ public class OrExpansion extends OneExplorationRuleFactory {
|
||||
newReplaced.putAll(newRight.getProducerToConsumerOutputMap());
|
||||
hashCond = hashCond.rewriteUp(s -> newReplaced.containsKey(s) ? newReplaced.get(s) : s);
|
||||
newPlan = new LogicalJoin<>(JoinType.LEFT_ANTI_JOIN, Lists.newArrayList(hashCond),
|
||||
new ArrayList<>(), originJoin.getHint(),
|
||||
new ArrayList<>(), originJoin.getDistributeHint(),
|
||||
originJoin.getMarkJoinSlotReference(), newPlan, newRight);
|
||||
if (hashCond.children().stream().anyMatch(e -> !(e instanceof Slot))) {
|
||||
newPlan = PushDownExpressionsInHashCondition.pushDownHashExpression(
|
||||
@ -253,7 +253,7 @@ public class OrExpansion extends OneExplorationRuleFactory {
|
||||
.collect(Collectors.toList());
|
||||
|
||||
LogicalJoin<? extends Plan, ? extends Plan> newJoin = new LogicalJoin<>(
|
||||
JoinType.INNER_JOIN, hashCond, otherCond, join.getHint(),
|
||||
JoinType.INNER_JOIN, hashCond, otherCond, join.getDistributeHint(),
|
||||
join.getMarkJoinSlotReference(), left, right);
|
||||
if (newJoin.getHashJoinConjuncts().stream()
|
||||
.anyMatch(equalTo -> equalTo.children().stream().anyMatch(e -> !(e instanceof Slot)))) {
|
||||
|
||||
@ -20,6 +20,7 @@ package org.apache.doris.nereids.rules.rewrite;
|
||||
import org.apache.doris.catalog.constraint.ForeignKeyConstraint;
|
||||
import org.apache.doris.catalog.constraint.PrimaryKeyConstraint;
|
||||
import org.apache.doris.catalog.constraint.UniqueConstraint;
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.jobs.JobContext;
|
||||
import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
@ -31,7 +32,7 @@ import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.expressions.SlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.Literal;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.algebra.SetOperation.Qualifier;
|
||||
@ -521,7 +522,7 @@ public class PullUpJoinFromUnionAll extends OneRewriteRuleFactory {
|
||||
JoinType.INNER_JOIN,
|
||||
newHashJoinConjuncts,
|
||||
ExpressionUtils.EMPTY_CONDITION,
|
||||
JoinHint.NONE,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
Optional.empty(),
|
||||
newUnionNode,
|
||||
pullUpTable);
|
||||
@ -634,7 +635,7 @@ public class PullUpJoinFromUnionAll extends OneRewriteRuleFactory {
|
||||
return new LogicalJoin(JoinType.INNER_JOIN,
|
||||
join.getHashJoinConjuncts(),
|
||||
join.getOtherJoinConjuncts(),
|
||||
JoinHint.NONE,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
Optional.empty(),
|
||||
leftChild, rightChild);
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ public class PushDownFilterThroughJoin extends OneRewriteRuleFactory {
|
||||
new LogicalJoin<>(join.getJoinType(),
|
||||
join.getHashJoinConjuncts(),
|
||||
joinConditions,
|
||||
join.getHint(),
|
||||
join.getDistributeHint(),
|
||||
join.getMarkJoinSlotReference(),
|
||||
PlanUtils.filterOrSelf(leftPredicates, join.left()),
|
||||
PlanUtils.filterOrSelf(rightPredicates, join.right())));
|
||||
|
||||
@ -89,7 +89,7 @@ public class PushDownJoinOtherCondition extends OneRewriteRuleFactory {
|
||||
Plan right = PlanUtils.filterOrSelf(rightConjuncts, join.right());
|
||||
|
||||
return new LogicalJoin<>(join.getJoinType(), join.getHashJoinConjuncts(),
|
||||
remainingOther, join.getHint(), join.getMarkJoinSlotReference(), left, right);
|
||||
remainingOther, join.getDistributeHint(), join.getMarkJoinSlotReference(), left, right);
|
||||
|
||||
}).toRule(RuleType.PUSH_DOWN_JOIN_OTHER_CONDITION);
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ public class PushFilterInsideJoin extends OneRewriteRuleFactory {
|
||||
LogicalJoin<Plan, Plan> join = filter.child();
|
||||
otherConditions.addAll(join.getOtherJoinConjuncts());
|
||||
return new LogicalJoin<>(join.getJoinType(), join.getHashJoinConjuncts(),
|
||||
otherConditions, join.getHint(), join.getMarkJoinSlotReference(),
|
||||
otherConditions, join.getDistributeHint(), join.getMarkJoinSlotReference(),
|
||||
join.children());
|
||||
}).toRule(RuleType.PUSH_FILTER_INSIDE_JOIN);
|
||||
}
|
||||
|
||||
@ -19,12 +19,13 @@ package org.apache.doris.nereids.rules.rewrite;
|
||||
|
||||
import org.apache.doris.common.Pair;
|
||||
import org.apache.doris.nereids.annotation.DependsRules;
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.trees.expressions.ExprId;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint.JoinHintType;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType.JoinDistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
@ -83,7 +84,7 @@ public class ReorderJoin extends OneRewriteRuleFactory {
|
||||
}
|
||||
LogicalFilter<Plan> filter = ctx.root;
|
||||
|
||||
Map<Plan, JoinHintType> planToHintType = Maps.newHashMap();
|
||||
Map<Plan, JoinDistributeType> planToHintType = Maps.newHashMap();
|
||||
Plan plan = joinToMultiJoin(filter, planToHintType);
|
||||
Preconditions.checkState(plan instanceof MultiJoin);
|
||||
MultiJoin multiJoin = (MultiJoin) plan;
|
||||
@ -99,7 +100,7 @@ public class ReorderJoin extends OneRewriteRuleFactory {
|
||||
* {@link LogicalJoin} or {@link LogicalFilter}--{@link LogicalJoin}
|
||||
* --> {@link MultiJoin}
|
||||
*/
|
||||
public Plan joinToMultiJoin(Plan plan, Map<Plan, JoinHintType> planToHintType) {
|
||||
public Plan joinToMultiJoin(Plan plan, Map<Plan, JoinDistributeType> planToHintType) {
|
||||
// subtree can't specify the end of Pattern. so end can be GroupPlan or Filter
|
||||
if (nonJoinAndNonFilter(plan)
|
||||
|| (plan instanceof LogicalFilter && nonJoinAndNonFilter(plan.child(0)))) {
|
||||
@ -215,7 +216,7 @@ public class ReorderJoin extends OneRewriteRuleFactory {
|
||||
* A B C D F ──► A B C │ D F ──► MJ(FOJ MJ(A,B,C) MJ(D,F))
|
||||
* </pre>
|
||||
*/
|
||||
public Plan multiJoinToJoin(MultiJoin multiJoin, Map<Plan, JoinHintType> planToHintType) {
|
||||
public Plan multiJoinToJoin(MultiJoin multiJoin, Map<Plan, JoinDistributeType> planToHintType) {
|
||||
if (multiJoin.arity() == 1) {
|
||||
return PlanUtils.filterOrSelf(ImmutableSet.copyOf(multiJoin.getJoinFilter()), multiJoin.child(0));
|
||||
}
|
||||
@ -282,7 +283,8 @@ public class ReorderJoin extends OneRewriteRuleFactory {
|
||||
return PlanUtils.filterOrSelf(ImmutableSet.copyOf(remainingFilter), new LogicalJoin<>(
|
||||
multiJoinHandleChildren.getJoinType(),
|
||||
ExpressionUtils.EMPTY_CONDITION, multiJoinHandleChildren.getNotInnerJoinConditions(),
|
||||
JoinHint.fromRightPlanHintType(planToHintType.getOrDefault(right, JoinHintType.NONE)),
|
||||
new DistributeHint(DistributeType.fromRightPlanHintType(
|
||||
planToHintType.getOrDefault(right, JoinDistributeType.NONE))),
|
||||
Optional.empty(),
|
||||
left, right));
|
||||
}
|
||||
@ -326,7 +328,7 @@ public class ReorderJoin extends OneRewriteRuleFactory {
|
||||
* @return InnerJoin or CrossJoin{left, last of [candidates]}
|
||||
*/
|
||||
private LogicalJoin<? extends Plan, ? extends Plan> findInnerJoin(Plan left, List<Plan> candidates,
|
||||
Set<Expression> joinFilter, Set<Integer> usedPlansIndex, Map<Plan, JoinHintType> planToHintType) {
|
||||
Set<Expression> joinFilter, Set<Integer> usedPlansIndex, Map<Plan, JoinDistributeType> planToHintType) {
|
||||
List<Expression> otherJoinConditions = Lists.newArrayList();
|
||||
Set<ExprId> leftOutputExprIdSet = left.getOutputExprIdSet();
|
||||
int candidateIndex = 0;
|
||||
@ -357,7 +359,8 @@ public class ReorderJoin extends OneRewriteRuleFactory {
|
||||
usedPlansIndex.add(i);
|
||||
return new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
hashJoinConditions, otherJoinConditions,
|
||||
JoinHint.fromRightPlanHintType(planToHintType.getOrDefault(candidate, JoinHintType.NONE)),
|
||||
new DistributeHint(DistributeType.fromRightPlanHintType(
|
||||
planToHintType.getOrDefault(candidate, JoinDistributeType.NONE))),
|
||||
Optional.empty(),
|
||||
left, candidate);
|
||||
}
|
||||
@ -369,7 +372,8 @@ public class ReorderJoin extends OneRewriteRuleFactory {
|
||||
return new LogicalJoin<>(JoinType.CROSS_JOIN,
|
||||
ExpressionUtils.EMPTY_CONDITION,
|
||||
otherJoinConditions,
|
||||
JoinHint.fromRightPlanHintType(planToHintType.getOrDefault(right, JoinHintType.NONE)),
|
||||
new DistributeHint(DistributeType.fromRightPlanHintType(
|
||||
planToHintType.getOrDefault(right, JoinDistributeType.NONE))),
|
||||
Optional.empty(),
|
||||
left, right);
|
||||
}
|
||||
|
||||
@ -18,12 +18,13 @@
|
||||
package org.apache.doris.nereids.rules.rewrite;
|
||||
|
||||
import org.apache.doris.nereids.exceptions.AnalysisException;
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.trees.expressions.AssertNumRowsElement;
|
||||
import org.apache.doris.nereids.trees.expressions.EqualTo;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalApply;
|
||||
@ -62,7 +63,7 @@ public class ScalarApplyToJoin extends OneRewriteRuleFactory {
|
||||
return new LogicalJoin<>(JoinType.CROSS_JOIN,
|
||||
ExpressionUtils.EMPTY_CONDITION,
|
||||
ExpressionUtils.EMPTY_CONDITION,
|
||||
JoinHint.NONE,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
apply.getMarkJoinSlotReference(),
|
||||
(LogicalPlan) apply.left(), assertNumRows);
|
||||
}
|
||||
@ -85,7 +86,7 @@ public class ScalarApplyToJoin extends OneRewriteRuleFactory {
|
||||
apply.isNeedAddSubOutputToProjects() ? JoinType.LEFT_OUTER_JOIN : JoinType.LEFT_SEMI_JOIN,
|
||||
ExpressionUtils.EMPTY_CONDITION,
|
||||
ExpressionUtils.extractConjunction(correlationFilter.get()),
|
||||
JoinHint.NONE,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
apply.getMarkJoinSlotReference(),
|
||||
apply.children());
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ public class SemiJoinCommute extends OneRewriteRuleFactory {
|
||||
return logicalJoin()
|
||||
.when(join -> join.getJoinType().isRightSemiOrAntiJoin() || join.getJoinType().isRightOuterJoin())
|
||||
.whenNot(join -> ConnectContext.get().getSessionVariable().isDisableJoinReorder())
|
||||
.whenNot(LogicalJoin::hasJoinHint)
|
||||
.whenNot(LogicalJoin::hasDistributeHint)
|
||||
.whenNot(LogicalJoin::isMarkJoin)
|
||||
.then(join -> join.withTypeChildren(join.getJoinType().swap(), join.right(), join.left()))
|
||||
.toRule(RuleType.LOGICAL_SEMI_JOIN_COMMUTE);
|
||||
|
||||
@ -43,7 +43,7 @@ public class TransposeSemiJoinLogicalJoin extends OneRewriteRuleFactory {
|
||||
&& (topJoin.left().getJoinType().isInnerJoin()
|
||||
|| topJoin.left().getJoinType().isLeftOuterJoin()
|
||||
|| topJoin.left().getJoinType().isRightOuterJoin())))
|
||||
.whenNot(topJoin -> topJoin.hasJoinHint() || topJoin.left().hasJoinHint())
|
||||
.whenNot(topJoin -> topJoin.hasDistributeHint() || topJoin.left().hasDistributeHint())
|
||||
.whenNot(LogicalJoin::isMarkJoin)
|
||||
.then(topSemiJoin -> {
|
||||
LogicalJoin<Plan, Plan> bottomJoin = topSemiJoin.left();
|
||||
|
||||
@ -48,7 +48,7 @@ public class TransposeSemiJoinLogicalJoinProject extends OneRewriteRuleFactory {
|
||||
|| topJoin.left().child().getJoinType().isLeftOuterJoin()
|
||||
|| topJoin.left().child().getJoinType().isRightOuterJoin())))
|
||||
.when(join -> join.left().isAllSlots())
|
||||
.whenNot(join -> join.hasJoinHint() || join.left().child().hasJoinHint())
|
||||
.whenNot(join -> join.hasDistributeHint() || join.left().child().hasDistributeHint())
|
||||
.whenNot(join -> join.isMarkJoin() || join.left().child().isMarkJoin())
|
||||
.when(join -> join.left().getProjects().stream().allMatch(expr -> expr instanceof Slot))
|
||||
.then(topSemiJoin -> {
|
||||
|
||||
@ -337,7 +337,7 @@ public class LogicalPlanDeepCopier extends DefaultPlanRewriter<DeepCopierContext
|
||||
.map(c -> ExpressionDeepCopier.INSTANCE.deepCopy(c, context))
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
return new LogicalJoin<>(join.getJoinType(), hashJoinConjuncts, otherJoinConjuncts,
|
||||
join.getHint(), join.getMarkJoinSlotReference(), children);
|
||||
join.getDistributeHint(), join.getMarkJoinSlotReference(), children);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -23,15 +23,15 @@ package org.apache.doris.nereids.trees.plans;
|
||||
* Hints for the right child of join are supported currently.
|
||||
* Left input and right input of join could have different hints for further extension.
|
||||
*/
|
||||
public enum JoinHint {
|
||||
NONE(JoinHintType.NONE, JoinHintType.NONE),
|
||||
BROADCAST_RIGHT(JoinHintType.NONE, JoinHintType.BROADCAST),
|
||||
SHUFFLE_RIGHT(JoinHintType.NONE, JoinHintType.SHUFFLE);
|
||||
public enum DistributeType {
|
||||
NONE(JoinDistributeType.NONE, JoinDistributeType.NONE),
|
||||
BROADCAST_RIGHT(JoinDistributeType.NONE, JoinDistributeType.BROADCAST),
|
||||
SHUFFLE_RIGHT(JoinDistributeType.NONE, JoinDistributeType.SHUFFLE);
|
||||
|
||||
/**
|
||||
* Join hint type for single join input plan.
|
||||
*/
|
||||
public enum JoinHintType {
|
||||
public enum JoinDistributeType {
|
||||
// No join hint.
|
||||
NONE,
|
||||
// Shuffle join hint.
|
||||
@ -40,26 +40,26 @@ public enum JoinHint {
|
||||
BROADCAST,
|
||||
}
|
||||
|
||||
private final JoinHintType leftHint;
|
||||
private final JoinHintType rightHint;
|
||||
private final JoinDistributeType leftHint;
|
||||
private final JoinDistributeType rightHint;
|
||||
|
||||
JoinHint(JoinHintType leftHint, JoinHintType rightHint) {
|
||||
DistributeType(JoinDistributeType leftHint, JoinDistributeType rightHint) {
|
||||
this.leftHint = leftHint;
|
||||
this.rightHint = rightHint;
|
||||
}
|
||||
|
||||
public JoinHintType getLeftHint() {
|
||||
public JoinDistributeType getLeftHint() {
|
||||
return leftHint;
|
||||
}
|
||||
|
||||
public JoinHintType getRightHint() {
|
||||
public JoinDistributeType getRightHint() {
|
||||
return rightHint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create join hint from join right child's join hint type.
|
||||
*/
|
||||
public static JoinHint fromRightPlanHintType(JoinHintType hintType) {
|
||||
public static DistributeType fromRightPlanHintType(JoinDistributeType hintType) {
|
||||
switch (hintType) {
|
||||
case SHUFFLE:
|
||||
return SHUFFLE_RIGHT;
|
||||
@ -17,11 +17,12 @@
|
||||
|
||||
package org.apache.doris.nereids.trees.plans.algebra;
|
||||
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.trees.expressions.EqualTo;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.MarkJoinSlotReference;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint.JoinHintType;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType.JoinDistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
|
||||
import java.util.List;
|
||||
@ -45,12 +46,12 @@ public interface Join {
|
||||
|
||||
Optional<Expression> getOnClauseCondition();
|
||||
|
||||
JoinHint getHint();
|
||||
DistributeHint getDistributeHint();
|
||||
|
||||
boolean isMarkJoin();
|
||||
|
||||
default boolean hasJoinHint() {
|
||||
return getHint() != JoinHint.NONE;
|
||||
default boolean hasDistributeHint() {
|
||||
return getDistributeHint().distributeType != DistributeType.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,21 +61,21 @@ public interface Join {
|
||||
return !getHashJoinConjuncts().isEmpty() || !getOtherJoinConjuncts().isEmpty();
|
||||
}
|
||||
|
||||
default JoinHintType getLeftHint() {
|
||||
return JoinHintType.NONE;
|
||||
default JoinDistributeType getLeftHint() {
|
||||
return JoinDistributeType.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hint type of join's right child.
|
||||
*/
|
||||
default JoinHintType getRightHint() {
|
||||
switch (getHint()) {
|
||||
default JoinDistributeType getRightHint() {
|
||||
switch (getDistributeHint().distributeType) {
|
||||
case SHUFFLE_RIGHT:
|
||||
return JoinHintType.SHUFFLE;
|
||||
return JoinDistributeType.SHUFFLE;
|
||||
case BROADCAST_RIGHT:
|
||||
return JoinHintType.BROADCAST;
|
||||
return JoinDistributeType.BROADCAST;
|
||||
default:
|
||||
return JoinHintType.NONE;
|
||||
return JoinDistributeType.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
package org.apache.doris.nereids.trees.plans.logical;
|
||||
|
||||
import org.apache.doris.common.Pair;
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
|
||||
import org.apache.doris.nereids.memo.GroupExpression;
|
||||
import org.apache.doris.nereids.properties.FunctionalDependencies;
|
||||
@ -30,7 +31,7 @@ import org.apache.doris.nereids.trees.expressions.ExprId;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.MarkJoinSlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.PlanType;
|
||||
@ -75,21 +76,23 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
// Table bitmap for tables below this join
|
||||
private long bitmap = LongBitmap.newBitmap();
|
||||
|
||||
private JoinHint hint;
|
||||
private DistributeHint hint;
|
||||
|
||||
public LogicalJoin(JoinType joinType, LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) {
|
||||
this(joinType, ExpressionUtils.EMPTY_CONDITION, ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE,
|
||||
this(joinType, ExpressionUtils.EMPTY_CONDITION, ExpressionUtils.EMPTY_CONDITION,
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
Optional.empty(), Optional.empty(), Optional.empty(), leftChild, rightChild);
|
||||
}
|
||||
|
||||
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts, LEFT_CHILD_TYPE leftChild,
|
||||
RIGHT_CHILD_TYPE rightChild) {
|
||||
this(joinType, hashJoinConjuncts, ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, Optional.empty(),
|
||||
this(joinType, hashJoinConjuncts, ExpressionUtils.EMPTY_CONDITION,
|
||||
new DistributeHint(DistributeType.NONE), Optional.empty(),
|
||||
Optional.empty(), Optional.empty(), leftChild, rightChild);
|
||||
}
|
||||
|
||||
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts, List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint, LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) {
|
||||
DistributeHint hint, LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) {
|
||||
this(joinType, hashJoinConjuncts, otherJoinConjuncts, hint, Optional.empty(), Optional.empty(),
|
||||
Optional.empty(), leftChild, rightChild);
|
||||
}
|
||||
@ -98,7 +101,7 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
JoinType joinType,
|
||||
List<Expression> hashJoinConjuncts,
|
||||
List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint,
|
||||
DistributeHint hint,
|
||||
Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) {
|
||||
this(joinType, hashJoinConjuncts,
|
||||
@ -111,7 +114,7 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
JoinType joinType,
|
||||
List<Expression> hashJoinConjuncts,
|
||||
List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint,
|
||||
DistributeHint hint,
|
||||
Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) {
|
||||
this(joinType, hashJoinConjuncts,
|
||||
@ -124,7 +127,7 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
JoinType joinType,
|
||||
List<Expression> hashJoinConjuncts,
|
||||
List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint,
|
||||
DistributeHint hint,
|
||||
Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
List<Plan> children) {
|
||||
this(joinType, hashJoinConjuncts,
|
||||
@ -133,7 +136,7 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
}
|
||||
|
||||
private LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts, List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint, Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
DistributeHint hint, Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
Optional<GroupExpression> groupExpression, Optional<LogicalProperties> logicalProperties,
|
||||
List<Plan> children, JoinReorderContext joinReorderContext) {
|
||||
// Just use in withXXX method. Don't need check/copyOf()
|
||||
@ -150,7 +153,7 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
JoinType joinType,
|
||||
List<Expression> hashJoinConjuncts,
|
||||
List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint,
|
||||
DistributeHint hint,
|
||||
Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
Optional<GroupExpression> groupExpression,
|
||||
Optional<LogicalProperties> logicalProperties,
|
||||
@ -168,7 +171,7 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
JoinType joinType,
|
||||
List<Expression> hashJoinConjuncts,
|
||||
List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint,
|
||||
DistributeHint hint,
|
||||
Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
Optional<GroupExpression> groupExpression,
|
||||
Optional<LogicalProperties> logicalProperties,
|
||||
@ -220,11 +223,11 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
return joinType;
|
||||
}
|
||||
|
||||
public JoinHint getHint() {
|
||||
public DistributeHint getDistributeHint() {
|
||||
return hint;
|
||||
}
|
||||
|
||||
public void setHint(JoinHint hint) {
|
||||
public void setHint(DistributeHint hint) {
|
||||
this.hint = hint;
|
||||
}
|
||||
|
||||
@ -252,9 +255,9 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
"markJoinSlotReference", markJoinSlotReference,
|
||||
"hashJoinConjuncts", hashJoinConjuncts,
|
||||
"otherJoinConjuncts", otherJoinConjuncts);
|
||||
if (hint != JoinHint.NONE) {
|
||||
if (hint.distributeType != DistributeType.NONE) {
|
||||
args.add("hint");
|
||||
args.add(hint);
|
||||
args.add(hint.getExplainString());
|
||||
}
|
||||
return Utils.toSqlString("LogicalJoin[" + id.asInt() + "]", args.toArray());
|
||||
}
|
||||
@ -269,7 +272,7 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
}
|
||||
LogicalJoin<?, ?> that = (LogicalJoin<?, ?>) o;
|
||||
return joinType == that.joinType
|
||||
&& hint == that.hint
|
||||
&& hint.equals(that.hint)
|
||||
&& hashJoinConjuncts.equals(that.hashJoinConjuncts)
|
||||
&& otherJoinConjuncts.equals(that.otherJoinConjuncts)
|
||||
&& Objects.equals(markJoinSlotReference, that.markJoinSlotReference);
|
||||
@ -486,7 +489,7 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
properties.put("JoinType", joinType.toString());
|
||||
properties.put("HashJoinConjuncts", hashJoinConjuncts.toString());
|
||||
properties.put("OtherJoinConjuncts", otherJoinConjuncts.toString());
|
||||
properties.put("JoinHint", hint.toString());
|
||||
properties.put("DistributeHint", hint.toString());
|
||||
properties.put("MarkJoinSlotReference", markJoinSlotReference.toString());
|
||||
logicalJoin.put("Properties", properties);
|
||||
return logicalJoin;
|
||||
|
||||
@ -17,13 +17,13 @@
|
||||
|
||||
package org.apache.doris.nereids.trees.plans.logical;
|
||||
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.memo.GroupExpression;
|
||||
import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.MarkJoinSlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.BlockFuncDepsPropagation;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.PlanType;
|
||||
@ -47,12 +47,12 @@ public class UsingJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends Pl
|
||||
private final JoinType joinType;
|
||||
private final ImmutableList<Expression> otherJoinConjuncts;
|
||||
private final ImmutableList<Expression> hashJoinConjuncts;
|
||||
private final JoinHint hint;
|
||||
private final DistributeHint hint;
|
||||
private final Optional<MarkJoinSlotReference> markJoinSlotReference;
|
||||
|
||||
public UsingJoin(JoinType joinType, LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild,
|
||||
List<Expression> expressions, List<Expression> hashJoinConjuncts,
|
||||
JoinHint hint) {
|
||||
DistributeHint hint) {
|
||||
this(joinType, leftChild, rightChild, expressions,
|
||||
hashJoinConjuncts, Optional.empty(), Optional.empty(), hint, Optional.empty());
|
||||
}
|
||||
@ -63,7 +63,7 @@ public class UsingJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends Pl
|
||||
public UsingJoin(JoinType joinType, LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild,
|
||||
List<Expression> expressions, List<Expression> hashJoinConjuncts, Optional<GroupExpression> groupExpression,
|
||||
Optional<LogicalProperties> logicalProperties,
|
||||
JoinHint hint, Optional<MarkJoinSlotReference> markJoinSlotReference) {
|
||||
DistributeHint hint, Optional<MarkJoinSlotReference> markJoinSlotReference) {
|
||||
super(PlanType.LOGICAL_USING_JOIN, groupExpression, logicalProperties, leftChild, rightChild);
|
||||
this.joinType = joinType;
|
||||
this.otherJoinConjuncts = ImmutableList.copyOf(expressions);
|
||||
@ -155,7 +155,7 @@ public class UsingJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends Pl
|
||||
return hashJoinConjuncts;
|
||||
}
|
||||
|
||||
public JoinHint getHint() {
|
||||
public DistributeHint getDistributeHint() {
|
||||
return hint;
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ public class UsingJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends Pl
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasJoinHint() {
|
||||
public boolean hasDistributeHint() {
|
||||
return hint != null;
|
||||
}
|
||||
|
||||
|
||||
@ -17,13 +17,14 @@
|
||||
|
||||
package org.apache.doris.nereids.trees.plans.physical;
|
||||
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.memo.GroupExpression;
|
||||
import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
import org.apache.doris.nereids.properties.PhysicalProperties;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.MarkJoinSlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.PlanType;
|
||||
@ -58,7 +59,7 @@ public abstract class AbstractPhysicalJoin<
|
||||
protected final JoinType joinType;
|
||||
protected final List<Expression> hashJoinConjuncts;
|
||||
protected final List<Expression> otherJoinConjuncts;
|
||||
protected final JoinHint hint;
|
||||
protected final DistributeHint hint;
|
||||
protected final Optional<MarkJoinSlotReference> markJoinSlotReference;
|
||||
protected final List<RuntimeFilter> runtimeFilters = Lists.newArrayList();
|
||||
|
||||
@ -74,7 +75,7 @@ public abstract class AbstractPhysicalJoin<
|
||||
JoinType joinType,
|
||||
List<Expression> hashJoinConjuncts,
|
||||
List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint,
|
||||
DistributeHint hint,
|
||||
Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
Optional<GroupExpression> groupExpression,
|
||||
LogicalProperties logicalProperties, LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) {
|
||||
@ -94,7 +95,7 @@ public abstract class AbstractPhysicalJoin<
|
||||
JoinType joinType,
|
||||
List<Expression> hashJoinConjuncts,
|
||||
List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint,
|
||||
DistributeHint hint,
|
||||
Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
Optional<GroupExpression> groupExpression,
|
||||
LogicalProperties logicalProperties,
|
||||
@ -174,7 +175,7 @@ public abstract class AbstractPhysicalJoin<
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinHint getHint() {
|
||||
public DistributeHint getDistributeHint() {
|
||||
return hint;
|
||||
}
|
||||
|
||||
@ -239,9 +240,9 @@ public abstract class AbstractPhysicalJoin<
|
||||
args.add("MarkJoinSlotReference");
|
||||
args.add(markJoinSlotReference.get());
|
||||
}
|
||||
if (hint != JoinHint.NONE) {
|
||||
if (hint.distributeType != DistributeType.NONE) {
|
||||
args.add("hint");
|
||||
args.add(hint);
|
||||
args.add(hint.getExplainString());
|
||||
}
|
||||
if (!runtimeFilters.isEmpty()) {
|
||||
args.add("runtimeFilters");
|
||||
|
||||
@ -166,4 +166,11 @@ public class PhysicalDistribute<CHILD_TYPE extends Plan> extends PhysicalUnary<C
|
||||
return new PhysicalDistribute<>(distributionSpec, groupExpression,
|
||||
null, physicalProperties, statistics, child());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shapeInfo() {
|
||||
StringBuilder builder = new StringBuilder("PhysicalDistribute");
|
||||
builder.append("[").append(getDistributionSpec().shapeInfo()).append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ package org.apache.doris.nereids.trees.plans.physical;
|
||||
import org.apache.doris.common.IdGenerator;
|
||||
import org.apache.doris.common.Pair;
|
||||
import org.apache.doris.nereids.CascadesContext;
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.memo.GroupExpression;
|
||||
import org.apache.doris.nereids.processor.post.RuntimeFilterContext;
|
||||
import org.apache.doris.nereids.processor.post.RuntimeFilterGenerator;
|
||||
@ -31,7 +32,6 @@ import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.MarkJoinSlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.PlanType;
|
||||
@ -64,7 +64,7 @@ public class PhysicalHashJoin<
|
||||
JoinType joinType,
|
||||
List<Expression> hashJoinConjuncts,
|
||||
List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint,
|
||||
DistributeHint hint,
|
||||
Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
LogicalProperties logicalProperties,
|
||||
LEFT_CHILD_TYPE leftChild,
|
||||
@ -83,7 +83,7 @@ public class PhysicalHashJoin<
|
||||
JoinType joinType,
|
||||
List<Expression> hashJoinConjuncts,
|
||||
List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint,
|
||||
DistributeHint hint,
|
||||
Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
Optional<GroupExpression> groupExpression,
|
||||
LogicalProperties logicalProperties,
|
||||
@ -96,7 +96,7 @@ public class PhysicalHashJoin<
|
||||
JoinType joinType,
|
||||
List<Expression> hashJoinConjuncts,
|
||||
List<Expression> otherJoinConjuncts,
|
||||
JoinHint hint,
|
||||
DistributeHint hint,
|
||||
Optional<MarkJoinSlotReference> markJoinSlotReference,
|
||||
Optional<GroupExpression> groupExpression,
|
||||
LogicalProperties logicalProperties,
|
||||
|
||||
@ -17,13 +17,14 @@
|
||||
|
||||
package org.apache.doris.nereids.trees.plans.physical;
|
||||
|
||||
import org.apache.doris.nereids.hint.DistributeHint;
|
||||
import org.apache.doris.nereids.memo.GroupExpression;
|
||||
import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
import org.apache.doris.nereids.properties.PhysicalProperties;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.MarkJoinSlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.JoinHint;
|
||||
import org.apache.doris.nereids.trees.plans.DistributeType;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.PlanType;
|
||||
@ -83,7 +84,7 @@ public class PhysicalNestedLoopJoin<
|
||||
LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) {
|
||||
super(PlanType.PHYSICAL_NESTED_LOOP_JOIN, joinType, hashJoinConjuncts, otherJoinConjuncts,
|
||||
// nested loop join ignores join hints.
|
||||
JoinHint.NONE, markJoinSlotReference,
|
||||
new DistributeHint(DistributeType.NONE), markJoinSlotReference,
|
||||
groupExpression, logicalProperties, leftChild, rightChild);
|
||||
}
|
||||
|
||||
@ -106,7 +107,7 @@ public class PhysicalNestedLoopJoin<
|
||||
RIGHT_CHILD_TYPE rightChild) {
|
||||
super(PlanType.PHYSICAL_NESTED_LOOP_JOIN, joinType, hashJoinConjuncts, otherJoinConjuncts,
|
||||
// nested loop join ignores join hints.
|
||||
JoinHint.NONE, markJoinSlotReference,
|
||||
new DistributeHint(DistributeType.NONE), markJoinSlotReference,
|
||||
groupExpression, logicalProperties, physicalProperties, statistics, leftChild, rightChild);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user