This is an automated email from the ASF dual-hosted git repository. dataroaring pushed a commit to branch branch-3.0 in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.0 by this push: new a63832c05ff [fix](nerieds) avoid redundant enumeration same LogicalProject in memo (#38317) a63832c05ff is described below commit a63832c05ff867c7b3a7b41ba4e3fcac7d73ad75 Author: morrySnow <101034200+morrys...@users.noreply.github.com> AuthorDate: Mon Jul 29 11:48:30 2024 +0800 [fix](nerieds) avoid redundant enumeration same LogicalProject in memo (#38317) 1. use set to compare project 2. use map to store enforcer 3. avoid genarate useless project under bottom join when do join reorder --- .../org/apache/doris/nereids/NereidsPlanner.java | 2 +- .../doris/nereids/jobs/cascades/ApplyRuleJob.java | 5 +++ .../java/org/apache/doris/nereids/memo/Group.java | 12 +++--- .../java/org/apache/doris/nereids/memo/Memo.java | 7 ++-- .../java/org/apache/doris/nereids/rules/Rule.java | 4 ++ .../org/apache/doris/nereids/rules/RuleType.java | 47 +++++++++++----------- .../doris/nereids/rules/exploration/CBOUtils.java | 7 ++++ .../exploration/join/InnerJoinLAsscomProject.java | 2 +- .../join/InnerJoinLeftAssociateProject.java | 2 +- .../join/InnerJoinRightAssociateProject.java | 2 +- .../join/LogicalJoinSemiJoinTransposeProject.java | 4 +- .../exploration/join/OuterJoinAssocProject.java | 2 +- .../exploration/join/OuterJoinLAsscomProject.java | 2 +- .../join/SemiJoinSemiJoinTransposeProject.java | 2 +- .../trees/plans/logical/LogicalProject.java | 9 ++++- .../trees/plans/physical/PhysicalProject.java | 13 ++++-- .../trees/plans/physical/PhysicalUnion.java | 6 +-- .../shape/query72.out | 14 +++---- .../nereids_tpch_shape_sf1000_p0/rf_prune/q21.out | 16 ++++---- .../nereids_tpch_shape_sf1000_p0/shape/q21.out | 16 ++++---- .../new_shapes_p0/tpcds_sf1000/shape/query72.out | 14 +++---- .../new_shapes_p0/tpch_sf1000/rf_prune/q21.out | 16 ++++---- .../data/new_shapes_p0/tpch_sf1000/shape/q21.out | 16 ++++---- 23 files changed, 124 insertions(+), 96 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java index 41cfbb659a9..046686255c1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java @@ -446,7 +446,7 @@ public class NereidsPlanner extends Planner { GroupExpression groupExpression = rootGroup.getLowestCostPlan(physicalProperties).orElseThrow( () -> new AnalysisException("lowestCostPlans with physicalProperties(" + physicalProperties + ") doesn't exist in root group")).second; - if (rootGroup.getEnforcers().contains(groupExpression)) { + if (rootGroup.getEnforcers().containsKey(groupExpression)) { rootGroup.addChosenEnforcerId(groupExpression.getId().asInt()); rootGroup.addChosenEnforcerProperties(physicalProperties); } else { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java index eb4f86bb0ca..18b9b86dae7 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java @@ -74,6 +74,11 @@ public class ApplyRuleJob extends Job { GroupExpressionMatching groupExpressionMatching = new GroupExpressionMatching(rule.getPattern(), groupExpression); for (Plan plan : groupExpressionMatching) { + if (rule.isExploration() + && context.getCascadesContext().getMemo().getGroupExpressionsSize() > context.getCascadesContext() + .getConnectContext().getSessionVariable().memoMaxGroupExpressionSize) { + break; + } List<Plan> newPlans = rule.transform(plan, context.getCascadesContext()); for (Plan newPlan : newPlans) { if (newPlan == plan) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Group.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Group.java index 2f1e34fae5a..a01db5546cb 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Group.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Group.java @@ -59,7 +59,7 @@ public class Group { private final List<GroupExpression> logicalExpressions = Lists.newArrayList(); private final List<GroupExpression> physicalExpressions = Lists.newArrayList(); - private final List<GroupExpression> enforcers = Lists.newArrayList(); + private final Map<GroupExpression, GroupExpression> enforcers = Maps.newHashMap(); private boolean isStatsReliable = true; private LogicalProperties logicalProperties; @@ -239,10 +239,10 @@ public class Group { public void addEnforcer(GroupExpression enforcer) { enforcer.setOwnerGroup(this); - enforcers.add(enforcer); + enforcers.put(enforcer, enforcer); } - public List<GroupExpression> getEnforcers() { + public Map<GroupExpression, GroupExpression> getEnforcers() { return enforcers; } @@ -346,9 +346,9 @@ public class Group { parentExpressions.keySet().forEach(parent -> target.addParentExpression(parent)); // move enforcers Ownership - enforcers.forEach(ge -> ge.children().set(0, target)); + enforcers.forEach((k, v) -> k.children().set(0, target)); // TODO: dedup? - enforcers.forEach(enforcer -> target.addEnforcer(enforcer)); + enforcers.forEach((k, v) -> target.addEnforcer(k)); enforcers.clear(); // move LogicalExpression PhysicalExpression Ownership @@ -458,7 +458,7 @@ public class Group { str.append(" ").append(physicalExpression).append("\n"); } str.append(" enforcers:\n"); - for (GroupExpression enforcer : enforcers) { + for (GroupExpression enforcer : enforcers.keySet()) { str.append(" ").append(enforcer).append("\n"); } if (!chosenEnforcerIdList.isEmpty()) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java index 6c530c6aa2f..c34aa00a053 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java @@ -552,8 +552,7 @@ public class Memo { return; } Group parentOwnerGroup = srcParent.getOwnerGroup(); - HashSet<GroupExpression> enforcers = new HashSet<>(parentOwnerGroup.getEnforcers()); - if (enforcers.contains(srcParent)) { + if (parentOwnerGroup.getEnforcers().containsKey(srcParent)) { continue; } needReplaceChild.add(srcParent); @@ -946,7 +945,7 @@ public class Memo { List<GroupExpression> exprs = Lists.newArrayList(bestExpr); Set<GroupExpression> hasVisited = new HashSet<>(); hasVisited.add(bestExpr); - Stream.concat(group.getPhysicalExpressions().stream(), group.getEnforcers().stream()) + Stream.concat(group.getPhysicalExpressions().stream(), group.getEnforcers().keySet().stream()) .forEach(groupExpression -> { if (!groupExpression.getInputPropertiesListOrEmpty(prop).isEmpty() && !groupExpression.equals(bestExpr) && !hasVisited.contains(groupExpression)) { @@ -969,7 +968,7 @@ public class Memo { res.add(groupExpression.getInputPropertiesList(prop)); // return optimized input for enforcer - if (groupExpression.getOwnerGroup().getEnforcers().contains(groupExpression)) { + if (groupExpression.getOwnerGroup().getEnforcers().containsKey(groupExpression)) { return res; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/Rule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/Rule.java index 207dd6458c9..7d5b4001d9a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/Rule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/Rule.java @@ -64,6 +64,10 @@ public abstract class Rule { return ruleType.getRuleTypeClass() == RuleTypeClass.REWRITE; } + public boolean isExploration() { + return ruleType.getRuleTypeClass() == RuleTypeClass.EXPLORATION; + } + @Override public String toString() { return getRuleType().toString(); 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 7525d2a960d..f2c572f7779 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 @@ -384,29 +384,29 @@ public enum RuleType { EAGER_SPLIT(RuleTypeClass.EXPLORATION), EXPLORATION_SENTINEL(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_PROJECT_JOIN(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_FILTER_JOIN(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_PROJECT_FILTER_JOIN(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_FILTER_PROJECT_JOIN(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_ONLY_JOIN(RuleTypeClass.EXPLORATION), - - MATERIALIZED_VIEW_PROJECT_AGGREGATE(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_FILTER_AGGREGATE(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_PROJECT_FILTER_AGGREGATE(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_FILTER_PROJECT_AGGREGATE(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_ONLY_AGGREGATE(RuleTypeClass.EXPLORATION), - - MATERIALIZED_VIEW_PROJECT_AGGREGATE_ON_NONE_AGGREGATE(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_FILTER_AGGREGATE_ON_NONE_AGGREGATE(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_PROJECT_FILTER_AGGREGATE_ON_NONE_AGGREGATE(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_FILTER_PROJECT_AGGREGATE_ON_NONE_AGGREGATE(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_ONLY_AGGREGATE_ON_NONE_AGGREGATE(RuleTypeClass.EXPLORATION), - - MATERIALIZED_VIEW_FILTER_SCAN(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_PROJECT_SCAN(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_FILTER_PROJECT_SCAN(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_PROJECT_FILTER_SCAN(RuleTypeClass.EXPLORATION), - MATERIALIZED_VIEW_ONLY_SCAN(RuleTypeClass.EXPLORATION), + MATERIALIZED_VIEW_PROJECT_JOIN(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_FILTER_JOIN(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_PROJECT_FILTER_JOIN(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_FILTER_PROJECT_JOIN(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_ONLY_JOIN(RuleTypeClass.MATERIALIZE_VIEW), + + MATERIALIZED_VIEW_PROJECT_AGGREGATE(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_FILTER_AGGREGATE(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_PROJECT_FILTER_AGGREGATE(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_FILTER_PROJECT_AGGREGATE(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_ONLY_AGGREGATE(RuleTypeClass.MATERIALIZE_VIEW), + + MATERIALIZED_VIEW_PROJECT_AGGREGATE_ON_NONE_AGGREGATE(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_FILTER_AGGREGATE_ON_NONE_AGGREGATE(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_PROJECT_FILTER_AGGREGATE_ON_NONE_AGGREGATE(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_FILTER_PROJECT_AGGREGATE_ON_NONE_AGGREGATE(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_ONLY_AGGREGATE_ON_NONE_AGGREGATE(RuleTypeClass.MATERIALIZE_VIEW), + + MATERIALIZED_VIEW_FILTER_SCAN(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_PROJECT_SCAN(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_FILTER_PROJECT_SCAN(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_PROJECT_FILTER_SCAN(RuleTypeClass.MATERIALIZE_VIEW), + MATERIALIZED_VIEW_ONLY_SCAN(RuleTypeClass.MATERIALIZE_VIEW), // implementation rules LOGICAL_ONE_ROW_RELATION_TO_PHYSICAL_ONE_ROW_RELATION(RuleTypeClass.IMPLEMENTATION), @@ -494,6 +494,7 @@ public enum RuleType { enum RuleTypeClass { REWRITE, EXPLORATION, + MATERIALIZE_VIEW, // This type is used for unit test only. CHECK, IMPLEMENTATION, diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/CBOUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/CBOUtils.java index c069dfe0be5..0ac0c6ea415 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/CBOUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/CBOUtils.java @@ -42,6 +42,13 @@ public class CBOUtils { .collect(Collectors.toSet()); } + public static Plan newProjectIfNeeded(Set<ExprId> requiredExprIds, Plan plan) { + if (requiredExprIds.equals(plan.getOutputExprIdSet())) { + return plan; + } + return newProject(requiredExprIds, plan); + } + public static Plan newProject(Set<ExprId> requiredExprIds, Plan plan) { List<NamedExpression> projects = plan.getOutput().stream() .filter(namedExpr -> requiredExprIds.contains(namedExpr.getExprId())) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinLAsscomProject.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinLAsscomProject.java index b13451cfe3e..9ff7f01b829 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinLAsscomProject.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinLAsscomProject.java @@ -98,7 +98,7 @@ public class InnerJoinLAsscomProject extends OneExplorationRuleFactory { newTopHashConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds())); newTopOtherConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds())); Plan left = CBOUtils.newProject(topUsedExprIds, newBottomJoin); - Plan right = CBOUtils.newProject(topUsedExprIds, b); + Plan right = CBOUtils.newProjectIfNeeded(topUsedExprIds, b); LogicalJoin<Plan, Plan> newTopJoin = bottomJoin.withConjunctsChildren(newTopHashConjuncts, newTopOtherConjuncts, left, right, null); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinLeftAssociateProject.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinLeftAssociateProject.java index 50666fdaa9d..e836eac3692 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinLeftAssociateProject.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinLeftAssociateProject.java @@ -85,7 +85,7 @@ public class InnerJoinLeftAssociateProject extends OneExplorationRuleFactory { newTopHashConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds())); newTopOtherConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds())); Plan left = CBOUtils.newProject(topUsedExprIds, newBottomJoin); - Plan right = CBOUtils.newProject(topUsedExprIds, c); + Plan right = CBOUtils.newProjectIfNeeded(topUsedExprIds, c); LogicalJoin<Plan, Plan> newTopJoin = bottomJoin.withConjunctsChildren( newTopHashConjuncts, newTopOtherConjuncts, left, right, null); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinRightAssociateProject.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinRightAssociateProject.java index c2198725f8b..841963e9a7b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinRightAssociateProject.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinRightAssociateProject.java @@ -81,7 +81,7 @@ public class InnerJoinRightAssociateProject extends OneExplorationRuleFactory { topProject.getProjects().forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds())); newTopHashConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds())); newTopOtherConjuncts.forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds())); - Plan left = CBOUtils.newProject(topUsedExprIds, a); + Plan left = CBOUtils.newProjectIfNeeded(topUsedExprIds, a); Plan right = CBOUtils.newProject(topUsedExprIds, newBottomJoin); LogicalJoin<Plan, Plan> newTopJoin = bottomJoin.withConjunctsChildren( diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/LogicalJoinSemiJoinTransposeProject.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/LogicalJoinSemiJoinTransposeProject.java index 75d05b7f35d..a0e2b83cc1b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/LogicalJoinSemiJoinTransposeProject.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/LogicalJoinSemiJoinTransposeProject.java @@ -70,7 +70,7 @@ public class LogicalJoinSemiJoinTransposeProject implements ExplorationRuleFacto .forEach(e -> topUsedExprIds.addAll(e.getInputSlotExprIds())); Plan newBottomJoin = topJoin.withChildrenNoContext(a, c, null); Plan left = CBOUtils.newProject(topUsedExprIds, newBottomJoin); - Plan right = CBOUtils.newProject(topUsedExprIds, b); + Plan right = CBOUtils.newProjectIfNeeded(topUsedExprIds, b); Plan newTopJoin = bottomJoin.withChildrenNoContext(left, right, null); return topProject.withChildren(newTopJoin); @@ -102,7 +102,7 @@ public class LogicalJoinSemiJoinTransposeProject implements ExplorationRuleFacto .forEach(e -> topUsedExprIds.addAll(e.getInputSlotExprIds())); Plan newBottomJoin = topJoin.withChildrenNoContext(a, b, null); Plan left = CBOUtils.newProject(topUsedExprIds, newBottomJoin); - Plan right = CBOUtils.newProject(topUsedExprIds, c); + Plan right = CBOUtils.newProjectIfNeeded(topUsedExprIds, c); Plan newTopJoin = bottomJoin.withChildrenNoContext(left, right, null); return topProject.withChildren(newTopJoin); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/OuterJoinAssocProject.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/OuterJoinAssocProject.java index 12d2560a364..af8f002afbd 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/OuterJoinAssocProject.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/OuterJoinAssocProject.java @@ -104,7 +104,7 @@ public class OuterJoinAssocProject extends OneExplorationRuleFactory { topProject.getProjects().forEach(expr -> topUsedExprIds.addAll(expr.getInputSlotExprIds())); bottomJoin.getHashJoinConjuncts().forEach(e -> topUsedExprIds.addAll(e.getInputSlotExprIds())); bottomJoin.getOtherJoinConjuncts().forEach(e -> topUsedExprIds.addAll(e.getInputSlotExprIds())); - Plan left = CBOUtils.newProject(topUsedExprIds, a); + Plan left = CBOUtils.newProjectIfNeeded(topUsedExprIds, a); Plan right = CBOUtils.newProject(topUsedExprIds, newBottomJoin); LogicalJoin newTopJoin = bottomJoin.withChildrenNoContext(left, right, null); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/OuterJoinLAsscomProject.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/OuterJoinLAsscomProject.java index 6fe0bb1a458..b8948b22bde 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/OuterJoinLAsscomProject.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/OuterJoinLAsscomProject.java @@ -90,7 +90,7 @@ public class OuterJoinLAsscomProject extends OneExplorationRuleFactory { bottomJoin.getHashJoinConjuncts().forEach(e -> topUsedExprIds.addAll(e.getInputSlotExprIds())); bottomJoin.getOtherJoinConjuncts().forEach(e -> topUsedExprIds.addAll(e.getInputSlotExprIds())); Plan left = CBOUtils.newProject(topUsedExprIds, newBottomJoin); - Plan right = CBOUtils.newProject(topUsedExprIds, b); + Plan right = CBOUtils.newProjectIfNeeded(topUsedExprIds, b); LogicalJoin newTopJoin = bottomJoin.withChildrenNoContext(left, right, null); newTopJoin.getJoinReorderContext().copyFrom(topJoin.getJoinReorderContext()); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinSemiJoinTransposeProject.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinSemiJoinTransposeProject.java index 5c61ae2b526..b4a5b177f8c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinSemiJoinTransposeProject.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinSemiJoinTransposeProject.java @@ -106,7 +106,7 @@ public class SemiJoinSemiJoinTransposeProject extends OneExplorationRuleFactory bottomSemi.getOtherJoinConjuncts().forEach(e -> topUsedExprIds.addAll(e.getInputSlotExprIds())); Plan left = CBOUtils.newProject(topUsedExprIds, newBottomSemi); - Plan right = CBOUtils.newProject(topUsedExprIds, b); + Plan right = CBOUtils.newProjectIfNeeded(topUsedExprIds, b); LogicalJoin newTopSemi = bottomSemi.withChildrenNoContext(left, right, null); newTopSemi.getJoinReorderContext().copyFrom(topSemi.getJoinReorderContext()); 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 44b97086aa0..fc07ba876bd 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 @@ -36,6 +36,8 @@ import org.apache.doris.nereids.util.ExpressionUtils; import org.apache.doris.nereids.util.Utils; import com.google.common.base.Preconditions; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.ImmutableSet; @@ -46,6 +48,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; /** * Logical project plan. @@ -54,6 +57,7 @@ public class LogicalProject<CHILD_TYPE extends Plan> extends LogicalUnary<CHILD_ implements Project, OutputPrunable { private final List<NamedExpression> projects; + private final Supplier<Set<NamedExpression>> projectsSet; private final List<NamedExpression> excepts; private final boolean isDistinct; @@ -83,6 +87,7 @@ public class LogicalProject<CHILD_TYPE extends Plan> extends LogicalUnary<CHILD_ this.projects = projects.isEmpty() ? ImmutableList.of(ExpressionUtils.selectMinimumColumn(child.get(0).getOutput())) : projects; + this.projectsSet = Suppliers.memoize(() -> ImmutableSet.copyOf(this.projects)); this.excepts = Utils.fastToImmutableList(excepts); this.isDistinct = isDistinct; } @@ -138,7 +143,7 @@ public class LogicalProject<CHILD_TYPE extends Plan> extends LogicalUnary<CHILD_ return false; } LogicalProject<?> that = (LogicalProject<?>) o; - boolean equal = projects.equals(that.projects) + boolean equal = projectsSet.get().equals(that.projectsSet.get()) && excepts.equals(that.excepts) && isDistinct == that.isDistinct; // TODO: should add exprId for UnBoundStar and BoundStar for equality comparison @@ -150,7 +155,7 @@ public class LogicalProject<CHILD_TYPE extends Plan> extends LogicalUnary<CHILD_ @Override public int hashCode() { - return Objects.hash(projects); + return Objects.hash(projectsSet.get()); } @Override 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 02769e47524..0e7bdf36e8f 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 @@ -34,12 +34,16 @@ import org.apache.doris.nereids.util.Utils; import org.apache.doris.statistics.Statistics; import com.google.common.base.Preconditions; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.Set; /** * Physical project plan. @@ -47,6 +51,7 @@ import java.util.Optional; public class PhysicalProject<CHILD_TYPE extends Plan> extends PhysicalUnary<CHILD_TYPE> implements Project { private final List<NamedExpression> projects; + private final Supplier<Set<NamedExpression>> projectsSet; //multiLayerProjects is used to extract common expressions // projects: (A+B) * 2, (A+B) * 3 // multiLayerProjects: @@ -62,6 +67,7 @@ public class PhysicalProject<CHILD_TYPE extends Plan> extends PhysicalUnary<CHIL LogicalProperties logicalProperties, CHILD_TYPE child) { super(PlanType.PHYSICAL_PROJECT, groupExpression, logicalProperties, child); this.projects = ImmutableList.copyOf(Objects.requireNonNull(projects, "projects can not be null")); + this.projectsSet = Suppliers.memoize(() -> ImmutableSet.copyOf(this.projects)); } public PhysicalProject(List<NamedExpression> projects, Optional<GroupExpression> groupExpression, @@ -70,6 +76,7 @@ public class PhysicalProject<CHILD_TYPE extends Plan> extends PhysicalUnary<CHIL super(PlanType.PHYSICAL_PROJECT, groupExpression, logicalProperties, physicalProperties, statistics, child); this.projects = ImmutableList.copyOf(Objects.requireNonNull(projects, "projects can not be null")); + this.projectsSet = Suppliers.memoize(() -> ImmutableSet.copyOf(this.projects)); } public List<NamedExpression> getProjects() { @@ -96,13 +103,13 @@ public class PhysicalProject<CHILD_TYPE extends Plan> extends PhysicalUnary<CHIL if (o == null || getClass() != o.getClass()) { return false; } - PhysicalProject that = (PhysicalProject) o; - return projects.equals(that.projects); + PhysicalProject<?> that = (PhysicalProject<?>) o; + return projectsSet.get().equals(that.projectsSet.get()); } @Override public int hashCode() { - return Objects.hash(projects); + return Objects.hash(projectsSet.get()); } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalUnion.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalUnion.java index b3b3eb9e5f7..ba20c926705 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalUnion.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalUnion.java @@ -88,7 +88,7 @@ public class PhysicalUnion extends PhysicalSetOperation implements Union { @Override public String toString() { - return Utils.toSqlString("PhysicalUnion" + getGroupIdWithPrefix(), + return Utils.toSqlString("PhysicalUnion" + "[" + id.asInt() + "]" + getGroupIdWithPrefix(), "qualifier", qualifier, "outputs", outputs, "regularChildrenOutputs", regularChildrenOutputs, @@ -98,7 +98,7 @@ public class PhysicalUnion extends PhysicalSetOperation implements Union { @Override public PhysicalUnion withChildren(List<Plan> children) { - return new PhysicalUnion(qualifier, outputs, regularChildrenOutputs, constantExprsList, + return new PhysicalUnion(qualifier, outputs, regularChildrenOutputs, constantExprsList, groupExpression, getLogicalProperties(), children); } @@ -119,7 +119,7 @@ public class PhysicalUnion extends PhysicalSetOperation implements Union { public PhysicalUnion withPhysicalPropertiesAndStats( PhysicalProperties physicalProperties, Statistics statistics) { return new PhysicalUnion(qualifier, outputs, regularChildrenOutputs, constantExprsList, - Optional.empty(), getLogicalProperties(), physicalProperties, statistics, children); + groupExpression, getLogicalProperties(), physicalProperties, statistics, children); } @Override diff --git a/regression-test/data/nereids_tpcds_shape_sf1000_p0/shape/query72.out b/regression-test/data/nereids_tpcds_shape_sf1000_p0/shape/query72.out index 67ebfbb69dc..45708bb80f5 100644 --- a/regression-test/data/nereids_tpcds_shape_sf1000_p0/shape/query72.out +++ b/regression-test/data/nereids_tpcds_shape_sf1000_p0/shape/query72.out @@ -8,14 +8,12 @@ PhysicalResultSink ----------PhysicalDistribute[DistributionSpecHash] ------------hashAgg[LOCAL] --------------PhysicalProject -----------------hashJoin[INNER_JOIN broadcast] hashCondition=((warehouse.w_warehouse_sk = inventory.inv_warehouse_sk)) otherCondition=() build RFs:RF10 w_warehouse_sk->[inv_warehouse_sk] +----------------hashJoin[LEFT_OUTER_JOIN shuffle] hashCondition=((catalog_returns.cr_item_sk = catalog_sales.cs_item_sk) and (catalog_returns.cr_order_number = catalog_sales.cs_order_number)) otherCondition=() ------------------PhysicalProject ---------------------hashJoin[INNER_JOIN shuffle] hashCondition=((catalog_sales.cs_item_sk = inventory.inv_item_sk) and (inventory.inv_date_sk = d2.d_date_sk)) otherCondition=((inventory.inv_quantity_on_hand < catalog_sales.cs_quantity)) build RFs:RF8 d_date_sk->[inv_date_sk];RF9 cs_item_sk->[inv_item_sk] -----------------------PhysicalOlapScan[inventory] apply RFs: RF8 RF9 RF10 +--------------------hashJoin[INNER_JOIN broadcast] hashCondition=((warehouse.w_warehouse_sk = inventory.inv_warehouse_sk)) otherCondition=() build RFs:RF8 w_warehouse_sk->[inv_warehouse_sk] ----------------------PhysicalProject -------------------------hashJoin[RIGHT_OUTER_JOIN shuffle] hashCondition=((catalog_returns.cr_item_sk = catalog_sales.cs_item_sk) and (catalog_returns.cr_order_number = catalog_sales.cs_order_number)) otherCondition=() build RFs:RF6 cs_item_sk->[cr_item_sk];RF7 cs_order_number->[cr_order_number] ---------------------------PhysicalProject -----------------------------PhysicalOlapScan[catalog_returns] apply RFs: RF6 RF7 +------------------------hashJoin[INNER_JOIN shuffle] hashCondition=((catalog_sales.cs_item_sk = inventory.inv_item_sk) and (inventory.inv_date_sk = d2.d_date_sk)) otherCondition=((inventory.inv_quantity_on_hand < catalog_sales.cs_quantity)) build RFs:RF6 d_date_sk->[inv_date_sk];RF7 cs_item_sk->[inv_item_sk] +--------------------------PhysicalOlapScan[inventory] apply RFs: RF6 RF7 RF8 --------------------------PhysicalProject ----------------------------hashJoin[INNER_JOIN broadcast] hashCondition=((d1.d_week_seq = d2.d_week_seq)) otherCondition=() build RFs:RF5 d_week_seq->[d_week_seq] ------------------------------PhysicalProject @@ -49,6 +47,8 @@ PhysicalResultSink ------------------------------------PhysicalOlapScan[item] ------------------------------PhysicalProject --------------------------------PhysicalOlapScan[date_dim] +----------------------PhysicalProject +------------------------PhysicalOlapScan[warehouse] ------------------PhysicalProject ---------------------PhysicalOlapScan[warehouse] +--------------------PhysicalOlapScan[catalog_returns] diff --git a/regression-test/data/nereids_tpch_shape_sf1000_p0/rf_prune/q21.out b/regression-test/data/nereids_tpch_shape_sf1000_p0/rf_prune/q21.out index 6f08b5e9c35..0436a7b245b 100644 --- a/regression-test/data/nereids_tpch_shape_sf1000_p0/rf_prune/q21.out +++ b/regression-test/data/nereids_tpch_shape_sf1000_p0/rf_prune/q21.out @@ -11,15 +11,15 @@ PhysicalResultSink ----------------hashJoin[RIGHT_SEMI_JOIN colocated] hashCondition=((l2.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF4 l_orderkey->[l_orderkey] ------------------PhysicalProject --------------------PhysicalOlapScan[lineitem] apply RFs: RF4 -------------------PhysicalProject ---------------------hashJoin[INNER_JOIN colocated] hashCondition=((orders.o_orderkey = l1.l_orderkey)) otherCondition=() build RFs:RF3 l_orderkey->[o_orderkey] -----------------------PhysicalProject -------------------------filter((orders.o_orderstatus = 'F')) ---------------------------PhysicalOlapScan[orders] apply RFs: RF3 -----------------------hashJoin[RIGHT_ANTI_JOIN colocated] hashCondition=((l3.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF2 l_orderkey->[l_orderkey] +------------------hashJoin[RIGHT_ANTI_JOIN colocated] hashCondition=((l3.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF3 l_orderkey->[l_orderkey] +--------------------PhysicalProject +----------------------filter((l3.l_receiptdate > l3.l_commitdate)) +------------------------PhysicalOlapScan[lineitem] apply RFs: RF3 +--------------------PhysicalProject +----------------------hashJoin[INNER_JOIN colocated] hashCondition=((orders.o_orderkey = l1.l_orderkey)) otherCondition=() build RFs:RF2 l_orderkey->[o_orderkey] ------------------------PhysicalProject ---------------------------filter((l3.l_receiptdate > l3.l_commitdate)) -----------------------------PhysicalOlapScan[lineitem] apply RFs: RF2 +--------------------------filter((orders.o_orderstatus = 'F')) +----------------------------PhysicalOlapScan[orders] apply RFs: RF2 ------------------------PhysicalProject --------------------------hashJoin[INNER_JOIN broadcast] hashCondition=((supplier.s_suppkey = l1.l_suppkey)) otherCondition=() build RFs:RF1 s_suppkey->[l_suppkey] ----------------------------PhysicalProject diff --git a/regression-test/data/nereids_tpch_shape_sf1000_p0/shape/q21.out b/regression-test/data/nereids_tpch_shape_sf1000_p0/shape/q21.out index 6f08b5e9c35..0436a7b245b 100644 --- a/regression-test/data/nereids_tpch_shape_sf1000_p0/shape/q21.out +++ b/regression-test/data/nereids_tpch_shape_sf1000_p0/shape/q21.out @@ -11,15 +11,15 @@ PhysicalResultSink ----------------hashJoin[RIGHT_SEMI_JOIN colocated] hashCondition=((l2.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF4 l_orderkey->[l_orderkey] ------------------PhysicalProject --------------------PhysicalOlapScan[lineitem] apply RFs: RF4 -------------------PhysicalProject ---------------------hashJoin[INNER_JOIN colocated] hashCondition=((orders.o_orderkey = l1.l_orderkey)) otherCondition=() build RFs:RF3 l_orderkey->[o_orderkey] -----------------------PhysicalProject -------------------------filter((orders.o_orderstatus = 'F')) ---------------------------PhysicalOlapScan[orders] apply RFs: RF3 -----------------------hashJoin[RIGHT_ANTI_JOIN colocated] hashCondition=((l3.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF2 l_orderkey->[l_orderkey] +------------------hashJoin[RIGHT_ANTI_JOIN colocated] hashCondition=((l3.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF3 l_orderkey->[l_orderkey] +--------------------PhysicalProject +----------------------filter((l3.l_receiptdate > l3.l_commitdate)) +------------------------PhysicalOlapScan[lineitem] apply RFs: RF3 +--------------------PhysicalProject +----------------------hashJoin[INNER_JOIN colocated] hashCondition=((orders.o_orderkey = l1.l_orderkey)) otherCondition=() build RFs:RF2 l_orderkey->[o_orderkey] ------------------------PhysicalProject ---------------------------filter((l3.l_receiptdate > l3.l_commitdate)) -----------------------------PhysicalOlapScan[lineitem] apply RFs: RF2 +--------------------------filter((orders.o_orderstatus = 'F')) +----------------------------PhysicalOlapScan[orders] apply RFs: RF2 ------------------------PhysicalProject --------------------------hashJoin[INNER_JOIN broadcast] hashCondition=((supplier.s_suppkey = l1.l_suppkey)) otherCondition=() build RFs:RF1 s_suppkey->[l_suppkey] ----------------------------PhysicalProject diff --git a/regression-test/data/new_shapes_p0/tpcds_sf1000/shape/query72.out b/regression-test/data/new_shapes_p0/tpcds_sf1000/shape/query72.out index 9ff0cd2f442..b9d2d9210df 100644 --- a/regression-test/data/new_shapes_p0/tpcds_sf1000/shape/query72.out +++ b/regression-test/data/new_shapes_p0/tpcds_sf1000/shape/query72.out @@ -8,14 +8,12 @@ PhysicalResultSink ----------PhysicalDistribute[DistributionSpecHash] ------------hashAgg[LOCAL] --------------PhysicalProject -----------------hashJoin[INNER_JOIN broadcast] hashCondition=((warehouse.w_warehouse_sk = inventory.inv_warehouse_sk)) otherCondition=() build RFs:RF10 w_warehouse_sk->[inv_warehouse_sk] +----------------hashJoin[LEFT_OUTER_JOIN bucketShuffle] hashCondition=((catalog_returns.cr_item_sk = catalog_sales.cs_item_sk) and (catalog_returns.cr_order_number = catalog_sales.cs_order_number)) otherCondition=() ------------------PhysicalProject ---------------------hashJoin[INNER_JOIN shuffle] hashCondition=((catalog_sales.cs_item_sk = inventory.inv_item_sk) and (inventory.inv_date_sk = d2.d_date_sk)) otherCondition=((inventory.inv_quantity_on_hand < catalog_sales.cs_quantity)) build RFs:RF8 d_date_sk->[inv_date_sk];RF9 cs_item_sk->[inv_item_sk] -----------------------PhysicalOlapScan[inventory] apply RFs: RF8 RF9 RF10 +--------------------hashJoin[INNER_JOIN broadcast] hashCondition=((warehouse.w_warehouse_sk = inventory.inv_warehouse_sk)) otherCondition=() build RFs:RF8 w_warehouse_sk->[inv_warehouse_sk] ----------------------PhysicalProject -------------------------hashJoin[RIGHT_OUTER_JOIN bucketShuffle] hashCondition=((catalog_returns.cr_item_sk = catalog_sales.cs_item_sk) and (catalog_returns.cr_order_number = catalog_sales.cs_order_number)) otherCondition=() build RFs:RF6 cs_item_sk->[cr_item_sk];RF7 cs_order_number->[cr_order_number] ---------------------------PhysicalProject -----------------------------PhysicalOlapScan[catalog_returns] apply RFs: RF6 RF7 +------------------------hashJoin[INNER_JOIN shuffleBucket] hashCondition=((catalog_sales.cs_item_sk = inventory.inv_item_sk) and (inventory.inv_date_sk = d2.d_date_sk)) otherCondition=((inventory.inv_quantity_on_hand < catalog_sales.cs_quantity)) build RFs:RF6 d_date_sk->[inv_date_sk];RF7 cs_item_sk->[inv_item_sk] +--------------------------PhysicalOlapScan[inventory] apply RFs: RF6 RF7 RF8 --------------------------PhysicalProject ----------------------------hashJoin[INNER_JOIN broadcast] hashCondition=((d1.d_week_seq = d2.d_week_seq)) otherCondition=() build RFs:RF5 d_week_seq->[d_week_seq] ------------------------------PhysicalProject @@ -49,6 +47,8 @@ PhysicalResultSink ------------------------------------PhysicalOlapScan[item] ------------------------------PhysicalProject --------------------------------PhysicalOlapScan[date_dim] +----------------------PhysicalProject +------------------------PhysicalOlapScan[warehouse] ------------------PhysicalProject ---------------------PhysicalOlapScan[warehouse] +--------------------PhysicalOlapScan[catalog_returns] diff --git a/regression-test/data/new_shapes_p0/tpch_sf1000/rf_prune/q21.out b/regression-test/data/new_shapes_p0/tpch_sf1000/rf_prune/q21.out index 6f08b5e9c35..0436a7b245b 100644 --- a/regression-test/data/new_shapes_p0/tpch_sf1000/rf_prune/q21.out +++ b/regression-test/data/new_shapes_p0/tpch_sf1000/rf_prune/q21.out @@ -11,15 +11,15 @@ PhysicalResultSink ----------------hashJoin[RIGHT_SEMI_JOIN colocated] hashCondition=((l2.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF4 l_orderkey->[l_orderkey] ------------------PhysicalProject --------------------PhysicalOlapScan[lineitem] apply RFs: RF4 -------------------PhysicalProject ---------------------hashJoin[INNER_JOIN colocated] hashCondition=((orders.o_orderkey = l1.l_orderkey)) otherCondition=() build RFs:RF3 l_orderkey->[o_orderkey] -----------------------PhysicalProject -------------------------filter((orders.o_orderstatus = 'F')) ---------------------------PhysicalOlapScan[orders] apply RFs: RF3 -----------------------hashJoin[RIGHT_ANTI_JOIN colocated] hashCondition=((l3.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF2 l_orderkey->[l_orderkey] +------------------hashJoin[RIGHT_ANTI_JOIN colocated] hashCondition=((l3.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF3 l_orderkey->[l_orderkey] +--------------------PhysicalProject +----------------------filter((l3.l_receiptdate > l3.l_commitdate)) +------------------------PhysicalOlapScan[lineitem] apply RFs: RF3 +--------------------PhysicalProject +----------------------hashJoin[INNER_JOIN colocated] hashCondition=((orders.o_orderkey = l1.l_orderkey)) otherCondition=() build RFs:RF2 l_orderkey->[o_orderkey] ------------------------PhysicalProject ---------------------------filter((l3.l_receiptdate > l3.l_commitdate)) -----------------------------PhysicalOlapScan[lineitem] apply RFs: RF2 +--------------------------filter((orders.o_orderstatus = 'F')) +----------------------------PhysicalOlapScan[orders] apply RFs: RF2 ------------------------PhysicalProject --------------------------hashJoin[INNER_JOIN broadcast] hashCondition=((supplier.s_suppkey = l1.l_suppkey)) otherCondition=() build RFs:RF1 s_suppkey->[l_suppkey] ----------------------------PhysicalProject diff --git a/regression-test/data/new_shapes_p0/tpch_sf1000/shape/q21.out b/regression-test/data/new_shapes_p0/tpch_sf1000/shape/q21.out index 6f08b5e9c35..0436a7b245b 100644 --- a/regression-test/data/new_shapes_p0/tpch_sf1000/shape/q21.out +++ b/regression-test/data/new_shapes_p0/tpch_sf1000/shape/q21.out @@ -11,15 +11,15 @@ PhysicalResultSink ----------------hashJoin[RIGHT_SEMI_JOIN colocated] hashCondition=((l2.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF4 l_orderkey->[l_orderkey] ------------------PhysicalProject --------------------PhysicalOlapScan[lineitem] apply RFs: RF4 -------------------PhysicalProject ---------------------hashJoin[INNER_JOIN colocated] hashCondition=((orders.o_orderkey = l1.l_orderkey)) otherCondition=() build RFs:RF3 l_orderkey->[o_orderkey] -----------------------PhysicalProject -------------------------filter((orders.o_orderstatus = 'F')) ---------------------------PhysicalOlapScan[orders] apply RFs: RF3 -----------------------hashJoin[RIGHT_ANTI_JOIN colocated] hashCondition=((l3.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF2 l_orderkey->[l_orderkey] +------------------hashJoin[RIGHT_ANTI_JOIN colocated] hashCondition=((l3.l_orderkey = l1.l_orderkey)) otherCondition=(( not (l_suppkey = l_suppkey))) build RFs:RF3 l_orderkey->[l_orderkey] +--------------------PhysicalProject +----------------------filter((l3.l_receiptdate > l3.l_commitdate)) +------------------------PhysicalOlapScan[lineitem] apply RFs: RF3 +--------------------PhysicalProject +----------------------hashJoin[INNER_JOIN colocated] hashCondition=((orders.o_orderkey = l1.l_orderkey)) otherCondition=() build RFs:RF2 l_orderkey->[o_orderkey] ------------------------PhysicalProject ---------------------------filter((l3.l_receiptdate > l3.l_commitdate)) -----------------------------PhysicalOlapScan[lineitem] apply RFs: RF2 +--------------------------filter((orders.o_orderstatus = 'F')) +----------------------------PhysicalOlapScan[orders] apply RFs: RF2 ------------------------PhysicalProject --------------------------hashJoin[INNER_JOIN broadcast] hashCondition=((supplier.s_suppkey = l1.l_suppkey)) otherCondition=() build RFs:RF1 s_suppkey->[l_suppkey] ----------------------------PhysicalProject --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org