This is an automated email from the ASF dual-hosted git repository. huajianlan pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 7c950c7cd5 [feature](Nereids) support cross join in Nereids (#11502) 7c950c7cd5 is described below commit 7c950c7cd54e4eda77d155a737597b70ea329dd7 Author: morrySnow <101034200+morrys...@users.noreply.github.com> AuthorDate: Mon Aug 8 22:14:27 2022 +0800 [feature](Nereids) support cross join in Nereids (#11502) support cross join in Nereids 1. add PhysicalNestedLoopJoin 2. Translate PhysicalNestedLoopJoin to CrossJoinNode in PhysicalPlanTranslator --- fe/check/checkstyle/import-control.xml | 1 + .../apache/doris/nereids/cost/CostCalculator.java | 28 +++++++++ .../glue/translator/PhysicalPlanTranslator.java | 30 ++++++++- .../doris/nereids/pattern/PatternDescriptor.java | 4 ++ .../properties/ChildOutputPropertyDeriver.java | 35 +++++++++++ .../nereids/properties/RequestPropertyDeriver.java | 26 ++++++++ .../org/apache/doris/nereids/rules/RuleSet.java | 2 + .../org/apache/doris/nereids/rules/RuleType.java | 1 + .../implementation/LogicalJoinToHashJoin.java | 5 +- ...hJoin.java => LogicalJoinToNestedLoopJoin.java} | 23 ++++--- .../apache/doris/nereids/stats/JoinEstimation.java | 11 +++- .../doris/nereids/stats/StatsCalculator.java | 24 ++++--- .../org/apache/doris/nereids/trees/TreeNode.java | 3 +- .../apache/doris/nereids/trees/plans/PlanType.java | 1 + .../trees/plans/{ => algebra}/Aggregate.java | 2 +- .../nereids/trees/plans/{ => algebra}/Filter.java | 2 +- .../trees/plans/{Filter.java => algebra/Join.java} | 13 ++-- .../nereids/trees/plans/{ => algebra}/Limit.java | 2 +- .../nereids/trees/plans/{ => algebra}/Project.java | 2 +- .../nereids/trees/plans/{ => algebra}/Scan.java | 2 +- .../trees/plans/logical/LogicalAggregate.java | 2 +- .../nereids/trees/plans/logical/LogicalFilter.java | 2 +- .../nereids/trees/plans/logical/LogicalJoin.java | 3 +- .../nereids/trees/plans/logical/LogicalLimit.java | 2 +- .../trees/plans/logical/LogicalProject.java | 2 +- .../trees/plans/logical/LogicalRelation.java | 2 +- .../trees/plans/physical/PhysicalAggregate.java | 2 +- .../trees/plans/physical/PhysicalFilter.java | 2 +- .../trees/plans/physical/PhysicalHashJoin.java | 44 +------------ .../{PhysicalHashJoin.java => PhysicalJoin.java} | 65 ++++--------------- .../trees/plans/physical/PhysicalLimit.java | 2 +- ...alHashJoin.java => PhysicalNestedLoopJoin.java} | 73 ++++++---------------- .../trees/plans/physical/PhysicalProject.java | 2 +- .../trees/plans/physical/PhysicalRelation.java | 2 +- .../nereids/trees/plans/visitor/PlanVisitor.java | 5 ++ .../org/apache/doris/nereids/util/JoinUtils.java | 17 +++-- .../doris/nereids/stats/StatsCalculatorTest.java | 13 ++-- .../doris/nereids/trees/plans/FakeJoin.java} | 29 +++++---- regression-test/data/nereids_syntax_p0/join.out | 11 ++++ .../suites/nereids_syntax_p0/join.groovy | 4 ++ 40 files changed, 283 insertions(+), 218 deletions(-) diff --git a/fe/check/checkstyle/import-control.xml b/fe/check/checkstyle/import-control.xml index 21be19ab30..5173416552 100644 --- a/fe/check/checkstyle/import-control.xml +++ b/fe/check/checkstyle/import-control.xml @@ -24,6 +24,7 @@ under the License. <import-control pkg="org.apache.doris" strategyOnMismatch="allowed"> <disallow pkg="com.clearspring.analytics.util" /> + <disallow pkg="com.alibaba.google" /> <subpackage name="nereids"> <allow pkg="org.junit.jupiter"/> <disallow pkg="org.junit"/> diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java index 055232bda1..6bf577cdf3 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java @@ -25,6 +25,7 @@ import org.apache.doris.nereids.trees.plans.physical.PhysicalAggregate; import org.apache.doris.nereids.trees.plans.physical.PhysicalDistribution; import org.apache.doris.nereids.trees.plans.physical.PhysicalHashJoin; import org.apache.doris.nereids.trees.plans.physical.PhysicalHeapSort; +import org.apache.doris.nereids.trees.plans.physical.PhysicalNestedLoopJoin; import org.apache.doris.nereids.trees.plans.physical.PhysicalOlapScan; import org.apache.doris.nereids.trees.plans.physical.PhysicalProject; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; @@ -133,5 +134,32 @@ public class CostCalculator { 0); } + @Override + public CostEstimate visitPhysicalNestedLoopJoin(PhysicalNestedLoopJoin<Plan, Plan> nestedLoopJoin, + PlanContext context) { + // TODO: copy from physicalHashJoin, should update according to physical nested loop join properties. + Preconditions.checkState(context.getGroupExpression().arity() == 2); + Preconditions.checkState(context.getChildrenStats().size() == 2); + + StatsDeriveResult leftStatistics = context.getChildStatistics(0); + StatsDeriveResult rightStatistics = context.getChildStatistics(1); + List<Id> leftIds = context.getChildOutputIds(0); + List<Id> rightIds = context.getChildOutputIds(1); + + // TODO: handle some case + // handle cross join, onClause is empty ..... + if (nestedLoopJoin.getJoinType().isCrossJoin()) { + return new CostEstimate( + leftStatistics.computeColumnSize(leftIds) + rightStatistics.computeColumnSize(rightIds), + rightStatistics.computeColumnSize(rightIds), + 0); + } + + // TODO: network 0? + return new CostEstimate( + (leftStatistics.computeColumnSize(leftIds) + rightStatistics.computeColumnSize(rightIds)) / 2, + rightStatistics.computeColumnSize(rightIds), + 0); + } } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java index eb61c3fe9c..9270d51a41 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java @@ -47,14 +47,17 @@ import org.apache.doris.nereids.trees.plans.physical.PhysicalFilter; import org.apache.doris.nereids.trees.plans.physical.PhysicalHashJoin; import org.apache.doris.nereids.trees.plans.physical.PhysicalHeapSort; import org.apache.doris.nereids.trees.plans.physical.PhysicalLimit; +import org.apache.doris.nereids.trees.plans.physical.PhysicalNestedLoopJoin; import org.apache.doris.nereids.trees.plans.physical.PhysicalOlapScan; import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan; import org.apache.doris.nereids.trees.plans.physical.PhysicalProject; import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanVisitor; import org.apache.doris.nereids.util.ExpressionUtils; +import org.apache.doris.nereids.util.JoinUtils; import org.apache.doris.nereids.util.SlotExtractor; import org.apache.doris.nereids.util.Utils; import org.apache.doris.planner.AggregationNode; +import org.apache.doris.planner.CrossJoinNode; import org.apache.doris.planner.DataPartition; import org.apache.doris.planner.ExchangeNode; import org.apache.doris.planner.HashJoinNode; @@ -338,8 +341,7 @@ public class PhysicalPlanTranslator extends DefaultPlanVisitor<PlanFragment, Pla PlanNode rightFragmentPlanRoot = rightFragment.getPlanRoot(); JoinType joinType = hashJoin.getJoinType(); - if (joinType.equals(JoinType.CROSS_JOIN) - || (joinType.equals(JoinType.INNER_JOIN) && !hashJoin.getCondition().isPresent())) { + if (JoinUtils.shouldNestedLoopJoin(hashJoin)) { throw new RuntimeException("Physical hash join could not execute without equal join condition."); } else { Expression eqJoinExpression = hashJoin.getCondition().get(); @@ -368,6 +370,30 @@ public class PhysicalPlanTranslator extends DefaultPlanVisitor<PlanFragment, Pla } } + @Override + public PlanFragment visitPhysicalNestedLoopJoin(PhysicalNestedLoopJoin<Plan, Plan> nestedLoopJoin, + PlanTranslatorContext context) { + // NOTICE: We must visit from right to left, to ensure the last fragment is root fragment + // TODO: we should add a helper method to wrap this logic. + // Maybe something like private List<PlanFragment> postOrderVisitChildren( + // PhysicalPlan plan, PlanVisitor visitor, Context context). + PlanFragment rightFragment = nestedLoopJoin.child(1).accept(this, context); + PlanFragment leftFragment = nestedLoopJoin.child(0).accept(this, context); + PlanNode leftFragmentPlanRoot = leftFragment.getPlanRoot(); + PlanNode rightFragmentPlanRoot = rightFragment.getPlanRoot(); + if (JoinUtils.shouldNestedLoopJoin(nestedLoopJoin)) { + CrossJoinNode crossJoinNode = + new CrossJoinNode(context.nextPlanNodeId(), leftFragmentPlanRoot, rightFragmentPlanRoot, null); + rightFragment.getPlanRoot().setCompactData(false); + crossJoinNode.setChild(0, leftFragment.getPlanRoot()); + connectChildFragment(crossJoinNode, 1, leftFragment, rightFragment, context); + leftFragment.setPlanRoot(crossJoinNode); + return leftFragment; + } else { + throw new RuntimeException("Physical nested loop join could not execute with equal join condition."); + } + } + // TODO: generate expression mapping when be project could do in ExecNode @Override public PlanFragment visitPhysicalProject(PhysicalProject<Plan> project, PlanTranslatorContext context) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/pattern/PatternDescriptor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/pattern/PatternDescriptor.java index d2b44427c9..dd742c34e0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/pattern/PatternDescriptor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/pattern/PatternDescriptor.java @@ -48,6 +48,10 @@ public class PatternDescriptor<INPUT_TYPE extends Plan> { return new PatternDescriptor<>(pattern.withPredicates(predicates), defaultPromise); } + public PatternDescriptor<INPUT_TYPE> whenNot(Predicate<INPUT_TYPE> predicate) { + return when(predicate.negate()); + } + public <OUTPUT_TYPE extends Plan> PatternMatcher<INPUT_TYPE, OUTPUT_TYPE> then( Function<INPUT_TYPE, OUTPUT_TYPE> matchedAction) { return new PatternMatcher<>(pattern, defaultPromise, ctx -> matchedAction.apply(ctx.root)); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/ChildOutputPropertyDeriver.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/ChildOutputPropertyDeriver.java index 5f6b96d82d..3a55cf858b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/ChildOutputPropertyDeriver.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/ChildOutputPropertyDeriver.java @@ -21,6 +21,7 @@ import org.apache.doris.nereids.PlanContext; import org.apache.doris.nereids.memo.GroupExpression; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.physical.PhysicalHashJoin; +import org.apache.doris.nereids.trees.plans.physical.PhysicalNestedLoopJoin; import org.apache.doris.nereids.trees.plans.physical.PhysicalOlapScan; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; @@ -99,6 +100,40 @@ public class ChildOutputPropertyDeriver extends PlanVisitor<PhysicalProperties, return leftOutputProperty; } + @Override + public PhysicalProperties visitPhysicalNestedLoopJoin(PhysicalNestedLoopJoin<Plan, Plan> nestedLoopJoin, + PlanContext context) { + // TODO: copy from hash join, should update according to nested loop join properties. + Preconditions.checkState(childrenOutputProperties.size() == 2); + PhysicalProperties leftOutputProperty = childrenOutputProperties.get(0); + PhysicalProperties rightOutputProperty = childrenOutputProperties.get(1); + + // broadcast + if (rightOutputProperty.getDistributionSpec() instanceof DistributionSpecReplicated) { + // TODO + return leftOutputProperty; + } + + // shuffle + // List<SlotReference> leftSlotRefs = hashJoin.left().getOutput().stream().map(slot -> (SlotReference) slot) + // .collect(Collectors.toList()); + // List<SlotReference> rightSlotRefs = hashJoin.right().getOutput().stream().map(slot -> (SlotReference) slot) + // .collect(Collectors.toList()); + + // List<SlotReference> leftOnSlotRefs; + // List<SlotReference> rightOnSlotRefs; + // Preconditions.checkState(leftOnSlotRefs.size() == rightOnSlotRefs.size()); + DistributionSpec leftDistribution = leftOutputProperty.getDistributionSpec(); + DistributionSpec rightDistribution = rightOutputProperty.getDistributionSpec(); + if (!(leftDistribution instanceof DistributionSpecHash) + || !(rightDistribution instanceof DistributionSpecHash)) { + Preconditions.checkState(false, "error"); + return new PhysicalProperties(); + } + + return leftOutputProperty; + } + @Override public PhysicalProperties visitPhysicalOlapScan(PhysicalOlapScan olapScan, PlanContext context) { return olapScan.getPhysicalProperties(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/RequestPropertyDeriver.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/RequestPropertyDeriver.java index 848ed44f9d..112d0db3e6 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/RequestPropertyDeriver.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/RequestPropertyDeriver.java @@ -25,6 +25,7 @@ import org.apache.doris.nereids.properties.DistributionSpecHash.ShuffleType; import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.physical.PhysicalHashJoin; +import org.apache.doris.nereids.trees.plans.physical.PhysicalNestedLoopJoin; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import org.apache.doris.nereids.util.JoinUtils; import org.apache.doris.nereids.util.Utils; @@ -92,6 +93,31 @@ public class RequestPropertyDeriver extends PlanVisitor<Void, PlanContext> { return null; } + @Override + public Void visitPhysicalNestedLoopJoin(PhysicalNestedLoopJoin<Plan, Plan> nestedLoopJoin, PlanContext context) { + // TODO: copy from physicalHashJoin, should update according to physical nested loop join properties. + // for broadcast join + List<PhysicalProperties> propertiesForBroadcast = Lists.newArrayList( + new PhysicalProperties(), + new PhysicalProperties(new DistributionSpecReplicated()) + ); + // for shuffle join + Pair<List<SlotReference>, List<SlotReference>> onClauseUsedSlots + = JoinUtils.getOnClauseUsedSlots(nestedLoopJoin); + List<PhysicalProperties> propertiesForShuffle = Lists.newArrayList( + new PhysicalProperties(new DistributionSpecHash(onClauseUsedSlots.first, ShuffleType.JOIN)), + new PhysicalProperties(new DistributionSpecHash(onClauseUsedSlots.second, ShuffleType.JOIN))); + + if (!JoinUtils.onlyBroadcast(nestedLoopJoin)) { + requestPropertyToChildren.add(propertiesForShuffle); + } + if (!JoinUtils.onlyShuffle(nestedLoopJoin)) { + requestPropertyToChildren.add(propertiesForBroadcast); + } + + return null; + } + protected static List<PhysicalProperties> computeShuffleJoinRequiredProperties( PhysicalProperties requestedProperty, List<SlotReference> leftShuffleColumns, List<SlotReference> rightShuffleColumns) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java index aafc618574..9cc7bf7449 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java @@ -21,6 +21,7 @@ import org.apache.doris.nereids.rules.exploration.join.JoinCommute; import org.apache.doris.nereids.rules.implementation.LogicalAggToPhysicalHashAgg; import org.apache.doris.nereids.rules.implementation.LogicalFilterToPhysicalFilter; import org.apache.doris.nereids.rules.implementation.LogicalJoinToHashJoin; +import org.apache.doris.nereids.rules.implementation.LogicalJoinToNestedLoopJoin; import org.apache.doris.nereids.rules.implementation.LogicalLimitToPhysicalLimit; import org.apache.doris.nereids.rules.implementation.LogicalOlapScanToPhysicalOlapScan; import org.apache.doris.nereids.rules.implementation.LogicalProjectToPhysicalProject; @@ -48,6 +49,7 @@ public class RuleSet { .add(new LogicalAggToPhysicalHashAgg()) .add(new LogicalFilterToPhysicalFilter()) .add(new LogicalJoinToHashJoin()) + .add(new LogicalJoinToNestedLoopJoin()) .add(new LogicalOlapScanToPhysicalOlapScan()) .add(new LogicalProjectToPhysicalProject()) .add(new LogicalLimitToPhysicalLimit()) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java index d1d02e54a2..18b077fd2b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java @@ -68,6 +68,7 @@ public enum RuleType { // implementation rules LOGICAL_AGG_TO_PHYSICAL_HASH_AGG_RULE(RuleTypeClass.IMPLEMENTATION), LOGICAL_JOIN_TO_HASH_JOIN_RULE(RuleTypeClass.IMPLEMENTATION), + LOGICAL_JOIN_TO_NESTED_LOOP_JOIN_RULE(RuleTypeClass.IMPLEMENTATION), LOGICAL_PROJECT_TO_PHYSICAL_PROJECT_RULE(RuleTypeClass.IMPLEMENTATION), LOGICAL_FILTER_TO_PHYSICAL_FILTER_RULE(RuleTypeClass.IMPLEMENTATION), LOGICAL_SORT_TO_PHYSICAL_HEAP_SORT_RULE(RuleTypeClass.IMPLEMENTATION), diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalJoinToHashJoin.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalJoinToHashJoin.java index ee48303f1d..8e5fb996da 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalJoinToHashJoin.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalJoinToHashJoin.java @@ -20,6 +20,7 @@ package org.apache.doris.nereids.rules.implementation; import org.apache.doris.nereids.rules.Rule; import org.apache.doris.nereids.rules.RuleType; import org.apache.doris.nereids.trees.plans.physical.PhysicalHashJoin; +import org.apache.doris.nereids.util.JoinUtils; /** * Implementation rule that convert logical join to physical hash join. @@ -27,7 +28,9 @@ import org.apache.doris.nereids.trees.plans.physical.PhysicalHashJoin; public class LogicalJoinToHashJoin extends OneImplementationRuleFactory { @Override public Rule build() { - return logicalJoin().then(join -> new PhysicalHashJoin<>( + return logicalJoin() + .whenNot(JoinUtils::shouldNestedLoopJoin) + .then(join -> new PhysicalHashJoin<>( join.getJoinType(), join.getCondition(), join.getLogicalProperties(), diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalJoinToHashJoin.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalJoinToNestedLoopJoin.java similarity index 58% copy from fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalJoinToHashJoin.java copy to fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalJoinToNestedLoopJoin.java index ee48303f1d..00f1ba25ac 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalJoinToHashJoin.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalJoinToNestedLoopJoin.java @@ -19,20 +19,23 @@ package org.apache.doris.nereids.rules.implementation; import org.apache.doris.nereids.rules.Rule; import org.apache.doris.nereids.rules.RuleType; -import org.apache.doris.nereids.trees.plans.physical.PhysicalHashJoin; +import org.apache.doris.nereids.trees.plans.physical.PhysicalNestedLoopJoin; +import org.apache.doris.nereids.util.JoinUtils; /** - * Implementation rule that convert logical join to physical hash join. + * Implementation rule that convert logical join to physical nested loop join. */ -public class LogicalJoinToHashJoin extends OneImplementationRuleFactory { +public class LogicalJoinToNestedLoopJoin extends OneImplementationRuleFactory { @Override public Rule build() { - return logicalJoin().then(join -> new PhysicalHashJoin<>( - join.getJoinType(), - join.getCondition(), - join.getLogicalProperties(), - join.left(), - join.right()) - ).toRule(RuleType.LOGICAL_JOIN_TO_HASH_JOIN_RULE); + return logicalJoin() + .when(JoinUtils::shouldNestedLoopJoin) + .then(join -> new PhysicalNestedLoopJoin<>( + join.getJoinType(), + join.getCondition(), + join.getLogicalProperties(), + join.left(), + join.right()) + ).toRule(RuleType.LOGICAL_JOIN_TO_NESTED_LOOP_JOIN_RULE); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/JoinEstimation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/JoinEstimation.java index 881e3acf91..ca141471c8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/JoinEstimation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/JoinEstimation.java @@ -22,14 +22,17 @@ import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.plans.JoinType; +import org.apache.doris.nereids.trees.plans.algebra.Join; import org.apache.doris.nereids.util.ExpressionUtils; import org.apache.doris.statistics.ColumnStats; import org.apache.doris.statistics.StatsDeriveResult; import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import java.util.List; import java.util.Map; +import java.util.Optional; /** * Estimate hash join stats. @@ -40,11 +43,13 @@ public class JoinEstimation { /** * Do estimate. */ - public static StatsDeriveResult estimate(StatsDeriveResult leftStats, StatsDeriveResult rightStats, - Expression eqCondition, JoinType joinType) { + public static StatsDeriveResult estimate(StatsDeriveResult leftStats, StatsDeriveResult rightStats, Join join) { + Optional<Expression> eqCondition = join.getCondition(); + JoinType joinType = join.getJoinType(); StatsDeriveResult statsDeriveResult = new StatsDeriveResult(leftStats); statsDeriveResult.merge(rightStats); - List<Expression> eqConjunctList = ExpressionUtils.extractConjunction(eqCondition); + List<Expression> eqConjunctList = Lists.newArrayList(); + eqCondition.ifPresent(e -> eqConjunctList.addAll(ExpressionUtils.extractConjunction(e))); long rowCount = -1; if (joinType.isSemiOrAntiJoin()) { rowCount = getSemiJoinRowCount(leftStats, rightStats, eqConjunctList, joinType); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java index 373e105dff..e223b65f57 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java @@ -23,12 +23,12 @@ import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.NamedExpression; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.expressions.SlotReference; -import org.apache.doris.nereids.trees.plans.Aggregate; -import org.apache.doris.nereids.trees.plans.Filter; -import org.apache.doris.nereids.trees.plans.Limit; import org.apache.doris.nereids.trees.plans.Plan; -import org.apache.doris.nereids.trees.plans.Project; -import org.apache.doris.nereids.trees.plans.Scan; +import org.apache.doris.nereids.trees.plans.algebra.Aggregate; +import org.apache.doris.nereids.trees.plans.algebra.Filter; +import org.apache.doris.nereids.trees.plans.algebra.Limit; +import org.apache.doris.nereids.trees.plans.algebra.Project; +import org.apache.doris.nereids.trees.plans.algebra.Scan; import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate; import org.apache.doris.nereids.trees.plans.logical.LogicalFilter; import org.apache.doris.nereids.trees.plans.logical.LogicalJoin; @@ -42,6 +42,7 @@ import org.apache.doris.nereids.trees.plans.physical.PhysicalFilter; import org.apache.doris.nereids.trees.plans.physical.PhysicalHashJoin; import org.apache.doris.nereids.trees.plans.physical.PhysicalHeapSort; import org.apache.doris.nereids.trees.plans.physical.PhysicalLimit; +import org.apache.doris.nereids.trees.plans.physical.PhysicalNestedLoopJoin; import org.apache.doris.nereids.trees.plans.physical.PhysicalOlapScan; import org.apache.doris.nereids.trees.plans.physical.PhysicalProject; import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanVisitor; @@ -119,8 +120,7 @@ public class StatsCalculator extends DefaultPlanVisitor<StatsDeriveResult, Void> @Override public StatsDeriveResult visitLogicalJoin(LogicalJoin<Plan, Plan> join, Void context) { return JoinEstimation.estimate(groupExpression.getCopyOfChildStats(0), - groupExpression.getCopyOfChildStats(1), - join.getCondition().get(), join.getJoinType()); + groupExpression.getCopyOfChildStats(1), join); } @Override @@ -141,8 +141,14 @@ public class StatsCalculator extends DefaultPlanVisitor<StatsDeriveResult, Void> @Override public StatsDeriveResult visitPhysicalHashJoin(PhysicalHashJoin<Plan, Plan> hashJoin, Void context) { return JoinEstimation.estimate(groupExpression.getCopyOfChildStats(0), - groupExpression.getCopyOfChildStats(1), - hashJoin.getCondition().get(), hashJoin.getJoinType()); + groupExpression.getCopyOfChildStats(1), hashJoin); + } + + @Override + public StatsDeriveResult visitPhysicalNestedLoopJoin(PhysicalNestedLoopJoin<Plan, Plan> nestedLoopJoin, + Void context) { + return JoinEstimation.estimate(groupExpression.getCopyOfChildStats(0), + groupExpression.getCopyOfChildStats(1), nestedLoopJoin); } // TODO: We should subtract those pruned column, and consider the expression transformations in the node. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/TreeNode.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/TreeNode.java index 29b509c884..d4fcd05531 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/TreeNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/TreeNode.java @@ -17,7 +17,8 @@ package org.apache.doris.nereids.trees; -import com.alibaba.google.common.collect.ImmutableList; + +import com.google.common.collect.ImmutableList; import java.util.List; import java.util.function.Consumer; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java index 6ca7462d93..53f45a7ab1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java @@ -47,6 +47,7 @@ public enum PlanType { PHYSICAL_SORT, PHYSICAL_LIMIT, PHYSICAL_HASH_JOIN, + PHYSICAL_NESTED_LOOP_JOIN, PHYSICAL_EXCHANGE, PHYSICAL_DISTRIBUTION; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Aggregate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Aggregate.java similarity index 95% rename from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Aggregate.java rename to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Aggregate.java index 4773403ad5..774052e0fa 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Aggregate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Aggregate.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package org.apache.doris.nereids.trees.plans; +package org.apache.doris.nereids.trees.plans.algebra; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.NamedExpression; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Filter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Filter.java similarity index 94% copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Filter.java copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Filter.java index 1dd37fdd06..f4371eb4f7 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Filter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Filter.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package org.apache.doris.nereids.trees.plans; +package org.apache.doris.nereids.trees.plans.algebra; import org.apache.doris.nereids.trees.expressions.Expression; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Filter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Join.java similarity index 75% rename from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Filter.java rename to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Join.java index 1dd37fdd06..c2f05879e2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Filter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Join.java @@ -15,13 +15,18 @@ // specific language governing permissions and limitations // under the License. -package org.apache.doris.nereids.trees.plans; +package org.apache.doris.nereids.trees.plans.algebra; import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.plans.JoinType; + +import java.util.Optional; /** - * Common interface for logical/physical filter. + * Common interface for logical/physical join. */ -public interface Filter { - Expression getPredicates(); +public interface Join { + JoinType getJoinType(); + + Optional<Expression> getCondition(); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Limit.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Limit.java similarity index 94% rename from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Limit.java rename to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Limit.java index 394eaafae3..a198d1253d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Limit.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Limit.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package org.apache.doris.nereids.trees.plans; +package org.apache.doris.nereids.trees.plans.algebra; /** * Common interface for logical/physical limit. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Project.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Project.java similarity index 94% rename from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Project.java rename to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Project.java index 78c3864a00..1203998a5b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Project.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Project.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package org.apache.doris.nereids.trees.plans; +package org.apache.doris.nereids.trees.plans.algebra; import org.apache.doris.nereids.trees.expressions.NamedExpression; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Scan.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Scan.java similarity index 95% copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Scan.java copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Scan.java index b5bcbca786..f0c536cf83 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Scan.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/algebra/Scan.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package org.apache.doris.nereids.trees.plans; +package org.apache.doris.nereids.trees.plans.algebra; import org.apache.doris.catalog.Table; import org.apache.doris.nereids.trees.expressions.Expression; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java index d60850d044..06ec298851 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java @@ -23,9 +23,9 @@ import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.NamedExpression; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.plans.AggPhase; -import org.apache.doris.nereids.trees.plans.Aggregate; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.algebra.Aggregate; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.base.Preconditions; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalFilter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalFilter.java index af58cc2f7c..56ecea983e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalFilter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalFilter.java @@ -21,9 +21,9 @@ import org.apache.doris.nereids.memo.GroupExpression; import org.apache.doris.nereids.properties.LogicalProperties; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.Slot; -import org.apache.doris.nereids.trees.plans.Filter; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.algebra.Filter; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.base.Preconditions; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalJoin.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalJoin.java index 5d6f06458e..81fbafdde6 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalJoin.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalJoin.java @@ -25,6 +25,7 @@ import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.plans.JoinType; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.algebra.Join; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.base.Preconditions; @@ -39,7 +40,7 @@ import java.util.stream.Collectors; * Logical join plan. */ public class LogicalJoin<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends Plan> - extends LogicalBinary<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> { + extends LogicalBinary<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> implements Join { private final JoinType joinType; private final Optional<Expression> condition; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalLimit.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalLimit.java index 756a7d36e2..6b78ff2ab5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalLimit.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalLimit.java @@ -22,9 +22,9 @@ import org.apache.doris.nereids.properties.LogicalProperties; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.IntegerLiteral; import org.apache.doris.nereids.trees.expressions.Slot; -import org.apache.doris.nereids.trees.plans.Limit; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.algebra.Limit; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.base.Preconditions; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalProject.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalProject.java index 6e2df85cb3..1b3f57949c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalProject.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalProject.java @@ -24,7 +24,7 @@ import org.apache.doris.nereids.trees.expressions.NamedExpression; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.PlanType; -import org.apache.doris.nereids.trees.plans.Project; +import org.apache.doris.nereids.trees.plans.algebra.Project; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.base.Preconditions; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalRelation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalRelation.java index daa28f6841..21a977d394 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalRelation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalRelation.java @@ -24,7 +24,7 @@ import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.plans.PlanType; -import org.apache.doris.nereids.trees.plans.Scan; +import org.apache.doris.nereids.trees.plans.algebra.Scan; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import org.apache.doris.nereids.util.Utils; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalAggregate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalAggregate.java index 2dfc493bd3..05a97c19ff 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalAggregate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalAggregate.java @@ -22,9 +22,9 @@ import org.apache.doris.nereids.properties.LogicalProperties; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.NamedExpression; import org.apache.doris.nereids.trees.plans.AggPhase; -import org.apache.doris.nereids.trees.plans.Aggregate; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.algebra.Aggregate; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.base.Preconditions; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalFilter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalFilter.java index d7a60a8426..c2eb461bd5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalFilter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalFilter.java @@ -20,9 +20,9 @@ package org.apache.doris.nereids.trees.plans.physical; import org.apache.doris.nereids.memo.GroupExpression; import org.apache.doris.nereids.properties.LogicalProperties; import org.apache.doris.nereids.trees.expressions.Expression; -import org.apache.doris.nereids.trees.plans.Filter; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.algebra.Filter; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.base.Preconditions; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java index a2f53f2e3e..6c30a0c606 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java @@ -26,10 +26,8 @@ import org.apache.doris.nereids.trees.plans.PlanType; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; import java.util.List; -import java.util.Objects; import java.util.Optional; /** @@ -38,12 +36,7 @@ import java.util.Optional; public class PhysicalHashJoin< LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends Plan> - extends PhysicalBinary<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> { - - private final JoinType joinType; - - private final Optional<Expression> condition; - + extends PhysicalJoin<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> { public PhysicalHashJoin(JoinType joinType, Optional<Expression> condition, LogicalProperties logicalProperties, LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) { @@ -59,17 +52,8 @@ public class PhysicalHashJoin< public PhysicalHashJoin(JoinType joinType, Optional<Expression> condition, Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties, LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) { - super(PlanType.PHYSICAL_HASH_JOIN, groupExpression, logicalProperties, leftChild, rightChild); - this.joinType = Objects.requireNonNull(joinType, "joinType can not be null"); - this.condition = Objects.requireNonNull(condition, "condition can not be null"); - } - - public JoinType getJoinType() { - return joinType; - } - - public Optional<Expression> getCondition() { - return condition; + super(PlanType.PHYSICAL_HASH_JOIN, joinType, condition, + groupExpression, logicalProperties, leftChild, rightChild); } @Override @@ -77,11 +61,6 @@ public class PhysicalHashJoin< return visitor.visitPhysicalHashJoin((PhysicalHashJoin<Plan, Plan>) this, context); } - @Override - public List<Expression> getExpressions() { - return condition.<List<Expression>>map(ImmutableList::of).orElseGet(ImmutableList::of); - } - @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -93,23 +72,6 @@ public class PhysicalHashJoin< return sb.toString(); } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PhysicalHashJoin that = (PhysicalHashJoin) o; - return joinType == that.joinType && Objects.equals(condition, that.condition); - } - - @Override - public int hashCode() { - return Objects.hash(joinType, condition); - } - @Override public PhysicalBinary<Plan, Plan> withChildren(List<Plan> children) { Preconditions.checkArgument(children.size() == 2); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalJoin.java similarity index 52% copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalJoin.java index a2f53f2e3e..d47be13f6c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalJoin.java @@ -23,9 +23,8 @@ import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.plans.JoinType; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.PlanType; -import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; +import org.apache.doris.nereids.trees.plans.algebra.Join; -import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import java.util.List; @@ -33,33 +32,26 @@ import java.util.Objects; import java.util.Optional; /** - * Physical hash join plan. + * Abstract class for all physical join node. */ -public class PhysicalHashJoin< +public abstract class PhysicalJoin< LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends Plan> - extends PhysicalBinary<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> { + extends PhysicalBinary<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> implements Join { + protected final JoinType joinType; - private final JoinType joinType; - - private final Optional<Expression> condition; - - - public PhysicalHashJoin(JoinType joinType, Optional<Expression> condition, LogicalProperties logicalProperties, - LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) { - this(joinType, condition, Optional.empty(), logicalProperties, leftChild, rightChild); - } + protected final Optional<Expression> condition; /** - * Constructor of PhysicalHashJoinNode. + * Constructor of PhysicalJoin. * * @param joinType Which join type, left semi join, inner join... * @param condition join condition. */ - public PhysicalHashJoin(JoinType joinType, Optional<Expression> condition, - Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties, - LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) { - super(PlanType.PHYSICAL_HASH_JOIN, groupExpression, logicalProperties, leftChild, rightChild); + public PhysicalJoin(PlanType type, JoinType joinType, Optional<Expression> condition, + Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties, + LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) { + super(type, groupExpression, logicalProperties, leftChild, rightChild); this.joinType = Objects.requireNonNull(joinType, "joinType can not be null"); this.condition = Objects.requireNonNull(condition, "condition can not be null"); } @@ -72,27 +64,11 @@ public class PhysicalHashJoin< return condition; } - @Override - public <R, C> R accept(PlanVisitor<R, C> visitor, C context) { - return visitor.visitPhysicalHashJoin((PhysicalHashJoin<Plan, Plan>) this, context); - } - @Override public List<Expression> getExpressions() { return condition.<List<Expression>>map(ImmutableList::of).orElseGet(ImmutableList::of); } - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("PhysicalHashJoin ([").append(joinType).append("]"); - condition.ifPresent( - expression -> sb.append(", [").append(expression).append("]") - ); - sb.append(")"); - return sb.toString(); - } - @Override public boolean equals(Object o) { if (this == o) { @@ -101,7 +77,7 @@ public class PhysicalHashJoin< if (o == null || getClass() != o.getClass()) { return false; } - PhysicalHashJoin that = (PhysicalHashJoin) o; + PhysicalJoin that = (PhysicalJoin) o; return joinType == that.joinType && Objects.equals(condition, that.condition); } @@ -109,21 +85,4 @@ public class PhysicalHashJoin< public int hashCode() { return Objects.hash(joinType, condition); } - - @Override - public PhysicalBinary<Plan, Plan> withChildren(List<Plan> children) { - Preconditions.checkArgument(children.size() == 2); - return new PhysicalHashJoin<>(joinType, condition, logicalProperties, children.get(0), children.get(1)); - } - - @Override - public Plan withGroupExpression(Optional<GroupExpression> groupExpression) { - return new PhysicalHashJoin<>(joinType, condition, groupExpression, logicalProperties, left(), right()); - } - - @Override - public Plan withLogicalProperties(Optional<LogicalProperties> logicalProperties) { - return new PhysicalHashJoin<>(joinType, condition, Optional.empty(), - logicalProperties.get(), left(), right()); - } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalLimit.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalLimit.java index b7e07167e0..6124bd7da9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalLimit.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalLimit.java @@ -21,9 +21,9 @@ import org.apache.doris.nereids.memo.GroupExpression; import org.apache.doris.nereids.properties.LogicalProperties; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.IntegerLiteral; -import org.apache.doris.nereids.trees.plans.Limit; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.algebra.Limit; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.base.Preconditions; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalNestedLoopJoin.java similarity index 50% copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalNestedLoopJoin.java index a2f53f2e3e..0e3452adc9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalNestedLoopJoin.java @@ -26,66 +26,46 @@ import org.apache.doris.nereids.trees.plans.PlanType; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; import java.util.List; -import java.util.Objects; import java.util.Optional; /** - * Physical hash join plan. + * Use nested loop algorithm to do join. */ -public class PhysicalHashJoin< +public class PhysicalNestedLoopJoin< LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends Plan> - extends PhysicalBinary<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> { + extends PhysicalJoin<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> { - private final JoinType joinType; - - private final Optional<Expression> condition; - - - public PhysicalHashJoin(JoinType joinType, Optional<Expression> condition, LogicalProperties logicalProperties, - LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) { + public PhysicalNestedLoopJoin(JoinType joinType, Optional<Expression> condition, + LogicalProperties logicalProperties, LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) { this(joinType, condition, Optional.empty(), logicalProperties, leftChild, rightChild); } /** - * Constructor of PhysicalHashJoinNode. + * Constructor of PhysicalNestedLoopJoin. * * @param joinType Which join type, left semi join, inner join... * @param condition join condition. */ - public PhysicalHashJoin(JoinType joinType, Optional<Expression> condition, - Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties, - LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) { - super(PlanType.PHYSICAL_HASH_JOIN, groupExpression, logicalProperties, leftChild, rightChild); - this.joinType = Objects.requireNonNull(joinType, "joinType can not be null"); - this.condition = Objects.requireNonNull(condition, "condition can not be null"); - } - - public JoinType getJoinType() { - return joinType; - } - - public Optional<Expression> getCondition() { - return condition; + public PhysicalNestedLoopJoin(JoinType joinType, Optional<Expression> condition, + Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties, + LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild) { + super(PlanType.PHYSICAL_NESTED_LOOP_JOIN, joinType, condition, + groupExpression, logicalProperties, leftChild, rightChild); } @Override public <R, C> R accept(PlanVisitor<R, C> visitor, C context) { - return visitor.visitPhysicalHashJoin((PhysicalHashJoin<Plan, Plan>) this, context); - } - - @Override - public List<Expression> getExpressions() { - return condition.<List<Expression>>map(ImmutableList::of).orElseGet(ImmutableList::of); + return visitor.visitPhysicalNestedLoopJoin((PhysicalNestedLoopJoin<Plan, Plan>) this, context); } @Override public String toString() { + // TODO: Maybe we could pull up this to the abstract class in the future. StringBuilder sb = new StringBuilder(); - sb.append("PhysicalHashJoin ([").append(joinType).append("]"); + sb.append("PhysicalNestedLoopJoin ([").append(joinType).append("]"); condition.ifPresent( expression -> sb.append(", [").append(expression).append("]") ); @@ -93,37 +73,20 @@ public class PhysicalHashJoin< return sb.toString(); } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PhysicalHashJoin that = (PhysicalHashJoin) o; - return joinType == that.joinType && Objects.equals(condition, that.condition); - } - - @Override - public int hashCode() { - return Objects.hash(joinType, condition); - } - @Override public PhysicalBinary<Plan, Plan> withChildren(List<Plan> children) { Preconditions.checkArgument(children.size() == 2); - return new PhysicalHashJoin<>(joinType, condition, logicalProperties, children.get(0), children.get(1)); + return new PhysicalNestedLoopJoin<>(joinType, condition, logicalProperties, children.get(0), children.get(1)); } @Override public Plan withGroupExpression(Optional<GroupExpression> groupExpression) { - return new PhysicalHashJoin<>(joinType, condition, groupExpression, logicalProperties, left(), right()); + return new PhysicalNestedLoopJoin<>(joinType, condition, groupExpression, logicalProperties, left(), right()); } @Override public Plan withLogicalProperties(Optional<LogicalProperties> logicalProperties) { - return new PhysicalHashJoin<>(joinType, condition, Optional.empty(), - logicalProperties.get(), left(), right()); + return new PhysicalNestedLoopJoin<>(joinType, condition, Optional.empty(), + logicalProperties.get(), left(), right()); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalProject.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalProject.java index 7f4c2151f6..fd9b66bba3 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalProject.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalProject.java @@ -23,7 +23,7 @@ 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.PlanType; -import org.apache.doris.nereids.trees.plans.Project; +import org.apache.doris.nereids.trees.plans.algebra.Project; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.base.Preconditions; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalRelation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalRelation.java index 485e5d926c..93898031c2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalRelation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalRelation.java @@ -21,7 +21,7 @@ import org.apache.doris.nereids.memo.GroupExpression; import org.apache.doris.nereids.properties.LogicalProperties; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.plans.PlanType; -import org.apache.doris.nereids.trees.plans.Scan; +import org.apache.doris.nereids.trees.plans.algebra.Scan; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import com.google.common.collect.ImmutableList; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/PlanVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/PlanVisitor.java index 5c11a43424..2f91e1f7f3 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/PlanVisitor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/PlanVisitor.java @@ -37,6 +37,7 @@ import org.apache.doris.nereids.trees.plans.physical.PhysicalFilter; import org.apache.doris.nereids.trees.plans.physical.PhysicalHashJoin; import org.apache.doris.nereids.trees.plans.physical.PhysicalHeapSort; import org.apache.doris.nereids.trees.plans.physical.PhysicalLimit; +import org.apache.doris.nereids.trees.plans.physical.PhysicalNestedLoopJoin; import org.apache.doris.nereids.trees.plans.physical.PhysicalOlapScan; import org.apache.doris.nereids.trees.plans.physical.PhysicalProject; import org.apache.doris.nereids.trees.plans.physical.PhysicalRelation; @@ -136,6 +137,10 @@ public abstract class PlanVisitor<R, C> { return visit(hashJoin, context); } + public R visitPhysicalNestedLoopJoin(PhysicalNestedLoopJoin<Plan, Plan> nestedLoopJoin, C context) { + return visit(nestedLoopJoin, context); + } + public R visitPhysicalProject(PhysicalProject<Plan> project, C context) { return visit(project, context); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/JoinUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/JoinUtils.java index 5c66dc85a2..23417ae1d3 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/JoinUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/JoinUtils.java @@ -21,8 +21,10 @@ import org.apache.doris.common.Pair; import org.apache.doris.nereids.trees.expressions.EqualTo; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.SlotReference; +import org.apache.doris.nereids.trees.plans.JoinType; import org.apache.doris.nereids.trees.plans.Plan; -import org.apache.doris.nereids.trees.plans.physical.PhysicalHashJoin; +import org.apache.doris.nereids.trees.plans.algebra.Join; +import org.apache.doris.nereids.trees.plans.physical.PhysicalJoin; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; @@ -34,19 +36,19 @@ import java.util.List; * Utils for join */ public class JoinUtils { - public static boolean onlyBroadcast(PhysicalHashJoin join) { + public static boolean onlyBroadcast(PhysicalJoin join) { // Cross-join only can be broadcast join. return join.getJoinType().isCrossJoin(); } - public static boolean onlyShuffle(PhysicalHashJoin join) { + public static boolean onlyShuffle(PhysicalJoin join) { return join.getJoinType().isRightJoin() || join.getJoinType().isFullOuterJoin(); } /** * Get all equalTo from onClause of join */ - public static List<EqualTo> getEqualTo(PhysicalHashJoin<Plan, Plan> join) { + public static List<EqualTo> getEqualTo(PhysicalJoin<Plan, Plan> join) { List<EqualTo> eqConjuncts = Lists.newArrayList(); if (!join.getCondition().isPresent()) { return eqConjuncts; @@ -86,7 +88,7 @@ public class JoinUtils { * Return pair of left used slots and right used slots. */ public static Pair<List<SlotReference>, List<SlotReference>> getOnClauseUsedSlots( - PhysicalHashJoin<Plan, Plan> join) { + PhysicalJoin<Plan, Plan> join) { Pair<List<SlotReference>, List<SlotReference>> childSlots = new Pair<>(Lists.newArrayList(), Lists.newArrayList()); @@ -114,4 +116,9 @@ public class JoinUtils { return childSlots; } + + public static boolean shouldNestedLoopJoin(Join join) { + JoinType joinType = join.getJoinType(); + return (joinType.isInnerJoin() && !join.getCondition().isPresent()) || joinType.isCrossJoin(); + } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/stats/StatsCalculatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/stats/StatsCalculatorTest.java index ff3195d7fb..a22d0f27d2 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/stats/StatsCalculatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/stats/StatsCalculatorTest.java @@ -32,6 +32,7 @@ import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.expressions.functions.AggregateFunction; import org.apache.doris.nereids.trees.expressions.functions.Sum; +import org.apache.doris.nereids.trees.plans.FakeJoin; import org.apache.doris.nereids.trees.plans.GroupPlan; import org.apache.doris.nereids.trees.plans.JoinType; import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate; @@ -190,11 +191,13 @@ public class StatsCalculatorTest { StatsDeriveResult rightStats = new StatsDeriveResult(rightRowCount, slotColumnStatsMap2); EqualTo equalTo = new EqualTo(slot1, slot2); - StatsDeriveResult semiJoinStats = JoinEstimation.estimate(leftStats, - rightStats, equalTo, JoinType.LEFT_SEMI_JOIN); + + FakeJoin fakeSemiJoin = new FakeJoin(JoinType.LEFT_SEMI_JOIN, Optional.of(equalTo)); + FakeJoin fakeInnerJoin = new FakeJoin(JoinType.INNER_JOIN, Optional.of(equalTo)); + + StatsDeriveResult semiJoinStats = JoinEstimation.estimate(leftStats, rightStats, fakeSemiJoin); Assertions.assertEquals(leftRowCount, semiJoinStats.getRowCount()); - StatsDeriveResult innerJoinStats = JoinEstimation.estimate(leftStats, - rightStats, equalTo, JoinType.INNER_JOIN); + StatsDeriveResult innerJoinStats = JoinEstimation.estimate(leftStats, rightStats, fakeInnerJoin); Assertions.assertEquals(2500000, innerJoinStats.getRowCount()); } @@ -240,7 +243,6 @@ public class StatsCalculatorTest { Assertions.assertNotNull(stats.getSlotToColumnStats().get(slot1)); } - @Test public void testLimit() { List<String> qualifier = new ArrayList<>(); @@ -276,6 +278,5 @@ public class StatsCalculatorTest { ColumnStats slot1Stats = limitStats.getSlotToColumnStats().get(slot1); Assertions.assertEquals(1, slot1Stats.getNdv()); Assertions.assertEquals(1, slot1Stats.getNumNulls()); - } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Scan.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/FakeJoin.java similarity index 63% rename from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Scan.java rename to fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/FakeJoin.java index b5bcbca786..431abccae1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/Scan.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/FakeJoin.java @@ -17,22 +17,27 @@ package org.apache.doris.nereids.trees.plans; -import org.apache.doris.catalog.Table; import org.apache.doris.nereids.trees.expressions.Expression; -import org.apache.doris.nereids.trees.expressions.Slot; +import org.apache.doris.nereids.trees.plans.algebra.Join; -import java.util.Collections; -import java.util.List; +import java.util.Optional; -/** - * Common interface for logical/physical scan. - */ -public interface Scan { - List<Expression> getExpressions(); +public class FakeJoin implements Join { + private final JoinType joinType; + private final Optional<Expression> condition; - Table getTable(); + public FakeJoin(JoinType joinType, Optional<Expression> condition) { + this.joinType = joinType; + this.condition = condition; + } + + @Override + public JoinType getJoinType() { + return joinType; + } - default List<Slot> getOutput() { - return Collections.emptyList(); + @Override + public Optional<Expression> getCondition() { + return condition; } } diff --git a/regression-test/data/nereids_syntax_p0/join.out b/regression-test/data/nereids_syntax_p0/join.out index 2a1cc0480a..2285f8357e 100644 --- a/regression-test/data/nereids_syntax_p0/join.out +++ b/regression-test/data/nereids_syntax_p0/join.out @@ -43,3 +43,14 @@ -- !right_anti_join -- +-- !cross_join -- +1309892 1 1303 1432 15 19920517 3-MEDIUM 0 24 2959704 5119906 7 2752524 73992 0 19920619 TRUCK 15 Supplier#000000015 DF35PepL5saAK INDIA 0 INDIA ASIA 18-687-542-7601 +1309892 1 1303 1432 15 19920517 3-MEDIUM 0 24 2959704 5119906 7 2752524 73992 0 19920619 TRUCK 29 Supplier#000000029 VVSymB3fbwaN ARGENTINA4 ARGENTINA AMERICA 11-773-203-7342 +1309892 1 1303 1432 15 19920517 3-MEDIUM 0 24 2959704 5119906 7 2752524 73992 0 19920619 TRUCK 9 Supplier#000000009 ,gJ6K2MKveYxQT IRAN 6 IRAN MIDDLE EAST 20-338-906-3675 +1309892 2 1303 1165 9 19920517 3-MEDIUM 0 21 2404899 5119906 8 2212507 68711 7 19920616 RAIL 15 Supplier#000000015 DF35PepL5saAK INDIA 0 INDIA ASIA 18-687-542-7601 +1309892 2 1303 1165 9 19920517 3-MEDIUM 0 21 2404899 5119906 8 2212507 68711 7 19920616 RAIL 29 Supplier#000000029 VVSymB3fbwaN ARGENTINA4 ARGENTINA AMERICA 11-773-203-7342 +1309892 2 1303 1165 9 19920517 3-MEDIUM 0 21 2404899 5119906 8 2212507 68711 7 19920616 RAIL 9 Supplier#000000009 ,gJ6K2MKveYxQT IRAN 6 IRAN MIDDLE EAST 20-338-906-3675 +1310179 6 1312 1455 29 19921110 3-MEDIUM 0 15 1705830 20506457 10 1535247 68233 8 19930114 FOB 15 Supplier#000000015 DF35PepL5saAK INDIA 0 INDIA ASIA 18-687-542-7601 +1310179 6 1312 1455 29 19921110 3-MEDIUM 0 15 1705830 20506457 10 1535247 68233 8 19930114 FOB 29 Supplier#000000029 VVSymB3fbwaN ARGENTINA4 ARGENTINA AMERICA 11-773-203-7342 +1310179 6 1312 1455 29 19921110 3-MEDIUM 0 15 1705830 20506457 10 1535247 68233 8 19930114 FOB 9 Supplier#000000009 ,gJ6K2MKveYxQT IRAN 6 IRAN MIDDLE EAST 20-338-906-3675 + diff --git a/regression-test/suites/nereids_syntax_p0/join.groovy b/regression-test/suites/nereids_syntax_p0/join.groovy index 0f598e78b1..ccae67bf71 100644 --- a/regression-test/suites/nereids_syntax_p0/join.groovy +++ b/regression-test/suites/nereids_syntax_p0/join.groovy @@ -63,5 +63,9 @@ suite("join") { order_qt_right_anti_join """ SELECT * FROM lineorder RIGHT ANTI JOIN supplier ON lineorder.lo_suppkey = supplier.s_suppkey """ + + order_qt_cross_join """ + SELECT * FROM lineorder CROSS JOIN supplier; + """ } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org