Yingyi Bu has uploaded a new change for review.

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

Change subject: Add a REST endpoint for query cancellation.
......................................................................

Add a REST endpoint for query cancellation.

Change-Id: I2936ac83f71bbef533e2695ed0a2b220c23fc483
---
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutor.java
A 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutorContext.java
A 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/ctx/StatementExecutorContext.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
A 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryCancellationServlet.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/RestApiServlet.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ServletConstants.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java
A 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/CancellationTestExecutor.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/APIExecutionTest.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionFullParallelismIT.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionLessParallelismIT.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionTest.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateDefaultParameterTest.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateExecutionFullParallelismTest.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateExecutionLessParallelismTest.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/LangExecutionUtil.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionFullParallelismIT.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionLessParallelismIT.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionTest.java
A 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionWithCancellationTest.java
M 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/any-object/any-object.2.query.sqlpp
M 
asterixdb/asterix-app/src/test/resources/runtimets/results/types/any-object/any-object.2.adm
M 
asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetLifecycleManager.java
M 
asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/Info.java
M 
asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/Servlets.java
M 
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
M 
hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/FileHandle.java
M 
hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/IOManager.java
M 
hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/partitions/MaterializingPipelinedPartition.java
M 
hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/partitions/PipelinedPartition.java
M 
hyracks-fullstack/hyracks/hyracks-dataflow-common/src/main/java/org/apache/hyracks/dataflow/common/io/RunFileReader.java
M 
hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/connectors/PartitionDataWriter.java
M 
hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/sort/AbstractExternalSortRunMerger.java
M 
hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java
M 
hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexSearchOperatorNodePushable.java
M 
hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorNodePushable.java
M 
hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/dataflow/LSMIndexCompactOperatorNodePushable.java
43 files changed, 688 insertions(+), 258 deletions(-)


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

diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutor.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutor.java
index 2066f73..8156be1 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutor.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutor.java
@@ -85,26 +85,12 @@
      *            A Hyracks dataset client object that is used to read the 
results.
      * @param resultDelivery
      *            The {@code ResultDelivery} kind required for queries in the 
list of statements
-     * @throws Exception
-     */
-    void compileAndExecute(IHyracksClientConnection hcc, IHyracksDataset hdc, 
ResultDelivery resultDelivery)
-            throws Exception;
-
-    /**
-     * Compiles and execute a list of statements.
-     *
-     * @param hcc
-     *            A Hyracks client connection that is used to submit a jobspec 
to Hyracks.
-     * @param hdc
-     *            A Hyracks dataset client object that is used to read the 
results.
-     * @param resultDelivery
-     *            The {@code ResultDelivery} kind required for queries in the 
list of statements
      * @param stats
      *            a reference to write the stats of executed queries
      * @throws Exception
      */
     void compileAndExecute(IHyracksClientConnection hcc, IHyracksDataset hdc, 
ResultDelivery resultDelivery,
-            Stats stats) throws Exception;
+            Stats stats, String clientContextId, IStatementExecutorContext 
ctx) throws Exception;
 
     /**
      * rewrites and compiles query into a hyracks job specifications
diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutorContext.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutorContext.java
new file mode 100644
index 0000000..9e4f564
--- /dev/null
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IStatementExecutorContext.java
@@ -0,0 +1,31 @@
+/*
+ * 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.hyracks.api.job.JobId;
+
+public interface IStatementExecutorContext {
+
+    JobId get(String clientContextId);
+
+    void put(String clientContextId, JobId jobId);
+
+    void remove(String clientContextId);
+}
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/ctx/StatementExecutorContext.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/ctx/StatementExecutorContext.java
new file mode 100644
index 0000000..fd4d1d8
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/ctx/StatementExecutorContext.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.api.http.ctx;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.asterix.translator.IStatementExecutorContext;
+import org.apache.hyracks.api.job.JobId;
+
+public class StatementExecutorContext implements IStatementExecutorContext {
+
+    private final Map<String, JobId> activeQueries = new ConcurrentHashMap<>();
+
+    @Override
+    public JobId get(String clientContextId) {
+        return activeQueries.get(clientContextId);
+    }
+
+    @Override
+    public void put(String clientContextId, JobId jobId) {
+        activeQueries.put(clientContextId, jobId);
+    }
+
+    @Override
+    public void remove(String clientContextId) {
+        activeQueries.remove(clientContextId);
+    }
+}
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
index 7a33c0e..5ad0943 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
@@ -145,7 +145,8 @@
                     compilationProvider, componentProvider);
             double duration;
             long startTime = System.currentTimeMillis();
-            translator.compileAndExecute(hcc, hds, 
IStatementExecutor.ResultDelivery.IMMEDIATE);
+            translator.compileAndExecute(hcc, hds, 
IStatementExecutor.ResultDelivery.IMMEDIATE,
+                    new IStatementExecutor.Stats(), null, null);
             long endTime = System.currentTimeMillis();
             duration = (endTime - startTime) / 1000.00;
             out.println(HTML_STATEMENT_SEPARATOR);
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryCancellationServlet.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryCancellationServlet.java
new file mode 100644
index 0000000..e7f9185
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryCancellationServlet.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.api.http.server;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.asterix.api.http.servlet.ServletConstants;
+import org.apache.asterix.translator.IStatementExecutorContext;
+import org.apache.hyracks.api.client.IHyracksClientConnection;
+import org.apache.hyracks.api.job.JobId;
+import org.apache.hyracks.http.api.IServletRequest;
+import org.apache.hyracks.http.api.IServletResponse;
+import org.apache.hyracks.http.server.AbstractServlet;
+import org.apache.hyracks.http.server.utils.HttpUtil;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+
+public class QueryCancellationServlet extends AbstractServlet {
+    private static final Logger LOGGER = 
Logger.getLogger(QueryCancellationServlet.class.getName());
+    private static final String CLIENT_CONTEXT_ID = "client_context_id";
+    private static final String JOB_ID = "jobId";
+    private static final String CANCELLED = "cancelled";
+
+    public QueryCancellationServlet(ConcurrentMap<String, Object> ctx, 
String[] paths) {
+        super(ctx, paths);
+    }
+
+    @Override
+    protected void post(IServletRequest request, IServletResponse response) 
throws IOException {
+        // Parses clientContextId from the request uri.
+        String requestURI = request.getHttpRequest().uri().toString();
+        String clientContextId = 
requestURI.substring(requestURI.lastIndexOf('/') + 1);
+
+        // Retrieves the corresponding Hyracks job id.
+        IStatementExecutorContext activeQueries = (IStatementExecutorContext) 
ctx
+                .get(ServletConstants.ACTIVE_QUERIES_ATTR);
+        IHyracksClientConnection hcc = (IHyracksClientConnection) 
ctx.get(ServletConstants.HYRACKS_CONNECTION_ATTR);
+        JobId jobId = activeQueries.get(clientContextId);
+
+        // Creates the response data.
+        ObjectMapper om = new ObjectMapper();
+        om.enable(SerializationFeature.INDENT_OUTPUT);
+        ObjectNode result = om.createObjectNode();
+        result.put(CLIENT_CONTEXT_ID, clientContextId);
+
+        // Gets the response writer.
+        response.setStatus(HttpResponseStatus.OK);
+        HttpUtil.setContentType(response, 
HttpUtil.ContentType.APPLICATION_JSON, HttpUtil.Encoding.UTF8);
+        PrintWriter responseWriter = response.writer();
+        if (jobId == null) {
+            // Writes the result.
+            result.put(JOB_ID, "null");
+            
responseWriter.write(om.writerWithDefaultPrettyPrinter().writeValueAsString(result));
+            return;
+        }
+
+        try {
+            // Cancels the ongoing job.
+            hcc.cancelJob(jobId);
+
+            // Adds response fields for the case of success.
+            result.put(JOB_ID, jobId.getId());
+            result.put(CANCELLED, true);
+
+            // Removes the cancelled query.
+            activeQueries.remove(clientContextId);
+        } catch (Exception e) {
+            if (LOGGER.isLoggable(Level.WARNING)) {
+                LOGGER.log(Level.WARNING, e.getMessage(), e);
+            }
+            // Adds response fields for the case of failure.
+            result.put(CANCELLED, false);
+            response.setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR);
+        } finally {
+            // Writes the result.
+            
responseWriter.write(om.writerWithDefaultPrettyPrinter().writeValueAsString(result));
+        }
+    }
+}
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
index 9d22452..fd82e41 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
@@ -29,6 +29,8 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.apache.asterix.api.http.ctx.StatementExecutorContext;
+import org.apache.asterix.api.http.servlet.ServletConstants;
 import org.apache.asterix.app.result.ResultUtil;
 import org.apache.asterix.common.api.IClusterManagementWork;
 import org.apache.asterix.common.config.GlobalConfig;
@@ -43,6 +45,7 @@
 import org.apache.asterix.runtime.utils.ClusterStateManager;
 import org.apache.asterix.translator.IStatementExecutor;
 import org.apache.asterix.translator.IStatementExecutor.Stats;
+import org.apache.asterix.translator.IStatementExecutorContext;
 import org.apache.asterix.translator.IStatementExecutorFactory;
 import org.apache.asterix.translator.SessionConfig;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -65,6 +68,7 @@
     private final ILangCompilationProvider compilationProvider;
     private final IStatementExecutorFactory statementExecutorFactory;
     private final IStorageComponentProvider componentProvider;
+    private final IStatementExecutorContext queryCtx = new 
StatementExecutorContext();
 
     public QueryServiceServlet(ConcurrentMap<String, Object> ctx, String[] 
paths,
             ILangCompilationProvider compilationProvider, 
IStatementExecutorFactory statementExecutorFactory,
@@ -73,6 +77,7 @@
         this.compilationProvider = compilationProvider;
         this.statementExecutorFactory = statementExecutorFactory;
         this.componentProvider = componentProvider;
+        ctx.put(ServletConstants.ACTIVE_QUERIES_ATTR, queryCtx);
     }
 
     @Override
@@ -425,7 +430,8 @@
             IStatementExecutor translator =
                     statementExecutorFactory.create(statements, sessionConfig, 
compilationProvider, componentProvider);
             execStart = System.nanoTime();
-            translator.compileAndExecute(getHyracksClientConnection(), 
getHyracksDataset(), delivery, stats);
+            translator.compileAndExecute(getHyracksClientConnection(), 
getHyracksDataset(), delivery, stats,
+                    param.clientContextID, queryCtx);
             execEnd = System.nanoTime();
             printStatus(resultWriter, ResultDelivery.ASYNC == delivery ? 
ResultStatus.RUNNING : ResultStatus.SUCCESS);
         } catch (AsterixException | TokenMgrError | 
org.apache.asterix.aqlplus.parser.TokenMgrError pe) {
@@ -459,4 +465,4 @@
             LOGGER.warning("Error flushing output writer");
         }
     }
-}
+}
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/RestApiServlet.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/RestApiServlet.java
index bdc9d62..d32f51c 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/RestApiServlet.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/RestApiServlet.java
@@ -203,7 +203,7 @@
             MetadataManager.INSTANCE.init();
             IStatementExecutor translator = 
statementExecutorFactory.create(aqlStatements, sessionConfig,
                     compilationProvider, componentProvider);
-            translator.compileAndExecute(hcc, hds, resultDelivery);
+            translator.compileAndExecute(hcc, hds, resultDelivery, new 
IStatementExecutor.Stats(), null, null);
         } catch (AsterixException | TokenMgrError | 
org.apache.asterix.aqlplus.parser.TokenMgrError pe) {
             response.setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR);
             GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, pe.getMessage(), pe);
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ServletConstants.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ServletConstants.java
index 5b96cab..f5f6572 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ServletConstants.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ServletConstants.java
@@ -23,6 +23,7 @@
     public static final String HYRACKS_DATASET_ATTR = 
"org.apache.asterix.HYRACKS_DATASET";
     public static final String ASTERIX_APP_CONTEXT_INFO_ATTR = 
"org.apache.asterix.APP_CONTEXT_INFO";
     public static final String EXECUTOR_SERVICE = 
"org.apache.asterix.EXECUTOR_SERVICE";
+    public static final String ACTIVE_QUERIES_ATTR = 
"org.apache.asterix.ACTIVE_QUERIES";
 
     private ServletConstants() {
     }
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
index c09f8cb..7ac3cfb 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
@@ -104,7 +104,8 @@
 
         IStatementExecutor translator =
                 statementExecutorFactory.create(statements, conf, 
compilationProvider, storageComponentProvider);
-        translator.compileAndExecute(hcc, null, 
QueryTranslator.ResultDelivery.IMMEDIATE);
+        translator.compileAndExecute(hcc, null, 
QueryTranslator.ResultDelivery.IMMEDIATE,
+                new IStatementExecutor.Stats(), null, null);
         writer.flush();
     }
 
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 1e4d866..92119a1 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
@@ -156,6 +156,7 @@
 import 
org.apache.asterix.translator.CompiledStatements.CompiledUpsertStatement;
 import org.apache.asterix.translator.CompiledStatements.ICompiledDmlStatement;
 import org.apache.asterix.translator.IStatementExecutor;
+import org.apache.asterix.translator.IStatementExecutorContext;
 import org.apache.asterix.translator.SessionConfig;
 import org.apache.asterix.translator.TypeTranslator;
 import org.apache.asterix.translator.util.ValidateUtil;
@@ -232,27 +233,9 @@
         return functionDecls;
     }
 
-    /**
-     * Compiles and submits for execution a list of AQL statements.
-     *
-     * @param hcc
-     *            A Hyracks client connection that is used to submit a jobspec 
to Hyracks.
-     * @param hdc
-     *            A Hyracks dataset client object that is used to read the 
results.
-     * @param resultDelivery
-     *            True if the results should be read asynchronously or false 
if we should wait for results to be read.
-     * @return A List<QueryResult> containing a QueryResult instance 
corresponding to each submitted query.
-     * @throws Exception
-     */
-    @Override
-    public void compileAndExecute(IHyracksClientConnection hcc, 
IHyracksDataset hdc, ResultDelivery resultDelivery)
-            throws Exception {
-        compileAndExecute(hcc, hdc, resultDelivery, new Stats());
-    }
-
     @Override
     public void compileAndExecute(IHyracksClientConnection hcc, 
IHyracksDataset hdc, ResultDelivery resultDelivery,
-            Stats stats) throws Exception {
+            Stats stats, String clientContextId, IStatementExecutorContext 
ctx) throws Exception {
         int resultSetIdCounter = 0;
         FileSplit outputFile = null;
         IAWriterFactory writerFactory = PrinterBasedWriterFactory.INSTANCE;
@@ -329,7 +312,8 @@
                             metadataProvider.setResultAsyncMode(resultDelivery 
== ResultDelivery.ASYNC
                                     || resultDelivery == 
ResultDelivery.DEFERRED);
                         }
-                        handleInsertUpsertStatement(metadataProvider, stmt, 
hcc, hdc, resultDelivery, stats, false);
+                        handleInsertUpsertStatement(metadataProvider, stmt, 
hcc, hdc, resultDelivery, stats, false,
+                                clientContextId, ctx);
                         break;
                     case Statement.Kind.DELETE:
                         handleDeleteStatement(metadataProvider, stmt, hcc, 
false);
@@ -362,7 +346,8 @@
                         metadataProvider.setResultSetId(new 
ResultSetId(resultSetIdCounter++));
                         metadataProvider.setResultAsyncMode(
                                 resultDelivery == ResultDelivery.ASYNC || 
resultDelivery == ResultDelivery.DEFERRED);
-                        handleQuery(metadataProvider, (Query) stmt, hcc, hdc, 
resultDelivery, stats);
+                        handleQuery(metadataProvider, (Query) stmt, hcc, hdc, 
resultDelivery, stats, clientContextId,
+                                ctx);
                         break;
                     case Statement.Kind.COMPACT:
                         handleCompactStatement(metadataProvider, stmt, hcc);
@@ -1809,8 +1794,8 @@
 
     public JobSpecification handleInsertUpsertStatement(MetadataProvider 
metadataProvider, Statement stmt,
             IHyracksClientConnection hcc, IHyracksDataset hdc, ResultDelivery 
resultDelivery,
-            IStatementExecutor.Stats stats, boolean compileOnly) throws 
Exception {
-
+            IStatementExecutor.Stats stats, boolean compileOnly, String 
clientContextId, IStatementExecutorContext ctx)
+            throws Exception {
         InsertStatement stmtInsertUpsert = (InsertStatement) stmt;
         String dataverseName = 
getActiveDataverse(stmtInsertUpsert.getDataverseName());
         Query query = stmtInsertUpsert.getQuery();
@@ -1852,7 +1837,7 @@
         }
 
         if (stmtInsertUpsert.getReturnExpression() != null) {
-            deliverResult(hcc, hdc, compiler, metadataProvider, locker, 
resultDelivery, stats);
+            deliverResult(hcc, hdc, compiler, metadataProvider, locker, 
resultDelivery, stats, clientContextId, ctx);
         } else {
             locker.lock();
             try {
@@ -2371,7 +2356,8 @@
     }
 
     protected void handleQuery(MetadataProvider metadataProvider, Query query, 
IHyracksClientConnection hcc,
-            IHyracksDataset hdc, ResultDelivery resultDelivery, Stats stats) 
throws Exception {
+            IHyracksDataset hdc, ResultDelivery resultDelivery, Stats stats, 
String clientContextId,
+            IStatementExecutorContext ctx) throws Exception {
         final IMetadataLocker locker = new IMetadataLocker() {
             @Override
             public void lock() {
@@ -2402,11 +2388,12 @@
                 throw e;
             }
         };
-        deliverResult(hcc, hdc, compiler, metadataProvider, locker, 
resultDelivery, stats);
+        deliverResult(hcc, hdc, compiler, metadataProvider, locker, 
resultDelivery, stats, clientContextId, ctx);
     }
 
     private void deliverResult(IHyracksClientConnection hcc, IHyracksDataset 
hdc, IStatementCompiler compiler,
-            MetadataProvider metadataProvider, IMetadataLocker locker, 
ResultDelivery resultDelivery, Stats stats)
+            MetadataProvider metadataProvider, IMetadataLocker locker, 
ResultDelivery resultDelivery, Stats stats,
+            String clientContextId, IStatementExecutorContext ctx)
             throws Exception {
         final ResultSetId resultSetId = metadataProvider.getResultSetId();
         switch (resultDelivery) {
@@ -2422,7 +2409,7 @@
                                 printed.setTrue();
                                 printed.notify();
                             }
-                        });
+                        }, clientContextId, ctx);
                     } catch (Exception e) {
                         GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE,
                                 resultDelivery.name() + " job " + "with id " + 
jobId + " failed", e);
@@ -2439,12 +2426,12 @@
                     final ResultReader resultReader = new ResultReader(hdc, 
id, resultSetId);
                     ResultUtil.printResults(resultReader, sessionConfig, stats,
                             metadataProvider.findOutputRecordType());
-                });
+                }, clientContextId, ctx);
                 break;
             case DEFERRED:
                 createAndRunJob(hcc, compiler, locker, resultDelivery, id -> {
                     ResultUtil.printResultHandle(new ResultHandle(id, 
resultSetId), sessionConfig);
-                });
+                }, clientContextId, ctx);
                 break;
             default:
                 break;
@@ -2452,7 +2439,8 @@
     }
 
     private static JobId createAndRunJob(IHyracksClientConnection hcc, 
IStatementCompiler compiler,
-            IMetadataLocker locker, ResultDelivery resultDelivery, 
IResultPrinter printer) throws Exception {
+            IMetadataLocker locker, ResultDelivery resultDelivery, 
IResultPrinter printer, String clientContextId,
+            IStatementExecutorContext ctx) throws Exception {
         locker.lock();
         try {
             final JobSpecification jobSpec = compiler.compile();
@@ -2460,6 +2448,10 @@
                 return JobId.INVALID;
             }
             final JobId jobId = JobUtils.runJob(hcc, jobSpec, false);
+
+            if (ctx != null && clientContextId != null) {
+                ctx.put(clientContextId, jobId); // Adds the running job into 
the context.
+            }
             if (ResultDelivery.ASYNC == resultDelivery) {
                 printer.print(jobId);
                 hcc.waitForCompletion(jobId);
@@ -2467,6 +2459,9 @@
                 hcc.waitForCompletion(jobId);
                 printer.print(jobId);
             }
+            if (ctx != null && clientContextId != null) {
+                ctx.remove(clientContextId); // Removes the running job into 
the context.
+            }
             return jobId;
         } finally {
             locker.unlock();
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java
index b63bb31..7629908 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.asterix.hyracks.bootstrap;
 
 import static 
org.apache.asterix.api.http.servlet.ServletConstants.ASTERIX_APP_CONTEXT_INFO_ATTR;
@@ -38,6 +39,7 @@
 import org.apache.asterix.api.http.server.FullApiServlet;
 import org.apache.asterix.api.http.server.NodeControllerDetailsApiServlet;
 import org.apache.asterix.api.http.server.QueryApiServlet;
+import org.apache.asterix.api.http.server.QueryCancellationServlet;
 import org.apache.asterix.api.http.server.QueryResultApiServlet;
 import org.apache.asterix.api.http.server.QueryServiceServlet;
 import org.apache.asterix.api.http.server.QueryStatusApiServlet;
@@ -72,6 +74,7 @@
 import org.apache.asterix.runtime.utils.AppContextInfo;
 import org.apache.asterix.translator.IStatementExecutorFactory;
 import org.apache.hyracks.api.application.ICCApplicationContext;
+import org.apache.hyracks.api.application.ICCApplicationEntryPoint;
 import org.apache.hyracks.api.client.HyracksConnection;
 import org.apache.hyracks.api.client.IHyracksClientConnection;
 import org.apache.hyracks.api.config.IConfigManager;
@@ -206,6 +209,7 @@
         addServlet(jsonAPIServer, Servlets.QUERY_STATUS);
         addServlet(jsonAPIServer, Servlets.QUERY_RESULT);
         addServlet(jsonAPIServer, Servlets.QUERY_SERVICE);
+        addServlet(jsonAPIServer, Servlets.QUERY_CANCEL);
         addServlet(jsonAPIServer, Servlets.CONNECTOR);
         addServlet(jsonAPIServer, Servlets.SHUTDOWN);
         addServlet(jsonAPIServer, Servlets.VERSION);
@@ -263,6 +267,8 @@
             case Servlets.SQLPP_DDL:
                 return new DdlApiServlet(ctx, paths, 
ccExtensionManager.getSqlppCompilationProvider(),
                         getStatementExecutorFactory(), componentProvider);
+            case Servlets.QUERY_CANCEL:
+                return new QueryCancellationServlet(ctx, paths);
             case Servlets.QUERY_STATUS:
                 return new QueryStatusApiServlet(ctx, paths);
             case Servlets.QUERY_RESULT:
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/CancellationTestExecutor.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/CancellationTestExecutor.java
new file mode 100644
index 0000000..db072a3
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/CancellationTestExecutor.java
@@ -0,0 +1,72 @@
+/*
+ * 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.test.common;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.asterix.common.utils.Servlets;
+import org.apache.asterix.testframework.context.TestCaseContext;
+import org.apache.asterix.testframework.xml.TestCase;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpUriRequest;
+
+public class CancellationTestExecutor extends TestExecutor {
+
+    private ExecutorService executor = Executors.newSingleThreadExecutor();
+
+    @Override
+    public InputStream executeQueryService(String str, 
TestCaseContext.OutputFormat fmt, URI uri,
+            List<TestCase.CompilationUnit.Parameter> params, boolean 
jsonEncoded, boolean cancellable)
+            throws Exception {
+        String clientContextId = UUID.randomUUID().toString();
+        if (cancellable) {
+            setParam(params, "client_context_id", clientContextId);
+        }
+        Callable<InputStream> query = () -> {
+            try {
+                return CancellationTestExecutor.super.executeQueryService(str, 
fmt, uri, params, jsonEncoded, true);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw e;
+            }
+        };
+        Future<InputStream> future = executor.submit(query);
+        if (cancellable) {
+            Thread.sleep(20);
+            // Cancels the query request while the query is executing.
+            cancelQuery(str, getEndpoint(Servlets.QUERY_CANCEL), 
clientContextId);
+        }
+        return future.get();
+    }
+
+    private InputStream cancelQuery(String str, URI uri, String 
clientContextId) throws Exception {
+        URI baseURI = new URI(uri.toString() + "/");
+        HttpUriRequest method = constructPostMethodUrl(str, 
baseURI.resolve(clientContextId), null, null);
+        HttpResponse response = executeHttpRequest(method);
+        return response.getEntity().getContent();
+    }
+}
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
index 3531211..53a0f6c 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
@@ -19,7 +19,6 @@
 package org.apache.asterix.test.common;
 
 import java.io.InputStream;
-import java.io.StringWriter;
 import java.nio.charset.Charset;
 import java.util.Iterator;
 import java.util.logging.Logger;
@@ -59,6 +58,8 @@
             field = sIter.next();
             switch (field) {
                 case "requestID":
+                    break;
+                case "clientContextID":
                     break;
                 case "signature":
                     break;
@@ -106,7 +107,7 @@
                     }
                     break;
                 default:
-                    throw new AsterixException(field + "unanticipated field");
+                    throw new AsterixException(field + " unanticipated field");
             }
         }
 
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
index 7765572..a1fcd3f 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
@@ -457,6 +457,11 @@
 
     public InputStream executeQueryService(String str, OutputFormat fmt, URI 
uri,
             List<CompilationUnit.Parameter> params, boolean jsonEncoded) 
throws Exception {
+        return executeQueryService(str, fmt, uri, params, jsonEncoded, false);
+    }
+
+    public InputStream executeQueryService(String str, OutputFormat fmt, URI 
uri,
+            List<CompilationUnit.Parameter> params, boolean jsonEncoded, 
boolean cancellable) throws Exception {
         setParam(params, "format", fmt.mimeType());
         HttpUriRequest method = jsonEncoded ? constructPostMethodJson(str, 
uri, "statement", params)
                 : constructPostMethodUrl(str, uri, "statement", params);
@@ -830,12 +835,12 @@
                     }
                     final URI uri = getEndpoint(Servlets.QUERY_SERVICE);
                     if (DELIVERY_IMMEDIATE.equals(delivery)) {
-                        resultStream = executeQueryService(statement, fmt, 
uri, params, true);
+                        resultStream = executeQueryService(statement, fmt, 
uri, params, true, true);
                         resultStream = ResultExtractor.extract(resultStream);
                     } else {
                         String handleVar = getHandleVariable(statement);
                         setParam(params, "mode", delivery);
-                        resultStream = executeQueryService(statement, fmt, 
uri, params, true);
+                        resultStream = executeQueryService(statement, fmt, 
uri, params, true, true);
                         String handle = 
ResultExtractor.extractHandle(resultStream);
                         Assert.assertNotNull("no handle for " + reqType + " 
test " + testFile.toString(), handleVar);
                         variableCtx.put(handleVar, handle);
@@ -1221,6 +1226,9 @@
             } catch (JsonMappingException e) {
                 result = om.createArrayNode();
             }
+            if (result == null) {
+                return;
+            }
             for (int i = 0; i < result.size(); i++) {
                 JsonNode json = result.get(i);
                 if (json != null) {
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/APIExecutionTest.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/APIExecutionTest.java
index 82f90ec..dd87455 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/APIExecutionTest.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/APIExecutionTest.java
@@ -21,6 +21,7 @@
 
 import java.util.Collection;
 
+import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -38,7 +39,7 @@
 
     @BeforeClass
     public static void setUp() throws Exception {
-        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME);
+        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new TestExecutor());
     }
 
     @AfterClass
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionFullParallelismIT.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionFullParallelismIT.java
index 8df93ba..6cc5a9c 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionFullParallelismIT.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionFullParallelismIT.java
@@ -21,6 +21,7 @@
 
 import java.util.Collection;
 
+import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -38,7 +39,7 @@
 
     @BeforeClass
     public static void setUp() throws Exception {
-        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME);
+        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new TestExecutor());
     }
 
     @AfterClass
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionLessParallelismIT.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionLessParallelismIT.java
index 2f3c395..dc03626 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionLessParallelismIT.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionLessParallelismIT.java
@@ -21,6 +21,7 @@
 
 import java.util.Collection;
 
+import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -38,7 +39,7 @@
 
     @BeforeClass
     public static void setUp() throws Exception {
-        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME);
+        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new TestExecutor());
     }
 
     @AfterClass
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionTest.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionTest.java
index 4169a07..abc9f2f 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionTest.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/AqlExecutionTest.java
@@ -21,6 +21,7 @@
 
 import java.util.Collection;
 
+import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -38,7 +39,7 @@
 
     @BeforeClass
     public static void setUp() throws Exception {
-        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME);
+        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new TestExecutor());
     }
 
     @AfterClass
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateDefaultParameterTest.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateDefaultParameterTest.java
index 86a9639..17e88a6 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateDefaultParameterTest.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateDefaultParameterTest.java
@@ -25,6 +25,7 @@
 import java.net.URL;
 import java.util.Collection;
 
+import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.junit.AfterClass;
 import org.junit.Assert;
@@ -43,7 +44,7 @@
 
     @BeforeClass
     public static void setUp() throws Exception {
-        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME);
+        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new TestExecutor());
     }
 
     @AfterClass
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateExecutionFullParallelismTest.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateExecutionFullParallelismTest.java
index b7b4312..e428c93 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateExecutionFullParallelismTest.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateExecutionFullParallelismTest.java
@@ -21,6 +21,7 @@
 
 import java.util.Collection;
 
+import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -38,7 +39,7 @@
 
     @BeforeClass
     public static void setUp() throws Exception {
-        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME);
+        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new TestExecutor());
     }
 
     @AfterClass
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateExecutionLessParallelismTest.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateExecutionLessParallelismTest.java
index 9516d7d..346ae2f 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateExecutionLessParallelismTest.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateExecutionLessParallelismTest.java
@@ -21,6 +21,7 @@
 
 import java.util.Collection;
 
+import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -38,7 +39,7 @@
 
     @BeforeClass
     public static void setUp() throws Exception {
-        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME);
+        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new TestExecutor());
     }
 
     @AfterClass
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/LangExecutionUtil.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/LangExecutionUtil.java
index 0e6be0f..52e98f1 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/LangExecutionUtil.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/LangExecutionUtil.java
@@ -35,7 +35,6 @@
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.apache.commons.lang.SystemUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.junit.Assert;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
@@ -52,12 +51,13 @@
     private static final boolean cleanupOnStart = true;
     private static final boolean cleanupOnStop = true;
     private static final List<String> badTestCases = new ArrayList<>();
-    private static final TestExecutor testExecutor = new TestExecutor();
+    private static TestExecutor testExecutor;
 
     private static TestLibrarian librarian;
     private static final int repeat = Integer.getInteger("test.repeat", 1);
 
-    public static void setUp(String configFile) throws Exception {
+    public static void setUp(String configFile, TestExecutor executor) throws 
Exception {
+        testExecutor = executor;
         File outdir = new File(PATH_ACTUAL);
         outdir.mkdirs();
         List<ILibraryManager> libraryManagers = 
ExecutionTestUtil.setUp(cleanupOnStart, configFile);
@@ -142,7 +142,21 @@
                 .exec(new String[] { "bash", "-c", "lsof -p " + processId + 
"|grep waf|wc -l" });
         try (BufferedReader reader = new BufferedReader(new 
InputStreamReader(process.getInputStream()))) {
             int runFileCount = Integer.parseInt(reader.readLine().trim());
-            Assert.assertTrue(runFileCount == 0);
+            if (runFileCount != 0) {
+                outputLeakedFiles(processId);
+                throw new AssertionError("There are " + runFileCount + " 
leaked run files.");
+            }
+        }
+    }
+
+    private static void outputLeakedFiles(String processId) throws IOException 
{
+        Process process = Runtime.getRuntime()
+                .exec(new String[] { "bash", "-c", "lsof -p " + processId + 
"|grep waf" });
+        try (BufferedReader reader = new BufferedReader(new 
InputStreamReader(process.getInputStream()))) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                System.err.println(line);
+            }
         }
     }
 }
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionFullParallelismIT.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionFullParallelismIT.java
index f2372ed..3d93c36 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionFullParallelismIT.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionFullParallelismIT.java
@@ -21,6 +21,7 @@
 
 import java.util.Collection;
 
+import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -38,7 +39,7 @@
 
     @BeforeClass
     public static void setUp() throws Exception {
-        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME);
+        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new TestExecutor());
     }
 
     @AfterClass
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionLessParallelismIT.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionLessParallelismIT.java
index c3cc058..53b068e 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionLessParallelismIT.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionLessParallelismIT.java
@@ -21,6 +21,7 @@
 
 import java.util.Collection;
 
+import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -38,7 +39,7 @@
 
     @BeforeClass
     public static void setUp() throws Exception {
-        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME);
+        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new TestExecutor());
     }
 
     @AfterClass
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionTest.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionTest.java
index f19ebbf..8ec1fe7 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionTest.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionTest.java
@@ -20,6 +20,7 @@
 
 import java.util.Collection;
 
+import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -37,7 +38,7 @@
 
     @BeforeClass
     public static void setUp() throws Exception {
-        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME);
+        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new TestExecutor());
     }
 
     @AfterClass
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionWithCancellationTest.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionWithCancellationTest.java
new file mode 100644
index 0000000..668f109
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionWithCancellationTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.test.runtime;
+
+import java.util.Collection;
+
+import org.apache.asterix.test.common.CancellationTestExecutor;
+import org.apache.asterix.testframework.context.TestCaseContext;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Runs the SQL++ runtime tests with the storage parallelism.
+ */
+@RunWith(Parameterized.class)
+public class SqlppExecutionWithCancellationTest {
+    protected static final String TEST_CONFIG_FILE_NAME = 
"asterix-build-configuration.xml";
+    private static int numCancelledQueries = 0;
+
+    @BeforeClass
+    public static void setUp() throws Exception {
+        LangExecutionUtil.setUp(TEST_CONFIG_FILE_NAME, new 
CancellationTestExecutor());
+    }
+
+    @AfterClass
+    public static void tearDown() throws Exception {
+        System.err.println(numCancelledQueries + " queries has been cancelled 
during the test.");
+        LangExecutionUtil.tearDown();
+    }
+
+    @Parameters(name = "SqlppExecutionWithCancellationTest {index}: {0}")
+    public static Collection<Object[]> tests() throws Exception {
+        return LangExecutionUtil.tests("only_sqlpp.xml", 
"testsuite_sqlpp.xml");
+    }
+
+    protected TestCaseContext tcCtx;
+
+    public SqlppExecutionWithCancellationTest(TestCaseContext tcCtx) {
+        this.tcCtx = tcCtx;
+    }
+
+    @Test
+    public void test() throws Exception {
+        try {
+            LangExecutionUtil.test(tcCtx);
+        } catch (Exception e) {
+            Throwable cause = getRootCause(e);
+            String errorMsg = cause.getMessage();
+            // "HYR0025" means a user cancelled the query.
+            // "status" check result can change because of cancellation.
+            if (errorMsg.startsWith("HYR0025") // Expected
+                    || errorMsg.contains("\"status\": ") // Expected
+                    || errorMsg.contains("reference count") // Unexpected: 
ASTERIXDB
+                    || errorMsg.contains("Resource doesn't exist") // 
Unexpected: ASTERIXDB
+                    || errorMsg.contains("is pinned and file is being closed") 
// Unexpected: ASTERIXDB
+            ) {
+                numCancelledQueries++;
+            } else {
+                // Re-throw other kinds of exceptions.
+                throw e;
+            }
+        }
+    }
+
+    private Throwable getRootCause(Throwable e) {
+        Throwable current = e;
+        Throwable cause = e.getCause();
+        while (cause != null) {
+            Throwable nextCause = current.getCause();
+            current = cause;
+            cause = nextCause;
+        }
+        return current;
+    }
+}
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/any-object/any-object.2.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/any-object/any-object.2.query.sqlpp
index afaa5b1..81d65a9 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/any-object/any-object.2.query.sqlpp
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/any-object/any-object.2.query.sqlpp
@@ -17,4 +17,6 @@
  * under the License.
  */
 
-select element x from Metadata.Datatype as x;
+select element x from Metadata.Datatype as x
+where DataverseName = "test" or DataverseName = "Metadata"
+order by DataversName, DatatypeName;
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/any-object/any-object.2.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/any-object/any-object.2.adm
index 91df332..0e57bc0 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/any-object/any-object.2.adm
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/any-object/any-object.2.adm
@@ -1,69 +1,69 @@
-{ "DataverseName": "Metadata", "DatatypeName": "AnyObject", "Derived": { 
"Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [  
] } }, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "CompactionPolicyRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "CompactionPolicy", "FieldType": 
"string", "IsNullable": false }, { "FieldName": "Classname", "FieldType": 
"string", "IsNullable": false } ] } }, "Timestamp": "Mon Oct 10 14:53:55 PDT 
2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "DatasetRecordType", "Derived": 
{ "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": 
[ { "FieldName": "DataverseName", "FieldType": "string", "IsNullable": false }, 
{ "FieldName": "DatasetName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "DatatypeDataverseName", "FieldType": "string", "IsNullable": 
false }, { "FieldName": "DatatypeName", "FieldType": "string", "IsNullable": 
false }, { "FieldName": "DatasetType", "FieldType": "string", "IsNullable": 
false }, { "FieldName": "GroupName", "FieldType": "string", "IsNullable": false 
}, { "FieldName": "CompactionPolicy", "FieldType": "string", "IsNullable": 
false }, { "FieldName": "CompactionPolicyProperties", "FieldType": 
"DatasetRecordType_CompactionPolicyProperties", "IsNullable": false }, { 
"FieldName": "InternalDetails", "FieldType": 
"DatasetRecordType_InternalDetails", "IsNullable": true }, { "FieldName": 
"ExternalDetails", "FieldType":
  "DatasetRecordType_ExternalDetails", "IsNullable": true }, { "FieldName": 
"Hints", "FieldType": "DatasetRecordType_Hints", "IsNullable": false }, { 
"FieldName": "Timestamp", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "DatasetId", "FieldType": "int32", "IsNullable": false }, { 
"FieldName": "PendingOp", "FieldType": "int32", "IsNullable": false } ] } }, 
"Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_CompactionPolicyProperties", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": 
"DatasetRecordType_CompactionPolicyProperties_Item" }, "Timestamp": "Mon Oct 10 
14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_CompactionPolicyProperties_Item", "Derived": { "Tag": 
"RECORD", "IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { 
"FieldName": "Name", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "Value", "FieldType": "string", "IsNullable": false } ] } }, 
"Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_ExternalDetails", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"DatasourceAdapter", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "Properties", "FieldType": 
"DatasetRecordType_ExternalDetails_Properties", "IsNullable": false }, { 
"FieldName": "LastRefreshTime", "FieldType": "datetime", "IsNullable": false }, 
{ "FieldName": "TransactionState", "FieldType": "int32", "IsNullable": false } 
] } }, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_ExternalDetails_Properties", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": 
"DatasetRecordType_ExternalDetails_Properties_Item" }, "Timestamp": "Mon Oct 10 
14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_ExternalDetails_Properties_Item", "Derived": { "Tag": 
"RECORD", "IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { 
"FieldName": "Name", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "Value", "FieldType": "string", "IsNullable": false } ] } }, 
"Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "DatasetRecordType_Hints", 
"Derived": { "Tag": "UNORDEREDLIST", "IsAnonymous": true, "UnorderedList": 
"DatasetRecordType_Hints_Item" }, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "DatasetRecordType_Hints_Item", 
"Derived": { "Tag": "RECORD", "IsAnonymous": true, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "Name", "FieldType": "string", "IsNullable": false 
}, { "FieldName": "Value", "FieldType": "string", "IsNullable": false } ] } }, 
"Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_InternalDetails", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"FileStructure", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"PartitioningStrategy", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "PartitioningKey", "FieldType": 
"DatasetRecordType_InternalDetails_PartitioningKey", "IsNullable": false }, { 
"FieldName": "PrimaryKey", "FieldType": 
"DatasetRecordType_InternalDetails_PrimaryKey", "IsNullable": false }, { 
"FieldName": "Autogenerated", "FieldType": "boolean", "IsNullable": false } ] } 
}, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_InternalDetails_PartitioningKey", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": 
"DatasetRecordType_InternalDetails_PartitioningKey_Item" }, "Timestamp": "Mon 
Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_InternalDetails_PartitioningKey_Item", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": "string" }, "Timestamp": 
"Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_InternalDetails_PrimaryKey", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": 
"DatasetRecordType_InternalDetails_PrimaryKey_Item" }, "Timestamp": "Mon Oct 10 
14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_InternalDetails_PrimaryKey_Item", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": "string" }, "Timestamp": 
"Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "DatasourceAdapterRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Name", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Classname", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Type", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Timestamp", "FieldType": "string", 
"IsNullable": false } ] } }, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "DatatypeRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "DatatypeName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Derived", "FieldType": 
"DatatypeRecordType_Derived", "IsNullable": true }, { "FieldName": "Timestamp", 
"FieldType": "string", "IsNullable": false } ] } }, "Timestamp": "Mon Oct 10 
14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "DatatypeRecordType_Derived", 
"Derived": { "Tag": "RECORD", "IsAnonymous": true, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "Tag", "FieldType": "string", "IsNullable": false }, 
{ "FieldName": "IsAnonymous", "FieldType": "boolean", "IsNullable": false }, { 
"FieldName": "Record", "FieldType": "DatatypeRecordType_Derived_Record", 
"IsNullable": true }, { "FieldName": "UnorderedList", "FieldType": "string", 
"IsNullable": true }, { "FieldName": "OrderedList", "FieldType": "string", 
"IsNullable": true } ] } }, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatatypeRecordType_Derived_Record", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"IsOpen", "FieldType": "boolean", "IsNullable": false }, { "FieldName": 
"Fields", "FieldType": "DatatypeRecordType_Derived_Record_Fields", 
"IsNullable": false } ] } }, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatatypeRecordType_Derived_Record_Fields", "Derived": { "Tag": "ORDEREDLIST", 
"IsAnonymous": true, "OrderedList": 
"DatatypeRecordType_Derived_Record_Fields_Item" }, "Timestamp": "Mon Oct 10 
14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"DatatypeRecordType_Derived_Record_Fields_Item", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"FieldName", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"FieldType", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"IsNullable", "FieldType": "boolean", "IsNullable": false } ] } }, "Timestamp": 
"Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "DataverseRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "DataFormat", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Timestamp", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "PendingOp", "FieldType": "int32", 
"IsNullable": false } ] } }, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "ExternalFileRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "DatasetName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "FileNumber", "FieldType": "int32", 
"IsNullable": false }, { "FieldName": "FileName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "FileSize", "FieldType": "int64", 
"IsNullable": false }, { "FieldName": "FileModTime", "FieldType": "datetime", 
"IsNullable": false }, { "FieldName": "PendingOp", "FieldType": "int32", 
"IsNullable": false } ] } }, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "FeedConnectionRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "FeedName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "DatasetName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "ReturnType", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "AppliedFunctions", "FieldType": 
"FeedConnectionRecordType_AppliedFunctions", "IsNullable": false }, { 
"FieldName": "PolicyName", "FieldType": "string", "IsNullable": false } ] } }, 
"Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"FeedConnectionRecordType_AppliedFunctions", "Derived": { "Tag": 
"UNORDEREDLIST", "IsAnonymous": true, "UnorderedList": "string" }, "Timestamp": 
"Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "FeedPolicyRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "PolicyName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Description", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Properties", "FieldType": 
"FeedPolicyRecordType_Properties", "IsNullable": false } ] } }, "Timestamp": 
"Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"FeedPolicyRecordType_Properties", "Derived": { "Tag": "UNORDEREDLIST", 
"IsAnonymous": true, "UnorderedList": "FeedPolicyRecordType_Properties_Item" }, 
"Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"FeedPolicyRecordType_Properties_Item", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"Name", "FieldType": "string", "IsNullable": false }, { "FieldName": "Value", 
"FieldType": "string", "IsNullable": false } ] } }, "Timestamp": "Mon Oct 10 
14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "FeedRecordType", "Derived": { 
"Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [ 
{ "FieldName": "DataverseName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "FeedName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "AdapterName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "AdapterConfiguration", "FieldType": 
"FeedRecordType_AdapterConfiguration", "IsNullable": false }, { "FieldName": 
"Timestamp", "FieldType": "string", "IsNullable": false } ] } }, "Timestamp": 
"Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"FeedRecordType_AdapterConfiguration", "Derived": { "Tag": "UNORDEREDLIST", 
"IsAnonymous": true, "UnorderedList": 
"FeedRecordType_AdapterConfiguration_Item" }, "Timestamp": "Mon Oct 10 14:53:55 
PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"FeedRecordType_AdapterConfiguration_Item", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"Name", "FieldType": "string", "IsNullable": false }, { "FieldName": "Value", 
"FieldType": "string", "IsNullable": false } ] } }, "Timestamp": "Mon Oct 10 
14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "FunctionRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Name", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Arity", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Params", "FieldType": 
"FunctionRecordType_Params", "IsNullable": false }, { "FieldName": 
"ReturnType", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"Definition", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"Language", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"Kind", "FieldType": "string", "IsNullable": false } ] } }, "Timestamp": "Mon 
Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "FunctionRecordType_Params", 
"Derived": { "Tag": "ORDEREDLIST", "IsAnonymous": true, "OrderedList": "string" 
}, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "IndexRecordType", "Derived": { 
"Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [ 
{ "FieldName": "DataverseName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "DatasetName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "IndexName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "IndexStructure", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "SearchKey", "FieldType": "IndexRecordType_SearchKey", 
"IsNullable": false }, { "FieldName": "IsPrimary", "FieldType": "boolean", 
"IsNullable": false }, { "FieldName": "Timestamp", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "PendingOp", "FieldType": "int32", 
"IsNullable": false } ] } }, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "IndexRecordType_SearchKey", 
"Derived": { "Tag": "ORDEREDLIST", "IsAnonymous": true, "OrderedList": 
"IndexRecordType_SearchKey_Item" }, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" 
}
-{ "DataverseName": "Metadata", "DatatypeName": 
"IndexRecordType_SearchKey_Item", "Derived": { "Tag": "ORDEREDLIST", 
"IsAnonymous": true, "OrderedList": "string" }, "Timestamp": "Mon Oct 10 
14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "LibraryRecordType", "Derived": 
{ "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": 
[ { "FieldName": "DataverseName", "FieldType": "string", "IsNullable": false }, 
{ "FieldName": "Name", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "Timestamp", "FieldType": "string", "IsNullable": false } ] } }, 
"Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "NodeGroupRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "GroupName", "FieldType": "string", "IsNullable": 
false }, { "FieldName": "NodeNames", "FieldType": 
"NodeGroupRecordType_NodeNames", "IsNullable": false }, { "FieldName": 
"Timestamp", "FieldType": "string", "IsNullable": false } ] } }, "Timestamp": 
"Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": 
"NodeGroupRecordType_NodeNames", "Derived": { "Tag": "UNORDEREDLIST", 
"IsAnonymous": true, "UnorderedList": "string" }, "Timestamp": "Mon Oct 10 
14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "NodeRecordType", "Derived": { 
"Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [ 
{ "FieldName": "NodeName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "NumberOfCores", "FieldType": "int64", "IsNullable": false }, { 
"FieldName": "WorkingMemorySize", "FieldType": "int64", "IsNullable": false } ] 
} }, "Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "binary", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "boolean", "Timestamp": "Mon 
Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "circle", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "date", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "datetime", "Timestamp": "Mon 
Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "day-time-duration", 
"Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "double", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "duration", "Timestamp": "Mon 
Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "float", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "int16", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "int32", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "int64", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "int8", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "interval", "Timestamp": "Mon 
Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "line", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "missing", "Timestamp": "Mon 
Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "null", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "point", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "point3d", "Timestamp": "Mon 
Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "polygon", "Timestamp": "Mon 
Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "rectangle", "Timestamp": "Mon 
Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "shortwithouttypeinfo", 
"Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "string", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "time", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "uuid", "Timestamp": "Mon Oct 
10 14:53:55 PDT 2016" }
-{ "DataverseName": "Metadata", "DatatypeName": "year-month-duration", 
"Timestamp": "Mon Oct 10 14:53:55 PDT 2016" }
-{ "DataverseName": "test", "DatatypeName": "AnyObject", "Derived": { "Tag": 
"RECORD", "IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [  ] } }, 
"Timestamp": "Mon Oct 10 15:00:08 PDT 2016" }
-{ "DataverseName": "test", "DatatypeName": "kv1", "Derived": { "Tag": 
"RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [ { 
"FieldName": "id", "FieldType": "int32", "IsNullable": false }, { "FieldName": 
"val", "FieldType": "AnyObject", "IsNullable": false } ] } }, "Timestamp": "Mon 
Oct 10 15:00:08 PDT 2016" }
-{ "DataverseName": "test", "DatatypeName": "kv2", "Derived": { "Tag": 
"RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [ { 
"FieldName": "id", "FieldType": "int32", "IsNullable": false }, { "FieldName": 
"val", "FieldType": "AnyObject", "IsNullable": false } ] } }, "Timestamp": "Mon 
Oct 10 15:00:08 PDT 2016" }
+{ "DataverseName": "test", "DatatypeName": "AnyObject", "Derived": { "Tag": 
"RECORD", "IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [  ] } }, 
"Timestamp": "Thu Mar 09 15:46:46 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "AnyObject", "Derived": { 
"Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [  
] } }, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "CompactionPolicyRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "CompactionPolicy", "FieldType": 
"string", "IsNullable": false }, { "FieldName": "Classname", "FieldType": 
"string", "IsNullable": false } ] } }, "Timestamp": "Thu Mar 09 15:46:42 PST 
2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "DatasetRecordType", "Derived": 
{ "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": 
[ { "FieldName": "DataverseName", "FieldType": "string", "IsNullable": false }, 
{ "FieldName": "DatasetName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "DatatypeDataverseName", "FieldType": "string", "IsNullable": 
false }, { "FieldName": "DatatypeName", "FieldType": "string", "IsNullable": 
false }, { "FieldName": "DatasetType", "FieldType": "string", "IsNullable": 
false }, { "FieldName": "GroupName", "FieldType": "string", "IsNullable": false 
}, { "FieldName": "CompactionPolicy", "FieldType": "string", "IsNullable": 
false }, { "FieldName": "CompactionPolicyProperties", "FieldType": 
"DatasetRecordType_CompactionPolicyProperties", "IsNullable": false }, { 
"FieldName": "InternalDetails", "FieldType": 
"DatasetRecordType_InternalDetails", "IsNullable": true }, { "FieldName": 
"ExternalDetails", "FieldType":
  "DatasetRecordType_ExternalDetails", "IsNullable": true }, { "FieldName": 
"Hints", "FieldType": "DatasetRecordType_Hints", "IsNullable": false }, { 
"FieldName": "Timestamp", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "DatasetId", "FieldType": "int32", "IsNullable": false }, { 
"FieldName": "PendingOp", "FieldType": "int32", "IsNullable": false } ] } }, 
"Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_CompactionPolicyProperties", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": 
"DatasetRecordType_CompactionPolicyProperties_Item" }, "Timestamp": "Thu Mar 09 
15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_CompactionPolicyProperties_Item", "Derived": { "Tag": 
"RECORD", "IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { 
"FieldName": "Name", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "Value", "FieldType": "string", "IsNullable": false } ] } }, 
"Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_ExternalDetails", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"DatasourceAdapter", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "Properties", "FieldType": 
"DatasetRecordType_ExternalDetails_Properties", "IsNullable": false }, { 
"FieldName": "LastRefreshTime", "FieldType": "datetime", "IsNullable": false }, 
{ "FieldName": "TransactionState", "FieldType": "int32", "IsNullable": false } 
] } }, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_ExternalDetails_Properties", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": 
"DatasetRecordType_ExternalDetails_Properties_Item" }, "Timestamp": "Thu Mar 09 
15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_ExternalDetails_Properties_Item", "Derived": { "Tag": 
"RECORD", "IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { 
"FieldName": "Name", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "Value", "FieldType": "string", "IsNullable": false } ] } }, 
"Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "DatasetRecordType_Hints", 
"Derived": { "Tag": "UNORDEREDLIST", "IsAnonymous": true, "UnorderedList": 
"DatasetRecordType_Hints_Item" }, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "DatasetRecordType_Hints_Item", 
"Derived": { "Tag": "RECORD", "IsAnonymous": true, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "Name", "FieldType": "string", "IsNullable": false 
}, { "FieldName": "Value", "FieldType": "string", "IsNullable": false } ] } }, 
"Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_InternalDetails", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"FileStructure", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"PartitioningStrategy", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "PartitioningKey", "FieldType": 
"DatasetRecordType_InternalDetails_PartitioningKey", "IsNullable": false }, { 
"FieldName": "PrimaryKey", "FieldType": 
"DatasetRecordType_InternalDetails_PrimaryKey", "IsNullable": false }, { 
"FieldName": "Autogenerated", "FieldType": "boolean", "IsNullable": false } ] } 
}, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_InternalDetails_PartitioningKey", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": 
"DatasetRecordType_InternalDetails_PartitioningKey_Item" }, "Timestamp": "Thu 
Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_InternalDetails_PartitioningKey_Item", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": "string" }, "Timestamp": 
"Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_InternalDetails_PrimaryKey", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": 
"DatasetRecordType_InternalDetails_PrimaryKey_Item" }, "Timestamp": "Thu Mar 09 
15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatasetRecordType_InternalDetails_PrimaryKey_Item", "Derived": { "Tag": 
"ORDEREDLIST", "IsAnonymous": true, "OrderedList": "string" }, "Timestamp": 
"Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "DatasourceAdapterRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Name", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Classname", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Type", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Timestamp", "FieldType": "string", 
"IsNullable": false } ] } }, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "DatatypeRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "DatatypeName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Derived", "FieldType": 
"DatatypeRecordType_Derived", "IsNullable": true }, { "FieldName": "Timestamp", 
"FieldType": "string", "IsNullable": false } ] } }, "Timestamp": "Thu Mar 09 
15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "DatatypeRecordType_Derived", 
"Derived": { "Tag": "RECORD", "IsAnonymous": true, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "Tag", "FieldType": "string", "IsNullable": false }, 
{ "FieldName": "IsAnonymous", "FieldType": "boolean", "IsNullable": false }, { 
"FieldName": "Record", "FieldType": "DatatypeRecordType_Derived_Record", 
"IsNullable": true }, { "FieldName": "UnorderedList", "FieldType": "string", 
"IsNullable": true }, { "FieldName": "OrderedList", "FieldType": "string", 
"IsNullable": true } ] } }, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatatypeRecordType_Derived_Record", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"IsOpen", "FieldType": "boolean", "IsNullable": false }, { "FieldName": 
"Fields", "FieldType": "DatatypeRecordType_Derived_Record_Fields", 
"IsNullable": false } ] } }, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatatypeRecordType_Derived_Record_Fields", "Derived": { "Tag": "ORDEREDLIST", 
"IsAnonymous": true, "OrderedList": 
"DatatypeRecordType_Derived_Record_Fields_Item" }, "Timestamp": "Thu Mar 09 
15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"DatatypeRecordType_Derived_Record_Fields_Item", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"FieldName", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"FieldType", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"IsNullable", "FieldType": "boolean", "IsNullable": false } ] } }, "Timestamp": 
"Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "DataverseRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "DataFormat", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Timestamp", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "PendingOp", "FieldType": "int32", 
"IsNullable": false } ] } }, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "ExternalFileRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "DatasetName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "FileNumber", "FieldType": "int32", 
"IsNullable": false }, { "FieldName": "FileName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "FileSize", "FieldType": "int64", 
"IsNullable": false }, { "FieldName": "FileModTime", "FieldType": "datetime", 
"IsNullable": false }, { "FieldName": "PendingOp", "FieldType": "int32", 
"IsNullable": false } ] } }, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "FeedConnectionRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "FeedName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "DatasetName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "ReturnType", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "AppliedFunctions", "FieldType": 
"FeedConnectionRecordType_AppliedFunctions", "IsNullable": false }, { 
"FieldName": "PolicyName", "FieldType": "string", "IsNullable": false } ] } }, 
"Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"FeedConnectionRecordType_AppliedFunctions", "Derived": { "Tag": 
"UNORDEREDLIST", "IsAnonymous": true, "UnorderedList": "string" }, "Timestamp": 
"Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "FeedPolicyRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "PolicyName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Description", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Properties", "FieldType": 
"FeedPolicyRecordType_Properties", "IsNullable": false } ] } }, "Timestamp": 
"Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"FeedPolicyRecordType_Properties", "Derived": { "Tag": "UNORDEREDLIST", 
"IsAnonymous": true, "UnorderedList": "FeedPolicyRecordType_Properties_Item" }, 
"Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"FeedPolicyRecordType_Properties_Item", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"Name", "FieldType": "string", "IsNullable": false }, { "FieldName": "Value", 
"FieldType": "string", "IsNullable": false } ] } }, "Timestamp": "Thu Mar 09 
15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "FeedRecordType", "Derived": { 
"Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [ 
{ "FieldName": "DataverseName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "FeedName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "AdapterName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "AdapterConfiguration", "FieldType": 
"FeedRecordType_AdapterConfiguration", "IsNullable": false }, { "FieldName": 
"Timestamp", "FieldType": "string", "IsNullable": false } ] } }, "Timestamp": 
"Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"FeedRecordType_AdapterConfiguration", "Derived": { "Tag": "UNORDEREDLIST", 
"IsAnonymous": true, "UnorderedList": 
"FeedRecordType_AdapterConfiguration_Item" }, "Timestamp": "Thu Mar 09 15:46:42 
PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"FeedRecordType_AdapterConfiguration_Item", "Derived": { "Tag": "RECORD", 
"IsAnonymous": true, "Record": { "IsOpen": true, "Fields": [ { "FieldName": 
"Name", "FieldType": "string", "IsNullable": false }, { "FieldName": "Value", 
"FieldType": "string", "IsNullable": false } ] } }, "Timestamp": "Thu Mar 09 
15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "FunctionRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "DataverseName", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Name", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Arity", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "Params", "FieldType": 
"FunctionRecordType_Params", "IsNullable": false }, { "FieldName": 
"ReturnType", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"Definition", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"Language", "FieldType": "string", "IsNullable": false }, { "FieldName": 
"Kind", "FieldType": "string", "IsNullable": false } ] } }, "Timestamp": "Thu 
Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "FunctionRecordType_Params", 
"Derived": { "Tag": "ORDEREDLIST", "IsAnonymous": true, "OrderedList": "string" 
}, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "IndexRecordType", "Derived": { 
"Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [ 
{ "FieldName": "DataverseName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "DatasetName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "IndexName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "IndexStructure", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "SearchKey", "FieldType": "IndexRecordType_SearchKey", 
"IsNullable": false }, { "FieldName": "IsPrimary", "FieldType": "boolean", 
"IsNullable": false }, { "FieldName": "Timestamp", "FieldType": "string", 
"IsNullable": false }, { "FieldName": "PendingOp", "FieldType": "int32", 
"IsNullable": false } ] } }, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "IndexRecordType_SearchKey", 
"Derived": { "Tag": "ORDEREDLIST", "IsAnonymous": true, "OrderedList": 
"IndexRecordType_SearchKey_Item" }, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" 
}
+{ "DataverseName": "Metadata", "DatatypeName": 
"IndexRecordType_SearchKey_Item", "Derived": { "Tag": "ORDEREDLIST", 
"IsAnonymous": true, "OrderedList": "string" }, "Timestamp": "Thu Mar 09 
15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "LibraryRecordType", "Derived": 
{ "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": 
[ { "FieldName": "DataverseName", "FieldType": "string", "IsNullable": false }, 
{ "FieldName": "Name", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "Timestamp", "FieldType": "string", "IsNullable": false } ] } }, 
"Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "NodeGroupRecordType", 
"Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, 
"Fields": [ { "FieldName": "GroupName", "FieldType": "string", "IsNullable": 
false }, { "FieldName": "NodeNames", "FieldType": 
"NodeGroupRecordType_NodeNames", "IsNullable": false }, { "FieldName": 
"Timestamp", "FieldType": "string", "IsNullable": false } ] } }, "Timestamp": 
"Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": 
"NodeGroupRecordType_NodeNames", "Derived": { "Tag": "UNORDEREDLIST", 
"IsAnonymous": true, "UnorderedList": "string" }, "Timestamp": "Thu Mar 09 
15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "NodeRecordType", "Derived": { 
"Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [ 
{ "FieldName": "NodeName", "FieldType": "string", "IsNullable": false }, { 
"FieldName": "NumberOfCores", "FieldType": "int64", "IsNullable": false }, { 
"FieldName": "WorkingMemorySize", "FieldType": "int64", "IsNullable": false } ] 
} }, "Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "binary", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "boolean", "Timestamp": "Thu 
Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "circle", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "date", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "datetime", "Timestamp": "Thu 
Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "day-time-duration", 
"Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "double", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "duration", "Timestamp": "Thu 
Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "float", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "int16", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "int32", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "int64", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "int8", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "interval", "Timestamp": "Thu 
Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "test", "DatatypeName": "kv1", "Derived": { "Tag": 
"RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [ { 
"FieldName": "id", "FieldType": "int32", "IsNullable": false }, { "FieldName": 
"val", "FieldType": "AnyObject", "IsNullable": false } ] } }, "Timestamp": "Thu 
Mar 09 15:46:46 PST 2017" }
+{ "DataverseName": "test", "DatatypeName": "kv2", "Derived": { "Tag": 
"RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [ { 
"FieldName": "id", "FieldType": "int32", "IsNullable": false }, { "FieldName": 
"val", "FieldType": "AnyObject", "IsNullable": false } ] } }, "Timestamp": "Thu 
Mar 09 15:46:46 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "line", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "missing", "Timestamp": "Thu 
Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "null", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "point", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "point3d", "Timestamp": "Thu 
Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "polygon", "Timestamp": "Thu 
Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "rectangle", "Timestamp": "Thu 
Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "shortwithouttypeinfo", 
"Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "string", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "time", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "uuid", "Timestamp": "Thu Mar 
09 15:46:42 PST 2017" }
+{ "DataverseName": "Metadata", "DatatypeName": "year-month-duration", 
"Timestamp": "Thu Mar 09 15:46:42 PST 2017" }
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetLifecycleManager.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetLifecycleManager.java
index 1a8ccae..05ad42e 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetLifecycleManager.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetLifecycleManager.java
@@ -133,7 +133,8 @@
 
         PrimaryIndexOperationTracker opTracker = dsr.getOpTracker();
         if (iInfo.getReferenceCount() != 0 || (opTracker != null && 
opTracker.getNumActiveOperations() != 0)) {
-            throw new HyracksDataException("Cannot remove index while it is 
open. (Dataset reference count = "
+            throw new HyracksDataException("Cannot remove index" + 
iInfo.getIndex()
+                    + " while it is open. (Dataset reference count = "
                     + iInfo.getReferenceCount() + ", Operation tracker number 
of active operations = "
                     + opTracker.getNumActiveOperations() + ")");
         }
@@ -196,6 +197,9 @@
             iInfo.setOpen(true);
         }
         iInfo.touch();
+        if 
(iInfo.getIndex().toString().endsWith("test/DBLP_idx_ngram_index/")) {
+            System.out.println("XXXX touch index " + iInfo.getIndex());
+        }
     }
 
     private boolean evictCandidateDataset() throws HyracksDataException {
@@ -266,19 +270,34 @@
 
     @Override
     public synchronized void close(String resourcePath) throws 
HyracksDataException {
-        validateDatasetLifecycleManagerState();
-        int did = getDIDfromResourcePath(resourcePath);
-        long resourceID = getResourceIDfromResourcePath(resourcePath);
-        DatasetResource dsr = datasets.get(did);
-        if (dsr == null) {
-            throw new HyracksDataException("No index found with resourceID " + 
resourceID);
+        DatasetResource dsr = null;
+        IndexInfo iInfo = null;
+        try {
+            validateDatasetLifecycleManagerState();
+            int did = getDIDfromResourcePath(resourcePath);
+            long resourceID = getResourceIDfromResourcePath(resourcePath);
+            dsr = datasets.get(did);
+            if (dsr == null) {
+                throw new HyracksDataException("No index found with resourceID 
" + resourceID);
+            }
+            iInfo = dsr.getIndexInfo(resourceID);
+            if (iInfo == null) {
+                throw new HyracksDataException("No index found with resourceID 
" + resourceID);
+            }
+        } finally {
+            try {
+                if (iInfo != null) {
+                    iInfo.untouch();
+                    if 
(iInfo.getIndex().toString().endsWith("test/DBLP_idx_ngram_index/")) {
+                        System.out.println("XXXX untouch index " + 
iInfo.getIndex());
+                    }
+                }
+            } finally {
+                if (dsr != null) {
+                    dsr.untouch();
+                }
+            }
         }
-        IndexInfo iInfo = dsr.getIndexInfo(resourceID);
-        if (iInfo == null) {
-            throw new HyracksDataException("No index found with resourceID " + 
resourceID);
-        }
-        iInfo.untouch();
-        dsr.untouch();
     }
 
     @Override
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/Info.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/Info.java
index 999eb34..8afae0d 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/Info.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/Info.java
@@ -39,10 +39,6 @@
         return referenceCount;
     }
 
-    public void setReferenceCount(int referenceCount) {
-        this.referenceCount = referenceCount;
-    }
-
     public boolean isOpen() {
         return isOpen;
     }
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/Servlets.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/Servlets.java
index 5ffb334..df57ebd 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/Servlets.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/Servlets.java
@@ -34,6 +34,7 @@
     public static final String CONNECTOR = "/connector";
     public static final String SHUTDOWN = "/admin/shutdown";
     public static final String VERSION = "/admin/version";
+    public static final String QUERY_CANCEL = "/admin/request/cancel/*";
     public static final String CLUSTER_STATE = "/admin/cluster/*";
     public static final String CLUSTER_STATE_NODE_DETAIL = 
"/admin/cluster/node/*";
     public static final String CLUSTER_STATE_CC_DETAIL = "/admin/cluster/cc/*";
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
index 037945a..c75c252 100644
--- 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
@@ -161,7 +161,6 @@
             frameOpCallback =
                     frameOpCallbackFactory.createFrameOperationCallback(ctx, 
(ILSMIndexAccessor) indexAccessor);
         } catch (Exception e) {
-            indexHelper.close();
             throw new HyracksDataException(e);
         }
     }
diff --git 
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/FileHandle.java
 
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/FileHandle.java
index 33b8980..560c2a4 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/FileHandle.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/FileHandle.java
@@ -68,7 +68,6 @@
                 throw new IllegalArgumentException();
         }
         raf = new RandomAccessFile(fileRef.getFile(), mode);
-        channel = raf.getChannel();
     }
 
     public void close() throws IOException {
@@ -80,10 +79,10 @@
     }
 
     public FileChannel getFileChannel() {
+        if (channel == null) {
+            channel = raf.getChannel();
+        }
         return channel;
     }
 
-    public void sync(boolean metadata) throws IOException {
-        channel.force(metadata);
-    }
 }
diff --git 
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/IOManager.java
 
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/IOManager.java
index 5ccdaa8..d97a7b5 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/IOManager.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/IOManager.java
@@ -324,7 +324,7 @@
     @Override
     public void sync(IFileHandle fileHandle, boolean metadata) throws 
HyracksDataException {
         try {
-            ((FileHandle) fileHandle).sync(metadata);
+            ((FileHandle) fileHandle).getFileChannel().force(metadata);
         } catch (IOException e) {
             throw new HyracksDataException(e);
         }
diff --git 
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/partitions/MaterializingPipelinedPartition.java
 
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/partitions/MaterializingPipelinedPartition.java
index 137ef37..cef3150 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/partitions/MaterializingPipelinedPartition.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/partitions/MaterializingPipelinedPartition.java
@@ -18,6 +18,7 @@
  */
 package org.apache.hyracks.control.nc.partitions;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.concurrent.Executor;
 import java.util.logging.Level;
@@ -51,7 +52,9 @@
 
     private FileReference fRef;
 
-    private IFileHandle handle;
+    private IFileHandle writeHandle;
+
+    private IFileHandle readHandle;
 
     private long size;
 
@@ -60,6 +63,8 @@
     private boolean failed;
 
     protected boolean flushRequest;
+
+    private Thread pushDataThread;
 
     private Level openCloseLevel = Level.FINE;
 
@@ -80,6 +85,13 @@
 
     @Override
     public void deallocate() {
+        if (readHandle != null) {
+            try {
+                ioManager.close(readHandle);
+            } catch (IOException e) {
+                LOGGER.log(Level.WARNING, e.getMessage(), e);
+            }
+        }
         if (fRef != null) {
             fRef.delete();
         }
@@ -87,70 +99,69 @@
 
     @Override
     public void writeTo(final IFrameWriter writer) {
-        executor.execute(new Runnable() {
+        Runnable dataPusher = new Runnable() {
             @Override
             public void run() {
                 try {
                     synchronized (MaterializingPipelinedPartition.this) {
-                        while (fRef == null && eos == false) {
+                        while (readHandle == null && !eos && !failed) {
                             MaterializingPipelinedPartition.this.wait();
                         }
                     }
-                    IFileHandle fh = fRef == null ? null
-                            : ioManager.open(fRef, 
IIOManager.FileReadWriteMode.READ_ONLY,
-                                    
IIOManager.FileSyncMode.METADATA_ASYNC_DATA_ASYNC);
+                    writer.open();
                     try {
-                        writer.open();
-                        try {
-                            if (fh != null) {
-                                long offset = 0;
-                                ByteBuffer buffer = ctx.allocateFrame();
-                                boolean fail = false;
-                                boolean done = false;
-                                while (!fail && !done) {
-                                    synchronized 
(MaterializingPipelinedPartition.this) {
-                                        while (offset >= size && !eos && 
!failed) {
-                                            if (flushRequest) {
-                                                flushRequest = false;
-                                                writer.flush();
-                                            }
-                                            try {
-                                                
MaterializingPipelinedPartition.this.wait();
-                                            } catch (InterruptedException e) {
-                                                throw new 
HyracksDataException(e);
-                                            }
-                                        }
-                                        flushRequest = false;
-                                        fail = failed;
-                                        done = eos && offset >= size;
+                        long offset = 0;
+                        ByteBuffer buffer = ctx.allocateFrame();
+                        boolean done = false;
+                        while (!done) {
+                            boolean flush;
+                            boolean fail;
+                            synchronized 
(MaterializingPipelinedPartition.this) {
+                                while (offset >= size && !eos && !failed) {
+                                    
MaterializingPipelinedPartition.this.wait();
                                     }
-                                    if (fail) {
-                                        writer.fail();
-                                    } else if (!done) {
-                                        buffer.clear();
-                                        long readLen = ioManager.syncRead(fh, 
offset, buffer);
-                                        if (readLen < buffer.capacity()) {
-                                            throw new 
HyracksDataException("Premature end of file");
-                                        }
-                                        offset += readLen;
-                                        buffer.flip();
-                                        writer.nextFrame(buffer);
+                                flush = flushRequest;
+                                flushRequest = false; // Clear the flush flag.
+                                fail = failed;
+                                done = eos && offset >= size;
+                            }
+                            if (fail) {
+                                writer.fail();
+                                break;
+                            }
+                            if (!done) {
+                                buffer.clear();
+                                long readLen = ioManager.syncRead(readHandle, 
offset, buffer);
+                                if (readLen < buffer.capacity()) {
+                                    throw new HyracksDataException("Premature 
end of file");
                                     }
+                                offset += readLen;
+                                buffer.flip();
+                                writer.nextFrame(buffer);
                                 }
+                            if (flush) {
+                                writer.flush();
+                            }
+                        }
+                    } catch (Exception e) {
+                        writer.fail();
+                        throw e;
+                    } finally {
+                        try {
+                            if (readHandle != null) {
+                                ioManager.close(readHandle); // close is 
idempotent.
                             }
                         } finally {
                             writer.close();
                         }
-                    } finally {
-                        if (fh != null) {
-                            ioManager.close(fh);
-                        }
                     }
                 } catch (Exception e) {
-                    throw new RuntimeException(e);
+                    LOGGER.log(Level.SEVERE, e.getMessage(), e);
                 }
             }
-        });
+        };
+        pushDataThread = new Thread(dataPusher);
+        executor.execute(pushDataThread);
     }
 
     @Override
@@ -172,7 +183,9 @@
     private void checkOrCreateFile() throws HyracksDataException {
         if (fRef == null) {
             fRef = 
manager.getFileFactory().createUnmanagedWorkspaceFile(pid.toString().replace(":",
 "$"));
-            handle = ctx.getIOManager().open(fRef, 
IIOManager.FileReadWriteMode.READ_WRITE,
+            writeHandle = ioManager.open(fRef, 
IIOManager.FileReadWriteMode.READ_WRITE,
+                    IIOManager.FileSyncMode.METADATA_ASYNC_DATA_ASYNC);
+            readHandle = ioManager.open(fRef, 
IIOManager.FileReadWriteMode.READ_ONLY,
                     IIOManager.FileSyncMode.METADATA_ASYNC_DATA_ASYNC);
         }
     }
@@ -180,7 +193,7 @@
     @Override
     public synchronized void nextFrame(ByteBuffer buffer) throws 
HyracksDataException {
         checkOrCreateFile();
-        size += ctx.getIOManager().syncWrite(handle, size, buffer);
+        size += ctx.getIOManager().syncWrite(writeHandle, size, buffer);
         notifyAll();
     }
 
@@ -195,12 +208,12 @@
         if (LOGGER.isLoggable(openCloseLevel)) {
             LOGGER.log(openCloseLevel, "close(" + pid + " by " + taId);
         }
+        if (writeHandle != null) {
+            ctx.getIOManager().close(writeHandle);
+        }
         synchronized (this) {
             eos = true;
-            if (handle != null) {
-                ctx.getIOManager().close(handle);
-            }
-            handle = null;
+            writeHandle = null;
             notifyAll();
         }
     }
@@ -210,4 +223,5 @@
         flushRequest = true;
         notifyAll();
     }
+
 }
\ No newline at end of file
diff --git 
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/partitions/PipelinedPartition.java
 
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/partitions/PipelinedPartition.java
index 84d2283..fd434d7 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/partitions/PipelinedPartition.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/partitions/PipelinedPartition.java
@@ -76,12 +76,12 @@
         manager.registerPartition(pid, taId, this, PartitionState.STARTED, 
false);
         failed = false;
         pendingConnection = true;
+        ensureConnected();
     }
 
     @Override
     public void nextFrame(ByteBuffer buffer) throws HyracksDataException {
         if (!failed) {
-            ensureConnected();
             delegate.nextFrame(buffer);
         }
     }
@@ -113,7 +113,6 @@
     @Override
     public void close() throws HyracksDataException {
         if (!failed) {
-            ensureConnected();
             delegate.close();
         }
     }
@@ -121,7 +120,6 @@
     @Override
     public void flush() throws HyracksDataException {
         if (!failed) {
-            ensureConnected();
             delegate.flush();
         }
     }
diff --git 
a/hyracks-fullstack/hyracks/hyracks-dataflow-common/src/main/java/org/apache/hyracks/dataflow/common/io/RunFileReader.java
 
b/hyracks-fullstack/hyracks/hyracks-dataflow-common/src/main/java/org/apache/hyracks/dataflow/common/io/RunFileReader.java
index f0bd318..ffee1a6 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-dataflow-common/src/main/java/org/apache/hyracks/dataflow/common/io/RunFileReader.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-dataflow-common/src/main/java/org/apache/hyracks/dataflow/common/io/RunFileReader.java
@@ -84,6 +84,9 @@
 
     @Override
     public void close() throws HyracksDataException {
+        if (handle == null) {
+            return; // Makes sure the close operation is idempotent.
+        }
         if (deleteAfterClose) {
             try {
                 ioManager.close(handle);
@@ -94,6 +97,7 @@
         } else {
             ioManager.close(handle);
         }
+        handle = null;
     }
 
     public long getFileSize() {
diff --git 
a/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/connectors/PartitionDataWriter.java
 
b/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/connectors/PartitionDataWriter.java
index dbd3afa..0ac8cec 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/connectors/PartitionDataWriter.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/connectors/PartitionDataWriter.java
@@ -74,19 +74,29 @@
     @Override
     public void close() throws HyracksDataException {
         HyracksDataException closeException = null;
+        if (!failed) {
+            boolean newFailure = false;
+            for (int i = 0; i < pWriters.length; ++i) {
+                try {
+                    if (isOpen[i] && allocatedFrames[i] && 
appenders[i].getTupleCount() > 0) {
+                        appenders[i].write(pWriters[i], true);
+                    }
+                } catch (Exception e) {
+                    newFailure = true;
+                    closeException = HyracksDataException.create(e);
+                    break;
+                }
+            }
+            if (newFailure) {
+                fail(); // Fail all writers if any new failure happens.
+            }
+        }
         for (int i = 0; i < pWriters.length; ++i) {
             if (isOpen[i]) {
-                if (allocatedFrames[i] && appenders[i].getTupleCount() > 0 && 
!failed) {
-                    try {
-                        appenders[i].write(pWriters[i], true);
-                    } catch (Throwable th) {
-                        closeException = 
HyracksDataException.suppress(closeException, th);
-                    }
-                }
                 try {
                     pWriters[i].close();
-                } catch (Throwable th) {
-                    closeException = 
HyracksDataException.suppress(closeException, th);
+                } catch (Exception e) {
+                    closeException = HyracksDataException.create(e);
                 }
             }
         }
@@ -129,14 +139,15 @@
             if (isOpen[i]) {
                 try {
                     pWriters[i].fail();
-                } catch (Throwable th) {
-                    failException = 
HyracksDataException.suppress(failException, th);
+                } catch (Exception e) {
+                    failException = HyracksDataException.create(e);
                 }
             }
         }
         if (failException != null) {
             throw failException;
         }
+        failed = true;
     }
 
     @Override
diff --git 
a/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/sort/AbstractExternalSortRunMerger.java
 
b/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/sort/AbstractExternalSortRunMerger.java
index f4158ac..89238e5 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/sort/AbstractExternalSortRunMerger.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/sort/AbstractExternalSortRunMerger.java
@@ -35,6 +35,7 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.dataflow.common.comm.util.FrameUtils;
 import org.apache.hyracks.dataflow.common.io.GeneratedRunFileReader;
+import org.apache.hyracks.dataflow.common.io.RunFileReader;
 import org.apache.hyracks.dataflow.common.io.RunFileWriter;
 import org.apache.hyracks.dataflow.std.sort.util.GroupVSizeFrame;
 
@@ -167,11 +168,18 @@
             if (finalWriter != null) {
                 finalWriter.fail();
             }
-            throw new HyracksDataException(e);
+            throw HyracksDataException.create(e);
         } finally {
-            if (finalWriter != null) {
-                finalWriter.close();
+            try {
+                for (RunFileReader reader : runs) {
+                    reader.close(); // close is idempotent.
+                }
+            } finally {
+                if (finalWriter != null) {
+                    finalWriter.close();
+                }
             }
+
         }
     }
 
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java
index c6d4e35..40366da 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java
@@ -123,6 +123,7 @@
         }
     }
 
+
     @Override
     public void close() throws HyracksDataException {
         synchronized (lcManager) {
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexSearchOperatorNodePushable.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexSearchOperatorNodePushable.java
index c089854..09823aa 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexSearchOperatorNodePushable.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexSearchOperatorNodePushable.java
@@ -71,6 +71,7 @@
     protected final int[] maxFilterFieldIndexes;
     protected PermutingFrameTupleReference minFilterKey;
     protected PermutingFrameTupleReference maxFilterKey;
+    private boolean failed = false;
 
     public IndexSearchOperatorNodePushable(IIndexOperatorDescriptor opDesc, 
IHyracksTaskContext ctx, int partition,
             IRecordDescriptorProvider recordDescProvider, int[] 
minFilterFieldIndexes, int[] maxFilterFieldIndexes)
@@ -196,53 +197,50 @@
 
     @Override
     public void close() throws HyracksDataException {
-        HyracksDataException closeException = null;
-        if (index != null) {
-            // if index == null, then the index open was not successful
+        try {
+            HyracksDataException closeException = null;
+            if (index == null) {
+                // if index == null, then the index open was not successful
+                return;
+            }
             try {
-                if (appender.getTupleCount() > 0) {
+                if (appender.getTupleCount() > 0 && !failed) {
                     appender.write(writer, true);
                 }
-            } catch (Throwable th) {
-                closeException = new HyracksDataException(th);
+            } catch (Exception e) {
+                closeException = HyracksDataException.create(e);
             }
 
             try {
                 cursor.close();
-            } catch (Throwable th) {
+            } catch (Exception e) {
                 if (closeException == null) {
-                    closeException = new HyracksDataException(th);
+                    closeException = HyracksDataException.create(e);
                 } else {
-                    closeException.addSuppressed(th);
+                    closeException.addSuppressed(e);
                 }
             }
+
             try {
                 indexHelper.close();
-            } catch (Throwable th) {
+            } catch (Exception e) {
                 if (closeException == null) {
-                    closeException = new HyracksDataException(th);
+                    closeException = HyracksDataException.create(e);
                 } else {
-                    closeException.addSuppressed(th);
+                    closeException.addSuppressed(e);
                 }
             }
-        }
-        try {
-            // will definitely be called regardless of exceptions
-            writer.close();
-        } catch (Throwable th) {
-            if (closeException == null) {
-                closeException = new HyracksDataException(th);
-            } else {
-                closeException.addSuppressed(th);
+            if (closeException != null) {
+                throw closeException;
             }
-        }
-        if (closeException != null) {
-            throw closeException;
+        } finally {
+            writer.close();
         }
     }
 
     @Override
     public void fail() throws HyracksDataException {
         writer.fail();
+        failed = true;
     }
 }
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorNodePushable.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorNodePushable.java
index 91d433c..4e6c6ad 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorNodePushable.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorNodePushable.java
@@ -94,8 +94,11 @@
             writer.fail();
             throw new HyracksDataException(e);
         } finally {
-            writer.close();
-            treeIndexHelper.close();
+            try {
+                treeIndexHelper.close();
+            } finally {
+                writer.close();
+            }
         }
     }
 }
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/dataflow/LSMIndexCompactOperatorNodePushable.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/dataflow/LSMIndexCompactOperatorNodePushable.java
index 48f59f1..b787994 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/dataflow/LSMIndexCompactOperatorNodePushable.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/dataflow/LSMIndexCompactOperatorNodePushable.java
@@ -62,8 +62,9 @@
         try {
             accessor.scheduleFullMerge(NoOpIOOperationCallback.INSTANCE);
         } catch (Exception e) {
+            throw HyracksDataException.create(e);
+        } finally {
             indexHelper.close();
-            throw new HyracksDataException(e);
         }
     }
 

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2936ac83f71bbef533e2695ed0a2b220c23fc483
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Yingyi Bu <buyin...@gmail.com>

Reply via email to