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);
