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