[ASTERIXDB-2545][COMP] Compiler error with window function call

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
- Fixed compiler error when window function call
  contains several aggregate functions

Change-Id: Iea946be7f9988bcf991566e4fea9e7a3565b3eaf
Reviewed-on: https://asterix-gerrit.ics.uci.edu/3344
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggFuncIntoStandaloneAggregateRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggFuncIntoStandaloneAggregateRule.java
index 4ae25e8..1fff73a 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggFuncIntoStandaloneAggregateRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggFuncIntoStandaloneAggregateRule.java
@@ -19,11 +19,10 @@
 package org.apache.asterix.optimizer.rules;
 
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 
+import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
@@ -196,9 +195,7 @@
         }
 
         List<Mutable<ILogicalExpression>> srcAssignExprRefs = new LinkedList<Mutable<ILogicalExpression>>();
-        if (fingAggFuncExprRef(assignOp.getExpressions(), aggVar, srcAssignExprRefs) == false) {
-            return false;
-        }
+        findAggFuncExprRef(assignOp.getExpressions(), aggVar, srcAssignExprRefs);
         if (srcAssignExprRefs.isEmpty()) {
             return false;
         }
@@ -239,36 +236,21 @@
         return true;
     }
 
-    private boolean fingAggFuncExprRef(List<Mutable<ILogicalExpression>> exprRefs, LogicalVariable aggVar,
+    private void findAggFuncExprRef(List<Mutable<ILogicalExpression>> exprRefs, LogicalVariable aggVar,
             List<Mutable<ILogicalExpression>> srcAssignExprRefs) {
         for (Mutable<ILogicalExpression> exprRef : exprRefs) {
             ILogicalExpression expr = exprRef.getValue();
-
-            if ((expr.getExpressionTag() == LogicalExpressionTag.VARIABLE)
-                    && ((VariableReferenceExpression) expr).getVariableReference().equals(aggVar)) {
-                return false;
-            }
-
-            if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
-                continue;
-            }
-            AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
-            FunctionIdentifier funcIdent = BuiltinFunctions.getAggregateFunction(funcExpr.getFunctionIdentifier());
-            if (funcIdent == null) {
-                // Recursively look in func args.
-                if (fingAggFuncExprRef(funcExpr.getArguments(), aggVar, srcAssignExprRefs) == false) {
-                    return false;
-                }
-
-            } else {
-                // Check if this is the expr that uses aggVar.
-                Collection<LogicalVariable> usedVars = new HashSet<LogicalVariable>();
-                funcExpr.getUsedVariables(usedVars);
-                if (usedVars.contains(aggVar)) {
+            if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+                AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
+                FunctionIdentifier funcIdent = BuiltinFunctions.getAggregateFunction(funcExpr.getFunctionIdentifier());
+                if (funcIdent != null
+                        && aggVar.equals(SqlppVariableUtil.getVariable(funcExpr.getArguments().get(0).getValue()))) {
                     srcAssignExprRefs.add(exprRef);
+                } else {
+                    // Recursively look in func args.
+                    findAggFuncExprRef(funcExpr.getArguments(), aggVar, srcAssignExprRefs);
                 }
             }
         }
-        return true;
     }
 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/window/misc_01/misc_01.8.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/window/misc_01/misc_01.8.query.sqlpp
new file mode 100644
index 0000000..6345d25
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/window/misc_01/misc_01.8.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * Description  : Window function call with multiple aggregates
+ * Expected Res : SUCCESS
+ */
+
+from range(1, 4) x
+select x, array_sum(to_array(array_count(w))) over w as () as `sum`
+order by x;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/window/misc_01/misc_01.8.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/window/misc_01/misc_01.8.adm
new file mode 100644
index 0000000..d7f0a48
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/window/misc_01/misc_01.8.adm
@@ -0,0 +1,4 @@
+{ "x": 1, "sum": 4 }
+{ "x": 2, "sum": 4 }
+{ "x": 3, "sum": 4 }
+{ "x": 4, "sum": 4 }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/window/misc_01/misc_01.8.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/window/misc_01/misc_01.8.ast
new file mode 100644
index 0000000..6204b11
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/window/misc_01/misc_01.8.ast
@@ -0,0 +1,26 @@
+Query:
+SELECT [
+Variable [ Name=$x ]
+x
+WINDOW null.array_sum@1[
+  FunctionCall null.to-array@1[
+    FunctionCall asterix.sql-count@1[
+      Variable [ Name=$w ]
+    ]
+  ]
+]
+  AS Variable [ Name=$w ]
+OVER (
+)
+sum
+]
+FROM [  FunctionCall null.range@2[
+    LiteralExpr [LONG] [1]
+    LiteralExpr [LONG] [4]
+  ]
+  AS Variable [ Name=$x ]
+]
+Orderby
+  Variable [ Name=$x ]
+  ASC
+
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
index 5d9ce21..361bcf6 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
@@ -42,6 +42,10 @@
 import org.apache.asterix.lang.sqlpp.clause.FromTerm;
 import org.apache.asterix.lang.sqlpp.visitor.FreeVariableVisitor;
 import org.apache.hyracks.algebricks.common.utils.Pair;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 
 public class SqlppVariableUtil {
 
@@ -207,4 +211,9 @@
         newVarExpr.setSourceLocation(varExpr.getSourceLocation());
         outFieldList.add(new Pair<>(newVarExpr, toUserDefinedVariableName(var)));
     }
+
+    public static LogicalVariable getVariable(ILogicalExpression expr) {
+        return expr.getExpressionTag() == LogicalExpressionTag.VARIABLE
+                ? ((VariableReferenceExpression) expr).getVariableReference() : null;
+    }
 }