This is an automated email from the ASF dual-hosted git repository.

kxiao pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git

commit 811a619cff2e3023f33eb1cf45062434ce317d8b
Author: morrySnow <[email protected]>
AuthorDate: Thu Aug 17 17:48:50 2023 +0800

    [fix](Nereids) non-inner join should not merge dist info (#22979)
    
    1. left join should use left dist info.
    2. right join should use right dist info.
    3. full outer join should return ANY dist info.
---
 .../properties/ChildOutputPropertyDeriver.java     |  37 ++-
 .../nereids/properties/DistributionSpecHash.java   |  18 +-
 .../org/apache/doris/nereids/util/JoinUtils.java   |   1 +
 .../properties/ChildOutputPropertyDeriverTest.java | 362 ++++++++++++++++++++-
 .../nereids_tpcds_shape_sf100_p0/shape/query95.out |  31 +-
 .../infer_predicate/infer_predicate.groovy         |  10 +-
 6 files changed, 403 insertions(+), 56 deletions(-)

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 97c197faa1..33df7657fa 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
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.properties;
 
 import org.apache.doris.nereids.PlanContext;
+import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.memo.GroupExpression;
 import org.apache.doris.nereids.properties.DistributionSpecHash.ShuffleType;
 import org.apache.doris.nereids.trees.expressions.Alias;
@@ -239,18 +240,32 @@ public class ChildOutputPropertyDeriver extends 
PlanVisitor<PhysicalProperties,
             DistributionSpecHash leftHashSpec = (DistributionSpecHash) 
leftOutputProperty.getDistributionSpec();
             DistributionSpecHash rightHashSpec = (DistributionSpecHash) 
rightOutputProperty.getDistributionSpec();
 
-            // colocate join
-            if (leftHashSpec.getShuffleType() == ShuffleType.NATURAL
-                    && rightHashSpec.getShuffleType() == ShuffleType.NATURAL) {
-                if (JoinUtils.couldColocateJoin(leftHashSpec, rightHashSpec)) {
-                    return new 
PhysicalProperties(DistributionSpecHash.merge(leftHashSpec, rightHashSpec));
-                }
+            switch (hashJoin.getJoinType()) {
+                case INNER_JOIN:
+                case CROSS_JOIN:
+                    return new PhysicalProperties(DistributionSpecHash.merge(
+                            leftHashSpec, rightHashSpec, 
leftHashSpec.getShuffleType()));
+                case LEFT_SEMI_JOIN:
+                case LEFT_ANTI_JOIN:
+                case NULL_AWARE_LEFT_ANTI_JOIN:
+                case LEFT_OUTER_JOIN:
+                    return new PhysicalProperties(leftHashSpec);
+                case RIGHT_SEMI_JOIN:
+                case RIGHT_ANTI_JOIN:
+                case RIGHT_OUTER_JOIN:
+                    if (JoinUtils.couldColocateJoin(leftHashSpec, 
rightHashSpec)) {
+                        return new PhysicalProperties(rightHashSpec);
+                    } else {
+                        // retain left shuffle type, since coordinator use 
left most node to schedule fragment
+                        // forbid colocate join, since right table already 
shuffle
+                        return new 
PhysicalProperties(rightHashSpec.withShuffleTypeAndForbidColocateJoin(
+                                leftHashSpec.getShuffleType()));
+                    }
+                case FULL_OUTER_JOIN:
+                    return PhysicalProperties.ANY;
+                default:
+                    throw new AnalysisException("unknown join type " + 
hashJoin.getJoinType());
             }
-
-            // shuffle, if left child is natural mean current join is bucket 
shuffle join
-            // and remain natural for colocate join on upper join.
-            return new PhysicalProperties(DistributionSpecHash.merge(
-                    leftHashSpec, rightHashSpec, 
leftHashSpec.getShuffleType()));
         }
 
         throw new RuntimeException("Could not derive hash join's output 
properties. join: " + hashJoin);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/DistributionSpecHash.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/DistributionSpecHash.java
index d61e99688a..979e098c80 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/DistributionSpecHash.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/DistributionSpecHash.java
@@ -43,21 +43,16 @@ import java.util.Set;
 public class DistributionSpecHash extends DistributionSpec {
 
     private final List<ExprId> orderedShuffledColumns;
-
     private final ShuffleType shuffleType;
+    // use for satisfied judge
+    private final List<Set<ExprId>> equivalenceExprIds;
+    private final Map<ExprId, Integer> exprIdToEquivalenceSet;
 
-    // below two attributes use for colocate join
+    // below two attributes use for colocate join, only store one table info 
is enough
     private final long tableId;
-
     private final Set<Long> partitionIds;
-
     private final long selectedIndexId;
 
-    // use for satisfied judge
-    private final List<Set<ExprId>> equivalenceExprIds;
-
-    private final Map<ExprId, Integer> exprIdToEquivalenceSet;
-
     /**
      * Use for no need set table related attributes.
      */
@@ -239,6 +234,11 @@ public class DistributionSpecHash extends DistributionSpec 
{
                 equivalenceExprIds, exprIdToEquivalenceSet);
     }
 
+    public DistributionSpecHash 
withShuffleTypeAndForbidColocateJoin(ShuffleType shuffleType) {
+        return new DistributionSpecHash(orderedShuffledColumns, shuffleType, 
-1, -1, partitionIds,
+                equivalenceExprIds, exprIdToEquivalenceSet);
+    }
+
     /**
      * generate a new DistributionSpec after projection.
      */
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 bfe1594425..a13a22ccb6 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
@@ -254,6 +254,7 @@ public class JoinUtils {
                 || rightHashSpec.getShuffleType() != ShuffleType.NATURAL) {
             return false;
         }
+
         final long leftTableId = leftHashSpec.getTableId();
         final long rightTableId = rightHashSpec.getTableId();
         final Set<Long> leftTablePartitions = leftHashSpec.getPartitionIds();
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/properties/ChildOutputPropertyDeriverTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/properties/ChildOutputPropertyDeriverTest.java
index 2f6a973503..9c9634e44d 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/properties/ChildOutputPropertyDeriverTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/properties/ChildOutputPropertyDeriverTest.java
@@ -18,7 +18,6 @@
 package org.apache.doris.nereids.properties;
 
 import org.apache.doris.catalog.ColocateTableIndex;
-import org.apache.doris.catalog.ColocateTableIndex.GroupId;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.common.Pair;
 import org.apache.doris.nereids.memo.GroupExpression;
@@ -54,7 +53,6 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import mockit.Expectations;
 import mockit.Injectable;
 import mockit.Mock;
 import mockit.MockUp;
@@ -99,22 +97,46 @@ public class ChildOutputPropertyDeriverTest {
     }
 
     @Test
-    public void testColocateJoin() {
+    public void testInnerJoin() {
+        PhysicalHashJoin<GroupPlan, GroupPlan> join = new 
PhysicalHashJoin<>(JoinType.INNER_JOIN,
+                ExpressionUtils.EMPTY_CONDITION, 
ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, Optional.empty(), 
logicalProperties,
+                groupPlan, groupPlan);
+        GroupExpression groupExpression = new GroupExpression(join);
+
+        PhysicalProperties left = new PhysicalProperties(
+                new DistributionSpecHash(
+                        Lists.newArrayList(new ExprId(0)),
+                        ShuffleType.NATURAL,
+                        0,
+                        Sets.newHashSet(0L)
+                ),
+                new OrderSpec(
+                        Lists.newArrayList(new OrderKey(new 
SlotReference("ignored", IntegerType.INSTANCE),
+                                true, true)))
+        );
 
-        new Expectations() {
-            {
-                colocateTableIndex.isSameGroup(0, 1);
-                result = true;
+        PhysicalProperties right = new PhysicalProperties(new 
DistributionSpecHash(
+                Lists.newArrayList(new ExprId(1)),
+                ShuffleType.EXECUTION_BUCKETED,
+                1,
+                Sets.newHashSet(1L)
+        ));
 
-                colocateTableIndex.getGroup(0);
-                result = new GroupId(0, 0);
+        List<PhysicalProperties> childrenOutputProperties = 
Lists.newArrayList(left, right);
+        ChildOutputPropertyDeriver deriver = new 
ChildOutputPropertyDeriver(childrenOutputProperties);
 
-                colocateTableIndex.isGroupUnstable(new GroupId(0, 0));
-                result = false;
-            }
-        };
+        PhysicalProperties result = 
deriver.getOutputProperties(groupExpression);
+        Assertions.assertTrue(result.getOrderSpec().getOrderKeys().isEmpty());
+        Assertions.assertTrue(result.getDistributionSpec() instanceof 
DistributionSpecHash);
+        DistributionSpecHash actual = (DistributionSpecHash) 
result.getDistributionSpec();
+        Assertions.assertEquals(ShuffleType.NATURAL, actual.getShuffleType());
+        // check merged
+        Assertions.assertEquals(2, actual.getExprIdToEquivalenceSet().size());
+    }
 
-        PhysicalHashJoin<GroupPlan, GroupPlan> join = new 
PhysicalHashJoin<>(JoinType.RIGHT_OUTER_JOIN,
+    @Test
+    public void testCrossJoin() {
+        PhysicalHashJoin<GroupPlan, GroupPlan> join = new 
PhysicalHashJoin<>(JoinType.CROSS_JOIN,
                 ExpressionUtils.EMPTY_CONDITION, 
ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, Optional.empty(), 
logicalProperties,
                 groupPlan, groupPlan);
         GroupExpression groupExpression = new GroupExpression(join);
@@ -133,7 +155,7 @@ public class ChildOutputPropertyDeriverTest {
 
         PhysicalProperties right = new PhysicalProperties(new 
DistributionSpecHash(
                 Lists.newArrayList(new ExprId(1)),
-                ShuffleType.NATURAL,
+                ShuffleType.EXECUTION_BUCKETED,
                 1,
                 Sets.newHashSet(1L)
         ));
@@ -150,6 +172,316 @@ public class ChildOutputPropertyDeriverTest {
         Assertions.assertEquals(2, actual.getExprIdToEquivalenceSet().size());
     }
 
+    @Test
+    public void testLeftOuterJoin() {
+        PhysicalHashJoin<GroupPlan, GroupPlan> join = new 
PhysicalHashJoin<>(JoinType.LEFT_OUTER_JOIN,
+                ExpressionUtils.EMPTY_CONDITION, 
ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, Optional.empty(), 
logicalProperties,
+                groupPlan, groupPlan);
+        GroupExpression groupExpression = new GroupExpression(join);
+
+        PhysicalProperties left = new PhysicalProperties(
+                new DistributionSpecHash(
+                        Lists.newArrayList(new ExprId(0)),
+                        ShuffleType.NATURAL,
+                        0,
+                        Sets.newHashSet(0L)
+                ),
+                new OrderSpec(
+                        Lists.newArrayList(new OrderKey(new 
SlotReference("ignored", IntegerType.INSTANCE),
+                                true, true)))
+        );
+
+        PhysicalProperties right = new PhysicalProperties(new 
DistributionSpecHash(
+                Lists.newArrayList(new ExprId(1)),
+                ShuffleType.EXECUTION_BUCKETED,
+                1,
+                Sets.newHashSet(1L)
+        ));
+
+        List<PhysicalProperties> childrenOutputProperties = 
Lists.newArrayList(left, right);
+        ChildOutputPropertyDeriver deriver = new 
ChildOutputPropertyDeriver(childrenOutputProperties);
+
+        PhysicalProperties result = 
deriver.getOutputProperties(groupExpression);
+        Assertions.assertTrue(result.getOrderSpec().getOrderKeys().isEmpty());
+        Assertions.assertTrue(result.getDistributionSpec() instanceof 
DistributionSpecHash);
+        DistributionSpecHash actual = (DistributionSpecHash) 
result.getDistributionSpec();
+        Assertions.assertEquals(ShuffleType.NATURAL, actual.getShuffleType());
+        // check merged
+        Assertions.assertEquals(1, actual.getExprIdToEquivalenceSet().size());
+        Assertions.assertEquals(0, 
actual.getExprIdToEquivalenceSet().keySet().iterator().next().asInt());
+    }
+
+    @Test
+    public void testLeftSemiJoin() {
+        PhysicalHashJoin<GroupPlan, GroupPlan> join = new 
PhysicalHashJoin<>(JoinType.LEFT_SEMI_JOIN,
+                ExpressionUtils.EMPTY_CONDITION, 
ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, Optional.empty(), 
logicalProperties,
+                groupPlan, groupPlan);
+        GroupExpression groupExpression = new GroupExpression(join);
+
+        PhysicalProperties left = new PhysicalProperties(
+                new DistributionSpecHash(
+                        Lists.newArrayList(new ExprId(0)),
+                        ShuffleType.NATURAL,
+                        0,
+                        Sets.newHashSet(0L)
+                ),
+                new OrderSpec(
+                        Lists.newArrayList(new OrderKey(new 
SlotReference("ignored", IntegerType.INSTANCE),
+                                true, true)))
+        );
+
+        PhysicalProperties right = new PhysicalProperties(new 
DistributionSpecHash(
+                Lists.newArrayList(new ExprId(1)),
+                ShuffleType.EXECUTION_BUCKETED,
+                1,
+                Sets.newHashSet(1L)
+        ));
+
+        List<PhysicalProperties> childrenOutputProperties = 
Lists.newArrayList(left, right);
+        ChildOutputPropertyDeriver deriver = new 
ChildOutputPropertyDeriver(childrenOutputProperties);
+
+        PhysicalProperties result = 
deriver.getOutputProperties(groupExpression);
+        Assertions.assertTrue(result.getOrderSpec().getOrderKeys().isEmpty());
+        Assertions.assertTrue(result.getDistributionSpec() instanceof 
DistributionSpecHash);
+        DistributionSpecHash actual = (DistributionSpecHash) 
result.getDistributionSpec();
+        Assertions.assertEquals(ShuffleType.NATURAL, actual.getShuffleType());
+        // check merged
+        Assertions.assertEquals(1, actual.getExprIdToEquivalenceSet().size());
+        Assertions.assertEquals(0, 
actual.getExprIdToEquivalenceSet().keySet().iterator().next().asInt());
+    }
+
+    @Test
+    public void testLeftAntiJoin() {
+        PhysicalHashJoin<GroupPlan, GroupPlan> join = new 
PhysicalHashJoin<>(JoinType.LEFT_ANTI_JOIN,
+                ExpressionUtils.EMPTY_CONDITION, 
ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, Optional.empty(), 
logicalProperties,
+                groupPlan, groupPlan);
+        GroupExpression groupExpression = new GroupExpression(join);
+
+        PhysicalProperties left = new PhysicalProperties(
+                new DistributionSpecHash(
+                        Lists.newArrayList(new ExprId(0)),
+                        ShuffleType.NATURAL,
+                        0,
+                        Sets.newHashSet(0L)
+                ),
+                new OrderSpec(
+                        Lists.newArrayList(new OrderKey(new 
SlotReference("ignored", IntegerType.INSTANCE),
+                                true, true)))
+        );
+
+        PhysicalProperties right = new PhysicalProperties(new 
DistributionSpecHash(
+                Lists.newArrayList(new ExprId(1)),
+                ShuffleType.EXECUTION_BUCKETED,
+                1,
+                Sets.newHashSet(1L)
+        ));
+
+        List<PhysicalProperties> childrenOutputProperties = 
Lists.newArrayList(left, right);
+        ChildOutputPropertyDeriver deriver = new 
ChildOutputPropertyDeriver(childrenOutputProperties);
+
+        PhysicalProperties result = 
deriver.getOutputProperties(groupExpression);
+        Assertions.assertTrue(result.getOrderSpec().getOrderKeys().isEmpty());
+        Assertions.assertTrue(result.getDistributionSpec() instanceof 
DistributionSpecHash);
+        DistributionSpecHash actual = (DistributionSpecHash) 
result.getDistributionSpec();
+        Assertions.assertEquals(ShuffleType.NATURAL, actual.getShuffleType());
+        // check merged
+        Assertions.assertEquals(1, actual.getExprIdToEquivalenceSet().size());
+        Assertions.assertEquals(0, 
actual.getExprIdToEquivalenceSet().keySet().iterator().next().asInt());
+    }
+
+    @Test
+    public void testNullAwareLeftAntiJoin() {
+        PhysicalHashJoin<GroupPlan, GroupPlan> join = new 
PhysicalHashJoin<>(JoinType.NULL_AWARE_LEFT_ANTI_JOIN,
+                ExpressionUtils.EMPTY_CONDITION, 
ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, Optional.empty(), 
logicalProperties,
+                groupPlan, groupPlan);
+        GroupExpression groupExpression = new GroupExpression(join);
+
+        PhysicalProperties left = new PhysicalProperties(
+                new DistributionSpecHash(
+                        Lists.newArrayList(new ExprId(0)),
+                        ShuffleType.NATURAL,
+                        0,
+                        Sets.newHashSet(0L)
+                ),
+                new OrderSpec(
+                        Lists.newArrayList(new OrderKey(new 
SlotReference("ignored", IntegerType.INSTANCE),
+                                true, true)))
+        );
+
+        PhysicalProperties right = new PhysicalProperties(new 
DistributionSpecHash(
+                Lists.newArrayList(new ExprId(1)),
+                ShuffleType.EXECUTION_BUCKETED,
+                1,
+                Sets.newHashSet(1L)
+        ));
+
+        List<PhysicalProperties> childrenOutputProperties = 
Lists.newArrayList(left, right);
+        ChildOutputPropertyDeriver deriver = new 
ChildOutputPropertyDeriver(childrenOutputProperties);
+
+        PhysicalProperties result = 
deriver.getOutputProperties(groupExpression);
+        Assertions.assertTrue(result.getOrderSpec().getOrderKeys().isEmpty());
+        Assertions.assertTrue(result.getDistributionSpec() instanceof 
DistributionSpecHash);
+        DistributionSpecHash actual = (DistributionSpecHash) 
result.getDistributionSpec();
+        Assertions.assertEquals(ShuffleType.NATURAL, actual.getShuffleType());
+        // check merged
+        Assertions.assertEquals(1, actual.getExprIdToEquivalenceSet().size());
+        Assertions.assertEquals(0, 
actual.getExprIdToEquivalenceSet().keySet().iterator().next().asInt());
+    }
+
+    @Test
+    public void testRightSemiJoin() {
+        PhysicalHashJoin<GroupPlan, GroupPlan> join = new 
PhysicalHashJoin<>(JoinType.RIGHT_SEMI_JOIN,
+                ExpressionUtils.EMPTY_CONDITION, 
ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, Optional.empty(), 
logicalProperties,
+                groupPlan, groupPlan);
+        GroupExpression groupExpression = new GroupExpression(join);
+
+        PhysicalProperties left = new PhysicalProperties(
+                new DistributionSpecHash(
+                        Lists.newArrayList(new ExprId(0)),
+                        ShuffleType.NATURAL,
+                        0,
+                        Sets.newHashSet(0L)
+                ),
+                new OrderSpec(
+                        Lists.newArrayList(new OrderKey(new 
SlotReference("ignored", IntegerType.INSTANCE),
+                                true, true)))
+        );
+
+        PhysicalProperties right = new PhysicalProperties(new 
DistributionSpecHash(
+                Lists.newArrayList(new ExprId(1)),
+                ShuffleType.EXECUTION_BUCKETED,
+                1,
+                Sets.newHashSet(1L)
+        ));
+
+        List<PhysicalProperties> childrenOutputProperties = 
Lists.newArrayList(left, right);
+        ChildOutputPropertyDeriver deriver = new 
ChildOutputPropertyDeriver(childrenOutputProperties);
+
+        PhysicalProperties result = 
deriver.getOutputProperties(groupExpression);
+        Assertions.assertTrue(result.getOrderSpec().getOrderKeys().isEmpty());
+        Assertions.assertTrue(result.getDistributionSpec() instanceof 
DistributionSpecHash);
+        DistributionSpecHash actual = (DistributionSpecHash) 
result.getDistributionSpec();
+        Assertions.assertEquals(ShuffleType.NATURAL, actual.getShuffleType());
+        Assertions.assertEquals(-1, actual.getTableId());
+        // check merged
+        Assertions.assertEquals(1, actual.getExprIdToEquivalenceSet().size());
+        Assertions.assertEquals(1, 
actual.getExprIdToEquivalenceSet().keySet().iterator().next().asInt());
+    }
+
+    @Test
+    public void testRightAntiJoin() {
+        PhysicalHashJoin<GroupPlan, GroupPlan> join = new 
PhysicalHashJoin<>(JoinType.RIGHT_ANTI_JOIN,
+                ExpressionUtils.EMPTY_CONDITION, 
ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, Optional.empty(), 
logicalProperties,
+                groupPlan, groupPlan);
+        GroupExpression groupExpression = new GroupExpression(join);
+
+        PhysicalProperties left = new PhysicalProperties(
+                new DistributionSpecHash(
+                        Lists.newArrayList(new ExprId(0)),
+                        ShuffleType.NATURAL,
+                        0,
+                        Sets.newHashSet(0L)
+                ),
+                new OrderSpec(
+                        Lists.newArrayList(new OrderKey(new 
SlotReference("ignored", IntegerType.INSTANCE),
+                                true, true)))
+        );
+
+        PhysicalProperties right = new PhysicalProperties(new 
DistributionSpecHash(
+                Lists.newArrayList(new ExprId(1)),
+                ShuffleType.NATURAL,
+                1,
+                Sets.newHashSet(1L)
+        ));
+
+        List<PhysicalProperties> childrenOutputProperties = 
Lists.newArrayList(left, right);
+        ChildOutputPropertyDeriver deriver = new 
ChildOutputPropertyDeriver(childrenOutputProperties);
+
+        PhysicalProperties result = 
deriver.getOutputProperties(groupExpression);
+        Assertions.assertTrue(result.getOrderSpec().getOrderKeys().isEmpty());
+        Assertions.assertTrue(result.getDistributionSpec() instanceof 
DistributionSpecHash);
+        DistributionSpecHash actual = (DistributionSpecHash) 
result.getDistributionSpec();
+        Assertions.assertEquals(ShuffleType.NATURAL, actual.getShuffleType());
+        Assertions.assertEquals(-1, actual.getTableId());
+        // check merged
+        Assertions.assertEquals(1, actual.getExprIdToEquivalenceSet().size());
+        Assertions.assertEquals(1, 
actual.getExprIdToEquivalenceSet().keySet().iterator().next().asInt());
+    }
+
+    @Test
+    public void testRightOuterJoin() {
+        PhysicalHashJoin<GroupPlan, GroupPlan> join = new 
PhysicalHashJoin<>(JoinType.RIGHT_OUTER_JOIN,
+                ExpressionUtils.EMPTY_CONDITION, 
ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, Optional.empty(), 
logicalProperties,
+                groupPlan, groupPlan);
+        GroupExpression groupExpression = new GroupExpression(join);
+
+        PhysicalProperties left = new PhysicalProperties(
+                new DistributionSpecHash(
+                        Lists.newArrayList(new ExprId(0)),
+                        ShuffleType.NATURAL,
+                        0,
+                        Sets.newHashSet(0L)
+                ),
+                new OrderSpec(
+                        Lists.newArrayList(new OrderKey(new 
SlotReference("ignored", IntegerType.INSTANCE),
+                                true, true)))
+        );
+
+        PhysicalProperties right = new PhysicalProperties(new 
DistributionSpecHash(
+                Lists.newArrayList(new ExprId(1)),
+                ShuffleType.EXECUTION_BUCKETED,
+                1,
+                Sets.newHashSet(1L)
+        ));
+
+        List<PhysicalProperties> childrenOutputProperties = 
Lists.newArrayList(left, right);
+        ChildOutputPropertyDeriver deriver = new 
ChildOutputPropertyDeriver(childrenOutputProperties);
+
+        PhysicalProperties result = 
deriver.getOutputProperties(groupExpression);
+        Assertions.assertTrue(result.getOrderSpec().getOrderKeys().isEmpty());
+        Assertions.assertTrue(result.getDistributionSpec() instanceof 
DistributionSpecHash);
+        DistributionSpecHash actual = (DistributionSpecHash) 
result.getDistributionSpec();
+        Assertions.assertEquals(ShuffleType.NATURAL, actual.getShuffleType());
+        Assertions.assertEquals(-1, actual.getTableId());
+        // check merged
+        Assertions.assertEquals(1, actual.getExprIdToEquivalenceSet().size());
+        Assertions.assertEquals(1, 
actual.getExprIdToEquivalenceSet().keySet().iterator().next().asInt());
+    }
+
+    @Test
+    public void testFullOuterJoin() {
+        PhysicalHashJoin<GroupPlan, GroupPlan> join = new 
PhysicalHashJoin<>(JoinType.FULL_OUTER_JOIN,
+                ExpressionUtils.EMPTY_CONDITION, 
ExpressionUtils.EMPTY_CONDITION, JoinHint.NONE, Optional.empty(), 
logicalProperties,
+                groupPlan, groupPlan);
+        GroupExpression groupExpression = new GroupExpression(join);
+
+        PhysicalProperties left = new PhysicalProperties(
+                new DistributionSpecHash(
+                        Lists.newArrayList(new ExprId(0)),
+                        ShuffleType.NATURAL,
+                        0,
+                        Sets.newHashSet(0L)
+                ),
+                new OrderSpec(
+                        Lists.newArrayList(new OrderKey(new 
SlotReference("ignored", IntegerType.INSTANCE),
+                                true, true)))
+        );
+
+        PhysicalProperties right = new PhysicalProperties(new 
DistributionSpecHash(
+                Lists.newArrayList(new ExprId(1)),
+                ShuffleType.NATURAL,
+                1,
+                Sets.newHashSet(1L)
+        ));
+
+        List<PhysicalProperties> childrenOutputProperties = 
Lists.newArrayList(left, right);
+        ChildOutputPropertyDeriver deriver = new 
ChildOutputPropertyDeriver(childrenOutputProperties);
+
+        PhysicalProperties result = 
deriver.getOutputProperties(groupExpression);
+        Assertions.assertTrue(result.getOrderSpec().getOrderKeys().isEmpty());
+        Assertions.assertTrue(result.getDistributionSpec() instanceof 
DistributionSpecAny);
+    }
+
     @Test
     public void testBroadcastJoin() {
         new MockUp<JoinUtils>() {
diff --git 
a/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query95.out 
b/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query95.out
index f13ff715af..3cb412688b 100644
--- a/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query95.out
+++ b/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query95.out
@@ -32,22 +32,21 @@ PhysicalCteAnchor ( cteId=CTEId#0 )
 ----------------------------PhysicalDistribute
 ------------------------------PhysicalProject
 --------------------------------PhysicalOlapScan[web_returns]
-------------------------PhysicalDistribute
---------------------------hashJoin[RIGHT_SEMI_JOIN](ws1.ws_order_number = 
ws_wh.ws_order_number)
-----------------------------PhysicalDistribute
-------------------------------PhysicalProject
---------------------------------PhysicalCteConsumer ( cteId=CTEId#0 )
-----------------------------PhysicalDistribute
-------------------------------hashJoin[INNER_JOIN](ws1.ws_web_site_sk = 
web_site.web_site_sk)
---------------------------------hashJoin[INNER_JOIN](ws1.ws_ship_addr_sk = 
customer_address.ca_address_sk)
-----------------------------------PhysicalProject
-------------------------------------PhysicalOlapScan[web_sales]
-----------------------------------PhysicalDistribute
-------------------------------------PhysicalProject
---------------------------------------filter((cast(ca_state as VARCHAR(*)) = 
'NC'))
-----------------------------------------PhysicalOlapScan[customer_address]
+------------------------hashJoin[RIGHT_SEMI_JOIN](ws1.ws_order_number = 
ws_wh.ws_order_number)
+--------------------------PhysicalDistribute
+----------------------------PhysicalProject
+------------------------------PhysicalCteConsumer ( cteId=CTEId#0 )
+--------------------------PhysicalDistribute
+----------------------------hashJoin[INNER_JOIN](ws1.ws_web_site_sk = 
web_site.web_site_sk)
+------------------------------hashJoin[INNER_JOIN](ws1.ws_ship_addr_sk = 
customer_address.ca_address_sk)
+--------------------------------PhysicalProject
+----------------------------------PhysicalOlapScan[web_sales]
 --------------------------------PhysicalDistribute
 ----------------------------------PhysicalProject
-------------------------------------filter((cast(web_company_name as 
VARCHAR(*)) = 'pri'))
---------------------------------------PhysicalOlapScan[web_site]
+------------------------------------filter((cast(ca_state as VARCHAR(*)) = 
'NC'))
+--------------------------------------PhysicalOlapScan[customer_address]
+------------------------------PhysicalDistribute
+--------------------------------PhysicalProject
+----------------------------------filter((cast(web_company_name as VARCHAR(*)) 
= 'pri'))
+------------------------------------PhysicalOlapScan[web_site]
 
diff --git 
a/regression-test/suites/nereids_p0/infer_predicate/infer_predicate.groovy 
b/regression-test/suites/nereids_p0/infer_predicate/infer_predicate.groovy
index 2ad1c250ca..a1b0ad3b0f 100644
--- a/regression-test/suites/nereids_p0/infer_predicate/infer_predicate.groovy
+++ b/regression-test/suites/nereids_p0/infer_predicate/infer_predicate.groovy
@@ -31,27 +31,27 @@ suite("test_infer_predicate") {
 
     explain {
         sql "select * from infer_tb1 inner join infer_tb2 where infer_tb2.k1 = 
infer_tb1.k2  and infer_tb2.k1 = 1;"
-        contains "PREDICATES: k2[#20] = 1"
+        contains "PREDICATES: k2"
     }
 
     explain {
         sql "select * from infer_tb1 inner join infer_tb2 where infer_tb1.k2 = 
infer_tb2.k1  and infer_tb2.k1 = 1;"
-        contains "PREDICATES: k2[#20] = 1"
+        contains "PREDICATES: k2"
     }
 
     explain {
         sql "select * from infer_tb1 inner join infer_tb2 where 
cast(infer_tb2.k4 as int) = infer_tb1.k2  and infer_tb2.k4 = 1;"
-        notContains "PREDICATES: k2[#20] = 1"
+        notContains "PREDICATES: k2"
     }
 
     explain {
         sql "select * from infer_tb1 inner join infer_tb3 where infer_tb3.k1 = 
infer_tb1.k2  and infer_tb3.k1 = '123';"
-        notContains "PREDICATES: k2[#6] = '123'"
+        notContains "PREDICATES: k2"
     }
 
     explain {
         sql "select * from infer_tb1 left join infer_tb2 on infer_tb1.k1 = 
infer_tb2.k3 left join infer_tb3 on " +
                 "infer_tb2.k3 = infer_tb3.k2 where infer_tb1.k1 = 1;"
-        contains "PREDICATES: k3[#4] = 1"
+        contains "PREDICATES: k3"
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to