groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sun...@apache.org
Subject [groovy] branch master updated: Tweak the optimizer of GINQ
Date Mon, 07 Dec 2020 14:01:56 GMT
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 803b4d0  Tweak the optimizer of GINQ
803b4d0 is described below

commit 803b4d093402fbc0ff91e5760dc05de60b152f2e
Author: Daniel Sun <sunlan@apache.org>
AuthorDate: Mon Dec 7 22:01:14 2020 +0800

    Tweak the optimizer of GINQ
---
 .../apache/groovy/ginq/dsl/GinqAstOptimizer.groovy | 69 ++++++++++++----------
 .../test/org/apache/groovy/ginq/GinqTest.groovy    |  9 ++-
 2 files changed, 41 insertions(+), 37 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 e77d6ec..c892388 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
@@ -27,7 +27,6 @@ import org.apache.groovy.ginq.dsl.expression.SelectExpression
 import org.apache.groovy.ginq.dsl.expression.WhereExpression
 import org.codehaus.groovy.ast.expr.ArgumentListExpression
 import org.codehaus.groovy.ast.expr.BinaryExpression
-import org.codehaus.groovy.ast.expr.ConstantExpression
 import org.codehaus.groovy.ast.expr.Expression
 import org.codehaus.groovy.ast.expr.ExpressionTransformer
 import org.codehaus.groovy.ast.expr.ListExpression
@@ -36,7 +35,6 @@ import org.codehaus.groovy.syntax.Token
 import org.codehaus.groovy.syntax.Types
 
 import java.util.stream.Collectors
-
 /**
  * Optimize the execution plan of GINQ through transforming AST.
  * <p>
@@ -60,7 +58,6 @@ import java.util.stream.Collectors
  *      where alias23802906 <= 3
  *      select alias23802906
  *    ) on n1 == n2
- *    where true && true  // omit the original filters with `true`, we could optimize
further, e.g. omit the `where` totally
  *    select n1, n2
  * </pre>
  *
@@ -110,10 +107,37 @@ class GinqAstOptimizer extends GinqAstBaseVisitor {
 
         WhereExpression whereExpression = ginqExpression.whereExpression
         if (whereExpression) {
-            boolean toOptimize = true
             Map<String, List<Expression>> conditionsToOptimize = [:]
-            List<Expression> candidatesToOptimize = []
+            List<Expression> candidatesToOptimize = findCandidatesToOptimize(whereExpression)
+
+            candidatesToOptimize.stream()
+                    .forEach(e -> collectConditionsToOptimize(e, allAliasList, optimizingAliasList,
conditionsToOptimize))
+
+            transformFromClause(conditionsToOptimize, optimizingAliasList, optimizingDataSourceExpressionList)
+
+            List<Expression> candidates = findCandidatesToOptimize(whereExpression)
+            List<Expression> nonOptimizedCandidates = candidates.grep { Expression
e ->
+                Boolean optimize = e.getNodeMetaData(TO_OPTIMIZE)
+                return null == optimize || !optimize
+            }
+
+            if (nonOptimizedCandidates) {
+                whereExpression.filterExpr = contructFilterExpr(nonOptimizedCandidates)
+            } else {
+                ginqExpression.whereExpression = null
+            }
+        }
+
+        return null
+    }
 
+    private List<Expression> findCandidatesToOptimize(WhereExpression whereExpression)
{
+        boolean toOptimize = true
+        List<Expression> candidatesToOptimize = []
+
+        if (isCandidate(whereExpression.filterExpr)) {
+            candidatesToOptimize << whereExpression.filterExpr
+        } else {
             whereExpression.filterExpr.visit(new GinqAstBaseVisitor() {
                 @Override
                 void visitBinaryExpression(BinaryExpression expression) {
@@ -136,36 +160,17 @@ class GinqAstOptimizer extends GinqAstBaseVisitor {
 
                     super.visitBinaryExpression(expression)
                 }
-
-                static boolean isCandidate(Expression expression) {
-                    if (expression instanceof BinaryExpression && expression.operation.type
in [Types.LOGICAL_AND, Types.LOGICAL_OR]) {
-                        return false
-                    }
-
-                    return true
-                }
             })
+        }
 
-            candidatesToOptimize.stream()
-                    .forEach(e -> collectConditionsToOptimize(e, allAliasList, optimizingAliasList,
conditionsToOptimize))
-
-            transformFromClause(conditionsToOptimize, optimizingAliasList, optimizingDataSourceExpressionList)
-
-            whereExpression.filterExpr =
-                    ((ListExpression) new ListExpression(Collections.singletonList(whereExpression.filterExpr))
-                            .transformExpression(new ExpressionTransformer() {
-                                @Override
-                                Expression transform(Expression expression) {
-                                    if (expression.getNodeMetaData(TO_OPTIMIZE)) {
-                                        return ConstantExpression.TRUE
-                                    }
-
-                                    return expression.transformExpression(this)
-                                }
-                            })).getExpression(0)
-        };
+        return candidatesToOptimize
+    }
+    static boolean isCandidate(Expression expression) {
+        if (expression instanceof BinaryExpression && expression.operation.type in
[Types.LOGICAL_AND, Types.LOGICAL_OR]) {
+            return false
+        }
 
-        return null
+        return true
     }
 
     private void transformFromClause(LinkedHashMap<String, List<Expression>>
conditionsToOptimize, List<String> optimizingAliasList, List<DataSourceExpression>
optimizingDataSourceExpressionList) {
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 96a5c30..010b37b 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
@@ -3465,9 +3465,7 @@ class GinqTest {
 
         GinqAstOptimizer ginqAstOptimizer = new GinqAstOptimizer()
         ginqAstOptimizer.visitGinqExpression(ginqExpression)
-        BinaryExpression filterExpr = (BinaryExpression) ginqExpression.whereExpression.filterExpr
-        assert 'true' == filterExpr.leftExpression.text
-        assert 'true' == filterExpr.rightExpression.text
+        assert null == ginqExpression.whereExpression
 
         assert ginqExpression.fromExpression.dataSourceExpr instanceof GinqExpression
         BinaryExpression contructedFilterExpr1 = ((GinqExpression) ginqExpression.fromExpression.dataSourceExpr).whereExpression.filterExpr
@@ -3512,8 +3510,9 @@ class GinqTest {
         GinqAstOptimizer ginqAstOptimizer = new GinqAstOptimizer()
         ginqAstOptimizer.visitGinqExpression(ginqExpression)
         BinaryExpression filterExpr = (BinaryExpression) ginqExpression.whereExpression.filterExpr
-        assert 'true' == filterExpr.leftExpression.text
-        assert 'true' != filterExpr.rightExpression.text
+        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


Mime
View raw message