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 2020/12/26 14:10:35 UTC
[groovy] branch master updated: Tweak `firstValue` and `lastValue`
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 b2a4ef3 Tweak `firstValue` and `lastValue`
b2a4ef3 is described below
commit b2a4ef347ffb8e569193f99c2fe92d0e15d0ef1a
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Dec 26 22:10:13 2020 +0800
Tweak `firstValue` and `lastValue`
---
.../provider/collection/runtime/WindowImpl.java | 23 +++++++++--
.../groovy-ginq/src/spec/doc/ginq-userguide.adoc | 20 +++++++++
.../test/org/apache/groovy/ginq/GinqTest.groovy | 48 ++++++++++++++++++++++
3 files changed, 87 insertions(+), 4 deletions(-)
diff --git a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/WindowImpl.java b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/WindowImpl.java
index 4ad9924..8e5ec92 100644
--- a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/WindowImpl.java
+++ b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/WindowImpl.java
@@ -83,14 +83,31 @@ class WindowImpl<T, U extends Comparable<? super U>> extends QueryableCollection
@Override
public <V> V firstValue(Function<? super T, ? extends V> extractor) {
+ long lastIndex = getLastIndex();
+ if (lastIndex < 0) {
+ return null;
+ }
long firstIndex = getFirstIndex();
- return extractor.apply(this.toList().get((int) firstIndex));
+ if (firstIndex >= this.size()) {
+ return null;
+ }
+ int resultIndex = (int) Math.max(0, firstIndex);
+ return extractor.apply(this.toList().get(resultIndex));
}
@Override
public <V> V lastValue(Function<? super T, ? extends V> extractor) {
+ long firstIndex = getFirstIndex();
+ long size = this.size();
+ if (firstIndex >= size) {
+ return null;
+ }
long lastIndex = getLastIndex();
- return extractor.apply(this.toList().get((int) lastIndex));
+ if (lastIndex < 0) {
+ return null;
+ }
+ int resultIndex = (int) Math.min(size - 1, lastIndex);
+ return extractor.apply(this.toList().get(resultIndex));
}
private long getFirstIndex() {
@@ -101,7 +118,6 @@ class WindowImpl<T, U extends Comparable<? super U>> extends QueryableCollection
firstRowIndex = 0;
} else {
firstRowIndex = index + lower;
- firstRowIndex = Math.max(firstRowIndex, 0);
}
return firstRowIndex;
}
@@ -115,7 +131,6 @@ class WindowImpl<T, U extends Comparable<? super U>> extends QueryableCollection
lastRowIndex = size - 1;
} else {
lastRowIndex = index + upper;
- lastRowIndex = Math.min(lastRowIndex, size - 1);
}
return lastRowIndex;
}
diff --git a/subprojects/groovy-ginq/src/spec/doc/ginq-userguide.adoc b/subprojects/groovy-ginq/src/spec/doc/ginq-userguide.adoc
index 8431d7d..647cd2f 100644
--- a/subprojects/groovy-ginq/src/spec/doc/ginq-userguide.adoc
+++ b/subprojects/groovy-ginq/src/spec/doc/ginq-userguide.adoc
@@ -471,6 +471,26 @@ include::../test/org/apache/groovy/ginq/GinqTest.groovy[tags=ginq_winfunction_10
----
include::../test/org/apache/groovy/ginq/GinqTest.groovy[tags=ginq_winfunction_13,indent=0]
----
+
+[source, groovy]
+----
+include::../test/org/apache/groovy/ginq/GinqTest.groovy[tags=ginq_winfunction_16,indent=0]
+----
+
+[source, groovy]
+----
+include::../test/org/apache/groovy/ginq/GinqTest.groovy[tags=ginq_winfunction_17,indent=0]
+----
+
+[source, groovy]
+----
+include::../test/org/apache/groovy/ginq/GinqTest.groovy[tags=ginq_winfunction_18,indent=0]
+----
+
+[source, groovy]
+----
+include::../test/org/apache/groovy/ginq/GinqTest.groovy[tags=ginq_winfunction_19,indent=0]
+----
[NOTE]
`0` in the `rows` clause is equivalent to SQL's `CURRENT ROW`,
negative means `PRECEDING`,
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 1d87857..1b209ba 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
@@ -5046,6 +5046,54 @@ class GinqTest {
'''
}
+ @Test
+ void "testGinq - window - 35"() {
+ assertGinqScript '''
+// tag::ginq_winfunction_16[]
+ assert [[2, 1], [1, null], [3, 1]] == GQ {
+ from n in [2, 1, 3]
+ select n, (firstValue(n) over(orderby n rows -2, -1))
+ }.toList()
+// end::ginq_winfunction_16[]
+ '''
+ }
+
+ @Test
+ void "testGinq - window - 36"() {
+ assertGinqScript '''
+// tag::ginq_winfunction_17[]
+ assert [[2, 1], [1, null], [3, 2]] == GQ {
+ from n in [2, 1, 3]
+ select n, (lastValue(n) over(orderby n rows -2, -1))
+ }.toList()
+// end::ginq_winfunction_17[]
+ '''
+ }
+
+ @Test
+ void "testGinq - window - 37"() {
+ assertGinqScript '''
+// tag::ginq_winfunction_18[]
+ assert [[2, 3], [1, 3], [3, null]] == GQ {
+ from n in [2, 1, 3]
+ select n, (lastValue(n) over(orderby n rows 1, 2))
+ }.toList()
+// end::ginq_winfunction_18[]
+ '''
+ }
+
+ @Test
+ void "testGinq - window - 38"() {
+ assertGinqScript '''
+// tag::ginq_winfunction_19[]
+ assert [[2, 3], [1, 2], [3, null]] == GQ {
+ from n in [2, 1, 3]
+ select n, (firstValue(n) over(orderby n rows 1, 2))
+ }.toList()
+// end::ginq_winfunction_19[]
+ '''
+ }
+
private static void assertGinqScript(String script) {
String deoptimizedScript = script.replaceAll(/\bGQ\s*[{]/, 'GQ(optimize:false) {')
List<String> scriptList = [deoptimizedScript, script]