[Feat](nereids) support multi-leading (#30379)

support multi-leading in each query block
This commit is contained in:
LiBinfeng
2024-02-28 10:58:11 +08:00
committed by yiguolei
parent c5e6e3d45f
commit 5824f8a4bc
90 changed files with 13343 additions and 223 deletions

View File

@ -120,6 +120,8 @@ public class CascadesContext implements ScheduleContext {
private final List<MaterializationContext> materializationContexts;
private boolean isLeadingJoin = false;
private boolean isLeadingDisableJoinReorder = false;
private final Map<String, Hint> hintMap = Maps.newLinkedHashMap();
private final boolean shouldCheckRelationAuthentication;
private final ThreadLocal<Boolean> showPlanProcess = new ThreadLocal<>();
@ -657,6 +659,14 @@ public class CascadesContext implements ScheduleContext {
return shouldCheckRelationAuthentication;
}
public boolean isLeadingDisableJoinReorder() {
return isLeadingDisableJoinReorder;
}
public void setLeadingDisableJoinReorder(boolean leadingDisableJoinReorder) {
isLeadingDisableJoinReorder = leadingDisableJoinReorder;
}
public Map<String, Hint> getHintMap() {
return hintMap;
}

View File

@ -503,7 +503,8 @@ public class LeadingHint extends Hint {
distributeHint,
Optional.empty(),
newStackTop.second.first,
logicalPlan);
logicalPlan, null);
logicalJoin.getJoinReorderContext().setLeadingJoin(true);
distributeIndex = newStackTop.second.second;
logicalJoin.setBitmap(LongBitmap.or(getBitmap(newStackTop.second.first), getBitmap(logicalPlan)));
if (stackTopLevel > 0) {

View File

@ -75,6 +75,7 @@ public class OptimizeGroupExpressionJob extends Job {
private List<Rule> getJoinRules() {
boolean isDisableJoinReorder = context.getCascadesContext().getConnectContext().getSessionVariable()
.isDisableJoinReorder()
|| context.getCascadesContext().isLeadingDisableJoinReorder()
|| context.getCascadesContext().getMemo().getGroupExpressionsSize() > context.getCascadesContext()
.getConnectContext().getSessionVariable().memoMaxGroupExpressionSize;
boolean isDpHyp = context.getCascadesContext().getStatementContext().isDpHyp();

View File

@ -68,6 +68,7 @@ public class Optimizer {
|| maxJoinCount > maxTableCount;
cascadesContext.getStatementContext().setDpHyp(isDpHyp);
if (!getSessionVariable().isDisableJoinReorder() && isDpHyp
&& !cascadesContext.isLeadingDisableJoinReorder()
&& maxJoinCount <= getSessionVariable().getMaxJoinNumberOfReorder()) {
//RightNow, dphyper can only order 64 join operators
dpHypOptimize();

View File

@ -413,7 +413,7 @@ public class GraphSimplifier {
.mapToObj(i -> graph.getJoinEdge(i).getJoin().getHashJoinConjuncts())
.flatMap(Collection::stream)
.collect(Collectors.toList());
join = edge.getJoin().withJoinConjuncts(hashConditions, otherConditions);
join = edge.getJoin().withJoinConjuncts(hashConditions, otherConditions, null);
}
JoinEdge newEdge = new JoinEdge(join, edge.getIndex(),

View File

@ -551,7 +551,7 @@ public class HyperGraph {
LogicalJoin<?, ?> singleJoin = new LogicalJoin<>(join.getJoinType(), entry.getValue().first,
entry.getValue().second,
new DistributeHint(DistributeType.NONE), join.getMarkJoinSlotReference(),
Lists.newArrayList(join.left(), join.right()));
Lists.newArrayList(join.left(), join.right()), null);
Pair<Long, Long> ends = entry.getKey();
JoinEdge edge = new JoinEdge(singleJoin, joinEdges.size(), leftEdgeNodes.first, rightEdgeNodes.first,
LongBitmap.newBitmapUnion(leftEdgeNodes.second, rightEdgeNodes.second),

View File

@ -67,7 +67,7 @@ public class JoinEdge extends Edge {
}
public JoinEdge withJoinTypeAndCleanCR(JoinType joinType) {
return new JoinEdge(join.withJoinType(joinType), getIndex(), getLeftChildEdges(), getRightChildEdges(),
return new JoinEdge(join.withJoinType(joinType, null), getIndex(), getLeftChildEdges(), getRightChildEdges(),
getSubTreeNodes(), getLeftRequiredNodes(), getRightRequiredNodes(), leftInputSlots, rightInputSlots);
}

View File

@ -198,7 +198,7 @@ public class PlanReceiver implements AbstractReceiver {
private LogicalPlan proposeJoin(JoinType joinType, Plan left, Plan right, List<Expression> hashConjuncts,
List<Expression> otherConjuncts) {
return new LogicalJoin<>(joinType, hashConjuncts, otherConjuncts, left, right);
return new LogicalJoin<>(joinType, hashConjuncts, otherConjuncts, left, right, null);
}
@Override

View File

@ -2907,7 +2907,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
distributeHint,
Optional.empty(),
last,
plan(join.relationPrimary()));
plan(join.relationPrimary()), null);
} else {
last = new UsingJoin<>(joinType, last,
plan(join.relationPrimary()), ImmutableList.of(), ids, distributeHint);
@ -3025,7 +3025,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
new DistributeHint(DistributeType.NONE),
Optional.empty(),
left,
right);
right, null);
// TODO: pivot and lateral view
}
return left;

View File

@ -43,11 +43,16 @@ public class PlanPreprocessors {
return resultPlan;
}
/**
* get preprocessors before doing optimize
* @return preprocessors
*/
public List<PlanPreprocessor> getProcessors() {
// add processor if we need
return ImmutableList.of(
new TurnOffPipelineForDml(),
new TurnOffPageCacheForInsertIntoSelect()
new TurnOffPageCacheForInsertIntoSelect(),
new PullUpSubqueryAliasToCTE()
);
}
}

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.processor.pre;
import org.apache.doris.nereids.StatementContext;
import org.apache.doris.nereids.analyzer.UnboundRelation;
import org.apache.doris.nereids.analyzer.UnboundResultSink;
import org.apache.doris.nereids.trees.expressions.StatementScopeIdGenerator;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalCTE;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.trees.plans.logical.LogicalSelectHint;
import org.apache.doris.nereids.trees.plans.logical.LogicalSubQueryAlias;
import java.util.ArrayList;
import java.util.List;
/**
* TODO turnoff pipeline for any dml temporary, remove this pre-process when pipeline-sink is ok.
*/
public class PullUpSubqueryAliasToCTE extends PlanPreprocessor {
private List<LogicalSubQueryAlias<Plan>> aliasQueries = new ArrayList<>();
@Override
public Plan visitUnboundResultSink(UnboundResultSink<? extends Plan> unboundResultSink,
StatementContext context) {
Plan topPlan = visitChildren(this, unboundResultSink, context);
if (!aliasQueries.isEmpty()) {
return topPlan.withChildren(
new LogicalCTE<>(aliasQueries, (LogicalPlan) ((UnboundResultSink) topPlan).child()));
}
return topPlan;
}
@Override
public Plan visitLogicalSubQueryAlias(LogicalSubQueryAlias<? extends Plan> alias,
StatementContext context) {
if (alias.child() instanceof LogicalSelectHint
&& ((LogicalSelectHint) alias.child()).isIncludeLeading()) {
aliasQueries.add((LogicalSubQueryAlias<Plan>) alias);
List<String> tableName = new ArrayList<>();
tableName.add(alias.getAlias());
return new UnboundRelation(StatementScopeIdGenerator.newRelationId(), tableName);
}
return alias;
}
@Override
public Plan visitLogicalCTE(LogicalCTE<? extends Plan> logicalCTE, StatementContext context) {
List<LogicalSubQueryAlias<Plan>> subQueryAliases = logicalCTE.getAliasQueries();
for (LogicalSubQueryAlias<Plan> subQueryAlias : subQueryAliases) {
Plan newSubQueryAlias = subQueryAlias.accept(new PullUpSubqueryAliasToCTE(), context);
if (newSubQueryAlias instanceof LogicalSubQueryAlias) {
subQueryAlias = (LogicalSubQueryAlias<Plan>) newSubQueryAlias;
} else {
subQueryAlias = new LogicalSubQueryAlias<>(subQueryAlias.getAlias(), newSubQueryAlias);
}
}
return visitChildren(this, logicalCTE, context);
}
}

View File

@ -184,7 +184,7 @@ public class BindExpression implements AnalysisRuleFactory {
? JoinType.INNER_JOIN : using.getJoinType(),
using.getHashJoinConjuncts(),
using.getOtherJoinConjuncts(), using.getDistributeHint(), using.getMarkJoinSlotReference(),
using.children());
using.children(), null);
List<Expression> unboundSlots = lj.getHashJoinConjuncts();
Set<String> slotNames = new HashSet<>();
List<Slot> leftOutput = new ArrayList<>(lj.left().getOutput());
@ -216,7 +216,7 @@ public class BindExpression implements AnalysisRuleFactory {
for (int i = 0; i < size; i++) {
hashEqExpr.add(new EqualTo(leftSlots.get(i), rightSlots.get(i)));
}
return lj.withJoinConjuncts(hashEqExpr, lj.getOtherJoinConjuncts());
return lj.withJoinConjuncts(hashEqExpr, lj.getOtherJoinConjuncts(), null);
})
),
RuleType.BINDING_JOIN_SLOT.build(
@ -234,7 +234,7 @@ public class BindExpression implements AnalysisRuleFactory {
.collect(Collectors.toList());
return new LogicalJoin<>(join.getJoinType(),
hashJoinConjuncts, cond, join.getDistributeHint(), join.getMarkJoinSlotReference(),
join.children());
join.children(), null);
})
),
RuleType.BINDING_AGGREGATE_SLOT.build(

View File

@ -126,7 +126,8 @@ public class EliminateLogicalSelectHint extends OneRewriteRuleFactory {
}
statementContext.addHint(hint);
context.getHintMap().put("Leading", hint);
if (hints.get("ordered") != null || ConnectContext.get().getSessionVariable().isDisableJoinReorder()) {
if (hints.get("ordered") != null || ConnectContext.get().getSessionVariable().isDisableJoinReorder()
|| context.isLeadingDisableJoinReorder()) {
context.setLeadingJoin(false);
hint.setStatus(Hint.HintStatus.UNUSED);
} else {

View File

@ -17,7 +17,6 @@
package org.apache.doris.nereids.rules.analysis;
import org.apache.doris.common.DdlException;
import org.apache.doris.nereids.hint.Hint;
import org.apache.doris.nereids.hint.LeadingHint;
import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
@ -25,7 +24,6 @@ import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleType;
import org.apache.doris.nereids.rules.rewrite.RewriteRuleFactory;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.qe.ConnectContext;
import com.google.common.collect.ImmutableList;
@ -40,9 +38,8 @@ public class LeadingJoin implements RewriteRuleFactory {
public List<Rule> buildRules() {
return ImmutableList.of(
logicalJoin()
.whenNot(join -> ConnectContext.get().getSessionVariable().isDisableJoinReorder())
.thenApply(ctx -> {
if (!ctx.cascadesContext.isLeadingJoin()) {
if (!ctx.cascadesContext.isLeadingJoin() || ctx.cascadesContext.isLeadingDisableJoinReorder()) {
return ctx.root;
}
Hint leadingHint = ctx.cascadesContext.getHintMap().get("Leading");
@ -52,13 +49,8 @@ public class LeadingJoin implements RewriteRuleFactory {
&& leadingHint.isSuccess()) {
Plan leadingJoin = ((LeadingHint) leadingHint).generateLeadingJoinPlan();
if (leadingHint.isSuccess() && leadingJoin != null) {
try {
ctx.cascadesContext.getConnectContext().getSessionVariable()
.disableNereidsJoinReorderOnce();
ctx.cascadesContext.setLeadingJoin(false);
} catch (DdlException e) {
throw new RuntimeException(e);
}
ctx.cascadesContext.setLeadingDisableJoinReorder(true);
ctx.cascadesContext.setLeadingJoin(false);
return leadingJoin;
}
}

View File

@ -261,7 +261,7 @@ public class SubqueryToApply implements AnalysisRuleFactory {
newConjuncts.addAll(simpleConjuncts);
}
Plan newJoin = join.withConjunctsChildren(join.getHashJoinConjuncts(),
newConjuncts.build(), leftChildPlan, rightChildPlan);
newConjuncts.build(), leftChildPlan, rightChildPlan, null);
return newJoin;
}))
);

View File

@ -80,10 +80,10 @@ public class InnerJoinLAsscom extends OneExplorationRuleFactory {
}
LogicalJoin<Plan, Plan> newBottomJoin = topJoin.withConjunctsChildren(newBottomHashConjuncts,
newBottomOtherConjuncts, a, c);
newBottomOtherConjuncts, a, c, null);
LogicalJoin<Plan, Plan> newTopJoin = bottomJoin.withConjunctsChildren(newTopHashConjuncts,
newTopOtherConjuncts, newBottomJoin, b);
newTopOtherConjuncts, newBottomJoin, b, null);
newTopJoin.getJoinReorderContext().copyFrom(topJoin.getJoinReorderContext());
newTopJoin.getJoinReorderContext().setHasLAsscom(true);
@ -96,6 +96,10 @@ public class InnerJoinLAsscom extends OneExplorationRuleFactory {
*/
public static boolean checkReorder(LogicalJoin<? extends Plan, GroupPlan> topJoin,
LogicalJoin<GroupPlan, GroupPlan> bottomJoin, boolean leftZigZag) {
if (topJoin.isLeadingJoin()
|| bottomJoin.isLeadingJoin()) {
return false;
}
if (leftZigZag) {
double bRows = bottomJoin.right().getGroup().getStatistics().getRowCount();
double cRows = topJoin.right().getGroup().getStatistics().getRowCount();

View File

@ -88,7 +88,7 @@ public class InnerJoinLAsscomProject extends OneExplorationRuleFactory {
/* ********** new Plan ********** */
LogicalJoin<Plan, Plan> newBottomJoin = topJoin.withConjunctsChildren(newBottomHashConjuncts,
newBottomOtherConjuncts, a, c);
newBottomOtherConjuncts, a, c, null);
// merge newTopHashConjuncts newTopOtherConjuncts topJoin.getOutputExprIdSet()
Set<ExprId> topUsedExprIds = new HashSet<>(topJoin.getOutputExprIdSet());
@ -98,7 +98,7 @@ public class InnerJoinLAsscomProject extends OneExplorationRuleFactory {
Plan right = CBOUtils.newProject(topUsedExprIds, b);
LogicalJoin<Plan, Plan> newTopJoin = bottomJoin.withConjunctsChildren(newTopHashConjuncts,
newTopOtherConjuncts, left, right);
newTopOtherConjuncts, left, right, null);
newTopJoin.getJoinReorderContext().copyFrom(topJoin.getJoinReorderContext());
newTopJoin.getJoinReorderContext().setHasLAsscom(true);

View File

@ -85,9 +85,9 @@ public class InnerJoinLeftAssociate extends OneExplorationRuleFactory {
// new join.
LogicalJoin<Plan, Plan> newBottomJoin = topJoin.withConjunctsChildren(
newBottomHashJoinConjuncts, newBottomOtherJoinConjuncts, a, b);
newBottomHashJoinConjuncts, newBottomOtherJoinConjuncts, a, b, null);
LogicalJoin<Plan, Plan> newTopJoin = bottomJoin.withConjunctsChildren(
newTopHashJoinConjuncts, newTopOtherJoinConjuncts, newBottomJoin, c);
newTopHashJoinConjuncts, newTopOtherJoinConjuncts, newBottomJoin, c, null);
newTopJoin.getJoinReorderContext().setHasLeftAssociate(true);
return newTopJoin;
@ -96,6 +96,10 @@ public class InnerJoinLeftAssociate extends OneExplorationRuleFactory {
/** Check JoinReorderContext. */
public static boolean checkReorder(LogicalJoin<GroupPlan, ? extends Plan> topJoin) {
if (topJoin.isLeadingJoin()
|| JoinExchange.isChildLeadingJoin(topJoin.right())) {
return false;
}
return !topJoin.getJoinReorderContext().hasCommute()
&& !topJoin.getJoinReorderContext().hasLeftAssociate()
&& !topJoin.getJoinReorderContext().hasRightAssociate()

View File

@ -77,7 +77,7 @@ public class InnerJoinLeftAssociateProject extends OneExplorationRuleFactory {
// new join.
LogicalJoin<Plan, Plan> newBottomJoin = topJoin.withConjunctsChildren(
newBottomHashConjuncts, newBottomOtherConjuncts, a, b);
newBottomHashConjuncts, newBottomOtherConjuncts, a, b, null);
// new Project.
Set<ExprId> topUsedExprIds = new HashSet<>(topJoin.getOutputExprIdSet());
@ -87,7 +87,7 @@ public class InnerJoinLeftAssociateProject extends OneExplorationRuleFactory {
Plan right = CBOUtils.newProject(topUsedExprIds, c);
LogicalJoin<Plan, Plan> newTopJoin = bottomJoin.withConjunctsChildren(
newTopHashConjuncts, newTopOtherConjuncts, left, right);
newTopHashConjuncts, newTopOtherConjuncts, left, right, null);
newTopJoin.getJoinReorderContext().setHasLeftAssociate(true);
return CBOUtils.projectOrSelf(ImmutableList.copyOf(topJoin.getOutput()), newTopJoin);

View File

@ -83,9 +83,9 @@ public class InnerJoinRightAssociate extends OneExplorationRuleFactory {
}
LogicalJoin<Plan, Plan> newBottomJoin = topJoin.withConjunctsChildren(
newBottomHashJoinConjuncts, newBottomOtherJoinConjuncts, b, c);
newBottomHashJoinConjuncts, newBottomOtherJoinConjuncts, b, c, null);
LogicalJoin<Plan, Plan> newTopJoin = bottomJoin.withConjunctsChildren(newTopHashJoinConjuncts,
newTopOtherJoinConjuncts, a, newBottomJoin);
newTopOtherJoinConjuncts, a, newBottomJoin, null);
newTopJoin.getJoinReorderContext().setHasRightAssociate(true);
return newTopJoin;
@ -94,6 +94,10 @@ public class InnerJoinRightAssociate extends OneExplorationRuleFactory {
/** Check JoinReorderContext */
public static boolean checkReorder(LogicalJoin<? extends Plan, GroupPlan> topJoin) {
if (topJoin.isLeadingJoin()
|| JoinExchange.isChildLeadingJoin(topJoin.left())) {
return false;
}
return !topJoin.getJoinReorderContext().hasCommute()
&& !topJoin.getJoinReorderContext().hasRightAssociate()
&& !topJoin.getJoinReorderContext().hasLeftAssociate()

View File

@ -74,7 +74,7 @@ public class InnerJoinRightAssociateProject extends OneExplorationRuleFactory {
}
LogicalJoin<Plan, Plan> newBottomJoin = topJoin.withConjunctsChildren(
newBottomHashConjuncts, newBottomOtherConjuncts, b, c);
newBottomHashConjuncts, newBottomOtherConjuncts, b, c, null);
// new Project.
Set<ExprId> topUsedExprIds = new HashSet<>(topJoin.getOutputExprIdSet());
@ -84,7 +84,7 @@ public class InnerJoinRightAssociateProject extends OneExplorationRuleFactory {
Plan right = CBOUtils.newProject(topUsedExprIds, newBottomJoin);
LogicalJoin<Plan, Plan> newTopJoin = bottomJoin.withConjunctsChildren(
newTopHashConjuncts, newTopOtherConjuncts, left, right);
newTopHashConjuncts, newTopOtherConjuncts, left, right, null);
newTopJoin.getJoinReorderContext().setHasRightAssociate(true);
return CBOUtils.projectOrSelf(ImmutableList.copyOf(topJoin.getOutput()), newTopJoin);
@ -95,6 +95,10 @@ public class InnerJoinRightAssociateProject extends OneExplorationRuleFactory {
* Check JoinReorderContext
*/
public static boolean checkReorder(LogicalJoin<? extends Plan, GroupPlan> topJoin) {
if (topJoin.isLeadingJoin()
|| ((LogicalJoin) topJoin.left().child(0)).isLeadingJoin()) {
return false;
}
return !topJoin.getJoinReorderContext().hasCommute()
&& !topJoin.getJoinReorderContext().hasRightAssociate()
&& !topJoin.getJoinReorderContext().hasLeftAssociate()

View File

@ -62,7 +62,7 @@ public class JoinCommute extends OneExplorationRuleFactory {
.whenNot(LogicalJoin::isMarkJoin)
.then(join -> {
LogicalJoin<Plan, Plan> newJoin = join.withTypeChildren(join.getJoinType().swap(),
join.right(), join.left());
join.right(), join.left(), null);
newJoin.getJoinReorderContext().copyFrom(join.getJoinReorderContext());
newJoin.getJoinReorderContext().setHasCommute(true);
if (swapType == SwapType.ZIG_ZAG && isNotBottomJoin(join)) {
@ -100,6 +100,9 @@ public class JoinCommute extends OneExplorationRuleFactory {
}
private boolean checkReorder(LogicalJoin<GroupPlan, GroupPlan> join) {
if (join.isLeadingJoin()) {
return false;
}
return !join.getJoinReorderContext().hasCommute()
&& !join.getJoinReorderContext().hasExchange();
}

View File

@ -28,6 +28,7 @@ import org.apache.doris.nereids.trees.plans.GroupPlan;
import org.apache.doris.nereids.trees.plans.JoinType;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
import org.apache.doris.nereids.util.JoinUtils;
import com.google.common.collect.Lists;
@ -88,14 +89,14 @@ public class JoinExchange extends OneExplorationRuleFactory {
LogicalJoin<GroupPlan, GroupPlan> newLeftJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE), a, c);
new DistributeHint(DistributeType.NONE), a, c, null);
LogicalJoin<GroupPlan, GroupPlan> newRightJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE), b, d);
new DistributeHint(DistributeType.NONE), b, d, null);
LogicalJoin newTopJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE),
newLeftJoin, newRightJoin);
newLeftJoin, newRightJoin, null);
newTopJoin.getJoinReorderContext().setHasExchange(true);
return newTopJoin;
@ -106,6 +107,10 @@ public class JoinExchange extends OneExplorationRuleFactory {
* check reorder masks.
*/
public static boolean checkReorder(LogicalJoin<? extends Plan, ? extends Plan> topJoin) {
if (topJoin.isLeadingJoin()
|| isChildLeadingJoin(topJoin.left()) || isChildLeadingJoin(topJoin.right())) {
return false;
}
if (topJoin.getJoinReorderContext().hasCommute()
|| topJoin.getJoinReorderContext().hasLeftAssociate()
|| topJoin.getJoinReorderContext().hasRightAssociate()
@ -116,6 +121,24 @@ public class JoinExchange extends OneExplorationRuleFactory {
}
}
/**
* check whether a child plan is generate by leading
* @param child input plan by rule
* @return boolean value if child is generate by leading
*/
public static boolean isChildLeadingJoin(Plan child) {
if (child instanceof LogicalProject) {
if (((LogicalJoin) (child.child(0))).isLeadingJoin()) {
return true;
}
} else if (child instanceof LogicalJoin) {
if (((LogicalJoin) child).isLeadingJoin()) {
return true;
}
}
return false;
}
/**
* split condition.
*/

View File

@ -92,10 +92,10 @@ public class JoinExchangeBothProject extends OneExplorationRuleFactory {
LogicalJoin<GroupPlan, GroupPlan> newLeftJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE), a, c);
new DistributeHint(DistributeType.NONE), a, c, null);
LogicalJoin<GroupPlan, GroupPlan> newRightJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE), b, d);
new DistributeHint(DistributeType.NONE), b, d, null);
Set<ExprId> topUsedExprIds = new HashSet<>(topJoin.getOutputExprIdSet());
newTopJoinHashJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
newTopJoinOtherJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
@ -104,7 +104,7 @@ public class JoinExchangeBothProject extends OneExplorationRuleFactory {
LogicalJoin newTopJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE),
left, right);
left, right, null);
newTopJoin.getJoinReorderContext().setHasExchange(true);
return CBOUtils.projectOrSelf(ImmutableList.copyOf(topJoin.getOutput()), newTopJoin);
@ -115,6 +115,11 @@ public class JoinExchangeBothProject extends OneExplorationRuleFactory {
* check reorder masks.
*/
public static boolean checkReorder(LogicalJoin<? extends Plan, ? extends Plan> topJoin) {
if (topJoin.isLeadingJoin()
|| ((LogicalJoin) topJoin.left().child(0)).isLeadingJoin()
|| ((LogicalJoin) topJoin.right().child(0)).isLeadingJoin()) {
return false;
}
if (topJoin.getJoinReorderContext().hasCommute()
|| topJoin.getJoinReorderContext().hasLeftAssociate()
|| topJoin.getJoinReorderContext().hasRightAssociate()

View File

@ -92,10 +92,10 @@ public class JoinExchangeLeftProject extends OneExplorationRuleFactory {
LogicalJoin<GroupPlan, GroupPlan> newLeftJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE), a, c);
new DistributeHint(DistributeType.NONE), a, c, null);
LogicalJoin<GroupPlan, GroupPlan> newRightJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE), b, d);
new DistributeHint(DistributeType.NONE), b, d, null);
Set<ExprId> topUsedExprIds = new HashSet<>(topJoin.getOutputExprIdSet());
newTopJoinHashJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
newTopJoinOtherJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
@ -104,24 +104,10 @@ public class JoinExchangeLeftProject extends OneExplorationRuleFactory {
LogicalJoin newTopJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE),
left, right);
left, right, null);
newTopJoin.getJoinReorderContext().setHasExchange(true);
return CBOUtils.projectOrSelf(ImmutableList.copyOf(topJoin.getOutput()), newTopJoin);
}).toRule(RuleType.LOGICAL_JOIN_EXCHANGE_LEFT_PROJECT);
}
/**
* check reorder masks.
*/
public static boolean checkReorder(LogicalJoin<? extends Plan, ? extends Plan> topJoin) {
if (topJoin.getJoinReorderContext().hasCommute()
|| topJoin.getJoinReorderContext().hasLeftAssociate()
|| topJoin.getJoinReorderContext().hasRightAssociate()
|| topJoin.getJoinReorderContext().hasExchange()) {
return false;
} else {
return true;
}
}
}

View File

@ -92,10 +92,10 @@ public class JoinExchangeRightProject extends OneExplorationRuleFactory {
LogicalJoin<GroupPlan, GroupPlan> newLeftJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newLeftJoinHashJoinConjuncts, newLeftJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE), a, c);
new DistributeHint(DistributeType.NONE), a, c, null);
LogicalJoin<GroupPlan, GroupPlan> newRightJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newRightJoinHashJoinConjuncts, newRightJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE), b, d);
new DistributeHint(DistributeType.NONE), b, d, null);
Set<ExprId> topUsedExprIds = new HashSet<>(topJoin.getOutputExprIdSet());
newTopJoinHashJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
newTopJoinOtherJoinConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds()));
@ -104,7 +104,7 @@ public class JoinExchangeRightProject extends OneExplorationRuleFactory {
LogicalJoin newTopJoin = new LogicalJoin<>(JoinType.INNER_JOIN,
newTopJoinHashJoinConjuncts, newTopJoinOtherJoinConjuncts,
new DistributeHint(DistributeType.NONE),
left, right);
left, right, null);
newTopJoin.getJoinReorderContext().setHasExchange(true);
return CBOUtils.projectOrSelf(ImmutableList.copyOf(topJoin.getOutput()), newTopJoin);
@ -115,6 +115,10 @@ public class JoinExchangeRightProject extends OneExplorationRuleFactory {
* check reorder masks.
*/
public static boolean checkReorder(LogicalJoin<? extends Plan, ? extends Plan> topJoin) {
if (topJoin.isLeadingJoin()
|| ((LogicalJoin) topJoin.right().child(0)).isLeadingJoin()) {
return false;
}
if (topJoin.getJoinReorderContext().hasCommute()
|| topJoin.getJoinReorderContext().hasLeftAssociate()
|| topJoin.getJoinReorderContext().hasRightAssociate()

View File

@ -39,6 +39,8 @@ public class JoinReorderContext {
private boolean hasRightAssociate = false;
private boolean hasLeftAssociate = false;
private boolean isLeadingJoin = false;
public JoinReorderContext() {
}
@ -52,6 +54,7 @@ public class JoinReorderContext {
this.hasLeftAssociate = joinReorderContext.hasLeftAssociate;
this.hasRightAssociate = joinReorderContext.hasRightAssociate;
this.hasCommuteZigZag = joinReorderContext.hasCommuteZigZag;
this.isLeadingJoin = joinReorderContext.isLeadingJoin;
}
/**
@ -64,6 +67,7 @@ public class JoinReorderContext {
hasExchange = false;
hasRightAssociate = false;
hasLeftAssociate = false;
isLeadingJoin = false;
}
public boolean hasCommute() {
@ -113,4 +117,12 @@ public class JoinReorderContext {
public void setHasCommuteZigZag(boolean hasCommuteZigZag) {
this.hasCommuteZigZag = hasCommuteZigZag;
}
public boolean isLeadingJoin() {
return isLeadingJoin;
}
public void setLeadingJoin(boolean leadingJoin) {
isLeadingJoin = leadingJoin;
}
}

View File

@ -52,8 +52,8 @@ public class LogicalJoinSemiJoinTranspose implements ExplorationRuleFactory {
GroupPlan b = bottomJoin.right();
GroupPlan c = topJoin.right();
Plan newBottomJoin = topJoin.withChildrenNoContext(a, c);
return bottomJoin.withChildrenNoContext(newBottomJoin, b);
Plan newBottomJoin = topJoin.withChildrenNoContext(a, c, null);
return bottomJoin.withChildrenNoContext(newBottomJoin, b, null);
}).toRule(RuleType.LOGICAL_JOIN_LOGICAL_SEMI_JOIN_TRANSPOSE_LEFT),
logicalJoin(group(), logicalJoin())
@ -69,8 +69,8 @@ public class LogicalJoinSemiJoinTranspose implements ExplorationRuleFactory {
GroupPlan b = bottomJoin.left();
GroupPlan c = bottomJoin.right();
Plan newBottomJoin = topJoin.withChildrenNoContext(a, b);
return bottomJoin.withChildrenNoContext(newBottomJoin, c);
Plan newBottomJoin = topJoin.withChildrenNoContext(a, b, null);
return bottomJoin.withChildrenNoContext(newBottomJoin, c, null);
}).toRule(RuleType.LOGICAL_JOIN_LOGICAL_SEMI_JOIN_TRANSPOSE_RIGHT)
);
}

View File

@ -55,8 +55,8 @@ public class LogicalJoinSemiJoinTransposeProject implements ExplorationRuleFacto
GroupPlan c = topJoin.right();
// Discard this project, because it is useless.
Plan newBottomJoin = topJoin.withChildrenNoContext(a, c);
Plan newTopJoin = bottomJoin.withChildrenNoContext(newBottomJoin, b);
Plan newBottomJoin = topJoin.withChildrenNoContext(a, c, null);
Plan newTopJoin = bottomJoin.withChildrenNoContext(newBottomJoin, b, null);
return CBOUtils.projectOrSelf(ImmutableList.copyOf(topJoin.getOutput()),
newTopJoin);
}).toRule(RuleType.LOGICAL_JOIN_LOGICAL_SEMI_JOIN_TRANSPOSE_LEFT_PROJECT),
@ -76,8 +76,8 @@ public class LogicalJoinSemiJoinTransposeProject implements ExplorationRuleFacto
GroupPlan c = bottomJoin.right();
// Discard this project, because it is useless.
Plan newBottomJoin = topJoin.withChildrenNoContext(a, b);
Plan newTopJoin = bottomJoin.withChildrenNoContext(newBottomJoin, c);
Plan newBottomJoin = topJoin.withChildrenNoContext(a, b, null);
Plan newTopJoin = bottomJoin.withChildrenNoContext(newBottomJoin, c, null);
return CBOUtils.projectOrSelf(ImmutableList.copyOf(topJoin.getOutput()),
newTopJoin);
}).toRule(RuleType.LOGICAL_JOIN_LOGICAL_SEMI_JOIN_TRANSPOSE_RIGHT_PROJECT)

View File

@ -84,9 +84,9 @@ public class OuterJoinAssoc extends OneExplorationRuleFactory {
}
}
LogicalJoin newBottomJoin = topJoin.withChildrenNoContext(b, c);
LogicalJoin newBottomJoin = topJoin.withChildrenNoContext(b, c, null);
newBottomJoin.getJoinReorderContext().copyFrom(bottomJoin.getJoinReorderContext());
LogicalJoin newTopJoin = bottomJoin.withChildrenNoContext(a, newBottomJoin);
LogicalJoin newTopJoin = bottomJoin.withChildrenNoContext(a, newBottomJoin, null);
newTopJoin.getJoinReorderContext().copyFrom(topJoin.getJoinReorderContext());
setReorderContext(newTopJoin, newBottomJoin);
return newTopJoin;

View File

@ -86,7 +86,7 @@ public class OuterJoinAssocProject extends OneExplorationRuleFactory {
}
/* ********** new Plan ********** */
LogicalJoin newBottomJoin = topJoin.withChildrenNoContext(b, c);
LogicalJoin newBottomJoin = topJoin.withChildrenNoContext(b, c, null);
newBottomJoin.getJoinReorderContext().copyFrom(bottomJoin.getJoinReorderContext());
Set<ExprId> topUsedExprIds = new HashSet<>(topJoin.getOutputExprIdSet());
@ -95,7 +95,7 @@ public class OuterJoinAssocProject extends OneExplorationRuleFactory {
Plan left = CBOUtils.newProject(topUsedExprIds, a);
Plan right = CBOUtils.newProject(topUsedExprIds, newBottomJoin);
LogicalJoin newTopJoin = bottomJoin.withChildrenNoContext(left, right);
LogicalJoin newTopJoin = bottomJoin.withChildrenNoContext(left, right, null);
newTopJoin.getJoinReorderContext().copyFrom(topJoin.getJoinReorderContext());
OuterJoinAssoc.setReorderContext(newTopJoin, newBottomJoin);

View File

@ -71,12 +71,12 @@ public class OuterJoinLAsscom extends OneExplorationRuleFactory {
GroupPlan b = bottomJoin.right();
GroupPlan c = topJoin.right();
LogicalJoin newBottomJoin = topJoin.withChildrenNoContext(a, c);
LogicalJoin newBottomJoin = topJoin.withChildrenNoContext(a, c, null);
newBottomJoin.getJoinReorderContext().copyFrom(bottomJoin.getJoinReorderContext());
newBottomJoin.getJoinReorderContext().setHasLAsscom(false);
newBottomJoin.getJoinReorderContext().setHasCommute(false);
LogicalJoin newTopJoin = bottomJoin.withChildrenNoContext(newBottomJoin, b);
LogicalJoin newTopJoin = bottomJoin.withChildrenNoContext(newBottomJoin, b, null);
newTopJoin.getJoinReorderContext().copyFrom(topJoin.getJoinReorderContext());
newTopJoin.getJoinReorderContext().setHasLAsscom(true);

View File

@ -66,7 +66,7 @@ public class OuterJoinLAsscomProject extends OneExplorationRuleFactory {
GroupPlan c = topJoin.right();
/* ********** new Plan ********** */
LogicalJoin newBottomJoin = topJoin.withChildrenNoContext(a, c);
LogicalJoin newBottomJoin = topJoin.withChildrenNoContext(a, c, null);
newBottomJoin.getJoinReorderContext().copyFrom(bottomJoin.getJoinReorderContext());
newBottomJoin.getJoinReorderContext().setHasLAsscom(false);
newBottomJoin.getJoinReorderContext().setHasCommute(false);
@ -77,7 +77,7 @@ public class OuterJoinLAsscomProject extends OneExplorationRuleFactory {
Plan left = CBOUtils.newProject(topUsedExprIds, newBottomJoin);
Plan right = CBOUtils.newProject(topUsedExprIds, b);
LogicalJoin newTopJoin = bottomJoin.withChildrenNoContext(left, right);
LogicalJoin newTopJoin = bottomJoin.withChildrenNoContext(left, right, null);
newTopJoin.getJoinReorderContext().copyFrom(topJoin.getJoinReorderContext());
newTopJoin.getJoinReorderContext().setHasLAsscom(true);

View File

@ -70,8 +70,8 @@ public class SemiJoinSemiJoinTranspose extends OneExplorationRuleFactory {
GroupPlan b = bottomJoin.right();
GroupPlan c = topJoin.right();
Plan newBottomJoin = topJoin.withChildrenNoContext(a, c);
Plan newTopJoin = bottomJoin.withChildrenNoContext(newBottomJoin, b);
Plan newBottomJoin = topJoin.withChildrenNoContext(a, c, null);
Plan newTopJoin = bottomJoin.withChildrenNoContext(newBottomJoin, b, null);
return newTopJoin;
}).toRule(RuleType.LOGICAL_SEMI_JOIN_SEMI_JOIN_TRANSPOSE);
}

View File

@ -72,13 +72,13 @@ public class SemiJoinSemiJoinTransposeProject extends OneExplorationRuleFactory
acProjects.add(slot);
}
});
LogicalJoin newBottomSemi = topSemi.withChildrenNoContext(a, c);
LogicalJoin newBottomSemi = topSemi.withChildrenNoContext(a, c, null);
newBottomSemi.getJoinReorderContext().copyFrom(bottomSemi.getJoinReorderContext());
newBottomSemi.getJoinReorderContext().setHasCommute(false);
newBottomSemi.getJoinReorderContext().setHasLAsscom(false);
LogicalProject acProject = new LogicalProject<>(Lists.newArrayList(acProjects), newBottomSemi);
LogicalJoin newTopSemi = bottomSemi.withChildrenNoContext(acProject, b);
LogicalJoin newTopSemi = bottomSemi.withChildrenNoContext(acProject, b, null);
newTopSemi.getJoinReorderContext().copyFrom(topSemi.getJoinReorderContext());
newTopSemi.getJoinReorderContext().setHasLAsscom(true);
return CBOUtils.projectOrSelf(ImmutableList.copyOf(topSemi.getOutput()), newTopSemi);

View File

@ -197,7 +197,8 @@ public class ExpressionRewrite implements RewriteRuleFactory {
return new LogicalJoin<>(join.getJoinType(), newHashJoinConjuncts.second,
newOtherJoinConjuncts.second, newMarkJoinConjuncts.second,
join.getDistributeHint(), join.getMarkJoinSlotReference(), join.children());
join.getDistributeHint(), join.getMarkJoinSlotReference(), join.children(),
join.getJoinReorderContext());
}).toRule(RuleType.REWRITE_JOIN_EXPRESSION);
}

View File

@ -67,6 +67,6 @@ public class AdjustConjunctsReturnType extends DefaultPlanRewriter<Void> impleme
List<Expression> markConjuncts = join.getMarkJoinConjuncts().stream()
.map(expr -> TypeCoercionUtils.castIfNotSameType(expr, BooleanType.INSTANCE))
.collect(Collectors.toList());
return join.withJoinConjuncts(hashConjuncts, otherConjuncts, markConjuncts);
return join.withJoinConjuncts(hashConjuncts, otherConjuncts, markConjuncts, join.getJoinReorderContext());
}
}

View File

@ -133,7 +133,8 @@ public class AdjustNullable extends DefaultPlanRewriter<Map<ExprId, Slot>> imple
markConjuncts = updateExpressions(join.getMarkJoinConjuncts(), replaceMap);
}
List<Expression> otherConjuncts = updateExpressions(join.getOtherJoinConjuncts(), replaceMap);
return join.withJoinConjuncts(hashConjuncts, otherConjuncts, markConjuncts).recomputeLogicalProperties();
return join.withJoinConjuncts(hashConjuncts, otherConjuncts, markConjuncts,
join.getJoinReorderContext()).recomputeLogicalProperties();
}
@Override

View File

@ -39,12 +39,12 @@ public class ConvertInnerOrCrossJoin implements RewriteRuleFactory {
innerLogicalJoin()
.when(join -> join.getHashJoinConjuncts().isEmpty() && join.getOtherJoinConjuncts().isEmpty()
&& join.getMarkJoinConjuncts().isEmpty())
.then(join -> join.withJoinType(JoinType.CROSS_JOIN))
.then(join -> join.withJoinType(JoinType.CROSS_JOIN, join.getJoinReorderContext()))
.toRule(RuleType.INNER_TO_CROSS_JOIN),
crossLogicalJoin()
.when(join -> !join.getHashJoinConjuncts().isEmpty() || !join.getOtherJoinConjuncts().isEmpty()
|| !join.getMarkJoinConjuncts().isEmpty())
.then(join -> join.withJoinType(JoinType.INNER_JOIN))
.then(join -> join.withJoinType(JoinType.INNER_JOIN, join.getJoinReorderContext()))
.toRule(RuleType.CROSS_TO_INNER_JOIN)
);
}

View File

@ -84,7 +84,7 @@ public class ConvertOuterJoinToAntiJoin extends OneRewriteRuleFactory {
.flatMap(p -> p.getInputSlots().stream())
.anyMatch(join.right().getOutputSet()::contains);
if (!containRightSlot) {
res = join.withJoinType(JoinType.LEFT_ANTI_JOIN);
res = join.withJoinType(JoinType.LEFT_ANTI_JOIN, join.getJoinReorderContext());
res = predicates.isEmpty() ? res : filter.withConjuncts(predicates).withChildren(res);
res = project.withChildren(res);
}
@ -98,7 +98,7 @@ public class ConvertOuterJoinToAntiJoin extends OneRewriteRuleFactory {
.flatMap(p -> p.getInputSlots().stream())
.anyMatch(join.left().getOutputSet()::contains);
if (!containLeftSlot) {
res = join.withJoinType(JoinType.RIGHT_ANTI_JOIN);
res = join.withJoinType(JoinType.RIGHT_ANTI_JOIN, join.getJoinReorderContext());
res = predicates.isEmpty() ? res : filter.withConjuncts(predicates).withChildren(res);
res = project.withChildren(res);
}

View File

@ -44,7 +44,8 @@ public class EliminateDedupJoinCondition extends OneRewriteRuleFactory {
&& dedupMarkJoinConjuncts.size() == join.getMarkJoinConjuncts().size()) {
return null;
}
return join.withJoinConjuncts(dedupHashJoinConjuncts, dedupOtherJoinConjuncts, dedupMarkJoinConjuncts);
return join.withJoinConjuncts(dedupHashJoinConjuncts, dedupOtherJoinConjuncts, dedupMarkJoinConjuncts,
join.getJoinReorderContext());
}).toRule(RuleType.ELIMINATE_DEDUP_JOIN_CONDITION);
}
}

View File

@ -47,7 +47,8 @@ public class EliminateJoinCondition extends OneRewriteRuleFactory {
&& markJoinConjuncts.size() == join.getMarkJoinConjuncts().size()) {
return null;
}
return join.withJoinConjuncts(hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts);
return join.withJoinConjuncts(hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts,
join.getJoinReorderContext());
}).toRule(RuleType.ELIMINATE_JOIN_CONDITION);
}
}

View File

@ -54,6 +54,6 @@ public class EliminateMarkJoin extends OneRewriteRuleFactory {
newHashConjuncts.addAll(join.getHashJoinConjuncts());
newHashConjuncts.addAll(join.getMarkJoinConjuncts());
return join.withJoinConjuncts(newHashConjuncts.build(), join.getOtherJoinConjuncts(),
ExpressionUtils.EMPTY_CONDITION);
ExpressionUtils.EMPTY_CONDITION, join.getJoinReorderContext());
}
}

View File

@ -70,7 +70,8 @@ public class EliminateNotNull implements RewriteRuleFactory {
if (newOtherJoinConjuncts.size() == join.getOtherJoinConjuncts().size()) {
return null;
}
return join.withJoinConjuncts(join.getHashJoinConjuncts(), newOtherJoinConjuncts);
return join.withJoinConjuncts(join.getHashJoinConjuncts(), newOtherJoinConjuncts,
join.getJoinReorderContext());
})
.toRule(RuleType.ELIMINATE_NOT_NULL)
);

View File

@ -36,7 +36,7 @@ public class EliminateNullAwareLeftAntiJoin extends OneRewriteRuleFactory {
antiJoin.getOtherJoinConjuncts().stream()),
antiJoin.getMarkJoinConjuncts().stream())
.noneMatch(expression -> expression.nullable())) {
return antiJoin.withJoinType(JoinType.LEFT_ANTI_JOIN);
return antiJoin.withJoinType(JoinType.LEFT_ANTI_JOIN, antiJoin.getJoinReorderContext());
} else {
return null;
}

View File

@ -106,9 +106,9 @@ public class EliminateOuterJoin extends OneRewriteRuleFactory {
}
if (conjunctsChanged) {
return filter.withConjuncts(conjuncts.stream().collect(ImmutableSet.toImmutableSet()))
.withChildren(join.withJoinType(newJoinType));
.withChildren(join.withJoinType(newJoinType, join.getJoinReorderContext()));
}
return filter.withChildren(join.withJoinType(newJoinType));
return filter.withChildren(join.withJoinType(newJoinType, join.getJoinReorderContext()));
}).toRule(RuleType.ELIMINATE_OUTER_JOIN);
}

View File

@ -96,13 +96,13 @@ public class ExistsApplyToJoin extends OneRewriteRuleFactory {
correlationFilter.map(ExpressionUtils::extractConjunction).orElse(ExpressionUtils.EMPTY_CONDITION),
new DistributeHint(DistributeType.NONE),
apply.getMarkJoinSlotReference(),
apply.children());
apply.children(), null);
} else {
return new LogicalJoin<>(JoinType.LEFT_SEMI_JOIN, ExpressionUtils.EMPTY_CONDITION,
correlationFilter.map(ExpressionUtils::extractConjunction).orElse(ExpressionUtils.EMPTY_CONDITION),
new DistributeHint(DistributeType.NONE),
apply.getMarkJoinSlotReference(),
apply.children());
apply.children(), null);
}
}
@ -123,7 +123,7 @@ public class ExistsApplyToJoin extends OneRewriteRuleFactory {
ExpressionUtils.EMPTY_CONDITION,
new DistributeHint(DistributeType.NONE),
unapply.getMarkJoinSlotReference(),
(LogicalPlan) unapply.left(), newAgg);
(LogicalPlan) unapply.left(), newAgg, null);
return new LogicalFilter<>(ImmutableSet.of(new EqualTo(newAgg.getOutput().get(0),
new IntegerLiteral(0))), newJoin);
}
@ -133,6 +133,6 @@ public class ExistsApplyToJoin extends OneRewriteRuleFactory {
return new LogicalJoin<>(JoinType.CROSS_JOIN, ExpressionUtils.EMPTY_CONDITION,
ExpressionUtils.EMPTY_CONDITION,
new DistributeHint(DistributeType.NONE), unapply.getMarkJoinSlotReference(),
(LogicalPlan) unapply.left(), newLimit);
(LogicalPlan) unapply.left(), newLimit, null);
}
}

View File

@ -43,7 +43,7 @@ public class ExtractFilterFromCrossJoin extends OneRewriteRuleFactory {
ExpressionUtils.EMPTY_CONDITION, ExpressionUtils.EMPTY_CONDITION,
join.getMarkJoinConjuncts(),
join.getDistributeHint(),
join.getMarkJoinSlotReference(), join.children());
join.getMarkJoinSlotReference(), join.children(), join.getJoinReorderContext());
Set<Expression> predicates = Stream.concat(join.getHashJoinConjuncts().stream(),
join.getOtherJoinConjuncts().stream())
.collect(ImmutableSet.toImmutableSet());

View File

@ -76,7 +76,7 @@ public class FindHashConditionForJoin extends OneRewriteRuleFactory {
join.getMarkJoinConjuncts(),
join.getDistributeHint(),
join.getMarkJoinSlotReference(),
join.children());
join.children(), join.getJoinReorderContext());
}).toRule(RuleType.FIND_HASH_CONDITION_FOR_JOIN);
}
}

View File

@ -90,7 +90,7 @@ public class InApplyToJoin extends OneRewriteRuleFactory {
return new LogicalJoin<>(JoinType.LEFT_SEMI_JOIN, Lists.newArrayList(),
Lists.newArrayList(expr),
new DistributeHint(DistributeType.NONE),
apply.left(), agg);
apply.left(), agg, null);
}
//in-predicate to equal
@ -119,7 +119,7 @@ public class InApplyToJoin extends OneRewriteRuleFactory {
inSubquery.isNot() ? JoinType.LEFT_ANTI_JOIN : JoinType.LEFT_SEMI_JOIN,
Lists.newArrayList(), joinConjuncts, markConjuncts,
new DistributeHint(DistributeType.NONE), apply.getMarkJoinSlotReference(),
apply.children());
apply.children(), null);
} else {
if (apply.isCorrelated()) {
if (inSubquery.isNot()) {
@ -141,12 +141,12 @@ public class InApplyToJoin extends OneRewriteRuleFactory {
? JoinType.NULL_AWARE_LEFT_ANTI_JOIN
: JoinType.LEFT_ANTI_JOIN,
Lists.newArrayList(), conjuncts, new DistributeHint(DistributeType.NONE),
apply.getMarkJoinSlotReference(), apply.children());
apply.getMarkJoinSlotReference(), apply.children(), null);
} else {
return new LogicalJoin<>(JoinType.LEFT_SEMI_JOIN, Lists.newArrayList(),
conjuncts,
new DistributeHint(DistributeType.NONE), apply.getMarkJoinSlotReference(),
apply.children());
apply.children(), null);
}
}
}).toRule(RuleType.IN_APPLY_TO_JOIN);

View File

@ -178,7 +178,7 @@ public class OrExpansion extends OneExplorationRuleFactory {
hashCond = hashCond.rewriteUp(s -> replaced.containsKey(s) ? replaced.get(s) : s);
Plan newPlan = new LogicalJoin<>(JoinType.LEFT_ANTI_JOIN, Lists.newArrayList(hashCond),
otherConditions, originJoin.getDistributeHint(),
originJoin.getMarkJoinSlotReference(), left, right);
originJoin.getMarkJoinSlotReference(), left, right, null);
if (hashCond.children().stream().anyMatch(e -> !(e instanceof Slot))) {
Plan normalizedPlan = PushDownExpressionsInHashCondition.pushDownHashExpression(
(LogicalJoin<? extends Plan, ? extends Plan>) newPlan);
@ -195,7 +195,7 @@ public class OrExpansion extends OneExplorationRuleFactory {
hashCond = hashCond.rewriteUp(s -> newReplaced.containsKey(s) ? newReplaced.get(s) : s);
newPlan = new LogicalJoin<>(JoinType.LEFT_ANTI_JOIN, Lists.newArrayList(hashCond),
new ArrayList<>(), originJoin.getDistributeHint(),
originJoin.getMarkJoinSlotReference(), newPlan, newRight);
originJoin.getMarkJoinSlotReference(), newPlan, newRight, null);
if (hashCond.children().stream().anyMatch(e -> !(e instanceof Slot))) {
newPlan = PushDownExpressionsInHashCondition.pushDownHashExpression(
(LogicalJoin<? extends Plan, ? extends Plan>) newPlan);
@ -255,7 +255,7 @@ public class OrExpansion extends OneExplorationRuleFactory {
LogicalJoin<? extends Plan, ? extends Plan> newJoin = new LogicalJoin<>(
JoinType.INNER_JOIN, hashCond, otherCond, join.getDistributeHint(),
join.getMarkJoinSlotReference(), left, right);
join.getMarkJoinSlotReference(), left, right, null);
if (newJoin.getHashJoinConjuncts().stream()
.anyMatch(equalTo -> equalTo.children().stream().anyMatch(e -> !(e instanceof Slot)))) {
Plan plan = PushDownExpressionsInHashCondition.pushDownHashExpression(newJoin);

View File

@ -525,7 +525,7 @@ public class PullUpJoinFromUnionAll extends OneRewriteRuleFactory {
new DistributeHint(DistributeType.NONE),
Optional.empty(),
newUnionNode,
pullUpTable);
pullUpTable, null);
}
private LogicalUnion makeNewUnionNode(LogicalUnion origUnion,
@ -637,7 +637,7 @@ public class PullUpJoinFromUnionAll extends OneRewriteRuleFactory {
join.getOtherJoinConjuncts(),
new DistributeHint(DistributeType.NONE),
Optional.empty(),
leftChild, rightChild);
leftChild, rightChild, null);
}
}

View File

@ -98,7 +98,8 @@ public class PushDownAliasThroughJoin extends OneRewriteRuleFactory {
List<Expression> newOther = replaceJoinConjuncts(join.getOtherJoinConjuncts(), replaceMap);
List<Expression> newMark = replaceJoinConjuncts(join.getMarkJoinConjuncts(), replaceMap);
Plan newJoin = join.withConjunctsChildren(newHash, newOther, newMark, left, right);
Plan newJoin = join.withConjunctsChildren(newHash, newOther, newMark, left, right,
join.getJoinReorderContext());
return project.withProjectsAndChild(newProjects, newJoin);
}).toRule(RuleType.PUSH_DOWN_ALIAS_THROUGH_JOIN);
}

View File

@ -120,7 +120,7 @@ public class PushDownExpressionsInHashCondition extends OneRewriteRuleFactory {
return join.withHashJoinConjunctsAndChildren(
newHashConjuncts,
createChildProjectPlan(join.left(), join, leftProjectExprs),
createChildProjectPlan(join.right(), join, rightProjectExprs));
createChildProjectPlan(join.right(), join, rightProjectExprs), join.getJoinReorderContext());
}

View File

@ -141,7 +141,8 @@ public class PushDownFilterThroughJoin extends OneRewriteRuleFactory {
join.getDistributeHint(),
join.getMarkJoinSlotReference(),
PlanUtils.filterOrSelf(leftPredicates, join.left()),
PlanUtils.filterOrSelf(rightPredicates, join.right())));
PlanUtils.filterOrSelf(rightPredicates, join.right()),
join.getJoinReorderContext()));
}).toRule(RuleType.PUSH_DOWN_FILTER_THROUGH_JOIN);
}

View File

@ -91,7 +91,7 @@ public class PushDownJoinOtherCondition extends OneRewriteRuleFactory {
return new LogicalJoin<>(join.getJoinType(), join.getHashJoinConjuncts(),
remainingOther, join.getMarkJoinConjuncts(), join.getDistributeHint(),
join.getMarkJoinSlotReference(), left, right);
join.getMarkJoinSlotReference(), left, right, join.getJoinReorderContext());
}).toRule(RuleType.PUSH_DOWN_JOIN_OTHER_CONDITION);
}

View File

@ -49,7 +49,7 @@ public class PushFilterInsideJoin extends OneRewriteRuleFactory {
otherConditions.addAll(join.getOtherJoinConjuncts());
return new LogicalJoin<>(join.getJoinType(), join.getHashJoinConjuncts(),
otherConditions, join.getDistributeHint(), join.getMarkJoinSlotReference(),
join.children());
join.children(), join.getJoinReorderContext());
}).toRule(RuleType.PUSH_FILTER_INSIDE_JOIN);
}
}

View File

@ -79,7 +79,9 @@ public class ReorderJoin extends OneRewriteRuleFactory {
.whenNot(filter -> filter.child() instanceof LogicalJoin
&& ((LogicalJoin<?, ?>) filter.child()).isMarkJoin())
.thenApply(ctx -> {
if (ctx.statementContext.getConnectContext().getSessionVariable().isDisableJoinReorder()) {
if (ctx.statementContext.getConnectContext().getSessionVariable().isDisableJoinReorder()
|| ctx.cascadesContext.isLeadingDisableJoinReorder()
|| ((LogicalJoin<?, ?>) ctx.root.child()).isLeadingJoin()) {
return null;
}
LogicalFilter<Plan> filter = ctx.root;
@ -286,7 +288,7 @@ public class ReorderJoin extends OneRewriteRuleFactory {
new DistributeHint(DistributeType.fromRightPlanHintType(
planToHintType.getOrDefault(right, JoinDistributeType.NONE))),
Optional.empty(),
left, right));
left, right, null));
}
// following this multiJoin just contain INNER/CROSS.
@ -362,7 +364,7 @@ public class ReorderJoin extends OneRewriteRuleFactory {
new DistributeHint(DistributeType.fromRightPlanHintType(
planToHintType.getOrDefault(candidate, JoinDistributeType.NONE))),
Optional.empty(),
left, candidate);
left, candidate, null);
}
}
// All { left -> one in [candidates] } is CrossJoin
@ -375,7 +377,7 @@ public class ReorderJoin extends OneRewriteRuleFactory {
new DistributeHint(DistributeType.fromRightPlanHintType(
planToHintType.getOrDefault(right, JoinDistributeType.NONE))),
Optional.empty(),
left, right);
left, right, null);
}
private boolean nonJoinAndNonFilter(Plan plan) {

View File

@ -65,7 +65,7 @@ public class ScalarApplyToJoin extends OneRewriteRuleFactory {
ExpressionUtils.EMPTY_CONDITION,
new DistributeHint(DistributeType.NONE),
apply.getMarkJoinSlotReference(),
(LogicalPlan) apply.left(), assertNumRows);
(LogicalPlan) apply.left(), assertNumRows, null);
}
private Plan correlatedToJoin(LogicalApply apply) {
@ -88,6 +88,6 @@ public class ScalarApplyToJoin extends OneRewriteRuleFactory {
ExpressionUtils.extractConjunction(correlationFilter.get()),
new DistributeHint(DistributeType.NONE),
apply.getMarkJoinSlotReference(),
apply.children());
apply.children(), null);
}
}

View File

@ -33,9 +33,10 @@ public class SemiJoinCommute extends OneRewriteRuleFactory {
return logicalJoin()
.when(join -> join.getJoinType().isRightSemiOrAntiJoin() || join.getJoinType().isRightOuterJoin())
.whenNot(join -> ConnectContext.get().getSessionVariable().isDisableJoinReorder())
.whenNot(join -> join.isLeadingJoin())
.whenNot(LogicalJoin::hasDistributeHint)
.whenNot(LogicalJoin::isMarkJoin)
.then(join -> join.withTypeChildren(join.getJoinType().swap(), join.right(), join.left()))
.then(join -> join.withTypeChildren(join.getJoinType().swap(), join.right(), join.left(), null))
.toRule(RuleType.LOGICAL_SEMI_JOIN_COMMUTE);
}
}

View File

@ -45,6 +45,7 @@ public class TransposeSemiJoinLogicalJoin extends OneRewriteRuleFactory {
|| topJoin.left().getJoinType().isRightOuterJoin())))
.whenNot(topJoin -> topJoin.hasDistributeHint() || topJoin.left().hasDistributeHint())
.whenNot(LogicalJoin::isMarkJoin)
.whenNot(topJoin -> topJoin.isLeadingJoin() || topJoin.left().isLeadingJoin())
.then(topSemiJoin -> {
LogicalJoin<Plan, Plan> bottomJoin = topSemiJoin.left();
Plan a = bottomJoin.left();

View File

@ -50,6 +50,7 @@ public class TransposeSemiJoinLogicalJoinProject extends OneRewriteRuleFactory {
.when(join -> join.left().isAllSlots())
.whenNot(join -> join.hasDistributeHint() || join.left().child().hasDistributeHint())
.whenNot(join -> join.isMarkJoin() || join.left().child().isMarkJoin())
.whenNot(topJoin -> topJoin.isLeadingJoin() || topJoin.left().child().isLeadingJoin())
.when(join -> join.left().getProjects().stream().allMatch(expr -> expr instanceof Slot))
.then(topSemiJoin -> {
LogicalProject<LogicalJoin<Plan, Plan>> project = topSemiJoin.left();

View File

@ -341,7 +341,7 @@ public class LogicalPlanDeepCopier extends DefaultPlanRewriter<DeepCopierContext
.map(c -> ExpressionDeepCopier.INSTANCE.deepCopy(c, context))
.collect(ImmutableList.toImmutableList());
return new LogicalJoin<>(join.getJoinType(), hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts,
join.getDistributeHint(), join.getMarkJoinSlotReference(), children);
join.getDistributeHint(), join.getMarkJoinSlotReference(), children, join.getJoinReorderContext());
}
@Override

View File

@ -84,76 +84,69 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
private DistributeHint hint;
public LogicalJoin(JoinType joinType, LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) {
public LogicalJoin(JoinType joinType, LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild,
JoinReorderContext otherJoinReorderContext) {
this(joinType, ExpressionUtils.EMPTY_CONDITION, ExpressionUtils.EMPTY_CONDITION,
ExpressionUtils.EMPTY_CONDITION, new DistributeHint(DistributeType.NONE),
Optional.empty(), Optional.empty(), Optional.empty(),
ImmutableList.of(leftChild, rightChild), null);
ImmutableList.of(leftChild, rightChild), otherJoinReorderContext);
}
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts,
LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) {
LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild, JoinReorderContext otherJoinReorderContext) {
this(joinType, hashJoinConjuncts, ExpressionUtils.EMPTY_CONDITION,
ExpressionUtils.EMPTY_CONDITION, new DistributeHint(DistributeType.NONE),
Optional.empty(), Optional.empty(), Optional.empty(),
ImmutableList.of(leftChild, rightChild), null);
ImmutableList.of(leftChild, rightChild), otherJoinReorderContext);
}
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts, List<Expression> otherJoinConjuncts,
LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) {
LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild, JoinReorderContext otherJoinReorderContext) {
this(joinType, hashJoinConjuncts, otherJoinConjuncts, ExpressionUtils.EMPTY_CONDITION,
new DistributeHint(DistributeType.NONE), Optional.empty(),
Optional.empty(), Optional.empty(), ImmutableList.of(leftChild, rightChild), null);
Optional.empty(), Optional.empty(), ImmutableList.of(leftChild, rightChild), otherJoinReorderContext);
}
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts,
List<Expression> otherJoinConjuncts, DistributeHint hint, LEFT_CHILD_TYPE leftChild,
RIGHT_CHILD_TYPE rightChild) {
RIGHT_CHILD_TYPE rightChild, JoinReorderContext otherJoinReorderContext) {
this(joinType, hashJoinConjuncts, otherJoinConjuncts, ExpressionUtils.EMPTY_CONDITION, hint,
Optional.empty(), Optional.empty(), Optional.empty(),
ImmutableList.of(leftChild, rightChild), null);
ImmutableList.of(leftChild, rightChild), otherJoinReorderContext);
}
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts,
List<Expression> otherJoinConjuncts, DistributeHint hint,
Optional<MarkJoinSlotReference> markJoinSlotReference, LEFT_CHILD_TYPE leftChild,
RIGHT_CHILD_TYPE rightChild) {
RIGHT_CHILD_TYPE rightChild, JoinReorderContext otherJoinReorderContext) {
this(joinType, hashJoinConjuncts, otherJoinConjuncts, ExpressionUtils.EMPTY_CONDITION, hint,
markJoinSlotReference, Optional.empty(), Optional.empty(),
ImmutableList.of(leftChild, rightChild), null);
ImmutableList.of(leftChild, rightChild), otherJoinReorderContext);
}
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts,
List<Expression> otherJoinConjuncts, List<Expression> markJoinConjuncts, DistributeHint hint,
Optional<MarkJoinSlotReference> markJoinSlotReference, LEFT_CHILD_TYPE leftChild,
RIGHT_CHILD_TYPE rightChild) {
RIGHT_CHILD_TYPE rightChild, JoinReorderContext joinReorderContext) {
this(joinType, hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts, hint,
markJoinSlotReference, Optional.empty(), Optional.empty(),
ImmutableList.of(leftChild, rightChild), null);
}
public LogicalJoin(long bitmap, JoinType joinType, List<Expression> hashJoinConjuncts,
List<Expression> otherJoinConjuncts, DistributeHint hint,
Optional<MarkJoinSlotReference> markJoinSlotReference, LEFT_CHILD_TYPE leftChild,
RIGHT_CHILD_TYPE rightChild) {
this(joinType, hashJoinConjuncts, otherJoinConjuncts, ExpressionUtils.EMPTY_CONDITION, hint,
markJoinSlotReference, Optional.empty(), Optional.empty(),
ImmutableList.of(leftChild, rightChild), null);
this.bitmap = LongBitmap.or(this.bitmap, bitmap);
ImmutableList.of(leftChild, rightChild), joinReorderContext);
}
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts,
List<Expression> otherJoinConjuncts, DistributeHint hint,
Optional<MarkJoinSlotReference> markJoinSlotReference, List<Plan> children) {
Optional<MarkJoinSlotReference> markJoinSlotReference, List<Plan> children,
JoinReorderContext otherJoinReorderContext) {
this(joinType, hashJoinConjuncts, otherJoinConjuncts, ExpressionUtils.EMPTY_CONDITION, hint,
markJoinSlotReference, Optional.empty(), Optional.empty(), children, null);
markJoinSlotReference, Optional.empty(), Optional.empty(), children, otherJoinReorderContext);
}
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts,
List<Expression> otherJoinConjuncts, List<Expression> markJoinConjuncts, DistributeHint hint,
Optional<MarkJoinSlotReference> markJoinSlotReference, List<Plan> children) {
Optional<MarkJoinSlotReference> markJoinSlotReference, List<Plan> children,
JoinReorderContext otherJoinReorderContext) {
this(joinType, hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts, hint,
markJoinSlotReference, Optional.empty(), Optional.empty(), children, null);
markJoinSlotReference, Optional.empty(), Optional.empty(), children, otherJoinReorderContext);
}
private LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts,
@ -177,7 +170,7 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
public LogicalJoin<? extends Plan, ? extends Plan> swap() {
return withTypeChildren(getJoinType().swap(),
right(), left());
right(), left(), null);
}
public List<Expression> getOtherJoinConjuncts() {
@ -256,6 +249,10 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
return markJoinSlotReference.isPresent();
}
public boolean isLeadingJoin() {
return joinReorderContext.isLeadingJoin();
}
public List<Expression> getMarkJoinConjuncts() {
return markJoinConjuncts;
}
@ -370,63 +367,67 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
joinReorderContext);
}
public LogicalJoin<Plan, Plan> withChildrenNoContext(Plan left, Plan right) {
public LogicalJoin<Plan, Plan> withChildrenNoContext(Plan left, Plan right,
JoinReorderContext otherJoinReorderContext) {
return new LogicalJoin<>(joinType, hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts,
hint, markJoinSlotReference, Optional.empty(), Optional.empty(),
ImmutableList.of(left, right), null);
ImmutableList.of(left, right), otherJoinReorderContext);
}
/**
* Using in binding using join, and must set logical properties to empty.
*/
public LogicalJoin<Plan, Plan> withJoinConjuncts(List<Expression> hashJoinConjuncts,
List<Expression> otherJoinConjuncts) {
List<Expression> otherJoinConjuncts, JoinReorderContext otherJoinReorderContext) {
return new LogicalJoin<>(joinType, hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts,
hint, markJoinSlotReference, Optional.empty(), Optional.empty(),
children, null);
children, otherJoinReorderContext);
}
public LogicalJoin<Plan, Plan> withJoinConjuncts(List<Expression> hashJoinConjuncts,
List<Expression> otherJoinConjuncts,
List<Expression> markJoinConjuncts) {
List<Expression> markJoinConjuncts,
JoinReorderContext otherJoinReorderContext) {
return new LogicalJoin<>(joinType, hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts,
hint, markJoinSlotReference, Optional.empty(), Optional.of(getLogicalProperties()),
children, null);
children, otherJoinReorderContext);
}
public LogicalJoin<Plan, Plan> withHashJoinConjunctsAndChildren(
List<Expression> hashJoinConjuncts, Plan left, Plan right) {
List<Expression> hashJoinConjuncts, Plan left, Plan right, JoinReorderContext otherJoinReorderContext) {
Preconditions.checkArgument(children.size() == 2);
return new LogicalJoin<>(joinType, hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts,
hint, markJoinSlotReference, Optional.empty(), Optional.empty(),
ImmutableList.of(left, right), null);
ImmutableList.of(left, right), otherJoinReorderContext);
}
public LogicalJoin<Plan, Plan> withConjunctsChildren(List<Expression> hashJoinConjuncts,
List<Expression> otherJoinConjuncts, Plan left, Plan right) {
List<Expression> otherJoinConjuncts, Plan left, Plan right, JoinReorderContext otherJoinReorderContext) {
return new LogicalJoin<>(joinType, hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts,
hint, markJoinSlotReference, Optional.empty(), Optional.empty(),
ImmutableList.of(left, right), null);
ImmutableList.of(left, right), otherJoinReorderContext);
}
public LogicalJoin<Plan, Plan> withConjunctsChildren(List<Expression> hashJoinConjuncts,
List<Expression> otherJoinConjuncts,
List<Expression> markJoinConjuncts, Plan left, Plan right) {
List<Expression> markJoinConjuncts, Plan left, Plan right,
JoinReorderContext otherJoinReorderContext) {
return new LogicalJoin<>(joinType, hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts,
hint, markJoinSlotReference, Optional.empty(), Optional.empty(),
ImmutableList.of(left, right), null);
ImmutableList.of(left, right), otherJoinReorderContext);
}
public LogicalJoin<Plan, Plan> withJoinType(JoinType joinType) {
public LogicalJoin<Plan, Plan> withJoinType(JoinType joinType, JoinReorderContext otherJoinReorderContext) {
return new LogicalJoin<>(joinType, hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts,
hint, markJoinSlotReference, Optional.empty(), Optional.empty(),
children, null);
children, otherJoinReorderContext);
}
public LogicalJoin<Plan, Plan> withTypeChildren(JoinType joinType, Plan left, Plan right) {
public LogicalJoin<Plan, Plan> withTypeChildren(JoinType joinType, Plan left, Plan right,
JoinReorderContext otherJoinReorderContext) {
return new LogicalJoin<>(joinType, hashJoinConjuncts, otherJoinConjuncts, markJoinConjuncts,
hint, markJoinSlotReference, Optional.empty(), Optional.empty(),
ImmutableList.of(left, right), null);
ImmutableList.of(left, right), otherJoinReorderContext);
}
/**

View File

@ -68,6 +68,10 @@ public class LogicalSelectHint<CHILD_TYPE extends Plan> extends LogicalUnary<CHI
return hints;
}
public boolean isIncludeLeading() {
return hints.containsKey("leading");
}
@Override
public LogicalSelectHint<Plan> withChildren(List<Plan> children) {
Preconditions.checkArgument(children.size() == 1);