From 51eabb75728985464c32c9821290ddd60f277594 Mon Sep 17 00:00:00 2001 From: joeyutong Date: Thu, 12 Dec 2024 14:07:26 +0800 Subject: [PATCH] [CALCITE-6727] Column uniqueness constrain should only apply to inner join --- .../rel/metadata/RelMdColumnUniqueness.java | 19 +++++---- .../apache/calcite/test/RelMetadataTest.java | 42 +++++++++++++++++++ 2 files changed, 52 insertions(+), 9 deletions(-) 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 1889e5b93e8d..81d3e9a9e725 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 3392f3fa91e6..3610516ec601 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"