asterixdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From buyin...@apache.org
Subject [3/3] asterixdb git commit: ASTERIXDB-1755: add UPSERT in SQL++.
Date Wed, 04 Jan 2017 01:29:53 GMT
ASTERIXDB-1755: add UPSERT in SQL++.

Detailed list of changes included:
- Fix AQL RETURNING clause to use an expression instead of a query;
- Add a rule to check whether a RETURNING expression contains dataset accesses;
- Perform AST-level rewrites for INSERT/UPSERT as a whole, including the
  body query and the returning expression.

Change-Id: I02b2be7ff2653573eccb48037895f5c8c4bc8c74
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1401
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Yingyi Bu <buyingyi@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/cb5bf33d
Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/cb5bf33d
Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/cb5bf33d

Branch: refs/heads/master
Commit: cb5bf33d09ee826c44d74938c194e5d0c606a124
Parents: 44384a2
Author: Yingyi Bu <yingyi@couchbase.com>
Authored: Mon Jan 2 22:19:50 2017 -0800
Committer: Yingyi Bu <buyingyi@gmail.com>
Committed: Tue Jan 3 17:29:20 2017 -0800

----------------------------------------------------------------------
 .../asterix/optimizer/base/RuleCollections.java |   2 +
 .../rules/CheckInsertUpsertReturningRule.java   |  51 +++++++
 .../rules/util/InsertUpsertCheckUtil.java       | 102 +++++++++++++
 .../AqlExpressionToPlanTranslator.java          |  13 +-
 .../asterix/translator/CompiledStatements.java  |  16 +-
 .../LangExpressionToPlanTranslator.java         | 145 +++++++++----------
 .../apache/asterix/api/common/APIFramework.java |   6 +-
 .../asterix/app/translator/QueryTranslator.java |  79 +++++-----
 .../asterix/test/sqlpp/ParserTestExecutor.java  |   3 +-
 .../results/insert-return-custom-result.plan    |  27 ++--
 ...nsert-returning-fieldname-implicit.1.ddl.aql |  37 +++++
 ...ert-returning-fieldname-implicit.3.query.aql |  30 ++++
 .../insert-returning-udf.1.ddl.aql              |  42 ++++++
 .../insert-returning-udf.3.query.aql            |  30 ++++
 .../upsert-return-custom-result.3.query.aql     |   3 +-
 .../insert-return-records.1.ddl.sqlpp           |  36 +++++
 .../insert-return-records.3.query.sqlpp         |  36 +++++
 ...ert-returning-fieldname-implicit.1.ddl.sqlpp |  37 +++++
 ...t-returning-fieldname-implicit.3.query.sqlpp |  30 ++++
 .../insert-returning-fieldname.1.ddl.sqlpp      |  37 +++++
 .../insert-returning-fieldname.3.query.sqlpp    |  30 ++++
 .../insert-returning-udf.1.ddl.sqlpp            |  41 ++++++
 .../insert-returning-udf.3.query.sqlpp          |  30 ++++
 .../insert-with-bad-return.1.ddl.sqlpp          |  36 +++++
 .../insert-with-bad-return.3.query.sqlpp        |  41 ++++++
 .../upsert-dataset-with-meta.1.ddl.sqlpp        |  36 +++++
 .../upsert-dataset-with-meta.2.update.sqlpp     |  29 ++++
 .../upsert-return-custom-result.1.ddl.sqlpp     |  37 +++++
 .../upsert-return-custom-result.3.query.sqlpp   |  46 ++++++
 .../feeds/upsert-feed/upsert-feed.1.ddl.sqlpp   |  46 ++++++
 .../upsert-feed/upsert-feed.2.update.sqlpp      |  29 ++++
 .../upsert-feed/upsert-feed.3.server.sqlpp      |  26 ++++
 .../feeds/upsert-feed/upsert-feed.4.sleep.sqlpp |  26 ++++
 .../upsert-feed/upsert-feed.5.update.sqlpp      |  28 ++++
 .../feeds/upsert-feed/upsert-feed.6.query.sqlpp |  31 ++++
 .../upsert-feed/upsert-feed.7.server.sqlpp      |  27 ++++
 .../feeds/upsert-feed/upsert-feed.8.ddl.sqlpp   |  27 ++++
 .../enforced-type-delete.1.ddl.sqlpp            |  33 +++++
 .../enforced-type-delete.2.update.sqlpp         |  29 ++++
 .../enforced-type-delete.3.ddl.sqlpp            |  27 ++++
 .../enforced-type-delete.4.update.sqlpp         |  32 ++++
 .../enforced-type-delete.5.query.sqlpp          |  33 +++++
 .../enforced-type-upsert.1.ddl.sqlpp            |  33 +++++
 .../enforced-type-upsert.2.update.sqlpp         |  29 ++++
 .../enforced-type-upsert.3.ddl.sqlpp            |  27 ++++
 .../enforced-type-upsert.4.update.sqlpp         |  29 ++++
 .../enforced-type-upsert.5.query.sqlpp          |  33 +++++
 .../filtered-dataset.1.ddl.sqlpp                |  46 ++++++
 .../filtered-dataset.2.update.sqlpp             |  30 ++++
 .../filtered-dataset.3.query.sqlpp              |  24 +++
 .../issue1587-foreignDataType.1.ddl.sqlpp       |  38 +++++
 .../issue1587-foreignDataType.2.update.sqlpp    |  38 +++++
 .../issue1587-foreignDataType.3.query.sqlpp     |  30 ++++
 .../issue1587-foreignDataType.4.ddl.sqlpp       |  25 ++++
 .../multiple-secondaries.1.ddl.sqlpp            |  44 ++++++
 .../multiple-secondaries.2.update.sqlpp         |  33 +++++
 .../multiple-secondaries.3.query.sqlpp          |  24 +++
 .../nested-index/nested-index.1.ddl.sqlpp       |  48 ++++++
 .../nested-index/nested-index.2.update.sqlpp    |  43 ++++++
 .../nested-index/nested-index.3.query.sqlpp     |  24 +++
 .../nullable-index/nullable-index.1.ddl.sqlpp   |  41 ++++++
 .../nullable-index.2.update.sqlpp               |  32 ++++
 .../nullable-index/nullable-index.3.query.sqlpp |  24 +++
 .../upsert/open-index/open-index.1.ddl.sqlpp    |  56 +++++++
 .../upsert/open-index/open-index.2.update.sqlpp |  37 +++++
 .../upsert/open-index/open-index.3.query.sqlpp  |  24 +++
 .../primary-index/primary-index.1.ddl.sqlpp     |  37 +++++
 .../primary-index/primary-index.2.update.sqlpp  |  41 ++++++
 .../primary-index/primary-index.3.query.sqlpp   |  28 ++++
 .../primary-secondary-btree.1.ddl.sqlpp         |  38 +++++
 .../primary-secondary-btree.2.update.sqlpp      |  41 ++++++
 .../primary-secondary-btree.3.query.sqlpp       |  30 ++++
 .../primary-secondary-inverted.1.ddl.sqlpp      |  37 +++++
 .../primary-secondary-inverted.2.update.sqlpp   |  32 ++++
 .../primary-secondary-inverted.3.query.sqlpp    |  24 +++
 .../primary-secondary-rtree.1.ddl.sqlpp         |  41 ++++++
 .../primary-secondary-rtree.2.update.sqlpp      |  32 ++++
 .../primary-secondary-rtree.3.query.sqlpp       |  23 +++
 .../upsert-with-self-read.1.ddl.sqlpp           |  36 +++++
 .../upsert-with-self-read.2.update.sqlpp        |  36 +++++
 .../upsert-with-self-read.3.query.sqlpp         |  28 ++++
 .../query-ASTERIXDB-1298.1.ddl.sqlpp            |  43 ++++++
 .../query-ASTERIXDB-1298.2.update.sqlpp         |  56 +++++++
 .../query-ASTERIXDB-1298.3.query.sqlpp          |  25 ++++
 .../upsert-return-custom-result.1.adm           |   6 +-
 .../src/test/resources/runtimets/testsuite.xml  |  13 +-
 .../resources/runtimets/testsuite_sqlpp.xml     | 117 +++++++++++++++
 .../asterix/common/exceptions/ErrorCode.java    |   4 +
 .../lang/aql/rewrites/AqlQueryRewriter.java     |  52 +++----
 .../lang/aql/util/AQLFormatPrintUtil.java       |  17 ++-
 .../asterix-lang-aql/src/main/javacc/AQL.jj     |  54 +++++--
 .../lang/common/base/IQueryRewriter.java        |   5 +-
 .../lang/common/base/IReturningStatement.java   |  67 +++++++++
 .../lang/common/statement/InsertStatement.java  |  62 ++++++--
 .../asterix/lang/common/statement/Query.java    |  19 ++-
 .../lang/common/statement/UpsertStatement.java  |   5 +-
 .../visitor/AbstractInlineUdfsVisitor.java      |  15 ++
 .../visitor/GatherFunctionCallsVisitor.java     |  11 ++
 .../rewrites/SqlppFunctionBodyRewriter.java     |   7 +-
 .../lang/sqlpp/rewrites/SqlppQueryRewriter.java |  87 ++++-------
 .../AbstractSqlppExpressionScopingVisitor.java  |  22 +++
 .../AbstractSqlppSimpleExpressionVisitor.java   |  12 ++
 .../asterix-lang-sqlpp/src/main/javacc/SQLPP.jj |  39 ++++-
 .../asterix/metadata/entities/Dataset.java      |   3 +-
 104 files changed, 3263 insertions(+), 276 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
index f12a02f..ec73185 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
@@ -30,6 +30,7 @@ import org.apache.asterix.optimizer.rules.AsterixIntroduceGroupByCombinerRule;
 import org.apache.asterix.optimizer.rules.ByNameToByIndexFieldAccessRule;
 import org.apache.asterix.optimizer.rules.CancelUnnestWithNestedListifyRule;
 import org.apache.asterix.optimizer.rules.CheckFilterExpressionTypeRule;
+import org.apache.asterix.optimizer.rules.CheckInsertUpsertReturningRule;
 import org.apache.asterix.optimizer.rules.ConstantFoldingRule;
 import org.apache.asterix.optimizer.rules.CountVarToCountOneRule;
 import org.apache.asterix.optimizer.rules.DisjunctivePredicateToJoinRule;
@@ -163,6 +164,7 @@ public final class RuleCollections {
     public static final List<IAlgebraicRewriteRule> buildNormalizationRuleCollection() {
         List<IAlgebraicRewriteRule> normalization = new LinkedList<>();
         normalization.add(new ResolveVariableRule());
+        normalization.add(new CheckInsertUpsertReturningRule());
         normalization.add(new IntroduceUnnestForCollectionToSequenceRule());
         normalization.add(new EliminateSubplanRule());
         normalization.add(new EnforceOrderByAfterSubplan());

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CheckInsertUpsertReturningRule.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CheckInsertUpsertReturningRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CheckInsertUpsertReturningRule.java
new file mode 100644
index 0000000..d181dd3
--- /dev/null
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CheckInsertUpsertReturningRule.java
@@ -0,0 +1,51 @@
+/*
+ * 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.optimizer.rules;
+
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.optimizer.rules.util.InsertUpsertCheckUtil;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
+import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+
+/**
+ * This rule checks whether a returning clause for INSERT/UPSERT contains a dataset access.
+ * NOTE: the rule should be invoked before rewriting Unnests (with dataset functions) into DataSourceScans.
+ */
+public class CheckInsertUpsertReturningRule implements IAlgebraicRewriteRule {
+
+    private boolean checked = false;
+
+    @Override
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        if (checked) {
+            return false;
+        }
+        if (InsertUpsertCheckUtil.check(opRef.getValue())) {
+            throw new CompilationException(ErrorCode.ERROR_COMPILATION_INVALID_RETURNING_EXPRESSION);
+        }
+        checked = true;
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/InsertUpsertCheckUtil.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/InsertUpsertCheckUtil.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/InsertUpsertCheckUtil.java
new file mode 100644
index 0000000..178e8b9
--- /dev/null
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/InsertUpsertCheckUtil.java
@@ -0,0 +1,102 @@
+/*
+ * 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.optimizer.rules.util;
+
+import java.util.List;
+
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
+import org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
+
+public class InsertUpsertCheckUtil {
+
+    private InsertUpsertCheckUtil() {
+    }
+
+    /**
+     *
+     * Checks the query plan rooted at <code>op</code> to see whether there is an invalid returning expression
+     * for insert/upsert, i.e., an returning expression that contains dataset accesses.
+     *
+     * @param op,
+     *            the operator in consideration
+     * @return true if the returning expression after insert/upsert is invalid; false otherwise.
+     */
+    public static boolean check(ILogicalOperator op) {
+        return checkTopDown(op, false);
+    }
+
+    // Checks the query plan rooted at <code>op</code> top down to see whether there is an invalid returning expression
+    // for insert/upsert, i.e., a returning expression that contains dataset accesses.
+    private static boolean checkTopDown(ILogicalOperator op, boolean hasSubplanAboveWithDatasetAccess) {
+        boolean metSubplanWithDataScan = hasSubplanAboveWithDatasetAccess;
+        if (op.getOperatorTag() == LogicalOperatorTag.SUBPLAN) {
+            SubplanOperator subplanOp = (SubplanOperator) op;
+            metSubplanWithDataScan = containsDatasetAccess(subplanOp);
+        }
+        if (op.getOperatorTag() == LogicalOperatorTag.INSERT_DELETE_UPSERT && metSubplanWithDataScan) {
+            return true;
+        }
+        for (Mutable<ILogicalOperator> inputOpRef : op.getInputs()) {
+            if (checkTopDown(inputOpRef.getValue(), metSubplanWithDataScan)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // Checks whether a subplan operator contains a dataset accesses in its nested pipeline.
+    private static boolean containsDatasetAccess(SubplanOperator subplanOp) {
+        List<ILogicalPlan> nestedPlans = subplanOp.getNestedPlans();
+        for (ILogicalPlan nestedPlan : nestedPlans) {
+            for (Mutable<ILogicalOperator> opRef : nestedPlan.getRoots()) {
+                if (containsDatasetAccessInternal(opRef.getValue())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    // Checks whether a query plan rooted at <code>op</code> contains dataset accesses.
+    private static boolean containsDatasetAccessInternal(ILogicalOperator op) {
+        if (op.getOperatorTag() == LogicalOperatorTag.UNNEST) {
+            UnnestOperator unnestOp = (UnnestOperator) op;
+            ILogicalExpression unnestExpr = unnestOp.getExpressionRef().getValue();
+            UnnestingFunctionCallExpression unnestingFuncExpr = (UnnestingFunctionCallExpression) unnestExpr;
+            return unnestingFuncExpr.getFunctionIdentifier().equals(BuiltinFunctions.DATASET);
+        }
+        if (op.getOperatorTag() == LogicalOperatorTag.SUBPLAN && containsDatasetAccess((SubplanOperator) op)) {
+            return true;
+        }
+        for (Mutable<ILogicalOperator> childRef : op.getInputs()) {
+            if (containsDatasetAccessInternal(childRef.getValue())) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlExpressionToPlanTranslator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlExpressionToPlanTranslator.java
index de17448..7d1ce7d 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlExpressionToPlanTranslator.java
@@ -169,13 +169,16 @@ class AqlExpressionToPlanTranslator extends LangExpressionToPlanTranslator imple
 
     @Override
     protected boolean expressionNeedsNoNesting(Expression expr) {
-        boolean noForFLWOR = false;
-        // No nesting is needed for a FLWOR expression without a FOR clause.
-        if (expr.getKind() == Kind.FLWOGR_EXPRESSION) {
+        boolean isFLWOGR = expr.getKind() == Kind.FLWOGR_EXPRESSION;
+        boolean letOnly = true;
+        // No nesting is needed for a FLWOR expression that only has LETs and RETURN.
+        if (isFLWOGR) {
             FLWOGRExpression flwor = (FLWOGRExpression) expr;
-            noForFLWOR = flwor.noForClause();
+            for (Clause clause : flwor.getClauseList()) {
+                letOnly &= clause.getClauseType() == Clause.ClauseType.LET_CLAUSE;
+            }
         }
-        return noForFLWOR || super.expressionNeedsNoNesting(expr);
+        return (isFLWOGR && letOnly) || super.expressionNeedsNoNesting(expr);
     }
 
     private Pair<ILogicalOperator, LogicalVariable> produceFlworPlan(boolean noForClause, boolean isTop,

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/CompiledStatements.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/CompiledStatements.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/CompiledStatements.java
index 98c717c..c21b5db 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/CompiledStatements.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/CompiledStatements.java
@@ -295,17 +295,17 @@ public class CompiledStatements {
         private final String datasetName;
         private final Query query;
         private final int varCounter;
-        VariableExpr var;
-        Query returnQuery;
+        private final VariableExpr var;
+        private final Expression returnExpression;
 
         public CompiledInsertStatement(String dataverseName, String datasetName, Query query, int varCounter,
-                VariableExpr var, Query returnQuery) {
+                VariableExpr var, Expression returnExpression) {
             this.dataverseName = dataverseName;
             this.datasetName = datasetName;
             this.query = query;
             this.varCounter = varCounter;
             this.var = var;
-            this.returnQuery = returnQuery;
+            this.returnExpression = returnExpression;
         }
 
         @Override
@@ -330,8 +330,8 @@ public class CompiledStatements {
             return var;
         }
 
-        public Query getReturnQuery() {
-            return returnQuery;
+        public Expression getReturnExpression() {
+            return returnExpression;
         }
 
         @Override
@@ -343,8 +343,8 @@ public class CompiledStatements {
     public static class CompiledUpsertStatement extends CompiledInsertStatement {
 
         public CompiledUpsertStatement(String dataverseName, String datasetName, Query query, int varCounter,
-                VariableExpr var, Query returnQuery) {
-            super(dataverseName, datasetName, query, varCounter, var, returnQuery);
+                VariableExpr var, Expression returnExpression) {
+            super(dataverseName, datasetName, query, varCounter, var, returnExpression);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
index fe5e590..cf722cc 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
@@ -71,6 +71,7 @@ import org.apache.asterix.lang.common.struct.OperatorType;
 import org.apache.asterix.lang.common.struct.QuantifiedPair;
 import org.apache.asterix.lang.common.util.FunctionUtil;
 import org.apache.asterix.lang.common.visitor.base.AbstractQueryExpressionVisitor;
+import org.apache.asterix.lang.sqlpp.clause.Projection;
 import org.apache.asterix.metadata.MetadataException;
 import org.apache.asterix.metadata.MetadataManager;
 import org.apache.asterix.metadata.declared.DataSource;
@@ -300,18 +301,12 @@ class LangExpressionToPlanTranslator
         Pair<ILogicalOperator, LogicalVariable> p = expr.accept(this, base);
         ArrayList<Mutable<ILogicalOperator>> globalPlanRoots = new ArrayList<>();
         ILogicalOperator topOp = p.first;
+        List<LogicalVariable> liveVars = new ArrayList<>();
+        VariableUtilities.getLiveVariables(topOp, liveVars);
+        LogicalVariable unnestVar = liveVars.get(0);
+        LogicalVariable resVar = unnestVar;
 
         if (outputDatasetName == null) {
-            LogicalVariable resVar;
-            if (topOp instanceof ProjectOperator) {
-                resVar = ((ProjectOperator) topOp).getVariables().get(0);
-            } else if (topOp instanceof AssignOperator) {
-                resVar = ((AssignOperator) topOp).getVariables().get(0);
-            } else if (topOp instanceof AggregateOperator) {
-                resVar = ((AggregateOperator) topOp).getVariables().get(0);
-            } else {
-                throw new AlgebricksException("Invalid returning query");
-            }
             FileSplit outputFileSplit = metadataProvider.getOutputFile();
             if (outputFileSplit == null) {
                 outputFileSplit = getDefaultOutputFileLocation();
@@ -333,10 +328,6 @@ class LangExpressionToPlanTranslator
                 topOp.getAnnotations().put("output-record-type", outputRecordType);
             }
         } else {
-            ProjectOperator project = (ProjectOperator) topOp;
-            LogicalVariable unnestVar = project.getVariables().get(0);
-            LogicalVariable resVar = project.getVariables().get(0);
-
             /**
              * add the collection-to-sequence right before the project,
              * because dataset only accept non-collection records
@@ -350,9 +341,10 @@ class LangExpressionToPlanTranslator
                     new MutableObject<>(new ScalarFunctionCallExpression(
                             FunctionUtil.getFunctionInfo(BuiltinFunctions.COLLECTION_TO_SEQUENCE),
                             new MutableObject<>(new VariableReferenceExpression(resVar)))));
-            assignCollectionToSequence.getInputs().add(new MutableObject<>(project.getInputs().get(0).getValue()));
-            project.getInputs().get(0).setValue(assignCollectionToSequence);
-            project.getVariables().set(0, seqVar);
+            assignCollectionToSequence.getInputs().add(new MutableObject<>(topOp.getInputs().get(0).getValue()));
+            topOp.getInputs().get(0).setValue(assignCollectionToSequence);
+            ProjectOperator projectOperator = (ProjectOperator) topOp;
+            projectOperator.getVariables().set(0, seqVar);
             resVar = seqVar;
             DatasetDataSource targetDatasource = validateDatasetInfo(metadataProvider, stmt.getDataverseName(),
                     stmt.getDatasetName());
@@ -391,10 +383,10 @@ class LangExpressionToPlanTranslator
 
                 additionalFilteringAssign = new AssignOperator(additionalFilteringVars,
                         additionalFilteringAssignExpressions);
-                additionalFilteringAssign.getInputs().add(new MutableObject<>(project));
+                additionalFilteringAssign.getInputs().add(new MutableObject<>(topOp));
                 assign.getInputs().add(new MutableObject<>(additionalFilteringAssign));
             } else {
-                assign.getInputs().add(new MutableObject<>(project));
+                assign.getInputs().add(new MutableObject<>(topOp));
             }
 
             Mutable<ILogicalExpression> varRef = new MutableObject<>(new VariableReferenceExpression(resVar));
@@ -406,7 +398,7 @@ class LangExpressionToPlanTranslator
                     break;
                 case Statement.Kind.UPSERT:
                     leafOperator = translateUpsert(targetDatasource, varRef, varRefsForLoading,
-                            additionalFilteringExpressions, assign, additionalFilteringField, unnestVar, project, exprs,
+                            additionalFilteringExpressions, assign, additionalFilteringField, unnestVar, topOp, exprs,
                             resVar, additionalFilteringAssign, stmt);
                     break;
                 case Statement.Kind.DELETE:
@@ -419,7 +411,7 @@ class LangExpressionToPlanTranslator
                     break;
                 case Statement.Kind.SUBSCRIBE_FEED:
                     leafOperator = translateSubscribeFeed((CompiledSubscribeFeedStatement) stmt, targetDatasource,
-                            unnestVar, project, exprs, resVar, varRefsForLoading, varRef, assign,
+                            unnestVar, topOp, exprs, resVar, varRefsForLoading, varRef, assign,
                             additionalFilteringField, additionalFilteringAssign, additionalFilteringExpressions);
                     break;
                 default:
@@ -463,7 +455,7 @@ class LangExpressionToPlanTranslator
     }
 
     private ILogicalOperator translateSubscribeFeed(CompiledSubscribeFeedStatement sfs,
-            DatasetDataSource targetDatasource, LogicalVariable unnestVar, ProjectOperator project,
+            DatasetDataSource targetDatasource, LogicalVariable unnestVar, ILogicalOperator topOp,
             ArrayList<Mutable<ILogicalExpression>> exprs, LogicalVariable resVar,
             List<Mutable<ILogicalExpression>> varRefsForLoading, Mutable<ILogicalExpression> varRef,
             ILogicalOperator assign, List<String> additionalFilteringField, AssignOperator additionalFilteringAssign,
@@ -478,6 +470,7 @@ class LangExpressionToPlanTranslator
         boolean isChangeFeed = ExternalDataUtils.isChangeFeed(feed.getAdapterConfiguration());
         boolean isUpsertFeed = ExternalDataUtils.isUpsertFeed(feed.getAdapterConfiguration());
 
+        ProjectOperator project = (ProjectOperator) topOp;
         if (targetDatasource.getDataset().hasMetaPart() || isChangeFeed) {
             metaAndKeysVars = new ArrayList<>();
             metaAndKeysExprs = new ArrayList<>();
@@ -546,8 +539,8 @@ class LangExpressionToPlanTranslator
         }
         if (targetDatasource.getDataset().hasMetaPart() || isChangeFeed) {
             metaAndKeysAssign = new AssignOperator(metaAndKeysVars, metaAndKeysExprs);
-            metaAndKeysAssign.getInputs().add(project.getInputs().get(0));
-            project.getInputs().set(0, new MutableObject<>(metaAndKeysAssign));
+            metaAndKeysAssign.getInputs().add(topOp.getInputs().get(0));
+            topOp.getInputs().set(0, new MutableObject<>(metaAndKeysAssign));
         }
         feedModificationOp.setAdditionalFilteringExpressions(additionalFilteringExpressions);
         ILogicalOperator leafOperator = new DelegateOperator(new CommitOperator(true));
@@ -558,18 +551,20 @@ class LangExpressionToPlanTranslator
     private ILogicalOperator translateUpsert(DatasetDataSource targetDatasource, Mutable<ILogicalExpression> varRef,
             List<Mutable<ILogicalExpression>> varRefsForLoading,
             List<Mutable<ILogicalExpression>> additionalFilteringExpressions, ILogicalOperator assign,
-            List<String> additionalFilteringField, LogicalVariable unnestVar, ProjectOperator project,
+            List<String> additionalFilteringField, LogicalVariable unnestVar, ILogicalOperator topOp,
             List<Mutable<ILogicalExpression>> exprs, LogicalVariable resVar, AssignOperator additionalFilteringAssign,
             ICompiledDmlStatement stmt) throws AlgebricksException {
-        if (!targetDatasource.getDataset().allow(project, Dataset.OP_UPSERT)) {
+        if (!targetDatasource.getDataset().allow(topOp, Dataset.OP_UPSERT)) {
             throw new AlgebricksException(targetDatasource.getDataset().getDatasetName()
                     + ": upsert into dataset is not supported on Datasets with Meta records");
         }
+        ProjectOperator project = (ProjectOperator) topOp;
         CompiledUpsertStatement compiledUpsert = (CompiledUpsertStatement) stmt;
+        Expression returnExpression = compiledUpsert.getReturnExpression();
         InsertDeleteUpsertOperator upsertOp;
-        ILogicalOperator leafOperator;
+        ILogicalOperator rootOperator;
         if (targetDatasource.getDataset().hasMetaPart()) {
-            if (compiledUpsert.getReturnQuery() != null) {
+            if (returnExpression != null) {
                 throw new AlgebricksException("Returning not allowed on datasets with Meta records");
 
             }
@@ -628,12 +623,9 @@ class LangExpressionToPlanTranslator
                 upsertOp.getInputs().add(assign.getInputs().get(0));
             }
             metaAndKeysAssign = new AssignOperator(metaAndKeysVars, metaAndKeysExprs);
-            metaAndKeysAssign.getInputs().add(project.getInputs().get(0));
-            project.getInputs().set(0, new MutableObject<>(metaAndKeysAssign));
+            metaAndKeysAssign.getInputs().add(topOp.getInputs().get(0));
+            topOp.getInputs().set(0, new MutableObject<>(metaAndKeysAssign));
             upsertOp.setAdditionalFilteringExpressions(additionalFilteringExpressions);
-            leafOperator = new DelegateOperator(new CommitOperator(true));
-            leafOperator.getInputs().add(new MutableObject<>(upsertOp));
-
         } else {
             upsertOp = new InsertDeleteUpsertOperator(targetDatasource, varRef, varRefsForLoading,
                     InsertDeleteUpsertOperator.Kind.UPSERT, false);
@@ -647,46 +639,13 @@ class LangExpressionToPlanTranslator
                 upsertOp.setPrevFilterVar(context.newVar());
                 upsertOp.setPrevFilterType(recordType.getFieldType(additionalFilteringField.get(0)));
             }
-
-            if (compiledUpsert.getReturnQuery() != null) {
-                leafOperator = createReturningQuery(compiledUpsert, upsertOp);
-
-            } else {
-                leafOperator = new DelegateOperator(new CommitOperator(true));
-                leafOperator.getInputs().add(new MutableObject<ILogicalOperator>(upsertOp));
-            }
         }
-        return leafOperator;
-
-    }
-
-    private ILogicalOperator createReturningQuery(CompiledInsertStatement compiledInsert,
-            InsertDeleteUpsertOperator insertOp) throws AlgebricksException {
-        //Make the id of the insert var point to the record variable
-        context.newVar(compiledInsert.getVar());
-        context.setVar(compiledInsert.getVar(),
-                ((VariableReferenceExpression) insertOp.getPayloadExpression().getValue()).getVariableReference());
-        // context
-
-        ILogicalPlan planAfterInsert = translate(compiledInsert.getReturnQuery(), null, null, insertOp);
+        rootOperator = new DelegateOperator(new CommitOperator(returnExpression == null));
+        rootOperator.getInputs().add(new MutableObject<>(upsertOp));
 
-        ILogicalOperator finalRoot = planAfterInsert.getRoots().get(0).getValue();
-        ILogicalOperator op;
-        for (op = finalRoot;; op = op.getInputs().get(0).getValue()) {
-            if (op.getInputs().size() != 1) {
-                throw new AlgebricksException("Cannot have a multi-branch returning query");
-            }
-            if (op.getInputs().get(0).getValue() instanceof InsertDeleteUpsertOperator) {
-                break;
-            }
-        }
+        // Compiles the return expression.
+        return processReturningExpression(rootOperator, upsertOp, compiledUpsert);
 
-        op.getInputs().clear();
-        ILogicalOperator leafOperator = new DelegateOperator(new CommitOperator(false));
-        leafOperator.getInputs().add(new MutableObject<ILogicalOperator>(insertOp));
-        op.getInputs().add(new MutableObject<>(leafOperator));
-        leafOperator = finalRoot;
-        return leafOperator;
     }
 
     private ILogicalOperator translateInsert(DatasetDataSource targetDatasource, Mutable<ILogicalExpression> varRef,
@@ -697,20 +656,52 @@ class LangExpressionToPlanTranslator
             throw new AlgebricksException(targetDatasource.getDataset().getDatasetName()
                     + ": insert into dataset is not supported on Datasets with Meta records");
         }
-        ILogicalOperator leafOperator;
+        // Adds the insert operator.
         InsertDeleteUpsertOperator insertOp = new InsertDeleteUpsertOperator(targetDatasource, varRef,
                 varRefsForLoading, InsertDeleteUpsertOperator.Kind.INSERT, false);
         insertOp.setAdditionalFilteringExpressions(additionalFilteringExpressions);
         insertOp.getInputs().add(new MutableObject<>(assign));
+
+        // Adds the commit operator.
         CompiledInsertStatement compiledInsert = (CompiledInsertStatement) stmt;
-        if (compiledInsert.getReturnQuery() != null) {
-            leafOperator = createReturningQuery(compiledInsert, insertOp);
+        Expression returnExpression = compiledInsert.getReturnExpression();
+        ILogicalOperator rootOperator = new DelegateOperator(
+                new CommitOperator(returnExpression == null ? true : false));
+        rootOperator.getInputs().add(new MutableObject<>(insertOp));
 
-        } else {
-            leafOperator = new DelegateOperator(new CommitOperator(true));
-            leafOperator.getInputs().add(new MutableObject<ILogicalOperator>(insertOp));
+        // Compiles the return expression.
+        return processReturningExpression(rootOperator, insertOp, compiledInsert);
+    }
+
+    // Stitches the translated operators for the returning expression into the query plan.
+    private ILogicalOperator processReturningExpression(ILogicalOperator inputOperator,
+            InsertDeleteUpsertOperator insertOp, CompiledInsertStatement compiledInsert) throws AlgebricksException {
+        Expression returnExpression = compiledInsert.getReturnExpression();
+        if (returnExpression == null) {
+            return inputOperator;
         }
-        return leafOperator;
+        ILogicalOperator rootOperator = inputOperator;
+
+        //Makes the id of the insert var point to the record variable.
+        context.newVar(compiledInsert.getVar());
+        context.setVar(compiledInsert.getVar(),
+                ((VariableReferenceExpression) insertOp.getPayloadExpression().getValue()).getVariableReference());
+        Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = langExprToAlgExpression(returnExpression,
+                    new MutableObject<>(rootOperator));
+
+        // Adds an assign operator for the returning expression.
+        LogicalVariable resultVar = context.newVar();
+        AssignOperator assignOperator = new AssignOperator(resultVar, new MutableObject<>(p.first));
+        assignOperator.getInputs().add(p.second);
+
+        // Adds a distribute result operator.
+        List<Mutable<ILogicalExpression>> expressions = new ArrayList<>();
+        expressions.add(new MutableObject<>(new VariableReferenceExpression(resultVar)));
+        ResultSetSinkId rssId = new ResultSetSinkId(metadataProvider.getResultSetId());
+        ResultSetDataSink sink = new ResultSetDataSink(rssId, null);
+        rootOperator = new DistributeResultOperator(expressions, sink);
+        rootOperator.getInputs().add(new MutableObject<>(assignOperator));
+        return rootOperator;
     }
 
     private DatasetDataSource validateDatasetInfo(MetadataProvider metadataProvider, String dataverseName,

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/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 643ba71..f9794e4 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
@@ -21,7 +21,6 @@ package org.apache.asterix.api.common;
 
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.rmi.Remote;
 import java.rmi.RemoteException;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -53,6 +52,7 @@ import org.apache.asterix.lang.common.base.IAstPrintVisitorFactory;
 import org.apache.asterix.lang.common.base.IQueryRewriter;
 import org.apache.asterix.lang.common.base.IRewriterFactory;
 import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.common.base.IReturningStatement;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
 import org.apache.asterix.lang.common.statement.FunctionDecl;
 import org.apache.asterix.lang.common.statement.Query;
@@ -145,8 +145,8 @@ public class APIFramework {
         }
     }
 
-    public Pair<Query, Integer> reWriteQuery(List<FunctionDecl> declaredFunctions, MetadataProvider metadataProvider,
-            Query q, SessionConfig conf) throws AsterixException {
+    public Pair<IReturningStatement, Integer> reWriteQuery(List<FunctionDecl> declaredFunctions,
+            MetadataProvider metadataProvider, IReturningStatement q, SessionConfig conf) throws AsterixException {
         if (q == null) {
             return null;
         }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
index 4fab8d7..906525c 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
@@ -90,6 +90,7 @@ import org.apache.asterix.lang.aql.statement.SubscribeFeedStatement;
 import org.apache.asterix.lang.common.base.IRewriterFactory;
 import org.apache.asterix.lang.common.base.IStatementRewriter;
 import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.common.base.IReturningStatement;
 import org.apache.asterix.lang.common.expression.TypeExpression;
 import org.apache.asterix.lang.common.statement.CompactStatement;
 import org.apache.asterix.lang.common.statement.ConnectFeedStatement;
@@ -340,7 +341,7 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
                         break;
                     case Statement.Kind.INSERT:
                     case Statement.Kind.UPSERT:
-                        if (((InsertStatement) stmt).getReturnQuery() != null) {
+                        if (((InsertStatement) stmt).getReturnExpression() != null) {
                             metadataProvider.setResultSetId(new ResultSetId(resultSetIdCounter++));
                             metadataProvider.setResultAsyncMode(resultDelivery == ResultDelivery.ASYNC
                                     || resultDelivery == ResultDelivery.DEFERRED);
@@ -1859,51 +1860,21 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
             IStatementExecutor.Stats stats, boolean compileOnly) throws Exception {
 
         InsertStatement stmtInsertUpsert = (InsertStatement) stmt;
-
         String dataverseName = getActiveDataverse(stmtInsertUpsert.getDataverseName());
         Query query = stmtInsertUpsert.getQuery();
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         boolean bActiveTxn = true;
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
-        if (stmtInsertUpsert.getReturnQuery() != null) {
-            if (!stmtInsertUpsert.getReturnQuery().getDatasets().isEmpty()) {
-                throw new AsterixException("Cannot use datasets in an insert returning query");
-            }
-            // returnQuery Rewriting (happens under the same ongoing metadata transaction)
-            Pair<Query, Integer> rewrittenReturnQuery = apiFramework.reWriteQuery(declaredFunctions, metadataProvider,
-                    stmtInsertUpsert.getReturnQuery(), sessionConfig);
-
-            stmtInsertUpsert.getQuery().setVarCounter(rewrittenReturnQuery.first.getVarCounter());
-            stmtInsertUpsert.setRewrittenReturnQuery(rewrittenReturnQuery.first);
-            stmtInsertUpsert.addToVarCounter(rewrittenReturnQuery.second);
-        }
-
         MetadataLockManager.INSTANCE.insertDeleteUpsertBegin(dataverseName,
                 dataverseName + "." + stmtInsertUpsert.getDatasetName(), query.getDataverses(), query.getDatasets());
         try {
             metadataProvider.setWriteTransaction(true);
-            CompiledInsertStatement clfrqs = null;
-            switch (stmtInsertUpsert.getKind()) {
-                case Statement.Kind.INSERT:
-                    clfrqs = new CompiledInsertStatement(dataverseName, stmtInsertUpsert.getDatasetName().getValue(),
-                            query, stmtInsertUpsert.getVarCounter(), stmtInsertUpsert.getVar(),
-                            stmtInsertUpsert.getReturnQuery());
-                    break;
-                case Statement.Kind.UPSERT:
-                    clfrqs = new CompiledUpsertStatement(dataverseName, stmtInsertUpsert.getDatasetName().getValue(),
-                            query, stmtInsertUpsert.getVarCounter(), stmtInsertUpsert.getVar(),
-                            stmtInsertUpsert.getReturnQuery());
-                    break;
-                default:
-                    throw new AlgebricksException("Unsupported statement type " + stmtInsertUpsert.getKind());
-            }
-            JobSpecification jobSpec = rewriteCompileQuery(hcc, metadataProvider, query, clfrqs);
-
+            JobSpecification jobSpec = rewriteCompileInsertUpsert(hcc, metadataProvider, stmtInsertUpsert);
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
             bActiveTxn = false;
 
             if (jobSpec != null && !compileOnly) {
-                if (stmtInsertUpsert.getReturnQuery() != null) {
+                if (stmtInsertUpsert.getReturnExpression() != null) {
                     handleQueryResult(metadataProvider, hcc, hdc, jobSpec, resultDelivery, stats);
                 } else {
                     JobUtils.runJob(hcc, jobSpec, true);
@@ -1964,18 +1935,46 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
     public JobSpecification rewriteCompileQuery(IClusterInfoCollector clusterInfoCollector,
             MetadataProvider metadataProvider, Query query,
             ICompiledDmlStatement stmt)
-            throws AsterixException, RemoteException, AlgebricksException, ACIDException {
+            throws RemoteException, AlgebricksException, ACIDException {
 
         // Query Rewriting (happens under the same ongoing metadata transaction)
-        Pair<Query, Integer> reWrittenQuery = apiFramework.reWriteQuery(declaredFunctions, metadataProvider, query,
-                sessionConfig);
+        Pair<IReturningStatement, Integer> rewrittenResult = apiFramework.reWriteQuery(declaredFunctions,
+                metadataProvider, query, sessionConfig);
 
         // Query Compilation (happens under the same ongoing metadata transaction)
-        JobSpecification spec = apiFramework.compileQuery(clusterInfoCollector, metadataProvider, reWrittenQuery.first,
-                reWrittenQuery.second, stmt == null ? null : stmt.getDatasetName(), sessionConfig, stmt);
-
-        return spec;
+        return apiFramework.compileQuery(clusterInfoCollector, metadataProvider, (Query) rewrittenResult.first,
+                rewrittenResult.second, stmt == null ? null : stmt.getDatasetName(), sessionConfig, stmt);
+    }
 
+    private JobSpecification rewriteCompileInsertUpsert(IClusterInfoCollector clusterInfoCollector,
+            MetadataProvider metadataProvider, InsertStatement insertUpsert)
+            throws RemoteException, AlgebricksException, ACIDException {
+
+        // Insert/upsert statement rewriting (happens under the same ongoing metadata transaction)
+        Pair<IReturningStatement, Integer> rewrittenResult = apiFramework.reWriteQuery(declaredFunctions,
+                metadataProvider, insertUpsert, sessionConfig);
+
+        InsertStatement rewrittenInsertUpsert = (InsertStatement) rewrittenResult.first;
+        String dataverseName = getActiveDataverse(rewrittenInsertUpsert.getDataverseName());
+        String datasetName = rewrittenInsertUpsert.getDatasetName().getValue();
+        CompiledInsertStatement clfrqs;
+        switch (insertUpsert.getKind()) {
+            case Statement.Kind.INSERT:
+                clfrqs = new CompiledInsertStatement(dataverseName, datasetName, rewrittenInsertUpsert.getQuery(),
+                        rewrittenInsertUpsert.getVarCounter(), rewrittenInsertUpsert.getVar(),
+                        rewrittenInsertUpsert.getReturnExpression());
+                break;
+            case Statement.Kind.UPSERT:
+                clfrqs = new CompiledUpsertStatement(dataverseName, datasetName, rewrittenInsertUpsert.getQuery(),
+                        rewrittenInsertUpsert.getVarCounter(), rewrittenInsertUpsert.getVar(),
+                        rewrittenInsertUpsert.getReturnExpression());
+                break;
+            default:
+                throw new AlgebricksException("Unsupported statement type " + rewrittenInsertUpsert.getKind());
+        }
+        // Insert/upsert statement compilation (happens under the same ongoing metadata transaction)
+        return apiFramework.compileQuery(clusterInfoCollector, metadataProvider, rewrittenInsertUpsert.getQuery(),
+                rewrittenResult.second, datasetName, sessionConfig, clfrqs);
     }
 
     protected void handleCreateFeedStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
index 5ede01c..2b9b357 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
@@ -185,7 +185,8 @@ public class ParserTestExecutor extends TestExecutor {
     private void rewrite(IQueryRewriter rewriter, List<FunctionDecl> declaredFunctions, Query topExpr,
             MetadataProvider metadataProvider, LangRewritingContext context) throws AsterixException {
         PA.invokeMethod(rewriter,
-                "setup(java.util.List, org.apache.asterix.lang.common.statement.Query, org.apache.asterix.metadata.declared.MetadataProvider, "
+                "setup(java.util.List, org.apache.asterix.lang.common.base.IReturningStatement, "
+                        + "org.apache.asterix.metadata.declared.MetadataProvider, "
                         + "org.apache.asterix.lang.common.rewrites.LangRewritingContext)",
                 declaredFunctions, topExpr, metadataProvider, context);
         PA.invokeMethod(rewriter, "inlineColumnAlias()");

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/optimizerts/results/insert-return-custom-result.plan
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/insert-return-custom-result.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/insert-return-custom-result.plan
index 391b248..ef733cb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/insert-return-custom-result.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/insert-return-custom-result.plan
@@ -1,17 +1,20 @@
 -- DISTRIBUTE_RESULT  |PARTITIONED|
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
-      -- ASSIGN  |PARTITIONED|
-        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- STABLE_SORT [$$16(ASC)]  |PARTITIONED|
+      -- SUBPLAN  |PARTITIONED|
+              {
+                -- ASSIGN  |LOCAL|
+                  -- ASSIGN  |LOCAL|
+                    -- IN_MEMORY_STABLE_SORT [$$16(ASC)]  |LOCAL|
+                      -- NESTED_TUPLE_SOURCE  |LOCAL|
+              }
+        -- COMMIT  |PARTITIONED|
+          -- STREAM_PROJECT  |PARTITIONED|
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- COMMIT  |PARTITIONED|
-                -- STREAM_PROJECT  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- INSERT_DELETE  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$16]  |PARTITIONED|
+              -- INSERT_DELETE  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$16]  |PARTITIONED|
+                  -- ASSIGN  |UNPARTITIONED|
+                    -- STREAM_PROJECT  |UNPARTITIONED|
+                      -- UNNEST  |UNPARTITIONED|
                         -- ASSIGN  |UNPARTITIONED|
-                          -- STREAM_PROJECT  |UNPARTITIONED|
-                            -- UNNEST  |UNPARTITIONED|
-                              -- ASSIGN  |UNPARTITIONED|
-                                -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
\ No newline at end of file
+                          -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.1.ddl.aql
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.1.ddl.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.1.ddl.aql
new file mode 100644
index 0000000..9e77afb
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.1.ddl.aql
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-returning-fieldname
+ * Description     : Check fields returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type TweetMessageTypeuuid as closed {
+  tweetid: uuid,
+  message-text: string
+}
+
+create dataset TweetMessageuuids(TweetMessageTypeuuid)
+primary key tweetid autogenerated;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.3.query.aql
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.3.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.3.query.aql
new file mode 100644
index 0000000..8e9cff5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.3.query.aql
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-returning-fieldname
+ * Description     : Check fields returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+use dataverse test;
+
+insert into dataset TweetMessageuuids (
+     { "message-text":"hello"}
+) returning 1;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-udf/insert-returning-udf.1.ddl.aql
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-udf/insert-returning-udf.1.ddl.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-udf/insert-returning-udf.1.ddl.aql
new file mode 100644
index 0000000..f579a73
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-udf/insert-returning-udf.1.ddl.aql
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-returning-fieldname
+ * Description     : Check fields returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type TweetMessageTypeuuid as closed {
+  tweetid: uuid,
+  message-text: string
+}
+
+create dataset TweetMessageuuids(TweetMessageTypeuuid)
+primary key tweetid autogenerated;
+
+create function project($foo){
+    let $result := $foo.message-text
+    return $result
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-udf/insert-returning-udf.3.query.aql
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-udf/insert-returning-udf.3.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-udf/insert-returning-udf.3.query.aql
new file mode 100644
index 0000000..ecbb50d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/insert-returning-udf/insert-returning-udf.3.query.aql
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-returning-fieldname
+ * Description     : Check fields returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+use dataverse test;
+
+insert into dataset TweetMessageuuids as $message (
+{ "message-text":"hello"}
+) returning project($message);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/upsert-return-custom-result/upsert-return-custom-result.3.query.aql
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/upsert-return-custom-result/upsert-return-custom-result.3.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/upsert-return-custom-result/upsert-return-custom-result.3.query.aql
index 9abf667..45a9595 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/upsert-return-custom-result/upsert-return-custom-result.3.query.aql
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/dml/upsert-return-custom-result/upsert-return-custom-result.3.query.aql
@@ -23,7 +23,7 @@
  * Date            : Mar 2015
  */
 
- use dataverse test;
+use dataverse test;
 
 upsert into dataset TweetMessageuuids as $a (
 let $x :=
@@ -33,6 +33,7 @@ let $x :=
 {"tweetid":4,"message-text":"what","location":create-point(3.0,6.0)},
 {"tweetid":5,"message-text":"good","location":create-point(5.0,6.0)}]
 for $y in $x
+where $y.tweetid=5
 return $y
 ) returning
 let $x := create-circle($a.location,5.0)

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-return-records/insert-return-records.1.ddl.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-return-records/insert-return-records.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-return-records/insert-return-records.1.ddl.sqlpp
new file mode 100644
index 0000000..5c66655
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-return-records/insert-return-records.1.ddl.sqlpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-return-records
+ * Description     : Check records returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type TweetMessageTypeuuid as closed {
+  tweetid: int,
+  `message-text`: string
+}
+
+create dataset TweetMessageuuids(TweetMessageTypeuuid)
+primary key tweetid;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-return-records/insert-return-records.3.query.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-return-records/insert-return-records.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-return-records/insert-return-records.3.query.sqlpp
new file mode 100644
index 0000000..09a3b59
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-return-records/insert-return-records.3.query.sqlpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-return-records
+ * Description     : Check records returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+use test;
+
+insert into TweetMessageuuids as message (
+    [
+     { "tweetid":1,"message-text":"hello"},
+     {"tweetid":2,"message-text":"goodbye"},
+     {"tweetid":3,"message-text":"the end"},
+     {"tweetid":4,"message-text":"what"},
+     {"tweetid":5,"message-text":"good"}
+    ]
+) returning message;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.1.ddl.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.1.ddl.sqlpp
new file mode 100644
index 0000000..f20fcbe
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.1.ddl.sqlpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-returning-fieldname
+ * Description     : Check fields returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type TweetMessageTypeuuid as closed {
+  tweetid: uuid,
+  `message-text`: string
+}
+
+create dataset TweetMessageuuids(TweetMessageTypeuuid)
+primary key tweetid autogenerated;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.3.query.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.3.query.sqlpp
new file mode 100644
index 0000000..c8d14e9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname-implicit/insert-returning-fieldname-implicit.3.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-returning-fieldname
+ * Description     : Check fields returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+use test;
+
+insert into TweetMessageuuids (
+     { "message-text":"hello"}
+) returning `message-text`;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname/insert-returning-fieldname.1.ddl.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname/insert-returning-fieldname.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname/insert-returning-fieldname.1.ddl.sqlpp
new file mode 100644
index 0000000..f20fcbe
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname/insert-returning-fieldname.1.ddl.sqlpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-returning-fieldname
+ * Description     : Check fields returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type TweetMessageTypeuuid as closed {
+  tweetid: uuid,
+  `message-text`: string
+}
+
+create dataset TweetMessageuuids(TweetMessageTypeuuid)
+primary key tweetid autogenerated;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname/insert-returning-fieldname.3.query.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname/insert-returning-fieldname.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname/insert-returning-fieldname.3.query.sqlpp
new file mode 100644
index 0000000..d56a954
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-fieldname/insert-returning-fieldname.3.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-returning-fieldname
+ * Description     : Check fields returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+use test;
+
+insert into TweetMessageuuids as message (
+     { "message-text":"hello"}
+) returning message.`message-text`;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-udf/insert-returning-udf.1.ddl.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-udf/insert-returning-udf.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-udf/insert-returning-udf.1.ddl.sqlpp
new file mode 100644
index 0000000..885c347
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-udf/insert-returning-udf.1.ddl.sqlpp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-returning-fieldname
+ * Description     : Check fields returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type TweetMessageTypeuuid as closed {
+  tweetid: uuid,
+  `message-text`: string
+}
+
+create dataset TweetMessageuuids(TweetMessageTypeuuid)
+primary key tweetid autogenerated;
+
+create function project(foo){
+    foo.`message-text`
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-udf/insert-returning-udf.3.query.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-udf/insert-returning-udf.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-udf/insert-returning-udf.3.query.sqlpp
new file mode 100644
index 0000000..2d2d70f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-returning-udf/insert-returning-udf.3.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-returning-fieldname
+ * Description     : Check fields returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+use test;
+
+insert into TweetMessageuuids as message (
+     { "message-text":"hello"}
+) returning project(message);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-with-bad-return/insert-with-bad-return.1.ddl.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-with-bad-return/insert-with-bad-return.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-with-bad-return/insert-with-bad-return.1.ddl.sqlpp
new file mode 100644
index 0000000..5c66655
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-with-bad-return/insert-with-bad-return.1.ddl.sqlpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-return-records
+ * Description     : Check records returned on insert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type TweetMessageTypeuuid as closed {
+  tweetid: int,
+  `message-text`: string
+}
+
+create dataset TweetMessageuuids(TweetMessageTypeuuid)
+primary key tweetid;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-with-bad-return/insert-with-bad-return.3.query.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-with-bad-return/insert-with-bad-return.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-with-bad-return/insert-with-bad-return.3.query.sqlpp
new file mode 100644
index 0000000..aa91b42
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-with-bad-return/insert-with-bad-return.3.query.sqlpp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : insert-with-bad-return
+ * Description     : Throw an error
+ * Expected Result : Error
+ * Date            : Oct 2016
+ */
+
+use test;
+
+insert into TweetMessageuuids as message (
+    [
+       { "tweetid":1,"message-text":"hello"},
+       {"tweetid":2,"message-text":"goodbye"},
+       {"tweetid":3,"message-text":"the end"},
+       {"tweetid":4,"message-text":"what"},
+       {"tweetid":5,"message-text":"good"}
+    ]
+) returning
+(
+ from TweetMessageuuids as result
+ where result.`message-text`=message
+ select value result
+);

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-dataset-with-meta/upsert-dataset-with-meta.1.ddl.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-dataset-with-meta/upsert-dataset-with-meta.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-dataset-with-meta/upsert-dataset-with-meta.1.ddl.sqlpp
new file mode 100644
index 0000000..d77f990
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-dataset-with-meta/upsert-dataset-with-meta.1.ddl.sqlpp
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * Description  : Upsert into a dataset with meta type
+ * Expected Res : Failure
+ * Date         : 15th Mar 2016
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type RecordType as open{
+};
+
+create type MetaType as open{
+id:string
+};
+
+create dataset DatasetWithMeta(RecordType) with meta(MetaType)primary key meta().id;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-dataset-with-meta/upsert-dataset-with-meta.2.update.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-dataset-with-meta/upsert-dataset-with-meta.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-dataset-with-meta/upsert-dataset-with-meta.2.update.sqlpp
new file mode 100644
index 0000000..af7ab4b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-dataset-with-meta/upsert-dataset-with-meta.2.update.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * Description  : Upsert into a dataset with meta type
+ * Expected Res : Failure
+ * Date         : 15th Mar 2016
+ */
+
+use test;
+
+upsert into DatasetWithMeta (
+{"id": 2, "name": "Person Two", "hobbies": {{"Rock", "Jazz"}}}
+);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/cb5bf33d/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-return-custom-result/upsert-return-custom-result.1.ddl.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-return-custom-result/upsert-return-custom-result.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-return-custom-result/upsert-return-custom-result.1.ddl.sqlpp
new file mode 100644
index 0000000..40768db
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/upsert-return-custom-result/upsert-return-custom-result.1.ddl.sqlpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name  : upsert-return-custom-result
+ * Description     : Check records returned on upsert
+ * Expected Result : Success
+ * Date            : Mar 2015
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type TweetMessageTypeuuid as closed {
+  tweetid: int,
+  `message-text`: string,
+  location:point
+}
+
+create dataset TweetMessageuuids(TweetMessageTypeuuid)
+primary key tweetid;
\ No newline at end of file


Mime
View raw message