You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by bu...@apache.org on 2016/04/05 05:40:41 UTC

[02/10] incubator-asterixdb git commit: Rewrite SQL++ functions.

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/3dd80ec4/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/InlineColumnAliasVisitor.java
----------------------------------------------------------------------
diff --git a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/InlineColumnAliasVisitor.java b/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/InlineColumnAliasVisitor.java
deleted file mode 100644
index 98c74b4..0000000
--- a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/InlineColumnAliasVisitor.java
+++ /dev/null
@@ -1,447 +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.lang.sqlpp.visitor;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.asterix.common.exceptions.AsterixException;
-import org.apache.asterix.lang.common.base.Expression;
-import org.apache.asterix.lang.common.base.Expression.Kind;
-import org.apache.asterix.lang.common.base.Literal;
-import org.apache.asterix.lang.common.clause.GroupbyClause;
-import org.apache.asterix.lang.common.clause.LetClause;
-import org.apache.asterix.lang.common.clause.LimitClause;
-import org.apache.asterix.lang.common.clause.OrderbyClause;
-import org.apache.asterix.lang.common.clause.WhereClause;
-import org.apache.asterix.lang.common.expression.CallExpr;
-import org.apache.asterix.lang.common.expression.FieldAccessor;
-import org.apache.asterix.lang.common.expression.FieldBinding;
-import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
-import org.apache.asterix.lang.common.expression.IfExpr;
-import org.apache.asterix.lang.common.expression.IndexAccessor;
-import org.apache.asterix.lang.common.expression.ListConstructor;
-import org.apache.asterix.lang.common.expression.LiteralExpr;
-import org.apache.asterix.lang.common.expression.OperatorExpr;
-import org.apache.asterix.lang.common.expression.QuantifiedExpression;
-import org.apache.asterix.lang.common.expression.RecordConstructor;
-import org.apache.asterix.lang.common.expression.UnaryExpr;
-import org.apache.asterix.lang.common.expression.VariableExpr;
-import org.apache.asterix.lang.common.parser.ScopeChecker;
-import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
-import org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment;
-import org.apache.asterix.lang.common.statement.FunctionDecl;
-import org.apache.asterix.lang.common.statement.Query;
-import org.apache.asterix.lang.common.struct.QuantifiedPair;
-import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
-import org.apache.asterix.lang.sqlpp.clause.FromClause;
-import org.apache.asterix.lang.sqlpp.clause.FromTerm;
-import org.apache.asterix.lang.sqlpp.clause.HavingClause;
-import org.apache.asterix.lang.sqlpp.clause.JoinClause;
-import org.apache.asterix.lang.sqlpp.clause.NestClause;
-import org.apache.asterix.lang.sqlpp.clause.Projection;
-import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
-import org.apache.asterix.lang.sqlpp.clause.SelectClause;
-import org.apache.asterix.lang.sqlpp.clause.SelectElement;
-import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
-import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
-import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
-import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
-import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
-import org.apache.asterix.lang.sqlpp.util.SqlppVariableSubstitutionUtil;
-import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
-import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppQueryExpressionVisitor;
-
-public class InlineColumnAliasVisitor extends AbstractSqlppQueryExpressionVisitor<Void, Boolean> {
-
-    private final ScopeChecker scopeChecker = new ScopeChecker();
-    private final LangRewritingContext context;
-
-    public InlineColumnAliasVisitor(LangRewritingContext context) {
-        this.context = context;
-    }
-
-    @Override
-    public Void visit(WhereClause whereClause, Boolean arg) throws AsterixException {
-        whereClause.getWhereExpr().accept(this, arg);
-        return null;
-    }
-
-    @Override
-    public Void visit(FromClause fromClause, Boolean arg) throws AsterixException {
-        for (FromTerm fromTerm : fromClause.getFromTerms()) {
-            fromTerm.accept(this, arg);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(FromTerm fromTerm, Boolean arg) throws AsterixException {
-        fromTerm.getLeftExpression().accept(this, arg);
-        // A from binding variable will override the alias to substitute.
-        scopeChecker.getCurrentScope().removeSymbolExpressionMapping(fromTerm.getLeftVariable());
-        if (fromTerm.hasPositionalVariable()) {
-            scopeChecker.getCurrentScope().removeSymbolExpressionMapping(fromTerm.getPositionalVariable());
-        }
-
-        for (AbstractBinaryCorrelateClause correlate : fromTerm.getCorrelateClauses()) {
-            correlate.accept(this, arg);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(JoinClause joinClause, Boolean arg) throws AsterixException {
-        joinClause.getRightExpression().accept(this, arg);
-        removeSubsutitions(joinClause);
-        joinClause.getConditionExpression().accept(this, arg);
-        return null;
-    }
-
-    @Override
-    public Void visit(NestClause nestClause, Boolean arg) throws AsterixException {
-        nestClause.getRightExpression().accept(this, arg);
-        nestClause.getConditionExpression().accept(this, arg);
-        removeSubsutitions(nestClause);
-        return null;
-    }
-
-    @Override
-    public Void visit(UnnestClause unnestClause, Boolean arg) throws AsterixException {
-        unnestClause.getRightExpression().accept(this, arg);
-        removeSubsutitions(unnestClause);
-        return null;
-    }
-
-    @Override
-    public Void visit(Projection projection, Boolean arg) throws AsterixException {
-        projection.getExpression().accept(this, arg);
-        VariableExpr columnAlias = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(projection.getName()));
-        VariableSubstitutionEnvironment env = scopeChecker.getCurrentScope().getVarSubstitutionEnvironment();
-        Expression gbyKey = env.findSubstituion(columnAlias);
-        if (arg) {
-            scopeChecker.getCurrentScope().addSymbolExpressionMappingToScope(columnAlias, projection.getExpression());
-        } else {
-            if (gbyKey != null) {
-                projection.setExpression(gbyKey);
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectBlock selectBlock, Boolean arg) throws AsterixException {
-        // Traverses the select block in the order of "select", "group-by",
-        // "group-by" lets and "having".
-        selectBlock.getSelectClause().accept(this, true);
-
-        if (selectBlock.hasFromClause()) {
-            selectBlock.getFromClause().accept(this, arg);
-        }
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                letClause.accept(this, arg);
-            }
-        }
-        if (selectBlock.hasGroupbyClause()) {
-            selectBlock.getGroupbyClause().accept(this, arg);
-        }
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            for (LetClause letClauseAfterGby : selectBlock.getLetListAfterGroupby()) {
-                letClauseAfterGby.accept(this, true);
-            }
-        }
-        if (selectBlock.hasHavingClause()) {
-            selectBlock.getHavingClause().accept(this, arg);
-        }
-
-        // Visit select clause again to overwrite projection expressions if the group-by clause is rewritten.
-        selectBlock.getSelectClause().accept(this, false);
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectClause selectClause, Boolean arg) throws AsterixException {
-        if (selectClause.selectElement()) {
-            selectClause.getSelectElement().accept(this, arg);
-        }
-        if (selectClause.selectRegular()) {
-            selectClause.getSelectRegular().accept(this, arg);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectElement selectElement, Boolean arg) throws AsterixException {
-        Expression expr = selectElement.getExpression();
-        expr.accept(this, arg);
-        if (expr.getKind() == Kind.RECORD_CONSTRUCTOR_EXPRESSION) {
-            // To be consistent with SelectRegular.
-            mapForRecordConstructor(arg, (RecordConstructor) expr);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectRegular selectRegular, Boolean arg) throws AsterixException {
-        for (Projection projection : selectRegular.getProjections()) {
-            projection.accept(this, arg);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectSetOperation selectSetOperation, Boolean arg) throws AsterixException {
-        selectSetOperation.getLeftInput().accept(this, arg);
-        for (SetOperationRight right : selectSetOperation.getRightInputs()) {
-            right.getSetOperationRightInput().accept(this, arg);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectExpression selectExpression, Boolean arg) throws AsterixException {
-        scopeChecker.createNewScope();
-
-        // Visits let bindings.
-        if (selectExpression.hasLetClauses()) {
-            for (LetClause lc : selectExpression.getLetList()) {
-                lc.accept(this, arg);
-            }
-        }
-
-        // Visits selectSetOperation.
-        selectExpression.getSelectSetOperation().accept(this, arg);
-
-        // Visits order by.
-        if (selectExpression.hasOrderby()) {
-            selectExpression.getOrderbyClause().accept(this, arg);
-        }
-
-        // Visits limit.
-        if (selectExpression.hasLimit()) {
-            selectExpression.getLimitClause().accept(this, arg);
-        }
-
-        // Exits the scope that were entered within this select expression
-        scopeChecker.removeCurrentScope();
-        return null;
-    }
-
-    @Override
-    public Void visit(LetClause letClause, Boolean rewrite) throws AsterixException {
-        VariableSubstitutionEnvironment env = scopeChecker.getCurrentScope().getVarSubstitutionEnvironment();
-        if (rewrite) {
-            Expression newBindExpr = (Expression) SqlppVariableSubstitutionUtil
-                    .substituteVariableWithoutContext(letClause.getBindingExpr(), env);
-            letClause.setBindingExpr(newBindExpr);
-        }
-        letClause.getBindingExpr().accept(this, false);
-        // A let binding variable will override the alias to substitute.
-        scopeChecker.getCurrentScope().removeSymbolExpressionMapping(letClause.getVarExpr());
-        return null;
-    }
-
-    @Override
-    public Void visit(OrderbyClause oc, Boolean arg) throws AsterixException {
-        VariableSubstitutionEnvironment env = scopeChecker.getCurrentScope().getVarSubstitutionEnvironment();
-        List<Expression> orderExprs = new ArrayList<Expression>();
-        for (Expression orderExpr : oc.getOrderbyList()) {
-            orderExprs.add((Expression) SqlppVariableSubstitutionUtil.substituteVariableWithoutContext(orderExpr, env));
-            orderExpr.accept(this, arg);
-        }
-        oc.setOrderbyList(orderExprs);
-        return null;
-    }
-
-    @Override
-    public Void visit(GroupbyClause gc, Boolean arg) throws AsterixException {
-        VariableSubstitutionEnvironment env = scopeChecker.getCurrentScope().getVarSubstitutionEnvironment();
-        Map<VariableExpr, VariableExpr> oldGbyExprsToNewGbyVarMap = new HashMap<>();
-        for (GbyVariableExpressionPair gbyVarExpr : gc.getGbyPairList()) {
-            Expression oldGbyExpr = gbyVarExpr.getExpr();
-            Expression newExpr = (Expression) SqlppVariableSubstitutionUtil.substituteVariableWithoutContext(oldGbyExpr,
-                    env);
-            newExpr.accept(this, arg);
-            gbyVarExpr.setExpr(newExpr);
-            if (gbyVarExpr.getVar() == null) {
-                gbyVarExpr.setVar(new VariableExpr(context.newVariable()));
-            }
-            if (oldGbyExpr.getKind() == Kind.VARIABLE_EXPRESSION) {
-                VariableExpr oldGbyVarExpr = (VariableExpr) oldGbyExpr;
-                if (env.findSubstituion(oldGbyVarExpr) != null) {
-                    // Re-mapping that needs to be added.
-                    oldGbyExprsToNewGbyVarMap.put(oldGbyVarExpr, gbyVarExpr.getVar());
-                }
-            }
-        }
-        for (Entry<VariableExpr, VariableExpr> entry : oldGbyExprsToNewGbyVarMap.entrySet()) {
-            // The group-by key variable will override the alias to substitute.
-            scopeChecker.getCurrentScope().removeSymbolExpressionMapping(entry.getKey());
-            scopeChecker.getCurrentScope().addSymbolExpressionMappingToScope(entry.getKey(), entry.getValue());
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(LimitClause limitClause, Boolean arg) throws AsterixException {
-        limitClause.getLimitExpr().accept(this, arg);
-        return null;
-    }
-
-    @Override
-    public Void visit(HavingClause havingClause, Boolean arg) throws AsterixException {
-        VariableSubstitutionEnvironment env = scopeChecker.getCurrentScope().getVarSubstitutionEnvironment();
-        Expression newFilterExpr = (Expression) SqlppVariableSubstitutionUtil
-                .substituteVariableWithoutContext(havingClause.getFilterExpression(), env);
-        newFilterExpr.accept(this, arg);
-        havingClause.setFilterExpression(newFilterExpr);
-        return null;
-    }
-
-    @Override
-    public Void visit(Query q, Boolean arg) throws AsterixException {
-        q.getBody().accept(this, arg);
-        return null;
-    }
-
-    @Override
-    public Void visit(FunctionDecl fd, Boolean arg) throws AsterixException {
-        scopeChecker.createNewScope();
-        fd.getFuncBody().accept(this, arg);
-        scopeChecker.removeCurrentScope();
-        return null;
-    }
-
-    @Override
-    public Void visit(LiteralExpr l, Boolean arg) throws AsterixException {
-        return null;
-    }
-
-    @Override
-    public Void visit(ListConstructor lc, Boolean arg) throws AsterixException {
-        for (Expression expr : lc.getExprList()) {
-            expr.accept(this, arg);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(RecordConstructor rc, Boolean rewrite) throws AsterixException {
-        for (FieldBinding binding : rc.getFbList()) {
-            binding.getLeftExpr().accept(this, false);
-            binding.getRightExpr().accept(this, false);
-        }
-        return null;
-    }
-
-    private void mapForRecordConstructor(Boolean initPhase, RecordConstructor rc) {
-        for (FieldBinding binding : rc.getFbList()) {
-            Expression leftExpr = binding.getLeftExpr();
-            if (leftExpr.getKind() == Kind.LITERAL_EXPRESSION) {
-                LiteralExpr literalExpr = (LiteralExpr) leftExpr;
-                if (literalExpr.getValue().getLiteralType() == Literal.Type.STRING) {
-                    String fieldName = literalExpr.getValue().getStringValue();
-                    VariableExpr columnAlias = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(fieldName));
-                    VariableSubstitutionEnvironment env = scopeChecker.getCurrentScope()
-                            .getVarSubstitutionEnvironment();
-                    if (initPhase) {
-                        scopeChecker.getCurrentScope().addSymbolExpressionMappingToScope(columnAlias,
-                                binding.getRightExpr());
-                    } else {
-                        Expression gbyKey = env.findSubstituion(columnAlias);
-                        if (gbyKey != null) {
-                            binding.setRightExpr(gbyKey);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public Void visit(OperatorExpr operatorExpr, Boolean arg) throws AsterixException {
-        for (Expression expr : operatorExpr.getExprList()) {
-            expr.accept(this, arg);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(IfExpr ifExpr, Boolean arg) throws AsterixException {
-        ifExpr.getCondExpr().accept(this, arg);
-        ifExpr.getThenExpr().accept(this, arg);
-        ifExpr.getElseExpr().accept(this, arg);
-        return null;
-    }
-
-    @Override
-    public Void visit(QuantifiedExpression qe, Boolean arg) throws AsterixException {
-        for (QuantifiedPair pair : qe.getQuantifiedList()) {
-            pair.getExpr().accept(this, arg);
-        }
-        qe.getSatisfiesExpr().accept(this, arg);
-        return null;
-    }
-
-    @Override
-    public Void visit(CallExpr callExpr, Boolean arg) throws AsterixException {
-        for (Expression expr : callExpr.getExprList()) {
-            expr.accept(this, arg);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(VariableExpr varExpr, Boolean arg) throws AsterixException {
-        return null;
-    }
-
-    @Override
-    public Void visit(UnaryExpr u, Boolean arg) throws AsterixException {
-        u.getExpr().accept(this, arg);
-        return null;
-    }
-
-    @Override
-    public Void visit(FieldAccessor fa, Boolean arg) throws AsterixException {
-        fa.getExpr().accept(this, arg);
-        return null;
-    }
-
-    @Override
-    public Void visit(IndexAccessor ia, Boolean arg) throws AsterixException {
-        ia.getExpr().accept(this, arg);
-        Expression indexExpr = ia.getExpr();
-        if (indexExpr != null) {
-            indexExpr.accept(this, arg);
-        }
-        return null;
-    }
-
-    private void removeSubsutitions(AbstractBinaryCorrelateClause unnestClause) {
-        scopeChecker.getCurrentScope().removeSymbolExpressionMapping(unnestClause.getRightVariable());
-        if (unnestClause.hasPositionalVariable()) {
-            scopeChecker.getCurrentScope().removeSymbolExpressionMapping(unnestClause.getPositionalVariable());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/3dd80ec4/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
----------------------------------------------------------------------
diff --git a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java b/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
index df32b01..0f36646 100644
--- a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
+++ b/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
@@ -21,9 +21,11 @@ package org.apache.asterix.lang.sqlpp.visitor;
 import java.io.PrintWriter;
 
 import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.common.functions.FunctionSignature;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
 import org.apache.asterix.lang.common.clause.LetClause;
+import org.apache.asterix.lang.common.expression.CallExpr;
 import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
 import org.apache.asterix.lang.common.struct.Identifier;
 import org.apache.asterix.lang.common.visitor.QueryPrintVisitor;
@@ -42,7 +44,9 @@ import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
+import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
 import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.hyracks.algebricks.common.utils.Pair;
 
 public class SqlppAstPrintVisitor extends QueryPrintVisitor implements ISqlppVisitor<Void, Integer> {
@@ -243,7 +247,27 @@ public class SqlppAstPrintVisitor extends QueryPrintVisitor implements ISqlppVis
     }
 
     @Override
+    public Void visit(CallExpr pf, Integer step) throws AsterixException {
+        FunctionSignature functionSignature = pf.getFunctionSignature();
+        FunctionSignature normalizedFunctionSignature = FunctionMapUtil
+                .normalizeBuiltinFunctionSignature(functionSignature, false);
+        if (AsterixBuiltinFunctions.isBuiltinCompilerFunction(normalizedFunctionSignature, true)) {
+            functionSignature = normalizedFunctionSignature;
+        }
+        out.println(skip(step) + "FunctionCall " + functionSignature.toString() + "[");
+        for (Expression expr : pf.getExprList()) {
+            expr.accept(this, step + 1);
+        }
+        out.println(skip(step) + "]");
+        return null;
+    }
+
+    @Override
     public Void visit(GroupbyClause gc, Integer step) throws AsterixException {
+        if (gc.isGroupAll()) {
+            out.println(skip(step) + "Group All");
+            return null;
+        }
         out.println(skip(step) + "Groupby");
         for (GbyVariableExpressionPair pair : gc.getGbyPairList()) {
             if (pair.getVar() != null) {

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/3dd80ec4/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
----------------------------------------------------------------------
diff --git a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java b/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
index 5a15772..efff18e 100644
--- a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
+++ b/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
@@ -84,7 +84,7 @@ public class SqlppDeleteRewriteVisitor extends AbstractSqlppAstVisitor<Void, Voi
         SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, whereClause, null, null, null);
         SelectSetOperation selectSetOperation = new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
         SelectExpression selectExpression = new SelectExpression(null, selectSetOperation, null, null, false);
-        Query query = new Query();
+        Query query = new Query(false, selectExpression, 0, new ArrayList<>(), new ArrayList<>());
         query.setBody(selectExpression);
 
         // return the delete statement.

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/3dd80ec4/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppGroupBySugarVisitor.java
----------------------------------------------------------------------
diff --git a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppGroupBySugarVisitor.java b/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppGroupBySugarVisitor.java
deleted file mode 100644
index 5506256..0000000
--- a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppGroupBySugarVisitor.java
+++ /dev/null
@@ -1,127 +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.lang.sqlpp.visitor;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.asterix.common.exceptions.AsterixException;
-import org.apache.asterix.common.functions.FunctionConstants;
-import org.apache.asterix.common.functions.FunctionSignature;
-import org.apache.asterix.lang.common.base.Expression;
-import org.apache.asterix.lang.common.base.Expression.Kind;
-import org.apache.asterix.lang.common.expression.CallExpr;
-import org.apache.asterix.lang.common.expression.FieldAccessor;
-import org.apache.asterix.lang.common.expression.VariableExpr;
-import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
-import org.apache.asterix.lang.common.util.FunctionUtil;
-import org.apache.asterix.lang.sqlpp.clause.FromClause;
-import org.apache.asterix.lang.sqlpp.clause.FromTerm;
-import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
-import org.apache.asterix.lang.sqlpp.clause.SelectClause;
-import org.apache.asterix.lang.sqlpp.clause.SelectElement;
-import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
-import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
-import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
-import org.apache.asterix.lang.sqlpp.util.SqlppRewriteUtil;
-import org.apache.asterix.lang.sqlpp.util.SqlppVariableSubstitutionUtil;
-import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
-import org.apache.asterix.metadata.declared.AqlMetadataProvider;
-import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
-
-/**
- * An AST pre-processor to rewrite group-by sugar queries.
- */
-public class SqlppGroupBySugarVisitor extends VariableCheckAndRewriteVisitor {
-
-    private final Expression groupVar;
-    private final Collection<VariableExpr> targetVars;
-
-    public SqlppGroupBySugarVisitor(LangRewritingContext context, AqlMetadataProvider metadataProvider,
-            Expression groupVar, Collection<VariableExpr> targetVars) {
-        super(context, false, metadataProvider);
-        this.groupVar = groupVar;
-        this.targetVars = targetVars;
-    }
-
-    @Override
-    public Expression visit(CallExpr callExpr, Expression arg) throws AsterixException {
-        List<Expression> newExprList = new ArrayList<Expression>();
-        boolean aggregate = isAggregateFunction(callExpr.getFunctionSignature());
-        for (Expression expr : callExpr.getExprList()) {
-            Expression newExpr = aggregate ? wrapAggregationArgument(expr) : expr;
-            newExprList.add(newExpr.accept(this, arg));
-        }
-        callExpr.setExprList(newExprList);
-        return callExpr;
-    }
-
-    private boolean isAggregateFunction(FunctionSignature signature) throws AsterixException {
-        IFunctionInfo finfo = FunctionUtil.getFunctionInfo(
-                new FunctionIdentifier(FunctionConstants.ASTERIX_NS, signature.getName(), signature.getArity()));
-        if (finfo == null) {
-            return false;
-        }
-        return AsterixBuiltinFunctions.getAggregateFunction(finfo.getFunctionIdentifier()) != null;
-    }
-
-    private Expression wrapAggregationArgument(Expression expr) throws AsterixException {
-        if (expr.getKind() == Kind.SELECT_EXPRESSION) {
-            return expr;
-        }
-        Set<VariableExpr> definedVars = scopeChecker.getCurrentScope().getLiveVariables();
-        Set<VariableExpr> vars = new HashSet<>(targetVars);
-        vars.remove(definedVars); // Exclude re-defined local variables.
-        Set<VariableExpr> usedVars = SqlppRewriteUtil.getUsedVariable(expr);
-        if (!vars.containsAll(usedVars)) {
-            return expr;
-        }
-        VariableExpr var = new VariableExpr(context.newVariable());
-        FromTerm fromTerm = new FromTerm(groupVar, var, null, null);
-        FromClause fromClause = new FromClause(Collections.singletonList(fromTerm));
-
-        // Select clause.
-        SelectElement selectElement = new SelectElement(expr);
-        SelectClause selectClause = new SelectClause(selectElement, null, false);
-
-        // Construct the select expression.
-        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, null, null, null, null);
-        SelectSetOperation selectSetOperation = new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
-        SelectExpression selectExpression = new SelectExpression(null, selectSetOperation, null, null, false);
-        selectExpression.setSubquery(true);
-
-        // replace variable expressions with field access
-        Map<VariableExpr, Expression> varExprMap = new HashMap<>();
-        for (VariableExpr usedVar : usedVars) {
-            varExprMap.put(usedVar,
-                    new FieldAccessor(var, SqlppVariableUtil.toUserDefinedVariableName(usedVar.getVar())));
-        }
-        selectElement.setExpression(
-                (Expression) SqlppVariableSubstitutionUtil.substituteVariableWithoutContext(expr, varExprMap));
-        return selectExpression;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/3dd80ec4/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppGroupByVisitor.java
----------------------------------------------------------------------
diff --git a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppGroupByVisitor.java b/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppGroupByVisitor.java
deleted file mode 100644
index ecbdecd..0000000
--- a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppGroupByVisitor.java
+++ /dev/null
@@ -1,170 +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.lang.sqlpp.visitor;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.asterix.common.exceptions.AsterixException;
-import org.apache.asterix.lang.common.base.Expression;
-import org.apache.asterix.lang.common.clause.GroupbyClause;
-import org.apache.asterix.lang.common.clause.LetClause;
-import org.apache.asterix.lang.common.context.Scope;
-import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
-import org.apache.asterix.lang.common.expression.VariableExpr;
-import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
-import org.apache.asterix.lang.common.struct.Identifier;
-import org.apache.asterix.lang.common.struct.VarIdentifier;
-import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
-import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
-import org.apache.asterix.lang.sqlpp.util.SqlppRewriteUtil;
-import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
-import org.apache.asterix.metadata.declared.AqlMetadataProvider;
-import org.apache.hyracks.algebricks.common.utils.Pair;
-
-/**
- * A pre-processor that adds the group variable as well as its group field
- * list into the AST. It will also invoke SQL group-by aggregation sugar rewritings.
- */
-public class SqlppGroupByVisitor extends VariableCheckAndRewriteVisitor {
-
-    public SqlppGroupByVisitor(LangRewritingContext context, AqlMetadataProvider metadataProvider) {
-        super(context, false, metadataProvider);
-    }
-
-    @Override
-    public Expression visit(SelectBlock selectBlock, Expression arg) throws AsterixException {
-        // Traverses the select block in the order of "from", "let"s, "where",
-        // "group by", "let"s, "having" and "select".
-        if (selectBlock.hasFromClause()) {
-            selectBlock.getFromClause().accept(this, arg);
-        }
-        if (selectBlock.hasLetClauses()) {
-            List<LetClause> letList = selectBlock.getLetList();
-            for (LetClause letClause : letList) {
-                letClause.accept(this, arg);
-            }
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, arg);
-        }
-        if (selectBlock.hasGroupbyClause()) {
-            selectBlock.getGroupbyClause().accept(this, arg);
-            Set<VariableExpr> withVarSet = new HashSet<>(selectBlock.getGroupbyClause().getWithVarList());
-            withVarSet.remove(selectBlock.getGroupbyClause().getGroupVar());
-            //selectBlock.getGroupbyClause().getWithVarList()
-            //        .retainAll(Collections.singleton(selectBlock.getGroupbyClause().getGroupVar()));
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
-                for (LetClause letClauseAfterGby : letListAfterGby) {
-                    // Rewrites each let clause after the group-by.
-                    SqlppRewriteUtil.rewriteExpressionUsingGroupVariable(selectBlock.getGroupbyClause().getGroupVar(),
-                            withVarSet, letClauseAfterGby, context);
-                    letClauseAfterGby.accept(this, arg);
-                }
-            }
-            if (selectBlock.hasHavingClause()) {
-                // Rewrites the having clause.
-                SqlppRewriteUtil.rewriteExpressionUsingGroupVariable(selectBlock.getGroupbyClause().getGroupVar(),
-                        withVarSet, selectBlock.getHavingClause(), context);
-                selectBlock.getHavingClause().accept(this, arg);
-            }
-            // Rewrites the select clause.
-            SqlppRewriteUtil.rewriteExpressionUsingGroupVariable(selectBlock.getGroupbyClause().getGroupVar(),
-                    withVarSet, selectBlock.getSelectClause(), context);
-
-            SelectExpression parentSelectExpression = (SelectExpression) arg;
-            if (parentSelectExpression.hasOrderby()) {
-                // Rewrites the order-by clause.
-                SqlppRewriteUtil.rewriteExpressionUsingGroupVariable(selectBlock.getGroupbyClause().getGroupVar(),
-                        withVarSet, parentSelectExpression.getOrderbyClause(), context);
-            }
-            if (parentSelectExpression.hasLimit()) {
-                // Rewrites the limit clause.
-                SqlppRewriteUtil.rewriteExpressionUsingGroupVariable(selectBlock.getGroupbyClause().getGroupVar(),
-                        withVarSet, parentSelectExpression.getLimitClause(), context);
-            }
-        }
-        selectBlock.getSelectClause().accept(this, arg);
-        return null;
-    }
-
-    @Override
-    public Expression visit(GroupbyClause gc, Expression arg) throws AsterixException {
-        Scope newScope = scopeChecker.extendCurrentScopeNoPush(true);
-        // Puts all group-by variables into the symbol set of the new scope.
-        for (GbyVariableExpressionPair gbyVarExpr : gc.getGbyPairList()) {
-            gbyVarExpr.setExpr(gbyVarExpr.getExpr().accept(this, arg));
-            VariableExpr gbyVar = gbyVarExpr.getVar();
-            if (gbyVar != null) {
-                newScope.addNewVarSymbolToScope(gbyVarExpr.getVar().getVar());
-            }
-        }
-        // Puts all live variables into withVarList.
-        List<VariableExpr> withVarList = new ArrayList<VariableExpr>();
-        Iterator<Identifier> varIterator = scopeChecker.getCurrentScope().liveSymbols();
-        while (varIterator.hasNext()) {
-            Identifier ident = varIterator.next();
-            VariableExpr varExpr = new VariableExpr();
-            if (ident instanceof VarIdentifier) {
-                varExpr.setIsNewVar(false);
-                varExpr.setVar((VarIdentifier) ident);
-                withVarList.add(varExpr);
-                newScope.addNewVarSymbolToScope((VarIdentifier) ident);
-            }
-        }
-
-        // Sets the field list for the group variable.
-        List<Pair<Expression, Identifier>> groupFieldList = new ArrayList<>();
-        if (!gc.hasGroupFieldList()) {
-            for (VariableExpr varExpr : withVarList) {
-                Pair<Expression, Identifier> varIdPair = new Pair<>(new VariableExpr(varExpr.getVar()),
-                        SqlppVariableUtil.toUserDefinedVariableName(varExpr.getVar()));
-                groupFieldList.add(varIdPair);
-            }
-            gc.setGroupFieldList(groupFieldList);
-        } else {
-            // Check the scopes of group field variables.
-            for (Pair<Expression, Identifier> groupField : gc.getGroupFieldList()) {
-                Expression newVar = groupField.first.accept(this, arg);
-                groupFieldList.add(new Pair<>(newVar, groupField.second));
-            }
-        }
-        gc.setGroupFieldList(groupFieldList);
-
-        // Sets the group variable.
-        if (!gc.hasGroupVar()) {
-            VariableExpr groupVar = new VariableExpr(context.newVariable());
-            gc.setGroupVar(groupVar);
-        }
-        newScope.addNewVarSymbolToScope(gc.getGroupVar().getVar());
-
-        // Adds the group variable into the "with" (i.e., re-binding) variable list.
-        VariableExpr gbyVarRef = new VariableExpr(gc.getGroupVar().getVar());
-        gbyVarRef.setIsNewVar(false);
-        withVarList.add(gbyVarRef);
-        gc.setWithVarList(withVarList);
-
-        scopeChecker.replaceCurrentScope(newScope);
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/3dd80ec4/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppInlineUdfsVisitor.java
----------------------------------------------------------------------
diff --git a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppInlineUdfsVisitor.java b/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppInlineUdfsVisitor.java
deleted file mode 100644
index 37c8be8..0000000
--- a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppInlineUdfsVisitor.java
+++ /dev/null
@@ -1,236 +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.lang.sqlpp.visitor;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.asterix.common.exceptions.AsterixException;
-import org.apache.asterix.lang.common.base.Expression;
-import org.apache.asterix.lang.common.base.IRewriterFactory;
-import org.apache.asterix.lang.common.clause.LetClause;
-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.visitor.AbstractInlineUdfsVisitor;
-import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
-import org.apache.asterix.lang.sqlpp.clause.FromClause;
-import org.apache.asterix.lang.sqlpp.clause.FromTerm;
-import org.apache.asterix.lang.sqlpp.clause.HavingClause;
-import org.apache.asterix.lang.sqlpp.clause.JoinClause;
-import org.apache.asterix.lang.sqlpp.clause.NestClause;
-import org.apache.asterix.lang.sqlpp.clause.Projection;
-import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
-import org.apache.asterix.lang.sqlpp.clause.SelectClause;
-import org.apache.asterix.lang.sqlpp.clause.SelectElement;
-import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
-import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
-import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
-import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
-import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
-import org.apache.asterix.lang.sqlpp.util.SqlppVariableSubstitutionUtil;
-import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
-import org.apache.asterix.metadata.declared.AqlMetadataProvider;
-import org.apache.hyracks.algebricks.common.utils.Pair;
-
-public class SqlppInlineUdfsVisitor extends AbstractInlineUdfsVisitor
-        implements ISqlppVisitor<Boolean, List<FunctionDecl>> {
-
-    /**
-     * @param context,
-     *            manages ids of variables and guarantees uniqueness of variables.
-     * @param rewriterFactory,
-     *            a rewrite factory for rewriting user-defined functions.
-     * @param declaredFunctions,
-     *            a list of declared functions associated with the query.
-     * @param metadataProvider,
-     *            providing the definition of created (i.e., stored) user-defined functions.
-     */
-    public SqlppInlineUdfsVisitor(LangRewritingContext context, IRewriterFactory rewriterFactory,
-            List<FunctionDecl> declaredFunctions, AqlMetadataProvider metadataProvider) {
-        super(context, rewriterFactory, declaredFunctions, metadataProvider,
-                new SqlppCloneAndSubstituteVariablesVisitor(context));
-    }
-
-    @Override
-    protected Expression generateQueryExpression(List<LetClause> letClauses, Expression returnExpr)
-            throws AsterixException {
-        Map<VariableExpr, Expression> varExprMap = extractLetBindingVariableExpressionMappings(letClauses);
-        Expression inlinedReturnExpr = (Expression) SqlppVariableSubstitutionUtil
-                .substituteVariableWithoutContext(returnExpr, varExprMap);
-        return inlinedReturnExpr;
-    }
-
-    @Override
-    public Boolean visit(FromClause fromClause, List<FunctionDecl> func) throws AsterixException {
-        boolean changed = false;
-        for (FromTerm fromTerm : fromClause.getFromTerms()) {
-            changed |= fromTerm.accept(this, func);
-        }
-        return changed;
-    }
-
-    @Override
-    public Boolean visit(FromTerm fromTerm, List<FunctionDecl> func) throws AsterixException {
-        boolean changed = false;
-        Pair<Boolean, Expression> p = inlineUdfsInExpr(fromTerm.getLeftExpression(), func);
-        fromTerm.setLeftExpression(p.second);
-        changed |= p.first;
-        for (AbstractBinaryCorrelateClause correlateClause : fromTerm.getCorrelateClauses()) {
-            changed |= correlateClause.accept(this, func);
-        }
-        return changed;
-    }
-
-    @Override
-    public Boolean visit(JoinClause joinClause, List<FunctionDecl> funcs) throws AsterixException {
-        Pair<Boolean, Expression> p1 = inlineUdfsInExpr(joinClause.getRightExpression(), funcs);
-        joinClause.setRightExpression(p1.second);
-        Pair<Boolean, Expression> p2 = inlineUdfsInExpr(joinClause.getConditionExpression(), funcs);
-        joinClause.setConditionExpression(p2.second);
-        return p1.first || p2.first;
-    }
-
-    @Override
-    public Boolean visit(NestClause nestClause, List<FunctionDecl> funcs) throws AsterixException {
-        Pair<Boolean, Expression> p1 = inlineUdfsInExpr(nestClause.getRightExpression(), funcs);
-        nestClause.setRightExpression(p1.second);
-        Pair<Boolean, Expression> p2 = inlineUdfsInExpr(nestClause.getConditionExpression(), funcs);
-        nestClause.setConditionExpression(p2.second);
-        return p1.first || p2.first;
-    }
-
-    @Override
-    public Boolean visit(Projection projection, List<FunctionDecl> funcs) throws AsterixException {
-        Pair<Boolean, Expression> p = inlineUdfsInExpr(projection.getExpression(), funcs);
-        projection.setExpression(p.second);
-        return p.first;
-    }
-
-    @Override
-    public Boolean visit(SelectBlock selectBlock, List<FunctionDecl> funcs) throws AsterixException {
-        boolean changed = false;
-        if (selectBlock.hasFromClause()) {
-            changed |= selectBlock.getFromClause().accept(this, funcs);
-        }
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                changed |= letClause.accept(this, funcs);
-            }
-        }
-        if (selectBlock.hasWhereClause()) {
-            changed |= selectBlock.getWhereClause().accept(this, funcs);
-        }
-        if (selectBlock.hasGroupbyClause()) {
-            changed |= selectBlock.getGroupbyClause().accept(this, funcs);
-        }
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                changed |= letClause.accept(this, funcs);
-            }
-        }
-        if (selectBlock.hasHavingClause()) {
-            changed |= selectBlock.getHavingClause().accept(this, funcs);
-        }
-        changed |= selectBlock.getSelectClause().accept(this, funcs);
-        return changed;
-    }
-
-    @Override
-    public Boolean visit(SelectClause selectClause, List<FunctionDecl> funcs) throws AsterixException {
-        boolean changed = false;
-        if (selectClause.selectElement()) {
-            changed |= selectClause.getSelectElement().accept(this, funcs);
-        } else {
-            changed |= selectClause.getSelectRegular().accept(this, funcs);
-        }
-        return changed;
-    }
-
-    @Override
-    public Boolean visit(SelectElement selectElement, List<FunctionDecl> funcs) throws AsterixException {
-        Pair<Boolean, Expression> p = inlineUdfsInExpr(selectElement.getExpression(), funcs);
-        selectElement.setExpression(p.second);
-        return p.first;
-    }
-
-    @Override
-    public Boolean visit(SelectRegular selectRegular, List<FunctionDecl> funcs) throws AsterixException {
-        boolean changed = false;
-        for (Projection projection : selectRegular.getProjections()) {
-            changed |= projection.accept(this, funcs);
-        }
-        return changed;
-    }
-
-    @Override
-    public Boolean visit(SelectSetOperation selectSetOperation, List<FunctionDecl> funcs) throws AsterixException {
-        boolean changed = false;
-        changed |= selectSetOperation.getLeftInput().accept(this, funcs);
-        for (SetOperationRight right : selectSetOperation.getRightInputs()) {
-            changed |= right.getSetOperationRightInput().accept(this, funcs);
-        }
-        return changed;
-    }
-
-    @Override
-    public Boolean visit(SelectExpression selectExpression, List<FunctionDecl> funcs) throws AsterixException {
-        boolean changed = false;
-        if (selectExpression.hasLetClauses()) {
-            for (LetClause letClause : selectExpression.getLetList()) {
-                changed |= letClause.accept(this, funcs);
-            }
-        }
-        changed |= selectExpression.getSelectSetOperation().accept(this, funcs);
-        if (selectExpression.hasOrderby()) {
-            changed |= selectExpression.getOrderbyClause().accept(this, funcs);
-        }
-        if (selectExpression.hasLimit()) {
-            changed |= selectExpression.getLimitClause().accept(this, funcs);
-        }
-        return changed;
-    }
-
-    @Override
-    public Boolean visit(UnnestClause unnestClause, List<FunctionDecl> funcs) throws AsterixException {
-        Pair<Boolean, Expression> p = inlineUdfsInExpr(unnestClause.getRightExpression(), funcs);
-        unnestClause.setRightExpression(p.second);
-        return p.first;
-    }
-
-    @Override
-    public Boolean visit(HavingClause havingClause, List<FunctionDecl> funcs) throws AsterixException {
-        Pair<Boolean, Expression> p = inlineUdfsInExpr(havingClause.getFilterExpression(), funcs);
-        havingClause.setFilterExpression(p.second);
-        return p.first;
-    }
-
-    private Map<VariableExpr, Expression> extractLetBindingVariableExpressionMappings(List<LetClause> letClauses)
-            throws AsterixException {
-        Map<VariableExpr, Expression> varExprMap = new HashMap<VariableExpr, Expression>();
-        for (LetClause lc : letClauses) {
-            // inline let variables one by one iteratively.
-            lc.setBindingExpr((Expression) SqlppVariableSubstitutionUtil
-                    .substituteVariableWithoutContext(lc.getBindingExpr(), varExprMap));
-            varExprMap.put(lc.getVarExpr(), lc.getBindingExpr());
-        }
-        return varExprMap;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/3dd80ec4/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteVariablesVisitor.java
----------------------------------------------------------------------
diff --git a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteVariablesVisitor.java b/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteVariablesVisitor.java
index a9aff55..f737eb7 100644
--- a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteVariablesVisitor.java
+++ b/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteVariablesVisitor.java
@@ -18,10 +18,12 @@
  */
 package org.apache.asterix.lang.sqlpp.visitor;
 
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
 import org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment;
+import org.apache.asterix.lang.sqlpp.util.SqlppRewriteUtil;
 
 public class SqlppSubstituteVariablesVisitor extends SqlppCloneAndSubstituteVariablesVisitor {
 
@@ -30,9 +32,10 @@ public class SqlppSubstituteVariablesVisitor extends SqlppCloneAndSubstituteVari
     }
 
     @Override
-    protected Expression rewriteVariableExpr(VariableExpr expr, VariableSubstitutionEnvironment env) {
+    protected Expression rewriteVariableExpr(VariableExpr expr, VariableSubstitutionEnvironment env)
+            throws AsterixException {
         if (env.constainsOldVar(expr)) {
-            return env.findSubstituion(expr);
+            return (Expression) SqlppRewriteUtil.deepCopy(env.findSubstituion(expr));
         }
         return expr;
     }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/3dd80ec4/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/UsedVariableVisitor.java
----------------------------------------------------------------------
diff --git a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/UsedVariableVisitor.java b/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/UsedVariableVisitor.java
deleted file mode 100644
index 877f722..0000000
--- a/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/UsedVariableVisitor.java
+++ /dev/null
@@ -1,362 +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.lang.sqlpp.visitor;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.asterix.common.exceptions.AsterixException;
-import org.apache.asterix.lang.common.base.Expression;
-import org.apache.asterix.lang.common.clause.GroupbyClause;
-import org.apache.asterix.lang.common.clause.LetClause;
-import org.apache.asterix.lang.common.clause.LimitClause;
-import org.apache.asterix.lang.common.clause.OrderbyClause;
-import org.apache.asterix.lang.common.clause.WhereClause;
-import org.apache.asterix.lang.common.expression.CallExpr;
-import org.apache.asterix.lang.common.expression.FieldAccessor;
-import org.apache.asterix.lang.common.expression.FieldBinding;
-import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
-import org.apache.asterix.lang.common.expression.IfExpr;
-import org.apache.asterix.lang.common.expression.IndexAccessor;
-import org.apache.asterix.lang.common.expression.ListConstructor;
-import org.apache.asterix.lang.common.expression.LiteralExpr;
-import org.apache.asterix.lang.common.expression.OperatorExpr;
-import org.apache.asterix.lang.common.expression.QuantifiedExpression;
-import org.apache.asterix.lang.common.expression.RecordConstructor;
-import org.apache.asterix.lang.common.expression.UnaryExpr;
-import org.apache.asterix.lang.common.expression.VariableExpr;
-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.AbstractBinaryCorrelateClause;
-import org.apache.asterix.lang.sqlpp.clause.FromClause;
-import org.apache.asterix.lang.sqlpp.clause.FromTerm;
-import org.apache.asterix.lang.sqlpp.clause.HavingClause;
-import org.apache.asterix.lang.sqlpp.clause.JoinClause;
-import org.apache.asterix.lang.sqlpp.clause.NestClause;
-import org.apache.asterix.lang.sqlpp.clause.Projection;
-import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
-import org.apache.asterix.lang.sqlpp.clause.SelectClause;
-import org.apache.asterix.lang.sqlpp.clause.SelectElement;
-import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
-import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
-import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
-import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
-import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
-import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppQueryExpressionVisitor;
-import org.apache.hyracks.algebricks.common.utils.Pair;
-
-public class UsedVariableVisitor extends AbstractSqlppQueryExpressionVisitor<Void, Collection<VariableExpr>> {
-
-    @Override
-    public Void visit(FromClause fromClause, Collection<VariableExpr> usedVars) throws AsterixException {
-        for (FromTerm fromTerm : fromClause.getFromTerms()) {
-            fromTerm.accept(this, usedVars);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(FromTerm fromTerm, Collection<VariableExpr> usedVars) throws AsterixException {
-        // Visit the left expression of a from term.
-        fromTerm.getLeftExpression().accept(this, usedVars);
-
-        // Visits join/unnest/nest clauses.
-        for (AbstractBinaryCorrelateClause correlateClause : fromTerm.getCorrelateClauses()) {
-            correlateClause.accept(this, usedVars);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(JoinClause joinClause, Collection<VariableExpr> usedVars) throws AsterixException {
-        // NOTE: the two join branches cannot be correlated, instead of checking
-        // the correlation here,
-        // we defer the check to the query optimizer.
-        joinClause.getRightExpression().accept(this, usedVars);
-
-        // The condition expression can refer to the just registered variables
-        // for the right branch.
-        joinClause.getConditionExpression().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(NestClause nestClause, Collection<VariableExpr> usedVars) throws AsterixException {
-        // NOTE: the two branches of a NEST cannot be correlated, instead of
-        // checking the correlation here, we defer the check to the query
-        // optimizer.
-        nestClause.getRightExpression().accept(this, usedVars);
-
-        // The condition expression can refer to the just registered variables
-        // for the right branch.
-        nestClause.getConditionExpression().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(UnnestClause unnestClause, Collection<VariableExpr> usedVars) throws AsterixException {
-        unnestClause.getRightExpression().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(Projection projection, Collection<VariableExpr> usedVars) throws AsterixException {
-        projection.getExpression().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectBlock selectBlock, Collection<VariableExpr> usedVars) throws AsterixException {
-        // Traverses the select block in the order of "from", "let"s, "where",
-        // "group by", "let"s, "having" and "select".
-        if (selectBlock.hasFromClause()) {
-            selectBlock.getFromClause().accept(this, usedVars);
-        }
-        if (selectBlock.hasLetClauses()) {
-            List<LetClause> letList = selectBlock.getLetList();
-            for (LetClause letClause : letList) {
-                letClause.accept(this, usedVars);
-            }
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, usedVars);
-        }
-        if (selectBlock.hasGroupbyClause()) {
-            selectBlock.getGroupbyClause().accept(this, usedVars);
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
-                for (LetClause letClauseAfterGby : letListAfterGby) {
-                    letClauseAfterGby.accept(this, usedVars);
-                }
-            }
-            if (selectBlock.hasHavingClause()) {
-                selectBlock.getHavingClause().accept(this, usedVars);
-            }
-        }
-        selectBlock.getSelectClause().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectClause selectClause, Collection<VariableExpr> usedVars) throws AsterixException {
-        if (selectClause.selectElement()) {
-            selectClause.getSelectElement().accept(this, usedVars);
-        }
-        if (selectClause.selectRegular()) {
-            selectClause.getSelectRegular().accept(this, usedVars);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectElement selectElement, Collection<VariableExpr> usedVars) throws AsterixException {
-        selectElement.getExpression().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectRegular selectRegular, Collection<VariableExpr> usedVars) throws AsterixException {
-        for (Projection projection : selectRegular.getProjections()) {
-            projection.accept(this, usedVars);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectSetOperation selectSetOperation, Collection<VariableExpr> usedVars)
-            throws AsterixException {
-        selectSetOperation.getLeftInput().accept(this, usedVars);
-        for (SetOperationRight right : selectSetOperation.getRightInputs()) {
-            right.getSetOperationRightInput().accept(this, usedVars);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(HavingClause havingClause, Collection<VariableExpr> usedVars) throws AsterixException {
-        havingClause.getFilterExpression().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(Query q, Collection<VariableExpr> usedVars) throws AsterixException {
-        q.getBody().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(FunctionDecl fd, Collection<VariableExpr> usedVars) throws AsterixException {
-        fd.getFuncBody().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(WhereClause whereClause, Collection<VariableExpr> usedVars) throws AsterixException {
-        whereClause.getWhereExpr().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(OrderbyClause oc, Collection<VariableExpr> usedVars) throws AsterixException {
-        for (Expression orderExpr : oc.getOrderbyList()) {
-            orderExpr.accept(this, usedVars);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(GroupbyClause gc, Collection<VariableExpr> usedVars) throws AsterixException {
-        // Puts all group-by variables into the symbol set of the new scope.
-        for (GbyVariableExpressionPair gbyVarExpr : gc.getGbyPairList()) {
-            gbyVarExpr.getExpr().accept(this, usedVars);
-        }
-        for (GbyVariableExpressionPair decorVarExpr : gc.getDecorPairList()) {
-            decorVarExpr.getExpr().accept(this, usedVars);
-        }
-        if (gc.hasGroupFieldList()) {
-            for (Pair<Expression, Identifier> groupField : gc.getGroupFieldList()) {
-                groupField.first.accept(this, usedVars);
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(LimitClause limitClause, Collection<VariableExpr> usedVars) throws AsterixException {
-        limitClause.getLimitExpr().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(LetClause letClause, Collection<VariableExpr> usedVars) throws AsterixException {
-        letClause.getBindingExpr().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(SelectExpression selectExpression, Collection<VariableExpr> usedVars) throws AsterixException {
-        // visit let list
-        if (selectExpression.hasLetClauses()) {
-            for (LetClause letClause : selectExpression.getLetList()) {
-                letClause.accept(this, usedVars);
-            }
-        }
-
-        // visit the main select.
-        selectExpression.getSelectSetOperation().accept(this, usedVars);
-
-        // visit order by
-        if (selectExpression.hasOrderby()) {
-            for (Expression orderExpr : selectExpression.getOrderbyClause().getOrderbyList()) {
-                orderExpr.accept(this, usedVars);
-            }
-        }
-
-        // visit limit
-        if (selectExpression.hasLimit()) {
-            selectExpression.getLimitClause().accept(this, usedVars);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(LiteralExpr l, Collection<VariableExpr> usedVars) throws AsterixException {
-        return null;
-    }
-
-    @Override
-    public Void visit(ListConstructor lc, Collection<VariableExpr> usedVars) throws AsterixException {
-        for (Expression expr : lc.getExprList()) {
-            expr.accept(this, usedVars);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(RecordConstructor rc, Collection<VariableExpr> usedVars) throws AsterixException {
-        for (FieldBinding binding : rc.getFbList()) {
-            binding.getLeftExpr().accept(this, usedVars);
-            binding.getRightExpr().accept(this, usedVars);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(OperatorExpr operatorExpr, Collection<VariableExpr> usedVars) throws AsterixException {
-        for (Expression expr : operatorExpr.getExprList()) {
-            expr.accept(this, usedVars);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(IfExpr ifExpr, Collection<VariableExpr> usedVars) throws AsterixException {
-        ifExpr.getCondExpr().accept(this, usedVars);
-        ifExpr.getThenExpr().accept(this, usedVars);
-        ifExpr.getElseExpr().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(QuantifiedExpression qe, Collection<VariableExpr> usedVars) throws AsterixException {
-        for (QuantifiedPair pair : qe.getQuantifiedList()) {
-            pair.getExpr().accept(this, usedVars);
-        }
-        qe.getSatisfiesExpr().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(CallExpr callExpr, Collection<VariableExpr> usedVars) throws AsterixException {
-        for (Expression expr : callExpr.getExprList()) {
-            expr.accept(this, usedVars);
-        }
-        return null;
-    }
-
-    @Override
-    public Void visit(VariableExpr varExpr, Collection<VariableExpr> usedVars) throws AsterixException {
-        usedVars.add(varExpr);
-        return null;
-    }
-
-    @Override
-    public Void visit(UnaryExpr u, Collection<VariableExpr> usedVars) throws AsterixException {
-        u.getExpr().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(FieldAccessor fa, Collection<VariableExpr> usedVars) throws AsterixException {
-        fa.getExpr().accept(this, usedVars);
-        return null;
-    }
-
-    @Override
-    public Void visit(IndexAccessor ia, Collection<VariableExpr> usedVars) throws AsterixException {
-        ia.getExpr().accept(this, usedVars);
-        if (ia.getIndexExpr() != null) {
-            ia.getIndexExpr();
-        }
-        return null;
-    }
-
-}