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

rubenql pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new a27a8de278 [CALCITE-6474] Aggregate with constant key can get a 
RowCount greater than its MaxRowCount
a27a8de278 is described below

commit a27a8de278d06f0fa5875df4dc1bbbedc6a2213a
Author: Ruben Quesada Lopez <[email protected]>
AuthorDate: Tue Jul 16 17:26:24 2024 +0100

    [CALCITE-6474] Aggregate with constant key can get a RowCount greater than 
its MaxRowCount
---
 .../apache/calcite/rel/metadata/RelMdMaxRowCount.java   |  2 +-
 .../org/apache/calcite/rel/metadata/RelMdRowCount.java  | 12 ++++++++++++
 .../java/org/apache/calcite/test/RelMetadataTest.java   | 17 +++++++++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java 
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
index 0d9a61ebe9..2858fd908b 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
@@ -159,7 +159,7 @@ public class RelMdMaxRowCount
     return rowCount * rel.getGroupSets().size();
   }
 
-  private static boolean allGroupKeysAreConstant(Aggregate aggregate,
+  static boolean allGroupKeysAreConstant(Aggregate aggregate,
       RelOptPredicateList predicateList) {
     final RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder();
     for (int key : aggregate.getGroupSet()) {
diff --git 
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java 
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
index b7393823ba..8da6caa894 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
@@ -17,6 +17,7 @@
 package org.apache.calcite.rel.metadata;
 
 import org.apache.calcite.adapter.enumerable.EnumerableLimit;
+import org.apache.calcite.plan.RelOptPredicateList;
 import org.apache.calcite.plan.volcano.RelSubset;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.SingleRel;
@@ -191,6 +192,17 @@ public class RelMdRowCount
       // Aggregate with no GROUP BY always returns 1 row (even on empty table).
       return 1D;
     }
+
+    // Aggregate with constant GROUP BY always returns 1 row
+    if (rel.getGroupType() == Aggregate.Group.SIMPLE) {
+      final RelOptPredicateList predicateList =
+          mq.getPulledUpPredicates(rel.getInput());
+      if (!RelOptPredicateList.isEmpty(predicateList)
+          && RelMdMaxRowCount.allGroupKeysAreConstant(rel, predicateList)) {
+        return 1D;
+      }
+    }
+
     // rowCount is the cardinality of the group by columns
     Double distinctRowCount =
         mq.getDistinctRowCount(rel.getInput(), groupKey, null);
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 d9733486bd..5db8ec64a3 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -788,6 +788,23 @@ public class RelMetadataTest {
     sql(sql).assertThatRowCount(is(1D), is(0D), is(1D));
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6474";>[CALCITE-6474]
+   * Aggregate with constant key can get a RowCount greater than its 
MaxRowCount </a>. */
+  @Test void testRowCountAggregateConstantKeysOnBigInput() {
+    final String sql = ""
+        + "select distinct deptno from ("
+        + "select deptno from emp e1 union all "
+        + "select deptno from emp e2 union all "
+        + "select deptno from emp e3 union all "
+        + "select deptno from emp e4 union all "
+        + "select deptno from emp e5 union all "
+        + "select deptno from emp e6 union all "
+        + "select deptno from emp e7"
+        + ") where deptno=4";
+    sql(sql).assertThatRowCount(is(1D), is(0D), is(1D));
+  }
+
   @Test void testRowCountFilterAggregateEmptyKey() {
     final String sql = "select count(*) from emp where 1 = 0";
     sql(sql).assertThatRowCount(is(1D), is(1D), is(1D));

Reply via email to