You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by tl...@apache.org on 2021/02/20 09:10:59 UTC

[ignite] branch sql-calcite updated: IGNITE-14156 SQL. Calcite: fix aggregate result for empty input (#8812)

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

tledkov pushed a commit to branch sql-calcite
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/sql-calcite by this push:
     new 781bd14  IGNITE-14156 SQL. Calcite: fix aggregate result for empty input (#8812)
781bd14 is described below

commit 781bd1443e25164fca6923e3e3038f61a6a1a471
Author: Yuriy Gerzhedovich <yg...@gridgain.com>
AuthorDate: Sat Feb 20 12:10:41 2021 +0300

    IGNITE-14156 SQL. Calcite: fix aggregate result for empty input (#8812)
---
 .../query/calcite/exec/exp/agg/GroupKey.java       |  4 +++
 .../query/calcite/exec/rel/AggregateNode.java      |  5 ++++
 .../query/calcite/AggregatesIntegrationTest.java   | 35 +++++++++++++++++-----
 3 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/GroupKey.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/GroupKey.java
index b57e549..2796a14 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/GroupKey.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/GroupKey.java
@@ -18,12 +18,16 @@
 package org.apache.ignite.internal.processors.query.calcite.exec.exp.agg;
 
 import java.util.Arrays;
+import org.apache.ignite.internal.util.typedef.X;
 
 /**
  *
  */
 public class GroupKey {
     /** */
+    public static final GroupKey EMPTY_GRP_KEY = new GroupKey(X.EMPTY_OBJECT_ARRAY);
+
+    /** */
     private final Object[] fields;
 
     /** */
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AggregateNode.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AggregateNode.java
index 70cc79d..08743da 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AggregateNode.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AggregateNode.java
@@ -247,6 +247,11 @@ public class AggregateNode<Row> extends AbstractNode<Row> implements SingleNode<
             this.grpFields = grpFields;
 
             handler = context().rowHandler();
+
+            // Initializes aggregates for case when no any rows will be added into the aggregate to have 0 as result.
+            // Doesn't do it for MAP type due to we don't want send from MAP node zero results because it looks redundant.
+            if (grpFields.isEmpty() && (type == AggregateType.REDUCE || type == AggregateType.SINGLE))
+                groups.put(GroupKey.EMPTY_GRP_KEY, create(GroupKey.EMPTY_GRP_KEY));
         }
 
         /** */
diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/AggregatesIntegrationTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/AggregatesIntegrationTest.java
index 019d7f0..61fb358 100644
--- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/AggregatesIntegrationTest.java
+++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/AggregatesIntegrationTest.java
@@ -74,32 +74,51 @@ public class AggregatesIntegrationTest extends GridCommonAbstractTest {
         person.put(idx++, new Employer(null, 15d));
         person.put(idx++, new Employer("Ilya", 15d));
         person.put(idx++, new Employer("Roma", 10d));
+        person.put(idx++, new Employer("Roma", 10d));
+
+        assertQuery("select count(name) from person").returns(4L).check();
+        assertQuery("select count(*) from person").returns(5L).check();
+        assertQuery("select count(1) from person").returns(5L).check();
 
-        assertQuery("select count(name) from person").returns(3L).check();
-        assertQuery("select count(*) from person").returns(4L).check();
-        assertQuery("select count(1) from person").returns(4L).check();
+        assertQuery("select count(*) from person where salary < 0").returns(0L).check();
+        assertQuery("select count(*) from person where salary < 0 and salary > 0").returns(0L).check();
 
-        assertQuery("select count(case when name like 'R%' then 1 else null end) from person").returns(1L).check();
-        assertQuery("select count(case when name not like 'I%' then 1 else null end) from person").returns(1L).check();
+        assertQuery("select count(case when name like 'R%' then 1 else null end) from person").returns(2L).check();
+        assertQuery("select count(case when name not like 'I%' then 1 else null end) from person").returns(2L).check();
 
         assertQuery("select count(name) from person where salary > 10").returns(1L).check();
         assertQuery("select count(*) from person where salary > 10").returns(2L).check();
         assertQuery("select count(1) from person where salary > 10").returns(2L).check();
 
         assertQuery("select salary, count(name) from person group by salary order by salary")
-            .returns(10d, 2L)
+            .returns(10d, 3L)
             .returns(15d, 1L)
             .check();
 
         assertQuery("select salary, count(*) from person group by salary order by salary")
-            .returns(10d, 2L)
+            .returns(10d, 3L)
             .returns(15d, 2L)
             .check();
 
         assertQuery("select salary, count(1) from person group by salary order by salary")
-            .returns(10d, 2L)
+            .returns(10d, 3L)
             .returns(15d, 2L)
             .check();
+
+        assertQuery("select salary, count(1), sum(1) from person group by salary order by salary")
+            .returns(10d, 3L, 3)
+            .returns(15d, 2L, 2)
+            .check();
+
+        assertQuery("select salary, name, count(1), sum(salary) from person group by salary, name order by salary")
+            .returns(10d, "Igor", 1L, 10d)
+            .returns(10d, "Roma", 2L, 20d)
+            .returns(15d, "Ilya", 1L, 15d)
+            .returns(15d, null, 1L, 15d)
+            .check();
+
+        assertQuery("select salary, count(name) from person group by salary having salary < 10 order by salary")
+            .check();
     }
 
     /** */