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

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

commit 9538374e8fae5cec7d6f7b270850f5dfb4c1fc06
Author: Vineet Garg <[email protected]>
AuthorDate: Thu Apr 11 16:47:02 2019 -0700

    [CALCITE-2991] getMaxRowCount should return 1 for an Aggregate with 
constant keys (Vineet Garg)
    
    Close apache/calcite#1155
---
 .../calcite/rel/metadata/RelMdMaxRowCount.java     | 24 ++++++++++++++++++++++
 .../org/apache/calcite/test/RelMetadataTest.java   | 11 ++++++++++
 2 files changed, 35 insertions(+)

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 967960d..7058a6c 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
@@ -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.core.Aggregate;
@@ -29,6 +30,7 @@ import org.apache.calcite.rel.core.Sort;
 import org.apache.calcite.rel.core.TableScan;
 import org.apache.calcite.rel.core.Union;
 import org.apache.calcite.rel.core.Values;
+import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.util.Bug;
 import org.apache.calcite.util.BuiltInMethod;
@@ -129,6 +131,16 @@ public class RelMdMaxRowCount
       // 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 (predicateList != null
+          && allGroupKeysAreConstant(rel, predicateList)) {
+        return 1D;
+      }
+    }
     final Double rowCount = mq.getMaxRowCount(rel.getInput());
     if (rowCount == null) {
       return null;
@@ -136,6 +148,18 @@ public class RelMdMaxRowCount
     return rowCount * rel.getGroupSets().size();
   }
 
+  private static boolean allGroupKeysAreConstant(Aggregate aggregate,
+      RelOptPredicateList predicateList) {
+    final RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder();
+    for (int key : aggregate.getGroupSet()) {
+      if (!predicateList.constantMap.containsKey(
+          rexBuilder.makeInputRef(aggregate.getInput(), key))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   public Double getMaxRowCount(Join rel, RelMetadataQuery mq) {
     Double left = mq.getMaxRowCount(rel.getLeft());
     Double right = mq.getMaxRowCount(rel.getRight());
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 0d04bd2..85b4ba2 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -678,6 +678,17 @@ public class RelMetadataTest extends SqlToRelTestBase {
     checkRowCount(sql, 1D, 1D, 1D);
   }
 
+  @Test public void testRowCountAggregateConstantKey() {
+    final String sql = "select count(*) from emp where deptno=2 and 
ename='emp1' "
+        + "group by deptno, ename";
+    checkRowCount(sql, 1D, 0D, 1D);
+  }
+
+  @Test public void testRowCountAggregateConstantKeys() {
+    final String sql = "select distinct deptno from emp where deptno=4";
+    checkRowCount(sql, 1D, 0D, 1D);
+  }
+
   @Test public void testRowCountFilterAggregateEmptyKey() {
     final String sql = "select count(*) from emp where 1 = 0";
     checkRowCount(sql, 1D, 1D, 1D);

Reply via email to