Rewrite rules modified to convert(to and from) algebrics function correctly


Project: http://git-wip-us.apache.org/repos/asf/vxquery/repo
Commit: http://git-wip-us.apache.org/repos/asf/vxquery/commit/c31a36cb
Tree: http://git-wip-us.apache.org/repos/asf/vxquery/tree/c31a36cb
Diff: http://git-wip-us.apache.org/repos/asf/vxquery/diff/c31a36cb

Branch: refs/heads/master
Commit: c31a36cbbe942860e99e3450e97884412a36773a
Parents: 0771073
Author: Shivani Mall <[email protected]>
Authored: Thu Jun 25 14:16:40 2015 -0700
Committer: Preston Carman <[email protected]>
Committed: Sun Jun 28 17:56:38 2015 -0700

----------------------------------------------------------------------
 .../ConvertFromAlgebricksExpressionsRule.java   |  73 +++++++-----
 .../ConvertToAlgebricksExpressionsRule.java     | 110 ++++++++++++-------
 .../rewriter/rules/util/ExpressionToolbox.java  |  17 ++-
 3 files changed, 135 insertions(+), 65 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/vxquery/blob/c31a36cb/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/ConvertFromAlgebricksExpressionsRule.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/ConvertFromAlgebricksExpressionsRule.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/ConvertFromAlgebricksExpressionsRule.java
index 1bc2bd6..2ea95fe 100644
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/ConvertFromAlgebricksExpressionsRule.java
+++ 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/ConvertFromAlgebricksExpressionsRule.java
@@ -29,10 +29,12 @@ import org.apache.vxquery.functions.BuiltinFunctions;
 import org.apache.vxquery.functions.BuiltinOperators;
 
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -40,8 +42,8 @@ import 
edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
 import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
 
 /**
- * The rule searches for where the Algebricks builtin function are temporarly 
in the plan in place of XQuery function. 
- * The combination the Algebricks builtin function are replace with boolean 
XQuery function and the XQuery equivalent 
+ * The rule searches for where the Algebricks builtin function are temporarly 
in the plan in place of XQuery function.
+ * The combination the Algebricks builtin function are replace with boolean 
XQuery function and the XQuery equivalent
  * function.
  * 
  * <pre>
@@ -60,23 +62,30 @@ import 
edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
  *   plan__child
  * </pre>
  * 
- * @author prestonc
+ * @author prestonc, shivanim
  */
 public class ConvertFromAlgebricksExpressionsRule implements 
IAlgebraicRewriteRule {
     final List<Mutable<ILogicalExpression>> functionList = new 
ArrayList<Mutable<ILogicalExpression>>();
-
-    final Map<FunctionIdentifier, IFunctionInfo> ALGEBRICKS_MAP = new 
HashMap<FunctionIdentifier, IFunctionInfo>();
+    final static Map<FunctionIdentifier, Pair<IFunctionInfo, IFunctionInfo>> 
ALGEBRICKS_MAP = new HashMap<FunctionIdentifier, Pair<IFunctionInfo, 
IFunctionInfo>>();
+    final static String ConversionToAndFromAlgebrics = 
"ConversionToAndFromAlgebrics";
 
     public ConvertFromAlgebricksExpressionsRule() {
-        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.AND, 
BuiltinOperators.AND);
-        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.OR, BuiltinOperators.OR);
-        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.NOT, 
BuiltinFunctions.FN_NOT_1);
-        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.EQ, 
BuiltinOperators.VALUE_EQ);
-        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.NEQ, 
BuiltinOperators.VALUE_NE);
-        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.LT, 
BuiltinOperators.VALUE_LT);
-        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.LE, 
BuiltinOperators.VALUE_LE);
-        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.GT, 
BuiltinOperators.VALUE_GT);
-        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.GE, 
BuiltinOperators.VALUE_GE);
+        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.AND, new 
Pair(BuiltinOperators.AND, null));
+        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.EQ, new 
Pair(BuiltinOperators.VALUE_EQ,
+                BuiltinOperators.GENERAL_EQ));
+        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.GT, new 
Pair(BuiltinOperators.VALUE_GT,
+                BuiltinOperators.GENERAL_GT));
+        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.GE, new 
Pair(BuiltinOperators.VALUE_GE,
+                BuiltinOperators.GENERAL_GE));
+        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.IS_NULL, new Pair(null, 
BuiltinFunctions.FN_EMPTY_1));
+        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.LT, new 
Pair(BuiltinOperators.VALUE_LT,
+                BuiltinOperators.GENERAL_LT));
+        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.LE, new 
Pair(BuiltinOperators.VALUE_LE,
+                BuiltinOperators.GENERAL_LE));
+        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.NOT, new Pair(null, 
BuiltinFunctions.FN_NOT_1));
+        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.NEQ, new 
Pair(BuiltinOperators.VALUE_NE,
+                BuiltinOperators.GENERAL_NE));
+        ALGEBRICKS_MAP.put(AlgebricksBuiltinFunctions.OR, new 
Pair(BuiltinOperators.OR, null));
     }
 
     @Override
@@ -100,20 +109,32 @@ public class ConvertFromAlgebricksExpressionsRule 
implements IAlgebraicRewriteRu
     @SuppressWarnings("unchecked")
     private boolean processExpression(Mutable<ILogicalOperator> opRef, 
Mutable<ILogicalExpression> search) {
         boolean modified = false;
-        for (FunctionIdentifier fid : ALGEBRICKS_MAP.keySet()) {
-            functionList.clear();
-            ExpressionToolbox.findAllFunctionExpressions(search, fid, 
functionList);
-            for (Mutable<ILogicalExpression> searchM : functionList) {
-                AbstractFunctionCallExpression searchFunction = 
(AbstractFunctionCallExpression) searchM.getValue();
-                searchFunction.setFunctionInfo(ALGEBRICKS_MAP.get(fid));
-                // Add boolean function before vxquery expression.
-                ScalarFunctionCallExpression booleanExp = new 
ScalarFunctionCallExpression(
-                        BuiltinFunctions.FN_BOOLEAN_1, new 
MutableObject<ILogicalExpression>(searchM.getValue()));
-                searchM.setValue(booleanExp);
-                modified = true;
+        functionList.clear();
+        ExpressionToolbox.findAllFunctionExpressions(search, functionList);
+        for (Mutable<ILogicalExpression> searchM : functionList) {
+            AbstractFunctionCallExpression searchFunction = 
(AbstractFunctionCallExpression) searchM.getValue();
+            if 
(ALGEBRICKS_MAP.containsKey(searchFunction.getFunctionIdentifier())) {
+                ScalarFunctionCallExpression booleanFunctionCallExp = null;
+                IExpressionAnnotation annotate = 
searchFunction.getAnnotations().get(ConversionToAndFromAlgebrics);
+                FunctionIdentifier fid = 
searchFunction.getFunctionIdentifier();
+                if (((FunctionIdentifier) 
annotate.getObject()).equals(ALGEBRICKS_MAP.get(fid).first
+                        .getFunctionIdentifier())) {
+                    
searchFunction.setFunctionInfo(ALGEBRICKS_MAP.get(fid).first);
+                    booleanFunctionCallExp = new 
ScalarFunctionCallExpression(BuiltinFunctions.FN_BOOLEAN_1,
+                            new 
MutableObject<ILogicalExpression>(searchM.getValue()));
+                    searchM.setValue(booleanFunctionCallExp);
+                    modified = true;
+                } else if (((FunctionIdentifier) 
annotate.getObject()).equals(ALGEBRICKS_MAP.get(fid).second
+                        .getFunctionIdentifier())) {
+                    
searchFunction.setFunctionInfo(ALGEBRICKS_MAP.get(fid).second);
+                    booleanFunctionCallExp = new 
ScalarFunctionCallExpression(ALGEBRICKS_MAP.get(fid).second,
+                            searchFunction.getArguments());
+                    searchM.setValue(booleanFunctionCallExp);
+                    modified = true;
+                } else {
+                }
             }
         }
         return modified;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/vxquery/blob/c31a36cb/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/ConvertToAlgebricksExpressionsRule.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/ConvertToAlgebricksExpressionsRule.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/ConvertToAlgebricksExpressionsRule.java
index 943d630..fd9fa7c 100644
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/ConvertToAlgebricksExpressionsRule.java
+++ 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/ConvertToAlgebricksExpressionsRule.java
@@ -16,13 +16,11 @@
  */
 package org.apache.vxquery.compiler.rewriter.rules;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.lang3.mutable.Mutable;
-import org.apache.vxquery.compiler.rewriter.rules.util.ExpressionToolbox;
 import org.apache.vxquery.compiler.rewriter.rules.util.OperatorToolbox;
 import org.apache.vxquery.functions.BuiltinFunctions;
 import org.apache.vxquery.functions.BuiltinOperators;
@@ -33,21 +31,24 @@ import 
edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ExpressionAnnotationNoCopyImpl;
+import 
edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
 import 
edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
 import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
 
 /**
- * The rule searches for where the XQuery function are used in place of 
Algebricks builtin function. 
- * The combination the boolean XQuery function and the XQuery equivalent 
function are replace with 
- * the Algebricks builtin function  .
+ * The rule searches for where the XQuery function are used in place of 
Algebricks builtin function.
+ * The combination of the boolean XQuery function and the XQuery equivalent 
function are replaced with
+ * the Algebricks builtin function .
  * 
  * <pre>
  * Before
  * 
  *   plan__parent
- *   %OPERATOR( $v1 : boolean(xquery_function( \@input_expression ) ) )
+ *   %OPERATOR( $v1 : boolean(xquery_function( \@input_expression ) or $v1 : 
general-compare(xquery_function( \@input_expression ) 
+ *    or $v1 : fn_empty(xquery_function( \@input_expression ) or $v1 : 
fn_not(xquery_function( \@input_expression 
  *   plan__child
  *   
  *   Where xquery_function creates an atomic value.
@@ -59,23 +60,32 @@ import 
edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
  *   plan__child
  * </pre>
  * 
- * @author prestonc
+ * @author prestonc, shivanim
  */
 public class ConvertToAlgebricksExpressionsRule implements 
IAlgebraicRewriteRule {
-    final List<Mutable<ILogicalExpression>> functionList = new 
ArrayList<Mutable<ILogicalExpression>>();
-
     final Map<FunctionIdentifier, FunctionIdentifier> ALGEBRICKS_MAP = new 
HashMap<FunctionIdentifier, FunctionIdentifier>();
+    final Map<FunctionIdentifier, FunctionIdentifier> ALGEBRICKS_BOOL_MAP = 
new HashMap<FunctionIdentifier, FunctionIdentifier>();
+    final static String ConversionToAndFromAlgebrics = 
"ConversionToAndFromAlgebrics";
 
     public ConvertToAlgebricksExpressionsRule() {
-        ALGEBRICKS_MAP.put(BuiltinOperators.AND.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.AND);
-        ALGEBRICKS_MAP.put(BuiltinOperators.OR.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.OR);
+
+        ALGEBRICKS_BOOL_MAP.put(BuiltinOperators.AND.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.AND);
+        ALGEBRICKS_BOOL_MAP.put(BuiltinOperators.OR.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.OR);
+        
ALGEBRICKS_BOOL_MAP.put(BuiltinOperators.VALUE_NE.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.NEQ);
+        
ALGEBRICKS_BOOL_MAP.put(BuiltinOperators.VALUE_EQ.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.EQ);
+        
ALGEBRICKS_BOOL_MAP.put(BuiltinOperators.VALUE_LE.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.LE);
+        
ALGEBRICKS_BOOL_MAP.put(BuiltinOperators.VALUE_LT.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.LT);
+        
ALGEBRICKS_BOOL_MAP.put(BuiltinOperators.VALUE_GT.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.GT);
+        
ALGEBRICKS_BOOL_MAP.put(BuiltinOperators.VALUE_GE.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.GE);
+
+        
ALGEBRICKS_MAP.put(BuiltinFunctions.FN_EMPTY_1.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.IS_NULL);
         ALGEBRICKS_MAP.put(BuiltinFunctions.FN_NOT_1.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.NOT);
-        ALGEBRICKS_MAP.put(BuiltinOperators.VALUE_EQ.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.EQ);
-        ALGEBRICKS_MAP.put(BuiltinOperators.VALUE_NE.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.NEQ);
-        ALGEBRICKS_MAP.put(BuiltinOperators.VALUE_LT.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.LT);
-        ALGEBRICKS_MAP.put(BuiltinOperators.VALUE_LE.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.LE);
-        ALGEBRICKS_MAP.put(BuiltinOperators.VALUE_GT.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.GT);
-        ALGEBRICKS_MAP.put(BuiltinOperators.VALUE_GE.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.GE);
+        
ALGEBRICKS_MAP.put(BuiltinOperators.GENERAL_LT.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.LT);
+        
ALGEBRICKS_MAP.put(BuiltinOperators.GENERAL_EQ.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.EQ);
+        
ALGEBRICKS_MAP.put(BuiltinOperators.GENERAL_LE.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.LE);
+        
ALGEBRICKS_MAP.put(BuiltinOperators.GENERAL_GE.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.GE);
+        
ALGEBRICKS_MAP.put(BuiltinOperators.GENERAL_GT.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.GT);
+        
ALGEBRICKS_MAP.put(BuiltinOperators.GENERAL_NE.getFunctionIdentifier(), 
AlgebricksBuiltinFunctions.NEQ);
     }
 
     @Override
@@ -89,36 +99,60 @@ public class ConvertToAlgebricksExpressionsRule implements 
IAlgebraicRewriteRule
         boolean modified = false;
         List<Mutable<ILogicalExpression>> expressions = 
OperatorToolbox.getExpressions(opRef);
         for (Mutable<ILogicalExpression> expression : expressions) {
-            if (processExpression(opRef, expression, context)) {
+            if (processExpression(expression, context)) {
                 modified = true;
             }
         }
         return modified;
     }
 
-    private boolean processExpression(Mutable<ILogicalOperator> opRef, 
Mutable<ILogicalExpression> search,
-            IOptimizationContext context) {
+    private boolean processExpression(Mutable<ILogicalExpression> search, 
IOptimizationContext context) {
+        return checkAllFunctionExpressions(search, context);
+    }
+
+    public boolean 
convertFunctionToAlgebricksExpression(Mutable<ILogicalExpression> searchM,
+            AbstractFunctionCallExpression functionCall, IOptimizationContext 
context,
+            Map<FunctionIdentifier, FunctionIdentifier> map) {
+
+        if (map.containsKey(functionCall.getFunctionIdentifier())) {
+            IExpressionAnnotation annotate = new 
ExpressionAnnotationNoCopyImpl();
+            annotate.setObject(functionCall.getFunctionIdentifier());
+            FunctionIdentifier algebricksFid = 
map.get(functionCall.getFunctionIdentifier());
+            IFunctionInfo algebricksFunction = 
context.getMetadataProvider().lookupFunction(algebricksFid);
+            functionCall.setFunctionInfo(algebricksFunction);
+            functionCall.getAnnotations().put(ConversionToAndFromAlgebrics, 
annotate);
+            searchM.setValue(functionCall);
+            return true;
+        }
+        return false;
+    }
+
+    public boolean checkAllFunctionExpressions(Mutable<ILogicalExpression> 
search, IOptimizationContext context) {
         boolean modified = false;
-        functionList.clear();
-        ExpressionToolbox.findAllFunctionExpressions(search, 
BuiltinFunctions.FN_BOOLEAN_1.getFunctionIdentifier(),
-                functionList);
-        for (Mutable<ILogicalExpression> searchM : functionList) {
-            // Get input function
-            AbstractFunctionCallExpression searchFunction = 
(AbstractFunctionCallExpression) searchM.getValue();
-            ILogicalExpression argFirst = 
searchFunction.getArguments().get(0).getValue();
-            if (argFirst.getExpressionTag() != 
LogicalExpressionTag.FUNCTION_CALL) {
-                continue;
+        ILogicalExpression le = search.getValue();
+
+        if (le.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+            AbstractFunctionCallExpression afce = 
(AbstractFunctionCallExpression) le;
+            if 
(afce.getFunctionIdentifier().equals(BuiltinFunctions.FN_BOOLEAN_1.getFunctionIdentifier()))
 {
+                ILogicalExpression argFirst = 
afce.getArguments().get(0).getValue();
+                if (argFirst.getExpressionTag() == 
LogicalExpressionTag.FUNCTION_CALL) {
+                    AbstractFunctionCallExpression functionCall = 
(AbstractFunctionCallExpression) argFirst;
+                    if (convertFunctionToAlgebricksExpression(search, 
functionCall, context, ALGEBRICKS_BOOL_MAP)) {
+                        modified = true;
+                    }
+                }
+            } else if 
(ALGEBRICKS_MAP.containsKey(afce.getFunctionIdentifier())) {
+                if (convertFunctionToAlgebricksExpression(search, afce, 
context, ALGEBRICKS_MAP)) {
+                    modified = true;
+                }
+            } else {
             }
-            AbstractFunctionCallExpression functionCall = 
(AbstractFunctionCallExpression) argFirst;
-            if 
(ALGEBRICKS_MAP.containsKey(functionCall.getFunctionIdentifier())) {
-                FunctionIdentifier algebricksFid = 
ALGEBRICKS_MAP.get(functionCall.getFunctionIdentifier());
-                IFunctionInfo algebricksFunction = 
context.getMetadataProvider().lookupFunction(algebricksFid);
-                functionCall.setFunctionInfo(algebricksFunction);
-                searchM.setValue(argFirst);
-                modified = true;
+            for (Mutable<ILogicalExpression> argExp : afce.getArguments()) {
+                if (checkAllFunctionExpressions(argExp, context)) {
+                    modified = true;
+                }
             }
         }
         return modified;
     }
-
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/vxquery/blob/c31a36cb/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/ExpressionToolbox.java
----------------------------------------------------------------------
diff --git 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/ExpressionToolbox.java
 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/ExpressionToolbox.java
index 2b2bf0c..9374cc3 100644
--- 
a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/ExpressionToolbox.java
+++ 
b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/util/ExpressionToolbox.java
@@ -130,7 +130,22 @@ public class ExpressionToolbox {
     }
 
     /**
-     * Find all functions for a specific expression.
+     * Finds all functions for a given expression.
+     */
+    public static void findAllFunctionExpressions(Mutable<ILogicalExpression> 
mutableLe,
+            List<Mutable<ILogicalExpression>> finds) {
+        ILogicalExpression le = mutableLe.getValue();
+        if (le.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+            AbstractFunctionCallExpression afce = 
(AbstractFunctionCallExpression) le;
+            finds.add(mutableLe);
+            for (Mutable<ILogicalExpression> argExp : afce.getArguments()) {
+                findAllFunctionExpressions(argExp, finds);
+            }
+        }
+    }
+
+    /**
+     * Finds all functions for a given expression and function identifier.
      */
     public static void findAllFunctionExpressions(Mutable<ILogicalExpression> 
mutableLe, FunctionIdentifier fi,
             List<Mutable<ILogicalExpression>> finds) {

Reply via email to