You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by dl...@apache.org on 2018/05/30 17:44:46 UTC

[19/24] asterixdb git commit: [ASTERIXDB-2393][COMP][RT] Add source location to error messages

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ee54cc02/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
index 9e36ba9..5c7b165 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
@@ -26,6 +26,7 @@ import java.util.List;
 
 import org.apache.asterix.algebra.base.ILangExpressionToPlanTranslator;
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionSignature;
 import org.apache.asterix.lang.common.base.Clause.ClauseType;
 import org.apache.asterix.lang.common.base.Expression;
@@ -70,7 +71,6 @@ import org.apache.asterix.om.base.AString;
 import org.apache.asterix.om.constants.AsterixConstantValue;
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.types.BuiltinType;
-import org.apache.commons.lang3.NotImplementedException;
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -87,6 +87,7 @@ import org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionC
 import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestNonMapOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.DistinctOperator;
@@ -98,6 +99,7 @@ import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperat
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
 import org.apache.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
+import org.apache.hyracks.api.exceptions.SourceLocation;
 
 /**
  * Each visit returns a pair of an operator and a variable. The variable
@@ -121,6 +123,7 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
     public Pair<ILogicalOperator, LogicalVariable> visit(Query q, Mutable<ILogicalOperator> tupSource)
             throws CompilationException {
         Expression queryBody = q.getBody();
+        SourceLocation sourceLoc = queryBody.getSourceLocation();
         if (queryBody.getKind() == Kind.SELECT_EXPRESSION) {
             SelectExpression selectExpr = (SelectExpression) queryBody;
             if (q.isTopLevel()) {
@@ -132,8 +135,10 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
             Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(queryBody, tupSource);
             AssignOperator assignOp = new AssignOperator(var, new MutableObject<>(eo.first));
             assignOp.getInputs().add(eo.second);
+            assignOp.setSourceLocation(sourceLoc);
             ProjectOperator projectOp = new ProjectOperator(var);
             projectOp.getInputs().add(new MutableObject<>(assignOp));
+            projectOp.setSourceLocation(sourceLoc);
             return new Pair<>(projectOp, var);
         }
     }
@@ -175,21 +180,32 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
             return leftInput.accept(this, tupSource);
         }
         List<ILangExpression> inputExprs = new ArrayList<>();
-        inputExprs.add(leftInput.selectBlock()
-                ? new SelectExpression(null, new SelectSetOperation(leftInput, null), null, null, true)
-                : leftInput.getSubquery());
+        SelectExpression leftInputExpr;
+        if (leftInput.selectBlock()) {
+            leftInputExpr = new SelectExpression(null, new SelectSetOperation(leftInput, null), null, null, true);
+            leftInputExpr.setSourceLocation(leftInput.getSelectBlock().getSourceLocation());
+        } else {
+            leftInputExpr = leftInput.getSubquery();
+        }
+        inputExprs.add(leftInputExpr);
         for (SetOperationRight setOperationRight : selectSetOperation.getRightInputs()) {
             SetOpType setOpType = setOperationRight.getSetOpType();
             if (setOpType != SetOpType.UNION || setOperationRight.isSetSemantics()) {
-                throw new CompilationException("Operation " + setOpType
-                        + (setOperationRight.isSetSemantics() ? " with set semantics" : "ALL") + " is not supported.");
+                throw new CompilationException(ErrorCode.COMPILATION_ERROR, selectSetOperation.getSourceLocation(),
+                        "Operation " + setOpType + (setOperationRight.isSetSemantics() ? " with set semantics" : "ALL")
+                                + " is not supported.");
             }
             SetOperationInput rightInput = setOperationRight.getSetOperationRightInput();
-            inputExprs.add(rightInput.selectBlock()
-                    ? new SelectExpression(null, new SelectSetOperation(rightInput, null), null, null, true)
-                    : rightInput.getSubquery());
+            SelectExpression rightInputExpr;
+            if (rightInput.selectBlock()) {
+                rightInputExpr = new SelectExpression(null, new SelectSetOperation(rightInput, null), null, null, true);
+                rightInputExpr.setSourceLocation(rightInput.getSelectBlock().getSourceLocation());
+            } else {
+                rightInputExpr = rightInput.getSubquery();
+            }
+            inputExprs.add(rightInputExpr);
         }
-        return translateUnionAllFromInputExprs(inputExprs, tupSource);
+        return translateUnionAllFromInputExprs(inputExprs, tupSource, selectSetOperation.getSourceLocation());
     }
 
     @Override
@@ -236,10 +252,11 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
     @Override
     public Pair<ILogicalOperator, LogicalVariable> visit(FromTerm fromTerm, Mutable<ILogicalOperator> tupSource)
             throws CompilationException {
+        SourceLocation sourceLoc = fromTerm.getSourceLocation();
         LogicalVariable fromVar = context.newVarFromExpression(fromTerm.getLeftVariable());
         Expression fromExpr = fromTerm.getLeftExpression();
         Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(fromExpr, tupSource);
-        ILogicalOperator unnestOp;
+        UnnestOperator unnestOp;
         if (fromTerm.hasPositionalVariable()) {
             LogicalVariable pVar = context.newVarFromExpression(fromTerm.getPositionalVariable());
             // We set the positional variable type as BIGINT type.
@@ -249,6 +266,7 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
             unnestOp = new UnnestOperator(fromVar, new MutableObject<>(makeUnnestExpression(eo.first)));
         }
         unnestOp.getInputs().add(eo.second);
+        unnestOp.setSourceLocation(sourceLoc);
 
         // Processes joins, unnests, and nests.
         Mutable<ILogicalOperator> topOpRef = new MutableObject<>(unnestOp);
@@ -270,6 +288,7 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
     @Override
     public Pair<ILogicalOperator, LogicalVariable> visit(JoinClause joinClause, Mutable<ILogicalOperator> inputRef)
             throws CompilationException {
+        SourceLocation sourceLoc = joinClause.getSourceLocation();
         Mutable<ILogicalOperator> leftInputRef = uncorrelatedLeftBranchStack.pop();
         if (joinClause.getJoinType() == JoinType.INNER) {
             Pair<ILogicalOperator, LogicalVariable> rightBranch =
@@ -277,6 +296,7 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
             // A join operator with condition TRUE.
             AbstractBinaryJoinOperator joinOperator = new InnerJoinOperator(
                     new MutableObject<>(ConstantExpression.TRUE), leftInputRef, new MutableObject<>(rightBranch.first));
+            joinOperator.setSourceLocation(sourceLoc);
             Mutable<ILogicalOperator> joinOpRef = new MutableObject<>(joinOperator);
 
             // Add an additional filter operator.
@@ -284,13 +304,16 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
                     langExprToAlgExpression(joinClause.getConditionExpression(), joinOpRef);
             SelectOperator filter = new SelectOperator(new MutableObject<>(conditionExprOpPair.first), false, null);
             filter.getInputs().add(conditionExprOpPair.second);
+            filter.setSourceLocation(conditionExprOpPair.first.getSourceLocation());
             return new Pair<>(filter, rightBranch.second);
         } else {
             // Creates a subplan operator.
             SubplanOperator subplanOp = new SubplanOperator();
-            Mutable<ILogicalOperator> ntsRef =
-                    new MutableObject<>(new NestedTupleSourceOperator(new MutableObject<>(subplanOp)));
             subplanOp.getInputs().add(leftInputRef);
+            subplanOp.setSourceLocation(sourceLoc);
+            NestedTupleSourceOperator ntsOp = new NestedTupleSourceOperator(new MutableObject<>(subplanOp));
+            ntsOp.setSourceLocation(sourceLoc);
+            Mutable<ILogicalOperator> ntsRef = new MutableObject<>(ntsOp);
 
             // Enters the translation for a subplan.
             context.enterSubplan();
@@ -305,27 +328,36 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
                     langExprToAlgExpression(joinClause.getConditionExpression(), new MutableObject<>(rightUnnestOp));
             SelectOperator filter = new SelectOperator(new MutableObject<>(conditionExprOpPair.first), false, null);
             filter.getInputs().add(conditionExprOpPair.second);
+            filter.setSourceLocation(conditionExprOpPair.first.getSourceLocation());
 
             ILogicalOperator currentTopOp = filter;
             LogicalVariable varToListify;
             boolean hasRightPosVar = rightUnnestOp.getPositionalVariable() != null;
             if (hasRightPosVar) {
                 // Creates record to get correlation between the two aggregate variables.
+                VariableReferenceExpression rightUnnestVarRef =
+                        new VariableReferenceExpression(rightUnnestOp.getVariable());
+                rightUnnestVarRef.setSourceLocation(joinClause.getRightVariable().getSourceLocation());
+                VariableReferenceExpression rightUnnestPosVarRef =
+                        new VariableReferenceExpression(rightUnnestOp.getPositionalVariable());
+                rightUnnestPosVarRef.setSourceLocation(joinClause.getPositionalVariable().getSourceLocation());
                 ScalarFunctionCallExpression recordCreationFunc = new ScalarFunctionCallExpression(
                         FunctionUtil.getFunctionInfo(BuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR),
                         // Field name for the listified right unnest var.
                         new MutableObject<>(new ConstantExpression(new AsterixConstantValue(new AString("unnestvar")))),
                         // The listified right unnest var
-                        new MutableObject<>(new VariableReferenceExpression(rightUnnestOp.getVariable())),
+                        new MutableObject<>(rightUnnestVarRef),
                         // Field name for the listified right unnest positional var.
                         new MutableObject<>(new ConstantExpression(new AsterixConstantValue(new AString("posvar")))),
                         // The listified right unnest positional var.
-                        new MutableObject<>(new VariableReferenceExpression(rightUnnestOp.getPositionalVariable())));
+                        new MutableObject<>(rightUnnestPosVarRef));
+                recordCreationFunc.setSourceLocation(joinClause.getRightVariable().getSourceLocation());
 
                 // Assigns the record constructor function to a record variable.
                 LogicalVariable recordVar = context.newVar();
                 AssignOperator assignOp = new AssignOperator(recordVar, new MutableObject<>(recordCreationFunc));
                 assignOp.getInputs().add(new MutableObject<>(currentTopOp));
+                assignOp.setSourceLocation(joinClause.getRightVariable().getSourceLocation());
 
                 // Sets currentTopOp and varToListify for later usages.
                 currentTopOp = assignOp;
@@ -335,14 +367,17 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
             }
 
             // Adds an aggregate operator to listfy unnest variables.
-            AggregateFunctionCallExpression fListify =
-                    BuiltinFunctions.makeAggregateFunctionExpression(BuiltinFunctions.LISTIFY,
-                            mkSingletonArrayList(new MutableObject<>(new VariableReferenceExpression(varToListify))));
+            VariableReferenceExpression varToListifyRef = new VariableReferenceExpression(varToListify);
+            varToListifyRef.setSourceLocation(currentTopOp.getSourceLocation());
+            AggregateFunctionCallExpression fListify = BuiltinFunctions.makeAggregateFunctionExpression(
+                    BuiltinFunctions.LISTIFY, mkSingletonArrayList(new MutableObject<>(varToListifyRef)));
+            fListify.setSourceLocation(currentTopOp.getSourceLocation());
 
             LogicalVariable aggVar = context.newSubplanOutputVar();
             AggregateOperator aggOp = new AggregateOperator(mkSingletonArrayList(aggVar),
                     mkSingletonArrayList(new MutableObject<>(fListify)));
             aggOp.getInputs().add(new MutableObject<>(currentTopOp));
+            aggOp.setSourceLocation(fListify.getSourceLocation());
 
             // Exits the translation of a subplan.
             context.exitSubplan();
@@ -353,20 +388,30 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
 
             // Outer unnest the aggregated var from the subplan.
             LogicalVariable outerUnnestVar = context.newVar();
+            VariableReferenceExpression aggVarRefExpr = new VariableReferenceExpression(aggVar);
+            aggVarRefExpr.setSourceLocation(aggOp.getSourceLocation());
             LeftOuterUnnestOperator outerUnnestOp = new LeftOuterUnnestOperator(outerUnnestVar,
-                    new MutableObject<>(makeUnnestExpression(new VariableReferenceExpression(aggVar))));
+                    new MutableObject<>(makeUnnestExpression(aggVarRefExpr)));
             outerUnnestOp.getInputs().add(new MutableObject<>(subplanOp));
+            outerUnnestOp.setSourceLocation(aggOp.getSourceLocation());
             currentTopOp = outerUnnestOp;
 
             if (hasRightPosVar) {
+                VariableReferenceExpression outerUnnestVarRef1 = new VariableReferenceExpression(outerUnnestVar);
+                outerUnnestVarRef1.setSourceLocation(joinClause.getRightVariable().getSourceLocation());
                 ScalarFunctionCallExpression fieldAccessForRightUnnestVar = new ScalarFunctionCallExpression(
                         FunctionUtil.getFunctionInfo(BuiltinFunctions.FIELD_ACCESS_BY_INDEX),
-                        new MutableObject<>(new VariableReferenceExpression(outerUnnestVar)),
+                        new MutableObject<>(outerUnnestVarRef1),
                         new MutableObject<>(new ConstantExpression(new AsterixConstantValue(new AInt32(0)))));
+                fieldAccessForRightUnnestVar.setSourceLocation(joinClause.getRightVariable().getSourceLocation());
+
+                VariableReferenceExpression outerUnnestVarRef2 = new VariableReferenceExpression(outerUnnestVar);
+                outerUnnestVarRef2.setSourceLocation(joinClause.getPositionalVariable().getSourceLocation());
                 ScalarFunctionCallExpression fieldAccessForRightPosVar = new ScalarFunctionCallExpression(
                         FunctionUtil.getFunctionInfo(BuiltinFunctions.FIELD_ACCESS_BY_INDEX),
-                        new MutableObject<>(new VariableReferenceExpression(outerUnnestVar)),
+                        new MutableObject<>(outerUnnestVarRef2),
                         new MutableObject<>(new ConstantExpression(new AsterixConstantValue(new AInt32(1)))));
+                fieldAccessForRightPosVar.setSourceLocation(joinClause.getPositionalVariable().getSourceLocation());
 
                 // Creates variables for assign.
                 LogicalVariable rightUnnestVar = context.newVar();
@@ -389,6 +434,7 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
                 // Creates the assign operator.
                 AssignOperator assignOp = new AssignOperator(assignVars, assignExprs);
                 assignOp.getInputs().add(new MutableObject<>(currentTopOp));
+                assignOp.setSourceLocation(joinClause.getRightVariable().getSourceLocation());
                 currentTopOp = assignOp;
             } else {
                 context.setVar(joinClause.getRightVariable(), outerUnnestVar);
@@ -400,7 +446,8 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
     @Override
     public Pair<ILogicalOperator, LogicalVariable> visit(NestClause nestClause, Mutable<ILogicalOperator> arg)
             throws CompilationException {
-        throw new NotImplementedException("Nest clause has not been implemented");
+        throw new CompilationException(ErrorCode.COMPILATION_ERROR, nestClause.getSourceLocation(),
+                "Nest clause has not been implemented");
     }
 
     @Override
@@ -426,7 +473,7 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
         LogicalVariable rightVar = context.newVarFromExpression(binaryCorrelate.getRightVariable());
         Expression rightExpr = binaryCorrelate.getRightExpression();
         Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(rightExpr, inputOpRef);
-        ILogicalOperator unnestOp;
+        AbstractUnnestOperator unnestOp;
         if (binaryCorrelate.hasPositionalVariable()) {
             LogicalVariable pVar = context.newVarFromExpression(binaryCorrelate.getPositionalVariable());
             // We set the positional variable type as BIGINT type.
@@ -440,6 +487,7 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
                     : new LeftOuterUnnestOperator(rightVar, new MutableObject<>(makeUnnestExpression(eo.first)));
         }
         unnestOp.getInputs().add(eo.second);
+        unnestOp.setSourceLocation(binaryCorrelate.getRightVariable().getSourceLocation());
         return new Pair<>(unnestOp, rightVar);
     }
 
@@ -478,12 +526,14 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
         List<ILogicalExpression> branchCondVarReferences = new ArrayList<>();
         List<ILogicalExpression> allVarReferences = new ArrayList<>();
         for (int index = 0; index < whenExprList.size(); ++index) {
-            Pair<ILogicalOperator, LogicalVariable> whenExprResult = whenExprList.get(index).accept(this, currentOpRef);
+            Expression whenExpr = whenExprList.get(index);
+            Pair<ILogicalOperator, LogicalVariable> whenExprResult = whenExpr.accept(this, currentOpRef);
             currentOperator = whenExprResult.first;
             // Variable whenConditionVar is corresponds to the current "WHEN" condition.
             LogicalVariable whenConditionVar = whenExprResult.second;
-            Mutable<ILogicalExpression> branchEntraceConditionExprRef =
-                    new MutableObject<>(new VariableReferenceExpression(whenConditionVar));
+            VariableReferenceExpression whenConditionVarRef1 = new VariableReferenceExpression(whenConditionVar);
+            whenConditionVarRef1.setSourceLocation(whenExpr.getSourceLocation());
+            Mutable<ILogicalExpression> branchEntraceConditionExprRef = new MutableObject<>(whenConditionVarRef1);
 
             // Constructs an expression that filters data based on preceding "WHEN" conditions
             // and the current "WHEN" condition. Note that only one "THEN" expression can be run
@@ -492,31 +542,45 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
                 // The additional filter generated here makes sure the the tuple has not
                 // entered other matched "WHEN...THEN" case.
                 List<Mutable<ILogicalExpression>> andArgs = new ArrayList<>();
-                andArgs.add(generateNoMatchedPrecedingWhenBranchesFilter(branchCondVarReferences));
+                andArgs.add(generateNoMatchedPrecedingWhenBranchesFilter(branchCondVarReferences,
+                        caseExpression.getSourceLocation()));
                 andArgs.add(branchEntraceConditionExprRef);
 
                 // A "THEN" branch can be entered only when the tuple has not enter any other preceding
                 // branches and the current "WHEN" condition is TRUE.
-                branchEntraceConditionExprRef = new MutableObject<>(
-                        new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.AND), andArgs));
+                ScalarFunctionCallExpression andExpr =
+                        new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.AND), andArgs);
+                andExpr.setSourceLocation(whenExpr.getSourceLocation());
+                branchEntraceConditionExprRef = new MutableObject<>(andExpr);
             }
 
             // Translates the corresponding "THEN" expression.
-            Pair<ILogicalOperator, LogicalVariable> opAndVarForThen = constructSubplanOperatorForBranch(currentOperator,
-                    branchEntraceConditionExprRef, thenExprList.get(index));
+            Expression thenExpr = thenExprList.get(index);
+            Pair<ILogicalOperator, LogicalVariable> opAndVarForThen =
+                    constructSubplanOperatorForBranch(currentOperator, branchEntraceConditionExprRef, thenExpr);
+
+            VariableReferenceExpression whenConditionVarRef2 = new VariableReferenceExpression(whenConditionVar);
+            whenConditionVarRef2.setSourceLocation(whenExpr.getSourceLocation());
+            branchCondVarReferences.add(whenConditionVarRef2);
+
+            VariableReferenceExpression whenConditionVarRef3 = new VariableReferenceExpression(whenConditionVar);
+            whenConditionVarRef3.setSourceLocation(whenExpr.getSourceLocation());
+            allVarReferences.add(whenConditionVarRef3);
+
+            VariableReferenceExpression thenVarRef = new VariableReferenceExpression(opAndVarForThen.second);
+            thenVarRef.setSourceLocation(thenExpr.getSourceLocation());
+            allVarReferences.add(thenVarRef);
 
-            branchCondVarReferences.add(new VariableReferenceExpression(whenConditionVar));
-            allVarReferences.add(new VariableReferenceExpression(whenConditionVar));
-            allVarReferences.add(new VariableReferenceExpression(opAndVarForThen.second));
             currentOperator = opAndVarForThen.first;
             currentOpRef = new MutableObject<>(currentOperator);
         }
 
         // Creates a subplan for the "ELSE" branch.
-        Mutable<ILogicalExpression> elseCondExprRef =
-                generateNoMatchedPrecedingWhenBranchesFilter(branchCondVarReferences);
+        Mutable<ILogicalExpression> elseCondExprRef = generateNoMatchedPrecedingWhenBranchesFilter(
+                branchCondVarReferences, caseExpression.getSourceLocation());
+        Expression elseExpr = caseExpression.getElseExpr();
         Pair<ILogicalOperator, LogicalVariable> opAndVarForElse =
-                constructSubplanOperatorForBranch(currentOperator, elseCondExprRef, caseExpression.getElseExpr());
+                constructSubplanOperatorForBranch(currentOperator, elseCondExprRef, elseExpr);
 
         // Uses switch-case function to select the results of two branches.
         LogicalVariable selectVar = context.newVar();
@@ -525,25 +589,35 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
         for (ILogicalExpression argVar : allVarReferences) {
             arguments.add(new MutableObject<>(argVar));
         }
-        arguments.add(new MutableObject<>(new VariableReferenceExpression(opAndVarForElse.second)));
+        VariableReferenceExpression varForElseRef = new VariableReferenceExpression(opAndVarForElse.second);
+        varForElseRef.setSourceLocation(elseExpr.getSourceLocation());
+        arguments.add(new MutableObject<>(varForElseRef));
         AbstractFunctionCallExpression swithCaseExpr =
                 new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.SWITCH_CASE), arguments);
+        swithCaseExpr.setSourceLocation(caseExpression.getSourceLocation());
         AssignOperator assignOp = new AssignOperator(selectVar, new MutableObject<>(swithCaseExpr));
         assignOp.getInputs().add(new MutableObject<>(opAndVarForElse.first));
+        assignOp.setSourceLocation(caseExpression.getSourceLocation());
 
         // Unnests the selected (a "THEN" or "ELSE" branch) result.
         LogicalVariable unnestVar = context.newVar();
-        UnnestOperator unnestOp = new UnnestOperator(unnestVar,
-                new MutableObject<>(new UnnestingFunctionCallExpression(
-                        FunctionUtil.getFunctionInfo(BuiltinFunctions.SCAN_COLLECTION), Collections
-                                .singletonList(new MutableObject<>(new VariableReferenceExpression(selectVar))))));
+        VariableReferenceExpression selectVarRef = new VariableReferenceExpression(selectVar);
+        selectVarRef.setSourceLocation(caseExpression.getSourceLocation());
+        UnnestingFunctionCallExpression scanCollectionExpr =
+                new UnnestingFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.SCAN_COLLECTION),
+                        Collections.singletonList(new MutableObject<>(selectVarRef)));
+        scanCollectionExpr.setSourceLocation(caseExpression.getSourceLocation());
+        UnnestOperator unnestOp = new UnnestOperator(unnestVar, new MutableObject<>(scanCollectionExpr));
         unnestOp.getInputs().add(new MutableObject<>(assignOp));
+        unnestOp.setSourceLocation(caseExpression.getSourceLocation());
 
         // Produces the final assign operator.
         LogicalVariable resultVar = context.newVar();
-        AssignOperator finalAssignOp =
-                new AssignOperator(resultVar, new MutableObject<>(new VariableReferenceExpression(unnestVar)));
+        VariableReferenceExpression unnestVarRef = new VariableReferenceExpression(unnestVar);
+        unnestVarRef.setSourceLocation(caseExpression.getSourceLocation());
+        AssignOperator finalAssignOp = new AssignOperator(resultVar, new MutableObject<>(unnestVarRef));
         finalAssignOp.getInputs().add(new MutableObject<>(unnestOp));
+        finalAssignOp.setSourceLocation(caseExpression.getSourceLocation());
         return new Pair<>(finalAssignOp, resultVar);
     }
 
@@ -554,6 +628,7 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
         } else {
             ProjectOperator pr = new ProjectOperator(resVar);
             pr.getInputs().add(returnOpRef);
+            pr.setSourceLocation(returnOpRef.getValue().getSourceLocation());
             return new Pair<>(pr, resVar);
         }
     }
@@ -567,19 +642,25 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
         Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(returnExpr, tupSrc);
         LogicalVariable returnVar;
         ILogicalOperator returnOperator;
+        SourceLocation sourceLoc = returnExpr.getSourceLocation();
         if (returnExpr.getKind() == Kind.VARIABLE_EXPRESSION) {
             VariableExpr varExpr = (VariableExpr) returnExpr;
             returnOperator = eo.second.getValue();
             returnVar = context.getVar(varExpr.getVar().getId());
         } else {
             returnVar = context.newVar();
-            returnOperator = new AssignOperator(returnVar, new MutableObject<>(eo.first));
-            returnOperator.getInputs().add(eo.second);
+            AssignOperator assignOp = new AssignOperator(returnVar, new MutableObject<>(eo.first));
+            assignOp.getInputs().add(eo.second);
+            assignOp.setSourceLocation(sourceLoc);
+            returnOperator = assignOp;
         }
         if (selectClause.distinct()) {
-            DistinctOperator distinctOperator = new DistinctOperator(
-                    mkSingletonArrayList(new MutableObject<>(new VariableReferenceExpression(returnVar))));
+            VariableReferenceExpression returnVarRef = new VariableReferenceExpression(returnVar);
+            returnVarRef.setSourceLocation(sourceLoc);
+            DistinctOperator distinctOperator =
+                    new DistinctOperator(mkSingletonArrayList(new MutableObject<>(returnVarRef)));
             distinctOperator.getInputs().add(new MutableObject<>(returnOperator));
+            distinctOperator.setSourceLocation(returnOperator.getSourceLocation());
             return new Pair<>(distinctOperator, returnVar);
         } else {
             return new Pair<>(returnOperator, returnVar);
@@ -593,7 +674,9 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
         for (Projection projection : selectRegular.getProjections()) {
             if (projection.varStar()) {
                 if (!fieldBindings.isEmpty()) {
-                    recordExprs.add(new RecordConstructor(new ArrayList<>(fieldBindings)));
+                    RecordConstructor recordConstr = new RecordConstructor(new ArrayList<>(fieldBindings));
+                    recordConstr.setSourceLocation(projection.getSourceLocation());
+                    recordExprs.add(recordConstr);
                     fieldBindings.clear();
                 }
                 recordExprs.add(projection.getExpression());
@@ -617,11 +700,19 @@ class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTranslator imp
             }
         }
         if (!fieldBindings.isEmpty()) {
-            recordExprs.add(new RecordConstructor(fieldBindings));
+            RecordConstructor recordConstr = new RecordConstructor(fieldBindings);
+            recordConstr.setSourceLocation(selectRegular.getSourceLocation());
+            recordExprs.add(recordConstr);
         }
 
-        return recordExprs.size() == 1 ? recordExprs.get(0)
-                : new CallExpr(new FunctionSignature(BuiltinFunctions.RECORD_CONCAT_STRICT), recordExprs);
+        if (recordExprs.size() == 1) {
+            return recordExprs.get(0);
+        } else {
+            CallExpr recordConcatExpr =
+                    new CallExpr(new FunctionSignature(BuiltinFunctions.RECORD_CONCAT_STRICT), recordExprs);
+            recordConcatExpr.setSourceLocation(selectRegular.getSourceLocation());
+            return recordConcatExpr;
+        }
     }
 
     // Generates all field bindings according to the from clause.

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ee54cc02/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TranslationException.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TranslationException.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TranslationException.java
deleted file mode 100644
index 0660f23..0000000
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TranslationException.java
+++ /dev/null
@@ -1,29 +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.translator;
-
-import org.apache.asterix.common.exceptions.CompilationException;
-
-public class TranslationException extends CompilationException {
-    private static final long serialVersionUID = 685960054131778068L;
-
-    public TranslationException(String msg) {
-        super(msg);
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ee54cc02/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/PlanTranslationUtil.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/PlanTranslationUtil.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/PlanTranslationUtil.java
index 919bdf2..d2466bf 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/PlanTranslationUtil.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/PlanTranslationUtil.java
@@ -36,43 +36,52 @@ import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCall
 import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
+import org.apache.hyracks.api.exceptions.SourceLocation;
 
 public class PlanTranslationUtil {
     private static final LogicalVariable DUMMY_VAR = new LogicalVariable(-1);
 
     public static void prepareMetaKeyAccessExpression(List<String> field, LogicalVariable resVar,
             List<Mutable<ILogicalExpression>> assignExpressions, List<LogicalVariable> vars,
-            List<Mutable<ILogicalExpression>> varRefs, IVariableContext context) {
+            List<Mutable<ILogicalExpression>> varRefs, IVariableContext context, SourceLocation sourceLoc) {
         IAObject value = (field.size() > 1) ? new AOrderedList(field) : new AString(field.get(0));
         ScalarFunctionCallExpression metaKeyFunction =
                 new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.META_KEY));
-        metaKeyFunction.getArguments()
-                .add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(resVar)));
+        metaKeyFunction.setSourceLocation(sourceLoc);
+        VariableReferenceExpression resVarRef = new VariableReferenceExpression(resVar);
+        resVarRef.setSourceLocation(sourceLoc);
+        metaKeyFunction.getArguments().add(new MutableObject<ILogicalExpression>(resVarRef));
         metaKeyFunction.getArguments()
                 .add(new MutableObject<>(new ConstantExpression(new AsterixConstantValue(value))));
         assignExpressions.add(new MutableObject<ILogicalExpression>(metaKeyFunction));
         LogicalVariable v = context.newVar();
         vars.add(v);
         if (varRefs != null) {
-            varRefs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(v)));
+            VariableReferenceExpression vRef = new VariableReferenceExpression(v);
+            vRef.setSourceLocation(sourceLoc);
+            varRefs.add(new MutableObject<ILogicalExpression>(vRef));
         }
     }
 
     public static void prepareVarAndExpression(List<String> field, LogicalVariable resVar, List<LogicalVariable> vars,
             List<Mutable<ILogicalExpression>> assignExpressions, List<Mutable<ILogicalExpression>> varRefs,
-            IVariableContext context) {
-        ScalarFunctionCallExpression f = createFieldAccessExpression(new VariableReferenceExpression(DUMMY_VAR), field);
+            IVariableContext context, SourceLocation sourceLoc) {
+        VariableReferenceExpression dummyVarRef = new VariableReferenceExpression(DUMMY_VAR);
+        dummyVarRef.setSourceLocation(sourceLoc);
+        ScalarFunctionCallExpression f = createFieldAccessExpression(dummyVarRef, field, sourceLoc);
         f.substituteVar(DUMMY_VAR, resVar);
         assignExpressions.add(new MutableObject<ILogicalExpression>(f));
         LogicalVariable v = context.newVar();
         vars.add(v);
         if (varRefs != null) {
-            varRefs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(v)));
+            VariableReferenceExpression vRef = new VariableReferenceExpression(v);
+            vRef.setSourceLocation(sourceLoc);
+            varRefs.add(new MutableObject<ILogicalExpression>(vRef));
         }
     }
 
     private static ScalarFunctionCallExpression createFieldAccessExpression(ILogicalExpression target,
-            List<String> field) {
+            List<String> field, SourceLocation sourceLoc) {
         FunctionIdentifier functionIdentifier;
         IAObject value;
         if (field.size() > 1) {
@@ -83,7 +92,9 @@ public class PlanTranslationUtil {
             value = new AString(field.get(0));
         }
         IFunctionInfo finfoAccess = FunctionUtil.getFunctionInfo(functionIdentifier);
-        return new ScalarFunctionCallExpression(finfoAccess, new MutableObject<>(target),
+        ScalarFunctionCallExpression faExpr = new ScalarFunctionCallExpression(finfoAccess, new MutableObject<>(target),
                 new MutableObject<>(new ConstantExpression(new AsterixConstantValue(value))));
+        faExpr.setSourceLocation(sourceLoc);
+        return faExpr;
     }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ee54cc02/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java
index d5ebc6e..ffb1dd5 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java
@@ -32,6 +32,7 @@ import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.om.utils.RecordUtil;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.api.exceptions.SourceLocation;
 
 /**
  * A util that can verify if a filter field, a list of partitioning expressions,
@@ -50,16 +51,17 @@ public class ValidateUtil {
      *            the record type
      * @param filterField
      *            the full name of the field
+     * @param sourceLoc
      * @throws AlgebricksException
      *             if field is not found in record.
      *             if field type can't be a filter type.
      *             if field type is nullable.
      */
-    public static void validateFilterField(ARecordType recordType, List<String> filterField)
+    public static void validateFilterField(ARecordType recordType, List<String> filterField, SourceLocation sourceLoc)
             throws AlgebricksException {
         IAType fieldType = recordType.getSubFieldType(filterField);
         if (fieldType == null) {
-            throw new CompilationException(ErrorCode.COMPILATION_FIELD_NOT_FOUND,
+            throw new CompilationException(ErrorCode.COMPILATION_FIELD_NOT_FOUND, sourceLoc,
                     RecordUtil.toFullyQualifiedName(filterField));
         }
         switch (fieldType.getTypeTag()) {
@@ -100,6 +102,7 @@ public class ValidateUtil {
      *            the key sources (record vs. meta)
      * @param autogenerated
      *            true if auto generated, false otherwise
+     * @param sourceLoc
      * @return a list of partitioning expressions types
      * @throws AlgebricksException
      *             if composite key is autogenerated.
@@ -109,24 +112,25 @@ public class ValidateUtil {
      *             if the field type can't be a primary key.
      */
     public static List<IAType> validatePartitioningExpressions(ARecordType recType, ARecordType metaRecType,
-            List<List<String>> partitioningExprs, List<Integer> keySourceIndicators, boolean autogenerated)
-            throws AlgebricksException {
+            List<List<String>> partitioningExprs, List<Integer> keySourceIndicators, boolean autogenerated,
+            SourceLocation sourceLoc) throws AlgebricksException {
         List<IAType> partitioningExprTypes = new ArrayList<>(partitioningExprs.size());
         if (autogenerated) {
             if (partitioningExprs.size() > 1) {
-                throw new CompilationException(ErrorCode.COMPILATION_CANNOT_AUTOGENERATE_COMPOSITE_PRIMARY_KEY);
+                throw new CompilationException(ErrorCode.COMPILATION_CANNOT_AUTOGENERATE_COMPOSITE_PRIMARY_KEY,
+                        sourceLoc);
             }
             List<String> fieldName = partitioningExprs.get(0);
             IAType fieldType = recType.getSubFieldType(fieldName);
             if (fieldType == null) {
                 String unTypeField = fieldName.get(0) == null ? "" : fieldName.get(0);
-                throw new CompilationException(ErrorCode.COMPILATION_FIELD_NOT_FOUND, unTypeField);
+                throw new CompilationException(ErrorCode.COMPILATION_FIELD_NOT_FOUND, sourceLoc, unTypeField);
             }
             partitioningExprTypes.add(fieldType);
             ATypeTag pkTypeTag = fieldType.getTypeTag();
             if (pkTypeTag != ATypeTag.UUID) {
-                throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_AUTOGENERATED_TYPE, pkTypeTag.name(),
-                        ATypeTag.UUID.name());
+                throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_AUTOGENERATED_TYPE, sourceLoc,
+                        pkTypeTag.name(), ATypeTag.UUID.name());
             }
         } else {
             partitioningExprTypes =
@@ -135,14 +139,14 @@ public class ValidateUtil {
                 List<String> partitioningExpr = partitioningExprs.get(i);
                 IAType fieldType = partitioningExprTypes.get(i);
                 if (fieldType == null) {
-                    throw new CompilationException(ErrorCode.COMPILATION_FIELD_NOT_FOUND,
+                    throw new CompilationException(ErrorCode.COMPILATION_FIELD_NOT_FOUND, sourceLoc,
                             RecordUtil.toFullyQualifiedName(partitioningExpr));
                 }
                 boolean nullable = KeyFieldTypeUtil.chooseSource(keySourceIndicators, i, recType, metaRecType)
                         .isSubFieldNullable(partitioningExpr);
                 if (nullable) {
                     // key field is nullable
-                    throw new CompilationException(ErrorCode.COMPILATION_PRIMARY_KEY_CANNOT_BE_NULLABLE,
+                    throw new CompilationException(ErrorCode.COMPILATION_PRIMARY_KEY_CANNOT_BE_NULLABLE, sourceLoc,
                             RecordUtil.toFullyQualifiedName(partitioningExpr));
                 }
                 switch (fieldType.getTypeTag()) {
@@ -162,10 +166,10 @@ public class ValidateUtil {
                     case DAYTIMEDURATION:
                         break;
                     case UNION:
-                        throw new CompilationException(ErrorCode.COMPILATION_PRIMARY_KEY_CANNOT_BE_NULLABLE,
+                        throw new CompilationException(ErrorCode.COMPILATION_PRIMARY_KEY_CANNOT_BE_NULLABLE, sourceLoc,
                                 RecordUtil.toFullyQualifiedName(partitioningExpr));
                     default:
-                        throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_PRIMARY_KEY_TYPE,
+                        throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_PRIMARY_KEY_TYPE, sourceLoc,
                                 fieldType.getTypeTag());
                 }
             }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ee54cc02/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
index 537625d..a1d3f57 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
@@ -102,6 +102,7 @@ import org.apache.hyracks.api.client.IHyracksClientConnection;
 import org.apache.hyracks.api.client.NodeControllerInfo;
 import org.apache.hyracks.api.config.IOptionType;
 import org.apache.hyracks.api.exceptions.HyracksException;
+import org.apache.hyracks.api.exceptions.SourceLocation;
 import org.apache.hyracks.api.job.JobId;
 import org.apache.hyracks.api.job.JobSpecification;
 import org.apache.hyracks.api.job.resource.IClusterCapacity;
@@ -190,6 +191,8 @@ public class APIFramework {
         // establish facts
         final boolean isQuery = query != null;
         final boolean isLoad = statement != null && statement.getKind() == Statement.Kind.LOAD;
+        final SourceLocation sourceLoc =
+                query != null ? query.getSourceLocation() : statement != null ? statement.getSourceLocation() : null;
 
         SessionConfig conf = output.config();
         if (isQuery && !conf.is(SessionConfig.FORMAT_ONLY_PHYSICAL_OPS)
@@ -209,9 +212,9 @@ public class APIFramework {
             generateLogicalPlan(plan, output.config().getPlanFormat());
         }
         CompilerProperties compilerProperties = metadataProvider.getApplicationContext().getCompilerProperties();
-        Map<String, String> querySpecificConfig = validateConfig(metadataProvider.getConfig());
+        Map<String, String> querySpecificConfig = validateConfig(metadataProvider.getConfig(), sourceLoc);
         final PhysicalOptimizationConfig physOptConf =
-                getPhysicalOptimizationConfig(compilerProperties, querySpecificConfig);
+                getPhysicalOptimizationConfig(compilerProperties, querySpecificConfig, sourceLoc);
 
         HeuristicCompilerFactoryBuilder builder =
                 new HeuristicCompilerFactoryBuilder(OptimizationContextFactory.INSTANCE);
@@ -300,20 +303,20 @@ public class APIFramework {
     }
 
     protected PhysicalOptimizationConfig getPhysicalOptimizationConfig(CompilerProperties compilerProperties,
-            Map<String, String> querySpecificConfig) throws AlgebricksException {
+            Map<String, String> querySpecificConfig, SourceLocation sourceLoc) throws AlgebricksException {
         int frameSize = compilerProperties.getFrameSize();
         int sortFrameLimit = getFrameLimit(CompilerProperties.COMPILER_SORTMEMORY_KEY,
                 querySpecificConfig.get(CompilerProperties.COMPILER_SORTMEMORY_KEY),
-                compilerProperties.getSortMemorySize(), frameSize, MIN_FRAME_LIMIT_FOR_SORT);
+                compilerProperties.getSortMemorySize(), frameSize, MIN_FRAME_LIMIT_FOR_SORT, sourceLoc);
         int groupFrameLimit = getFrameLimit(CompilerProperties.COMPILER_GROUPMEMORY_KEY,
                 querySpecificConfig.get(CompilerProperties.COMPILER_GROUPMEMORY_KEY),
-                compilerProperties.getGroupMemorySize(), frameSize, MIN_FRAME_LIMIT_FOR_GROUP_BY);
+                compilerProperties.getGroupMemorySize(), frameSize, MIN_FRAME_LIMIT_FOR_GROUP_BY, sourceLoc);
         int joinFrameLimit = getFrameLimit(CompilerProperties.COMPILER_JOINMEMORY_KEY,
                 querySpecificConfig.get(CompilerProperties.COMPILER_JOINMEMORY_KEY),
-                compilerProperties.getJoinMemorySize(), frameSize, MIN_FRAME_LIMIT_FOR_JOIN);
+                compilerProperties.getJoinMemorySize(), frameSize, MIN_FRAME_LIMIT_FOR_JOIN, sourceLoc);
         int textSearchFrameLimit = getFrameLimit(CompilerProperties.COMPILER_TEXTSEARCHMEMORY_KEY,
                 querySpecificConfig.get(CompilerProperties.COMPILER_TEXTSEARCHMEMORY_KEY),
-                compilerProperties.getTextSearchMemorySize(), frameSize, MIN_FRAME_LIMIT_FOR_TEXTSEARCH);
+                compilerProperties.getTextSearchMemorySize(), frameSize, MIN_FRAME_LIMIT_FOR_TEXTSEARCH, sourceLoc);
         final PhysicalOptimizationConfig physOptConf = OptimizationConfUtil.getPhysicalOptimizationConfig();
         physOptConf.setFrameSize(frameSize);
         physOptConf.setMaxFramesExternalSort(sortFrameLimit);
@@ -450,12 +453,17 @@ public class APIFramework {
 
     // Gets the frame limit.
     private static int getFrameLimit(String parameterName, String parameter, long memBudgetInConfiguration,
-            int frameSize, int minFrameLimit) throws AlgebricksException {
+            int frameSize, int minFrameLimit, SourceLocation sourceLoc) throws AlgebricksException {
         IOptionType<Long> longBytePropertyInterpreter = OptionTypes.LONG_BYTE_UNIT;
-        long memBudget = parameter == null ? memBudgetInConfiguration : longBytePropertyInterpreter.parse(parameter);
+        long memBudget;
+        try {
+            memBudget = parameter == null ? memBudgetInConfiguration : longBytePropertyInterpreter.parse(parameter);
+        } catch (IllegalArgumentException e) {
+            throw AsterixException.create(ErrorCode.COMPILATION_ERROR, sourceLoc, e.getMessage());
+        }
         int frameLimit = (int) (memBudget / frameSize);
         if (frameLimit < minFrameLimit) {
-            throw AsterixException.create(ErrorCode.COMPILATION_BAD_QUERY_PARAMETER_VALUE, parameterName,
+            throw AsterixException.create(ErrorCode.COMPILATION_BAD_QUERY_PARAMETER_VALUE, sourceLoc, parameterName,
                     frameSize * minFrameLimit);
         }
         // Sets the frame limit to the minimum frame limit if the caculated frame limit is too small.
@@ -469,10 +477,12 @@ public class APIFramework {
     }
 
     // Validates if the query contains unsupported query parameters.
-    private static Map<String, String> validateConfig(Map<String, String> config) throws AlgebricksException {
+    private static Map<String, String> validateConfig(Map<String, String> config, SourceLocation sourceLoc)
+            throws AlgebricksException {
         for (String parameterName : config.keySet()) {
             if (!CONFIGURABLE_PARAMETER_NAMES.contains(parameterName)) {
-                throw AsterixException.create(ErrorCode.COMPILATION_UNSUPPORTED_QUERY_PARAMETER, parameterName);
+                throw AsterixException.create(ErrorCode.COMPILATION_UNSUPPORTED_QUERY_PARAMETER, sourceLoc,
+                        parameterName);
             }
         }
         return config;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ee54cc02/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetResourcesRewriter.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetResourcesRewriter.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetResourcesRewriter.java
index a575ba4..77e0310 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetResourcesRewriter.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetResourcesRewriter.java
@@ -18,6 +18,8 @@
  */
 package org.apache.asterix.app.function;
 
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionConstants;
 import org.apache.asterix.metadata.declared.MetadataProvider;
 import org.apache.asterix.metadata.entities.Dataset;
@@ -45,7 +47,8 @@ public class DatasetResourcesRewriter extends FunctionRewriter {
         MetadataProvider metadataProvider = (MetadataProvider) context.getMetadataProvider();
         Dataset dataset = metadataProvider.findDataset(dataverseName, datasetName);
         if (dataset == null) {
-            throw new AlgebricksException("Could not find dataset " + datasetName + " in dataverse " + dataverseName);
+            throw new CompilationException(ErrorCode.COMPILATION_ERROR, f.getSourceLocation(),
+                    "Could not find dataset " + datasetName + " in dataverse " + dataverseName);
         }
         return new DatasetResourcesDatasource(context.getComputationNodeDomain(), dataset.getDatasetId());
     }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ee54cc02/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetRewriter.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetRewriter.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetRewriter.java
index c857ce0..9b4b7c4 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetRewriter.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetRewriter.java
@@ -22,6 +22,8 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.asterix.common.config.DatasetConfig.DatasetType;
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.metadata.declared.DataSource;
 import org.apache.asterix.metadata.declared.DataSourceId;
 import org.apache.asterix.metadata.declared.MetadataProvider;
@@ -68,7 +70,8 @@ public class DatasetRewriter implements IFunctionToDataSourceRewriter, IResultTy
         UnnestOperator unnest = (UnnestOperator) opRef.getValue();
         if (unnest.getPositionalVariable() != null) {
             // TODO remove this after enabling the support of positional variables in data scan
-            throw new AlgebricksException("No positional variables are allowed over datasets.");
+            throw new CompilationException(ErrorCode.COMPILATION_ERROR, unnest.getSourceLocation(),
+                    "No positional variables are allowed over datasets.");
         }
         ILogicalExpression expr = f.getArguments().get(0).getValue();
         if (expr.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
@@ -90,7 +93,8 @@ public class DatasetRewriter implements IFunctionToDataSourceRewriter, IResultTy
         String datasetName = datasetReference.second;
         Dataset dataset = metadataProvider.findDataset(dataverseName, datasetName);
         if (dataset == null) {
-            throw new AlgebricksException("Could not find dataset " + datasetName + " in dataverse " + dataverseName);
+            throw new CompilationException(ErrorCode.COMPILATION_ERROR, unnest.getSourceLocation(),
+                    "Could not find dataset " + datasetName + " in dataverse " + dataverseName);
         }
         DataSourceId asid = new DataSourceId(dataverseName, datasetName);
         List<LogicalVariable> variables = new ArrayList<>();
@@ -107,6 +111,7 @@ public class DatasetRewriter implements IFunctionToDataSourceRewriter, IResultTy
             variables.add(context.newVar());
         }
         DataSourceScanOperator scan = new DataSourceScanOperator(variables, dataSource);
+        scan.setSourceLocation(unnest.getSourceLocation());
         List<Mutable<ILogicalOperator>> scanInpList = scan.getInputs();
         scanInpList.addAll(unnest.getInputs());
         opRef.setValue(scan);

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ee54cc02/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/FeedRewriter.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/FeedRewriter.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/FeedRewriter.java
index 51aca5d..e9087c2 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/FeedRewriter.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/FeedRewriter.java
@@ -21,6 +21,8 @@ package org.apache.asterix.app.function;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.external.feed.watch.FeedActivityDetails;
 import org.apache.asterix.external.util.ExternalDataUtils;
 import org.apache.asterix.external.util.FeedUtils;
@@ -70,7 +72,8 @@ public class FeedRewriter implements IFunctionToDataSourceRewriter, IResultTypeC
         AbstractFunctionCallExpression f = UnnestToDataScanRule.getFunctionCall(opRef);
         UnnestOperator unnest = (UnnestOperator) opRef.getValue();
         if (unnest.getPositionalVariable() != null) {
-            throw new AlgebricksException("No positional variables are allowed over feeds.");
+            throw new CompilationException(ErrorCode.COMPILATION_ERROR, unnest.getSourceLocation(),
+                    "No positional variables are allowed over feeds.");
         }
         String dataverse = ConstantExpressionUtil.getStringArgument(f, 0);
         String sourceFeedName = ConstantExpressionUtil.getStringArgument(f, 1);
@@ -85,7 +88,8 @@ public class FeedRewriter implements IFunctionToDataSourceRewriter, IResultTypeC
         if (policy == null) {
             policy = BuiltinFeedPolicies.getFeedPolicy(policyName);
             if (policy == null) {
-                throw new AlgebricksException("Unknown feed policy:" + policyName);
+                throw new CompilationException(ErrorCode.COMPILATION_ERROR, unnest.getSourceLocation(),
+                        "Unknown feed policy:" + policyName);
             }
         }
         ArrayList<LogicalVariable> feedDataScanOutputVariables = new ArrayList<>();
@@ -104,6 +108,7 @@ public class FeedRewriter implements IFunctionToDataSourceRewriter, IResultTypeC
             feedDataScanOutputVariables.addAll(pkVars);
         }
         DataSourceScanOperator scan = new DataSourceScanOperator(feedDataScanOutputVariables, ds);
+        scan.setSourceLocation(unnest.getSourceLocation());
         List<Mutable<ILogicalOperator>> scanInpList = scan.getInputs();
         scanInpList.addAll(unnest.getInputs());
         opRef.setValue(scan);
@@ -152,10 +157,10 @@ public class FeedRewriter implements IFunctionToDataSourceRewriter, IResultTypeC
                 List<String> key = partitioningKeys.get(i);
                 if (keySourceIndicator == null || keySourceIndicator.get(i).intValue() == 0) {
                     PlanTranslationUtil.prepareVarAndExpression(key, recordVar, pkVars, keyAccessExpression, null,
-                            context);
+                            context, null);
                 } else {
                     PlanTranslationUtil.prepareMetaKeyAccessExpression(key, recordVar, keyAccessExpression, pkVars,
-                            null, context);
+                            null, context, null);
                 }
             }
             keyAccessExpression.forEach(

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ee54cc02/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/FunctionRewriter.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/FunctionRewriter.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/FunctionRewriter.java
index 2ff9282..2bc5ab6 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/FunctionRewriter.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/FunctionRewriter.java
@@ -21,6 +21,8 @@ package org.apache.asterix.app.function;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.metadata.declared.FunctionDataSource;
 import org.apache.asterix.om.base.AString;
 import org.apache.asterix.om.constants.AsterixConstantValue;
@@ -55,24 +57,29 @@ public abstract class FunctionRewriter implements IFunctionToDataSourceRewriter
         AbstractFunctionCallExpression f = UnnestToDataScanRule.getFunctionCall(opRef);
         List<Mutable<ILogicalExpression>> args = f.getArguments();
         if (args.size() != functionId.getArity()) {
-            throw new AlgebricksException("Function " + functionId.getNamespace() + "." + functionId.getName()
-                    + " expects " + functionId.getArity() + " arguments");
+            throw new CompilationException(ErrorCode.COMPILATION_ERROR, f.getSourceLocation(),
+                    "Function " + functionId.getNamespace() + "." + functionId.getName() + " expects "
+                            + functionId.getArity() + " arguments");
         }
         for (int i = 0; i < args.size(); i++) {
-            if (args.get(i).getValue().getExpressionTag() != LogicalExpressionTag.CONSTANT) {
-                throw new AlgebricksException("Function " + functionId.getNamespace() + "." + functionId.getName()
-                        + " expects constant arguments while arg[" + i + "] is of type "
-                        + args.get(i).getValue().getExpressionTag());
+            ILogicalExpression argExpr = args.get(i).getValue();
+            if (argExpr.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
+                throw new CompilationException(ErrorCode.COMPILATION_ERROR, argExpr.getSourceLocation(),
+                        "Function " + functionId.getNamespace() + "." + functionId.getName()
+                                + " expects constant arguments while arg[" + i + "] is of type "
+                                + argExpr.getExpressionTag());
             }
         }
         UnnestOperator unnest = (UnnestOperator) opRef.getValue();
         if (unnest.getPositionalVariable() != null) {
-            throw new AlgebricksException("No positional variables are allowed over datasource functions");
+            throw new CompilationException(ErrorCode.COMPILATION_ERROR, unnest.getSourceLocation(),
+                    "No positional variables are allowed over datasource functions");
         }
         FunctionDataSource datasource = toDatasource(context, f);
         List<LogicalVariable> variables = new ArrayList<>();
         variables.add(unnest.getVariable());
         DataSourceScanOperator scan = new DataSourceScanOperator(variables, datasource);
+        scan.setSourceLocation(unnest.getSourceLocation());
         List<Mutable<ILogicalOperator>> scanInpList = scan.getInputs();
         scanInpList.addAll(unnest.getInputs());
         opRef.setValue(scan);

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ee54cc02/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/StorageComponentsRewriter.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/StorageComponentsRewriter.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/StorageComponentsRewriter.java
index 89bd115..d1796cf 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/StorageComponentsRewriter.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/StorageComponentsRewriter.java
@@ -18,6 +18,8 @@
  */
 package org.apache.asterix.app.function;
 
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionConstants;
 import org.apache.asterix.metadata.declared.MetadataProvider;
 import org.apache.asterix.metadata.entities.Dataset;
@@ -45,7 +47,8 @@ public class StorageComponentsRewriter extends FunctionRewriter {
         MetadataProvider metadataProvider = (MetadataProvider) context.getMetadataProvider();
         Dataset dataset = metadataProvider.findDataset(dataverseName, datasetName);
         if (dataset == null) {
-            throw new AlgebricksException("Could not find dataset " + datasetName + " in dataverse " + dataverseName);
+            throw new CompilationException(ErrorCode.COMPILATION_ERROR, f.getSourceLocation(),
+                    "Could not find dataset " + datasetName + " in dataverse " + dataverseName);
         }
         return new StorageComponentsDatasource(context.getComputationNodeDomain(), dataset.getDatasetId());
     }