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/08 00:45:15 UTC

[groovy] branch master updated: Tweak optimizer and add more tests

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 cfd3c92  Tweak optimizer and add more tests
cfd3c92 is described below

commit cfd3c927d3f86d5491834fb781a94cc0bb8fe555
Author: Daniel Sun <su...@apache.org>
AuthorDate: Tue Dec 8 08:44:46 2020 +0800

    Tweak optimizer and add more tests
---
 .../apache/groovy/ginq/dsl/GinqAstOptimizer.groovy | 25 +++++++--
 .../test/org/apache/groovy/ginq/GinqTest.groovy    | 61 ++++++++++------------
 2 files changed, 48 insertions(+), 38 deletions(-)

diff --git a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/dsl/GinqAstOptimizer.groovy b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/dsl/GinqAstOptimizer.groovy
index 90371a9..effc318 100644
--- a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/dsl/GinqAstOptimizer.groovy
+++ b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/dsl/GinqAstOptimizer.groovy
@@ -109,8 +109,10 @@ class GinqAstOptimizer extends GinqAstBaseVisitor {
 
         WhereExpression whereExpression = ginqExpression.whereExpression
         if (whereExpression) {
-            transformFromClause(whereExpression, optimizingAliasList, allAliasList, optimizingDataSourceExpressionList)
-            transformWhereClause(whereExpression, ginqExpression)
+            boolean transformed = transformFromClause(whereExpression, optimizingAliasList, allAliasList, optimizingDataSourceExpressionList)
+            if (transformed) {
+                transformWhereClause(whereExpression, ginqExpression)
+            }
         }
 
         return null
@@ -118,7 +120,7 @@ class GinqAstOptimizer extends GinqAstBaseVisitor {
 
     private static String constantText(ConstantExpression constantExpression) {
         if (constantExpression.value instanceof CharSequence) {
-            return "'$constantExpression.value'"
+            return "'''${constantExpression.value}'''"
         }
 
         return constantExpression.text
@@ -193,6 +195,10 @@ class GinqAstOptimizer extends GinqAstBaseVisitor {
             })
         }
 
+        if (!toOptimize) {
+            candidatesToOptimize.clear()
+        }
+
         return candidatesToOptimize
     }
     static boolean isCandidate(Expression expression) {
@@ -203,10 +209,15 @@ class GinqAstOptimizer extends GinqAstBaseVisitor {
         return true
     }
 
-    private void transformFromClause(WhereExpression whereExpression, List<String> optimizingAliasList, List<String> allAliasList, List<DataSourceExpression> optimizingDataSourceExpressionList) {
+    private boolean transformFromClause(WhereExpression whereExpression, List<String> optimizingAliasList, List<String> allAliasList, List<DataSourceExpression> optimizingDataSourceExpressionList) {
         Map<String, List<Expression>> conditionsToOptimize = [:]
         List<Expression> candidatesToOptimize = findCandidatesToOptimize(whereExpression)
 
+        boolean transformed = false
+        if (!candidatesToOptimize) {
+            return transformed
+        }
+
         candidatesToOptimize.stream()
                 .forEach(e -> collectConditionsToOptimize(e, allAliasList, optimizingAliasList, conditionsToOptimize))
 
@@ -225,6 +236,10 @@ class GinqAstOptimizer extends GinqAstBaseVisitor {
                                 .map(e -> correctVars(e, alias, constructedAlias))
                                 .collect(Collectors.toList())
 
+                if (transformedConditions) {
+                    transformed = true
+                }
+
                 contructedGinqExpression.fromExpression =
                         new FromExpression(new VariableExpression(constructedAlias), dataSourceExpression.dataSourceExpr)
                 contructedGinqExpression.whereExpression =
@@ -238,6 +253,8 @@ class GinqAstOptimizer extends GinqAstBaseVisitor {
                 dataSourceExpression.dataSourceExpr = contructedGinqExpression
             }
         })
+
+        return transformed
     }
 
     Expression correctVars(Expression expression, final String alias, final String constructedAlias) {
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 8369657..4240196 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
@@ -3486,7 +3486,7 @@ class GinqTest {
                 def c = {
                     from n1 in nums1
                     innerjoin n2 in nums2 on n1 == n2
-                    where n1 > 1 && n2 <= 3 && true && !false
+                    where n1 > 1 && n2 <= 3 && 1 < 2 && 3 == 3 && 4 > 3 && 'a' < 'b' && "a's" < "b's" && true && !false
                     select n1, n2
                 }
                 return
@@ -3529,8 +3529,8 @@ class GinqTest {
             def hello() {
                 def c = {
                     from n1 in nums1
-                    innerjoin n2 in nums2 on n1 == n2
-                    where n1 > 1 && n2 <= 3 && 1 < 2 && 3 == 3 && 4 > 3 && 'a' < 'b'
+                    leftjoin n2 in nums2 on n1 == n2
+                    where n1 > 1 && n2 <= 3
                     select n1, n2
                 }
                 return
@@ -3553,28 +3553,42 @@ class GinqTest {
 
         GinqAstOptimizer ginqAstOptimizer = new GinqAstOptimizer()
         ginqAstOptimizer.visitGinqExpression(ginqExpression)
-        assert null == ginqExpression.whereExpression
+        BinaryExpression filterExpr = (BinaryExpression) ginqExpression.whereExpression.filterExpr
+        assert 'n2' == filterExpr.leftExpression.text
+        assert Types.COMPARE_LESS_THAN_EQUAL == filterExpr.operation.type
+        assert '3' == filterExpr.rightExpression.text
 
         assert ginqExpression.fromExpression.dataSourceExpr instanceof GinqExpression
         BinaryExpression contructedFilterExpr1 = ((GinqExpression) ginqExpression.fromExpression.dataSourceExpr).whereExpression.filterExpr
         assert Types.COMPARE_GREATER_THAN == contructedFilterExpr1.operation.type
         assert '1' == contructedFilterExpr1.rightExpression.text
 
-        assert ginqExpression.joinExpressionList[0].dataSourceExpr instanceof GinqExpression
-        BinaryExpression contructedFilterExpr2 = ((GinqExpression) ginqExpression.joinExpressionList[0].dataSourceExpr).whereExpression.filterExpr
-        assert Types.COMPARE_LESS_THAN_EQUAL == contructedFilterExpr2.operation.type
-        assert '3' == contructedFilterExpr2.rightExpression.text
+        assert ginqExpression.joinExpressionList[0].dataSourceExpr !instanceof GinqExpression
     }
 
     @Test
-    @CompileDynamic
     void "testGinq - optimize - 4"() {
+        assertScript '''
+// tag::ginq_optimize_01[]
+            assert [[2, 2]] == GQ(optimize:false) {
+                from n1 in [1, 2, 3]
+                innerjoin n2 in [1, 2, 3] on n1 == n2
+                where n1 > 1 &&  n2 < 3
+                select n1, n2
+            }.toList()
+// end::ginq_optimize_01[]
+        '''
+    }
+
+    @Test
+    @CompileDynamic
+    void "testGinq - optimize - 5"() {
         def code = '''
             def hello() {
                 def c = {
                     from n1 in nums1
-                    leftjoin n2 in nums2 on n1 == n2
-                    where n1 > 1 && n2 <= 3
+                    innerjoin n2 in nums2 on n1 == n2
+                    where n1 > 1 || n2 <= 3
                     select n1, n2
                 }
                 return
@@ -3597,30 +3611,9 @@ class GinqTest {
 
         GinqAstOptimizer ginqAstOptimizer = new GinqAstOptimizer()
         ginqAstOptimizer.visitGinqExpression(ginqExpression)
-        BinaryExpression filterExpr = (BinaryExpression) ginqExpression.whereExpression.filterExpr
-        assert 'n2' == filterExpr.leftExpression.text
-        assert Types.COMPARE_LESS_THAN_EQUAL == filterExpr.operation.type
-        assert '3' == filterExpr.rightExpression.text
-
-        assert ginqExpression.fromExpression.dataSourceExpr instanceof GinqExpression
-        BinaryExpression contructedFilterExpr1 = ((GinqExpression) ginqExpression.fromExpression.dataSourceExpr).whereExpression.filterExpr
-        assert Types.COMPARE_GREATER_THAN == contructedFilterExpr1.operation.type
-        assert '1' == contructedFilterExpr1.rightExpression.text
+        assert null != ginqExpression.whereExpression
 
+        assert ginqExpression.fromExpression.dataSourceExpr !instanceof GinqExpression
         assert ginqExpression.joinExpressionList[0].dataSourceExpr !instanceof GinqExpression
     }
-
-    @Test
-    void "testGinq - optimize - 5"() {
-        assertScript '''
-// tag::ginq_optimize_01[]
-            assert [[2, 2]] == GQ(optimize:false) {
-                from n1 in [1, 2, 3]
-                innerjoin n2 in [1, 2, 3] on n1 == n2
-                where n1 > 1 &&  n2 < 3
-                select n1, n2
-            }.toList()
-// end::ginq_optimize_01[]
-        '''
-    }
 }