diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java index 1889e5b93e8..81d3e9a9e72 100644 --- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java +++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java @@ -321,15 +321,16 @@ public Boolean areColumnsUnique(Intersect rel, RelMetadataQuery mq, } final JoinInfo joinInfo = rel.analyzeCondition(); - - // Joining with a singleton constrains the keys on the other table - final Double rightMaxRowCount = mq.getMaxRowCount(right); - if (rightMaxRowCount != null && rightMaxRowCount <= 1.0) { - leftColumns = leftColumns.union(joinInfo.leftSet()); - } - final Double leftMaxRowCount = mq.getMaxRowCount(left); - if (leftMaxRowCount != null && leftMaxRowCount <= 1.0) { - rightColumns = rightColumns.union(joinInfo.rightSet()); + if (rel.getJoinType() == JoinRelType.INNER) { + // Joining with a singleton constrains the keys on the other table + final Double rightMaxRowCount = mq.getMaxRowCount(right); + if (rightMaxRowCount != null && rightMaxRowCount <= 1.0) { + leftColumns = leftColumns.union(joinInfo.leftSet()); + } + final Double leftMaxRowCount = mq.getMaxRowCount(left); + if (leftMaxRowCount != null && leftMaxRowCount <= 1.0) { + rightColumns = rightColumns.union(joinInfo.rightSet()); + } } // If the original column mask contains columns from both the left and diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java index 3392f3fa91e..3610516ec60 100644 --- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java @@ -1207,6 +1207,48 @@ private void checkColumnUniquenessForFilterWithConstantColumns(String sql) { .assertThatUniqueKeysAre(bitSetOf()); } + /** Test case for + * [CALCITE-6727] + * Column uniqueness constrain should only apply to inner join. */ + @Test void testColumnUniquenessForLeftJoinOnLimit1() { + final String sql = "" + + "select A.empno as a_empno,\n" + + " A.ename as a_ename,\n" + + " B.empno as b_empno,\n" + + " B.ename as b_ename\n" + + "from emp A\n" + + "left join (\n" + + " select * from emp\n" + + " limit 1) B\n" + + "on A.empno = B.empno"; + sql(sql) + .assertThatAreColumnsUnique(bitSetOf(0), is(true)) + .assertThatAreColumnsUnique(bitSetOf(1), is(false)) + .assertThatAreColumnsUnique(bitSetOf(2), is(false)) + .assertThatAreColumnsUnique(bitSetOf(3), is(false)); + } + + /** Test case for + * [CALCITE-6727] + * Column uniqueness constrain should only apply to inner join. */ + @Test void testColumnUniquenessForRightJoinOnLimit1() { + final String sql = "" + + "select A.empno as a_empno,\n" + + " A.ename as a_ename,\n" + + " B.empno as b_empno,\n" + + " B.ename as b_ename\n" + + "from emp A\n" + + "right join (\n" + + " select * from emp\n" + + " limit 1) B\n" + + "on A.empno = B.empno"; + sql(sql) + .assertThatAreColumnsUnique(bitSetOf(0), is(false)) + .assertThatAreColumnsUnique(bitSetOf(1), is(false)) + .assertThatAreColumnsUnique(bitSetOf(2), is(true)) + .assertThatAreColumnsUnique(bitSetOf(3), is(true)); + } + @Test void testColumnUniquenessForJoinOnAggregation() { final String sql = "" + "select *\n"