[Feat](nereids) support multi-leading (#30379)
support multi-leading in each query block
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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(
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}))
|
||||
);
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user