[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:
LiBinfeng
2024-01-04 17:51:06 +08:00
committed by GitHub
parent 441fb49345
commit abd9000368
702 changed files with 12310 additions and 9230 deletions

View File

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

View File

@ -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;
}
}

View File

@ -65,6 +65,10 @@ public class Hint {
return getStatus() == HintStatus.SYNTAX_ERROR;
}
public boolean isUnUsed() {
return getStatus() == HintStatus.UNUSED;
}
public String getHintName() {
return hintName;
}

View File

@ -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<>();

View File

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

View File

@ -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");

View File

@ -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);

View File

@ -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) {

View File

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

View File

@ -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());
})
),

View File

@ -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()) {

View File

@ -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();

View File

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

View File

@ -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();

View File

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

View File

@ -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();

View File

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

View File

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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

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

View File

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

View File

@ -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())

View File

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

View File

@ -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()))

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

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

View File

@ -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);
}

View File

@ -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(),

View File

@ -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);
}
}

View File

@ -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())

View File

@ -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);

View File

@ -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);

View File

@ -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)))) {

View File

@ -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);
}

View File

@ -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())));

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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());
}

View File

@ -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);

View File

@ -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();

View File

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

View File

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

View File

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

View File

@ -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;
}
}

View File

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

View File

@ -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;
}

View File

@ -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");

View File

@ -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();
}
}

View File

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

View File

@ -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);
}