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/10/07 10:00:22 UTC

[groovy] branch GROOVY-8258 updated (4440fd6 -> 463ae78)

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

sunlan pushed a change to branch GROOVY-8258
in repository https://gitbox.apache.org/repos/asf/groovy.git.


    from 4440fd6  GROOVY-8258: Tweak GINQ AST
     new e2a7ff6  GROOVY-8258: tweak from expression
     new 463ae78  GROOVY-8258: support nested linq

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/groovy/linq/dsl/GinqAstBuilder.java | 20 ++++--
 .../groovy/linq/dsl/expression/FromExpression.java |  2 +-
 .../linq/provider/collection/GinqAstWalker.groovy  | 12 +++-
 .../groovy/linq/provider/collection/Queryable.java |  4 --
 .../provider/collection/QueryableCollection.java   | 10 ++-
 .../groovy/org/apache/groovy/linq/GinqTest.groovy  | 77 ++++++++++++++++++++++
 .../collection/QueryableCollectionTest.groovy      |  1 -
 7 files changed, 110 insertions(+), 16 deletions(-)


[groovy] 02/02: GROOVY-8258: support nested linq

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 463ae780480aabfaa79bef1c2d197f0503cfac6d
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Oct 7 17:59:34 2020 +0800

    GROOVY-8258: support nested linq
---
 .../org/apache/groovy/linq/dsl/GinqAstBuilder.java | 20 ++++--
 .../linq/provider/collection/GinqAstWalker.groovy  | 12 +++-
 .../groovy/linq/provider/collection/Queryable.java |  4 --
 .../provider/collection/QueryableCollection.java   | 10 ++-
 .../groovy/org/apache/groovy/linq/GinqTest.groovy  | 77 ++++++++++++++++++++++
 .../collection/QueryableCollectionTest.groovy      |  1 -
 6 files changed, 109 insertions(+), 15 deletions(-)

diff --git a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqAstBuilder.java b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqAstBuilder.java
index ee37ce5..2e27d2b 100644
--- a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqAstBuilder.java
+++ b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqAstBuilder.java
@@ -43,7 +43,8 @@ import org.codehaus.groovy.syntax.Types;
  * @since 4.0.0
  */
 public class GinqAstBuilder extends CodeVisitorSupport implements SyntaxErrorReportable {
-    private SimpleGinqExpression simpleGinqExpression = new SimpleGinqExpression(); // store the result
+    private SimpleGinqExpression currentSimpleGinqExpression;
+    private SimpleGinqExpression latestSimpleGinqExpression;
     private GinqExpression ginqExpression; // store the return value
     private final SourceUnit sourceUnit;
 
@@ -52,7 +53,7 @@ public class GinqAstBuilder extends CodeVisitorSupport implements SyntaxErrorRep
     }
 
     public SimpleGinqExpression getSimpleGinqExpression() {
-        return simpleGinqExpression;
+        return latestSimpleGinqExpression;
     }
 
     @Override
@@ -60,6 +61,10 @@ public class GinqAstBuilder extends CodeVisitorSupport implements SyntaxErrorRep
         super.visitMethodCallExpression(call);
         final String methodName = call.getMethodAsString();
 
+        if ("from".equals(methodName)) {
+            currentSimpleGinqExpression = new SimpleGinqExpression(); // store the result
+        }
+
         if ("from".equals(methodName)  || "innerJoin".equals(methodName)) {
             ArgumentListExpression arguments = (ArgumentListExpression) call.getArguments();
             if (arguments.getExpressions().size() != 1) {
@@ -82,15 +87,15 @@ public class GinqAstBuilder extends CodeVisitorSupport implements SyntaxErrorRep
             }
             BinaryExpression binaryExpression = (BinaryExpression) expression;
             Expression aliasExpr = binaryExpression.getLeftExpression();
-            Expression dataSourceExpr = binaryExpression.getRightExpression();
+            Expression dataSourceExpr = null == latestSimpleGinqExpression ? binaryExpression.getRightExpression() : latestSimpleGinqExpression;
 
             FilterableExpression filterableExpression = null;
             if ("from".equals(methodName)) {
                 filterableExpression = new FromExpression(aliasExpr, dataSourceExpr);
-                simpleGinqExpression.setFromExpression((FromExpression) filterableExpression);
+                currentSimpleGinqExpression.setFromExpression((FromExpression) filterableExpression);
             } else if ("innerJoin".equals(methodName)) {
                 filterableExpression = new InnerJoinExpression(aliasExpr, dataSourceExpr);
-                simpleGinqExpression.addJoinExpression((JoinExpression) filterableExpression);
+                currentSimpleGinqExpression.addJoinExpression((JoinExpression) filterableExpression);
             }
             filterableExpression.setSourcePosition(call);
             ginqExpression = filterableExpression;
@@ -127,9 +132,12 @@ public class GinqAstBuilder extends CodeVisitorSupport implements SyntaxErrorRep
             SelectExpression selectExpression = new SelectExpression(call.getArguments());
             selectExpression.setSourcePosition(call);
 
-            simpleGinqExpression.setSelectExpression(selectExpression);
+            currentSimpleGinqExpression.setSelectExpression(selectExpression);
             ginqExpression = selectExpression;
 
+            latestSimpleGinqExpression = currentSimpleGinqExpression;
+            currentSimpleGinqExpression = null;
+
             return;
         }
     }
diff --git a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/GinqAstWalker.groovy b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/GinqAstWalker.groovy
index 3dd1188..e0453c1 100644
--- a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/GinqAstWalker.groovy
+++ b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/GinqAstWalker.groovy
@@ -147,9 +147,17 @@ class GinqAstWalker implements GinqVisitor<Object>, SyntaxErrorReportable {
 
     @CompileDynamic
     private MethodCallExpression constructFromMethodCallExpression(FromExpression fromExpression) {
-        macro {
-            $v{ makeQueryableCollectionClassExpression() }.from($v { fromExpression.dataSourceExpr })
+        MethodCallExpression fromMethodCallExpression = macro {
+            $v{ makeQueryableCollectionClassExpression() }.from($v {
+                if (fromExpression.dataSourceExpr instanceof SimpleGinqExpression) {
+                    return this.visitSimpleGinqExpression((SimpleGinqExpression) fromExpression.dataSourceExpr)
+                } else {
+                    return fromExpression.dataSourceExpr
+                }
+            })
         }
+
+        return fromMethodCallExpression
     }
 
     @CompileDynamic
diff --git a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/Queryable.java b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/Queryable.java
index 6e3e0a0..3f44c60 100644
--- a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/Queryable.java
+++ b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/Queryable.java
@@ -45,10 +45,6 @@ public interface Queryable<T> {
         return new QueryableCollection<>(sourceStream);
     }
 
-    static <T> Queryable<T> from(Queryable<T> queryable) {
-        return queryable;
-    }
-
     <U> Queryable<Tuple2<T, U>> innerJoin(Queryable<? extends U> queryable, BiPredicate<? super T, ? super U> joiner);
 
     <U> Queryable<Tuple2<T, U>> leftJoin(Queryable<? extends U> queryable, BiPredicate<? super T, ? super U> joiner);
diff --git a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/QueryableCollection.java b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/QueryableCollection.java
index 44681ae..645bb08 100644
--- a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/QueryableCollection.java
+++ b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/QueryableCollection.java
@@ -48,8 +48,14 @@ class QueryableCollection<T> implements Queryable<T>, Iterable<T> {
     private Stream<T> sourceStream;
 
     QueryableCollection(Iterable<T> sourceIterable) {
-        this.sourceIterable = sourceIterable;
-        this.sourceStream = toStream(sourceIterable);
+        if (sourceIterable instanceof QueryableCollection) {
+            QueryableCollection<T> queryableCollection = (QueryableCollection<T>) sourceIterable;
+            this.sourceIterable = queryableCollection.sourceIterable;
+            this.sourceStream = queryableCollection.sourceStream;
+        } else {
+            this.sourceIterable = sourceIterable;
+            this.sourceStream = toStream(sourceIterable);
+        }
     }
 
     @SuppressWarnings("unchecked")
diff --git a/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy b/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy
index 3120276..f34bc3f 100644
--- a/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy
+++ b/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy
@@ -387,4 +387,81 @@ class GinqTest {
             }.toList()
         '''
     }
+
+    @Test
+    void "testGinq - nested from - 0"() {
+        assertScript '''
+            assert [1, 2, 3] == GINQ {
+                from v in (
+                    from n in [1, 2, 3]
+                    select n
+                )
+                select v
+            }.toList()
+        '''
+    }
+
+    @Test
+    void "testGinq - nested from - 1"() {
+        assertScript '''
+            def numbers = [1, 2, 3]
+            assert [1, 2, 3] == GINQ {
+                from v in (
+                    from n in numbers
+                    select n
+                )
+                select v
+            }.toList()
+        '''
+    }
+
+    @Test
+    void "testGinq - nested from - 2"() {
+        assertScript '''
+            def numbers = [1, 2, 3]
+            assert [1, 2] == GINQ {
+                from v in (
+                    from n in numbers
+                    where n < 3
+                    select n
+                )
+                select v
+            }.toList()
+        '''
+    }
+
+    @Test
+    void "testGinq - nested from - 3"() {
+        assertScript '''
+            def numbers = [1, 2, 3]
+            assert [2] == GINQ {
+                from v in (
+                    from n in numbers
+                    where n < 3
+                    select n
+                )
+                where v > 1
+                select v
+            }.toList()
+        '''
+    }
+
+    @Test
+    void "testGinq - nested from - 4"() {
+        assertScript '''
+            def nums1 = [1, 2, 3, 4, 5]
+            def nums2 = [1, 2, 3, 4, 5]
+            assert [[3, 3], [5, 5]] == GINQ {
+                from v in (
+                    from n1 in nums1
+                    innerJoin n2 in nums2
+                    on n1 == n2
+                    where n1 > 1 && n2 <= 5
+                    select n1, n2
+                )
+                where v[0] >= 3 && v[1] in [3, 5] // v[0] references column 1, and v[1] references column 2
+                select v
+            }.toList()
+        '''
+    }
 }
diff --git a/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/provider/collection/QueryableCollectionTest.groovy b/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/provider/collection/QueryableCollectionTest.groovy
index 26d4255..0c31357 100644
--- a/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/provider/collection/QueryableCollectionTest.groovy
+++ b/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/provider/collection/QueryableCollectionTest.groovy
@@ -36,7 +36,6 @@ class QueryableCollectionTest {
     void testFrom() {
         assert [1, 2, 3] == from(Stream.of(1, 2, 3)).toList()
         assert [1, 2, 3] == from(Arrays.asList(1, 2, 3)).toList()
-        assert [1, 2, 3] == from(from(Arrays.asList(1, 2, 3))).toList()
     }
 
     @Test


[groovy] 01/02: GROOVY-8258: tweak from expression

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit e2a7ff653e2be11c36fb7faf4c8ad2d0b28787e5
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Oct 7 16:01:23 2020 +0800

    GROOVY-8258: tweak from expression
---
 .../groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java
index 4133eec..2ca2894 100644
--- a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java
+++ b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java
@@ -41,7 +41,7 @@ public class FromExpression extends DataSourceExpression {
         return "FromExpression{" +
                 "aliasExpr=" + aliasExpr +
                 ", dataSourceExpr=" + dataSourceExpr +
-                ", whereExpression=" + filterExpressionList.get(0) +
+                ", whereExpression=" + (filterExpressionList.isEmpty() ? null : filterExpressionList.get(0)) +
                 '}';
     }
 }