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]