[enhancement](Nereids) add optionalAnd to simplify code (#12497)
Add optionalAnd to avoid adding True which may make BE crash. Use optional to simplify code.
This commit is contained in:
@ -153,16 +153,14 @@ public class ExpressionTranslator extends DefaultExpressionVisitor<Expr, PlanTra
|
||||
true);
|
||||
} else if (not.child() instanceof EqualTo) {
|
||||
EqualTo equalTo = (EqualTo) not.child();
|
||||
BinaryPredicate binaryPredicate = new BinaryPredicate(Operator.NE,
|
||||
return new BinaryPredicate(Operator.NE,
|
||||
equalTo.child(0).accept(this, context),
|
||||
equalTo.child(1).accept(this, context));
|
||||
return binaryPredicate;
|
||||
} else if (not.child() instanceof InSubquery || not.child() instanceof Exists) {
|
||||
return new BoolLiteral(true);
|
||||
} else {
|
||||
return new CompoundPredicate(CompoundPredicate.Operator.NOT,
|
||||
not.child(0).accept(this, context),
|
||||
null);
|
||||
not.child(0).accept(this, context), null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,10 +263,9 @@ public class ExpressionTranslator extends DefaultExpressionVisitor<Expr, PlanTra
|
||||
|
||||
@Override
|
||||
public Expr visitBinaryArithmetic(BinaryArithmetic binaryArithmetic, PlanTranslatorContext context) {
|
||||
ArithmeticExpr arithmeticExpr = new ArithmeticExpr(binaryArithmetic.getLegacyOperator(),
|
||||
return new ArithmeticExpr(binaryArithmetic.getLegacyOperator(),
|
||||
binaryArithmetic.child(0).accept(this, context),
|
||||
binaryArithmetic.child(1).accept(this, context));
|
||||
return arithmeticExpr;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -42,7 +42,7 @@ public abstract class DistributionSpec {
|
||||
public GroupExpression addEnforcer(Group child) {
|
||||
// TODO:maybe we need to new a LogicalProperties or just do not set logical properties for this node.
|
||||
// If we don't set LogicalProperties explicitly, node will compute a applicable LogicalProperties for itself.
|
||||
PhysicalDistribute distribution = new PhysicalDistribute(
|
||||
PhysicalDistribute<GroupPlan> distribution = new PhysicalDistribute<>(
|
||||
this,
|
||||
child.getLogicalProperties(),
|
||||
new GroupPlan(child));
|
||||
|
||||
@ -23,6 +23,7 @@ import org.apache.doris.nereids.rules.exploration.OneExplorationRuleFactory;
|
||||
import org.apache.doris.nereids.trees.expressions.SlotReference;
|
||||
import org.apache.doris.nereids.trees.plans.GroupPlan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
|
||||
import org.apache.doris.nereids.util.PlanUtils;
|
||||
import org.apache.doris.nereids.util.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -63,7 +64,7 @@ public class JoinCommute extends OneExplorationRuleFactory {
|
||||
newJoin.getJoinReorderContext().setHasCommuteZigZag(true);
|
||||
}
|
||||
|
||||
return JoinReorderCommon.project(new ArrayList<>(join.getOutput()), newJoin).get();
|
||||
return PlanUtils.project(new ArrayList<>(join.getOutput()), newJoin).get();
|
||||
}).toRule(RuleType.LOGICAL_JOIN_COMMUTATIVE);
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ 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.util.ExpressionUtils;
|
||||
import org.apache.doris.nereids.util.PlanUtils;
|
||||
import org.apache.doris.nereids.util.Utils;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@ -91,21 +92,21 @@ class JoinLAsscomHelper extends ThreeJoinHelper {
|
||||
newLeftProjectExpr.addAll(cOutput);
|
||||
}
|
||||
LogicalJoin<GroupPlan, GroupPlan> newBottomJoin = new LogicalJoin<>(topJoin.getJoinType(),
|
||||
newBottomHashJoinConjuncts, ExpressionUtils.andByOptional(newBottomNonHashJoinConjuncts), a, c,
|
||||
newBottomHashJoinConjuncts, ExpressionUtils.optionalAnd(newBottomNonHashJoinConjuncts), a, c,
|
||||
bottomJoin.getJoinReorderContext());
|
||||
newBottomJoin.getJoinReorderContext().setHasLAsscom(false);
|
||||
newBottomJoin.getJoinReorderContext().setHasCommute(false);
|
||||
|
||||
Plan left = JoinReorderCommon.project(newLeftProjectExpr, newBottomJoin).orElse(newBottomJoin);
|
||||
Plan right = JoinReorderCommon.project(newRightProjectExprs, b).orElse(b);
|
||||
Plan left = PlanUtils.projectOrSelf(newLeftProjectExpr, newBottomJoin);
|
||||
Plan right = PlanUtils.projectOrSelf(newRightProjectExprs, b);
|
||||
|
||||
LogicalJoin<Plan, Plan> newTopJoin = new LogicalJoin<>(bottomJoin.getJoinType(),
|
||||
newTopHashJoinConjuncts,
|
||||
ExpressionUtils.andByOptional(newTopNonHashJoinConjuncts), left, right,
|
||||
ExpressionUtils.optionalAnd(newTopNonHashJoinConjuncts), left, right,
|
||||
topJoin.getJoinReorderContext());
|
||||
newTopJoin.getJoinReorderContext().setHasLAsscom(true);
|
||||
|
||||
return JoinReorderCommon.project(new ArrayList<>(topJoin.getOutput()), newTopJoin).get();
|
||||
return PlanUtils.projectOrSelf(new ArrayList<>(topJoin.getOutput()), newTopJoin);
|
||||
}
|
||||
|
||||
public static boolean check(Type type, LogicalJoin<? extends Plan, GroupPlan> topJoin,
|
||||
|
||||
@ -17,24 +17,9 @@
|
||||
|
||||
package org.apache.doris.nereids.rules.exploration.join;
|
||||
|
||||
import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
class JoinReorderCommon {
|
||||
public enum Type {
|
||||
INNER,
|
||||
OUTER
|
||||
}
|
||||
|
||||
public static Optional<Plan> project(List<NamedExpression> projectExprs, Plan plan) {
|
||||
if (!projectExprs.isEmpty()) {
|
||||
return Optional.of(new LogicalProject<>(projectExprs, plan));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,21 +27,21 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalApply;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.util.ExpressionUtils;
|
||||
import org.apache.doris.nereids.util.PlanUtils;
|
||||
import org.apache.doris.nereids.util.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Merge the correlated predicate and agg in the filter under apply.
|
||||
* And keep the unCorrelated predicate under agg.
|
||||
*
|
||||
* <p>
|
||||
* Use the correlated column as the group by column of agg,
|
||||
* the output column is the correlated column and the input column.
|
||||
*
|
||||
* <p>
|
||||
* before:
|
||||
* apply
|
||||
* / \
|
||||
@ -73,12 +73,6 @@ public class ApplyPullFilterOnAgg extends OneRewriteRuleFactory {
|
||||
return apply;
|
||||
}
|
||||
|
||||
LogicalFilter<GroupPlan> newUnCorrelatedFilter = null;
|
||||
if (!unCorrelatedPredicate.isEmpty()) {
|
||||
newUnCorrelatedFilter = new LogicalFilter<>(ExpressionUtils.and(unCorrelatedPredicate),
|
||||
filter.child());
|
||||
}
|
||||
|
||||
List<NamedExpression> newAggOutput = new ArrayList<>(agg.getOutputExpressions());
|
||||
List<Expression> newGroupby = Utils.getCorrelatedSlots(correlatedPredicate,
|
||||
apply.getCorrelationSlot());
|
||||
@ -86,10 +80,10 @@ public class ApplyPullFilterOnAgg extends OneRewriteRuleFactory {
|
||||
newAggOutput.addAll(newGroupby.stream().map(NamedExpression.class::cast).collect(Collectors.toList()));
|
||||
LogicalAggregate newAgg = new LogicalAggregate<>(
|
||||
newGroupby, newAggOutput,
|
||||
newUnCorrelatedFilter == null ? filter.child() : newUnCorrelatedFilter);
|
||||
PlanUtils.filterOrSelf(unCorrelatedPredicate, filter.child()));
|
||||
return new LogicalApply<>(apply.getCorrelationSlot(),
|
||||
apply.getSubqueryExpr(),
|
||||
Optional.ofNullable(ExpressionUtils.and(correlatedPredicate)),
|
||||
ExpressionUtils.optionalAnd(correlatedPredicate),
|
||||
apply.left(), newAgg);
|
||||
}).toRule(RuleType.APPLY_PULL_FILTER_ON_AGG);
|
||||
}
|
||||
|
||||
@ -34,14 +34,14 @@ import java.util.Optional;
|
||||
/**
|
||||
* this rule aims to find a conjunct list from on clause expression, which could
|
||||
* be used to build hash-table.
|
||||
*
|
||||
* <p>
|
||||
* For example:
|
||||
* A join B on A.x=B.x and A.y>1 and A.x+1=B.x+B.y and A.z=B.z+A.x and (A.z=B.z or A.x=B.x)
|
||||
* {A.x=B.x, A.x+1=B.x+B.y} could be used to build hash table,
|
||||
* but {A.y>1, A.z=B.z+A.z, (A.z=B.z or A.x=B.x)} are not.
|
||||
*
|
||||
* A join B on A.x=B.x and A.y>1 and A.x+1=B.x+B.y and A.z=B.z+A.x and (A.z=B.z or A.x=B.x)
|
||||
* {A.x=B.x, A.x+1=B.x+B.y} could be used to build hash table,
|
||||
* but {A.y>1, A.z=B.z+A.z, (A.z=B.z or A.x=B.x)} are not.
|
||||
* <p>
|
||||
* CAUTION:
|
||||
* This rule must be applied after BindSlotReference
|
||||
* This rule must be applied after BindSlotReference
|
||||
*/
|
||||
public class FindHashConditionForJoin extends OneRewriteRuleFactory {
|
||||
@Override
|
||||
@ -49,21 +49,21 @@ public class FindHashConditionForJoin extends OneRewriteRuleFactory {
|
||||
return logicalJoin().then(join -> {
|
||||
Pair<List<Expression>, List<Expression>> pair = JoinUtils.extractExpressionForHashTable(join);
|
||||
List<Expression> extractedHashJoinConjuncts = pair.first;
|
||||
Optional<Expression> remainedNonHashJoinConjuncts = Optional.of(ExpressionUtils.and(pair.second));
|
||||
if (!extractedHashJoinConjuncts.isEmpty()) {
|
||||
List<Expression> combinedHashJoinConjuncts = new ImmutableList.Builder<Expression>()
|
||||
.addAll(join.getHashJoinConjuncts())
|
||||
.addAll(extractedHashJoinConjuncts)
|
||||
.build();
|
||||
return new LogicalJoin(join.getJoinType(),
|
||||
Optional<Expression> remainedNonHashJoinConjuncts = ExpressionUtils.optionalAnd(pair.second);
|
||||
if (extractedHashJoinConjuncts.isEmpty()) {
|
||||
return join;
|
||||
}
|
||||
|
||||
List<Expression> combinedHashJoinConjuncts = new ImmutableList.Builder<Expression>()
|
||||
.addAll(join.getHashJoinConjuncts())
|
||||
.addAll(extractedHashJoinConjuncts)
|
||||
.build();
|
||||
return new LogicalJoin<>(join.getJoinType(),
|
||||
combinedHashJoinConjuncts,
|
||||
remainedNonHashJoinConjuncts,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
join.left(), join.right());
|
||||
} else {
|
||||
return join;
|
||||
}
|
||||
}).toRule(RuleType.FIND_HASH_CONDITION_FOR_JOIN);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.util.ExpressionUtils;
|
||||
|
||||
@ -46,12 +47,11 @@ public class MergeConsecutiveFilters extends OneRewriteRuleFactory {
|
||||
@Override
|
||||
public Rule build() {
|
||||
return logicalFilter(logicalFilter()).then(filter -> {
|
||||
LogicalFilter<?> childFilter = filter.child();
|
||||
LogicalFilter<? extends Plan> childFilter = filter.child();
|
||||
Expression predicates = filter.getPredicates();
|
||||
Expression childPredicates = childFilter.getPredicates();
|
||||
Expression mergedPredicates = ExpressionUtils.and(predicates, childPredicates);
|
||||
LogicalFilter mergedFilter = new LogicalFilter(mergedPredicates, childFilter.child());
|
||||
return mergedFilter;
|
||||
return new LogicalFilter<>(mergedPredicates, childFilter.child());
|
||||
}).toRule(RuleType.MERGE_CONSECUTIVE_FILTERS);
|
||||
}
|
||||
|
||||
|
||||
@ -42,9 +42,9 @@ public class MergeConsecutiveLimits extends OneRewriteRuleFactory {
|
||||
@Override
|
||||
public Rule build() {
|
||||
return logicalLimit(logicalLimit()).then(upperLimit -> {
|
||||
LogicalLimit bottomLimit = upperLimit.child();
|
||||
LogicalLimit<? extends Plan> bottomLimit = upperLimit.child();
|
||||
List<Plan> children = bottomLimit.children();
|
||||
return new LogicalLimit(
|
||||
return new LogicalLimit<>(
|
||||
Math.min(upperLimit.getLimit(), bottomLimit.getLimit()),
|
||||
bottomLimit.getOffset(),
|
||||
children.get(0)
|
||||
|
||||
@ -29,6 +29,7 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
|
||||
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
|
||||
import org.apache.doris.nereids.util.ExpressionUtils;
|
||||
import org.apache.doris.nereids.util.JoinUtils;
|
||||
import org.apache.doris.nereids.util.PlanUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@ -56,18 +57,13 @@ public class MultiJoin extends PlanVisitor<Void, Void> {
|
||||
|
||||
/**
|
||||
* reorderJoinsAccordingToConditions
|
||||
*
|
||||
* @return join or filter
|
||||
*/
|
||||
public Optional<Plan> reorderJoinsAccordingToConditions() {
|
||||
if (joinInputs.size() >= 2) {
|
||||
Plan root = reorderJoinsAccordingToConditions(joinInputs, conjunctsForAllHashJoins);
|
||||
if (!conjunctsKeepInFilter.isEmpty()) {
|
||||
root = new LogicalFilter(
|
||||
ExpressionUtils.and(conjunctsKeepInFilter),
|
||||
root
|
||||
);
|
||||
}
|
||||
return Optional.of(root);
|
||||
return Optional.of(PlanUtils.filterOrSelf(conjunctsKeepInFilter, root));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
@ -94,20 +90,11 @@ public class MultiJoin extends PlanVisitor<Void, Void> {
|
||||
conjuncts);
|
||||
List<Expression> joinConditions = pair.first;
|
||||
conjunctsKeepInFilter = pair.second;
|
||||
LogicalJoin join;
|
||||
if (joinConditions.isEmpty()) {
|
||||
join = new LogicalJoin(JoinType.CROSS_JOIN,
|
||||
new ArrayList<>(),
|
||||
Optional.empty(),
|
||||
joinInputs.get(0), joinInputs.get(1));
|
||||
} else {
|
||||
join = new LogicalJoin(JoinType.INNER_JOIN,
|
||||
new ArrayList<>(),
|
||||
Optional.of(ExpressionUtils.and(joinConditions)),
|
||||
joinInputs.get(0), joinInputs.get(1));
|
||||
}
|
||||
|
||||
return join;
|
||||
return new LogicalJoin<>(JoinType.INNER_JOIN,
|
||||
new ArrayList<>(),
|
||||
ExpressionUtils.optionalAnd(joinConditions),
|
||||
joinInputs.get(0), joinInputs.get(1));
|
||||
}
|
||||
// input size >= 3;
|
||||
Plan left = joinInputs.get(0);
|
||||
@ -145,16 +132,9 @@ public class MultiJoin extends PlanVisitor<Void, Void> {
|
||||
conjuncts);
|
||||
List<Expression> joinConditions = pair.first;
|
||||
List<Expression> nonJoinConditions = pair.second;
|
||||
LogicalJoin join;
|
||||
if (joinConditions.isEmpty()) {
|
||||
join = new LogicalJoin(JoinType.CROSS_JOIN, new ArrayList<Expression>(),
|
||||
Optional.empty(),
|
||||
left, right);
|
||||
} else {
|
||||
join = new LogicalJoin(JoinType.INNER_JOIN, new ArrayList<>(),
|
||||
Optional.of(ExpressionUtils.and(joinConditions)),
|
||||
left, right);
|
||||
}
|
||||
LogicalJoin join = new LogicalJoin<>(JoinType.INNER_JOIN, new ArrayList<>(),
|
||||
ExpressionUtils.optionalAnd(joinConditions),
|
||||
left, right);
|
||||
|
||||
List<Plan> newInputs = new ArrayList<>();
|
||||
newInputs.add(join);
|
||||
|
||||
@ -22,14 +22,15 @@ import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.GroupPlan;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalApply;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.util.ExpressionUtils;
|
||||
import org.apache.doris.nereids.util.PlanUtils;
|
||||
import org.apache.doris.nereids.util.Utils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Exchange apply and filter.
|
||||
@ -63,17 +64,10 @@ public class PushApplyUnderFilter extends OneRewriteRuleFactory {
|
||||
return apply;
|
||||
}
|
||||
|
||||
if (unCorrelatedPredicate.isEmpty()) {
|
||||
return new LogicalApply<>(apply.getCorrelationSlot(), apply.getSubqueryExpr(),
|
||||
Optional.ofNullable(ExpressionUtils.and(correlatedPredicate)),
|
||||
apply.left(), filter.child());
|
||||
} else {
|
||||
LogicalFilter<GroupPlan> newFilter = new LogicalFilter<>(
|
||||
ExpressionUtils.and(unCorrelatedPredicate), filter.child());
|
||||
return new LogicalApply<>(apply.getCorrelationSlot(), apply.getSubqueryExpr(),
|
||||
Optional.ofNullable(ExpressionUtils.and(correlatedPredicate)),
|
||||
apply.left(), newFilter);
|
||||
}
|
||||
Plan child = PlanUtils.filterOrSelf(unCorrelatedPredicate, filter.child());
|
||||
return new LogicalApply<>(apply.getCorrelationSlot(), apply.getSubqueryExpr(),
|
||||
ExpressionUtils.optionalAnd(correlatedPredicate),
|
||||
apply.left(), child);
|
||||
}).toRule(RuleType.PUSH_APPLY_UNDER_FILTER);
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.util.ExpressionUtils;
|
||||
import org.apache.doris.nereids.util.PlanUtils;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@ -89,19 +90,15 @@ public class PushPredicateThroughAggregation extends OneRewriteRuleFactory {
|
||||
}
|
||||
|
||||
private Plan pushDownPredicate(LogicalFilter filter, LogicalAggregate aggregate,
|
||||
List<Expression> pushDownPredicates, List<Expression> filterPredicates) {
|
||||
List<Expression> pushDownPredicates, List<Expression> filterPredicates) {
|
||||
if (pushDownPredicates.size() == 0) {
|
||||
//nothing pushed down, just return origin plan
|
||||
// nothing pushed down, just return origin plan
|
||||
return filter;
|
||||
}
|
||||
LogicalFilter bottomFilter = new LogicalFilter(ExpressionUtils.and(pushDownPredicates),
|
||||
(Plan) aggregate.child(0));
|
||||
if (filterPredicates.isEmpty()) {
|
||||
//all predicates are pushed down, just exchange filter and aggregate
|
||||
return aggregate.withChildren(Lists.newArrayList(bottomFilter));
|
||||
} else {
|
||||
aggregate = aggregate.withChildren(Lists.newArrayList(bottomFilter));
|
||||
return new LogicalFilter<>(ExpressionUtils.and(filterPredicates), aggregate);
|
||||
}
|
||||
LogicalFilter bottomFilter = new LogicalFilter<>(ExpressionUtils.and(pushDownPredicates),
|
||||
aggregate.child(0));
|
||||
|
||||
aggregate = aggregate.withChildren(Lists.newArrayList(bottomFilter));
|
||||
return PlanUtils.filterOrSelf(filterPredicates, aggregate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,15 +26,14 @@ import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
|
||||
import org.apache.doris.nereids.trees.plans.GroupPlan;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
|
||||
import org.apache.doris.nereids.util.ExpressionUtils;
|
||||
import org.apache.doris.nereids.util.PlanUtils;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -114,22 +113,12 @@ public class PushPredicateThroughJoin extends OneRewriteRuleFactory {
|
||||
|
||||
private Plan pushDownPredicate(LogicalJoin<GroupPlan, GroupPlan> joinPlan,
|
||||
List<Expression> joinConditions, List<Expression> leftPredicates, List<Expression> rightPredicates) {
|
||||
|
||||
Expression left = ExpressionUtils.and(leftPredicates);
|
||||
Expression right = ExpressionUtils.and(rightPredicates);
|
||||
//todo expr should optimize again using expr rewrite
|
||||
Plan leftPlan = joinPlan.left();
|
||||
Plan rightPlan = joinPlan.right();
|
||||
if (!left.equals(BooleanLiteral.TRUE)) {
|
||||
leftPlan = new LogicalFilter<>(left, leftPlan);
|
||||
}
|
||||
|
||||
if (!right.equals(BooleanLiteral.TRUE)) {
|
||||
rightPlan = new LogicalFilter<>(right, rightPlan);
|
||||
}
|
||||
// todo expr should optimize again using expr rewrite
|
||||
Plan leftPlan = PlanUtils.filterOrSelf(leftPredicates, joinPlan.left());
|
||||
Plan rightPlan = PlanUtils.filterOrSelf(rightPredicates, joinPlan.right());
|
||||
|
||||
return new LogicalJoin<>(joinPlan.getJoinType(), joinPlan.getHashJoinConjuncts(),
|
||||
Optional.of(ExpressionUtils.and(joinConditions)), leftPlan, rightPlan);
|
||||
ExpressionUtils.optionalAnd(joinConditions), leftPlan, rightPlan);
|
||||
}
|
||||
|
||||
private Expression getJoinCondition(Expression predicate, Set<Slot> leftOutputs, Set<Slot> rightOutputs) {
|
||||
|
||||
@ -63,23 +63,24 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
Optional.empty(), leftChild, rightChild);
|
||||
}
|
||||
|
||||
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts, Optional<Expression> condition,
|
||||
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts, Optional<Expression> otherJoinCondition,
|
||||
LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) {
|
||||
this(joinType, hashJoinConjuncts,
|
||||
condition, Optional.empty(), Optional.empty(), leftChild, rightChild);
|
||||
otherJoinCondition, Optional.empty(), Optional.empty(), leftChild, rightChild);
|
||||
}
|
||||
|
||||
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts, Optional<Expression> condition,
|
||||
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts, Optional<Expression> otherJoinCondition,
|
||||
LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild, JoinReorderContext joinReorderContext) {
|
||||
this(joinType, hashJoinConjuncts, condition,
|
||||
this(joinType, hashJoinConjuncts, otherJoinCondition,
|
||||
Optional.empty(), Optional.empty(), leftChild, rightChild);
|
||||
this.joinReorderContext.copyFrom(joinReorderContext);
|
||||
}
|
||||
|
||||
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts, Optional<Expression> condition,
|
||||
public LogicalJoin(JoinType joinType, List<Expression> hashJoinConjuncts, Optional<Expression> otherJoinCondition,
|
||||
Optional<GroupExpression> groupExpression, Optional<LogicalProperties> logicalProperties,
|
||||
LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild, JoinReorderContext joinReorderContext) {
|
||||
this(joinType, hashJoinConjuncts, condition, groupExpression, logicalProperties, leftChild, rightChild);
|
||||
this(joinType, hashJoinConjuncts, otherJoinCondition, groupExpression, logicalProperties, leftChild,
|
||||
rightChild);
|
||||
this.joinReorderContext.copyFrom(joinReorderContext);
|
||||
}
|
||||
|
||||
@ -118,15 +119,14 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
* @return the combination of hashJoinConjuncts and otherJoinCondition
|
||||
*/
|
||||
public Optional<Expression> getOnClauseCondition() {
|
||||
if (hashJoinConjuncts.isEmpty()) {
|
||||
return otherJoinCondition;
|
||||
Optional<Expression> hashJoinCondition = ExpressionUtils.optionalAnd(hashJoinConjuncts);
|
||||
|
||||
if (hashJoinCondition.isPresent() && otherJoinCondition.isPresent()) {
|
||||
return ExpressionUtils.optionalAnd(hashJoinCondition.get(), otherJoinCondition.get());
|
||||
}
|
||||
|
||||
Expression onClauseCondition = ExpressionUtils.and(hashJoinConjuncts);
|
||||
if (otherJoinCondition.isPresent()) {
|
||||
onClauseCondition = ExpressionUtils.and(onClauseCondition, otherJoinCondition.get());
|
||||
}
|
||||
return Optional.of(onClauseCondition);
|
||||
return hashJoinCondition.map(Optional::of)
|
||||
.orElse(otherJoinCondition);
|
||||
}
|
||||
|
||||
public JoinType getJoinType() {
|
||||
@ -207,7 +207,7 @@ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
|
||||
return visitor.visitLogicalJoin((LogicalJoin<Plan, Plan>) this, context);
|
||||
return visitor.visitLogicalJoin(this, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -128,14 +128,13 @@ public abstract class AbstractPhysicalJoin<
|
||||
* @return the combination of hashJoinConjuncts and otherJoinCondition
|
||||
*/
|
||||
public Optional<Expression> getOnClauseCondition() {
|
||||
if (hashJoinConjuncts.isEmpty()) {
|
||||
return otherJoinCondition;
|
||||
Optional<Expression> hashJoinCondition = ExpressionUtils.optionalAnd(hashJoinConjuncts);
|
||||
|
||||
if (hashJoinCondition.isPresent() && otherJoinCondition.isPresent()) {
|
||||
return ExpressionUtils.optionalAnd(hashJoinCondition.get(), otherJoinCondition.get());
|
||||
}
|
||||
|
||||
Expression onClauseCondition = ExpressionUtils.and(hashJoinConjuncts);
|
||||
if (otherJoinCondition.isPresent()) {
|
||||
onClauseCondition = ExpressionUtils.and(onClauseCondition, otherJoinCondition.get());
|
||||
}
|
||||
return Optional.of(onClauseCondition);
|
||||
return hashJoinCondition.map(Optional::of)
|
||||
.orElse(otherJoinCondition);
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ public class ExpressionUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<Expression> andByOptional(List<Expression> expressions) {
|
||||
public static Optional<Expression> optionalAnd(List<Expression> expressions) {
|
||||
if (expressions.isEmpty()) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
@ -87,6 +87,10 @@ public class ExpressionUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<Expression> optionalAnd(Expression... expressions) {
|
||||
return optionalAnd(Lists.newArrayList(expressions));
|
||||
}
|
||||
|
||||
public static Expression and(List<Expression> expressions) {
|
||||
return combine(And.class, expressions);
|
||||
}
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
// 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.util;
|
||||
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Util for plan
|
||||
*/
|
||||
public class PlanUtils {
|
||||
public static Optional<LogicalProject<? extends Plan>> project(List<NamedExpression> projectExprs, Plan plan) {
|
||||
if (projectExprs.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(new LogicalProject<>(projectExprs, plan));
|
||||
}
|
||||
|
||||
public static Plan projectOrSelf(List<NamedExpression> projectExprs, Plan plan) {
|
||||
return project(projectExprs, plan).map(Plan.class::cast).orElse(plan);
|
||||
}
|
||||
|
||||
public static Optional<LogicalFilter<? extends Plan>> filter(List<Expression> predicates, Plan plan) {
|
||||
return ExpressionUtils.optionalAnd(predicates)
|
||||
.map(predicate -> new LogicalFilter<>(predicate, plan));
|
||||
}
|
||||
|
||||
public static Plan filterOrSelf(List<Expression> predicates, Plan plan) {
|
||||
return filter(predicates, plan).map(Plan.class::cast).orElse(plan);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user