You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2016/09/03 00:12:13 UTC

calcite git commit: [CALCITE-1366] Metadata provider should not pull predicates up through GROUP BY ()

Repository: calcite
Updated Branches:
  refs/heads/master 317802d73 -> 29daa4513


[CALCITE-1366] Metadata provider should not pull predicates up through GROUP BY ()

Add a test for the previous fix-up of [CALCITE-1365].

Close apache/calcite#276


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/29daa451
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/29daa451
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/29daa451

Branch: refs/heads/master
Commit: 29daa4513f19c82a410ea3c36a6116260caa0216
Parents: 317802d
Author: Jesus Camacho Rodriguez <jc...@apache.org>
Authored: Tue Aug 30 16:30:16 2016 +0100
Committer: Julian Hyde <jh...@apache.org>
Committed: Fri Sep 2 11:07:49 2016 -0700

----------------------------------------------------------------------
 .../calcite/rel/metadata/RelMdPredicates.java   |  7 ++++
 .../org/apache/calcite/tools/PlannerTest.java   | 43 +++++++++++++++++---
 2 files changed, 45 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/29daa451/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
index 4572296..c416f4c 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
@@ -287,6 +287,13 @@ public class RelMdPredicates
     final List<RexNode> aggPullUpPredicates = new ArrayList<>();
 
     ImmutableBitSet groupKeys = agg.getGroupSet();
+    if (groupKeys.isEmpty()) {
+      // "GROUP BY ()" can convert an empty relation to a non-empty relation, so
+      // it is not valid to pull up predicates. In particular, consider the
+      // predicate "false": it is valid on all input rows (trivially - there are
+      // no rows!) but not on the output (there is one row).
+      return RelOptPredicateList.EMPTY;
+    }
     Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION,
         input.getRowType().getFieldCount(), agg.getRowType().getFieldCount());
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/29daa451/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/tools/PlannerTest.java b/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
index 826e775..8828801 100644
--- a/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
+++ b/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
@@ -267,7 +267,7 @@ public class PlannerTest {
 
   /** Helper method for testing {@link RelMetadataQuery#getPulledUpPredicates}
    * metadata. */
-  private void checkMetadataUnionPredicates(String sql,
+  private void checkMetadataPredicates(String sql,
       String expectedPredicates) throws Exception {
     Planner planner = getPlanner(null);
     SqlNode parse = planner.parse(sql);
@@ -281,7 +281,7 @@ public class PlannerTest {
 
   /** Tests predicates that can be pulled-up from a UNION. */
   @Test public void testMetadataUnionPredicates() throws Exception {
-    checkMetadataUnionPredicates(
+    checkMetadataPredicates(
         "select * from \"emps\" where \"deptno\" < 10\n"
             + "union all\n"
             + "select * from \"emps\" where \"empid\" > 2",
@@ -292,7 +292,7 @@ public class PlannerTest {
    * <a href="https://issues.apache.org/jira/browse/CALCITE-443">[CALCITE-443]
    * getPredicates from a union is not correct</a>. */
   @Test public void testMetadataUnionPredicates2() throws Exception {
-    checkMetadataUnionPredicates(
+    checkMetadataPredicates(
         "select * from \"emps\" where \"deptno\" < 10\n"
             + "union all\n"
             + "select * from \"emps\"",
@@ -302,7 +302,7 @@ public class PlannerTest {
   @Test public void testMetadataUnionPredicates3() throws Exception {
     // The result is [OR(<($1, 10), AND(<($1, 10), >($0, 1)))]
     // which can be simplified to [<($1, 10)].
-    checkMetadataUnionPredicates(
+    checkMetadataPredicates(
         "select * from \"emps\" where \"deptno\" < 10\n"
             + "union all\n"
             + "select * from \"emps\" where \"deptno\" < 10 and \"empid\" > 1",
@@ -310,13 +310,46 @@ public class PlannerTest {
   }
 
   @Test public void testMetadataUnionPredicates4() throws Exception {
-    checkMetadataUnionPredicates(
+    checkMetadataPredicates(
         "select * from \"emps\" where \"deptno\" < 10\n"
             + "union all\n"
             + "select * from \"emps\" where \"deptno\" < 10 or \"empid\" > 1",
         "[OR(<($1, 10), <($1, 10), >($0, 1))]");
   }
 
+  @Test public void testMetadataUnionPredicates5() throws Exception {
+    final String sql = "select * from \"emps\" where \"deptno\" < 10\n"
+        + "union all\n"
+        + "select * from \"emps\" where \"deptno\" < 10 and false";
+    checkMetadataPredicates(sql, "[<($1, 10)]");
+  }
+
+  /** Tests predicates that can be pulled-up from an Aggregate with
+   * {@code GROUP BY ()}. This form of Aggregate can convert an empty relation
+   * to a single-row relation, so it is not valid to pull up the predicate
+   * {@code false}. */
+  @Test public void testMetadataAggregatePredicates() throws Exception {
+    checkMetadataPredicates("select count(*) from \"emps\" where false",
+        "[]");
+  }
+
+  /** Tests predicates that can be pulled-up from an Aggregate with a non-empty
+   * group key. The {@code false} predicate effectively means that the relation
+   * is empty, because no row can satisfy {@code false}. */
+  @Test public void testMetadataAggregatePredicates2() throws Exception {
+    final String sql = "select \"deptno\", count(\"deptno\")\n"
+        + "from \"emps\" where false\n"
+        + "group by \"deptno\"";
+    checkMetadataPredicates(sql, "[false]");
+  }
+
+  @Test public void testMetadataAggregatePredicates3() throws Exception {
+    final String sql = "select \"deptno\", count(\"deptno\")\n"
+        + "from \"emps\" where \"deptno\" > 10\n"
+        + "group by \"deptno\"";
+    checkMetadataPredicates(sql, "[>($0, 10)]");
+  }
+
   /** Unit test that parses, validates, converts and plans. */
   @Test public void testPlan() throws Exception {
     Program program =