You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@asterixdb.apache.org by "Anon. E. Moose (Code Review)" <do...@asterixdb.incubator.apache.org> on 2018/12/05 14:57:00 UTC

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Sandeep.gupta@couchbase.com has uploaded a new change for review.

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

Change subject: parseOnly feature using namedParameterVisitor
......................................................................

parseOnly feature using namedParameterVisitor

Change-Id: If619d99c482154eac542c8fa184c857b707fef03
---
M asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.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/app/translator/QueryTranslator.java
A asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/NamedParameterVisitor.java
4 files changed, 494 insertions(+), 40 deletions(-)


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

diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
index 16a2105..e0af3bd 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
@@ -44,6 +44,7 @@
     private String planFormat;
     private Map<String, JsonNode> statementParams;
     private boolean expressionTree;
+    private boolean parseOnly; //don't execute; simply check for syntax correctness and named parameters.
     private boolean rewrittenExpressionTree;
     private boolean logicalPlan;
     private boolean optimizedLogicalPlan;
@@ -171,6 +172,14 @@
         this.optimizedLogicalPlan = optimizedLogicalPlan;
     }
 
+    public void setParseOnly(boolean parseOnly) {
+        this.parseOnly = parseOnly;
+    }
+
+    public boolean isParseOnly() {
+        return parseOnly;
+    }
+
     public boolean isJob() {
         return job;
     }
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 765ba9c..534cafb 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
@@ -28,11 +28,7 @@
 import java.io.PrintWriter;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.ConcurrentMap;
 import java.util.function.BiFunction;
 import java.util.function.Function;
@@ -44,12 +40,16 @@
 import org.apache.asterix.common.config.GlobalConfig;
 import org.apache.asterix.common.context.IStorageComponentProvider;
 import org.apache.asterix.common.dataflow.ICcApplicationContext;
+import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.exceptions.RuntimeDataException;
 import org.apache.asterix.compiler.provider.ILangCompilationProvider;
 import org.apache.asterix.lang.aql.parser.TokenMgrError;
 import org.apache.asterix.lang.common.base.IParser;
 import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
+import org.apache.asterix.lang.sqlpp.visitor.NamedParameterVisitor;
 import org.apache.asterix.metadata.MetadataManager;
 import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.translator.ExecutionPlans;
@@ -153,6 +153,7 @@
         REWRITTEN_EXPRESSION_TREE("rewritten-expression-tree"),
         LOGICAL_PLAN("logical-plan"),
         OPTIMIZED_LOGICAL_PLAN("optimized-logical-plan"),
+        PARSE_ONLY("parse-only"),
         JOB("job"),
         SIGNATURE("signature"),
         MULTI_STATEMENT("multi-statement");
@@ -436,6 +437,7 @@
                 param.setLogicalPlan(getOptBoolean(jsonRequest, Parameter.LOGICAL_PLAN.str(), false));
                 param.setOptimizedLogicalPlan(
                         getOptBoolean(jsonRequest, Parameter.OPTIMIZED_LOGICAL_PLAN.str(), false));
+                param.setParseOnly(getOptBoolean(jsonRequest, Parameter.PARSE_ONLY.str(), false));
                 param.setJob(getOptBoolean(jsonRequest, Parameter.JOB.str(), false));
                 param.setSignature(getOptBoolean(jsonRequest, Parameter.SIGNATURE.str(), true));
                 param.setStatementParams(
@@ -508,6 +510,29 @@
         return "http://" + host + path + handlePath(delivery);
     }
 
+    protected void parseOnlyStatement(String statementsText, QueryServiceRequestParameters param,
+            SessionOutput sessionOutput) throws CompilationException {
+        assert (param.isMultiStatement() == false);
+        try {
+            IParser parser = compilationProvider.getParserFactory().createParser(statementsText);
+            List<Statement> statements = parser.parse();
+            Set<VariableExpr> extVars = new HashSet<>();
+
+            NamedParameterVisitor erv = new NamedParameterVisitor();
+            for (Statement st : statements) {
+                st.accept(erv, extVars);
+            }
+            for (VariableExpr extVarRef : extVars) {
+                sessionOutput.out().println(SqlppVariableUtil.toUserDefinedName(extVarRef.getVar().getValue()));
+            }
+
+        } catch (CompilationException ce) {
+            System.out.println("Compilation Exception happened");
+            throw ce;
+        }
+
+    }
+
     private void handleRequest(IServletRequest request, IServletResponse response) throws IOException {
         QueryServiceRequestParameters param = getRequestParameters(request);
         LOGGER.info("handleRequest: {}", param);
@@ -525,7 +550,6 @@
         HttpUtil.setContentType(response, HttpUtil.ContentType.APPLICATION_JSON, HttpUtil.Encoding.UTF8);
 
         Stats stats = new Stats();
-        RequestExecutionState execution = new RequestExecutionState();
 
         // buffer the output until we are ready to set the status of the response message correctly
         sessionOutput.hold();
@@ -536,44 +560,72 @@
         printType(sessionOutput.out(), sessionConfig);
         long errorCount = 1; // so far we just return 1 error
         List<ExecutionWarning> warnings = Collections.emptyList(); // we don't have any warnings yet
-        try {
-            if (param.getStatement() == null || param.getStatement().isEmpty()) {
-                throw new RuntimeDataException(ErrorCode.NO_STATEMENT_PROVIDED);
+
+        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() + ";";
+
+        if (param.isParseOnly()) {
+            try {
+                parseOnlyStatement(statementsText, param, sessionOutput);
+            } catch (CompilationException ce) {
+                //TODO: figure out what to do with compilation error
+                //TODO: invoke the already backed exception handling
+                if (LOGGER.isDebugEnabled()) {
+
+                    LOGGER.debug("handleException: {}: {}", ce.getMessage(), param, ce);
+                } else {
+                    LOGGER.info("handleException: {}: {}", ce.getMessage(), param);
+                    sessionOutput.out()
+                            .print(ce.getMessage() + ";" + ce.getLocalizedMessage() + ";" + ce.getSourceLocation());
+                }
+
+            } finally {
+                // make sure that we stop buffering and return the result to the http response
+                sessionOutput.release();
+                //TODO: make sure we are exiting the function from here.
+
             }
-            String statementsText = param.getStatement() + ";";
-            Map<String, String> optionalParams = null;
-            if (optionalParamProvider != null) {
-                optionalParams = optionalParamProvider.apply(request);
-            }
-            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) {
+
+        } else {
+            RequestExecutionState execution = new RequestExecutionState();
+            try {
+                Map<String, String> optionalParams = null;
+                if (optionalParamProvider != null) {
+                    optionalParams = optionalParamProvider.apply(request);
+                }
+                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();
+            printMetrics(sessionOutput.out(), System.nanoTime() - elapsedStart, execution.duration(), stats.getCount(),
+                    stats.getSize(), stats.getProcessedObjects(), errorCount, warnings.size());
         }
-        printMetrics(sessionOutput.out(), System.nanoTime() - elapsedStart, execution.duration(), stats.getCount(),
-                stats.getSize(), stats.getProcessedObjects(), errorCount, warnings.size());
         sessionOutput.out().print("}\n");
         sessionOutput.out().flush();
         if (sessionOutput.out().checkError()) {
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
index 3638e55..6845641 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
@@ -251,6 +251,10 @@
         return sessionOutput;
     }
 
+    public List<Statement> getStatements() {
+        return this.statements;
+    }
+
     protected List<FunctionDecl> getDeclaredFunctions(List<Statement> statements) {
         List<FunctionDecl> functionDecls = new ArrayList<>();
         for (Statement st : statements) {
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/NamedParameterVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/NamedParameterVisitor.java
new file mode 100644
index 0000000..c819deb
--- /dev/null
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/NamedParameterVisitor.java
@@ -0,0 +1,389 @@
+/*
+ * 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.lang.sqlpp.visitor;
+
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.clause.*;
+import org.apache.asterix.lang.common.expression.*;
+import org.apache.asterix.lang.common.statement.FunctionDecl;
+import org.apache.asterix.lang.common.statement.Query;
+import org.apache.asterix.lang.common.struct.Identifier;
+import org.apache.asterix.lang.common.struct.QuantifiedPair;
+import org.apache.asterix.lang.sqlpp.clause.*;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
+import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
+import org.apache.asterix.lang.sqlpp.expression.WindowExpression;
+import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
+import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
+import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppQueryExpressionVisitor;
+import org.apache.hyracks.algebricks.common.utils.Pair;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import static org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil.isExternalVariableReference;
+
+public class NamedParameterVisitor extends AbstractSqlppQueryExpressionVisitor<Void, Collection<VariableExpr>> {
+    @Override
+    public Void visit(FromClause fromClause, Collection<VariableExpr> externalVars) throws CompilationException {
+        for (FromTerm fromTerm : fromClause.getFromTerms()) {
+            Collection<VariableExpr> fromTermExternalVars = new HashSet<>();
+            fromTerm.accept(this, fromTermExternalVars);
+            externalVars.addAll(fromTermExternalVars);
+            //TODO does binding vars need to be removed? probably see: FreeVariableVisitor.java:visit(FromClause..)
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(FromTerm fromTerm, Collection<VariableExpr> externalVars) throws CompilationException {
+        // Visit the left expression of a from term.
+        fromTerm.getLeftExpression().accept(this, externalVars);
+        //TODO should binding variables in correlated clause needs to be removed? see FreeVariableVisitor::visit(FromTerm)
+        return null;
+    }
+
+    @Override
+    public Void visit(JoinClause joinClause, Collection<VariableExpr> externalVars) throws CompilationException {
+        visitJoinAndNest(joinClause, joinClause.getConditionExpression(), externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(NestClause nestClause, Collection<VariableExpr> externalVars) throws CompilationException {
+        visitJoinAndNest(nestClause, nestClause.getConditionExpression(), externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(UnnestClause unnestClause, Collection<VariableExpr> externalVars) throws CompilationException {
+        unnestClause.getRightExpression().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(Projection projection, Collection<VariableExpr> externalVars) throws CompilationException {
+        if (!projection.star()) {
+            projection.getExpression().accept(this, externalVars);
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(SelectBlock selectBlock, Collection<VariableExpr> externalVars) throws CompilationException {
+        Collection<VariableExpr> selectexternalVars = new HashSet<>();
+        Collection<VariableExpr> fromexternalVars = new HashSet<>();
+        Collection<VariableExpr> letsexternalVars = new HashSet<>();
+        Collection<VariableExpr> whereexternalVars = new HashSet<>();
+        Collection<VariableExpr> gbyexternalVars = new HashSet<>();
+        Collection<VariableExpr> gbyLetsexternalVars = new HashSet<>();
+
+        //TODO what about binding variables
+
+        selectBlock.getSelectClause().accept(this, selectexternalVars);
+
+        if (selectBlock.hasFromClause()) {
+            selectBlock.getFromClause().accept(this, fromexternalVars);
+        }
+        if (selectBlock.hasLetClauses()) {
+            visitLetClauses(selectBlock.getLetList(), letsexternalVars);
+
+        }
+        if (selectBlock.hasWhereClause()) {
+            selectBlock.getWhereClause().accept(this, whereexternalVars);
+        }
+        if (selectBlock.hasGroupbyClause()) {
+            selectBlock.getGroupbyClause().accept(this, gbyexternalVars);
+
+            if (selectBlock.hasLetClausesAfterGroupby()) {
+                visitLetClauses(selectBlock.getLetListAfterGroupby(), gbyLetsexternalVars);
+            }
+            if (selectBlock.hasHavingClause()) {
+                selectBlock.getHavingClause().accept(this, selectexternalVars);
+            }
+        }
+
+        // Adds all free vars.
+        externalVars.addAll(selectexternalVars);
+        externalVars.addAll(fromexternalVars);
+        externalVars.addAll(letsexternalVars);
+        externalVars.addAll(whereexternalVars);
+        externalVars.addAll(gbyexternalVars);
+        externalVars.addAll(gbyLetsexternalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(SelectClause selectClause, Collection<VariableExpr> externalVars) throws CompilationException {
+        if (selectClause.selectElement()) {
+            selectClause.getSelectElement().accept(this, externalVars);
+        }
+        if (selectClause.selectRegular()) {
+            selectClause.getSelectRegular().accept(this, externalVars);
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(SelectElement selectElement, Collection<VariableExpr> externalVars) throws CompilationException {
+        selectElement.getExpression().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(SelectRegular selectRegular, Collection<VariableExpr> externalVars) throws CompilationException {
+        for (Projection projection : selectRegular.getProjections()) {
+            projection.accept(this, externalVars);
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(SelectSetOperation selectSetOperation, Collection<VariableExpr> externalVars)
+            throws CompilationException {
+        selectSetOperation.getLeftInput().accept(this, externalVars);
+        for (SetOperationRight right : selectSetOperation.getRightInputs()) {
+            right.getSetOperationRightInput().accept(this, externalVars);
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(HavingClause havingClause, Collection<VariableExpr> externalVars) throws CompilationException {
+        havingClause.getFilterExpression().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(Query q, Collection<VariableExpr> externalVars) throws CompilationException {
+        q.getBody().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(FunctionDecl fd, Collection<VariableExpr> externalVars) throws CompilationException {
+        fd.getFuncBody().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(WhereClause whereClause, Collection<VariableExpr> externalVars) throws CompilationException {
+        whereClause.getWhereExpr().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(OrderbyClause oc, Collection<VariableExpr> externalVars) throws CompilationException {
+        visit(oc.getOrderbyList(), externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(GroupbyClause gc, Collection<VariableExpr> externalVars) throws CompilationException {
+        // Puts all group-by variables into the symbol set of the new scope.
+        for (GbyVariableExpressionPair gbyVarExpr : gc.getGbyPairList()) {
+            gbyVarExpr.getExpr().accept(this, externalVars);
+        }
+        for (GbyVariableExpressionPair decorVarExpr : gc.getDecorPairList()) {
+            decorVarExpr.getExpr().accept(this, externalVars);
+        }
+        if (gc.hasGroupFieldList()) {
+            for (Pair<Expression, Identifier> groupField : gc.getGroupFieldList()) {
+                groupField.first.accept(this, externalVars);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(LimitClause limitClause, Collection<VariableExpr> externalVars) throws CompilationException {
+        limitClause.getLimitExpr().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(LetClause letClause, Collection<VariableExpr> externalVars) throws CompilationException {
+        letClause.getBindingExpr().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(SelectExpression selectExpression, Collection<VariableExpr> externalVars)
+            throws CompilationException {
+        Collection<VariableExpr> letsexternalVars = new HashSet<>();
+        Collection<VariableExpr> selectexternalVars = new HashSet<>();
+        visitLetClauses(selectExpression.getLetList(), letsexternalVars);
+
+        // visit order by
+        if (selectExpression.hasOrderby()) {
+            for (Expression orderExpr : selectExpression.getOrderbyClause().getOrderbyList()) {
+                orderExpr.accept(this, selectexternalVars);
+            }
+        }
+
+        // visit limit
+        if (selectExpression.hasLimit()) {
+            selectExpression.getLimitClause().accept(this, selectexternalVars);
+        }
+
+        // visit the main select
+        selectExpression.getSelectSetOperation().accept(this, selectexternalVars);
+
+        //TODO Does bindingVars need to be handled?
+        externalVars.addAll(letsexternalVars);
+        externalVars.addAll(selectexternalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(LiteralExpr l, Collection<VariableExpr> externalVars) throws CompilationException {
+        return null;
+    }
+
+    @Override
+    public Void visit(ListConstructor lc, Collection<VariableExpr> externalVars) throws CompilationException {
+        visit(lc.getExprList(), externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(RecordConstructor rc, Collection<VariableExpr> externalVars) throws CompilationException {
+        for (FieldBinding binding : rc.getFbList()) {
+            binding.getLeftExpr().accept(this, externalVars);
+            binding.getRightExpr().accept(this, externalVars);
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(OperatorExpr operatorExpr, Collection<VariableExpr> externalVars) throws CompilationException {
+        visit(operatorExpr.getExprList(), externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(IfExpr ifExpr, Collection<VariableExpr> externalVars) throws CompilationException {
+        ifExpr.getCondExpr().accept(this, externalVars);
+        ifExpr.getThenExpr().accept(this, externalVars);
+        ifExpr.getElseExpr().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(QuantifiedExpression qe, Collection<VariableExpr> externalVars) throws CompilationException {
+        for (QuantifiedPair pair : qe.getQuantifiedList()) {
+            pair.getExpr().accept(this, externalVars);
+        }
+        qe.getSatisfiesExpr().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(CallExpr callExpr, Collection<VariableExpr> externalVars) throws CompilationException {
+        for (Expression expr : callExpr.getExprList()) {
+            expr.accept(this, externalVars);
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(VariableExpr varExpr, Collection<VariableExpr> externalVars) throws CompilationException {
+        if (isExternalVariableReference(varExpr)) {
+            System.out.println(
+                    "External variable found" + SqlppVariableUtil.toUserDefinedName(varExpr.getVar().getValue()) + " "
+                            + varExpr.getVar().getValue());
+            externalVars.add(varExpr);
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(UnaryExpr u, Collection<VariableExpr> externalVars) throws CompilationException {
+        u.getExpr().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(FieldAccessor fa, Collection<VariableExpr> externalVars) throws CompilationException {
+        fa.getExpr().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(IndexAccessor ia, Collection<VariableExpr> externalVars) throws CompilationException {
+        ia.getExpr().accept(this, externalVars);
+        if (ia.getIndexExpr() != null) {
+            ia.getIndexExpr().accept(this, externalVars);
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(CaseExpression caseExpr, Collection<VariableExpr> externalVars) throws CompilationException {
+        caseExpr.getConditionExpr().accept(this, externalVars);
+        visit(caseExpr.getWhenExprs(), externalVars);
+        visit(caseExpr.getThenExprs(), externalVars);
+        caseExpr.getElseExpr().accept(this, externalVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(WindowExpression winExpr, Collection<VariableExpr> externalVars) throws CompilationException {
+        winExpr.getExpr().accept(this, externalVars);
+        if (winExpr.hasPartitionList()) {
+            visit(winExpr.getPartitionList(), externalVars);
+        }
+        visit(winExpr.getOrderbyList(), externalVars);
+        return null;
+    }
+
+    private void visitLetClauses(List<LetClause> letClauses, Collection<VariableExpr> externalVars)
+            throws CompilationException {
+        if (letClauses == null || letClauses.isEmpty()) {
+            return;
+        }
+        Collection<VariableExpr> bindingVars = new HashSet<>();
+        for (LetClause letClause : letClauses) {
+            Collection<VariableExpr> letExternalVars = new HashSet<>();
+            letClause.accept(this, letExternalVars);
+            externalVars.addAll(letExternalVars);
+            //TODO need to deal with binding vars, see FreeVariableVisitor::visitLetClause
+        }
+    }
+
+    private void visitJoinAndNest(AbstractBinaryCorrelateClause clause, Expression condition,
+            Collection<VariableExpr> externalVars) throws CompilationException {
+        clause.getRightExpression().accept(this, externalVars);
+        Collection<VariableExpr> conditionExternalVars = new HashSet<>();
+        condition.accept(this, externalVars);
+
+        //TODO see FreeVariableVisitor::visitJoinAndNest
+
+    }
+
+    private void visit(List<Expression> exprs, Collection<VariableExpr> arg) throws CompilationException {
+        for (Expression expr : exprs) {
+            expr.accept(this, arg);
+        }
+    }
+
+}

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-asterix-app-sql-execution/4801/ (6/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Anon. E. Moose (Code Review)" <do...@asterixdb.incubator.apache.org>.
Anon. E. Moose #1000171 has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Analytics Compatibility Compilation Successful
https://goo.gl/ypz4bv : SUCCESS

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-sonar/8747/ (9/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Anon. E. Moose (Code Review)" <do...@asterixdb.incubator.apache.org>.
Sandeep.gupta@couchbase.com has abandoned this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Abandoned

wrong commit

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

Gerrit-MessageType: abandon
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-verify-asterix-app/5185/ (5/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-stabilization-f69489-compat/221/ (12/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-source-assemblies/5020/ (10/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-verify-storage/5369/ (2/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-ensure-ancestor/2809/ (8/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-cancellation-test/4799/ (3/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-verify-no-installer-app/5139/ (1/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Integration Tests Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-integration-tests/7626/

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-notopic/10281/ (4/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-source-format/4765/ (11/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/hyracks-gerrit/4710/ (7/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: parseOnly feature using namedParameterVisitor

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: parseOnly feature using namedParameterVisitor
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-asterix-app-openjdk11/219/ (13/13)

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

Gerrit-MessageType: comment
Gerrit-Change-Id: If619d99c482154eac542c8fa184c857b707fef03
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Sandeep.gupta@couchbase.com
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No