You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2021/04/22 03:42:14 UTC

[groovy] branch master updated: Tweak GINQ aggregate for empty data source

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 4e2169f  Tweak GINQ aggregate for empty data source
4e2169f is described below

commit 4e2169f9f1948e55fb53f545ecbc0fa93fffc6c6
Author: Daniel Sun <su...@apache.org>
AuthorDate: Thu Apr 22 11:41:16 2021 +0800

    Tweak GINQ aggregate for empty data source
---
 .../ginq/provider/collection/runtime/Group.java    | 23 ++++++++++++++++++++++
 .../provider/collection/runtime/GroupImpl.java     | 19 ++++++++++++++++++
 .../collection/runtime/QueryableCollection.java    | 14 +++++++++++--
 .../test/org/apache/groovy/ginq/GinqTest.groovy    | 20 +++++++++++++++++++
 .../runtime/QueryableCollectionTest.groovy         |  4 ++--
 5 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/Group.java b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/Group.java
new file mode 100644
index 0000000..3f887f3
--- /dev/null
+++ b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/Group.java
@@ -0,0 +1,23 @@
+package org.apache.groovy.ginq.provider.collection.runtime;
+
+import java.util.stream.Stream;
+
+/**
+ * Represents group
+ *
+ * @param <T> the type of element
+ * @since 4.0.0
+ */
+public interface Group<T> extends Queryable<T> {
+    /**
+     * Factory method to create {@link Group} instance
+     *
+     * @param sourceStream the source stream
+     * @param <T> the type of element
+     * @return the {@link Group} instance
+     * @since 4.0.0
+     */
+    static <T> Group<T> of(Stream<T> sourceStream) {
+        return new GroupImpl<>(sourceStream);
+    }
+}
diff --git a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/GroupImpl.java b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/GroupImpl.java
new file mode 100644
index 0000000..0439a89
--- /dev/null
+++ b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/GroupImpl.java
@@ -0,0 +1,19 @@
+package org.apache.groovy.ginq.provider.collection.runtime;
+
+import java.util.stream.Stream;
+
+/**
+ * Represents group implementation
+ *
+ * @param <T> the type of element
+ * @since 4.0.0
+ */
+class GroupImpl<T> extends QueryableCollection<T> implements Group<T> {
+    GroupImpl(Iterable<T> sourceIterable) {
+        super(sourceIterable);
+    }
+
+    GroupImpl(Stream<T> sourceStream) {
+        super(sourceStream);
+    }
+}
diff --git a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollection.java b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollection.java
index eb0629f..f857ced 100644
--- a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollection.java
+++ b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollection.java
@@ -234,7 +234,7 @@ class QueryableCollection<T> implements Queryable<T>, Serializable {
                         .filter(m -> null == having || having.test(tuple(m.getKey(), from(m.getValue()))))
                         .map(m -> tuple(m.getKey(), from(m.getValue())));
 
-        return from(stream);
+        return Group.of(stream);
     }
 
     @Override
@@ -285,7 +285,17 @@ class QueryableCollection<T> implements Queryable<T>, Serializable {
             this.makeReusable();
         }
 
-        Stream<U> stream = this.stream().map((T t) -> mapper.apply(t, this));
+        Stream<U> stream = null;
+        if (this instanceof Group) {
+            this.makeReusable();
+            if (0 == this.count()) {
+                stream = Stream.of((T) tuple(Collections.emptyMap(), EMPTY_QUERYABLE)).map((T t) -> mapper.apply(t, this));
+            }
+        }
+        if (null == stream) {
+            stream = this.stream().map((T t) -> mapper.apply(t, this));
+        }
+
         if (TRUE_STR.equals(originalParallel)) {
             // invoke `collect` to trigger the intermediate operator, which will create `CompletableFuture` instances
             stream = stream.collect(Collectors.toList()).parallelStream().map((U u) -> {
diff --git a/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy b/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy
index 1b7ebe0..92bf5bc 100644
--- a/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy
+++ b/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy
@@ -3964,6 +3964,26 @@ class GinqTest {
     }
 
     @Test
+    void "testGinq - agg function - 10"() {
+        assertGinqScript '''
+            assert [0] == GQ {
+                from n in []
+                select count()
+            }.toList()
+        '''
+    }
+
+    @Test
+    void "testGinq - agg function - 11"() {
+        assertGinqScript '''
+            assert [[null, null]] == GQ {
+                from n in []
+                select max(n), min(n)
+            }.toList()
+        '''
+    }
+
+    @Test
     void "testGinq - GQL - 1"() {
         assertGinqScript '''
 // tag::ginq_tips_06[]
diff --git a/subprojects/groovy-ginq/src/test/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollectionTest.groovy b/subprojects/groovy-ginq/src/test/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollectionTest.groovy
index 2c69db8..2c31a56 100644
--- a/subprojects/groovy-ginq/src/test/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollectionTest.groovy
+++ b/subprojects/groovy-ginq/src/test/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollectionTest.groovy
@@ -868,11 +868,11 @@ class QueryableCollectionTest {
         def nums = []
         def result =
                 from(nums).groupBy(e -> 1)
-                        .select(e ->
+                        .select((e, q) ->
                                 e.v2.median(n -> n)
                         )
                         .toList()
-        assert [] == result
+        assert [null] == result
     }
 
     @Test