[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:
jakevin
2022-09-09 15:54:32 +08:00
committed by GitHub
parent 66491ec137
commit 77b93ebc09
17 changed files with 145 additions and 151 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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