[email protected] has uploaded a new change for review.

  https://asterix-gerrit.ics.uci.edu/3076

Change subject: review comments -- mid fix; ParseValueParser approach to be 
modified.
......................................................................

review comments -- mid fix;
ParseValueParser approach to be modified.

Change-Id: Icd4e434c0f00a1855578046ff42e6a387d884936
---
D 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ParseValuesJsonPrintUtils.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_parseonly.xml
M 
asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java
M 
asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
R 
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseOnlyResult.java
M 
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValueParser.java
M 
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
9 files changed, 121 insertions(+), 186 deletions(-)


  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/76/3076/1

diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ParseValuesJsonPrintUtils.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ParseValuesJsonPrintUtils.java
deleted file mode 100644
index 4d41e86..0000000
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ParseValuesJsonPrintUtils.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.asterix.api.http.server;
-
-import org.apache.asterix.lang.sqlpp.parser.ParseValues;
-import org.apache.asterix.translator.SessionConfig;
-import org.apache.hyracks.util.JSONUtil;
-
-public class ParseValuesJsonPrintUtils {
-
-    private static final String EXTERNAL_VARIABLE_LBL = "statement-parameters";
-
-    public static String asJson(ParseValues parseValues) {
-        final StringBuilder output = new StringBuilder();
-        appendOutputPrefix(output);
-        appendNonNull(output, EXTERNAL_VARIABLE_LBL, 
parseValues.toStringDebug());
-        appendOutputPostfix(output);
-        return output.toString();
-    }
-
-    private static void appendNonNull(StringBuilder builder, String lbl, 
String value) {
-        //TODO: The format is string. Should we use JSON?
-
-        SessionConfig.PlanFormat format = SessionConfig.PlanFormat.STRING;
-
-        if (value != null) {
-            printFieldPrefix(builder, lbl);
-            switch (format) {
-                case JSON:
-                    //TODO: No support for JSON currently.
-                    break;
-                case STRING:
-                    JSONUtil.quoteAndEscape(builder, value);
-                    break;
-                default:
-                    throw new IllegalStateException("Unrecognized plan format: 
" + format);
-            }
-            printFieldPostfix(builder);
-        }
-    }
-
-    //TODO: Refactor to remove code duplication from 
ExecutionPlansJsonPrintUtil
-    private static void appendOutputPrefix(StringBuilder builder) {
-        builder.append("{");
-    }
-
-    private static void printFieldPrefix(StringBuilder builder, String lbl) {
-        builder.append("\"" + lbl + "\": ");
-    }
-
-    private static void printFieldPostfix(StringBuilder builder) {
-        builder.append(",");
-    }
-
-    private static void appendOutputPostfix(StringBuilder builder) {
-        // remove extra comma if needed
-        if (builder.length() > 1) {
-            builder.deleteCharAt(builder.length() - 1);
-        }
-        builder.append("}");
-    }
-
-}
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
index 41cc69d..707590a 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
@@ -47,6 +47,7 @@
 import org.apache.asterix.lang.common.base.IParser;
 import org.apache.asterix.lang.common.base.IParserFactory;
 import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.sqlpp.parser.ParseOnlyResult;
 import org.apache.asterix.metadata.MetadataManager;
 import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.translator.*;
@@ -64,7 +65,6 @@
 import org.apache.logging.log4j.Logger;
 
 import org.apache.asterix.lang.sqlpp.parser.ParseValueParser;
-import org.apache.asterix.lang.sqlpp.parser.ParseValues;
 
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.JsonMappingException;
@@ -532,97 +532,63 @@
         long errorCount = 1; // so far we just return 1 error
         List<ExecutionWarning> warnings = Collections.emptyList(); // we don't 
have any warnings yet
 
-        if (param.getStatement() == null || param.getStatement().isEmpty()) {
-            throw new RuntimeDataException(ErrorCode.NO_STATEMENT_PROVIDED);
-        } //TODO: moved this out of try-catch block.
-
-        String statementsText = param.getStatement() + ";";
-
         RequestExecutionState execution = new RequestExecutionState();
-        if (param.isParseOnly()) {
-            try {
-                ParseValues parseValues = parseStatement(statementsText); //is 
cousin of executeStatement
+        try {
+            if (param.getStatement() == null || 
param.getStatement().isEmpty()) {
+                throw new 
RuntimeDataException(ErrorCode.NO_STATEMENT_PROVIDED);
+            } //TODO: moved this out of try-catch block.
+
+            String statementsText = param.getStatement() + ";";
+
+            Map<String, String> optionalParams = null;
+            if (optionalParamProvider != null) {
+                optionalParams = optionalParamProvider.apply(request);
+            }
+            if (param.isParseOnly()) {
+                ParseOnlyResult parseOnlyResult = 
parseStatement(statementsText); //is cousin of executeStatement
+                response.setStatus(HttpResponseStatus.OK);
                 // CORS
                 if (request.getHeader("Origin") != null) {
                     response.setHeader("Access-Control-Allow-Origin", 
request.getHeader("Origin"));
                 }
                 response.setHeader("Access-Control-Allow-Headers", "Origin, 
X-Requested-With, Content-Type, Accept");
-
-                response.setStatus(HttpResponseStatus.OK);
-                if (ResultDelivery.IMMEDIATE == delivery || 
ResultDelivery.DEFERRED == delivery) {
-                    ResultUtil.printStatus(sessionOutput, 
execution.getResultStatus());
-                }
-                if (!warnings.isEmpty()) {
-                    printWarnings(sessionOutput.out(), warnings);
-                }
-                errorCount = 0;
-                printParseValues(sessionOutput, parseValues);
-
-            } catch (Exception | TokenMgrError | 
org.apache.asterix.aqlplus.parser.TokenMgrError e) {
-                //TODO: figure out what to do with compilation error
-                //TODO: invoke the already backed exception handling
-                if (LOGGER.isDebugEnabled()) {
-
-                    LOGGER.debug("handleException: {}: {}", e.getMessage(), 
param, e);
-                } else {
-                    LOGGER.info("handleException: {}: {}", e.getMessage(), 
param);
-                    //sessionOutput.out()
-                    //       .print(e.getMessage() + ";" + 
e.getLocalizedMessage() + ";" + e.getSourceLocation());
-                }
-                handleExecuteStatementException(e, execution, param); //hope 
this is generic enough to do its thing.
-                response.setStatus(execution.getHttpStatus());
-                printError(sessionOutput.out(), e);
-                ResultUtil.printStatus(sessionOutput, 
execution.getResultStatus());
-                if (!warnings.isEmpty()) {
-                    printWarnings(sessionOutput.out(), warnings);
-                }
-
-            } finally {
-                // make sure that we stop buffering and return the result to 
the http response
-                sessionOutput.release();
-
-            }
-            //printMetrics(sessionOutput.out(), System.nanoTime() - 
elapsedStart, execution.duration(), stats.getCount(),
-            //        stats.getSize(), stats.getProcessedObjects(), 
errorCount, warnings.size());
-
-        } else {
-
-            try {
-                Map<String, String> optionalParams = null;
-                if (optionalParamProvider != null) {
-                    optionalParams = optionalParamProvider.apply(request);
-                }
+                printParseValues(sessionOutput, parseOnlyResult);
+            } else {
                 Map<String, byte[]> statementParams = 
org.apache.asterix.app.translator.RequestParameters
                         .serializeParameterValues(param.getStatementParams());
+
                 // CORS
                 if (request.getHeader("Origin") != null) {
                     response.setHeader("Access-Control-Allow-Origin", 
request.getHeader("Origin"));
                 }
                 response.setHeader("Access-Control-Allow-Headers", "Origin, 
X-Requested-With, Content-Type, Accept");
                 response.setStatus(execution.getHttpStatus());
+
                 executeStatement(statementsText, sessionOutput, 
resultProperties, stats, param, execution,
                         optionalParams, statementParams);
                 if (ResultDelivery.IMMEDIATE == delivery || 
ResultDelivery.DEFERRED == delivery) {
                     ResultUtil.printStatus(sessionOutput, 
execution.getResultStatus());
                 }
-                if (!warnings.isEmpty()) {
-                    printWarnings(sessionOutput.out(), warnings);
-                }
-                errorCount = 0;
-
-            } catch (Exception | TokenMgrError | 
org.apache.asterix.aqlplus.parser.TokenMgrError e) {
-                handleExecuteStatementException(e, execution, param);
-                response.setStatus(execution.getHttpStatus());
-                printError(sessionOutput.out(), e);
-                ResultUtil.printStatus(sessionOutput, 
execution.getResultStatus());
-            } finally {
-                // make sure that we stop buffering and return the result to 
the http response
-                sessionOutput.release();
-                execution.finish();
             }
+            if (!warnings.isEmpty()) {
+                printWarnings(sessionOutput.out(), warnings);
+            }
+
+            errorCount = 0;
+
+        } catch (Exception | TokenMgrError | 
org.apache.asterix.aqlplus.parser.TokenMgrError e) {
+            handleExecuteStatementException(e, execution, param);
+            response.setStatus(execution.getHttpStatus());
+            printError(sessionOutput.out(), e);
+            ResultUtil.printStatus(sessionOutput, execution.getResultStatus());
+        } finally {
+            // make sure that we stop buffering and return the result to the 
http response
+            sessionOutput.release();
+            execution.finish();
+        }
+        if (!param.isParseOnly()) {
             printMetrics(sessionOutput.out(), System.nanoTime() - 
elapsedStart, execution.duration(), stats.getCount(),
                     stats.getSize(), stats.getProcessedObjects(), errorCount, 
warnings.size());
-
         }
         sessionOutput.out().print("}\n");
         sessionOutput.out().flush();
@@ -631,19 +597,11 @@
         }
     }
 
-    protected ParseValues parseStatement(String statementsText) throws 
Exception {
-        //assert (param.isMultiStatement() == false);
-        try {
-            //IParser parser = 
compilationProvider.getParserFactory().createParser(statementsText);
-            IParserFactory factory = compilationProvider.getParserFactory();
-            ParseValueParser parser = new ParseValueParser(factory, 
statementsText);
-            parser.parse();
-            return parser.getParseValues();
-
-        } catch (Exception ce) {
-            throw ce;
-        }
-
+    protected ParseOnlyResult parseStatement(String statementsText) throws 
Exception {
+        IParserFactory factory = compilationProvider.getParserFactory();
+        ParseValueParser parser = new ParseValueParser(factory, 
statementsText);
+        parser.parse();
+        return parser.getParseOnlyResult();
     }
 
     protected void executeStatement(String statementsText, SessionOutput 
sessionOutput,
@@ -716,13 +674,13 @@
         ResultUtil.printWarnings(pw, warnings);
     }
 
-    protected void printParseValues(SessionOutput output, ParseValues 
parseValues) {
+    protected void printParseValues(SessionOutput output, ParseOnlyResult 
parseOnlyResult) {
         final PrintWriter pw = output.out();
         pw.print("\t\"");
         pw.print(ResultFields.PARSEVALS.str());
         pw.print("\":");
 
-        pw.print(ParseValuesJsonPrintUtils.asJson(parseValues));
+        pw.print(ResultUtil.ParseValuesJsonPrintUtils.asJson(parseOnlyResult));
 
         //pw.print(",\n"); //TODO: comma or no comma
         pw.print("\n"); //TODO: comma or no comma
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
index 8824f6a..a6d057b 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
@@ -35,6 +35,7 @@
 import org.apache.asterix.app.result.ResultReader;
 import org.apache.asterix.common.api.IApplicationContext;
 import org.apache.asterix.lang.aql.parser.TokenMgrError;
+import org.apache.asterix.lang.sqlpp.parser.ParseOnlyResult;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.translator.IStatementExecutor.Stats;
 import org.apache.asterix.translator.SessionOutput;
@@ -379,4 +380,47 @@
         return (app, status) -> 
app.append("\t\"").append(AbstractQueryApiServlet.ResultFields.STATUS.str())
                 .append("\": \"").append(status).append("\",\n");
     }
+
+    public static class ParseValuesJsonPrintUtils {
+
+        private static final String EXTERNAL_VARIABLE_LBL = 
"statement-parameters";
+
+        public static String asJson(ParseOnlyResult parseOnlyResult) {
+            final StringBuilder output = new StringBuilder();
+            appendOutputPrefix(output);
+            appendNonNull(output, EXTERNAL_VARIABLE_LBL, 
parseOnlyResult.toStringDebug());
+            appendOutputPostfix(output);
+            return output.toString();
+        }
+
+        private static void appendNonNull(StringBuilder builder, String lbl, 
String value) {
+            if (value != null) {
+                printFieldPrefix(builder, lbl);
+                JSONUtil.quoteAndEscape(builder, value);
+                printFieldPostfix(builder);
+            }
+        }
+
+        //TODO: Refactor to remove code duplication from 
ExecutionPlansJsonPrintUtil
+        private static void appendOutputPrefix(StringBuilder builder) {
+            builder.append("{");
+        }
+
+        private static void printFieldPrefix(StringBuilder builder, String 
lbl) {
+            builder.append("\"" + lbl + "\": ");
+        }
+
+        private static void printFieldPostfix(StringBuilder builder) {
+            builder.append(",");
+        }
+
+        private static void appendOutputPostfix(StringBuilder builder) {
+            // remove extra comma if needed
+            if (builder.length() > 1) {
+                builder.deleteCharAt(builder.length() - 1);
+            }
+            builder.append("}");
+        }
+
+    }
 }
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_parseonly.xml 
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_parseonly.xml
index 35ba883..d443a9f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_parseonly.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_parseonly.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <!--
  ! Licensed to the Apache Software Foundation (ASF) under one
  ! or more contributor license agreements.  See the NOTICE file
@@ -16,8 +17,6 @@
  ! specific language governing permissions and limitations
  ! under the License.
  !-->
-
-<?xml version="1.0" encoding="UTF-8"?>
 <test-suite xmlns="urn:xml.testframework.asterix.apache.org" 
ResultOffsetPath="results" QueryOffsetPath="queries"
             QueryFileExtension=".sqlpp">
     <test-group name="parseonly">
diff --git 
a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java
 
b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java
index 967fdae..85f19ad 100644
--- 
a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java
+++ 
b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java
@@ -140,6 +140,11 @@
         return gfc.getCalls();
     }
 
+    @Override
+    Set<VariableExpr> getFreeVariables(Expression expr) {
+        throw new UnsupportedOperationException("getFreeVariables not 
implemented for AQL");
+    }
+
     private static class GatherFunctionCalls extends 
GatherFunctionCallsVisitor implements IAQLVisitor<Void, Void> {
 
         public GatherFunctionCalls() {
diff --git 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
index 8f3b8a9..0c42e40 100644
--- 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
+++ 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
@@ -24,6 +24,7 @@
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
 import org.apache.asterix.lang.common.statement.FunctionDecl;
 import org.apache.asterix.lang.common.struct.VarIdentifier;
@@ -52,5 +53,7 @@
      * Find the function calls used by a given expression
      */
     Set<CallExpr> getFunctionCalls(Expression expression) throws 
CompilationException;
+    Set<VariableExpr> getFreeVariables(Expression expr) throws 
CompilationException;
+
 
 }
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValues.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseOnlyResult.java
similarity index 94%
rename from 
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValues.java
rename to 
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseOnlyResult.java
index 266e7d2..6b356d6 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValues.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseOnlyResult.java
@@ -22,10 +22,9 @@
 import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
 
-import java.io.Serializable;
 import java.util.Set;
 
-public class ParseValues implements Serializable {
+public class ParseOnlyResult {
     private Set<VariableExpr> externalVariables;
     private String extVarsSerialized;
 
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValueParser.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValueParser.java
index 14770b4..e765e83 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValueParser.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/ParseValueParser.java
@@ -25,15 +25,17 @@
 import org.apache.asterix.lang.common.base.IParserFactory;
 import org.apache.asterix.lang.common.base.Statement;
 import org.apache.asterix.lang.common.expression.VariableExpr;
-import org.apache.asterix.lang.sqlpp.visitor.NamedParameterVisitor;
+import org.apache.asterix.lang.sqlpp.visitor.FreeVariableVisitor;
+import 
org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppQueryExpressionVisitor;
 
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
 public class ParseValueParser {
     private final IParserFactory parserFactory;
-    private final ParseValues parseValues;
+    private final ParseOnlyResult parseOnlyResult;
     private final Set<VariableExpr> extVars;
     private final String statementsText;
     private IParser parser;
@@ -42,29 +44,25 @@
         this.statementsText = statementsText;
         this.parserFactory = parserFactory;
         this.extVars = new HashSet<>();
-        this.parseValues = new ParseValues();
+        this.parseOnlyResult = new ParseOnlyResult();
 
     }
 
     public List<Statement> parse() throws CompilationException {
         parser = parserFactory.createParser(statementsText);
         List<Statement> statements = parser.parse();
-        NamedParameterVisitor erv = new NamedParameterVisitor();
+        AbstractSqlppQueryExpressionVisitor<Void, Collection<VariableExpr>> 
frv = new FreeVariableVisitor();
+        //NamedParameterVisitor erv = new NamedParameterVisitor();
         for (Statement st : statements) {
-            st.accept(erv, extVars);
+            st.accept(frv, extVars);
         }
-        parseValues.setExternalVariables(extVars);
+        parseOnlyResult.setExternalVariables(extVars);
         return statements;
 
     }
 
-    public ParseValues getParseValues() {
-        return parseValues;
-    }
-
-    public String toStringDebug() {
-        return parseValues.toStringDebug();
-
+    public ParseOnlyResult getParseOnlyResult() {
+        return parseOnlyResult;
     }
 
 }
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
index 5aa5a8c..030c3bf 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
@@ -18,10 +18,7 @@
  */
 package org.apache.asterix.lang.sqlpp.rewrites;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.functions.FunctionSignature;
@@ -30,6 +27,7 @@
 import org.apache.asterix.lang.common.base.IReturningStatement;
 import org.apache.asterix.lang.common.clause.LetClause;
 import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
 import org.apache.asterix.lang.common.statement.FunctionDecl;
 import org.apache.asterix.lang.common.struct.VarIdentifier;
@@ -68,6 +66,8 @@
 import 
org.apache.asterix.lang.sqlpp.rewrites.visitor.VariableCheckAndRewriteVisitor;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
 import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
+import org.apache.asterix.lang.sqlpp.visitor.FreeVariableVisitor;
+import 
org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppQueryExpressionVisitor;
 import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
 import org.apache.asterix.metadata.declared.MetadataProvider;
 
@@ -251,6 +251,15 @@
         return gfc.getCalls();
     }
 
+    @Override
+    public Set<VariableExpr> getFreeVariables(Expression expr) throws 
CompilationException
+    {
+        Set<VariableExpr> extVars = new HashSet<>(); //TODO: memory alloc 
within function?
+        AbstractSqlppQueryExpressionVisitor<Void, Collection<VariableExpr>> 
frv = new FreeVariableVisitor();
+        expr.accept(frv, extVars);
+        return extVars;
+    }
+
     private static class GatherFunctionCalls extends 
GatherFunctionCallsVisitor implements ISqlppVisitor<Void, Void> {
 
         public GatherFunctionCalls() {

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3076
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Icd4e434c0f00a1855578046ff42e6a387d884936
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: [email protected]

Reply via email to