You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by ji...@apache.org on 2017/08/27 08:03:26 UTC

[01/12] incubator-quickstep git commit: Minor changes in QueryManager and QueryExecutionState. [Forced Update!]

Repository: incubator-quickstep
Updated Branches:
  refs/heads/copy-to 30e0221c4 -> 1e32afc81 (forced update)


Minor changes in QueryManager and QueryExecutionState.


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/09ccb7ca
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/09ccb7ca
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/09ccb7ca

Branch: refs/heads/copy-to
Commit: 09ccb7ca75dd914ece283ca6b8dc2ae759b12e48
Parents: c018882
Author: Zuyu Zhang <zu...@cs.wisc.edu>
Authored: Sat Aug 26 13:01:12 2017 -0500
Committer: Zuyu Zhang <zu...@cs.wisc.edu>
Committed: Sat Aug 26 13:13:25 2017 -0500

----------------------------------------------------------------------
 query_execution/QueryExecutionState.hpp    | 19 ++++++++-----------
 query_execution/QueryManagerBase.cpp       |  1 -
 query_execution/QueryManagerSingleNode.cpp | 18 +++++++++---------
 query_execution/QueryManagerSingleNode.hpp |  6 ++++--
 4 files changed, 21 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/09ccb7ca/query_execution/QueryExecutionState.hpp
----------------------------------------------------------------------
diff --git a/query_execution/QueryExecutionState.hpp b/query_execution/QueryExecutionState.hpp
index a4273dc..0f98964 100644
--- a/query_execution/QueryExecutionState.hpp
+++ b/query_execution/QueryExecutionState.hpp
@@ -99,14 +99,10 @@ class QueryExecutionState {
                                const bool rebuild_initiated) {
     DCHECK(operator_index < num_operators_);
     auto search_res = rebuild_status_.find(operator_index);
-    if (search_res != rebuild_status_.end()) {
-      search_res->second.has_initiated = rebuild_initiated;
-      search_res->second.num_pending_workorders = num_rebuild_workorders;
-    } else {
-      RebuildStatus rebuild_status(rebuild_initiated, num_rebuild_workorders);
+    DCHECK(search_res != rebuild_status_.end());
 
-      rebuild_status_.emplace(operator_index, std::move(rebuild_status));
-    }
+    search_res->second.has_initiated = rebuild_initiated;
+    search_res->second.num_pending_workorders = num_rebuild_workorders;
   }
 
 #ifdef QUICKSTEP_DISTRIBUTED
@@ -272,6 +268,8 @@ class QueryExecutionState {
   inline void setRebuildRequired(const std::size_t operator_index) {
     DCHECK(operator_index < num_operators_);
     rebuild_required_[operator_index] = true;
+
+    rebuild_status_.emplace(operator_index, RebuildStatus());
   }
 
   /**
@@ -353,10 +351,9 @@ class QueryExecutionState {
   std::vector<bool> execution_finished_;
 
   struct RebuildStatus {
-    RebuildStatus(const bool initiated,
-                  const std::size_t num_workorders)
-        : has_initiated(initiated),
-          num_pending_workorders(num_workorders) {}
+    RebuildStatus()
+        : has_initiated(false),
+          num_pending_workorders(0) {}
 
     // Whether rebuild for operator at index i has been initiated.
     bool has_initiated;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/09ccb7ca/query_execution/QueryManagerBase.cpp
----------------------------------------------------------------------
diff --git a/query_execution/QueryManagerBase.cpp b/query_execution/QueryManagerBase.cpp
index 14c9ba5..f353b64 100644
--- a/query_execution/QueryManagerBase.cpp
+++ b/query_execution/QueryManagerBase.cpp
@@ -64,7 +64,6 @@ QueryManagerBase::QueryManagerBase(QueryHandle *query_handle)
     if (insert_destination_index != QueryContext::kInvalidInsertDestinationId) {
       // Rebuild is necessary whenever InsertDestination is present.
       query_exec_state_->setRebuildRequired(node_index);
-      query_exec_state_->setRebuildStatus(node_index, 0, false);
     }
 
     for (const pair<dag_node_index, bool> &dependent_link :

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/09ccb7ca/query_execution/QueryManagerSingleNode.cpp
----------------------------------------------------------------------
diff --git a/query_execution/QueryManagerSingleNode.cpp b/query_execution/QueryManagerSingleNode.cpp
index 001faa8..82a0de6 100644
--- a/query_execution/QueryManagerSingleNode.cpp
+++ b/query_execution/QueryManagerSingleNode.cpp
@@ -126,22 +126,20 @@ bool QueryManagerSingleNode::initiateRebuild(const dag_node_index index) {
   DCHECK(checkRebuildRequired(index));
   DCHECK(!checkRebuildInitiated(index));
 
-  getRebuildWorkOrders(index, workorders_container_.get());
+  const std::size_t num_rebuild_work_orders = getRebuildWorkOrders(index, workorders_container_.get());
+  DCHECK_EQ(workorders_container_->getNumRebuildWorkOrders(index), num_rebuild_work_orders);
 
   query_exec_state_->setRebuildStatus(
-      index, workorders_container_->getNumRebuildWorkOrders(index), true);
+      index, num_rebuild_work_orders, true);
 
-  return (query_exec_state_->getNumRebuildWorkOrders(index) == 0);
+  return num_rebuild_work_orders == 0;
 }
 
-void QueryManagerSingleNode::getRebuildWorkOrders(const dag_node_index index,
-                                                  WorkOrdersContainer *container) {
+std::size_t QueryManagerSingleNode::getRebuildWorkOrders(const dag_node_index index,
+                                                         WorkOrdersContainer *container) {
   const RelationalOperator &op = query_dag_->getNodePayload(index);
   const QueryContext::insert_destination_id insert_destination_index = op.getInsertDestinationID();
-
-  if (insert_destination_index == QueryContext::kInvalidInsertDestinationId) {
-    return;
-  }
+  DCHECK_NE(insert_destination_index, QueryContext::kInvalidInsertDestinationId);
 
   std::vector<MutableBlockReference> partially_filled_block_refs;
   std::vector<partition_id> part_ids;
@@ -165,6 +163,8 @@ void QueryManagerSingleNode::getRebuildWorkOrders(const dag_node_index index,
                              bus_),
         index);
   }
+
+  return partially_filled_block_refs.size();
 }
 
 std::size_t QueryManagerSingleNode::getQueryMemoryConsumptionBytes() const {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/09ccb7ca/query_execution/QueryManagerSingleNode.hpp
----------------------------------------------------------------------
diff --git a/query_execution/QueryManagerSingleNode.hpp b/query_execution/QueryManagerSingleNode.hpp
index 6c5e38e..f9d038b 100644
--- a/query_execution/QueryManagerSingleNode.hpp
+++ b/query_execution/QueryManagerSingleNode.hpp
@@ -122,9 +122,11 @@ class QueryManagerSingleNode final : public QueryManagerBase {
    * @param index The index of the operator in the query plan DAG.
    * @param container A pointer to a WorkOrdersContainer to be used to store the
    *        generated WorkOrders.
+   *
+   * @return The number of generated rebuild work orders.
    **/
-  void getRebuildWorkOrders(const dag_node_index index,
-                            WorkOrdersContainer *container);
+  std::size_t getRebuildWorkOrders(const dag_node_index index,
+                                   WorkOrdersContainer *container);
 
   /**
    * @brief Get the total memory (in bytes) occupied by temporary relations


[04/12] incubator-quickstep git commit: Added num_partitions in RelationalOperator.

Posted by ji...@apache.org.
Added num_partitions in RelationalOperator.


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/942a15be
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/942a15be
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/942a15be

Branch: refs/heads/copy-to
Commit: 942a15bee482ffedef757d9b0d808f154606af3f
Parents: 32b5b83
Author: Zuyu Zhang <zu...@cs.wisc.edu>
Authored: Wed Aug 9 12:59:45 2017 -0500
Committer: Zuyu Zhang <zu...@cs.wisc.edu>
Committed: Sun Aug 27 00:50:53 2017 -0500

----------------------------------------------------------------------
 catalog/CMakeLists.txt                          |  1 +
 catalog/CatalogRelation.cpp                     |  5 ++
 catalog/CatalogRelation.hpp                     | 11 ++++
 query_optimizer/ExecutionGenerator.cpp          | 68 ++++++--------------
 relational_operators/AggregationOperator.hpp    |  4 +-
 .../BuildAggregationExistenceMapOperator.hpp    |  4 +-
 relational_operators/BuildHashOperator.hpp      |  7 +-
 relational_operators/BuildLIPFilterOperator.hpp | 13 +---
 relational_operators/CMakeLists.txt             |  5 +-
 relational_operators/CreateIndexOperator.hpp    |  2 +-
 relational_operators/CreateTableOperator.hpp    |  2 +-
 relational_operators/DeleteOperator.cpp         | 61 +++++++++++-------
 relational_operators/DeleteOperator.hpp         | 34 +++++++---
 .../DestroyAggregationStateOperator.hpp         |  4 +-
 relational_operators/DestroyHashOperator.cpp    |  4 +-
 relational_operators/DestroyHashOperator.hpp    |  8 +--
 .../FinalizeAggregationOperator.hpp             |  5 +-
 relational_operators/HashJoinOperator.hpp       |  4 +-
 .../InitializeAggregationOperator.hpp           |  5 +-
 .../NestedLoopsJoinOperator.hpp                 |  5 +-
 relational_operators/RelationalOperator.hpp     | 18 +++++-
 relational_operators/SaveBlocksOperator.cpp     | 43 +++++++------
 relational_operators/SaveBlocksOperator.hpp     | 17 +++--
 relational_operators/SelectOperator.hpp         | 29 ++++-----
 relational_operators/UpdateOperator.cpp         | 64 ++++++++++--------
 relational_operators/UpdateOperator.hpp         | 24 +++++--
 relational_operators/WorkOrder.proto            |  3 +
 relational_operators/WorkOrderFactory.cpp       | 31 +++++++--
 28 files changed, 266 insertions(+), 215 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/catalog/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/catalog/CMakeLists.txt b/catalog/CMakeLists.txt
index 0ca014e..1aa2b41 100644
--- a/catalog/CMakeLists.txt
+++ b/catalog/CMakeLists.txt
@@ -108,6 +108,7 @@ target_link_libraries(quickstep_catalog_CatalogRelation
                       quickstep_catalog_Catalog_proto
                       quickstep_catalog_IndexScheme
                       quickstep_catalog_PartitionScheme
+                      quickstep_catalog_PartitionSchemeHeader
                       quickstep_storage_StorageBlockInfo
                       quickstep_storage_StorageBlockLayout
                       quickstep_storage_StorageBlockLayout_proto

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/catalog/CatalogRelation.cpp
----------------------------------------------------------------------
diff --git a/catalog/CatalogRelation.cpp b/catalog/CatalogRelation.cpp
index 793fc2d..38c86f6 100644
--- a/catalog/CatalogRelation.cpp
+++ b/catalog/CatalogRelation.cpp
@@ -33,6 +33,7 @@
 #endif
 
 #include "catalog/PartitionScheme.hpp"
+#include "catalog/PartitionSchemeHeader.hpp"
 #include "storage/StorageBlockInfo.hpp"
 #include "storage/StorageBlockLayout.hpp"
 #include "storage/StorageBlockLayout.pb.h"
@@ -180,6 +181,10 @@ serialization::CatalogRelationSchema CatalogRelation::getProto() const {
 void CatalogRelation::setPartitionScheme(PartitionScheme* partition_scheme) {
   DCHECK_EQ(0u, size_blocks());
   partition_scheme_.reset(partition_scheme);
+
+  if (partition_scheme_) {
+    num_partitions_ = partition_scheme_->getPartitionSchemeHeader().getNumPartitions();
+  }
 }
 
 void CatalogRelation::setDefaultStorageBlockLayout(StorageBlockLayout *default_layout) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/catalog/CatalogRelation.hpp
----------------------------------------------------------------------
diff --git a/catalog/CatalogRelation.hpp b/catalog/CatalogRelation.hpp
index af7f273..e40b599 100644
--- a/catalog/CatalogRelation.hpp
+++ b/catalog/CatalogRelation.hpp
@@ -81,6 +81,7 @@ class CatalogRelation : public CatalogRelationSchema {
                   bool temporary = false)
       : CatalogRelationSchema(parent, name, id, temporary),
         default_layout_(nullptr),
+        num_partitions_(1u),
         statistics_(new CatalogRelationStatistics()) {
   }
 
@@ -138,6 +139,15 @@ class CatalogRelation : public CatalogRelationSchema {
   }
 
   /**
+   * @brief Get the number of partitions for the relation.
+   *
+   * @return The number of partitions the relation is partitioned into.
+   **/
+  std::size_t getNumPartitions() const {
+    return num_partitions_;
+  }
+
+  /**
    * @brief Check if a NUMA placement scheme is available for the relation.
    *
    * @return True if the relation has a NUMA placement scheme, false otherwise.
@@ -423,6 +433,7 @@ class CatalogRelation : public CatalogRelationSchema {
   // A relation may or may not have a Partition Scheme
   // assosiated with it.
   std::unique_ptr<PartitionScheme> partition_scheme_;
+  std::size_t num_partitions_;
 
   // Index scheme associated with this relation.
   // Defines a set of indices defined for this relation.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/query_optimizer/ExecutionGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/ExecutionGenerator.cpp b/query_optimizer/ExecutionGenerator.cpp
index 9bfd136..d43432c 100644
--- a/query_optimizer/ExecutionGenerator.cpp
+++ b/query_optimizer/ExecutionGenerator.cpp
@@ -747,13 +747,6 @@ void ExecutionGenerator::convertSelection(
                                  insert_destination_proto);
 
   // Create and add a Select operator.
-  const PartitionScheme *input_partition_scheme = input_relation.getPartitionScheme();
-
-  const std::size_t num_partitions =
-      input_partition_scheme
-          ? input_partition_scheme->getPartitionSchemeHeader().getNumPartitions()
-          : 1u;
-
   // Use the "simple" form of the selection operator (a pure projection that
   // doesn't require any expression evaluation or intermediate copies) if
   // possible.
@@ -766,16 +759,14 @@ void ExecutionGenerator::convertSelection(
                                insert_destination_index,
                                execution_predicate_index,
                                move(attributes),
-                               input_relation_info->isStoredRelation(),
-                               num_partitions)
+                               input_relation_info->isStoredRelation())
           : new SelectOperator(query_handle_->query_id(),
                                input_relation,
                                *output_relation,
                                insert_destination_index,
                                execution_predicate_index,
                                project_expressions_group_index,
-                               input_relation_info->isStoredRelation(),
-                               num_partitions);
+                               input_relation_info->isStoredRelation());
 
   const QueryPlan::DAGNodeIndex select_index =
       execution_plan_->addRelationalOperator(op);
@@ -847,12 +838,6 @@ void ExecutionGenerator::convertFilterJoin(const P::FilterJoinPtr &physical_plan
       findRelationInfoOutputByPhysical(build_physical);
 
   const CatalogRelation &build_relation = *build_relation_info->relation;
-  const PartitionScheme *build_partition_scheme = build_relation.getPartitionScheme();
-
-  const std::size_t build_num_partitions =
-      build_partition_scheme
-          ? build_partition_scheme->getPartitionSchemeHeader().getNumPartitions()
-          : 1u;
 
   // Create a BuildLIPFilterOperator for the FilterJoin. This operator builds
   // LIP filters that are applied properly in downstream operators to achieve
@@ -862,7 +847,6 @@ void ExecutionGenerator::convertFilterJoin(const P::FilterJoinPtr &physical_plan
           new BuildLIPFilterOperator(
               query_handle_->query_id(),
               build_relation,
-              build_num_partitions,
               build_side_predicate_index,
               build_relation_info->isStoredRelation()));
 
@@ -954,7 +938,7 @@ void ExecutionGenerator::convertHashJoin(const P::HashJoinPtr &physical_plan) {
 
   const CatalogRelationInfo *build_relation_info =
       findRelationInfoOutputByPhysical(build_physical);
-  const CatalogRelationInfo *probe_operator_info =
+  const CatalogRelationInfo *probe_relation_info =
       findRelationInfoOutputByPhysical(probe_physical);
 
   // Create a vector that indicates whether each project expression is using
@@ -970,9 +954,10 @@ void ExecutionGenerator::convertHashJoin(const P::HashJoinPtr &physical_plan) {
   }
 
   const CatalogRelation *build_relation = build_relation_info->relation;
+  const CatalogRelation *probe_relation = probe_relation_info->relation;
 
   // FIXME(quickstep-team): Add support for self-join.
-  if (build_relation == probe_operator_info->relation) {
+  if (build_relation == probe_relation) {
     THROW_SQL_ERROR() << "Self-join is not supported";
   }
 
@@ -982,9 +967,7 @@ void ExecutionGenerator::convertHashJoin(const P::HashJoinPtr &physical_plan) {
   S::QueryContext::HashTableContext *hash_table_context_proto =
       query_context_proto_->add_join_hash_tables();
 
-  const P::PartitionSchemeHeader *probe_partition_scheme_header = probe_physical->getOutputPartitionSchemeHeader();
-  const std::size_t probe_num_partitions =
-      probe_partition_scheme_header ? probe_partition_scheme_header->num_partitions : 1u;
+  const std::size_t probe_num_partitions = probe_relation->getNumPartitions();
   hash_table_context_proto->set_num_partitions(probe_num_partitions);
 
   S::HashTable *hash_table_proto = hash_table_context_proto->mutable_join_hash_table();
@@ -1052,8 +1035,8 @@ void ExecutionGenerator::convertHashJoin(const P::HashJoinPtr &physical_plan) {
           new HashJoinOperator(
               query_handle_->query_id(),
               *build_relation,
-              *probe_operator_info->relation,
-              probe_operator_info->isStoredRelation(),
+              *probe_relation,
+              probe_relation_info->isStoredRelation(),
               probe_attribute_ids,
               any_probe_attributes_nullable,
               probe_num_partitions,
@@ -1083,9 +1066,9 @@ void ExecutionGenerator::convertHashJoin(const P::HashJoinPtr &physical_plan) {
                                          build_relation_info->producer_operator_index,
                                          true /* is_pipeline_breaker */);
   }
-  if (!probe_operator_info->isStoredRelation()) {
+  if (!probe_relation_info->isStoredRelation()) {
     execution_plan_->addDirectDependency(join_operator_index,
-                                         probe_operator_info->producer_operator_index,
+                                         probe_relation_info->producer_operator_index,
                                          false /* is_pipeline_breaker */);
   }
   execution_plan_->addDirectDependency(join_operator_index,
@@ -1140,15 +1123,11 @@ void ExecutionGenerator::convertNestedLoopsJoin(
     THROW_SQL_ERROR() << "NestedLoopsJoin does not support self-join yet";
   }
 
-  const PartitionScheme *left_partition_scheme = left_relation.getPartitionScheme();
-  const std::size_t num_partitions =
-      left_partition_scheme ? left_partition_scheme->getPartitionSchemeHeader().getNumPartitions()
-                            : 1u;
+  const std::size_t num_partitions = left_relation.getNumPartitions();
 
 #ifdef QUICKSTEP_DEBUG
-  const PartitionScheme *right_partition_scheme = right_relation.getPartitionScheme();
-  if (right_partition_scheme) {
-    DCHECK_EQ(num_partitions, right_partition_scheme->getPartitionSchemeHeader().getNumPartitions());
+  if (right_relation.hasPartitionScheme()) {
+    DCHECK_EQ(num_partitions, right_relation.getNumPartitions());
   }
 #endif
 
@@ -1549,12 +1528,6 @@ void ExecutionGenerator::convertInsertSelection(
   const CatalogRelationInfo *selection_relation_info =
       findRelationInfoOutputByPhysical(physical_plan->selection());
   const CatalogRelation &selection_relation = *selection_relation_info->relation;
-  const PartitionScheme *selection_partition_scheme = selection_relation.getPartitionScheme();
-
-  const std::size_t num_partitions =
-      selection_partition_scheme
-          ? selection_partition_scheme->getPartitionSchemeHeader().getNumPartitions()
-          : 1u;
 
   // Prepare the attributes, which are output columns of the selection relation.
   std::vector<attribute_id> attributes;
@@ -1580,8 +1553,7 @@ void ExecutionGenerator::convertInsertSelection(
                          insert_destination_index,
                          QueryContext::kInvalidPredicateId,
                          move(attributes),
-                         selection_relation_info->isStoredRelation(),
-                         num_partitions);
+                         selection_relation_info->isStoredRelation());
 
   const QueryPlan::DAGNodeIndex insert_selection_index =
       execution_plan_->addRelationalOperator(insert_selection_op);
@@ -1756,11 +1728,7 @@ void ExecutionGenerator::convertAggregate(
   const CatalogRelationInfo *input_relation_info =
       findRelationInfoOutputByPhysical(physical_plan->input());
   const CatalogRelation &input_relation = *input_relation_info->relation;
-  const PartitionScheme *input_partition_scheme = input_relation.getPartitionScheme();
-  const size_t num_partitions =
-      input_partition_scheme
-          ? input_partition_scheme->getPartitionSchemeHeader().getNumPartitions()
-          : 1u;
+  const size_t num_partitions = input_relation.getNumPartitions();
 
   // Create aggr state proto.
   const QueryContext::aggregation_state_id aggr_state_index =
@@ -2312,7 +2280,9 @@ void ExecutionGenerator::convertWindowAggregate(
   // Get input.
   const CatalogRelationInfo *input_relation_info =
       findRelationInfoOutputByPhysical(physical_plan->input());
-  window_aggr_state_proto->set_input_relation_id(input_relation_info->relation->getID());
+  const CatalogRelation &input_relation = *input_relation_info->relation;
+  DCHECK_EQ(1u, input_relation.getNumPartitions());
+  window_aggr_state_proto->set_input_relation_id(input_relation.getID());
 
   // Get window aggregate function expression.
   const E::AliasPtr &named_window_aggregate_expression =
@@ -2382,7 +2352,7 @@ void ExecutionGenerator::convertWindowAggregate(
   const QueryPlan::DAGNodeIndex window_aggregation_operator_index =
       execution_plan_->addRelationalOperator(
           new WindowAggregationOperator(query_handle_->query_id(),
-                                        *input_relation_info->relation,
+                                        input_relation,
                                         *output_relation,
                                         window_aggr_state_index,
                                         insert_destination_index));

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/AggregationOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/AggregationOperator.hpp b/relational_operators/AggregationOperator.hpp
index 2fb620b..c673ff5 100644
--- a/relational_operators/AggregationOperator.hpp
+++ b/relational_operators/AggregationOperator.hpp
@@ -76,11 +76,10 @@ class AggregationOperator : public RelationalOperator {
                       bool input_relation_is_stored,
                       const QueryContext::aggregation_state_id aggr_state_index,
                       const std::size_t num_partitions)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, num_partitions),
         input_relation_(input_relation),
         input_relation_is_stored_(input_relation_is_stored),
         aggr_state_index_(aggr_state_index),
-        num_partitions_(num_partitions),
         input_relation_block_ids_(num_partitions),
         num_workorders_generated_(num_partitions),
         started_(false) {
@@ -136,7 +135,6 @@ class AggregationOperator : public RelationalOperator {
   const CatalogRelation &input_relation_;
   const bool input_relation_is_stored_;
   const QueryContext::aggregation_state_id aggr_state_index_;
-  const std::size_t num_partitions_;
 
   // The index is the partition id.
   std::vector<BlocksInPartition> input_relation_block_ids_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/BuildAggregationExistenceMapOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/BuildAggregationExistenceMapOperator.hpp b/relational_operators/BuildAggregationExistenceMapOperator.hpp
index 8791a38..9cfd93d 100644
--- a/relational_operators/BuildAggregationExistenceMapOperator.hpp
+++ b/relational_operators/BuildAggregationExistenceMapOperator.hpp
@@ -79,12 +79,11 @@ class BuildAggregationExistenceMapOperator : public RelationalOperator {
                                        const bool input_relation_is_stored,
                                        const QueryContext::aggregation_state_id aggr_state_index,
                                        const std::size_t num_partitions)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, num_partitions),
         input_relation_(input_relation),
         build_attribute_(build_attribute),
         input_relation_is_stored_(input_relation_is_stored),
         aggr_state_index_(aggr_state_index),
-        num_partitions_(num_partitions),
         input_relation_block_ids_(num_partitions),
         num_workorders_generated_(num_partitions),
         started_(false) {
@@ -138,7 +137,6 @@ class BuildAggregationExistenceMapOperator : public RelationalOperator {
   const attribute_id build_attribute_;
   const bool input_relation_is_stored_;
   const QueryContext::aggregation_state_id aggr_state_index_;
-  const std::size_t num_partitions_;
 
   // The index is the partition id.
   std::vector<BlocksInPartition> input_relation_block_ids_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/BuildHashOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/BuildHashOperator.hpp b/relational_operators/BuildHashOperator.hpp
index d18d9fb..dfb6dfe 100644
--- a/relational_operators/BuildHashOperator.hpp
+++ b/relational_operators/BuildHashOperator.hpp
@@ -89,12 +89,11 @@ class BuildHashOperator : public RelationalOperator {
                     const bool any_join_key_attributes_nullable,
                     const std::size_t num_partitions,
                     const QueryContext::join_hash_table_id hash_table_index)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, num_partitions),
         input_relation_(input_relation),
         input_relation_is_stored_(input_relation_is_stored),
         join_key_attributes_(join_key_attributes),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        num_partitions_(num_partitions),
         is_broadcast_join_(num_partitions > 1u && !input_relation.hasPartitionScheme()),
         hash_table_index_(hash_table_index),
         input_relation_block_ids_(num_partitions),
@@ -102,8 +101,9 @@ class BuildHashOperator : public RelationalOperator {
         started_(false) {
     if (input_relation_is_stored) {
       if (input_relation.hasPartitionScheme()) {
+        DCHECK_EQ(num_partitions_, input_relation.getNumPartitions());
+
         const PartitionScheme &part_scheme = *input_relation.getPartitionScheme();
-        DCHECK_EQ(part_scheme.getPartitionSchemeHeader().getNumPartitions(), num_partitions_);
         for (partition_id part_id = 0; part_id < num_partitions_; ++part_id) {
           input_relation_block_ids_[part_id] = part_scheme.getBlocksInPartition(part_id);
         }
@@ -162,7 +162,6 @@ class BuildHashOperator : public RelationalOperator {
   const bool input_relation_is_stored_;
   const std::vector<attribute_id> join_key_attributes_;
   const bool any_join_key_attributes_nullable_;
-  const std::size_t num_partitions_;
   const bool is_broadcast_join_;
   const QueryContext::join_hash_table_id hash_table_index_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/BuildLIPFilterOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/BuildLIPFilterOperator.hpp b/relational_operators/BuildLIPFilterOperator.hpp
index 9b23dd9..41c3294 100644
--- a/relational_operators/BuildLIPFilterOperator.hpp
+++ b/relational_operators/BuildLIPFilterOperator.hpp
@@ -28,7 +28,6 @@
 #include "catalog/CatalogRelation.hpp"
 #include "catalog/CatalogTypedefs.hpp"
 #include "catalog/PartitionScheme.hpp"
-#include "catalog/PartitionSchemeHeader.hpp"
 #include "query_execution/QueryContext.hpp"
 #include "relational_operators/RelationalOperator.hpp"
 #include "relational_operators/WorkOrder.hpp"
@@ -70,8 +69,6 @@ class BuildLIPFilterOperator : public RelationalOperator {
    *
    * @param query_id The ID of the query to which this operator belongs.
    * @param input_relation The relation to build LIP filters on.
-   * @param num_partitions The number of partitions in 'input_relation'.
-   *        If no partitions, it is one.
    * @param build_side_predicate_index The index of the predicate in QueryContext
    *        where the predicate is to be applied to the input relation before
    *        building the LIP filters (or kInvalidPredicateId if no predicate is
@@ -82,21 +79,18 @@ class BuildLIPFilterOperator : public RelationalOperator {
    **/
   BuildLIPFilterOperator(const std::size_t query_id,
                          const CatalogRelation &input_relation,
-                         const std::size_t num_partitions,
                          const QueryContext::predicate_id build_side_predicate_index,
                          const bool input_relation_is_stored)
-    : RelationalOperator(query_id),
+    : RelationalOperator(query_id, input_relation.getNumPartitions()),
       input_relation_(input_relation),
-      num_partitions_(num_partitions),
       build_side_predicate_index_(build_side_predicate_index),
       input_relation_is_stored_(input_relation_is_stored),
-      input_relation_block_ids_(num_partitions),
-      num_workorders_generated_(num_partitions),
+      input_relation_block_ids_(num_partitions_),
+      num_workorders_generated_(num_partitions_),
       started_(false) {
     if (input_relation_is_stored) {
       if (input_relation.hasPartitionScheme()) {
         const PartitionScheme &part_scheme = *input_relation.getPartitionScheme();
-        DCHECK_EQ(part_scheme.getPartitionSchemeHeader().getNumPartitions(), num_partitions_);
         for (partition_id part_id = 0; part_id < num_partitions_; ++part_id) {
           input_relation_block_ids_[part_id] = part_scheme.getBlocksInPartition(part_id);
         }
@@ -148,7 +142,6 @@ class BuildLIPFilterOperator : public RelationalOperator {
   serialization::WorkOrder* createWorkOrderProto(const partition_id part_id, const block_id block);
 
   const CatalogRelation &input_relation_;
-  const std::size_t num_partitions_;
   const QueryContext::predicate_id build_side_predicate_index_;
   const bool input_relation_is_stored_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/relational_operators/CMakeLists.txt b/relational_operators/CMakeLists.txt
index c0def6f..57ba9f9 100644
--- a/relational_operators/CMakeLists.txt
+++ b/relational_operators/CMakeLists.txt
@@ -153,7 +153,6 @@ target_link_libraries(quickstep_relationaloperators_BuildLIPFilterOperator
                       quickstep_catalog_CatalogRelation
                       quickstep_catalog_CatalogTypedefs
                       quickstep_catalog_PartitionScheme
-                      quickstep_catalog_PartitionSchemeHeader
                       quickstep_queryexecution_QueryContext
                       quickstep_queryexecution_WorkOrderProtosContainer
                       quickstep_queryexecution_WorkOrdersContainer
@@ -190,6 +189,7 @@ target_link_libraries(quickstep_relationaloperators_DeleteOperator
                       quickstep_catalog_CatalogRelation
                       quickstep_catalog_CatalogRelationSchema
                       quickstep_catalog_CatalogTypedefs
+                      quickstep_catalog_PartitionScheme
                       quickstep_queryexecution_QueryContext
                       quickstep_queryexecution_QueryExecutionMessages_proto
                       quickstep_queryexecution_QueryExecutionTypedefs
@@ -394,7 +394,7 @@ target_link_libraries(quickstep_relationaloperators_SelectOperator
                       glog
                       quickstep_catalog_CatalogRelation
                       quickstep_catalog_CatalogTypedefs
-                      quickstep_catalog_PartitionSchemeHeader
+                      quickstep_catalog_PartitionScheme
                       quickstep_queryexecution_QueryContext
                       quickstep_queryexecution_WorkOrderProtosContainer
                       quickstep_queryexecution_WorkOrdersContainer
@@ -534,6 +534,7 @@ target_link_libraries(quickstep_relationaloperators_UpdateOperator
                       quickstep_catalog_CatalogRelation
                       quickstep_catalog_CatalogRelationSchema
                       quickstep_catalog_CatalogTypedefs
+                      quickstep_catalog_PartitionScheme
                       quickstep_queryexecution_QueryContext
                       quickstep_queryexecution_QueryExecutionMessages_proto
                       quickstep_queryexecution_QueryExecutionTypedefs

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/CreateIndexOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/CreateIndexOperator.hpp b/relational_operators/CreateIndexOperator.hpp
index 09d5d81..9449f53 100644
--- a/relational_operators/CreateIndexOperator.hpp
+++ b/relational_operators/CreateIndexOperator.hpp
@@ -64,7 +64,7 @@ class CreateIndexOperator : public RelationalOperator {
                       CatalogRelation *relation,
                       const std::string &index_name,
                       IndexSubBlockDescription &&index_description)  // NOLINT(whitespace/operators)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, 0u),
         relation_(DCHECK_NOTNULL(relation)),
         index_name_(index_name),
         index_description_(index_description) {}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/CreateTableOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/CreateTableOperator.hpp b/relational_operators/CreateTableOperator.hpp
index 52c7846..827ed72 100644
--- a/relational_operators/CreateTableOperator.hpp
+++ b/relational_operators/CreateTableOperator.hpp
@@ -64,7 +64,7 @@ class CreateTableOperator : public RelationalOperator {
   CreateTableOperator(const std::size_t query_id,
                       CatalogRelation *relation,
                       CatalogDatabase *database)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, 0u),
         relation_(DCHECK_NOTNULL(relation)),
         database_(DCHECK_NOTNULL(database)) {}
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/DeleteOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/DeleteOperator.cpp b/relational_operators/DeleteOperator.cpp
index a8723a9..4958024 100644
--- a/relational_operators/DeleteOperator.cpp
+++ b/relational_operators/DeleteOperator.cpp
@@ -25,6 +25,7 @@
 #include <vector>
 
 #include "catalog/CatalogRelationSchema.hpp"
+#include "catalog/CatalogTypedefs.hpp"
 #include "query_execution/QueryContext.hpp"
 #include "query_execution/QueryExecutionMessages.pb.h"
 #include "query_execution/QueryExecutionUtil.hpp"
@@ -58,36 +59,42 @@ bool DeleteOperator::getAllWorkOrders(
       return true;
     }
 
-    for (const block_id input_block_id : relation_block_ids_) {
-      container->addNormalWorkOrder(
-          new DeleteWorkOrder(query_id_,
-                              relation_,
-                              input_block_id,
-                              predicate,
-                              storage_manager,
-                              op_index_,
-                              scheduler_client_id,
-                              bus),
-          op_index_);
+    for (partition_id part_id = 0; part_id < num_partitions_; ++part_id) {
+      for (const block_id input_block_id : relation_block_ids_[part_id]) {
+        container->addNormalWorkOrder(
+            new DeleteWorkOrder(query_id_,
+                                relation_,
+                                part_id,
+                                input_block_id,
+                                predicate,
+                                storage_manager,
+                                op_index_,
+                                scheduler_client_id,
+                                bus),
+            op_index_);
+      }
     }
     started_ = true;
     return true;
-  } else {
-    while (num_workorders_generated_ < relation_block_ids_.size()) {
+  }
+
+  for (partition_id part_id = 0; part_id < num_partitions_; ++part_id) {
+    while (num_workorders_generated_[part_id] < relation_block_ids_[part_id].size()) {
       container->addNormalWorkOrder(
           new DeleteWorkOrder(query_id_,
                               relation_,
-                              relation_block_ids_[num_workorders_generated_],
+                              part_id,
+                              relation_block_ids_[part_id][num_workorders_generated_[part_id]],
                               predicate,
                               storage_manager,
                               op_index_,
                               scheduler_client_id,
                               bus),
           op_index_);
-      ++num_workorders_generated_;
+      ++num_workorders_generated_[part_id];
     }
-    return done_feeding_input_relation_;
   }
+  return done_feeding_input_relation_;
 }
 
 bool DeleteOperator::getAllWorkOrderProtos(WorkOrderProtosContainer *container) {
@@ -97,23 +104,27 @@ bool DeleteOperator::getAllWorkOrderProtos(WorkOrderProtosContainer *container)
       return true;
     }
 
-    for (const block_id input_block_id : relation_block_ids_) {
-      container->addWorkOrderProto(createWorkOrderProto(input_block_id), op_index_);
+    for (partition_id part_id = 0; part_id < num_partitions_; ++part_id) {
+      for (const block_id input_block_id : relation_block_ids_[part_id]) {
+        container->addWorkOrderProto(createWorkOrderProto(part_id, input_block_id), op_index_);
+      }
     }
     started_ = true;
     return true;
-  } else {
-    while (num_workorders_generated_ < relation_block_ids_.size()) {
+  }
+
+  for (partition_id part_id = 0; part_id < num_partitions_; ++part_id) {
+    while (num_workorders_generated_[part_id] < relation_block_ids_[part_id].size()) {
       container->addWorkOrderProto(
-          createWorkOrderProto(relation_block_ids_[num_workorders_generated_]),
+          createWorkOrderProto(part_id, relation_block_ids_[part_id][num_workorders_generated_[part_id]]),
           op_index_);
-      ++num_workorders_generated_;
+      ++num_workorders_generated_[part_id];
     }
-    return done_feeding_input_relation_;
   }
+  return done_feeding_input_relation_;
 }
 
-serialization::WorkOrder* DeleteOperator::createWorkOrderProto(const block_id block) {
+serialization::WorkOrder* DeleteOperator::createWorkOrderProto(const partition_id part_id, const block_id block) {
   serialization::WorkOrder *proto = new serialization::WorkOrder;
   proto->set_work_order_type(serialization::DELETE);
   proto->set_query_id(query_id_);
@@ -122,6 +133,7 @@ serialization::WorkOrder* DeleteOperator::createWorkOrderProto(const block_id bl
   proto->SetExtension(serialization::DeleteWorkOrder::relation_id, relation_.getID());
   proto->SetExtension(serialization::DeleteWorkOrder::predicate_index, predicate_index_);
   proto->SetExtension(serialization::DeleteWorkOrder::block_id, block);
+  proto->SetExtension(serialization::DeleteWorkOrder::partition_id, part_id);
 
   return proto;
 }
@@ -139,6 +151,7 @@ void DeleteWorkOrder::execute() {
   proto.set_block_id(input_block_id_);
   proto.set_relation_id(input_relation_.getID());
   proto.set_query_id(query_id_);
+  proto.set_partition_id(partition_id_);
 
   // NOTE(zuyu): Using the heap memory to serialize proto as a c-like string.
   const std::size_t proto_length = proto.ByteSize();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/DeleteOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/DeleteOperator.hpp b/relational_operators/DeleteOperator.hpp
index aed37f6..b084560 100644
--- a/relational_operators/DeleteOperator.hpp
+++ b/relational_operators/DeleteOperator.hpp
@@ -26,6 +26,7 @@
 
 #include "catalog/CatalogRelation.hpp"
 #include "catalog/CatalogTypedefs.hpp"
+#include "catalog/PartitionScheme.hpp"
 #include "query_execution/QueryContext.hpp"
 #include "query_execution/QueryExecutionTypedefs.hpp"
 #include "relational_operators/RelationalOperator.hpp"
@@ -73,14 +74,26 @@ class DeleteOperator : public RelationalOperator {
                  const CatalogRelation &relation,
                  const QueryContext::predicate_id predicate_index,
                  const bool relation_is_stored)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, relation.getNumPartitions()),
         relation_(relation),
         predicate_index_(predicate_index),
         relation_is_stored_(relation_is_stored),
         started_(false),
-        relation_block_ids_(relation_is_stored ? relation.getBlocksSnapshot()
-                                               : std::vector<block_id>()),
-        num_workorders_generated_(0) {}
+        relation_block_ids_(num_partitions_),
+        num_workorders_generated_(num_partitions_) {
+    if (relation_is_stored) {
+      if (relation.hasPartitionScheme()) {
+        const PartitionScheme &part_scheme = *relation.getPartitionScheme();
+
+        for (partition_id part_id = 0; part_id < num_partitions_; ++part_id) {
+          relation_block_ids_[part_id] = part_scheme.getBlocksInPartition(part_id);
+        }
+      } else {
+        DCHECK_EQ(1u, num_partitions_);
+        relation_block_ids_[0] = relation.getBlocksSnapshot();
+      }
+    }
+  }
 
   ~DeleteOperator() override {}
 
@@ -107,16 +120,17 @@ class DeleteOperator : public RelationalOperator {
   void feedInputBlock(const block_id input_block_id, const relation_id input_relation_id,
                       const partition_id part_id) override {
     DCHECK(!relation_is_stored_);
-    relation_block_ids_.push_back(input_block_id);
+    relation_block_ids_[part_id].push_back(input_block_id);
   }
 
  private:
   /**
    * @brief Create Work Order proto.
    *
+   * @param part_id The partition id.
    * @param block The block id used in the Work Order.
    **/
-  serialization::WorkOrder* createWorkOrderProto(const block_id block);
+  serialization::WorkOrder* createWorkOrderProto(const partition_id part_id, const block_id block);
 
   const CatalogRelation &relation_;
   const QueryContext::predicate_id predicate_index_;
@@ -125,8 +139,8 @@ class DeleteOperator : public RelationalOperator {
 
   bool started_;
 
-  std::vector<block_id> relation_block_ids_;
-  std::vector<block_id>::size_type num_workorders_generated_;
+  std::vector<std::vector<block_id>> relation_block_ids_;
+  std::vector<std::size_t> num_workorders_generated_;
 
   DISALLOW_COPY_AND_ASSIGN(DeleteOperator);
 };
@@ -141,6 +155,7 @@ class DeleteWorkOrder : public WorkOrder {
    *
    * @param query_id The ID of the query to which this workorder belongs.
    * @param input_relation The relation to perform the DELETE over.
+   * @param part_id The partition id.
    * @param input_block_id The block Id.
    * @param predicate All tuples matching \c predicate will be deleted (If
    *        NULL, then all tuples will be deleted).
@@ -152,13 +167,14 @@ class DeleteWorkOrder : public WorkOrder {
    **/
   DeleteWorkOrder(const std::size_t query_id,
                   const CatalogRelationSchema &input_relation,
+                  const partition_id part_id,
                   const block_id input_block_id,
                   const Predicate *predicate,
                   StorageManager *storage_manager,
                   const std::size_t delete_operator_index,
                   const tmb::client_id scheduler_client_id,
                   MessageBus *bus)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         input_relation_(input_relation),
         input_block_id_(input_block_id),
         predicate_(predicate),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/DestroyAggregationStateOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/DestroyAggregationStateOperator.hpp b/relational_operators/DestroyAggregationStateOperator.hpp
index c5b092f..f285957 100644
--- a/relational_operators/DestroyAggregationStateOperator.hpp
+++ b/relational_operators/DestroyAggregationStateOperator.hpp
@@ -61,9 +61,8 @@ class DestroyAggregationStateOperator : public RelationalOperator {
       const std::size_t query_id,
       const QueryContext::aggregation_state_id aggr_state_index,
       const std::size_t num_partitions)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, num_partitions),
         aggr_state_index_(aggr_state_index),
-        num_partitions_(num_partitions),
         work_generated_(false) {}
 
   ~DestroyAggregationStateOperator() override {}
@@ -86,7 +85,6 @@ class DestroyAggregationStateOperator : public RelationalOperator {
 
  private:
   const QueryContext::aggregation_state_id aggr_state_index_;
-  const std::size_t num_partitions_;
   bool work_generated_;
 
   DISALLOW_COPY_AND_ASSIGN(DestroyAggregationStateOperator);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/DestroyHashOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/DestroyHashOperator.cpp b/relational_operators/DestroyHashOperator.cpp
index 4b93f0c..490c316 100644
--- a/relational_operators/DestroyHashOperator.cpp
+++ b/relational_operators/DestroyHashOperator.cpp
@@ -38,7 +38,7 @@ bool DestroyHashOperator::getAllWorkOrders(
     return true;
   }
 
-  for (std::size_t part_id = 0; part_id < build_num_partitions_; ++part_id) {
+  for (std::size_t part_id = 0; part_id < num_partitions_; ++part_id) {
     container->addNormalWorkOrder(
         new DestroyHashWorkOrder(query_id_, hash_table_index_, part_id, query_context),
         op_index_);
@@ -52,7 +52,7 @@ bool DestroyHashOperator::getAllWorkOrderProtos(WorkOrderProtosContainer *contai
     return true;
   }
 
-  for (std::size_t part_id = 0; part_id < build_num_partitions_; ++part_id) {
+  for (std::size_t part_id = 0; part_id < num_partitions_; ++part_id) {
     serialization::WorkOrder *proto = new serialization::WorkOrder;
     proto->set_work_order_type(serialization::DESTROY_HASH);
     proto->set_query_id(query_id_);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/DestroyHashOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/DestroyHashOperator.hpp b/relational_operators/DestroyHashOperator.hpp
index 3a6cf0e..6c4c997 100644
--- a/relational_operators/DestroyHashOperator.hpp
+++ b/relational_operators/DestroyHashOperator.hpp
@@ -53,14 +53,13 @@ class DestroyHashOperator : public RelationalOperator {
    * @brief Constructor.
    *
    * @param query_id The ID of the query to which this operator belongs.
-   * @param build_num_partitions The number of partitions in 'build_relation'.
+   * @param num_partitions The number of partitions.
    * @param hash_table_index The index of the JoinHashTable in QueryContext.
    **/
   DestroyHashOperator(const std::size_t query_id,
-                      const std::size_t build_num_partitions,
+                      const std::size_t num_partitions,
                       const QueryContext::join_hash_table_id hash_table_index)
-      : RelationalOperator(query_id),
-        build_num_partitions_(build_num_partitions),
+      : RelationalOperator(query_id, num_partitions),
         hash_table_index_(hash_table_index),
         work_generated_(false) {}
 
@@ -83,7 +82,6 @@ class DestroyHashOperator : public RelationalOperator {
   bool getAllWorkOrderProtos(WorkOrderProtosContainer *container) override;
 
  private:
-  const std::size_t build_num_partitions_;
   const QueryContext::join_hash_table_id hash_table_index_;
   bool work_generated_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/FinalizeAggregationOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/FinalizeAggregationOperator.hpp b/relational_operators/FinalizeAggregationOperator.hpp
index a6f1ef6..382a7da 100644
--- a/relational_operators/FinalizeAggregationOperator.hpp
+++ b/relational_operators/FinalizeAggregationOperator.hpp
@@ -72,9 +72,8 @@ class FinalizeAggregationOperator : public RelationalOperator {
       const std::size_t aggr_state_num_partitions,
       const CatalogRelation &output_relation,
       const QueryContext::insert_destination_id output_destination_index)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, num_partitions),
         aggr_state_index_(aggr_state_index),
-        num_partitions_(num_partitions),
         aggr_state_num_partitions_(aggr_state_num_partitions),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
@@ -108,7 +107,7 @@ class FinalizeAggregationOperator : public RelationalOperator {
 
  private:
   const QueryContext::aggregation_state_id aggr_state_index_;
-  const std::size_t num_partitions_, aggr_state_num_partitions_;
+  const std::size_t aggr_state_num_partitions_;
   const CatalogRelation &output_relation_;
   const QueryContext::insert_destination_id output_destination_index_;
   bool started_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/HashJoinOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/HashJoinOperator.hpp b/relational_operators/HashJoinOperator.hpp
index 316be66..519718c 100644
--- a/relational_operators/HashJoinOperator.hpp
+++ b/relational_operators/HashJoinOperator.hpp
@@ -137,13 +137,12 @@ class HashJoinOperator : public RelationalOperator {
       const QueryContext::scalar_group_id selection_index,
       const std::vector<bool> *is_selection_on_build = nullptr,
       const JoinType join_type = JoinType::kInnerJoin)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, num_partitions),
         build_relation_(build_relation),
         probe_relation_(probe_relation),
         probe_relation_is_stored_(probe_relation_is_stored),
         join_key_attributes_(join_key_attributes),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        num_partitions_(num_partitions),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
         hash_table_index_(hash_table_index),
@@ -276,7 +275,6 @@ class HashJoinOperator : public RelationalOperator {
   const bool probe_relation_is_stored_;
   const std::vector<attribute_id> join_key_attributes_;
   const bool any_join_key_attributes_nullable_;
-  const std::size_t num_partitions_;
   const CatalogRelation &output_relation_;
   const QueryContext::insert_destination_id output_destination_index_;
   const QueryContext::join_hash_table_id hash_table_index_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/InitializeAggregationOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/InitializeAggregationOperator.hpp b/relational_operators/InitializeAggregationOperator.hpp
index 0b052c7..cf9abe5 100644
--- a/relational_operators/InitializeAggregationOperator.hpp
+++ b/relational_operators/InitializeAggregationOperator.hpp
@@ -65,9 +65,8 @@ class InitializeAggregationOperator : public RelationalOperator {
                                 const QueryContext::aggregation_state_id aggr_state_index,
                                 const std::size_t num_partitions,
                                 const std::size_t aggr_state_num_init_partitions)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, num_partitions),
         aggr_state_index_(aggr_state_index),
-        num_partitions_(num_partitions),
         aggr_state_num_init_partitions_(aggr_state_num_init_partitions),
         started_(false) {}
 
@@ -91,7 +90,7 @@ class InitializeAggregationOperator : public RelationalOperator {
 
  private:
   const QueryContext::aggregation_state_id aggr_state_index_;
-  const std::size_t num_partitions_, aggr_state_num_init_partitions_;
+  const std::size_t aggr_state_num_init_partitions_;
   bool started_;
 
   DISALLOW_COPY_AND_ASSIGN(InitializeAggregationOperator);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/NestedLoopsJoinOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/NestedLoopsJoinOperator.hpp b/relational_operators/NestedLoopsJoinOperator.hpp
index 006d496..1b14638 100644
--- a/relational_operators/NestedLoopsJoinOperator.hpp
+++ b/relational_operators/NestedLoopsJoinOperator.hpp
@@ -100,11 +100,10 @@ class NestedLoopsJoinOperator : public RelationalOperator {
       const QueryContext::scalar_group_id selection_index,
       const bool left_relation_is_stored,
       const bool right_relation_is_stored)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, num_partitions),
         nested_loops_join_index_(nested_loops_join_index),
         left_input_relation_(left_input_relation),
         right_input_relation_(right_input_relation),
-        num_partitions_(num_partitions),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
         join_predicate_index_(join_predicate_index),
@@ -296,8 +295,6 @@ class NestedLoopsJoinOperator : public RelationalOperator {
   const CatalogRelation &left_input_relation_;
   const CatalogRelation &right_input_relation_;
 
-  const std::size_t num_partitions_;
-
   const CatalogRelation &output_relation_;
   const QueryContext::insert_destination_id output_destination_index_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/RelationalOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/RelationalOperator.hpp b/relational_operators/RelationalOperator.hpp
index 5de7eb5..29ae194 100644
--- a/relational_operators/RelationalOperator.hpp
+++ b/relational_operators/RelationalOperator.hpp
@@ -260,6 +260,15 @@ class RelationalOperator {
   }
 
   /**
+   * @brief Get the number of partitions of the input relation in the operator.
+   *
+   * @return The number of partitions of the input relation.
+   */
+  std::size_t getNumPartitions() const {
+    return num_partitions_;
+  }
+
+  /**
    * @brief Deploy a group of LIPFilters to this operator.
    */
   void deployLIPFilters(const QueryContext::lip_deployment_id lip_deployment_index,
@@ -273,15 +282,18 @@ class RelationalOperator {
    * @brief Constructor
    *
    * @param query_id The ID of the query to which this operator belongs.
-   * @param blocking_dependencies_met If those dependencies which break the
-   *        pipeline have been met.
+   * @param num_partitions The number of partitions of the input relation.
+   *        If create table / index, return zero. If no partitions, return one.
    **/
-  explicit RelationalOperator(const std::size_t query_id)
+  explicit RelationalOperator(const std::size_t query_id,
+                              const std::size_t num_partitions = 1u)
       : query_id_(query_id),
+        num_partitions_(num_partitions),
         done_feeding_input_relation_(false),
         lip_deployment_index_(QueryContext::kInvalidLIPDeploymentId) {}
 
   const std::size_t query_id_;
+  const std::size_t num_partitions_;
 
   bool done_feeding_input_relation_;
   std::size_t op_index_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/SaveBlocksOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/SaveBlocksOperator.cpp b/relational_operators/SaveBlocksOperator.cpp
index 9d6c3f6..591de12 100644
--- a/relational_operators/SaveBlocksOperator.cpp
+++ b/relational_operators/SaveBlocksOperator.cpp
@@ -22,6 +22,7 @@
 #include <vector>
 
 #include "catalog/CatalogRelation.hpp"
+#include "catalog/CatalogTypedefs.hpp"
 #include "query_execution/WorkOrderProtosContainer.hpp"
 #include "query_execution/WorkOrdersContainer.hpp"
 #include "relational_operators/WorkOrder.pb.h"
@@ -38,31 +39,37 @@ bool SaveBlocksOperator::getAllWorkOrders(
     StorageManager *storage_manager,
     const tmb::client_id scheduler_client_id,
     tmb::MessageBus *bus) {
-  while (num_workorders_generated_ < destination_block_ids_.size()) {
-    container->addNormalWorkOrder(
-        new SaveBlocksWorkOrder(
-            query_id_,
-            destination_block_ids_[num_workorders_generated_],
-            force_,
-            storage_manager),
-        op_index_);
-    ++num_workorders_generated_;
+  for (partition_id part_id = 0; part_id < num_partitions_; ++part_id) {
+    while (num_workorders_generated_[part_id] < destination_block_ids_[part_id].size()) {
+      container->addNormalWorkOrder(
+          new SaveBlocksWorkOrder(
+              query_id_,
+              part_id,
+              destination_block_ids_[part_id][num_workorders_generated_[part_id]],
+              force_,
+              storage_manager),
+          op_index_);
+      ++num_workorders_generated_[part_id];
+    }
   }
   return done_feeding_input_relation_;
 }
 
 bool SaveBlocksOperator::getAllWorkOrderProtos(WorkOrderProtosContainer *container) {
-  while (num_workorders_generated_ < destination_block_ids_.size()) {
-    serialization::WorkOrder *proto = new serialization::WorkOrder;
-    proto->set_work_order_type(serialization::SAVE_BLOCKS);
-    proto->set_query_id(query_id_);
-    proto->SetExtension(serialization::SaveBlocksWorkOrder::block_id,
-                        destination_block_ids_[num_workorders_generated_]);
-    proto->SetExtension(serialization::SaveBlocksWorkOrder::force, force_);
+  for (partition_id part_id = 0; part_id < num_partitions_; ++part_id) {
+    while (num_workorders_generated_[part_id] < destination_block_ids_[part_id].size()) {
+      serialization::WorkOrder *proto = new serialization::WorkOrder;
+      proto->set_work_order_type(serialization::SAVE_BLOCKS);
+      proto->set_query_id(query_id_);
+      proto->SetExtension(serialization::SaveBlocksWorkOrder::block_id,
+                          destination_block_ids_[part_id][num_workorders_generated_[part_id]]);
+      proto->SetExtension(serialization::SaveBlocksWorkOrder::force, force_);
+      proto->SetExtension(serialization::SaveBlocksWorkOrder::partition_id, part_id);
 
-    container->addWorkOrderProto(proto, op_index_);
+      container->addWorkOrderProto(proto, op_index_);
 
-    ++num_workorders_generated_;
+      ++num_workorders_generated_[part_id];
+    }
   }
   return done_feeding_input_relation_;
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/SaveBlocksOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/SaveBlocksOperator.hpp b/relational_operators/SaveBlocksOperator.hpp
index 4489299..cea2d7e 100644
--- a/relational_operators/SaveBlocksOperator.hpp
+++ b/relational_operators/SaveBlocksOperator.hpp
@@ -24,6 +24,7 @@
 #include <string>
 #include <vector>
 
+#include "catalog/CatalogRelation.hpp"
 #include "catalog/CatalogTypedefs.hpp"
 #include "relational_operators/RelationalOperator.hpp"
 #include "relational_operators/WorkOrder.hpp"
@@ -38,7 +39,6 @@ namespace tmb { class MessageBus; }
 
 namespace quickstep {
 
-class CatalogRelation;
 class QueryContext;
 class StorageManager;
 class WorkOrderProtosContainer;
@@ -64,10 +64,11 @@ class SaveBlocksOperator : public RelationalOperator {
   SaveBlocksOperator(const std::size_t query_id,
                      CatalogRelation *relation,
                      const bool force = false)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, relation->getNumPartitions()),
         force_(force),
         relation_(relation),
-        num_workorders_generated_(0) {}
+        destination_block_ids_(num_partitions_),
+        num_workorders_generated_(num_partitions_) {}
 
   ~SaveBlocksOperator() override {}
 
@@ -89,7 +90,7 @@ class SaveBlocksOperator : public RelationalOperator {
 
   void feedInputBlock(const block_id input_block_id, const relation_id input_relation_id,
                       const partition_id part_id) override {
-    destination_block_ids_.push_back(input_block_id);
+    destination_block_ids_[part_id].push_back(input_block_id);
   }
 
   void updateCatalogOnCompletion() override;
@@ -98,9 +99,9 @@ class SaveBlocksOperator : public RelationalOperator {
   const bool force_;
 
   CatalogRelation *relation_;
-  std::vector<block_id> destination_block_ids_;
+  std::vector<std::vector<block_id>> destination_block_ids_;
 
-  std::vector<block_id>::size_type num_workorders_generated_;
+  std::vector<std::size_t> num_workorders_generated_;
 
   DISALLOW_COPY_AND_ASSIGN(SaveBlocksOperator);
 };
@@ -114,16 +115,18 @@ class SaveBlocksWorkOrder : public WorkOrder {
    * @brief Constructor.
    *
    * @param query_id The ID of the query to which this operator belongs.
+   * @param part_id The partition id.
    * @param save_block_id The id of the block to save.
    * @param force If true, force writing of all blocks to disk, otherwise only
    *        write dirty blocks.
    * @param storage_manager The StorageManager to use.
    **/
   SaveBlocksWorkOrder(const std::size_t query_id,
+                      const partition_id part_id,
                       const block_id save_block_id,
                       const bool force,
                       StorageManager *storage_manager)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         save_block_id_(save_block_id),
         force_(force),
         storage_manager_(DCHECK_NOTNULL(storage_manager)) {}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/SelectOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/SelectOperator.hpp b/relational_operators/SelectOperator.hpp
index f4937b3..a71f4c1 100644
--- a/relational_operators/SelectOperator.hpp
+++ b/relational_operators/SelectOperator.hpp
@@ -32,7 +32,7 @@
 #include "catalog/NUMAPlacementScheme.hpp"
 #endif
 
-#include "catalog/PartitionSchemeHeader.hpp"
+#include "catalog/PartitionScheme.hpp"
 #include "query_execution/QueryContext.hpp"
 #include "relational_operators/RelationalOperator.hpp"
 #include "relational_operators/WorkOrder.hpp"
@@ -85,8 +85,6 @@ class SelectOperator : public RelationalOperator {
    * @param input_relation_is_stored If input_relation is a stored relation and
    *        is fully available to the operator before it can start generating
    *        workorders.
-   * @param num_partitions The number of partitions in 'input_relation'.
-   *        If no partitions, it is one.
    **/
   SelectOperator(
       const std::size_t query_id,
@@ -95,17 +93,15 @@ class SelectOperator : public RelationalOperator {
       const QueryContext::insert_destination_id output_destination_index,
       const QueryContext::predicate_id predicate_index,
       const QueryContext::scalar_group_id selection_index,
-      const bool input_relation_is_stored,
-      const std::size_t num_partitions)
-      : RelationalOperator(query_id),
+      const bool input_relation_is_stored)
+      : RelationalOperator(query_id, input_relation.getNumPartitions()),
         input_relation_(input_relation),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
         predicate_index_(predicate_index),
         selection_index_(selection_index),
-        num_partitions_(num_partitions),
-        input_relation_block_ids_(num_partitions),
-        num_workorders_generated_(num_partitions),
+        input_relation_block_ids_(num_partitions_),
+        num_workorders_generated_(num_partitions_),
         simple_projection_(false),
         input_relation_is_stored_(input_relation_is_stored),
         started_(false) {
@@ -120,6 +116,7 @@ class SelectOperator : public RelationalOperator {
           input_relation_block_ids_[part_id] = part_scheme.getBlocksInPartition(part_id);
         }
       } else {
+        DCHECK_EQ(1u, num_partitions_);
         input_relation_block_ids_[0] = input_relation.getBlocksSnapshot();
       }
     }
@@ -143,8 +140,6 @@ class SelectOperator : public RelationalOperator {
    * @param input_relation_is_stored If input_relation is a stored relation and
    *        is fully available to the operator before it can start generating
    *        workorders.
-   * @param num_partitions The number of partitions in 'input_relation'.
-   *        If no partitions, it is one.
    **/
   SelectOperator(
       const std::size_t query_id,
@@ -153,18 +148,16 @@ class SelectOperator : public RelationalOperator {
       const QueryContext::insert_destination_id output_destination_index,
       const QueryContext::predicate_id predicate_index,
       std::vector<attribute_id> &&selection,
-      const bool input_relation_is_stored,
-      const std::size_t num_partitions)
-      : RelationalOperator(query_id),
+      const bool input_relation_is_stored)
+      : RelationalOperator(query_id, input_relation.getNumPartitions()),
         input_relation_(input_relation),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
         predicate_index_(predicate_index),
         selection_index_(QueryContext::kInvalidScalarGroupId),
         simple_selection_(std::move(selection)),
-        num_partitions_(num_partitions),
-        input_relation_block_ids_(num_partitions),
-        num_workorders_generated_(num_partitions),
+        input_relation_block_ids_(num_partitions_),
+        num_workorders_generated_(num_partitions_),
         simple_projection_(true),
         input_relation_is_stored_(input_relation_is_stored),
         started_(false) {
@@ -179,6 +172,7 @@ class SelectOperator : public RelationalOperator {
           input_relation_block_ids_[part_id] = part_scheme.getBlocksInPartition(part_id);
         }
       } else {
+        DCHECK_EQ(1u, num_partitions_);
         input_relation_block_ids_[0] = input_relation.getBlocksSnapshot();
       }
     }
@@ -239,7 +233,6 @@ class SelectOperator : public RelationalOperator {
   const QueryContext::scalar_group_id selection_index_;
   const std::vector<attribute_id> simple_selection_;
 
-  const std::size_t num_partitions_;
   // A vector of vectors V where V[i] indicates the list of block IDs of the
   // input relation that belong to the partition i.
   std::vector<std::vector<block_id>> input_relation_block_ids_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/UpdateOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/UpdateOperator.cpp b/relational_operators/UpdateOperator.cpp
index 08bfa59..0f7f999 100644
--- a/relational_operators/UpdateOperator.cpp
+++ b/relational_operators/UpdateOperator.cpp
@@ -25,6 +25,7 @@
 #include <utility>
 
 #include "catalog/CatalogRelationSchema.hpp"
+#include "catalog/CatalogTypedefs.hpp"
 #include "query_execution/QueryContext.hpp"
 #include "query_execution/QueryExecutionMessages.pb.h"
 #include "query_execution/QueryExecutionUtil.hpp"
@@ -57,21 +58,24 @@ bool UpdateOperator::getAllWorkOrders(
   }
 
   DCHECK(query_context != nullptr);
-  for (const block_id input_block_id : input_blocks_) {
-    container->addNormalWorkOrder(
-        new UpdateWorkOrder(
-            query_id_,
-            relation_,
-            input_block_id,
-            query_context->getPredicate(predicate_index_),
-            query_context->getUpdateGroup(update_group_index_),
-            query_context->getInsertDestination(
-                relocation_destination_index_),
-            storage_manager,
-            op_index_,
-            scheduler_client_id,
-            bus),
-        op_index_);
+  for (partition_id part_id = 0; part_id < num_partitions_; ++part_id) {
+    for (const block_id input_block_id : input_blocks_[part_id]) {
+      container->addNormalWorkOrder(
+          new UpdateWorkOrder(
+              query_id_,
+              relation_,
+              part_id,
+              input_block_id,
+              query_context->getPredicate(predicate_index_),
+              query_context->getUpdateGroup(update_group_index_),
+              query_context->getInsertDestination(
+                  relocation_destination_index_),
+              storage_manager,
+              op_index_,
+              scheduler_client_id,
+              bus),
+          op_index_);
+    }
   }
   started_ = true;
   return true;
@@ -82,19 +86,22 @@ bool UpdateOperator::getAllWorkOrderProtos(WorkOrderProtosContainer *container)
     return true;
   }
 
-  for (const block_id input_block_id : input_blocks_) {
-    serialization::WorkOrder *proto = new serialization::WorkOrder;
-    proto->set_work_order_type(serialization::UPDATE);
-    proto->set_query_id(query_id_);
-
-    proto->SetExtension(serialization::UpdateWorkOrder::operator_index, op_index_);
-    proto->SetExtension(serialization::UpdateWorkOrder::relation_id, relation_.getID());
-    proto->SetExtension(serialization::UpdateWorkOrder::insert_destination_index, relocation_destination_index_);
-    proto->SetExtension(serialization::UpdateWorkOrder::predicate_index, predicate_index_);
-    proto->SetExtension(serialization::UpdateWorkOrder::update_group_index, update_group_index_);
-    proto->SetExtension(serialization::UpdateWorkOrder::block_id, input_block_id);
-
-    container->addWorkOrderProto(proto, op_index_);
+  for (std::size_t part_id = 0; part_id < num_partitions_; ++part_id) {
+    for (const block_id input_block_id : input_blocks_[part_id]) {
+      serialization::WorkOrder *proto = new serialization::WorkOrder;
+      proto->set_work_order_type(serialization::UPDATE);
+      proto->set_query_id(query_id_);
+
+      proto->SetExtension(serialization::UpdateWorkOrder::operator_index, op_index_);
+      proto->SetExtension(serialization::UpdateWorkOrder::relation_id, relation_.getID());
+      proto->SetExtension(serialization::UpdateWorkOrder::insert_destination_index, relocation_destination_index_);
+      proto->SetExtension(serialization::UpdateWorkOrder::predicate_index, predicate_index_);
+      proto->SetExtension(serialization::UpdateWorkOrder::update_group_index, update_group_index_);
+      proto->SetExtension(serialization::UpdateWorkOrder::block_id, input_block_id);
+      proto->SetExtension(serialization::UpdateWorkOrder::partition_id, part_id);
+
+      container->addWorkOrderProto(proto, op_index_);
+    }
   }
   started_ = true;
   return true;
@@ -120,6 +127,7 @@ void UpdateWorkOrder::execute() {
   proto.set_block_id(input_block_id_);
   proto.set_relation_id(relation_.getID());
   proto.set_query_id(query_id_);
+  proto.set_partition_id(partition_id_);
 
   // NOTE(zuyu): Using the heap memory to serialize proto as a c-like string.
   const std::size_t proto_length = proto.ByteSize();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/UpdateOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/UpdateOperator.hpp b/relational_operators/UpdateOperator.hpp
index 8e020d8..fd2096b 100644
--- a/relational_operators/UpdateOperator.hpp
+++ b/relational_operators/UpdateOperator.hpp
@@ -28,6 +28,7 @@
 
 #include "catalog/CatalogRelation.hpp"
 #include "catalog/CatalogTypedefs.hpp"
+#include "catalog/PartitionScheme.hpp"
 #include "query_execution/QueryContext.hpp"
 #include "query_execution/QueryExecutionTypedefs.hpp"
 #include "relational_operators/RelationalOperator.hpp"
@@ -87,13 +88,24 @@ class UpdateOperator : public RelationalOperator {
       const QueryContext::insert_destination_id relocation_destination_index,
       const QueryContext::predicate_id predicate_index,
       const QueryContext::update_group_id update_group_index)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, relation.getNumPartitions()),
         relation_(relation),
         relocation_destination_index_(relocation_destination_index),
         predicate_index_(predicate_index),
         update_group_index_(update_group_index),
-        input_blocks_(relation.getBlocksSnapshot()),
-        started_(false) {}
+        input_blocks_(num_partitions_),
+        started_(false) {
+    if (relation.hasPartitionScheme()) {
+      const PartitionScheme &part_scheme = *relation.getPartitionScheme();
+
+      for (partition_id part_id = 0; part_id < num_partitions_; ++part_id) {
+        input_blocks_[part_id] = part_scheme.getBlocksInPartition(part_id);
+      }
+    } else {
+      DCHECK_EQ(1u, num_partitions_);
+      input_blocks_[0] = relation.getBlocksSnapshot();
+    }
+  }
 
   ~UpdateOperator() override {}
 
@@ -127,7 +139,7 @@ class UpdateOperator : public RelationalOperator {
   const QueryContext::predicate_id predicate_index_;
   const QueryContext::update_group_id update_group_index_;
 
-  const std::vector<block_id> input_blocks_;
+  std::vector<std::vector<block_id>> input_blocks_;
 
   bool started_;
 
@@ -144,6 +156,7 @@ class UpdateWorkOrder : public WorkOrder {
    *
    * @param query_id The ID of the query to which this WorkOrder belongs.
    * @param relation The relation to perform the UPDATE over.
+   * @param part_id The partition id.
    * @param predicate All tuples matching \c predicate will be updated (or NULL
    *        to update all tuples).
    * @param assignments The assignments (the map of attribute_ids to Scalars)
@@ -161,6 +174,7 @@ class UpdateWorkOrder : public WorkOrder {
   UpdateWorkOrder(
       const std::size_t query_id,
       const CatalogRelationSchema &relation,
+      const partition_id part_id,
       const block_id input_block_id,
       const Predicate *predicate,
       const std::unordered_map<attribute_id, std::unique_ptr<const Scalar>>
@@ -170,7 +184,7 @@ class UpdateWorkOrder : public WorkOrder {
       const std::size_t update_operator_index,
       const tmb::client_id scheduler_client_id,
       MessageBus *bus)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         relation_(relation),
         input_block_id_(input_block_id),
         predicate_(predicate),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/WorkOrder.proto
----------------------------------------------------------------------
diff --git a/relational_operators/WorkOrder.proto b/relational_operators/WorkOrder.proto
index 42a0e7d..6dafbe0 100644
--- a/relational_operators/WorkOrder.proto
+++ b/relational_operators/WorkOrder.proto
@@ -116,6 +116,7 @@ message DeleteWorkOrder {
     optional int32 relation_id = 97;
     optional int32 predicate_index = 98;
     optional fixed64 block_id = 99;
+    optional uint64 partition_id = 100;
   }
 }
 
@@ -235,6 +236,7 @@ message SaveBlocksWorkOrder {
     // All required.
     optional fixed64 block_id = 224;
     optional bool force = 225;
+    optional uint64 partition_id = 226;
   }
 }
 
@@ -320,6 +322,7 @@ message UpdateWorkOrder {
     optional int32 predicate_index = 323;
     optional uint32 update_group_index = 324;
     optional fixed64 block_id = 325;
+    optional uint64 partition_id = 326;
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/942a15be/relational_operators/WorkOrderFactory.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/WorkOrderFactory.cpp b/relational_operators/WorkOrderFactory.cpp
index 68f7f55..5baa21b 100644
--- a/relational_operators/WorkOrderFactory.cpp
+++ b/relational_operators/WorkOrderFactory.cpp
@@ -170,11 +170,16 @@ WorkOrder* WorkOrderFactory::ReconstructFromProto(const serialization::WorkOrder
               proto.GetExtension(serialization::BuildHashWorkOrder::lip_deployment_index), query_context));
     }
     case serialization::DELETE: {
-      LOG(INFO) << "Creating DeleteWorkOrder for Query " << query_id << " in Shiftboss " << shiftboss_index;
+      const partition_id part_id =
+          proto.GetExtension(serialization::DeleteWorkOrder::partition_id);
+
+      LOG(INFO) << "Creating DeleteWorkOrder (Partition " << part_id << ") for Query " << query_id
+                << " in Shiftboss " << shiftboss_index;
       return new DeleteWorkOrder(
           query_id,
           catalog_database->getRelationSchemaById(
               proto.GetExtension(serialization::DeleteWorkOrder::relation_id)),
+          part_id,
           proto.GetExtension(serialization::DeleteWorkOrder::block_id),
           query_context->getPredicate(
               proto.GetExtension(serialization::DeleteWorkOrder::predicate_index)),
@@ -436,10 +441,14 @@ WorkOrder* WorkOrderFactory::ReconstructFromProto(const serialization::WorkOrder
           storage_manager);
     }
     case serialization::SAVE_BLOCKS: {
-      LOG(INFO) << "Creating SaveBlocksWorkOrder for Query " << query_id
+      const partition_id part_id =
+          proto.GetExtension(serialization::SaveBlocksWorkOrder::partition_id);
+
+      LOG(INFO) << "Creating SaveBlocksWorkOrder (Partition " << part_id << ") for Query " << query_id
                 << " in Shiftboss " << shiftboss_index;
       return new SaveBlocksWorkOrder(
           query_id,
+          part_id,
           proto.GetExtension(serialization::SaveBlocksWorkOrder::block_id),
           proto.GetExtension(serialization::SaveBlocksWorkOrder::force),
           storage_manager);
@@ -563,11 +572,16 @@ WorkOrder* WorkOrderFactory::ReconstructFromProto(const serialization::WorkOrder
           storage_manager);
     }
     case serialization::UPDATE: {
-      LOG(INFO) << "Creating UpdateWorkOrder for Query " << query_id << " in Shiftboss " << shiftboss_index;
+      const partition_id part_id =
+          proto.GetExtension(serialization::UpdateWorkOrder::partition_id);
+
+      LOG(INFO) << "Creating UpdateWorkOrder (Partition " << part_id << ") for Query " << query_id
+                << " in Shiftboss " << shiftboss_index;
       return new UpdateWorkOrder(
           query_id,
           catalog_database->getRelationSchemaById(
               proto.GetExtension(serialization::UpdateWorkOrder::relation_id)),
+          part_id,
           proto.GetExtension(serialization::UpdateWorkOrder::block_id),
           query_context->getPredicate(
               proto.GetExtension(serialization::UpdateWorkOrder::predicate_index)),
@@ -600,7 +614,7 @@ WorkOrder* WorkOrderFactory::ReconstructFromProto(const serialization::WorkOrder
     default:
       LOG(FATAL) << "Unknown WorkOrder Type in WorkOrderFactory::ReconstructFromProto in Shiftboss" << shiftboss_index;
   }
-}
+}  // NOLINT(readability/fn_size)
 
 bool WorkOrderFactory::ProtoIsValid(const serialization::WorkOrder &proto,
                                     const CatalogDatabaseLite &catalog_database,
@@ -726,7 +740,8 @@ bool WorkOrderFactory::ProtoIsValid(const serialization::WorkOrder &proto,
              query_context.isValidPredicate(
                  proto.GetExtension(serialization::DeleteWorkOrder::predicate_index)) &&
              proto.HasExtension(serialization::DeleteWorkOrder::block_id) &&
-             proto.HasExtension(serialization::DeleteWorkOrder::operator_index);
+             proto.HasExtension(serialization::DeleteWorkOrder::operator_index) &&
+             proto.GetExtension(serialization::DeleteWorkOrder::partition_id);
     }
     case serialization::DESTROY_AGGREGATION_STATE: {
       return proto.HasExtension(serialization::DestroyAggregationStateWorkOrder::aggr_state_index) &&
@@ -885,7 +900,8 @@ bool WorkOrderFactory::ProtoIsValid(const serialization::WorkOrder &proto,
     }
     case serialization::SAVE_BLOCKS: {
       return proto.HasExtension(serialization::SaveBlocksWorkOrder::block_id) &&
-             proto.HasExtension(serialization::SaveBlocksWorkOrder::force);
+             proto.HasExtension(serialization::SaveBlocksWorkOrder::force) &&
+             proto.HasExtension(serialization::SaveBlocksWorkOrder::partition_id);
     }
     case serialization::SELECT: {
       if (!proto.HasExtension(serialization::SelectWorkOrder::relation_id) ||
@@ -1016,7 +1032,8 @@ bool WorkOrderFactory::ProtoIsValid(const serialization::WorkOrder &proto,
              query_context.isValidUpdateGroupId(
                  proto.GetExtension(serialization::UpdateWorkOrder::update_group_index)) &&
              proto.HasExtension(serialization::UpdateWorkOrder::operator_index) &&
-             proto.HasExtension(serialization::UpdateWorkOrder::block_id);
+             proto.HasExtension(serialization::UpdateWorkOrder::block_id) &&
+             proto.GetExtension(serialization::UpdateWorkOrder::partition_id);
     }
     case serialization::WINDOW_AGGREGATION: {
       return proto.HasExtension(serialization::WindowAggregationWorkOrder::window_aggr_state_index) &&


[06/12] incubator-quickstep git commit: Added output_num_partitions in RelationalOperators.

Posted by ji...@apache.org.
Added output_num_partitions in RelationalOperators.


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/9afad881
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/9afad881
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/9afad881

Branch: refs/heads/copy-to
Commit: 9afad881da17dd3a8488a88922ab06b8ee96fbb9
Parents: 5f066fa
Author: Zuyu Zhang <zu...@cs.wisc.edu>
Authored: Wed Aug 23 12:57:38 2017 -0500
Committer: Zuyu Zhang <zu...@cs.wisc.edu>
Committed: Sun Aug 27 01:14:24 2017 -0500

----------------------------------------------------------------------
 relational_operators/DeleteOperator.hpp            |  3 ++-
 .../FinalizeAggregationOperator.hpp                |  6 ++++--
 relational_operators/HashJoinOperator.hpp          |  3 ++-
 relational_operators/InsertOperator.hpp            |  2 +-
 relational_operators/NestedLoopsJoinOperator.hpp   |  2 +-
 relational_operators/RelationalOperator.hpp        | 17 +++++++++++++++--
 relational_operators/SelectOperator.hpp            |  8 ++++++--
 relational_operators/SortMergeRunOperator.hpp      |  5 ++++-
 relational_operators/SortRunGenerationOperator.hpp |  7 +++++--
 relational_operators/TableGeneratorOperator.hpp    |  3 ++-
 relational_operators/TextScanOperator.hpp          |  3 ++-
 relational_operators/UpdateOperator.hpp            |  3 ++-
 relational_operators/WindowAggregationOperator.hpp |  5 ++++-
 13 files changed, 50 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/DeleteOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/DeleteOperator.hpp b/relational_operators/DeleteOperator.hpp
index b084560..cc6f6cf 100644
--- a/relational_operators/DeleteOperator.hpp
+++ b/relational_operators/DeleteOperator.hpp
@@ -74,7 +74,8 @@ class DeleteOperator : public RelationalOperator {
                  const CatalogRelation &relation,
                  const QueryContext::predicate_id predicate_index,
                  const bool relation_is_stored)
-      : RelationalOperator(query_id, relation.getNumPartitions()),
+      : RelationalOperator(query_id, relation.getNumPartitions(), false /* has_repartition */,
+                           relation.getNumPartitions()),
         relation_(relation),
         predicate_index_(predicate_index),
         relation_is_stored_(relation_is_stored),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/FinalizeAggregationOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/FinalizeAggregationOperator.hpp b/relational_operators/FinalizeAggregationOperator.hpp
index b344c13..5931ca2 100644
--- a/relational_operators/FinalizeAggregationOperator.hpp
+++ b/relational_operators/FinalizeAggregationOperator.hpp
@@ -74,12 +74,14 @@ class FinalizeAggregationOperator : public RelationalOperator {
       const std::size_t aggr_state_num_partitions,
       const CatalogRelation &output_relation,
       const QueryContext::insert_destination_id output_destination_index)
-      : RelationalOperator(query_id, num_partitions, has_repartition),
+      : RelationalOperator(query_id, num_partitions, has_repartition, output_relation.getNumPartitions()),
         aggr_state_index_(aggr_state_index),
         aggr_state_num_partitions_(aggr_state_num_partitions),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
-        started_(false) {}
+        started_(false) {
+    DCHECK(has_repartition || num_partitions == output_num_partitions_);
+  }
 
   ~FinalizeAggregationOperator() override {}
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/HashJoinOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/HashJoinOperator.hpp b/relational_operators/HashJoinOperator.hpp
index a5e6eb4..306875e 100644
--- a/relational_operators/HashJoinOperator.hpp
+++ b/relational_operators/HashJoinOperator.hpp
@@ -139,7 +139,7 @@ class HashJoinOperator : public RelationalOperator {
       const QueryContext::scalar_group_id selection_index,
       const std::vector<bool> *is_selection_on_build = nullptr,
       const JoinType join_type = JoinType::kInnerJoin)
-      : RelationalOperator(query_id, num_partitions, has_repartition),
+      : RelationalOperator(query_id, num_partitions, has_repartition, output_relation.getNumPartitions()),
         build_relation_(build_relation),
         probe_relation_(probe_relation),
         probe_relation_is_stored_(probe_relation_is_stored),
@@ -157,6 +157,7 @@ class HashJoinOperator : public RelationalOperator {
         probe_relation_block_ids_(num_partitions),
         num_workorders_generated_(num_partitions),
         started_(false) {
+    DCHECK(has_repartition || num_partitions == output_num_partitions_);
     DCHECK(join_type != JoinType::kLeftOuterJoin ||
                (is_selection_on_build != nullptr &&
                 residual_predicate_index == QueryContext::kInvalidPredicateId));

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/InsertOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/InsertOperator.hpp b/relational_operators/InsertOperator.hpp
index b0bdf87..b103538 100644
--- a/relational_operators/InsertOperator.hpp
+++ b/relational_operators/InsertOperator.hpp
@@ -68,7 +68,7 @@ class InsertOperator : public RelationalOperator {
       const CatalogRelation &output_relation,
       const QueryContext::insert_destination_id output_destination_index,
       const QueryContext::tuple_id tuple_index)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, 1u, false, output_relation.getNumPartitions()),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
         tuple_index_(tuple_index),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/NestedLoopsJoinOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/NestedLoopsJoinOperator.hpp b/relational_operators/NestedLoopsJoinOperator.hpp
index 777a737..daca91f 100644
--- a/relational_operators/NestedLoopsJoinOperator.hpp
+++ b/relational_operators/NestedLoopsJoinOperator.hpp
@@ -102,7 +102,7 @@ class NestedLoopsJoinOperator : public RelationalOperator {
       const QueryContext::scalar_group_id selection_index,
       const bool left_relation_is_stored,
       const bool right_relation_is_stored)
-      : RelationalOperator(query_id, num_partitions, has_repartition),
+      : RelationalOperator(query_id, num_partitions, has_repartition, output_relation.getNumPartitions()),
         nested_loops_join_index_(nested_loops_join_index),
         left_input_relation_(left_input_relation),
         right_input_relation_(right_input_relation),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/RelationalOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/RelationalOperator.hpp b/relational_operators/RelationalOperator.hpp
index 0541bbd..9307b5a 100644
--- a/relational_operators/RelationalOperator.hpp
+++ b/relational_operators/RelationalOperator.hpp
@@ -278,6 +278,15 @@ class RelationalOperator {
   }
 
   /**
+   * @brief Get the number of partitions of the output relation in the operator.
+   *
+   * @return The number of partitions of the output relation.
+   */
+  std::size_t getOutputNumPartitions() const {
+    return output_num_partitions_;
+  }
+
+  /**
    * @brief Deploy a group of LIPFilters to this operator.
    */
   void deployLIPFilters(const QueryContext::lip_deployment_id lip_deployment_index,
@@ -294,18 +303,22 @@ class RelationalOperator {
    * @param num_partitions The number of partitions of the input relation.
    *        If create table / index, return zero. If no partitions, return one.
    * @param has_repartition Whether this operator does repartition.
+   * @param output_num_partitions The number of partitions of the output
+   *        relation. If no output, return zero. If no partitions, return one.
    **/
   explicit RelationalOperator(const std::size_t query_id,
                               const std::size_t num_partitions = 1u,
-                              const bool has_repartition = false)
+                              const bool has_repartition = false,
+                              const std::size_t output_num_partitions = 0u)
       : query_id_(query_id),
         num_partitions_(num_partitions),
+        output_num_partitions_(output_num_partitions),
         has_repartition_(has_repartition),
         done_feeding_input_relation_(false),
         lip_deployment_index_(QueryContext::kInvalidLIPDeploymentId) {}
 
   const std::size_t query_id_;
-  const std::size_t num_partitions_;
+  const std::size_t num_partitions_, output_num_partitions_;
   const bool has_repartition_;
 
   bool done_feeding_input_relation_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/SelectOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/SelectOperator.hpp b/relational_operators/SelectOperator.hpp
index 71dcfca..e7cdcd0 100644
--- a/relational_operators/SelectOperator.hpp
+++ b/relational_operators/SelectOperator.hpp
@@ -96,7 +96,8 @@ class SelectOperator : public RelationalOperator {
       const QueryContext::predicate_id predicate_index,
       const QueryContext::scalar_group_id selection_index,
       const bool input_relation_is_stored)
-      : RelationalOperator(query_id, input_relation.getNumPartitions(), has_repartition),
+      : RelationalOperator(query_id, input_relation.getNumPartitions(), has_repartition,
+                           output_relation.getNumPartitions()),
         input_relation_(input_relation),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
@@ -107,6 +108,7 @@ class SelectOperator : public RelationalOperator {
         simple_projection_(false),
         input_relation_is_stored_(input_relation_is_stored),
         started_(false) {
+    DCHECK(has_repartition || num_partitions_ == output_num_partitions_);
 #ifdef QUICKSTEP_HAVE_LIBNUMA
     placement_scheme_ = input_relation.getNUMAPlacementSchemePtr();
 #endif
@@ -153,7 +155,8 @@ class SelectOperator : public RelationalOperator {
       const QueryContext::predicate_id predicate_index,
       std::vector<attribute_id> &&selection,
       const bool input_relation_is_stored)
-      : RelationalOperator(query_id, input_relation.getNumPartitions(), has_repartition),
+      : RelationalOperator(query_id, input_relation.getNumPartitions(), has_repartition,
+                           output_relation.getNumPartitions()),
         input_relation_(input_relation),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
@@ -165,6 +168,7 @@ class SelectOperator : public RelationalOperator {
         simple_projection_(true),
         input_relation_is_stored_(input_relation_is_stored),
         started_(false) {
+    DCHECK(has_repartition || num_partitions_ == output_num_partitions_);
 #ifdef QUICKSTEP_HAVE_LIBNUMA
     placement_scheme_ = input_relation.getNUMAPlacementSchemePtr();
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/SortMergeRunOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/SortMergeRunOperator.hpp b/relational_operators/SortMergeRunOperator.hpp
index a8ecb88..6287068 100644
--- a/relational_operators/SortMergeRunOperator.hpp
+++ b/relational_operators/SortMergeRunOperator.hpp
@@ -107,7 +107,8 @@ class SortMergeRunOperator : public RelationalOperator {
       const std::size_t merge_factor,
       const std::size_t top_k,
       const bool input_relation_is_stored)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, 1u /* input_num_partitions */, false /* has_repartition */,
+                           1u /* output_num_partition */),
         input_relation_(input_relation),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
@@ -124,6 +125,8 @@ class SortMergeRunOperator : public RelationalOperator {
         input_relation_is_stored_(input_relation_is_stored),
         input_stream_done_(input_relation_is_stored),
         started_(false) {
+    DCHECK_EQ(1u, input_relation.getNumPartitions());
+    DCHECK_EQ(1u, output_relation.getNumPartitions());
     DCHECK_GT(merge_factor_, 1u);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/SortRunGenerationOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/SortRunGenerationOperator.hpp b/relational_operators/SortRunGenerationOperator.hpp
index 716d4f7..aaac1c3 100644
--- a/relational_operators/SortRunGenerationOperator.hpp
+++ b/relational_operators/SortRunGenerationOperator.hpp
@@ -98,7 +98,8 @@ class SortRunGenerationOperator : public RelationalOperator {
       const QueryContext::insert_destination_id output_destination_index,
       const QueryContext::sort_config_id sort_config_index,
       bool input_relation_is_stored)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, 1u /* input_num_partitions */, false /* has_repartition */,
+                           1u /* output_num_partition */),
         input_relation_(input_relation),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
@@ -108,7 +109,9 @@ class SortRunGenerationOperator : public RelationalOperator {
                                       : std::vector<block_id>()),
         num_workorders_generated_(0),
         started_(false),
-        input_relation_is_stored_(input_relation_is_stored) {}
+        input_relation_is_stored_(input_relation_is_stored) {
+    DCHECK_EQ(1u, output_relation.getNumPartitions());
+  }
 
   ~SortRunGenerationOperator() {}
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/TableGeneratorOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/TableGeneratorOperator.hpp b/relational_operators/TableGeneratorOperator.hpp
index adfe2bb..c6a6b7d 100644
--- a/relational_operators/TableGeneratorOperator.hpp
+++ b/relational_operators/TableGeneratorOperator.hpp
@@ -70,7 +70,8 @@ class TableGeneratorOperator : public RelationalOperator {
       const CatalogRelation &output_relation,
       const QueryContext::insert_destination_id output_destination_index,
       const QueryContext::generator_function_id generator_function_index)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, 1u, output_relation.getNumPartitions() != 1u /* has_repartition */,
+                           output_relation.getNumPartitions()),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
         generator_function_index_(generator_function_index),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/TextScanOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/TextScanOperator.hpp b/relational_operators/TextScanOperator.hpp
index f6be8c8..4dbeb92 100644
--- a/relational_operators/TextScanOperator.hpp
+++ b/relational_operators/TextScanOperator.hpp
@@ -125,7 +125,8 @@ class TextScanOperator : public RelationalOperator {
                    const bool process_escape_sequences,
                    const CatalogRelation &output_relation,
                    const QueryContext::insert_destination_id output_destination_index)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, 1u, output_relation.getNumPartitions() != 1u /* has_repartition */,
+                           output_relation.getNumPartitions()),
         file_pattern_(file_pattern),
         field_terminator_(field_terminator),
         process_escape_sequences_(process_escape_sequences),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/UpdateOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/UpdateOperator.hpp b/relational_operators/UpdateOperator.hpp
index fd2096b..7b7fad6 100644
--- a/relational_operators/UpdateOperator.hpp
+++ b/relational_operators/UpdateOperator.hpp
@@ -88,7 +88,8 @@ class UpdateOperator : public RelationalOperator {
       const QueryContext::insert_destination_id relocation_destination_index,
       const QueryContext::predicate_id predicate_index,
       const QueryContext::update_group_id update_group_index)
-      : RelationalOperator(query_id, relation.getNumPartitions()),
+      : RelationalOperator(query_id, relation.getNumPartitions(), false /* has_repartition */,
+                           relation.getNumPartitions()),
         relation_(relation),
         relocation_destination_index_(relocation_destination_index),
         predicate_index_(predicate_index),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9afad881/relational_operators/WindowAggregationOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/WindowAggregationOperator.hpp b/relational_operators/WindowAggregationOperator.hpp
index 10546b4..beaf1a3 100644
--- a/relational_operators/WindowAggregationOperator.hpp
+++ b/relational_operators/WindowAggregationOperator.hpp
@@ -70,7 +70,10 @@ class WindowAggregationOperator : public RelationalOperator {
                             const CatalogRelation &output_relation,
                             const QueryContext::window_aggregation_state_id window_aggregation_state_index,
                             const QueryContext::insert_destination_id output_destination_index)
-      : RelationalOperator(query_id),
+      : RelationalOperator(query_id, input_relation.getNumPartitions(),
+                           input_relation.getNumPartitions() !=
+                               output_relation.getNumPartitions() /* has_repartition */,
+                           output_relation.getNumPartitions()),
         input_relation_(input_relation),
         output_relation_(output_relation),
         window_aggregation_state_index_(window_aggregation_state_index),


[12/12] incubator-quickstep git commit: Add "COPY TO" operator for exporting data from Quickstep.

Posted by ji...@apache.org.
Add "COPY TO" operator for exporting data from Quickstep.


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/1e32afc8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/1e32afc8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/1e32afc8

Branch: refs/heads/copy-to
Commit: 1e32afc8119ed37782c68de5b132f9b77f75bd71
Parents: 9afad88
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Fri Aug 4 16:49:45 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Sun Aug 27 02:57:25 2017 -0500

----------------------------------------------------------------------
 parser/ParseKeyValue.hpp                        |   83 +-
 parser/ParseStatement.hpp                       |  232 +-
 parser/SqlLexer.lpp                             |    9 +-
 parser/SqlParser.ypp                            |   93 +-
 parser/preprocessed/SqlLexer_gen.cpp            | 1889 ++++-----
 parser/preprocessed/SqlLexer_gen.hpp            |  467 ++-
 parser/preprocessed/SqlParser_gen.cpp           | 3633 +++++++++---------
 parser/preprocessed/SqlParser_gen.hpp           |  164 +-
 parser/tests/Copy.test                          |  119 +-
 query_execution/CMakeLists.txt                  |    1 +
 query_optimizer/CMakeLists.txt                  |    2 +
 query_optimizer/ExecutionGenerator.cpp          |   42 +-
 query_optimizer/ExecutionGenerator.hpp          |    8 +
 query_optimizer/logical/CMakeLists.txt          |   12 +
 query_optimizer/logical/CopyFrom.cpp            |    6 +-
 query_optimizer/logical/CopyFrom.hpp            |   43 +-
 query_optimizer/logical/CopyTo.cpp              |   75 +
 query_optimizer/logical/CopyTo.hpp              |  141 +
 query_optimizer/logical/LogicalType.hpp         |    1 +
 query_optimizer/physical/CMakeLists.txt         |   15 +-
 query_optimizer/physical/CopyFrom.cpp           |    6 +-
 query_optimizer/physical/CopyFrom.hpp           |   35 +-
 query_optimizer/physical/CopyTo.cpp             |   75 +
 query_optimizer/physical/CopyTo.hpp             |  148 +
 query_optimizer/physical/PhysicalType.hpp       |    1 +
 query_optimizer/resolver/CMakeLists.txt         |    2 +
 query_optimizer/resolver/Resolver.cpp           |  276 +-
 query_optimizer/resolver/Resolver.hpp           |   21 +-
 query_optimizer/strategy/CMakeLists.txt         |    2 +
 query_optimizer/strategy/OneToOne.cpp           |   27 +-
 .../tests/ExecutionGeneratorTestRunner.cpp      |    5 +-
 .../tests/execution_generator/CMakeLists.txt    |    6 +
 .../tests/execution_generator/Copy.test         |  105 +
 .../tests/physical_generator/Copy.test          |    4 +-
 query_optimizer/tests/resolver/Copy.test        |  164 +-
 relational_operators/CMakeLists.txt             |   22 +
 relational_operators/RelationalOperator.hpp     |    1 +
 relational_operators/TableExportOperator.cpp    |  322 ++
 relational_operators/TableExportOperator.hpp    |  224 ++
 relational_operators/TextScanOperator.cpp       |   70 +-
 relational_operators/TextScanOperator.hpp       |   10 +-
 relational_operators/WorkOrder.proto            |    3 +-
 .../tests/TextScanOperator_unittest.cpp         |    9 +-
 utility/BulkIOConfiguration.cpp                 |   50 +
 utility/BulkIOConfiguration.hpp                 |  117 +
 utility/CMakeLists.txt                          |    4 +
 46 files changed, 5615 insertions(+), 3129 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/parser/ParseKeyValue.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseKeyValue.hpp b/parser/ParseKeyValue.hpp
index 9d6d511..9acbba8 100644
--- a/parser/ParseKeyValue.hpp
+++ b/parser/ParseKeyValue.hpp
@@ -37,14 +37,15 @@ namespace quickstep {
  */
 class ParseKeyValue : public ParseTreeNode {
  public:
-  enum class KeyValueType {
+  enum KeyValueType {
+    kStringBool,
+    kStringInteger,
     kStringString,
-    kStringStringList,
-    kStringInteger
+    kStringStringList
   };
 
   /**
-   * @brief Single value constructor.
+   * @brief Constructor.
    *
    * @param line_number Line number of the first token of this node in the SQL statement.
    * @param column_number Column number of the first token of this node in the SQL statement.
@@ -87,7 +88,7 @@ class ParseKeyValue : public ParseTreeNode {
 class ParseKeyStringValue : public ParseKeyValue {
  public:
   /**
-   * @brief Single value constructor.
+   * @brief Constructor.
    *
    * @param line_number Line number of the first token of this node in the SQL statement.
    * @param column_number Column number of the first token of this node in the SQL statement.
@@ -102,7 +103,7 @@ class ParseKeyStringValue : public ParseKeyValue {
         value_(value) { }
 
   KeyValueType getKeyValueType() const override {
-    return ParseKeyValue::KeyValueType::kStringString;
+    return kStringString;
   }
 
   /**
@@ -143,7 +144,7 @@ class ParseKeyStringValue : public ParseKeyValue {
 class ParseKeyStringList : public ParseKeyValue {
  public:
   /**
-   * @brief Single value constructor.
+   * @brief Constructor.
    *
    * @param line_number Line number of the first token of this node in the SQL statement.
    * @param column_number Column number of the first token of this node in the SQL statement.
@@ -155,10 +156,10 @@ class ParseKeyStringList : public ParseKeyValue {
                      ParseString *key,
                      PtrList<ParseString> *value)
       : ParseKeyValue(line_number, column_number, key),
-        value_(value) { }
+        value_(value) {}
 
   KeyValueType getKeyValueType() const override {
-    return ParseKeyValue::KeyValueType::kStringStringList;
+    return kStringStringList;
   }
 
   /**
@@ -197,12 +198,12 @@ class ParseKeyStringList : public ParseKeyValue {
 };
 
 /**
- * @brief The parsed representation of a key-value pair.
+ * @brief The parsed representation of a key-value pair. Value is of int type.
  **/
 class ParseKeyIntegerValue : public ParseKeyValue {
  public:
   /**
-   * @brief Single value constructor.
+   * @brief Constructor.
    *
    * @param line_number Line number of the first token of this node in the SQL statement.
    * @param column_number Column number of the first token of this node in the SQL statement.
@@ -214,10 +215,10 @@ class ParseKeyIntegerValue : public ParseKeyValue {
                        ParseString *key,
                        NumericParseLiteralValue *value)
       : ParseKeyValue(line_number, column_number, key),
-        value_(value) { }
+        value_(value) {}
 
   KeyValueType getKeyValueType() const override {
-    return ParseKeyValue::KeyValueType::kStringInteger;
+    return kStringInteger;
   }
 
   /**
@@ -252,6 +253,62 @@ class ParseKeyIntegerValue : public ParseKeyValue {
   DISALLOW_COPY_AND_ASSIGN(ParseKeyIntegerValue);
 };
 
+/**
+ * @brief The parsed representation of a key-value pair. Value is of bool type.
+ **/
+class ParseKeyBoolValue : public ParseKeyValue {
+ public:
+  /**
+   * @brief Constructor.
+   *
+   * @param line_number Line number of the first token of this node in the SQL statement.
+   * @param column_number Column number of the first token of this node in the SQL statement.
+   * @param key A parse string representing the key.
+   * @param value A single bool literal value.
+   **/
+  ParseKeyBoolValue(const int line_number,
+                    const int column_number,
+                    ParseString *key,
+                    const bool value)
+      : ParseKeyValue(line_number, column_number, key),
+        value_(value) {}
+
+  KeyValueType getKeyValueType() const override {
+    return kStringBool;
+  }
+
+  /**
+   * @return The bool value.
+   */
+  bool value() const {
+    return value_;
+  }
+
+  std::string getName() const override {
+    return "KeyBoolValue";
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<const ParseTreeNode*> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
+    inline_field_names->push_back("key");
+    inline_field_values->push_back(key_->value());
+
+    inline_field_names->push_back("value");
+    inline_field_values->push_back(value_ ? "true" : "false");
+  }
+
+ private:
+  const bool value_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParseKeyBoolValue);
+};
+
 }  // namespace quickstep
 
 #endif  // QUICKSTEP_PARSER_PARSE_KEY_VALUE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/parser/ParseStatement.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseStatement.hpp b/parser/ParseStatement.hpp
index d876163..1e88044 100644
--- a/parser/ParseStatement.hpp
+++ b/parser/ParseStatement.hpp
@@ -60,16 +60,16 @@ class ParseStatement : public ParseTreeNode {
    * @brief The possible types of SQL statements.
    **/
   enum StatementType {
-    kCreateTable,
+    kCommand,
+    kCopy,
     kCreateIndex,
+    kCreateTable,
+    kDelete,
     kDropTable,
-    kSetOperation,
     kInsert,
-    kCopyFrom,
-    kUpdate,
-    kDelete,
     kQuit,
-    kCommand
+    kSetOperation,
+    kUpdate
   };
 
   /**
@@ -215,9 +215,10 @@ class ParseStatementCreateTable : public ParseStatement {
   DISALLOW_COPY_AND_ASSIGN(ParseStatementCreateTable);
 };
 
-  /**
-   * @brief The parsed representation of a CREATE INDEX statement.
-   **/
+
+/**
+ * @brief The parsed representation of a CREATE INDEX statement.
+ **/
 class ParseStatementCreateIndex : public ParseStatement {
  public:
     /**
@@ -423,6 +424,7 @@ class ParseStatementCreateIndex : public ParseStatement {
     DISALLOW_COPY_AND_ASSIGN(ParseStatementCreateIndex);
 };
 
+
 /**
  * @brief The parsed representation of a DROP TABLE statement.
  **/
@@ -479,6 +481,7 @@ class ParseStatementDropTable : public ParseStatement {
   DISALLOW_COPY_AND_ASSIGN(ParseStatementDropTable);
 };
 
+
 /**
  * @brief The parsed representation of an UNION/INTERSECT/SELECT statement.
  **/
@@ -519,14 +522,14 @@ class ParseStatementSetOperation : public ParseStatement {
   std::string getName() const override { return "SetOperationStatement"; }
 
   /**
-   * @return Gets the top-level set operation query.
+   * @return Get the top-level set operation query.
    */
   const ParseSetOperation* set_operation_query() const {
     return set_operation_query_.get();
   }
 
   /**
-   * @brief Gets the WITH table queries.
+   * @brief Get the WITH table queries.
    *
    * @return The parsed WITH table list.
    */
@@ -575,6 +578,7 @@ class ParseStatementSetOperation : public ParseStatement {
   DISALLOW_COPY_AND_ASSIGN(ParseStatementSetOperation);
 };
 
+
 /**
  * @brief The parsed representation of an INSERT statement.
  *
@@ -694,6 +698,7 @@ class ParseStatementInsertTuple : public ParseStatementInsert {
   DISALLOW_COPY_AND_ASSIGN(ParseStatementInsertTuple);
 };
 
+
 /**
  * @brief The parsed representation of an INSERT ... SELECT ... statement.
  **/
@@ -771,122 +776,132 @@ class ParseStatementInsertSelection : public ParseStatementInsert {
   DISALLOW_COPY_AND_ASSIGN(ParseStatementInsertSelection);
 };
 
+
 /**
- * @brief Optional parameters for a COPY FROM statement.
+ * @brief The parsed representation of a COPY FROM/COPY TO statement.
  **/
-struct ParseCopyFromParams : public ParseTreeNode {
-  /**
-   * @brief Constructor, sets default values.
-   **/
-  ParseCopyFromParams(const int line_number, const int column_number)
-      : ParseTreeNode(line_number, column_number),
-        escape_strings(true) {
-  }
-
-  std::string getName() const override { return "CopyFromParams"; }
-
+class ParseStatementCopy : public ParseStatement {
+ public:
   /**
-   * @brief Sets the column delimiter.
-   *
-   * @param delimiter_in The column delimiter string.
+   * @brief Copy direction (FROM text file/TO text file).
    */
-  void set_delimiter(ParseString* delimiter_in) {
-    delimiter.reset(delimiter_in);
-  }
-
-  /**
-   * @brief The string which terminates individual attribute values in the
-   *        input file. Can be NULL.
-   **/
-  std::unique_ptr<ParseString> delimiter;
+  enum CopyDirection {
+    kFrom,
+    kTo
+  };
 
   /**
-   * @brief If true, replace C-style escape sequences in strings from the input
-   *        text file.
+   * @brief Constructor.
+   *
+   * @param line_number Line number of the first token of this node in the SQL statement.
+   * @param column_number Column number of the first token of this node in the SQL statement.
+   * @param direction The copy direction (FROM/TO).
+   * @param relation_name The name of the relation.
+   * @param file_name The name of the file.
+   * @param params The optional parameters of the COPY statement.
    **/
-  bool escape_strings;
-
- protected:
-  void getFieldStringItems(
-      std::vector<std::string> *inline_field_names,
-      std::vector<std::string> *inline_field_values,
-      std::vector<std::string> *non_container_child_field_names,
-      std::vector<const ParseTreeNode*> *non_container_child_fields,
-      std::vector<std::string> *container_child_field_names,
-      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
-    if (delimiter != nullptr) {
-      inline_field_names->push_back("delimiter");
-      inline_field_values->push_back(delimiter->value());
-    }
-
-    inline_field_names->push_back("escape_string");
-    inline_field_values->push_back(escape_strings ? "true" : "false");
+  ParseStatementCopy(const int line_number,
+                     const int column_number,
+                     const CopyDirection direction,
+                     ParseString *relation_name,
+                     ParseString *file_name,
+                     PtrList<ParseKeyValue> *params)
+      : ParseStatement(line_number, column_number),
+        direction_(direction),
+        relation_name_(relation_name),
+        file_name_(file_name),
+        params_(params) {
   }
-};
 
-/**
- * @brief The parsed representation of a COPY FROM statement.
- **/
-class ParseStatementCopyFrom : public ParseStatement {
- public:
   /**
    * @brief Constructor.
    *
    * @param line_number Line number of the first token of this node in the SQL statement.
    * @param column_number Column number of the first token of this node in the SQL statement.
-   * @param relation_name The name of the relation to insert into.
-   * @param source_filename The name of the text file to bulk insert from.
-   * @param params The optional parameters of the COPY FROM statement (should
-   *        be supplied with defaults if not otherwise set).
+   * @param set_operation_query The set operation query.
+   * @param with_clause The WITH clause of common table query expressions.
+   * @param file_name The name of the file.
+   * @param params The optional parameters of the COPY statement.
    **/
-  ParseStatementCopyFrom(const int line_number,
-                         const int column_number,
-                         ParseString *relation_name,
-                         ParseString *source_filename,
-                         ParseCopyFromParams *params)
+  ParseStatementCopy(const int line_number,
+                     const int column_number,
+                     ParseSetOperation *set_operation_query,
+                     PtrVector<ParseSubqueryTableReference> *with_clause,
+                     ParseString *file_name,
+                     PtrList<ParseKeyValue> *params)
       : ParseStatement(line_number, column_number),
-        relation_name_(relation_name),
-        source_filename_(source_filename),
+        direction_(kTo),
+        set_operation_query_(set_operation_query),
+        with_clause_(with_clause),
+        file_name_(file_name),
         params_(params) {
   }
 
   /**
    * @brief Destructor.
    */
-  ~ParseStatementCopyFrom() override {
+  ~ParseStatementCopy() override {
   }
 
   StatementType getStatementType() const override {
-    return kCopyFrom;
+    return kCopy;
   }
 
-  std::string getName() const override { return "CopyFromStatement"; }
+  std::string getName() const override {
+    return "CopyStatement";
+  }
 
   /**
-   * @brief Get the name of the relation to insert into.
+   * @brief Get the direction (FROM text file/TO text file) of the COPY statement.
    *
-   * @return The name of the relation to insert into.
+   * return The direction of the COPY statement.
+   */
+  const CopyDirection getCopyDirection() const {
+    return direction_;
+  }
+
+  /**
+   * @brief Get the name of the relation.
+   *
+   * @return The name of the relation.
    **/
   const ParseString* relation_name() const {
     return relation_name_.get();
   }
 
   /**
-   * @brief Get the name of the text file to copy from.
+   * @brief Get the set operation query.
+   *
+   * @return The set operation query.
+   */
+  const ParseSetOperation* set_operation_query() const {
+    return set_operation_query_.get();
+  }
+
+  /**
+   * @brief Get the WITH table queries.
+   *
+   * @return The parsed WITH table list.
+   */
+  const PtrVector<ParseSubqueryTableReference>* with_clause() const {
+    return with_clause_.get();
+  }
+
+  /**
+   * @brief Get the name of the text file to import from/export to.
    *
-   * @return The name of the text file to copy from.
+   * @return The name of the text file.
    **/
-  const ParseString* source_filename() const {
-    return source_filename_.get();
+  const ParseString* file_name() const {
+    return file_name_.get();
   }
 
   /**
-   * @brief Get the additional COPY FROM parameters.
+   * @brief Get the additional COPY parameters.
    *
-   * @return The string which terminates individual attribute values in the
-   *         input file.
+   * @return The additional COPY parameters.
    **/
-  const ParseCopyFromParams* params() const {
+  const PtrList<ParseKeyValue>* params() const {
     return params_.get();
   }
 
@@ -898,24 +913,53 @@ class ParseStatementCopyFrom : public ParseStatement {
       std::vector<const ParseTreeNode*> *non_container_child_fields,
       std::vector<std::string> *container_child_field_names,
       std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
-    inline_field_names->push_back("relation_name");
-    inline_field_values->push_back(relation_name_->value());
+    inline_field_names->push_back("direction");
+    inline_field_values->push_back(direction_ == kFrom ? "FROM" : "TO");
 
-    inline_field_names->push_back("source_file");
-    inline_field_values->push_back(source_filename_->value());
+    inline_field_names->push_back("file");
+    inline_field_values->push_back(file_name_->value());
+
+    if (relation_name_ != nullptr) {
+      inline_field_names->push_back("relation_name");
+      inline_field_values->push_back(relation_name_->value());
+    }
+
+    if (set_operation_query_ != nullptr) {
+      non_container_child_field_names->push_back("set_operation_query");
+      non_container_child_fields->push_back(set_operation_query_.get());
+    }
+
+    if (with_clause_ != nullptr && !with_clause_->empty()) {
+      container_child_field_names->push_back("with_clause");
+      container_child_fields->emplace_back();
+      for (const ParseSubqueryTableReference &common_subquery : *with_clause_) {
+        container_child_fields->back().push_back(&common_subquery);
+      }
+    }
 
     if (params_ != nullptr) {
-      non_container_child_field_names->push_back("params");
-      non_container_child_fields->push_back(params_.get());
+      container_child_field_names->push_back("params");
+      container_child_fields->emplace_back();
+      for (const ParseKeyValue &param : *params_) {
+        container_child_fields->back().push_back(&param);
+      }
     }
   }
 
  private:
+  const CopyDirection direction_;
+
+  // NOTE(jianqiao):
+  // (1) Either relation_name_ or set_operation_query_ has non-null value.
+  // (2) set_operation_query_ must be null for COPY FROM statement.
   std::unique_ptr<ParseString> relation_name_;
-  std::unique_ptr<ParseString> source_filename_;
-  std::unique_ptr<ParseCopyFromParams> params_;
+  std::unique_ptr<ParseSetOperation> set_operation_query_;
+
+  std::unique_ptr<PtrVector<ParseSubqueryTableReference>> with_clause_;
+  std::unique_ptr<ParseString> file_name_;
+  std::unique_ptr<PtrList<ParseKeyValue>> params_;
 
-  DISALLOW_COPY_AND_ASSIGN(ParseStatementCopyFrom);
+  DISALLOW_COPY_AND_ASSIGN(ParseStatementCopy);
 };
 
 
@@ -1028,6 +1072,7 @@ class ParseStatementUpdate : public ParseStatement {
   DISALLOW_COPY_AND_ASSIGN(ParseStatementUpdate);
 };
 
+
 /**
  * @brief The parsed representation of a DELETE statement.
  **/
@@ -1140,6 +1185,7 @@ class ParseStatementQuit : public ParseStatement {
   DISALLOW_COPY_AND_ASSIGN(ParseStatementQuit);
 };
 
+
 /**
  * @brief Class to hold the parsed command name and an optional argument string.
  * @details Commands are non-sql statements which can be issued to quickstep.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/parser/SqlLexer.lpp
----------------------------------------------------------------------
diff --git a/parser/SqlLexer.lpp b/parser/SqlLexer.lpp
index c6402e0..d818d0b 100644
--- a/parser/SqlLexer.lpp
+++ b/parser/SqlLexer.lpp
@@ -45,13 +45,13 @@ class ParseAttributeDefinition;
 class ParseBlockProperties;
 class ParseColumnConstraint;
 class ParseCommand;
-struct ParseCopyFromParams;
 class ParseDataType;
 class ParseExpression;
 struct ParseFrameInfo;
 class ParseFunctionCall;
 class ParseGroupBy;
 class ParseHaving;
+class ParseKeyBoolValue;
 class ParseKeyIntegerValue;
 class ParseKeyStringValue;
 class ParseKeyStringList;
@@ -75,7 +75,7 @@ class ParseSimpleTableReference;
 class ParseSimpleWhenClause;
 class ParseStringKeyLiteralValues;
 class ParseStatement;
-class ParseStatementCopyFrom;
+class ParseStatementCopy;
 class ParseStatementCreateTable;
 class ParseStatementDelete;
 class ParseStatementDropTable;
@@ -200,7 +200,6 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "decimal"          return TOKEN_DECIMAL;
   "default"          return TOKEN_DEFAULT;
   "delete"           return TOKEN_DELETE;
-  "delimiter"        return TOKEN_DELIMITER;
   "desc"             return TOKEN_DESC;
   "descending"       return TOKEN_DESC;
   "distinct"         return TOKEN_DISTINCT;
@@ -208,7 +207,6 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "drop"             return TOKEN_DROP;
   "else"             return TOKEN_ELSE;
   "end"              return TOKEN_END;
-  "escape_strings"   return TOKEN_ESCAPE_STRINGS;
   "exists"           return TOKEN_EXISTS;
   "extract"          return TOKEN_EXTRACT;
   "false"            return TOKEN_FALSE;
@@ -271,11 +269,14 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "set"              return TOKEN_SET;
   "sma"              return TOKEN_SMA;
   "smallint"         return TOKEN_SMALLINT;
+  "stderr"           return TOKEN_STDERR;
+  "stdout"           return TOKEN_STDOUT;
   "substring"        return TOKEN_SUBSTRING;
   "table"            return TOKEN_TABLE;
   "then"             return TOKEN_THEN;
   "time"             return TOKEN_TIME;
   "timestamp"        return TOKEN_TIMESTAMP;
+  "to"               return TOKEN_TO;
   "true"             return TOKEN_TRUE;
   "tuplesample"      return TOKEN_TUPLESAMPLE;
   "unbounded"        return TOKEN_UNBOUNDED;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/parser/SqlParser.ypp
----------------------------------------------------------------------
diff --git a/parser/SqlParser.ypp b/parser/SqlParser.ypp
index 5db2171..8fbcdd7 100644
--- a/parser/SqlParser.ypp
+++ b/parser/SqlParser.ypp
@@ -168,8 +168,7 @@ typedef void* yyscan_t;
   quickstep::ParseKeyStringValue *key_string_value_;
   quickstep::ParseKeyStringList *key_string_list_;
   quickstep::ParseKeyIntegerValue *key_integer_value_;
-
-  quickstep::ParseCopyFromParams *copy_from_params_;
+  quickstep::ParseKeyBoolValue *key_bool_value_;
 
   quickstep::ParseAssignment *assignment_;
   quickstep::PtrList<quickstep::ParseAssignment> *assignment_list_;
@@ -182,7 +181,7 @@ typedef void* yyscan_t;
   quickstep::ParseStatementUpdate *update_statement_;
   quickstep::ParseStatementInsert *insert_statement_;
   quickstep::ParseStatementDelete *delete_statement_;
-  quickstep::ParseStatementCopyFrom *copy_from_statement_;
+  quickstep::ParseStatementCopy *copy_statement_;
   quickstep::ParseStatementCreateTable *create_table_statement_;
   quickstep::ParsePartitionClause *partition_clause_;
   quickstep::ParseBlockProperties *block_properties_;
@@ -275,14 +274,12 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_DECIMAL;
 %token TOKEN_DEFAULT;
 %token TOKEN_DELETE;
-%token TOKEN_DELIMITER;
 %token TOKEN_DESC;
 %token TOKEN_DISTINCT;
 %token TOKEN_DOUBLE;
 %token TOKEN_DROP;
 %token TOKEN_ELSE;
 %token TOKEN_END;
-%token TOKEN_ESCAPE_STRINGS;
 %token TOKEN_EXISTS;
 %token TOKEN_EXTRACT;
 %token TOKEN_FALSE;
@@ -342,11 +339,14 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_SET;
 %token TOKEN_SMA;
 %token TOKEN_SMALLINT;
+%token TOKEN_STDERR;
+%token TOKEN_STDOUT;
 %token TOKEN_SUBSTRING;
 %token TOKEN_TABLE;
 %token TOKEN_THEN;
 %token TOKEN_TIME;
 %token TOKEN_TIMESTAMP;
+%token TOKEN_TO;
 %token TOKEN_TRUE;
 %token TOKEN_TUPLESAMPLE;
 %token TOKEN_UNBOUNDED;
@@ -370,6 +370,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
   datetime_unit
   index_type
   partition_type
+  copy_to_target
 
 %type <boolean_value_>
   boolean_value
@@ -471,6 +472,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 
 %type <key_value_list_>
   key_value_list
+  opt_copy_params
   opt_index_properties
 
 %type <key_string_value_>
@@ -482,6 +484,9 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %type <key_integer_value_>
   key_integer_value
 
+%type <key_bool_value_>
+  key_bool_value
+
 %type <assignment_>
   assignment_item
 
@@ -511,12 +516,8 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %type <insert_statement_>
   insert_statement
 
-%type <copy_from_statement_>
-  copy_from_statement
-
-%type <copy_from_params_>
-  copy_from_params
-  opt_copy_from_params
+%type <copy_statement_>
+  copy_statement
 
 %type <create_table_statement_>
   create_table_statement
@@ -665,7 +666,7 @@ sql_statement:
   alter_table_statement {
     $$ = $1;
   }
-  | copy_from_statement {
+  | copy_statement {
     $$ = $1;
   }
   | create_table_statement {
@@ -1024,17 +1025,23 @@ key_value:
   }
   | key_integer_value {
     $$ = $1;
+  }
+  | key_bool_value {
+    $$ = $1;
   };
 
 key_string_value:
   any_name any_name {
     $$ = new quickstep::ParseKeyStringValue(@1.first_line, @1.first_column, $1, $2);
   }
+  | any_name TOKEN_STRING_SINGLE_QUOTED {
+    $$ = new quickstep::ParseKeyStringValue(@1.first_line, @1.first_column, $1, $2);
+  }
   | any_name TOKEN_ALL {
     // This is a special case to handle the COMPRESS ALL option of the BLOCK PROPERTIES.
     $$ = new quickstep::ParseKeyStringValue(@1.first_line, @1.first_column, $1,
         new quickstep::ParseString(@2.first_line, @2.first_column, "ALL"));
-  }
+  };
 
 key_string_list:
   any_name '(' name_commalist ')' {
@@ -1052,6 +1059,11 @@ key_integer_value:
     $$ = new quickstep::ParseKeyIntegerValue(@1.first_line, @1.first_column, $1, $2);
   };
 
+key_bool_value:
+  any_name boolean_value {
+    $$ = new quickstep::ParseKeyBoolValue(@1.first_line, @1.first_column, $1, $2);
+  };
+
 index_type:
   TOKEN_BITWEAVING {
     // Defaults to BitWeavingV, but IndexProperties can change this to H.
@@ -1100,35 +1112,44 @@ insert_statement:
   }
   ;
 
-copy_from_statement:
-  TOKEN_COPY any_name TOKEN_FROM TOKEN_STRING_SINGLE_QUOTED opt_copy_from_params {
-    $$ = new quickstep::ParseStatementCopyFrom(@1.first_line, @1.first_column, $2, $4, $5);
-  };
-
-opt_copy_from_params:
-  {
-    $$ = nullptr;
+copy_statement:
+  TOKEN_COPY any_name TOKEN_FROM TOKEN_STRING_SINGLE_QUOTED opt_copy_params {
+    $$ = new quickstep::ParseStatementCopy(@1.first_line, @1.first_column,
+                                           quickstep::ParseStatementCopy::kFrom,
+                                           $2, $4, $5);
   }
-  | TOKEN_WITH '(' copy_from_params ')' {
-    $$ = $3;
+  | TOKEN_COPY any_name copy_to_target opt_copy_params {
+    $$ = new quickstep::ParseStatementCopy(@1.first_line, @1.first_column,
+                                           quickstep::ParseStatementCopy::kTo,
+                                           $2, $3, $4);
+  }
+  | TOKEN_COPY set_operation_union copy_to_target opt_copy_params {
+    $$ = new quickstep::ParseStatementCopy(@1.first_line, @1.first_column,
+                                           $2, nullptr, $3, $4);
+  }
+  | with_clause TOKEN_COPY set_operation_union copy_to_target opt_copy_params {
+    $$ = new quickstep::ParseStatementCopy(@1.first_line, @1.first_column,
+                                           $3, $1, $4, $5);
   };
 
-copy_from_params:
-  TOKEN_DELIMITER TOKEN_STRING_SINGLE_QUOTED {
-    $$ = new quickstep::ParseCopyFromParams(@1.first_line, @1.first_column);
-    $$->set_delimiter($2);
+copy_to_target:
+  TOKEN_TO TOKEN_STRING_SINGLE_QUOTED {
+    $$ = new quickstep::ParseString($2->line_number(), $2->column_number(), "@" + $2->value());
+    delete $2;
   }
-  | TOKEN_ESCAPE_STRINGS boolean_value {
-    $$ = new quickstep::ParseCopyFromParams(@1.first_line, @1.first_column);
-    $$->escape_strings = $2;
+  | TOKEN_TO TOKEN_STDOUT {
+    $$ = new quickstep::ParseString(@2.first_line, @2.first_column, "$stdout");
   }
-  | copy_from_params ',' TOKEN_DELIMITER TOKEN_STRING_SINGLE_QUOTED {
-    $$ = $1;
-    $$->set_delimiter($4);
+  | TOKEN_TO TOKEN_STDERR {
+    $$ = new quickstep::ParseString(@2.first_line, @2.first_column, "$stderr");
+  };
+
+opt_copy_params:
+  {
+    $$ = nullptr;
   }
-  | copy_from_params ',' TOKEN_ESCAPE_STRINGS boolean_value {
-    $$ = $1;
-    $$->escape_strings = $4;
+  | TOKEN_WITH '(' key_value_list ')' {
+    $$ = $3;
   };
 
 update_statement:


[07/12] incubator-quickstep git commit: Add "COPY TO" operator for exporting data from Quickstep.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/relational_operators/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/relational_operators/CMakeLists.txt b/relational_operators/CMakeLists.txt
index 57ba9f9..0a60dca 100644
--- a/relational_operators/CMakeLists.txt
+++ b/relational_operators/CMakeLists.txt
@@ -71,6 +71,7 @@ add_library(quickstep_relationaloperators_SortMergeRunOperatorHelpers SortMergeR
             SortMergeRunOperatorHelpers.hpp)
 add_library(quickstep_relationaloperators_SortRunGenerationOperator SortRunGenerationOperator.cpp
             SortRunGenerationOperator.hpp)
+add_library(quickstep_relationaloperators_TableExportOperator TableExportOperator.cpp TableExportOperator.hpp)
 add_library(quickstep_relationaloperators_TableGeneratorOperator TableGeneratorOperator.cpp TableGeneratorOperator.hpp)
 add_library(quickstep_relationaloperators_TextScanOperator TextScanOperator.cpp TextScanOperator.hpp)
 add_library(quickstep_relationaloperators_UnionAllOperator UnionAllOperator.cpp UnionAllOperator.hpp)
@@ -473,6 +474,25 @@ target_link_libraries(quickstep_relationaloperators_SortRunGenerationOperator
                       quickstep_utility_Macros
                       quickstep_utility_SortConfiguration
                       tmb)
+target_link_libraries(quickstep_relationaloperators_TableExportOperator
+                      glog
+                      quickstep_catalog_CatalogAttribute
+                      quickstep_catalog_CatalogRelation
+                      quickstep_catalog_CatalogTypedefs
+                      quickstep_queryexecution_QueryContext
+                      quickstep_queryexecution_WorkOrderProtosContainer
+                      quickstep_queryexecution_WorkOrdersContainer
+                      quickstep_relationaloperators_RelationalOperator
+                      quickstep_relationaloperators_WorkOrder
+                      quickstep_relationaloperators_WorkOrder_proto
+                      quickstep_storage_StorageBlockInfo
+                      quickstep_storage_ValueAccessor
+                      quickstep_threading_SpinMutex
+                      quickstep_types_TypedValue
+                      quickstep_types_containers_Tuple
+                      quickstep_utility_BulkIOConfiguration
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
 target_link_libraries(quickstep_relationaloperators_TableGeneratorOperator
                       glog
                       quickstep_catalog_CatalogRelation
@@ -508,6 +528,7 @@ target_link_libraries(quickstep_relationaloperators_TextScanOperator
                       quickstep_types_containers_ColumnVector
                       quickstep_types_containers_ColumnVectorsValueAccessor
                       quickstep_types_containers_Tuple
+                      quickstep_utility_BulkIOConfiguration
                       quickstep_utility_Glob
                       quickstep_utility_Macros
                       tmb)
@@ -637,6 +658,7 @@ target_link_libraries(quickstep_relationaloperators
                       quickstep_relationaloperators_SortMergeRunOperatorHelpers
                       quickstep_relationaloperators_SortMergeRunOperator_proto
                       quickstep_relationaloperators_SortRunGenerationOperator
+                      quickstep_relationaloperators_TableExportOperator
                       quickstep_relationaloperators_TableGeneratorOperator
                       quickstep_relationaloperators_TextScanOperator
                       quickstep_relationaloperators_UnionAllOperator

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/relational_operators/RelationalOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/RelationalOperator.hpp b/relational_operators/RelationalOperator.hpp
index 9307b5a..60edf08 100644
--- a/relational_operators/RelationalOperator.hpp
+++ b/relational_operators/RelationalOperator.hpp
@@ -85,6 +85,7 @@ class RelationalOperator {
     kSelect,
     kSortMergeRun,
     kSortRunGeneration,
+    kTableExport,
     kTableGenerator,
     kTextScan,
     kUnionAll,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/relational_operators/TableExportOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/TableExportOperator.cpp b/relational_operators/TableExportOperator.cpp
new file mode 100644
index 0000000..9056603
--- /dev/null
+++ b/relational_operators/TableExportOperator.cpp
@@ -0,0 +1,322 @@
+/**
+ * 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.
+ **/
+
+#include "relational_operators/TableExportOperator.hpp"
+
+#include <cstdio>
+#include <exception>
+#include <string>
+#include <utility>
+
+#include "catalog/CatalogAttribute.hpp"
+#include "query_execution/QueryContext.hpp"
+#include "query_execution/WorkOrderProtosContainer.hpp"
+#include "query_execution/WorkOrdersContainer.hpp"
+#include "relational_operators/WorkOrder.pb.h"
+#include "storage/StorageBlockInfo.hpp"
+#include "storage/ValueAccessor.hpp"
+#include "threading/SpinMutex.hpp"
+#include "types/TypedValue.hpp"
+#include "types/containers/Tuple.hpp"
+#include "utility/BulkIOConfiguration.hpp"
+#include "utility/StringUtil.hpp"
+
+#include "glog/logging.h"
+
+#include "tmb/id_typedefs.h"
+
+namespace quickstep {
+
+bool TableExportOperator::getAllWorkOrders(
+    WorkOrdersContainer *container,
+    QueryContext *query_context,
+    StorageManager *storage_manager,
+    const tmb::client_id scheduler_client_id,
+    tmb::MessageBus *bus) {
+  const auto add_work_order = [&](const block_id input_block_id,
+                                  const bool is_first_work_order) -> void {
+    std::unique_ptr<std::string> output_buffer = std::make_unique<std::string>();
+    container->addNormalWorkOrder(
+        new TableExportToStringWorkOrder(query_id_,
+                                         input_relation_,
+                                         input_block_id,
+                                         options_->getFormat(),
+                                         is_first_work_order && options_->hasHeader(),
+                                         options_->getDelimiter(),
+                                         options_->escapeStrings(),
+                                         options_->getQuoteCharacter(),
+                                         options_->getNullString(),
+                                         output_buffer.get(),
+                                         op_index_,
+                                         scheduler_client_id,
+                                         storage_manager,
+                                         bus),
+        op_index_);
+
+    SpinMutexLock lock(output_buffers_mutex_);
+    output_buffers_.emplace(input_block_id, output_buffer.release());
+  };
+
+  if (input_relation_is_stored_) {
+    if (!started_) {
+      for (std::size_t i = 0; i < input_relation_block_ids_.size(); ++i) {
+        add_work_order(input_relation_block_ids_[i], i == 0);
+      }
+      started_ = true;
+    }
+    return true;
+  } else {
+    while (num_workorders_generated_ < input_relation_block_ids_.size()) {
+      add_work_order(input_relation_block_ids_[num_workorders_generated_],
+                     num_workorders_generated_ == 0);
+      ++num_workorders_generated_;
+    }
+    return done_feeding_input_relation_;
+  }
+}
+
+bool TableExportOperator::getAllWorkOrderProtos(
+    WorkOrderProtosContainer *container) {
+  // TODO(quickstep-team): Implement TextExportOperator for the distributed case.
+  LOG(FATAL) << "TableExportOperator::getAllWorkOrderProtos() is not supported";
+}
+
+void TableExportOperator::receiveFeedbackMessage(
+    const WorkOrder::FeedbackMessage &msg) {
+  DCHECK(TableExportOperator::kBlockOutputMessage == msg.type());
+  DCHECK(msg.payload_size() == sizeof(block_id));
+
+  if (file_ == nullptr) {
+    const std::string lo_file_name = ToLower(file_name_);
+    if (lo_file_name == "$stdout") {
+      file_ = stdout;
+    } else if (lo_file_name == "$stderr") {
+      file_ = stderr;
+    } else {
+      file_ = std::fopen(file_name_.substr(1).c_str(), "wb");
+      // TODO(quickstep-team): Decent handling of exceptions at query runtime.
+      if (file_ == nullptr) {
+        throw std::runtime_error("Can not open file " + file_name_ + " for writing");
+      }
+    }
+  }
+
+  // Mark block done.
+  const block_id done_block_id = *static_cast<const block_id*>(msg.payload());
+  {
+    SpinMutexLock lock(output_buffers_mutex_);
+    DCHECK(output_buffers_.find(done_block_id) != output_buffers_.end());
+    output_buffers_.at(done_block_id).done = true;
+  }
+
+  while (true) {
+    block_id next_block_id;
+    {
+      SpinMutexLock lock(block_ids_mutex_);
+      next_block_id = input_relation_block_ids_[num_blocks_written_];
+    }
+    std::unique_ptr<std::string> output_buffer;
+    {
+      SpinMutexLock lock(output_buffers_mutex_);
+      auto it = output_buffers_.find(next_block_id);
+      if (it == output_buffers_.end() || !it->second.done) {
+        break;
+      }
+      output_buffer = std::move(it->second.buffer);
+      output_buffers_.erase(it);
+    }
+    std::fwrite(output_buffer->c_str(), 1, output_buffer->length(), file_);
+    ++num_blocks_written_;
+  }
+}
+
+void TableExportOperator::updateCatalogOnCompletion() {
+  if (file_ != nullptr && file_ != stdout && file_ != stderr) {
+    std::fclose(file_);
+  }
+  file_ = nullptr;
+}
+
+void TableExportToStringWorkOrder::execute() {
+  BlockReference block(
+      storage_manager_->getBlock(input_block_id_, input_relation_));
+  std::unique_ptr<ValueAccessor> accessor(
+      block->getTupleStorageSubBlock().createValueAccessor());
+
+  switch (format_) {
+    case BulkIOFormat::kCSV:
+      writeToString<&TableExportToStringWorkOrder::quoteCSVField>(
+          accessor.get(), output_buffer_);
+      break;
+    case BulkIOFormat::kText:
+      writeToString<&TableExportToStringWorkOrder::escapeTextField>(
+          accessor.get(), output_buffer_);
+      break;
+    default:
+      LOG(FATAL) << "Unsupported export format in TableExportWorkOrder::execute()";
+  }
+
+  // Send completion message to operator.
+  FeedbackMessage msg(TableExportOperator::kBlockOutputMessage,
+                      getQueryID(),
+                      operator_index_,
+                      new block_id(input_block_id_),
+                      sizeof(input_block_id_));
+  SendFeedbackMessage(
+      bus_, ClientIDMap::Instance()->getValue(), scheduler_client_id_, msg);
+}
+
+inline std::string TableExportToStringWorkOrder::quoteCSVField(std::string &&field) const {
+  bool need_quote = false;
+  for (const char c : field) {
+    if (c == column_delimiter_ || c == quote_character_ || c == '\n') {
+      need_quote = true;
+      break;
+    }
+  }
+  if (!need_quote) {
+    return std::move(field);
+  }
+
+  std::string quoted;
+  quoted.push_back(quote_character_);
+  for (const char c : field) {
+    if (c == quote_character_) {
+      quoted.push_back(c);
+    }
+    quoted.push_back(c);
+  }
+  quoted.push_back(quote_character_);
+  return quoted;
+}
+
+
+inline std::string TableExportToStringWorkOrder::escapeTextField(std::string &&field) const {
+  if (escape_strings_ == false || field == "\\N") {
+    return std::move(field);
+  }
+  bool need_escape = false;
+  for (const unsigned char c : field) {
+    if (c < ' ' || c == '\\' || c == column_delimiter_) {
+      need_escape = true;
+      break;
+    }
+  }
+  if (!need_escape) {
+    return std::move(field);
+  }
+
+  std::string escaped;
+  for (const unsigned char c : field) {
+    if (c < 32) {
+      switch (c) {
+        case '\b':
+          // Backspace.
+          escaped.append("\\b");
+          break;
+        case '\f':
+          // Form-feed.
+          escaped.append("\\f");
+          break;
+        case '\n':
+          // Newline.
+          escaped.append("\\n");
+          break;
+        case '\r':
+          // Carriage return.
+          escaped.append("\\r");
+          break;
+        case '\t':
+          // Tab.
+          escaped.append("\\t");
+          break;
+        case '\v':
+          // Vertical tab
+          escaped.append("\\v");
+          break;
+        default: {
+          // Use hexidecimal representation.
+          static const std::string digits = "0123456789ABCDEF";
+          escaped.append("\\x");
+          escaped.push_back(digits.at(c >> 4));
+          escaped.push_back(digits.at(c & 0xF));
+          break;
+        }
+      }
+    } else {
+      if (c == '\\' || c == column_delimiter_) {
+        escaped.push_back('\\');
+      }
+      escaped.push_back(c);
+    }
+  }
+  return escaped;
+}
+
+template <std::string (TableExportToStringWorkOrder::*transform)(std::string&&) const,
+          typename Container, typename Functor>
+inline void TableExportToStringWorkOrder::writeEachToString(const Container &container,
+                                                            std::string *output,
+                                                            const Functor &functor) const {
+  auto it = container.begin();
+  if (it != container.end()) {
+    std::size_t idx = 0;
+    output->append((this->*transform)(functor(*it, idx++)));
+    while ((++it) != container.end()) {
+      output->push_back(column_delimiter_);
+      output->append((this->*transform)(functor(*it, idx++)));
+    }
+  }
+}
+
+template <std::string (TableExportToStringWorkOrder::*transform)(std::string&&) const>
+void TableExportToStringWorkOrder::writeToString(ValueAccessor *accessor,
+                                                 std::string *output) const {
+  std::vector<const Type*> value_types;
+  value_types.reserve(input_relation_.size());
+  for (const CatalogAttribute &attribute : input_relation_) {
+    value_types.emplace_back(&attribute.getType());
+  }
+
+  if (print_header_) {
+    writeEachToString<transform>(
+        input_relation_, output,
+        [&](const CatalogAttribute &attr, const std::size_t idx) -> std::string {
+      return attr.getDisplayName();
+    });
+    output->push_back('\n');
+  }
+
+  accessor->beginIterationVirtual();
+  while (accessor->nextVirtual()) {
+    std::unique_ptr<Tuple> tuple(accessor->getTupleVirtual());
+    writeEachToString<transform>(
+        *tuple, output,
+        [&](const TypedValue &value, const std::size_t idx) -> std::string {
+      if (value.isNull()) {
+        return null_string_;
+      } else {
+        return value_types[idx]->printValueToString(value);
+      }
+    });
+    output->push_back('\n');
+  }
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/relational_operators/TableExportOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/TableExportOperator.hpp b/relational_operators/TableExportOperator.hpp
new file mode 100644
index 0000000..e15144b
--- /dev/null
+++ b/relational_operators/TableExportOperator.hpp
@@ -0,0 +1,224 @@
+/**
+ * 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.
+ **/
+
+#ifndef QUICKSTEP_RELATIONAL_OPERATORS_TABLE_EXPORT_OPERATOR_HPP_
+#define QUICKSTEP_RELATIONAL_OPERATORS_TABLE_EXPORT_OPERATOR_HPP_
+
+#include <cstddef>
+#include <cstdio>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "catalog/CatalogRelation.hpp"
+#include "catalog/CatalogTypedefs.hpp"
+#include "query_execution/QueryContext.hpp"
+#include "relational_operators/RelationalOperator.hpp"
+#include "relational_operators/WorkOrder.hpp"
+#include "storage/StorageBlockInfo.hpp"
+#include "threading/SpinMutex.hpp"
+#include "utility/BulkIOConfiguration.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+#include "tmb/id_typedefs.h"
+
+namespace tmb { class MessageBus; }
+
+namespace quickstep {
+
+class CatalogRelationSchema;
+class InsertDestination;
+class StorageManager;
+class ValueAccessor;
+class WorkOrderProtosContainer;
+class WorkOrdersContainer;
+
+namespace serialization { class WorkOrder; }
+
+/** \addtogroup RelationalOperators
+ *  @{
+ */
+
+class TableExportOperator : public RelationalOperator {
+ public:
+  enum FeedbackMessageType : WorkOrder::FeedbackMessageType {
+      kBlockOutputMessage,
+  };
+
+  TableExportOperator(const std::size_t query_id,
+                      const CatalogRelation &input_relation,
+                      const bool input_relation_is_stored,
+                      const std::string &file_name,
+                      const BulkIOConfigurationPtr &options)
+      : RelationalOperator(query_id),
+        input_relation_(input_relation),
+        input_relation_is_stored_(input_relation_is_stored),
+        file_name_(file_name),
+        options_(options),
+        input_relation_block_ids_(input_relation_is_stored
+                                      ? input_relation.getBlocksSnapshot()
+                                      : std::vector<block_id>()),
+        num_workorders_generated_(0),
+        started_(false),
+        num_blocks_written_(0),
+        file_(nullptr) {}
+
+  ~TableExportOperator() override {}
+
+  OperatorType getOperatorType() const override {
+    return kTableExport;
+  }
+
+  std::string getName() const override {
+    return "TableExportOperator";
+  }
+
+  const CatalogRelation& input_relation() const {
+    return input_relation_;
+  }
+
+  bool getAllWorkOrders(WorkOrdersContainer *container,
+                        QueryContext *query_context,
+                        StorageManager *storage_manager,
+                        const tmb::client_id scheduler_client_id,
+                        tmb::MessageBus *bus) override;
+
+  bool getAllWorkOrderProtos(WorkOrderProtosContainer *container) override;
+
+  void feedInputBlock(const block_id input_block_id,
+                      const relation_id input_relation_id,
+                      const partition_id part_id) override {
+    if (input_relation_id == input_relation_.getID()) {
+      SpinMutexLock lock(block_ids_mutex_);
+      input_relation_block_ids_.emplace_back(input_block_id);
+    }
+  }
+
+  void receiveFeedbackMessage(const WorkOrder::FeedbackMessage &msg) override;
+
+  void updateCatalogOnCompletion() override;
+
+ private:
+  // Buffer for storing a block's exported string.
+  struct BlockBuffer {
+    BlockBuffer(std::string *buffer_in)
+        : done(false),
+          buffer(buffer_in) {}
+    bool done;
+    std::unique_ptr<std::string> buffer;
+  };
+
+  const CatalogRelation &input_relation_;
+  const bool input_relation_is_stored_;
+  const std::string file_name_;
+  const BulkIOConfigurationPtr options_;
+
+  std::vector<block_id> input_relation_block_ids_;
+  std::size_t num_workorders_generated_;
+  SpinMutex block_ids_mutex_;
+
+  bool started_;
+
+  std::size_t num_blocks_written_;
+  std::unordered_map<block_id, BlockBuffer> output_buffers_;
+  SpinMutex output_buffers_mutex_;
+
+  FILE *file_;
+
+  DISALLOW_COPY_AND_ASSIGN(TableExportOperator);
+};
+
+class TableExportToStringWorkOrder : public WorkOrder {
+ public:
+  TableExportToStringWorkOrder(const std::size_t query_id,
+                               const CatalogRelationSchema &input_relation,
+                               const block_id input_block_id,
+                               const BulkIOFormat format,
+                               const bool print_header,
+                               const char column_delimiter,
+                               const bool escape_strings,
+                               const char quote_character,
+                               const std::string null_string,
+                               std::string *output_buffer,
+                               const std::size_t operator_index,
+                               const tmb::client_id scheduler_client_id,
+                               StorageManager *storage_manager,
+                               MessageBus *bus)
+      : WorkOrder(query_id),
+        input_relation_(input_relation),
+        input_block_id_(input_block_id),
+        format_(format),
+        print_header_(print_header),
+        column_delimiter_(column_delimiter),
+        escape_strings_(escape_strings),
+        quote_character_(quote_character),
+        null_string_(null_string),
+        output_buffer_(output_buffer),
+        operator_index_(operator_index),
+        scheduler_client_id_(scheduler_client_id),
+        storage_manager_(storage_manager),
+        bus_(bus) {
+  }
+
+  ~TableExportToStringWorkOrder() override {}
+
+  void execute() override;
+
+ private:
+  inline std::string quoteCSVField(std::string &&field) const;
+  inline std::string escapeTextField(std::string &&field) const;
+
+  template <std::string (TableExportToStringWorkOrder::*transform)(std::string&&) const,
+            typename Container, typename Functor>
+  inline void writeEachToString(const Container &container,
+                                std::string *output,
+                                const Functor &functor) const;
+
+  template <std::string (TableExportToStringWorkOrder::*transform)(std::string&&) const>
+  void writeToString(ValueAccessor *accessor, std::string *output) const;
+
+  const CatalogRelationSchema &input_relation_;
+  const block_id input_block_id_;
+
+  const BulkIOFormat format_;
+  const bool print_header_;
+  const char column_delimiter_;
+  const bool escape_strings_;
+  const char quote_character_;
+  const std::string null_string_;
+
+  std::string *output_buffer_;
+
+  const std::size_t operator_index_;
+  const tmb::client_id scheduler_client_id_;
+  StorageManager *storage_manager_;
+  MessageBus *bus_;
+
+  DISALLOW_COPY_AND_ASSIGN(TableExportToStringWorkOrder);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_RELATIONAL_OPERATORS_TABLE_EXPORT_OPERATOR_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/relational_operators/TextScanOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/TextScanOperator.cpp b/relational_operators/TextScanOperator.cpp
index 3ca3af4..3cb78fb 100644
--- a/relational_operators/TextScanOperator.cpp
+++ b/relational_operators/TextScanOperator.cpp
@@ -31,6 +31,7 @@
 #include <cstdint>
 #include <cstdio>
 #include <cstdlib>
+#include <exception>
 #include <memory>
 #include <string>
 #include <utility>
@@ -54,6 +55,7 @@
 #include "types/containers/ColumnVector.hpp"
 #include "types/containers/ColumnVectorsValueAccessor.hpp"
 #include "types/containers/Tuple.hpp"
+#include "utility/BulkIOConfiguration.hpp"
 #include "utility/Glob.hpp"
 
 #include "gflags/gflags.h"
@@ -61,9 +63,6 @@
 
 #include "tmb/id_typedefs.h"
 
-using std::size_t;
-using std::string;
-
 namespace quickstep {
 
 // Text segment size set to 256KB.
@@ -82,14 +81,19 @@ static bool ValidateTextScanTextSegmentSize(const char *flagname,
   return true;
 }
 
-static const volatile bool text_scan_text_segment_size_dummy = gflags::RegisterFlagValidator(
-    &FLAGS_textscan_text_segment_size, &ValidateTextScanTextSegmentSize);
+static const volatile bool text_scan_text_segment_size_dummy =
+    gflags::RegisterFlagValidator(
+        &FLAGS_textscan_text_segment_size, &ValidateTextScanTextSegmentSize);
 
 namespace {
 
-size_t getFileSize(const string &file_name) {
+static std::size_t GetFileSize(const std::string &file_name) {
   // Use standard C libary to retrieve the file size.
   FILE *fp = std::fopen(file_name.c_str(), "rb");
+  // TODO(quickstep-team): Decent handling of exceptions at query runtime.
+  if (fp == nullptr) {
+    throw std::runtime_error("Can not open file " + file_name + " for reading");
+  }
   std::fseek(fp, 0, SEEK_END);
   const std::size_t file_size = std::ftell(fp);
   std::fclose(fp);
@@ -127,7 +131,7 @@ bool TextScanOperator::getAllWorkOrders(
         << "File " << file << " is not readable due to permission issues.";
 #endif  // QUICKSTEP_HAVE_UNISTD
 
-    const std::size_t file_size = getFileSize(file);
+    const std::size_t file_size = GetFileSize(file);
 
     std::size_t text_offset = 0;
     for (size_t num_full_segments = file_size / FLAGS_textscan_text_segment_size;
@@ -138,8 +142,8 @@ bool TextScanOperator::getAllWorkOrders(
                                 file,
                                 text_offset,
                                 FLAGS_textscan_text_segment_size,
-                                field_terminator_,
-                                process_escape_sequences_,
+                                options_->getDelimiter(),
+                                options_->escapeStrings(),
                                 output_destination),
           op_index_);
     }
@@ -152,8 +156,8 @@ bool TextScanOperator::getAllWorkOrders(
                                 file,
                                 text_offset,
                                 file_size - text_offset,
-                                field_terminator_,
-                                process_escape_sequences_,
+                                options_->getDelimiter(),
+                                options_->escapeStrings(),
                                 output_destination),
           op_index_);
     }
@@ -169,22 +173,25 @@ bool TextScanOperator::getAllWorkOrderProtos(WorkOrderProtosContainer *container
     return true;
   }
 
-  for (const string &file : files) {
-    const std::size_t file_size = getFileSize(file);
+  for (const std::string &file : files) {
+    const std::size_t file_size = GetFileSize(file);
 
     size_t text_offset = 0;
     for (size_t num_full_segments = file_size / FLAGS_textscan_text_segment_size;
          num_full_segments > 0;
          --num_full_segments, text_offset += FLAGS_textscan_text_segment_size) {
-      container->addWorkOrderProto(createWorkOrderProto(file, text_offset, FLAGS_textscan_text_segment_size),
-                                   op_index_);
+      container->addWorkOrderProto(
+          createWorkOrderProto(file, text_offset,
+                               FLAGS_textscan_text_segment_size),
+          op_index_);
     }
 
     // Deal with the residual partial segment whose size is less than
     // 'FLAGS_textscan_text_segment_size'.
     if (text_offset < file_size) {
-      container->addWorkOrderProto(createWorkOrderProto(file, text_offset, file_size - text_offset),
-                                   op_index_);
+      container->addWorkOrderProto(
+          createWorkOrderProto(file, text_offset, file_size - text_offset),
+          op_index_);
     }
   }
 
@@ -192,9 +199,10 @@ bool TextScanOperator::getAllWorkOrderProtos(WorkOrderProtosContainer *container
   return true;
 }
 
-serialization::WorkOrder* TextScanOperator::createWorkOrderProto(const string &filename,
-                                                                 const size_t text_offset,
-                                                                 const size_t text_segment_size) {
+serialization::WorkOrder* TextScanOperator::createWorkOrderProto(
+    const std::string &filename,
+    const std::size_t text_offset,
+    const std::size_t text_segment_size) {
   serialization::WorkOrder *proto = new serialization::WorkOrder;
   proto->set_work_order_type(serialization::TEXT_SCAN);
   proto->set_query_id(query_id_);
@@ -202,9 +210,10 @@ serialization::WorkOrder* TextScanOperator::createWorkOrderProto(const string &f
   proto->SetExtension(serialization::TextScanWorkOrder::filename, filename);
   proto->SetExtension(serialization::TextScanWorkOrder::text_offset, text_offset);
   proto->SetExtension(serialization::TextScanWorkOrder::text_segment_size, text_segment_size);
-  proto->SetExtension(serialization::TextScanWorkOrder::field_terminator, field_terminator_);
+  proto->SetExtension(serialization::TextScanWorkOrder::field_terminator,
+                      options_->getDelimiter());
   proto->SetExtension(serialization::TextScanWorkOrder::process_escape_sequences,
-                      process_escape_sequences_);
+                      options_->escapeStrings());
   proto->SetExtension(serialization::TextScanWorkOrder::insert_destination_index,
                       output_destination_index_);
 
@@ -235,12 +244,14 @@ void TextScanWorkOrder::execute() {
     file_handle = hdfsOpenFile(hdfs, filename_.c_str(), O_RDONLY, buffer_size,
                                0 /* default replication */, 0 /* default block size */);
     if (file_handle == nullptr) {
-      LOG(ERROR) << "Failed to open file " << filename_ << " with error: " << strerror(errno);
+      LOG(ERROR) << "Failed to open file " << filename_
+                 << " with error: " << strerror(errno);
       return;
     }
 
     if (hdfsSeek(hdfs, file_handle, text_offset_)) {
-      LOG(ERROR) << "Failed to seek in file " << filename_ << " with error: " << strerror(errno);
+      LOG(ERROR) << "Failed to seek in file " << filename_
+                 << " with error: " << strerror(errno);
 
       hdfsCloseFile(hdfs, file_handle);
       return;
@@ -248,7 +259,9 @@ void TextScanWorkOrder::execute() {
 
     bytes_read = hdfsRead(hdfs, file_handle, buffer, text_segment_size_);
     while (bytes_read != text_segment_size_) {
-      bytes_read += hdfsRead(hdfs, file_handle, buffer + bytes_read, text_segment_size_ - bytes_read);
+      bytes_read += hdfsRead(hdfs, file_handle,
+                             buffer + bytes_read,
+                             text_segment_size_ - bytes_read);
     }
   }
 #endif  // QUICKSTEP_HAVE_FILE_MANAGER_HDFS
@@ -325,7 +338,8 @@ void TextScanWorkOrder::execute() {
   if (use_hdfs) {
 #ifdef QUICKSTEP_HAVE_FILE_MANAGER_HDFS
     if (hdfsSeek(hdfs, file_handle, dynamic_read_offset)) {
-      LOG(ERROR) << "Failed to seek in file " << filename_ << " with error: " << strerror(errno);
+      LOG(ERROR) << "Failed to seek in file " << filename_
+                 << " with error: " << strerror(errno);
 
       hdfsCloseFile(hdfs, file_handle);
       return;
@@ -343,7 +357,9 @@ void TextScanWorkOrder::execute() {
 
       // Read again when acrossing the HDFS block boundary.
       if (bytes_read != dynamic_read_size) {
-        bytes_read += hdfsRead(hdfs, file_handle, buffer + bytes_read, dynamic_read_size - bytes_read);
+        bytes_read += hdfsRead(hdfs, file_handle,
+                               buffer + bytes_read,
+                               dynamic_read_size - bytes_read);
       }
 #endif  // QUICKSTEP_HAVE_FILE_MANAGER_HDFS
     } else {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/relational_operators/TextScanOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/TextScanOperator.hpp b/relational_operators/TextScanOperator.hpp
index 4dbeb92..e5df60a 100644
--- a/relational_operators/TextScanOperator.hpp
+++ b/relational_operators/TextScanOperator.hpp
@@ -32,6 +32,7 @@
 #include "relational_operators/RelationalOperator.hpp"
 #include "relational_operators/WorkOrder.hpp"
 #include "types/containers/Tuple.hpp"
+#include "utility/BulkIOConfiguration.hpp"
 #include "utility/Macros.hpp"
 
 #include "glog/logging.h"
@@ -121,15 +122,13 @@ class TextScanOperator : public RelationalOperator {
    **/
   TextScanOperator(const std::size_t query_id,
                    const std::string &file_pattern,
-                   const char field_terminator,
-                   const bool process_escape_sequences,
+                   const BulkIOConfigurationPtr &options,
                    const CatalogRelation &output_relation,
                    const QueryContext::insert_destination_id output_destination_index)
       : RelationalOperator(query_id, 1u, output_relation.getNumPartitions() != 1u /* has_repartition */,
                            output_relation.getNumPartitions()),
         file_pattern_(file_pattern),
-        field_terminator_(field_terminator),
-        process_escape_sequences_(process_escape_sequences),
+        options_(options),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
         work_generated_(false) {}
@@ -166,8 +165,7 @@ class TextScanOperator : public RelationalOperator {
                                                  const std::size_t text_segment_size);
 
   const std::string file_pattern_;
-  const char field_terminator_;
-  const bool process_escape_sequences_;
+  const BulkIOConfigurationPtr options_;
 
   const CatalogRelation &output_relation_;
   const QueryContext::insert_destination_id output_destination_index_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/relational_operators/WorkOrder.proto
----------------------------------------------------------------------
diff --git a/relational_operators/WorkOrder.proto b/relational_operators/WorkOrder.proto
index 6dafbe0..a9b4afd 100644
--- a/relational_operators/WorkOrder.proto
+++ b/relational_operators/WorkOrder.proto
@@ -21,7 +21,7 @@ package quickstep.serialization;
 
 import "relational_operators/SortMergeRunOperator.proto";
 
-// Next tag: 26.
+// Next tag: 27.
 enum WorkOrderType {
   AGGREGATION = 1;
   BUILD_AGGREGATION_EXISTENCE_MAP = 23;
@@ -43,6 +43,7 @@ enum WorkOrderType {
   SELECT = 15;
   SORT_MERGE_RUN = 16;
   SORT_RUN_GENERATION = 17;
+  TABLE_EXPORT = 26;
   TABLE_GENERATOR = 18;
   TEXT_SCAN = 19;
   UNION_ALL = 24;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/relational_operators/tests/TextScanOperator_unittest.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/tests/TextScanOperator_unittest.cpp b/relational_operators/tests/TextScanOperator_unittest.cpp
index c92a3dd..d609817 100644
--- a/relational_operators/tests/TextScanOperator_unittest.cpp
+++ b/relational_operators/tests/TextScanOperator_unittest.cpp
@@ -40,6 +40,7 @@
 #include "threading/ThreadIDBasedMap.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
+#include "utility/BulkIOConfiguration.hpp"
 #include "utility/MemStream.hpp"
 
 #include "gflags/gflags.h"
@@ -191,11 +192,15 @@ TEST_F(TextScanOperatorTest, ScanTest) {
   output_destination_proto->set_relation_id(relation_->getID());
   output_destination_proto->set_relational_op_index(kOpIndex);
 
+  std::unique_ptr<BulkIOConfiguration> options =
+      std::make_unique<BulkIOConfiguration>(BulkIOFormat::kText);
+  options->setDelimiter('\t');
+  options->setEscapeStrings(true);
+
   std::unique_ptr<TextScanOperator> text_scan_op(
       new TextScanOperator(kQueryId,
                            input_filename,
-                           '\t',
-                           true,
+                           BulkIOConfigurationPtr(options.release()),
                            *relation_,
                            output_destination_index));
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/utility/BulkIOConfiguration.cpp
----------------------------------------------------------------------
diff --git a/utility/BulkIOConfiguration.cpp b/utility/BulkIOConfiguration.cpp
new file mode 100644
index 0000000..af95dca
--- /dev/null
+++ b/utility/BulkIOConfiguration.cpp
@@ -0,0 +1,50 @@
+/**
+ * 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.
+ **/
+
+#include "utility/BulkIOConfiguration.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+void BulkIOConfiguration::initializeDefaultParameters(const BulkIOFormat format) {
+  switch (format) {
+    case BulkIOFormat::kCSV: {
+      delimiter_ = ',';
+      escape_strings_ = false;
+      header_ = true;
+      quote_ = '"';
+      null_string_ = "";
+      break;
+    }
+    case BulkIOFormat::kText: {
+      delimiter_ = '\t';
+      escape_strings_ = true;
+      header_ = false;
+      quote_ = 0;
+      null_string_ = "\\N";
+      break;
+    }
+    default:
+      LOG(FATAL) << "Unexpected format in "
+                 << "BulkIOConfiguration::initializeDefaultParameters()";
+  }
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/utility/BulkIOConfiguration.hpp
----------------------------------------------------------------------
diff --git a/utility/BulkIOConfiguration.hpp b/utility/BulkIOConfiguration.hpp
new file mode 100644
index 0000000..042932e
--- /dev/null
+++ b/utility/BulkIOConfiguration.hpp
@@ -0,0 +1,117 @@
+/**
+ * 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.
+ **/
+
+#ifndef QUICKSTEP_UTILITY_BULK_IO_CONFIGURATION_HPP_
+#define QUICKSTEP_UTILITY_BULK_IO_CONFIGURATION_HPP_
+
+#include <memory>
+#include <string>
+
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+/**
+ * @brief
+ */
+enum class BulkIOFormat {
+  kCSV,
+  kText
+};
+
+class BulkIOConfiguration;
+typedef std::shared_ptr<const BulkIOConfiguration> BulkIOConfigurationPtr;
+
+class BulkIOConfiguration {
+ public:
+  BulkIOConfiguration(const BulkIOFormat format)
+      : format_(format) {
+    initializeDefaultParameters(format);
+  }
+
+  inline BulkIOFormat getFormat() const {
+    return format_;
+  }
+
+  inline std::string getFormatName() const {
+    switch (format_) {
+      case BulkIOFormat::kCSV:
+        return "CSV";
+      case BulkIOFormat::kText:
+        return "TEXT";
+    }
+  }
+
+  inline char getDelimiter() const {
+    return delimiter_;
+  }
+
+  inline void setDelimiter(const char delimiter) {
+    delimiter_ = delimiter;
+  }
+
+  inline bool escapeStrings() const {
+    return escape_strings_;
+  }
+
+  inline void setEscapeStrings(const bool escape_strings) {
+    escape_strings_ = escape_strings;
+  }
+
+  inline bool hasHeader() const {
+    return header_;
+  }
+
+  inline void setHeader(const bool header) {
+    header_ = header;
+  }
+
+  inline char getQuoteCharacter() const {
+    return quote_;
+  }
+
+  inline void setQuoteCharacter(const char quote) {
+    quote_ = quote;
+  }
+
+  inline const std::string& getNullString() const {
+    return null_string_;
+  }
+
+  inline void setNullString(const std::string &null_string) {
+    null_string_ = null_string;
+  }
+
+ private:
+  void initializeDefaultParameters(const BulkIOFormat format);
+
+  const BulkIOFormat format_;
+
+  char delimiter_;
+  bool escape_strings_;
+  bool header_;
+  char quote_;
+  std::string null_string_;
+
+  DISALLOW_COPY_AND_ASSIGN(BulkIOConfiguration);
+};
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_BULK_IO_CONFIGURATION_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/utility/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/utility/CMakeLists.txt b/utility/CMakeLists.txt
index 16a83ee..59d843d 100644
--- a/utility/CMakeLists.txt
+++ b/utility/CMakeLists.txt
@@ -168,6 +168,7 @@ add_library(quickstep_utility_BloomFilter ../empty_src.cpp BloomFilter.hpp)
 add_library(quickstep_utility_BloomFilter_proto
             ${quickstep_utility_BloomFilter_proto_srcs}
             ${quickstep_utility_BloomFilter_proto_hdrs})
+add_library(quickstep_utility_BulkIOConfiguration BulkIOConfiguration.cpp BulkIOConfiguration.hpp)
 add_library(quickstep_utility_CalculateInstalledMemory CalculateInstalledMemory.cpp CalculateInstalledMemory.hpp)
 add_library(quickstep_utility_Cast ../empty_src.cpp Cast.hpp)
 add_library(quickstep_utility_CheckSnprintf ../empty_src.cpp CheckSnprintf.hpp)
@@ -249,6 +250,8 @@ target_link_libraries(quickstep_utility_CompositeHash
 target_link_libraries(quickstep_utility_BarrieredReadWriteConcurrentBitVector
                       quickstep_utility_BitManipulation
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_utility_BulkIOConfiguration
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_utility_DAG
                       glog
                       quickstep_utility_Macros)
@@ -347,6 +350,7 @@ target_link_libraries(quickstep_utility
                       quickstep_utility_BitVector
                       quickstep_utility_BloomFilter
                       quickstep_utility_BloomFilter_proto
+                      quickstep_utility_BulkIOConfiguration
                       quickstep_utility_CalculateInstalledMemory
                       quickstep_utility_Cast
                       quickstep_utility_CheckSnprintf



[10/12] incubator-quickstep git commit: Add "COPY TO" operator for exporting data from Quickstep.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/parser/preprocessed/SqlLexer_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlLexer_gen.hpp b/parser/preprocessed/SqlLexer_gen.hpp
index 86e36f0..5fafae5 100644
--- a/parser/preprocessed/SqlLexer_gen.hpp
+++ b/parser/preprocessed/SqlLexer_gen.hpp
@@ -13,88 +13,244 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 3
+#define YY_FLEX_SUBMINOR_VERSION 4
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
 
-    #define yy_create_buffer quickstep_yy_create_buffer
+#ifdef yy_create_buffer
+#define quickstep_yy_create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer quickstep_yy_create_buffer
+#endif
 
-    #define yy_delete_buffer quickstep_yy_delete_buffer
+#ifdef yy_delete_buffer
+#define quickstep_yy_delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer quickstep_yy_delete_buffer
+#endif
 
-    #define yy_scan_buffer quickstep_yy_scan_buffer
+#ifdef yy_scan_buffer
+#define quickstep_yy_scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer quickstep_yy_scan_buffer
+#endif
 
-    #define yy_scan_string quickstep_yy_scan_string
+#ifdef yy_scan_string
+#define quickstep_yy_scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string quickstep_yy_scan_string
+#endif
 
-    #define yy_scan_bytes quickstep_yy_scan_bytes
+#ifdef yy_scan_bytes
+#define quickstep_yy_scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes quickstep_yy_scan_bytes
+#endif
 
-    #define yy_init_buffer quickstep_yy_init_buffer
+#ifdef yy_init_buffer
+#define quickstep_yy_init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer quickstep_yy_init_buffer
+#endif
 
-    #define yy_flush_buffer quickstep_yy_flush_buffer
+#ifdef yy_flush_buffer
+#define quickstep_yy_flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer quickstep_yy_flush_buffer
+#endif
 
-    #define yy_load_buffer_state quickstep_yy_load_buffer_state
+#ifdef yy_load_buffer_state
+#define quickstep_yy_load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state quickstep_yy_load_buffer_state
+#endif
 
-    #define yy_switch_to_buffer quickstep_yy_switch_to_buffer
+#ifdef yy_switch_to_buffer
+#define quickstep_yy_switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer quickstep_yy_switch_to_buffer
+#endif
 
-    #define yypush_buffer_state quickstep_yypush_buffer_state
+#ifdef yypush_buffer_state
+#define quickstep_yypush_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state quickstep_yypush_buffer_state
+#endif
 
-    #define yypop_buffer_state quickstep_yypop_buffer_state
+#ifdef yypop_buffer_state
+#define quickstep_yypop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state quickstep_yypop_buffer_state
+#endif
 
-    #define yyensure_buffer_stack quickstep_yyensure_buffer_stack
+#ifdef yyensure_buffer_stack
+#define quickstep_yyensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack quickstep_yyensure_buffer_stack
+#endif
 
-    #define yylex quickstep_yylex
+#ifdef yylex
+#define quickstep_yylex_ALREADY_DEFINED
+#else
+#define yylex quickstep_yylex
+#endif
 
-    #define yyrestart quickstep_yyrestart
+#ifdef yyrestart
+#define quickstep_yyrestart_ALREADY_DEFINED
+#else
+#define yyrestart quickstep_yyrestart
+#endif
 
-    #define yylex_init quickstep_yylex_init
+#ifdef yylex_init
+#define quickstep_yylex_init_ALREADY_DEFINED
+#else
+#define yylex_init quickstep_yylex_init
+#endif
 
-    #define yylex_init_extra quickstep_yylex_init_extra
+#ifdef yylex_init_extra
+#define quickstep_yylex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra quickstep_yylex_init_extra
+#endif
 
-    #define yylex_destroy quickstep_yylex_destroy
+#ifdef yylex_destroy
+#define quickstep_yylex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy quickstep_yylex_destroy
+#endif
 
-    #define yyget_debug quickstep_yyget_debug
+#ifdef yyget_debug
+#define quickstep_yyget_debug_ALREADY_DEFINED
+#else
+#define yyget_debug quickstep_yyget_debug
+#endif
 
-    #define yyset_debug quickstep_yyset_debug
+#ifdef yyset_debug
+#define quickstep_yyset_debug_ALREADY_DEFINED
+#else
+#define yyset_debug quickstep_yyset_debug
+#endif
 
-    #define yyget_extra quickstep_yyget_extra
+#ifdef yyget_extra
+#define quickstep_yyget_extra_ALREADY_DEFINED
+#else
+#define yyget_extra quickstep_yyget_extra
+#endif
 
-    #define yyset_extra quickstep_yyset_extra
+#ifdef yyset_extra
+#define quickstep_yyset_extra_ALREADY_DEFINED
+#else
+#define yyset_extra quickstep_yyset_extra
+#endif
 
-    #define yyget_in quickstep_yyget_in
+#ifdef yyget_in
+#define quickstep_yyget_in_ALREADY_DEFINED
+#else
+#define yyget_in quickstep_yyget_in
+#endif
 
-    #define yyset_in quickstep_yyset_in
+#ifdef yyset_in
+#define quickstep_yyset_in_ALREADY_DEFINED
+#else
+#define yyset_in quickstep_yyset_in
+#endif
 
-    #define yyget_out quickstep_yyget_out
+#ifdef yyget_out
+#define quickstep_yyget_out_ALREADY_DEFINED
+#else
+#define yyget_out quickstep_yyget_out
+#endif
 
-    #define yyset_out quickstep_yyset_out
+#ifdef yyset_out
+#define quickstep_yyset_out_ALREADY_DEFINED
+#else
+#define yyset_out quickstep_yyset_out
+#endif
 
-    #define yyget_leng quickstep_yyget_leng
+#ifdef yyget_leng
+#define quickstep_yyget_leng_ALREADY_DEFINED
+#else
+#define yyget_leng quickstep_yyget_leng
+#endif
 
-    #define yyget_text quickstep_yyget_text
+#ifdef yyget_text
+#define quickstep_yyget_text_ALREADY_DEFINED
+#else
+#define yyget_text quickstep_yyget_text
+#endif
 
-    #define yyget_lineno quickstep_yyget_lineno
+#ifdef yyget_lineno
+#define quickstep_yyget_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno quickstep_yyget_lineno
+#endif
 
-    #define yyset_lineno quickstep_yyset_lineno
+#ifdef yyset_lineno
+#define quickstep_yyset_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno quickstep_yyset_lineno
+#endif
 
-        #define yyget_column quickstep_yyget_column
+#ifdef yyget_column
+#define quickstep_yyget_column_ALREADY_DEFINED
+#else
+#define yyget_column quickstep_yyget_column
+#endif
 
-        #define yyset_column quickstep_yyset_column
+#ifdef yyset_column
+#define quickstep_yyset_column_ALREADY_DEFINED
+#else
+#define yyset_column quickstep_yyset_column
+#endif
 
-    #define yywrap quickstep_yywrap
+#ifdef yywrap
+#define quickstep_yywrap_ALREADY_DEFINED
+#else
+#define yywrap quickstep_yywrap
+#endif
 
-    #define yyget_lval quickstep_yyget_lval
+#ifdef yyget_lval
+#define quickstep_yyget_lval_ALREADY_DEFINED
+#else
+#define yyget_lval quickstep_yyget_lval
+#endif
 
-    #define yyset_lval quickstep_yyset_lval
+#ifdef yyset_lval
+#define quickstep_yyset_lval_ALREADY_DEFINED
+#else
+#define yyset_lval quickstep_yyset_lval
+#endif
 
-    #define yyget_lloc quickstep_yyget_lloc
+#ifdef yyget_lloc
+#define quickstep_yyget_lloc_ALREADY_DEFINED
+#else
+#define yyget_lloc quickstep_yyget_lloc
+#endif
 
-    #define yyset_lloc quickstep_yyset_lloc
+#ifdef yyset_lloc
+#define quickstep_yyset_lloc_ALREADY_DEFINED
+#else
+#define yyset_lloc quickstep_yyset_lloc
+#endif
 
-    #define yyalloc quickstep_yyalloc
+#ifdef yyalloc
+#define quickstep_yyalloc_ALREADY_DEFINED
+#else
+#define yyalloc quickstep_yyalloc
+#endif
 
-    #define yyrealloc quickstep_yyrealloc
+#ifdef yyrealloc
+#define quickstep_yyrealloc_ALREADY_DEFINED
+#else
+#define yyrealloc quickstep_yyrealloc
+#endif
 
-    #define yyfree quickstep_yyfree
+#ifdef yyfree
+#define quickstep_yyfree_ALREADY_DEFINED
+#else
+#define yyfree quickstep_yyfree
+#endif
 
 /* First, we deal with  platform-specific or compiler-specific issues. */
 
@@ -166,10 +322,16 @@ typedef unsigned int flex_uint32_t;
 #define UINT32_MAX             (4294967295U)
 #endif
 
+#ifndef SIZE_MAX
+#define SIZE_MAX               (~(size_t)0)
+#endif
+
 #endif /* ! C99 */
 
 #endif /* ! FLEXINT_H */
 
+/* begin standard C++ headers. */
+
 /* TODO: this is always defined, so inline it */
 #define yyconst const
 
@@ -270,21 +432,21 @@ struct yy_buffer_state
 	};
 #endif /* !YY_STRUCT_YY_BUFFER_STATE */
 
-void quickstep_yyrestart ( FILE *input_file , yyscan_t yyscanner );
-void quickstep_yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
-YY_BUFFER_STATE quickstep_yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
-void quickstep_yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
-void quickstep_yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
-void quickstep_yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
-void quickstep_yypop_buffer_state ( yyscan_t yyscanner );
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
 
-YY_BUFFER_STATE quickstep_yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
-YY_BUFFER_STATE quickstep_yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
-YY_BUFFER_STATE quickstep_yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
 
-void *quickstep_yyalloc ( yy_size_t , yyscan_t yyscanner );
-void *quickstep_yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
-void quickstep_yyfree ( void * , yyscan_t yyscanner );
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
 
 /* Begin user sect3 */
 
@@ -315,50 +477,50 @@ void quickstep_yyfree ( void * , yyscan_t yyscanner );
 #define YY_EXTRA_TYPE void *
 #endif
 
-int quickstep_yylex_init (yyscan_t* scanner);
+int yylex_init (yyscan_t* scanner);
 
-int quickstep_yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
 
 /* Accessor methods to globals.
    These are made visible to non-reentrant scanners for convenience. */
 
-int quickstep_yylex_destroy ( yyscan_t yyscanner );
+int yylex_destroy ( yyscan_t yyscanner );
 
-int quickstep_yyget_debug ( yyscan_t yyscanner );
+int yyget_debug ( yyscan_t yyscanner );
 
-void quickstep_yyset_debug ( int debug_flag , yyscan_t yyscanner );
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
 
-YY_EXTRA_TYPE quickstep_yyget_extra ( yyscan_t yyscanner );
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
 
-void quickstep_yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
 
-FILE *quickstep_yyget_in ( yyscan_t yyscanner );
+FILE *yyget_in ( yyscan_t yyscanner );
 
-void quickstep_yyset_in  ( FILE * _in_str , yyscan_t yyscanner );
+void yyset_in  ( FILE * _in_str , yyscan_t yyscanner );
 
-FILE *quickstep_yyget_out ( yyscan_t yyscanner );
+FILE *yyget_out ( yyscan_t yyscanner );
 
-void quickstep_yyset_out  ( FILE * _out_str , yyscan_t yyscanner );
+void yyset_out  ( FILE * _out_str , yyscan_t yyscanner );
 
-			int quickstep_yyget_leng ( yyscan_t yyscanner );
+			int yyget_leng ( yyscan_t yyscanner );
 
-char *quickstep_yyget_text ( yyscan_t yyscanner );
+char *yyget_text ( yyscan_t yyscanner );
 
-int quickstep_yyget_lineno ( yyscan_t yyscanner );
+int yyget_lineno ( yyscan_t yyscanner );
 
-void quickstep_yyset_lineno ( int _line_number , yyscan_t yyscanner );
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
 
-int quickstep_yyget_column  ( yyscan_t yyscanner );
+int yyget_column  ( yyscan_t yyscanner );
 
-void quickstep_yyset_column ( int _column_no , yyscan_t yyscanner );
+void yyset_column ( int _column_no , yyscan_t yyscanner );
 
-YYSTYPE * quickstep_yyget_lval ( yyscan_t yyscanner );
+YYSTYPE * yyget_lval ( yyscan_t yyscanner );
 
-void quickstep_yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
+void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
 
-       YYLTYPE *quickstep_yyget_lloc ( yyscan_t yyscanner );
+       YYLTYPE *yyget_lloc ( yyscan_t yyscanner );
     
-        void quickstep_yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner );
+        void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner );
     
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -366,9 +528,9 @@ void quickstep_yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
-extern "C" int quickstep_yywrap ( yyscan_t yyscanner );
+extern "C" int yywrap ( yyscan_t yyscanner );
 #else
-extern int quickstep_yywrap ( yyscan_t yyscanner );
+extern int yywrap ( yyscan_t yyscanner );
 #endif
 #endif
 
@@ -405,10 +567,10 @@ static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
 #ifndef YY_DECL
 #define YY_DECL_IS_OURS 1
 
-extern int quickstep_yylex \
+extern int yylex \
                (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner);
 
-#define YY_DECL int quickstep_yylex \
+#define YY_DECL int yylex \
                (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
 #endif /* !YY_DECL */
 
@@ -426,9 +588,154 @@ extern int quickstep_yylex \
 #undef YY_DECL
 #endif
 
-#line 469 "../SqlLexer.lpp"
+#ifndef quickstep_yy_create_buffer_ALREADY_DEFINED
+#undef yy_create_buffer
+#endif
+#ifndef quickstep_yy_delete_buffer_ALREADY_DEFINED
+#undef yy_delete_buffer
+#endif
+#ifndef quickstep_yy_scan_buffer_ALREADY_DEFINED
+#undef yy_scan_buffer
+#endif
+#ifndef quickstep_yy_scan_string_ALREADY_DEFINED
+#undef yy_scan_string
+#endif
+#ifndef quickstep_yy_scan_bytes_ALREADY_DEFINED
+#undef yy_scan_bytes
+#endif
+#ifndef quickstep_yy_init_buffer_ALREADY_DEFINED
+#undef yy_init_buffer
+#endif
+#ifndef quickstep_yy_flush_buffer_ALREADY_DEFINED
+#undef yy_flush_buffer
+#endif
+#ifndef quickstep_yy_load_buffer_state_ALREADY_DEFINED
+#undef yy_load_buffer_state
+#endif
+#ifndef quickstep_yy_switch_to_buffer_ALREADY_DEFINED
+#undef yy_switch_to_buffer
+#endif
+#ifndef quickstep_yypush_buffer_state_ALREADY_DEFINED
+#undef yypush_buffer_state
+#endif
+#ifndef quickstep_yypop_buffer_state_ALREADY_DEFINED
+#undef yypop_buffer_state
+#endif
+#ifndef quickstep_yyensure_buffer_stack_ALREADY_DEFINED
+#undef yyensure_buffer_stack
+#endif
+#ifndef quickstep_yylex_ALREADY_DEFINED
+#undef yylex
+#endif
+#ifndef quickstep_yyrestart_ALREADY_DEFINED
+#undef yyrestart
+#endif
+#ifndef quickstep_yylex_init_ALREADY_DEFINED
+#undef yylex_init
+#endif
+#ifndef quickstep_yylex_init_extra_ALREADY_DEFINED
+#undef yylex_init_extra
+#endif
+#ifndef quickstep_yylex_destroy_ALREADY_DEFINED
+#undef yylex_destroy
+#endif
+#ifndef quickstep_yyget_debug_ALREADY_DEFINED
+#undef yyget_debug
+#endif
+#ifndef quickstep_yyset_debug_ALREADY_DEFINED
+#undef yyset_debug
+#endif
+#ifndef quickstep_yyget_extra_ALREADY_DEFINED
+#undef yyget_extra
+#endif
+#ifndef quickstep_yyset_extra_ALREADY_DEFINED
+#undef yyset_extra
+#endif
+#ifndef quickstep_yyget_in_ALREADY_DEFINED
+#undef yyget_in
+#endif
+#ifndef quickstep_yyset_in_ALREADY_DEFINED
+#undef yyset_in
+#endif
+#ifndef quickstep_yyget_out_ALREADY_DEFINED
+#undef yyget_out
+#endif
+#ifndef quickstep_yyset_out_ALREADY_DEFINED
+#undef yyset_out
+#endif
+#ifndef quickstep_yyget_leng_ALREADY_DEFINED
+#undef yyget_leng
+#endif
+#ifndef quickstep_yyget_text_ALREADY_DEFINED
+#undef yyget_text
+#endif
+#ifndef quickstep_yyget_lineno_ALREADY_DEFINED
+#undef yyget_lineno
+#endif
+#ifndef quickstep_yyset_lineno_ALREADY_DEFINED
+#undef yyset_lineno
+#endif
+#ifndef quickstep_yyget_column_ALREADY_DEFINED
+#undef yyget_column
+#endif
+#ifndef quickstep_yyset_column_ALREADY_DEFINED
+#undef yyset_column
+#endif
+#ifndef quickstep_yywrap_ALREADY_DEFINED
+#undef yywrap
+#endif
+#ifndef quickstep_yyget_lval_ALREADY_DEFINED
+#undef yyget_lval
+#endif
+#ifndef quickstep_yyset_lval_ALREADY_DEFINED
+#undef yyset_lval
+#endif
+#ifndef quickstep_yyget_lloc_ALREADY_DEFINED
+#undef yyget_lloc
+#endif
+#ifndef quickstep_yyset_lloc_ALREADY_DEFINED
+#undef yyset_lloc
+#endif
+#ifndef quickstep_yyalloc_ALREADY_DEFINED
+#undef yyalloc
+#endif
+#ifndef quickstep_yyrealloc_ALREADY_DEFINED
+#undef yyrealloc
+#endif
+#ifndef quickstep_yyfree_ALREADY_DEFINED
+#undef yyfree
+#endif
+#ifndef quickstep_yytext_ALREADY_DEFINED
+#undef yytext
+#endif
+#ifndef quickstep_yyleng_ALREADY_DEFINED
+#undef yyleng
+#endif
+#ifndef quickstep_yyin_ALREADY_DEFINED
+#undef yyin
+#endif
+#ifndef quickstep_yyout_ALREADY_DEFINED
+#undef yyout
+#endif
+#ifndef quickstep_yy_flex_debug_ALREADY_DEFINED
+#undef yy_flex_debug
+#endif
+#ifndef quickstep_yylineno_ALREADY_DEFINED
+#undef yylineno
+#endif
+#ifndef quickstep_yytables_fload_ALREADY_DEFINED
+#undef yytables_fload
+#endif
+#ifndef quickstep_yytables_destroy_ALREADY_DEFINED
+#undef yytables_destroy
+#endif
+#ifndef quickstep_yyTABLES_NAME_ALREADY_DEFINED
+#undef yyTABLES_NAME
+#endif
+
+#line 470 "../SqlLexer.lpp"
 
 
-#line 432 "SqlLexer_gen.hpp"
+#line 739 "SqlLexer_gen.hpp"
 #undef quickstep_yyIN_HEADER
 #endif /* quickstep_yyHEADER_H */


[08/12] incubator-quickstep git commit: Add "COPY TO" operator for exporting data from Quickstep.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/parser/preprocessed/SqlParser_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.hpp b/parser/preprocessed/SqlParser_gen.hpp
index a6d12e2..f6b5247 100644
--- a/parser/preprocessed/SqlParser_gen.hpp
+++ b/parser/preprocessed/SqlParser_gen.hpp
@@ -94,90 +94,91 @@ extern int quickstep_yydebug;
     TOKEN_DECIMAL = 304,
     TOKEN_DEFAULT = 305,
     TOKEN_DELETE = 306,
-    TOKEN_DELIMITER = 307,
-    TOKEN_DESC = 308,
-    TOKEN_DISTINCT = 309,
-    TOKEN_DOUBLE = 310,
-    TOKEN_DROP = 311,
-    TOKEN_ELSE = 312,
-    TOKEN_END = 313,
-    TOKEN_ESCAPE_STRINGS = 314,
-    TOKEN_EXISTS = 315,
-    TOKEN_EXTRACT = 316,
-    TOKEN_FALSE = 317,
-    TOKEN_FIRST = 318,
-    TOKEN_FLOAT = 319,
-    TOKEN_FOLLOWING = 320,
-    TOKEN_FOR = 321,
-    TOKEN_FOREIGN = 322,
-    TOKEN_FROM = 323,
-    TOKEN_FULL = 324,
-    TOKEN_GROUP = 325,
-    TOKEN_HASH = 326,
-    TOKEN_HAVING = 327,
-    TOKEN_HOUR = 328,
-    TOKEN_IN = 329,
-    TOKEN_INDEX = 330,
-    TOKEN_INNER = 331,
-    TOKEN_INSERT = 332,
-    TOKEN_INTEGER = 333,
-    TOKEN_INTERVAL = 334,
-    TOKEN_INTO = 335,
-    TOKEN_JOIN = 336,
-    TOKEN_KEY = 337,
-    TOKEN_LAST = 338,
-    TOKEN_LEFT = 339,
-    TOKEN_LIMIT = 340,
-    TOKEN_LONG = 341,
-    TOKEN_MINUTE = 342,
-    TOKEN_MONTH = 343,
-    TOKEN_NULL = 344,
-    TOKEN_NULLS = 345,
-    TOKEN_OFF = 346,
-    TOKEN_ON = 347,
-    TOKEN_ORDER = 348,
-    TOKEN_OUTER = 349,
-    TOKEN_OVER = 350,
-    TOKEN_PARTITION = 351,
-    TOKEN_PARTITIONS = 352,
-    TOKEN_PERCENT = 353,
-    TOKEN_PRECEDING = 354,
-    TOKEN_PRIMARY = 355,
-    TOKEN_PRIORITY = 356,
-    TOKEN_QUIT = 357,
-    TOKEN_RANGE = 358,
-    TOKEN_REAL = 359,
-    TOKEN_REFERENCES = 360,
-    TOKEN_RIGHT = 361,
-    TOKEN_ROW = 362,
-    TOKEN_ROW_DELIMITER = 363,
-    TOKEN_ROWS = 364,
-    TOKEN_SECOND = 365,
-    TOKEN_SELECT = 366,
-    TOKEN_SET = 367,
-    TOKEN_SMA = 368,
-    TOKEN_SMALLINT = 369,
+    TOKEN_DESC = 307,
+    TOKEN_DISTINCT = 308,
+    TOKEN_DOUBLE = 309,
+    TOKEN_DROP = 310,
+    TOKEN_ELSE = 311,
+    TOKEN_END = 312,
+    TOKEN_EXISTS = 313,
+    TOKEN_EXTRACT = 314,
+    TOKEN_FALSE = 315,
+    TOKEN_FIRST = 316,
+    TOKEN_FLOAT = 317,
+    TOKEN_FOLLOWING = 318,
+    TOKEN_FOR = 319,
+    TOKEN_FOREIGN = 320,
+    TOKEN_FROM = 321,
+    TOKEN_FULL = 322,
+    TOKEN_GROUP = 323,
+    TOKEN_HASH = 324,
+    TOKEN_HAVING = 325,
+    TOKEN_HOUR = 326,
+    TOKEN_IN = 327,
+    TOKEN_INDEX = 328,
+    TOKEN_INNER = 329,
+    TOKEN_INSERT = 330,
+    TOKEN_INTEGER = 331,
+    TOKEN_INTERVAL = 332,
+    TOKEN_INTO = 333,
+    TOKEN_JOIN = 334,
+    TOKEN_KEY = 335,
+    TOKEN_LAST = 336,
+    TOKEN_LEFT = 337,
+    TOKEN_LIMIT = 338,
+    TOKEN_LONG = 339,
+    TOKEN_MINUTE = 340,
+    TOKEN_MONTH = 341,
+    TOKEN_NULL = 342,
+    TOKEN_NULLS = 343,
+    TOKEN_OFF = 344,
+    TOKEN_ON = 345,
+    TOKEN_ORDER = 346,
+    TOKEN_OUTER = 347,
+    TOKEN_OVER = 348,
+    TOKEN_PARTITION = 349,
+    TOKEN_PARTITIONS = 350,
+    TOKEN_PERCENT = 351,
+    TOKEN_PRECEDING = 352,
+    TOKEN_PRIMARY = 353,
+    TOKEN_PRIORITY = 354,
+    TOKEN_QUIT = 355,
+    TOKEN_RANGE = 356,
+    TOKEN_REAL = 357,
+    TOKEN_REFERENCES = 358,
+    TOKEN_RIGHT = 359,
+    TOKEN_ROW = 360,
+    TOKEN_ROW_DELIMITER = 361,
+    TOKEN_ROWS = 362,
+    TOKEN_SECOND = 363,
+    TOKEN_SELECT = 364,
+    TOKEN_SET = 365,
+    TOKEN_SMA = 366,
+    TOKEN_SMALLINT = 367,
+    TOKEN_STDERR = 368,
+    TOKEN_STDOUT = 369,
     TOKEN_SUBSTRING = 370,
     TOKEN_TABLE = 371,
     TOKEN_THEN = 372,
     TOKEN_TIME = 373,
     TOKEN_TIMESTAMP = 374,
-    TOKEN_TRUE = 375,
-    TOKEN_TUPLESAMPLE = 376,
-    TOKEN_UNBOUNDED = 377,
-    TOKEN_UNIQUE = 378,
-    TOKEN_UPDATE = 379,
-    TOKEN_USING = 380,
-    TOKEN_VALUES = 381,
-    TOKEN_VARCHAR = 382,
-    TOKEN_WHEN = 383,
-    TOKEN_WHERE = 384,
-    TOKEN_WINDOW = 385,
-    TOKEN_WITH = 386,
-    TOKEN_YEAR = 387,
-    TOKEN_YEARMONTH = 388,
-    TOKEN_EOF = 389,
-    TOKEN_LEX_ERROR = 390
+    TOKEN_TO = 375,
+    TOKEN_TRUE = 376,
+    TOKEN_TUPLESAMPLE = 377,
+    TOKEN_UNBOUNDED = 378,
+    TOKEN_UNIQUE = 379,
+    TOKEN_UPDATE = 380,
+    TOKEN_USING = 381,
+    TOKEN_VALUES = 382,
+    TOKEN_VARCHAR = 383,
+    TOKEN_WHEN = 384,
+    TOKEN_WHERE = 385,
+    TOKEN_WINDOW = 386,
+    TOKEN_WITH = 387,
+    TOKEN_YEAR = 388,
+    TOKEN_YEARMONTH = 389,
+    TOKEN_EOF = 390,
+    TOKEN_LEX_ERROR = 391
   };
 #endif
 
@@ -237,8 +238,7 @@ union YYSTYPE
   quickstep::ParseKeyStringValue *key_string_value_;
   quickstep::ParseKeyStringList *key_string_list_;
   quickstep::ParseKeyIntegerValue *key_integer_value_;
-
-  quickstep::ParseCopyFromParams *copy_from_params_;
+  quickstep::ParseKeyBoolValue *key_bool_value_;
 
   quickstep::ParseAssignment *assignment_;
   quickstep::PtrList<quickstep::ParseAssignment> *assignment_list_;
@@ -251,7 +251,7 @@ union YYSTYPE
   quickstep::ParseStatementUpdate *update_statement_;
   quickstep::ParseStatementInsert *insert_statement_;
   quickstep::ParseStatementDelete *delete_statement_;
-  quickstep::ParseStatementCopyFrom *copy_from_statement_;
+  quickstep::ParseStatementCopy *copy_statement_;
   quickstep::ParseStatementCreateTable *create_table_statement_;
   quickstep::ParsePartitionClause *partition_clause_;
   quickstep::ParseBlockProperties *block_properties_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/parser/tests/Copy.test
----------------------------------------------------------------------
diff --git a/parser/tests/Copy.test b/parser/tests/Copy.test
index dccaa82..7d1677d 100644
--- a/parser/tests/Copy.test
+++ b/parser/tests/Copy.test
@@ -24,34 +24,131 @@ COPY test FROM 'test.txt' WITH ()
 
 COPY test FROM 'test.txt'
 --
-CopyFromStatement[relation_name=test,source_file=test.txt]
+CopyStatement[direction=FROM,file=test.txt,relation_name=test]
 ==
 
 COPY test FROM 'test.txt' WITH (DELIMITER 'd', ESCAPE_STRINGS FALSE)
 --
-CopyFromStatement[relation_name=test,source_file=test.txt]
-+-params=CopyFromParams[delimiter=d,escape_string=false]
+CopyStatement[direction=FROM,file=test.txt,relation_name=test]
++-params=
+  +-KeyStringValue[key=DELIMITER]
+  | +-value=String[value=d]
+  +-KeyBoolValue[key=ESCAPE_STRINGS,value=false]
 ==
 
 COPY test FROM 'test.txt' WITH (DELIMITER '123', ESCAPE_STRINGS FALSE)
 --
-CopyFromStatement[relation_name=test,source_file=test.txt]
-+-params=CopyFromParams[delimiter=123,escape_string=false]
+CopyStatement[direction=FROM,file=test.txt,relation_name=test]
++-params=
+  +-KeyStringValue[key=DELIMITER]
+  | +-value=String[value=123]
+  +-KeyBoolValue[key=ESCAPE_STRINGS,value=false]
 ==
 
 COPY test FROM 'test.txt' WITH (DELIMITER e'\t')
 --
-CopyFromStatement[relation_name=test,source_file=test.txt]
-+-params=CopyFromParams[delimiter=	,escape_string=true]
+CopyStatement[direction=FROM,file=test.txt,relation_name=test]
++-params=
+  +-KeyStringValue[key=DELIMITER]
+    +-value=String[value=	]
 ==
 
 COPY test FROM 'test.txt' WITH (ESCAPE_STRINGS FALSE, DELIMITER 'd')
 --
-CopyFromStatement[relation_name=test,source_file=test.txt]
-+-params=CopyFromParams[delimiter=d,escape_string=false]
+CopyStatement[direction=FROM,file=test.txt,relation_name=test]
++-params=
+  +-KeyBoolValue[key=ESCAPE_STRINGS,value=false]
+  +-KeyStringValue[key=DELIMITER]
+    +-value=String[value=d]
 ==
 
 COPY test FROM 'test.txt' WITH (DELIMITER '1', ESCAPE_STRINGS FALSE, DELIMITER '2', ESCAPE_STRINGS TRUE)
 --
-CopyFromStatement[relation_name=test,source_file=test.txt]
-+-params=CopyFromParams[delimiter=2,escape_string=true]
+CopyStatement[direction=FROM,file=test.txt,relation_name=test]
++-params=
+  +-KeyStringValue[key=DELIMITER]
+  | +-value=String[value=1]
+  +-KeyBoolValue[key=ESCAPE_STRINGS,value=false]
+  +-KeyStringValue[key=DELIMITER]
+  | +-value=String[value=2]
+  +-KeyBoolValue[key=ESCAPE_STRINGS,value=true]
+==
+
+COPY test TO 'test.txt';
+--
+CopyStatement[direction=TO,file=@test.txt,relation_name=test]
+==
+
+COPY test TO stdout;
+--
+CopyStatement[direction=TO,file=$stdout,relation_name=test]
+==
+
+COPY test TO stderr;
+--
+CopyStatement[direction=TO,file=$stderr,relation_name=test]
+==
+
+COPY test TO 'stdout';
+--
+CopyStatement[direction=TO,file=@stdout,relation_name=test]
+==
+
+COPY test TO 'test.txt' WITH (FORMAT 'TEXT');
+--
+CopyStatement[direction=TO,file=@test.txt,relation_name=test]
++-params=
+  +-KeyStringValue[key=FORMAT]
+    +-value=String[value=TEXT]
+==
+
+COPY test TO 'test.txt' WITH (FORMAT 'CSV');
+--
+CopyStatement[direction=TO,file=@test.txt,relation_name=test]
++-params=
+  +-KeyStringValue[key=FORMAT]
+    +-value=String[value=CSV]
+==
+
+COPY test TO stdout
+WITH (FORMAT 'CSV', DELIMITER e'\t', HEADER TRUE, QUOTE '$', NULL_STRING 'NULL');
+--
+CopyStatement[direction=TO,file=$stdout,relation_name=test]
++-params=
+  +-KeyStringValue[key=FORMAT]
+  | +-value=String[value=CSV]
+  +-KeyStringValue[key=DELIMITER]
+  | +-value=String[value=	]
+  +-KeyBoolValue[key=HEADER,value=true]
+  +-KeyStringValue[key=QUOTE]
+  | +-value=String[value=$]
+  +-KeyStringValue[key=NULL_STRING]
+    +-value=String[value=NULL]
+==
+
+COPY
+  SELECT SUM(int_col) AS sum_int,
+         AVG(double_col) AS avg_dbl
+  FROM test
+  GROUP BY char_col
+TO 'test.txt' WITH (DELIMITER ',');
+--
+CopyStatement[direction=TO,file=@test.txt]
++-set_operation_query=SetOperation[set_operation_type=Select]
+| +-children=
+|   +-Select
+|     +-select_clause=SelectList
+|     | +-SelectListItem[alias=sum_int]
+|     | | +-FunctionCall[name=SUM]
+|     | |   +-AttributeReference[attribute_name=int_col]
+|     | +-SelectListItem[alias=avg_dbl]
+|     |   +-FunctionCall[name=AVG]
+|     |     +-AttributeReference[attribute_name=double_col]
+|     +-group_by=GroupBy
+|     | +-AttributeReference[attribute_name=char_col]
+|     +-from_clause=
+|       +-TableReference[table=test]
++-params=
+  +-KeyStringValue[key=DELIMITER]
+    +-value=String[value=,]
+==

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_execution/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_execution/CMakeLists.txt b/query_execution/CMakeLists.txt
index 5c750f0..e7ebbae 100644
--- a/query_execution/CMakeLists.txt
+++ b/query_execution/CMakeLists.txt
@@ -216,6 +216,7 @@ target_link_libraries(quickstep_queryexecution_QueryContext
                       quickstep_storage_HashTableFactory
                       quickstep_storage_InsertDestination
                       quickstep_storage_InsertDestination_proto
+                      quickstep_storage_StorageBlockInfo
                       quickstep_storage_WindowAggregationOperationState
                       quickstep_threading_SpinSharedMutex
                       quickstep_types_TypedValue

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/CMakeLists.txt b/query_optimizer/CMakeLists.txt
index fdf8796..4ea21b2 100644
--- a/query_optimizer/CMakeLists.txt
+++ b/query_optimizer/CMakeLists.txt
@@ -94,6 +94,7 @@ target_link_libraries(quickstep_queryoptimizer_ExecutionGenerator
                       quickstep_queryoptimizer_expressions_WindowAggregateFunction
                       quickstep_queryoptimizer_physical_Aggregate
                       quickstep_queryoptimizer_physical_CopyFrom
+                      quickstep_queryoptimizer_physical_CopyTo
                       quickstep_queryoptimizer_physical_CreateIndex
                       quickstep_queryoptimizer_physical_CreateTable
                       quickstep_queryoptimizer_physical_CrossReferenceCoalesceAggregate
@@ -140,6 +141,7 @@ target_link_libraries(quickstep_queryoptimizer_ExecutionGenerator
                       quickstep_relationaloperators_SelectOperator
                       quickstep_relationaloperators_SortMergeRunOperator
                       quickstep_relationaloperators_SortRunGenerationOperator
+                      quickstep_relationaloperators_TableExportOperator
                       quickstep_relationaloperators_TableGeneratorOperator
                       quickstep_relationaloperators_TextScanOperator
                       quickstep_relationaloperators_UnionAllOperator

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/ExecutionGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/ExecutionGenerator.cpp b/query_optimizer/ExecutionGenerator.cpp
index d82a0c7..372d576 100644
--- a/query_optimizer/ExecutionGenerator.cpp
+++ b/query_optimizer/ExecutionGenerator.cpp
@@ -78,6 +78,7 @@
 #include "query_optimizer/expressions/WindowAggregateFunction.hpp"
 #include "query_optimizer/physical/Aggregate.hpp"
 #include "query_optimizer/physical/CopyFrom.hpp"
+#include "query_optimizer/physical/CopyTo.hpp"
 #include "query_optimizer/physical/CreateIndex.hpp"
 #include "query_optimizer/physical/CreateTable.hpp"
 #include "query_optimizer/physical/CrossReferenceCoalesceAggregate.hpp"
@@ -124,6 +125,7 @@
 #include "relational_operators/SelectOperator.hpp"
 #include "relational_operators/SortMergeRunOperator.hpp"
 #include "relational_operators/SortRunGenerationOperator.hpp"
+#include "relational_operators/TableExportOperator.hpp"
 #include "relational_operators/TableGeneratorOperator.hpp"
 #include "relational_operators/TextScanOperator.hpp"
 #include "relational_operators/UnionAllOperator.hpp"
@@ -409,6 +411,9 @@ void ExecutionGenerator::generatePlanInternal(
     case P::PhysicalType::kCopyFrom:
       return convertCopyFrom(
           std::static_pointer_cast<const P::CopyFrom>(physical_plan));
+    case P::PhysicalType::kCopyTo:
+      return convertCopyTo(
+          std::static_pointer_cast<const P::CopyTo>(physical_plan));
     case P::PhysicalType::kCreateIndex:
       return convertCreateIndex(
           std::static_pointer_cast<const P::CreateIndex>(physical_plan));
@@ -1223,8 +1228,7 @@ void ExecutionGenerator::convertCopyFrom(
           new TextScanOperator(
               query_handle_->query_id(),
               physical_plan->file_name(),
-              physical_plan->column_delimiter(),
-              physical_plan->escape_strings(),
+              physical_plan->options(),
               *output_relation,
               insert_destination_index));
   insert_destination_proto->set_relational_op_index(scan_operator_index);
@@ -1239,6 +1243,40 @@ void ExecutionGenerator::convertCopyFrom(
                                        false /* is_pipeline_breaker */);
 }
 
+void ExecutionGenerator::convertCopyTo(const P::CopyToPtr &physical_plan) {
+  // CopyTo is converted to a TableExport operator.
+
+  const CatalogRelation *input_relation;
+  bool input_relation_is_stored;
+
+  const P::PhysicalPtr &input = physical_plan->input();
+  P::TableReferencePtr table_reference;
+  const CatalogRelationInfo *input_relation_info = nullptr;
+  if (P::SomeTableReference::MatchesWithConditionalCast(input, &table_reference)) {
+    input_relation = table_reference->relation();
+    input_relation_is_stored = true;
+  } else {
+    input_relation_info = findRelationInfoOutputByPhysical(input);
+    input_relation = input_relation_info->relation;
+    input_relation_is_stored = false;
+  }
+
+  DCHECK(input_relation != nullptr);
+  const QueryPlan::DAGNodeIndex table_export_operator_index =
+      execution_plan_->addRelationalOperator(
+          new TableExportOperator(query_handle_->query_id(),
+                                  *input_relation,
+                                  input_relation_is_stored,
+                                  physical_plan->file_name(),
+                                  physical_plan->options()));
+  if (!input_relation_is_stored) {
+    DCHECK(input_relation_info != nullptr);
+    execution_plan_->addDirectDependency(table_export_operator_index,
+                                         input_relation_info->producer_operator_index,
+                                         false /* is_pipeline_breaker */);
+  }
+}
+
 void ExecutionGenerator::convertCreateIndex(
   const P::CreateIndexPtr &physical_plan) {
   // CreateIndex is converted to a CreateIndex operator.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/ExecutionGenerator.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/ExecutionGenerator.hpp b/query_optimizer/ExecutionGenerator.hpp
index 19e75c1..bc9f88b 100644
--- a/query_optimizer/ExecutionGenerator.hpp
+++ b/query_optimizer/ExecutionGenerator.hpp
@@ -44,6 +44,7 @@
 #include "query_optimizer/expressions/Predicate.hpp"
 #include "query_optimizer/physical/Aggregate.hpp"
 #include "query_optimizer/physical/CopyFrom.hpp"
+#include "query_optimizer/physical/CopyTo.hpp"
 #include "query_optimizer/physical/CreateIndex.hpp"
 #include "query_optimizer/physical/CreateTable.hpp"
 #include "query_optimizer/physical/CrossReferenceCoalesceAggregate.hpp"
@@ -282,6 +283,13 @@ class ExecutionGenerator {
   void convertCopyFrom(const physical::CopyFromPtr &physical_plan);
 
   /**
+   * @brief Converts a CopyTo to a TableExport operator.
+   *
+   * @param physical_plan The CopyTo to be converted.
+   */
+  void convertCopyTo(const physical::CopyToPtr &physical_plan);
+
+  /**
    * @brief Converts a CreateIndex to a CreateIndex operator.
    *
    * @param physical_plan The CreateIndex to be converted.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/logical/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/logical/CMakeLists.txt b/query_optimizer/logical/CMakeLists.txt
index 4480e0b..b3c9e36 100644
--- a/query_optimizer/logical/CMakeLists.txt
+++ b/query_optimizer/logical/CMakeLists.txt
@@ -19,6 +19,7 @@
 add_library(quickstep_queryoptimizer_logical_Aggregate Aggregate.cpp Aggregate.hpp)
 add_library(quickstep_queryoptimizer_logical_BinaryJoin BinaryJoin.cpp BinaryJoin.hpp)
 add_library(quickstep_queryoptimizer_logical_CopyFrom CopyFrom.cpp CopyFrom.hpp)
+add_library(quickstep_queryoptimizer_logical_CopyTo CopyTo.cpp CopyTo.hpp)
 add_library(quickstep_queryoptimizer_logical_CreateIndex CreateIndex.cpp CreateIndex.hpp)
 add_library(quickstep_queryoptimizer_logical_CreateTable CreateTable.cpp CreateTable.hpp)
 add_library(quickstep_queryoptimizer_logical_DeleteTuples DeleteTuples.cpp DeleteTuples.hpp)
@@ -74,6 +75,16 @@ target_link_libraries(quickstep_queryoptimizer_logical_CopyFrom
                       quickstep_queryoptimizer_expressions_AttributeReference
                       quickstep_queryoptimizer_logical_Logical
                       quickstep_queryoptimizer_logical_LogicalType
+                      quickstep_utility_BulkIOConfiguration
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
+target_link_libraries(quickstep_queryoptimizer_logical_CopyTo
+                      glog
+                      quickstep_queryoptimizer_OptimizerTree
+                      quickstep_queryoptimizer_expressions_AttributeReference
+                      quickstep_queryoptimizer_logical_Logical
+                      quickstep_queryoptimizer_logical_LogicalType
+                      quickstep_utility_BulkIOConfiguration
                       quickstep_utility_Macros
                       quickstep_utility_StringUtil)
 target_link_libraries(quickstep_queryoptimizer_logical_CreateIndex
@@ -290,6 +301,7 @@ target_link_libraries(quickstep_queryoptimizer_logical
                       quickstep_queryoptimizer_logical_Aggregate
                       quickstep_queryoptimizer_logical_BinaryJoin
                       quickstep_queryoptimizer_logical_CopyFrom
+                      quickstep_queryoptimizer_logical_CopyTo
                       quickstep_queryoptimizer_logical_CreateIndex
                       quickstep_queryoptimizer_logical_CreateTable
                       quickstep_queryoptimizer_logical_DeleteTuples

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/logical/CopyFrom.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/logical/CopyFrom.cpp b/query_optimizer/logical/CopyFrom.cpp
index b0a1423..a80c701 100644
--- a/query_optimizer/logical/CopyFrom.cpp
+++ b/query_optimizer/logical/CopyFrom.cpp
@@ -44,11 +44,11 @@ void CopyFrom::getFieldStringItems(
   inline_field_values->push_back(file_name_);
 
   inline_field_names->push_back("column_delimiter");
-  inline_field_values->push_back("\"" + EscapeSpecialChars(std::string(1, column_delimiter_)) +
-                                 "\"");
+  inline_field_values->push_back(
+      "\"" + EscapeSpecialChars(std::string(1, options_->getDelimiter())) + "\"");
 
   inline_field_names->push_back("escape_strings");
-  inline_field_values->push_back(escape_strings_ ? "true" : "false");
+  inline_field_values->push_back(options_->escapeStrings() ? "true" : "false");
 }
 
 }  // namespace logical

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/logical/CopyFrom.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/logical/CopyFrom.hpp b/query_optimizer/logical/CopyFrom.hpp
index 7c5907f..e0545dc 100644
--- a/query_optimizer/logical/CopyFrom.hpp
+++ b/query_optimizer/logical/CopyFrom.hpp
@@ -17,8 +17,8 @@
  * under the License.
  **/
 
-#ifndef QUICKSTEP_QUERY_OPTIMIZER_LOGICAL_COPYFROM_HPP_
-#define QUICKSTEP_QUERY_OPTIMIZER_LOGICAL_COPYFROM_HPP_
+#ifndef QUICKSTEP_QUERY_OPTIMIZER_LOGICAL_COPY_FROM_HPP_
+#define QUICKSTEP_QUERY_OPTIMIZER_LOGICAL_COPY_FROM_HPP_
 
 #include <memory>
 #include <string>
@@ -28,6 +28,7 @@
 #include "query_optimizer/expressions/AttributeReference.hpp"
 #include "query_optimizer/logical/Logical.hpp"
 #include "query_optimizer/logical/LogicalType.hpp"
+#include "utility/BulkIOConfiguration.hpp"
 #include "utility/Macros.hpp"
 
 #include "glog/logging.h"
@@ -66,20 +67,14 @@ class CopyFrom : public Logical {
   const std::string& file_name() const { return file_name_; }
 
   /**
-   * @return The delimiter used in the text file to separate columns.
+   * @return The options for this COPY FROM statement.
    */
-  const char column_delimiter() const { return column_delimiter_; }
-
-  /**
-   * @return Whether to decode escape sequences in the text file.
-   */
-  bool escape_strings() const { return escape_strings_; }
+  BulkIOConfigurationPtr options() const { return options_; }
 
   LogicalPtr copyWithNewChildren(
       const std::vector<LogicalPtr> &new_children) const override {
     DCHECK(new_children.empty());
-    return Create(catalog_relation_, file_name_, column_delimiter_,
-                  escape_strings_);
+    return Create(catalog_relation_, file_name_, options_);
   }
 
   std::vector<expressions::AttributeReferencePtr> getOutputAttributes() const override {
@@ -95,19 +90,13 @@ class CopyFrom : public Logical {
    *
    * @param catalog_relation The catalog relation to insert the tuples to.
    * @param file_name The name of the file to read the data from.
-   * @param column_delimiter The delimiter used in the text file to separate
-   *                         columns.
-   * @param escape_strings Whether to decode escape sequences in the text file.
+   * @param options The options for this COPY FROM statement.
    * @return An immutable CopyFrom logical node.
    */
   static CopyFromPtr Create(const CatalogRelation *catalog_relation,
                             const std::string &file_name,
-                            const char column_delimiter,
-                            bool escape_strings) {
-    return CopyFromPtr(new CopyFrom(catalog_relation,
-                                    file_name,
-                                    column_delimiter,
-                                    escape_strings));
+                            const BulkIOConfigurationPtr &options) {
+    return CopyFromPtr(new CopyFrom(catalog_relation, file_name, options));
   }
 
  protected:
@@ -122,18 +111,14 @@ class CopyFrom : public Logical {
  private:
   CopyFrom(const CatalogRelation *catalog_relation,
            const std::string &file_name,
-           const char column_delimiter,
-           bool escape_strings)
+           const BulkIOConfigurationPtr &options)
       : catalog_relation_(catalog_relation),
         file_name_(file_name),
-        column_delimiter_(column_delimiter),
-        escape_strings_(escape_strings) {}
+        options_(options) {}
 
   const CatalogRelation *catalog_relation_;
-  std::string file_name_;
-
-  const char column_delimiter_;
-  const bool escape_strings_;
+  const std::string file_name_;
+  const BulkIOConfigurationPtr options_;
 
   DISALLOW_COPY_AND_ASSIGN(CopyFrom);
 };
@@ -144,4 +129,4 @@ class CopyFrom : public Logical {
 }  // namespace optimizer
 }  // namespace quickstep
 
-#endif /* QUICKSTEP_QUERY_OPTIMIZER_LOGICAL_COPYFROM_HPP_ */
+#endif  // QUICKSTEP_QUERY_OPTIMIZER_LOGICAL_COPY_FROM_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/logical/CopyTo.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/logical/CopyTo.cpp b/query_optimizer/logical/CopyTo.cpp
new file mode 100644
index 0000000..369f732
--- /dev/null
+++ b/query_optimizer/logical/CopyTo.cpp
@@ -0,0 +1,75 @@
+/**
+ * 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.
+ **/
+
+#include "query_optimizer/logical/CopyTo.hpp"
+
+#include <string>
+#include <vector>
+
+#include "query_optimizer/OptimizerTree.hpp"
+#include "utility/StringUtil.hpp"
+
+namespace quickstep {
+namespace optimizer {
+namespace logical {
+
+void CopyTo::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
+  inline_field_names->push_back("file_name");
+  inline_field_values->push_back(file_name_);
+
+  non_container_child_field_names->push_back("input");
+  non_container_child_fields->push_back(input_);
+
+  inline_field_names->push_back("format");
+  inline_field_values->push_back(options_->getFormatName());
+
+  inline_field_names->push_back("column_delimiter");
+  inline_field_values->push_back(
+      "\"" + EscapeSpecialChars(std::string(1, options_->getDelimiter())) + "\"");
+
+  if (options_->escapeStrings()) {
+    inline_field_names->push_back("escape_strings");
+    inline_field_values->push_back("true");
+  }
+
+  if (options_->hasHeader()) {
+    inline_field_names->push_back("header");
+    inline_field_values->push_back("true");
+  }
+
+  if (options_->getQuoteCharacter() != 0) {
+    inline_field_names->push_back("quote");
+    inline_field_values->push_back(std::string(1, options_->getQuoteCharacter()));
+  }
+
+  if (options_->getNullString() != "") {
+    inline_field_names->push_back("null_string");
+    inline_field_values->push_back(options_->getNullString());
+  }
+}
+
+}  // namespace logical
+}  // namespace optimizer
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/logical/CopyTo.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/logical/CopyTo.hpp b/query_optimizer/logical/CopyTo.hpp
new file mode 100644
index 0000000..eafef0e
--- /dev/null
+++ b/query_optimizer/logical/CopyTo.hpp
@@ -0,0 +1,141 @@
+/**
+ * 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.
+ **/
+
+#ifndef QUICKSTEP_QUERY_OPTIMIZER_LOGICAL_COPY_TO_HPP_
+#define QUICKSTEP_QUERY_OPTIMIZER_LOGICAL_COPY_TO_HPP_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "query_optimizer/OptimizerTree.hpp"
+#include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/logical/Logical.hpp"
+#include "query_optimizer/logical/LogicalType.hpp"
+#include "utility/BulkIOConfiguration.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+namespace optimizer {
+namespace logical {
+
+/** \addtogroup OptimizerLogical
+ *  @{
+ */
+
+class CopyTo;
+typedef std::shared_ptr<const CopyTo> CopyToPtr;
+
+/**
+ * @brief Represents an operation that copies data from a relation to a text file.
+ */
+class CopyTo : public Logical {
+ public:
+  LogicalType getLogicalType() const override {
+    return LogicalType::kCopyTo;
+  }
+
+  std::string getName() const override {
+    return "CopyTo";
+  }
+
+  /**
+   * @return The input relation whose data is to be exported.
+   */
+  const LogicalPtr& input() const {
+    return input_;
+  }
+
+  /**
+   * @return The name of the file to write the data to.
+   */
+  const std::string& file_name() const {
+    return file_name_;
+  }
+
+  /**
+   * @return The options for this COPY TO statement.
+   */
+  BulkIOConfigurationPtr options() const {
+    return options_;
+  }
+
+  LogicalPtr copyWithNewChildren(
+      const std::vector<LogicalPtr> &new_children) const override {
+    DCHECK(new_children.size() == 1);
+    return Create(new_children.front(), file_name_, options_);
+  }
+
+  std::vector<expressions::AttributeReferencePtr> getOutputAttributes() const override {
+    return {};
+  }
+
+  std::vector<expressions::AttributeReferencePtr> getReferencedAttributes() const override {
+    return input_->getOutputAttributes();
+  }
+
+  /**
+   * @brief Creates a CopyTo logical node.
+   *
+   * @param input The input relation whose data is to be exported.
+   * @param file_name The name of the file to write the data to.
+   * @param options The options for this COPY TO statement.
+   * @return An immutable CopyTo logical node.
+   */
+  static CopyToPtr Create(const LogicalPtr &input,
+                          const std::string &file_name,
+                          const BulkIOConfigurationPtr &options) {
+    return CopyToPtr(new CopyTo(input, file_name, options));
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
+
+ private:
+  CopyTo(const LogicalPtr &input,
+         const std::string &file_name,
+         const BulkIOConfigurationPtr &options)
+      : input_(input),
+        file_name_(file_name),
+        options_(options) {
+    addChild(input);
+  }
+
+  const LogicalPtr input_;
+  const std::string file_name_;
+  const BulkIOConfigurationPtr options_;
+
+  DISALLOW_COPY_AND_ASSIGN(CopyTo);
+};
+
+/** @} */
+
+}  // namespace logical
+}  // namespace optimizer
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_QUERY_OPTIMIZER_LOGICAL_COPY_TO_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/logical/LogicalType.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/logical/LogicalType.hpp b/query_optimizer/logical/LogicalType.hpp
index 21ffdca..a629637 100644
--- a/query_optimizer/logical/LogicalType.hpp
+++ b/query_optimizer/logical/LogicalType.hpp
@@ -34,6 +34,7 @@ namespace logical {
 enum class LogicalType {
   kAggregate,
   kCopyFrom,
+  kCopyTo,
   kCreateIndex,
   kCreateTable,
   kDeleteTuples,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/physical/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/CMakeLists.txt b/query_optimizer/physical/CMakeLists.txt
index e510f6b..1c8dc3d 100644
--- a/query_optimizer/physical/CMakeLists.txt
+++ b/query_optimizer/physical/CMakeLists.txt
@@ -19,6 +19,7 @@
 add_library(quickstep_queryoptimizer_physical_Aggregate Aggregate.cpp Aggregate.hpp)
 add_library(quickstep_queryoptimizer_physical_BinaryJoin BinaryJoin.cpp BinaryJoin.hpp)
 add_library(quickstep_queryoptimizer_physical_CopyFrom CopyFrom.cpp CopyFrom.hpp)
+add_library(quickstep_queryoptimizer_physical_CopyTo CopyTo.cpp CopyTo.hpp)
 add_library(quickstep_queryoptimizer_physical_CreateIndex CreateIndex.cpp CreateIndex.hpp)
 add_library(quickstep_queryoptimizer_physical_CreateTable CreateTable.cpp CreateTable.hpp)
 add_library(quickstep_queryoptimizer_physical_CrossReferenceCoalesceAggregate
@@ -81,7 +82,18 @@ target_link_libraries(quickstep_queryoptimizer_physical_CopyFrom
                       quickstep_queryoptimizer_expressions_NamedExpression
                       quickstep_queryoptimizer_physical_Physical
                       quickstep_queryoptimizer_physical_PhysicalType
-                      quickstep_utility_Macros)
+                      quickstep_utility_BulkIOConfiguration
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
+target_link_libraries(quickstep_queryoptimizer_physical_CopyTo
+                      glog
+                      quickstep_queryoptimizer_OptimizerTree
+                      quickstep_queryoptimizer_expressions_AttributeReference
+                      quickstep_queryoptimizer_physical_Physical
+                      quickstep_queryoptimizer_physical_PhysicalType
+                      quickstep_utility_BulkIOConfiguration
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
 target_link_libraries(quickstep_queryoptimizer_physical_CreateIndex
                       glog
                       quickstep_queryoptimizer_OptimizerTree
@@ -327,6 +339,7 @@ target_link_libraries(quickstep_queryoptimizer_physical
                       quickstep_queryoptimizer_physical_Aggregate
                       quickstep_queryoptimizer_physical_BinaryJoin
                       quickstep_queryoptimizer_physical_CopyFrom
+                      quickstep_queryoptimizer_physical_CopyTo
                       quickstep_queryoptimizer_physical_CreateIndex
                       quickstep_queryoptimizer_physical_CreateTable
                       quickstep_queryoptimizer_physical_CrossReferenceCoalesceAggregate

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/physical/CopyFrom.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/CopyFrom.cpp b/query_optimizer/physical/CopyFrom.cpp
index 8448d4e..65279fe 100644
--- a/query_optimizer/physical/CopyFrom.cpp
+++ b/query_optimizer/physical/CopyFrom.cpp
@@ -24,6 +24,7 @@
 
 #include "catalog/CatalogRelation.hpp"
 #include "query_optimizer/OptimizerTree.hpp"
+#include "utility/StringUtil.hpp"
 
 namespace quickstep {
 namespace optimizer {
@@ -43,10 +44,11 @@ void CopyFrom::getFieldStringItems(
   inline_field_values->push_back(file_name_);
 
   inline_field_names->push_back("column_delimiter");
-  inline_field_values->push_back(std::string(1, column_delimiter_));
+  inline_field_values->push_back(
+      "\"" + EscapeSpecialChars(std::string(1, options_->getDelimiter())) + "\"");
 
   inline_field_names->push_back("escape_strings");
-  inline_field_values->push_back(escape_strings_ ? "true" : "false");
+  inline_field_values->push_back(options_->escapeStrings() ? "true" : "false");
 }
 
 }  // namespace physical

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/physical/CopyFrom.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/CopyFrom.hpp b/query_optimizer/physical/CopyFrom.hpp
index ecbf318..b100eaa 100644
--- a/query_optimizer/physical/CopyFrom.hpp
+++ b/query_optimizer/physical/CopyFrom.hpp
@@ -30,6 +30,7 @@
 #include "query_optimizer/expressions/NamedExpression.hpp"
 #include "query_optimizer/physical/Physical.hpp"
 #include "query_optimizer/physical/PhysicalType.hpp"
+#include "utility/BulkIOConfiguration.hpp"
 #include "utility/Macros.hpp"
 
 #include "glog/logging.h"
@@ -68,22 +69,14 @@ class CopyFrom : public Physical {
   const std::string& file_name() const { return file_name_; }
 
   /**
-   * @return The delimiter used in the text file to separate columns.
+   * @return The options for this COPY FROM statement.
    */
-  const char column_delimiter() const { return column_delimiter_; }
-
-  /**
-   * @return Whether to decode escape sequences in the text file.
-   */
-  bool escape_strings() const { return escape_strings_; }
+  BulkIOConfigurationPtr options() const { return options_; }
 
   PhysicalPtr copyWithNewChildren(
       const std::vector<PhysicalPtr> &new_children) const override {
     DCHECK(new_children.empty());
-    return Create(catalog_relation_,
-                  file_name_,
-                  column_delimiter_,
-                  escape_strings_);
+    return Create(catalog_relation_, file_name_, options_);
   }
 
   std::vector<expressions::AttributeReferencePtr> getOutputAttributes() const override {
@@ -112,12 +105,8 @@ class CopyFrom : public Physical {
    */
   static CopyFromPtr Create(const CatalogRelation *catalog_relation,
                             const std::string &file_name,
-                            const char &column_delimiter,
-                            bool escape_strings) {
-    return CopyFromPtr(new CopyFrom(catalog_relation,
-                                    file_name,
-                                    column_delimiter,
-                                    escape_strings));
+                            const BulkIOConfigurationPtr &options) {
+    return CopyFromPtr(new CopyFrom(catalog_relation, file_name, options));
   }
 
  protected:
@@ -132,18 +121,14 @@ class CopyFrom : public Physical {
  private:
   CopyFrom(const CatalogRelation *catalog_relation,
            const std::string &file_name,
-           const char column_delimiter,
-           bool escape_strings)
+           const BulkIOConfigurationPtr &options)
       : catalog_relation_(catalog_relation),
         file_name_(file_name),
-        column_delimiter_(column_delimiter),
-        escape_strings_(escape_strings) {}
+        options_(options) {}
 
   const CatalogRelation *catalog_relation_;
-  std::string file_name_;
-
-  const char column_delimiter_;
-  const bool escape_strings_;
+  const std::string file_name_;
+  const BulkIOConfigurationPtr options_;
 
   DISALLOW_COPY_AND_ASSIGN(CopyFrom);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/physical/CopyTo.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/CopyTo.cpp b/query_optimizer/physical/CopyTo.cpp
new file mode 100644
index 0000000..9cd954e
--- /dev/null
+++ b/query_optimizer/physical/CopyTo.cpp
@@ -0,0 +1,75 @@
+/**
+ * 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.
+ **/
+
+#include "query_optimizer/physical/CopyTo.hpp"
+
+#include <string>
+#include <vector>
+
+#include "query_optimizer/OptimizerTree.hpp"
+#include "utility/StringUtil.hpp"
+
+namespace quickstep {
+namespace optimizer {
+namespace physical {
+
+void CopyTo::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
+  inline_field_names->push_back("file_name");
+  inline_field_values->push_back(file_name_);
+
+  non_container_child_field_names->push_back("input");
+  non_container_child_fields->push_back(input_);
+
+  inline_field_names->push_back("format");
+  inline_field_values->push_back(options_->getFormatName());
+
+  inline_field_names->push_back("column_delimiter");
+  inline_field_values->push_back(
+      "\"" + EscapeSpecialChars(std::string(1, options_->getDelimiter())) + "\"");
+
+  if (options_->escapeStrings()) {
+    inline_field_names->push_back("escape_strings");
+    inline_field_values->push_back("true");
+  }
+
+  if (options_->hasHeader()) {
+    inline_field_names->push_back("header");
+    inline_field_values->push_back("true");
+  }
+
+  if (options_->getQuoteCharacter() != 0) {
+    inline_field_names->push_back("quote");
+    inline_field_values->push_back(std::string(1, options_->getQuoteCharacter()));
+  }
+
+  if (options_->getNullString() != "") {
+    inline_field_names->push_back("null_string");
+    inline_field_values->push_back(options_->getNullString());
+  }
+}
+
+}  // namespace physical
+}  // namespace optimizer
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/physical/CopyTo.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/CopyTo.hpp b/query_optimizer/physical/CopyTo.hpp
new file mode 100644
index 0000000..69d5c7a
--- /dev/null
+++ b/query_optimizer/physical/CopyTo.hpp
@@ -0,0 +1,148 @@
+/**
+ * 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.
+ **/
+
+#ifndef QUICKSTEP_QUERY_OPTIMIZER_PHYSICAL_COPY_TO_HPP_
+#define QUICKSTEP_QUERY_OPTIMIZER_PHYSICAL_COPY_TO_HPP_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "query_optimizer/OptimizerTree.hpp"
+#include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/physical/Physical.hpp"
+#include "query_optimizer/physical/PhysicalType.hpp"
+#include "utility/BulkIOConfiguration.hpp"
+#include "utility/BulkIOConfiguration.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+namespace optimizer {
+namespace physical {
+
+/** \addtogroup OptimizerPhysical
+ *  @{
+ */
+
+class CopyTo;
+typedef std::shared_ptr<const CopyTo> CopyToPtr;
+
+/**
+ * @brief Represents an operation that copies data from a relation to a text file.
+ */
+class CopyTo : public Physical {
+ public:
+  PhysicalType getPhysicalType() const override {
+    return PhysicalType::kCopyTo;
+  }
+
+  std::string getName() const override {
+    return "CopyTo";
+  }
+
+  /**
+   * @return The input relation whose data is to be exported.
+   */
+  const PhysicalPtr& input() const {
+    return input_;
+  }
+
+  /**
+   * @return The name of the file to write the data to.
+   */
+  const std::string& file_name() const {
+    return file_name_;
+  }
+
+  /**
+   * @return The options for this COPY TO statement.
+   */
+  BulkIOConfigurationPtr options() const {
+    return options_;
+  }
+
+  PhysicalPtr copyWithNewChildren(
+      const std::vector<PhysicalPtr> &new_children) const override {
+    DCHECK(new_children.size() == 1);
+    return Create(new_children.front(), file_name_, options_);
+  }
+
+  std::vector<expressions::AttributeReferencePtr> getOutputAttributes() const override {
+    return {};
+  }
+
+  std::vector<expressions::AttributeReferencePtr> getReferencedAttributes() const override {
+    return input_->getOutputAttributes();
+  }
+
+  bool maybeCopyWithPrunedExpressions(
+      const expressions::UnorderedNamedExpressionSet &referenced_expressions,
+      PhysicalPtr *output) const override {
+    return false;
+  }
+
+  /**
+   * @brief Creates a CopyTo physical node.
+   *
+   * @param input The input relation whose data is to be exported.
+   * @param file_name The name of the file to write the data to.
+   * @param options The options for this COPY TO statement.
+   * @return An immutable CopyTo physical node.
+   */
+  static CopyToPtr Create(const PhysicalPtr &input,
+                          const std::string &file_name,
+                          const BulkIOConfigurationPtr &options) {
+    return CopyToPtr(new CopyTo(input, file_name, options));
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
+
+ private:
+  CopyTo(const PhysicalPtr &input,
+         const std::string &file_name,
+         const BulkIOConfigurationPtr &options)
+      : input_(input),
+        file_name_(file_name),
+        options_(options) {
+    addChild(input);
+  }
+
+  const PhysicalPtr input_;
+  const std::string file_name_;
+  const BulkIOConfigurationPtr options_;
+
+  DISALLOW_COPY_AND_ASSIGN(CopyTo);
+};
+
+/** @} */
+
+}  // namespace physical
+}  // namespace optimizer
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_QUERY_OPTIMIZER_PHYSICAL_COPY_TO_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/physical/PhysicalType.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/PhysicalType.hpp b/query_optimizer/physical/PhysicalType.hpp
index 47db7ec..ac4376e 100644
--- a/query_optimizer/physical/PhysicalType.hpp
+++ b/query_optimizer/physical/PhysicalType.hpp
@@ -34,6 +34,7 @@ namespace physical {
 enum class PhysicalType {
   kAggregate,
   kCopyFrom,
+  kCopyTo,
   kCreateIndex,
   kCreateTable,
   kCrossReferenceCoalesceAggregate,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/resolver/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/CMakeLists.txt b/query_optimizer/resolver/CMakeLists.txt
index 4e364a6..18a03c7 100644
--- a/query_optimizer/resolver/CMakeLists.txt
+++ b/query_optimizer/resolver/CMakeLists.txt
@@ -97,6 +97,7 @@ target_link_libraries(quickstep_queryoptimizer_resolver_Resolver
                       quickstep_queryoptimizer_expressions_WindowAggregateFunction
                       quickstep_queryoptimizer_logical_Aggregate
                       quickstep_queryoptimizer_logical_CopyFrom
+                      quickstep_queryoptimizer_logical_CopyTo
                       quickstep_queryoptimizer_logical_CreateIndex
                       quickstep_queryoptimizer_logical_CreateTable
                       quickstep_queryoptimizer_logical_DeleteTuples
@@ -131,6 +132,7 @@ target_link_libraries(quickstep_queryoptimizer_resolver_Resolver
                       quickstep_types_operations_unaryoperations_DateExtractOperation
                       quickstep_types_operations_unaryoperations_SubstringOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
+                      quickstep_utility_BulkIOConfiguration
                       quickstep_utility_Macros
                       quickstep_utility_PtrList
                       quickstep_utility_PtrVector

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 0f65255..3215707 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -93,6 +93,7 @@
 #include "query_optimizer/expressions/WindowAggregateFunction.hpp"
 #include "query_optimizer/logical/Aggregate.hpp"
 #include "query_optimizer/logical/CopyFrom.hpp"
+#include "query_optimizer/logical/CopyTo.hpp"
 #include "query_optimizer/logical/CreateIndex.hpp"
 #include "query_optimizer/logical/CreateTable.hpp"
 #include "query_optimizer/logical/DeleteTuples.hpp"
@@ -126,6 +127,7 @@
 #include "types/operations/unary_operations/DateExtractOperation.hpp"
 #include "types/operations/unary_operations/SubstringOperation.hpp"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "utility/BulkIOConfiguration.hpp"
 #include "utility/PtrList.hpp"
 #include "utility/PtrVector.hpp"
 #include "utility/SqlError.hpp"
@@ -143,6 +145,45 @@ namespace E = ::quickstep::optimizer::expressions;
 namespace L = ::quickstep::optimizer::logical;
 namespace S = ::quickstep::serialization;
 
+namespace {
+
+static attribute_id GetAttributeIdFromName(
+    const PtrList<ParseAttributeDefinition> &attribute_definition_list,
+    const std::string &attribute_name) {
+  const std::string lower_attribute_name = ToLower(attribute_name);
+
+  attribute_id attr_id = 0;
+  for (const ParseAttributeDefinition &attribute_definition : attribute_definition_list) {
+    if (lower_attribute_name == ToLower(attribute_definition.name()->value())) {
+      return attr_id;
+    }
+
+    ++attr_id;
+  }
+
+  return kInvalidAttributeID;
+}
+
+static const ParseString* GetKeyValueString(const ParseKeyValue &key_value) {
+  if (key_value.getKeyValueType() != ParseKeyValue::kStringString) {
+      THROW_SQL_ERROR_AT(&key_value)
+          << "Invalid value type for " << key_value.key()->value()
+          << ", expected a string.";
+  }
+  return static_cast<const ParseKeyStringValue&>(key_value).value();
+}
+
+static bool GetKeyValueBool(const ParseKeyValue &key_value) {
+  if (key_value.getKeyValueType() != ParseKeyValue::kStringBool) {
+      THROW_SQL_ERROR_AT(&key_value)
+          << "Invalid value for " << key_value.key()->value()
+          << ", expected true or false.";
+  }
+  return static_cast<const ParseKeyBoolValue&>(key_value).value();
+}
+
+}  // namespace
+
 struct Resolver::ExpressionResolutionInfo {
   /**
    * @brief Constructs an ExpressionResolutionInfo that disallows aggregate
@@ -316,11 +357,25 @@ struct Resolver::SelectListInfo {
 
 L::LogicalPtr Resolver::resolve(const ParseStatement &parse_query) {
   switch (parse_query.getStatementType()) {
-    case ParseStatement::kCopyFrom:
-      context_->set_is_catalog_changed();
-      logical_plan_ = resolveCopyFrom(
-          static_cast<const ParseStatementCopyFrom&>(parse_query));
+    case ParseStatement::kCopy: {
+      const ParseStatementCopy &copy_statemnt =
+          static_cast<const ParseStatementCopy&>(parse_query);
+      if (copy_statemnt.getCopyDirection() == ParseStatementCopy::kFrom) {
+        context_->set_is_catalog_changed();
+        logical_plan_ = resolveCopyFrom(copy_statemnt);
+      } else {
+        DCHECK(copy_statemnt.getCopyDirection() == ParseStatementCopy::kTo);
+        if (copy_statemnt.with_clause() != nullptr) {
+          resolveWithClause(*copy_statemnt.with_clause());
+        }
+        logical_plan_ = resolveCopyTo(copy_statemnt);
+
+        if (copy_statemnt.with_clause() != nullptr) {
+          reportIfWithClauseUnused(*copy_statemnt.with_clause());
+        }
+      }
       break;
+    }
     case ParseStatement::kCreateTable:
       context_->set_is_catalog_changed();
       logical_plan_ = resolveCreateTable(
@@ -359,16 +414,7 @@ L::LogicalPtr Resolver::resolve(const ParseStatement &parse_query) {
         logical_plan_ = resolveInsertSelection(insert_selection_statement);
 
         if (insert_selection_statement.with_clause() != nullptr) {
-          // Report an error if there is a WITH query that is not actually used.
-          if (!with_queries_info_.unreferenced_query_indexes.empty()) {
-            int unreferenced_with_query_index = *with_queries_info_.unreferenced_query_indexes.begin();
-            const ParseSubqueryTableReference &unreferenced_with_query =
-                (*insert_selection_statement.with_clause())[unreferenced_with_query_index];
-            THROW_SQL_ERROR_AT(&unreferenced_with_query)
-                << "WITH query "
-                << unreferenced_with_query.table_reference_signature()->table_alias()->value()
-                << " is defined but not used";
-          }
+          reportIfWithClauseUnused(*insert_selection_statement.with_clause());
         }
       }
       break;
@@ -385,16 +431,7 @@ L::LogicalPtr Resolver::resolve(const ParseStatement &parse_query) {
                               nullptr /* type_hints */,
                               nullptr /* parent_resolver */);
       if (set_operation_statement.with_clause() != nullptr) {
-        // Report an error if there is a WITH query that is not actually used.
-        if (!with_queries_info_.unreferenced_query_indexes.empty()) {
-          int unreferenced_with_query_index = *with_queries_info_.unreferenced_query_indexes.begin();
-          const ParseSubqueryTableReference &unreferenced_with_query =
-              (*set_operation_statement.with_clause())[unreferenced_with_query_index];
-          THROW_SQL_ERROR_AT(&unreferenced_with_query)
-              << "WITH query "
-              << unreferenced_with_query.table_reference_signature()->table_alias()->value()
-              << " is defined but not used";
-        }
+        reportIfWithClauseUnused(*set_operation_statement.with_clause());
       }
       break;
     }
@@ -418,27 +455,157 @@ L::LogicalPtr Resolver::resolve(const ParseStatement &parse_query) {
 }
 
 L::LogicalPtr Resolver::resolveCopyFrom(
-    const ParseStatementCopyFrom &copy_from_statement) {
-  // Default parameters.
-  std::string column_delimiter_ = "\t";
-  bool escape_strings_ = true;
+    const ParseStatementCopy &copy_from_statement) {
+  DCHECK(copy_from_statement.getCopyDirection() == ParseStatementCopy::kFrom);
+  const PtrList<ParseKeyValue> *params = copy_from_statement.params();
 
-  const ParseCopyFromParams *params = copy_from_statement.params();
+  BulkIOFormat file_format = BulkIOFormat::kText;
   if (params != nullptr) {
-    if (params->delimiter != nullptr) {
-      column_delimiter_ = params->delimiter->value();
-      if (column_delimiter_.size() != 1) {
-        THROW_SQL_ERROR_AT(params->delimiter)
-            << "DELIMITER is not a single character";
+    for (const ParseKeyValue &param : *params) {
+      const std::string &key = ToLower(param.key()->value());
+      if (key == "format") {
+        const ParseString *parse_format = GetKeyValueString(param);
+        const std::string format = ToLower(parse_format->value());
+        // TODO(jianqiao): Support other bulk load formats such as CSV.
+        if (format != "text") {
+          THROW_SQL_ERROR_AT(parse_format) << "Unsupported file format: " << format;
+        }
+        // Update file_format when other formats get supported.
+        break;
+      }
+    }
+  }
+
+  std::unique_ptr<BulkIOConfiguration> options =
+      std::make_unique<BulkIOConfiguration>(file_format);
+  if (params != nullptr) {
+    for (const ParseKeyValue &param : *params) {
+      const std::string &key = ToLower(param.key()->value());
+      if (key == "delimiter") {
+        const ParseString *parse_delimiter = GetKeyValueString(param);
+        const std::string &delimiter = parse_delimiter->value();
+        if (delimiter.size() != 1) {
+          THROW_SQL_ERROR_AT(parse_delimiter)
+              << "DELIMITER is not a single character";
+        }
+        options->setDelimiter(delimiter.front());
+      } else if (key == "escape_strings") {
+        options->setEscapeStrings(GetKeyValueBool(param));
+      } else if (key != "format") {
+        THROW_SQL_ERROR_AT(&param) << "Unsupported copy option: " << key;
       }
     }
-    escape_strings_ = params->escape_strings;
   }
 
   return L::CopyFrom::Create(resolveRelationName(copy_from_statement.relation_name()),
-                             copy_from_statement.source_filename()->value(),
-                             column_delimiter_[0],
-                             escape_strings_);
+                             copy_from_statement.file_name()->value(),
+                             BulkIOConfigurationPtr(options.release()));
+}
+
+L::LogicalPtr Resolver::resolveCopyTo(
+    const ParseStatementCopy &copy_to_statement) {
+  DCHECK(copy_to_statement.getCopyDirection() == ParseStatementCopy::kTo);
+  const PtrList<ParseKeyValue> *params = copy_to_statement.params();
+
+  // Check if copy format is explicitly specified.
+  BulkIOFormat file_format = BulkIOFormat::kText;
+  bool format_specified = false;
+  if (params != nullptr) {
+    for (const ParseKeyValue &param : *params) {
+      const std::string &key = ToLower(param.key()->value());
+      if (key == "format") {
+        const ParseString *parse_format = GetKeyValueString(param);
+        const std::string format = ToLower(parse_format->value());
+        if (format == "csv") {
+          file_format = BulkIOFormat::kCSV;
+        } else if (format == "text") {
+          file_format = BulkIOFormat::kText;
+        } else {
+          THROW_SQL_ERROR_AT(parse_format) << "Unsupported file format: " << format;
+        }
+        format_specified = true;
+        break;
+      }
+    }
+  }
+
+  const std::string &file_name = copy_to_statement.file_name()->value();
+  if (file_name.length() <= 1) {
+    THROW_SQL_ERROR_AT(copy_to_statement.file_name())
+        << "File name can not be empty";
+  }
+
+  // Infer copy format from file name extension.
+  if (!format_specified) {
+    if (file_name.length() > 4) {
+      if (ToLower(file_name.substr(file_name.length() - 4)) == ".csv") {
+        file_format = BulkIOFormat::kCSV;
+      }
+    }
+  }
+
+  // Resolve the copy options.
+  std::unique_ptr<BulkIOConfiguration> options =
+      std::make_unique<BulkIOConfiguration>(file_format);
+  if (params != nullptr) {
+    for (const ParseKeyValue &param : *params) {
+      const std::string &key = ToLower(param.key()->value());
+      if (key == "delimiter") {
+        const ParseString *parse_delimiter = GetKeyValueString(param);
+        const std::string &delimiter = parse_delimiter->value();
+        if (delimiter.size() != 1) {
+          THROW_SQL_ERROR_AT(parse_delimiter)
+              << "DELIMITER is not a single character";
+        }
+        options->setDelimiter(delimiter.front());
+      } else if (file_format == BulkIOFormat::kText && key == "escape_strings") {
+        options->setEscapeStrings(GetKeyValueBool(param));
+      } else if (file_format == BulkIOFormat::kCSV && key == "header") {
+        options->setHeader(GetKeyValueBool(param));
+      } else if (file_format == BulkIOFormat::kCSV && key == "quote") {
+        const ParseString *parse_quote = GetKeyValueString(param);
+        const std::string &quote = parse_quote->value();
+        if (quote.size() != 1) {
+          THROW_SQL_ERROR_AT(parse_quote)
+              << "QUOTE is not a single character";
+        }
+        options->setQuoteCharacter(quote.front());
+      } else if (key == "null_string") {
+        const ParseString *parse_null_string = GetKeyValueString(param);
+        options->setNullString(parse_null_string->value());
+      } else if (key != "format") {
+        THROW_SQL_ERROR_AT(&param)
+            << "Unsupported copy option \"" << key
+            << "\" for file format " << options->getFormatName();
+      }
+    }
+  }
+
+  // Resolve the source relation.
+  L::LogicalPtr input;
+  if (copy_to_statement.set_operation_query() != nullptr) {
+    input = resolveSetOperation(*copy_to_statement.set_operation_query(),
+                                "" /* set_operation_name */,
+                                nullptr /* type_hints */,
+                                nullptr /* parent_resolver */);
+  } else {
+    const ParseString *relation_name = copy_to_statement.relation_name();
+    DCHECK(relation_name != nullptr);
+    std::unique_ptr<ParseTableReference> table_reference =
+        std::make_unique<ParseSimpleTableReference>(
+            relation_name->line_number(),
+            relation_name->column_number(),
+            new ParseString(relation_name->line_number(),
+                            relation_name->column_number(),
+                            relation_name->value()),
+            nullptr /* sample */);
+    NameResolver name_resolver;
+    input = resolveTableReference(*table_reference, &name_resolver);
+  }
+
+  return L::CopyTo::Create(input,
+                           copy_to_statement.file_name()->value(),
+                           BulkIOConfigurationPtr(options.release()));
 }
 
 L::LogicalPtr Resolver::resolveCreateTable(
@@ -491,26 +658,6 @@ L::LogicalPtr Resolver::resolveCreateTable(
   return L::CreateTable::Create(relation_name, attributes, block_properties, partition_scheme_header_proto);
 }
 
-namespace {
-
-attribute_id GetAttributeIdFromName(const PtrList<ParseAttributeDefinition> &attribute_definition_list,
-                                    const std::string &attribute_name) {
-  const std::string lower_attribute_name = ToLower(attribute_name);
-
-  attribute_id attr_id = 0;
-  for (const ParseAttributeDefinition &attribute_definition : attribute_definition_list) {
-    if (lower_attribute_name == ToLower(attribute_definition.name()->value())) {
-      return attr_id;
-    }
-
-    ++attr_id;
-  }
-
-  return kInvalidAttributeID;
-}
-
-}  // namespace
-
 StorageBlockLayoutDescription* Resolver::resolveBlockProperties(
     const ParseStatementCreateTable &create_table_statement) {
   const ParseBlockProperties *block_properties
@@ -1595,6 +1742,19 @@ void Resolver::appendProjectIfNeedPrecomputationAfterAggregation(
   }
 }
 
+void Resolver::reportIfWithClauseUnused(
+    const PtrVector<ParseSubqueryTableReference> &with_list) const {
+  if (!with_queries_info_.unreferenced_query_indexes.empty()) {
+    int unreferenced_with_query_index = *with_queries_info_.unreferenced_query_indexes.begin();
+    const ParseSubqueryTableReference &unreferenced_with_query =
+        with_list[unreferenced_with_query_index];
+    THROW_SQL_ERROR_AT(&unreferenced_with_query)
+        << "WITH query "
+        << unreferenced_with_query.table_reference_signature()->table_alias()->value()
+        << " is defined but not used";
+  }
+}
+
 void Resolver::validateSelectExpressionsForAggregation(
     const ParseSelectionClause &parse_selection,
     const std::vector<E::NamedExpressionPtr> &select_list_expressions,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/resolver/Resolver.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.hpp b/query_optimizer/resolver/Resolver.hpp
index 1ae565a..a7c1a80 100644
--- a/query_optimizer/resolver/Resolver.hpp
+++ b/query_optimizer/resolver/Resolver.hpp
@@ -55,7 +55,7 @@ class ParseSimpleCaseExpression;
 class ParseSimpleTableReference;
 class ParseSubqueryTableReference;
 class ParseStatement;
-class ParseStatementCopyFrom;
+class ParseStatementCopy;
 class ParseStatementCreateTable;
 class ParseStatementCreateIndex;
 class ParseStatementDelete;
@@ -283,7 +283,16 @@ class Resolver {
    * @return A logical plan for the COPY FROM query.
    */
   logical::LogicalPtr resolveCopyFrom(
-      const ParseStatementCopyFrom &copy_from_statement);
+      const ParseStatementCopy &copy_from_statement);
+
+  /**
+   * @brief Resolves a COPY TO query and returns a logical plan.
+   *
+   * @param copy_to_statement The COPY TO parse tree.
+   * @return A logical plan for the COPY TO query.
+   */
+  logical::LogicalPtr resolveCopyTo(
+      const ParseStatementCopy &copy_to_statement);
 
   /**
    * @brief Resolves a UPDATE query and returns a logical plan.
@@ -621,6 +630,14 @@ class Resolver {
   static std::string GenerateOrderingAttributeAlias(int index);
 
   /**
+   * @brief Report an error if there is a WITH query that is not actually used.
+   *
+   * @param with_list The list of subqueries in WITH clause.
+   */
+  void reportIfWithClauseUnused(
+      const PtrVector<ParseSubqueryTableReference> &with_list) const;
+
+  /**
    * @brief Validates each SELECT-list expression to ensure that it does not
    *        reference a named expression with an ID not in \p valid_expr_id_set.
    *

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/strategy/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/strategy/CMakeLists.txt b/query_optimizer/strategy/CMakeLists.txt
index e011126..20a4eb4 100644
--- a/query_optimizer/strategy/CMakeLists.txt
+++ b/query_optimizer/strategy/CMakeLists.txt
@@ -76,6 +76,7 @@ target_link_libraries(quickstep_queryoptimizer_strategy_OneToOne
                       quickstep_queryoptimizer_expressions_AttributeReference
                       quickstep_queryoptimizer_expressions_ExpressionUtil
                       quickstep_queryoptimizer_logical_CopyFrom
+                      quickstep_queryoptimizer_logical_CopyTo
                       quickstep_queryoptimizer_logical_CreateIndex
                       quickstep_queryoptimizer_logical_CreateTable
                       quickstep_queryoptimizer_logical_DeleteTuples
@@ -95,6 +96,7 @@ target_link_libraries(quickstep_queryoptimizer_strategy_OneToOne
                       quickstep_queryoptimizer_logical_WindowAggregate
                       quickstep_queryoptimizer_physical_Aggregate
                       quickstep_queryoptimizer_physical_CopyFrom
+                      quickstep_queryoptimizer_physical_CopyTo
                       quickstep_queryoptimizer_physical_CreateIndex
                       quickstep_queryoptimizer_physical_CreateTable
                       quickstep_queryoptimizer_physical_DeleteTuples

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/strategy/OneToOne.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/strategy/OneToOne.cpp b/query_optimizer/strategy/OneToOne.cpp
index af4e150..3cfe013 100644
--- a/query_optimizer/strategy/OneToOne.cpp
+++ b/query_optimizer/strategy/OneToOne.cpp
@@ -27,6 +27,7 @@
 #include "query_optimizer/expressions/AttributeReference.hpp"
 #include "query_optimizer/expressions/ExpressionUtil.hpp"
 #include "query_optimizer/logical/CopyFrom.hpp"
+#include "query_optimizer/logical/CopyTo.hpp"
 #include "query_optimizer/logical/CreateIndex.hpp"
 #include "query_optimizer/logical/CreateTable.hpp"
 #include "query_optimizer/logical/DeleteTuples.hpp"
@@ -45,6 +46,7 @@
 #include "query_optimizer/logical/WindowAggregate.hpp"
 #include "query_optimizer/physical/Aggregate.hpp"
 #include "query_optimizer/physical/CopyFrom.hpp"
+#include "query_optimizer/physical/CopyTo.hpp"
 #include "query_optimizer/physical/CreateIndex.hpp"
 #include "query_optimizer/physical/CreateTable.hpp"
 #include "query_optimizer/physical/DeleteTuples.hpp"
@@ -104,19 +106,28 @@ bool OneToOne::generatePlan(const L::LogicalPtr &logical_input,
     case L::LogicalType::kCopyFrom: {
       const L::CopyFromPtr copy_from =
           std::static_pointer_cast<const L::CopyFrom>(logical_input);
-      *physical_output = P::CopyFrom::Create(
-          copy_from->catalog_relation(), copy_from->file_name(),
-          copy_from->column_delimiter(), copy_from->escape_strings());
+      *physical_output = P::CopyFrom::Create(copy_from->catalog_relation(),
+                                             copy_from->file_name(),
+                                             copy_from->options());
+      return true;
+    }
+    case L::LogicalType::kCopyTo: {
+      const L::CopyToPtr copy_to =
+          std::static_pointer_cast<const L::CopyTo>(logical_input);
+      *physical_output = P::CopyTo::Create(
+          physical_mapper_->createOrGetPhysicalFromLogical(copy_to->input()),
+          copy_to->file_name(),
+          copy_to->options());
       return true;
     }
     case L::LogicalType::kCreateIndex: {
       const L::CreateIndexPtr create_index =
           std::static_pointer_cast<const L::CreateIndex>(logical_input);
-      *physical_output = P::CreateIndex::Create(physical_mapper_->createOrGetPhysicalFromLogical(
-                                                                    create_index->input()),
-                                                create_index->index_name(),
-                                                create_index->index_attributes(),
-                                                create_index->index_description());
+      *physical_output = P::CreateIndex::Create(
+          physical_mapper_->createOrGetPhysicalFromLogical(create_index->input()),
+          create_index->index_name(),
+          create_index->index_attributes(),
+          create_index->index_description());
       return true;
     }
     case L::LogicalType::kCreateTable: {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/tests/ExecutionGeneratorTestRunner.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/ExecutionGeneratorTestRunner.cpp b/query_optimizer/tests/ExecutionGeneratorTestRunner.cpp
index ee9bee7..050ef0d 100644
--- a/query_optimizer/tests/ExecutionGeneratorTestRunner.cpp
+++ b/query_optimizer/tests/ExecutionGeneratorTestRunner.cpp
@@ -62,6 +62,9 @@ void ExecutionGeneratorTestRunner::runTestCase(
   MemStream output_stream;
   sql_parser_.feedNextBuffer(new std::string(input));
 
+  // Redirect stderr to output_stream.
+  stderr = output_stream.file();
+
   while (true) {
     ParseResult result = sql_parser_.getNextStatement();
     if (result.condition != ParseResult::kSuccess) {
@@ -71,8 +74,6 @@ void ExecutionGeneratorTestRunner::runTestCase(
       break;
     } else {
       const ParseStatement &parse_statement = *result.parsed_statement;
-      std::printf("%s\n", parse_statement.toString().c_str());
-
       const CatalogRelation *query_result_relation = nullptr;
       try {
         OptimizerContext optimizer_context;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/tests/execution_generator/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/execution_generator/CMakeLists.txt b/query_optimizer/tests/execution_generator/CMakeLists.txt
index 09a7647..ebcb0b6 100644
--- a/query_optimizer/tests/execution_generator/CMakeLists.txt
+++ b/query_optimizer/tests/execution_generator/CMakeLists.txt
@@ -20,6 +20,11 @@ add_test(quickstep_queryoptimizer_tests_executiongenerator_commonsubexpression
          "${CMAKE_CURRENT_SOURCE_DIR}/CommonSubexpression.test"
          "${CMAKE_CURRENT_BINARY_DIR}/CommonSubexpression.test"
          "${CMAKE_CURRENT_BINARY_DIR}/CommonSubexpression/")
+add_test(quickstep_queryoptimizer_tests_executiongenerator_copy
+         "../quickstep_queryoptimizer_tests_ExecutionGeneratorTest"
+         "${CMAKE_CURRENT_SOURCE_DIR}/Copy.test"
+         "${CMAKE_CURRENT_BINARY_DIR}/Copy.test"
+         "${CMAKE_CURRENT_BINARY_DIR}/Copy/")
 add_test(quickstep_queryoptimizer_tests_executiongenerator_create
          "../quickstep_queryoptimizer_tests_ExecutionGeneratorTest"
          "${CMAKE_CURRENT_SOURCE_DIR}/Create.test"
@@ -158,6 +163,7 @@ endif(ENABLE_DISTRIBUTED)
 # Create the folders where the unit tests will store their data blocks for the
 # duration of their test.
 file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CommonSubexpression)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Copy)
 file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Create)
 file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Delete)
 file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Distinct)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/tests/execution_generator/Copy.test
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/execution_generator/Copy.test b/query_optimizer/tests/execution_generator/Copy.test
new file mode 100644
index 0000000..be924df
--- /dev/null
+++ b/query_optimizer/tests/execution_generator/Copy.test
@@ -0,0 +1,105 @@
+# 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.
+
+CREATE TABLE source (
+  int_col INT NULL,
+  date_col DATE NULL,
+  char_col CHAR(16),
+  varchar_col VARCHAR(16)
+);
+
+INSERT INTO source VALUES(1, '2000-01-01', 'aa', 'aaa');
+INSERT INTO source VALUES(2, '2000-02-02', 'bb', 'bbb');
+INSERT INTO source VALUES(3, '2000-03-03', 'cc', 'ccc');
+INSERT INTO source VALUES(4, '2000-04-04', 'aa', 'ddd');
+INSERT INTO source VALUES(5, '2000-05-05', 'bb', 'eee');
+INSERT INTO source VALUES(6, '2000-06-06', 'cc', 'fff');
+
+COPY source TO stderr WITH (DELIMITER '|');
+--
+1|2000-01-01|aa|aaa
+2|2000-02-02|bb|bbb
+3|2000-03-03|cc|ccc
+4|2000-04-04|aa|ddd
+5|2000-05-05|bb|eee
+6|2000-06-06|cc|fff
+==
+
+COPY
+  SELECT char_col, SUM(int_col)
+  FROM source
+  GROUP BY char_col
+TO stderr;
+--
+aa	5
+bb	7
+cc	9
+==
+
+COPY
+  SELECT * FROM (
+    SELECT -int_col * 1000, 'Negative' FROM source
+    UNION ALL
+    SELECT int_col * 1000, 'Positive' FROM source
+  ) AS t(VALUE, SIGN)
+  ORDER BY value
+TO stderr WITH (FORMAT 'CSV', DELIMITER e'\t');
+--
+VALUE	SIGN
+-6000	Negative
+-5000	Negative
+-4000	Negative
+-3000	Negative
+-2000	Negative
+-1000	Negative
+1000	Positive
+2000	Positive
+3000	Positive
+4000	Positive
+5000	Positive
+6000	Positive
+==
+
+# Test handling of NULL values and special characters.
+DELETE FROM source;
+INSERT INTO source VALUES(1, '2000-01-01', 'abc', 'def');
+INSERT INTO source VALUES(2, '2000-02-02', e'a\ta', '|,|');
+INSERT INTO source VALUES(NULL, NULL, e'b\nb', '"""');
+
+COPY source TO stderr;
+--
+1	2000-01-01	abc	def
+2	2000-02-02	a\ta	|,|
+\N	\N	b\nb	"""
+==
+
+COPY source TO stderr WITH (FORMAT 'CSV', HEADER FALSE);
+--
+1,2000-01-01,abc,def
+2,2000-02-02,a	a,"|,|"
+,,"b
+b",""""""""
+==
+
+COPY source TO stderr WITH (FORMAT 'CSV', DELIMITER '|', NULL_STRING '.na', HEADER TRUE);
+--
+int_col|date_col|char_col|varchar_col
+1|2000-01-01|abc|def
+2|2000-02-02|a	a|"|,|"
+.na|.na|"b
+b"|""""""""
+==

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/tests/physical_generator/Copy.test
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/physical_generator/Copy.test b/query_optimizer/tests/physical_generator/Copy.test
index 2f66415..3d76373 100644
--- a/query_optimizer/tests/physical_generator/Copy.test
+++ b/query_optimizer/tests/physical_generator/Copy.test
@@ -26,7 +26,7 @@ TopLevelPlan
   +-[]
 [Physical Plan]
 TopLevelPlan
-+-plan=CopyFrom[relation=Test,file_name=test.txt,column_delimiter=	,
++-plan=CopyFrom[relation=Test,file_name=test.txt,column_delimiter="\t",
 | escape_strings=true]
 +-output_attributes=
   +-[]
@@ -42,7 +42,7 @@ TopLevelPlan
   +-[]
 [Physical Plan]
 TopLevelPlan
-+-plan=CopyFrom[relation=Test,file_name=test.txt,column_delimiter=d,
++-plan=CopyFrom[relation=Test,file_name=test.txt,column_delimiter="d",
 | escape_strings=false]
 +-output_attributes=
   +-[]

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/query_optimizer/tests/resolver/Copy.test
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/resolver/Copy.test b/query_optimizer/tests/resolver/Copy.test
index c2ae91a..d68e18f 100644
--- a/query_optimizer/tests/resolver/Copy.test
+++ b/query_optimizer/tests/resolver/Copy.test
@@ -16,7 +16,7 @@
 # under the License.
 
 [default initial_logical_plan]
-copy test from 'test.txt'
+COPY test FROM 'test.txt'
 --
 TopLevelPlan
 +-plan=CopyFrom[relation=Test,file_name=test.txt,column_delimiter="\t",
@@ -25,14 +25,14 @@ TopLevelPlan
   +-[]
 ==
 
-copy tESt from 'test.txt' with (delimiter '123')
+COPY tESt FROM 'test.txt' WITH (delimiter '123')
 --
 ERROR: DELIMITER is not a single character (1 : 43)
-copy tESt from 'test.txt' with (delimiter '123')
+COPY tESt FROM 'test.txt' WITH (delimiter '123')
                                           ^
 ==
 
-copy tESt from 'test.txt' with (delimiter 'd', escape_strings false)
+COPY tESt FROM 'test.txt' WITH (delimiter 'd', escape_strings false)
 --
 TopLevelPlan
 +-plan=CopyFrom[relation=Test,file_name=test.txt,column_delimiter="d",
@@ -41,8 +41,160 @@ TopLevelPlan
   +-[]
 ==
 
-copy undefined_table from 'test.txt'
+COPY test TO 'test.txt';
+--
+TopLevelPlan
++-plan=CopyTo[file_name=@test.txt,format=TEXT,column_delimiter="\t",
+| escape_strings=true,null_string=\N]
+| +-input=TableReference[relation_name=Test,relation_alias=test]
+|   +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
+|   +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
+|   +-AttributeReference[id=2,name=float_col,relation=test,type=Float]
+|   +-AttributeReference[id=3,name=double_col,relation=test,type=Double NULL]
+|   +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
+|   +-AttributeReference[id=5,name=vchar_col,relation=test,type=VarChar(20) NULL]
++-output_attributes=
+  +-[]
+==
+
+COPY test TO stdout WITH (FORMAT 'CSV');
+--
+TopLevelPlan
++-plan=CopyTo[file_name=$stdout,format=CSV,column_delimiter=",",header=true,
+| quote="]
+| +-input=TableReference[relation_name=Test,relation_alias=test]
+|   +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
+|   +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
+|   +-AttributeReference[id=2,name=float_col,relation=test,type=Float]
+|   +-AttributeReference[id=3,name=double_col,relation=test,type=Double NULL]
+|   +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
+|   +-AttributeReference[id=5,name=vchar_col,relation=test,type=VarChar(20) NULL]
++-output_attributes=
+  +-[]
+==
+
+COPY
+  SELECT SUM(int_col) AS sum_int,
+         AVG(double_col) AS avg_dbl
+  FROM test
+  GROUP BY char_col
+  UNION ALL
+  SELECT 1, 2.0
+  FROM generate_series(1, 1)
+TO 'test.txt' WITH (DELIMITER ',');
+--
+TopLevelPlan
++-plan=CopyTo[file_name=@test.txt,format=TEXT,column_delimiter=",",
+| escape_strings=true,null_string=\N]
+| +-input=UnionAll[set_operation_type=UnionAll]
+|   +-operands=
+|   | +-Project
+|   | | +-input=Project
+|   | | | +-input=Aggregate
+|   | | | | +-input=TableReference[relation_name=Test,relation_alias=test]
+|   | | | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
+|   | | | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
+|   | | | | | +-AttributeReference[id=2,name=float_col,relation=test,type=Float]
+|   | | | | | +-AttributeReference[id=3,name=double_col,relation=test,
+|   | | | | | | type=Double NULL]
+|   | | | | | +-AttributeReference[id=4,name=char_col,relation=test,
+|   | | | | | | type=Char(20)]
+|   | | | | | +-AttributeReference[id=5,name=vchar_col,relation=test,
+|   | | | | |   type=VarChar(20) NULL]
+|   | | | | +-grouping_expressions=
+|   | | | | | +-AttributeReference[id=4,name=char_col,relation=test,
+|   | | | | |   type=Char(20)]
+|   | | | | +-aggregate_expressions=
+|   | | | |   +-Alias[id=6,name=,alias=$aggregate0,relation=$aggregate,
+|   | | | |   | type=Long NULL]
+|   | | | |   | +-AggregateFunction[function=SUM]
+|   | | | |   |   +-AttributeReference[id=0,name=int_col,relation=test,
+|   | | | |   |     type=Int NULL]
+|   | | | |   +-Alias[id=7,name=,alias=$aggregate1,relation=$aggregate,
+|   | | | |     type=Double NULL]
+|   | | | |     +-AggregateFunction[function=AVG]
+|   | | | |       +-AttributeReference[id=3,name=double_col,relation=test,
+|   | | | |         type=Double NULL]
+|   | | | +-project_list=
+|   | | |   +-Alias[id=6,name=sum_int,relation=,type=Long NULL]
+|   | | |   | +-AttributeReference[id=6,name=,alias=$aggregate0,
+|   | | |   |   relation=$aggregate,type=Long NULL]
+|   | | |   +-Alias[id=7,name=avg_dbl,relation=,type=Double NULL]
+|   | | |     +-AttributeReference[id=7,name=,alias=$aggregate1,
+|   | | |       relation=$aggregate,type=Double NULL]
+|   | | +-project_list=
+|   | |   +-AttributeReference[id=6,name=sum_int,relation=,type=Long NULL]
+|   | |   +-AttributeReference[id=7,name=avg_dbl,relation=,type=Double NULL]
+|   | +-Project
+|   |   +-input=Project
+|   |   | +-input=TableGenerator[function_name=generate_series]
+|   |   | | +-AttributeReference[id=8,name=generate_series,
+|   |   | |   relation=generate_series,type=Int]
+|   |   | +-project_list=
+|   |   |   +-Alias[id=9,name=,alias=1,relation=,type=Int]
+|   |   |   | +-Literal[value=1,type=Int]
+|   |   |   +-Alias[id=10,name=,alias=2.0,relation=,type=Double]
+|   |   |     +-Literal[value=2,type=Double]
+|   |   +-project_list=
+|   |     +-Alias[id=11,name=,alias=1,relation=,type=Long NULL]
+|   |     | +-Cast[target_type=Long NULL]
+|   |     |   +-operand=AttributeReference[id=9,name=,alias=1,relation=,type=Int]
+|   |     +-Alias[id=12,name=,alias=2.0,relation=,type=Double NULL]
+|   |       +-Cast[target_type=Double NULL]
+|   |         +-operand=AttributeReference[id=10,name=,alias=2.0,relation=,
+|   |           type=Double]
+|   +-project_attributes=
+|     +-AttributeReference[id=13,name=sum_int,relation=,type=Long NULL]
+|     +-AttributeReference[id=14,name=avg_dbl,relation=,type=Double NULL]
++-output_attributes=
+  +-[]
+==
+
+COPY undefined_table FROM 'test.txt'
 --
 ERROR: Unrecognized relation undefined_table (1 : 6)
-copy undefined_table from 'test.txt...
+COPY undefined_table FROM 'test.txt...
      ^
+==
+
+COPY test FROM 'test.txt' WITH (FORMAT 'CSV')
+--
+ERROR: Unsupported file format: csv (1 : 40)
+COPY test FROM 'test.txt' WITH (FORMAT 'CSV')
+                                       ^
+==
+
+COPY test FROM 'test.txt' WITH (XXX 'YY');
+--
+ERROR: Unsupported copy option: xxx (1 : 33)
+COPY test FROM 'test.txt' WITH (XXX 'YY');
+                                ^
+==
+
+COPY test TO 'test.txt' WITH (QUOTE '$');
+--
+ERROR: Unsupported copy option "quote" for file format TEXT (1 : 31)
+COPY test TO 'test.txt' WITH (QUOTE '$');
+                              ^
+==
+
+COPY test TO 'test.txt' WITH (FORMAT 'CSV', ESCAPE_STRINGS TRUE);
+--
+ERROR: Unsupported copy option "escape_strings" for file format CSV (1 : 45)
+... test TO 'test.txt' WITH (FORMAT 'CSV', ESCAPE_STRINGS TRUE);
+                                           ^
+==
+
+COPY test TO 'test.txt' WITH (FORMAT CSV, QUOTE '$$');
+--
+ERROR: QUOTE is not a single character (1 : 49)
+...test TO 'test.txt' WITH (FORMAT CSV, QUOTE '$$');
+                                              ^
+==
+
+COPY test TO 'test.txt' WITH (FORMAT 'TEXT', QUOTE '"');
+--
+ERROR: Unsupported copy option "quote" for file format TEXT (1 : 46)
+...test TO 'test.txt' WITH (FORMAT 'TEXT', QUOTE '"');
+                                           ^
+==


[09/12] incubator-quickstep git commit: Add "COPY TO" operator for exporting data from Quickstep.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/parser/preprocessed/SqlParser_gen.cpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.cpp b/parser/preprocessed/SqlParser_gen.cpp
index 5cd7426..72c61dd 100644
--- a/parser/preprocessed/SqlParser_gen.cpp
+++ b/parser/preprocessed/SqlParser_gen.cpp
@@ -237,90 +237,91 @@ extern int quickstep_yydebug;
     TOKEN_DECIMAL = 304,
     TOKEN_DEFAULT = 305,
     TOKEN_DELETE = 306,
-    TOKEN_DELIMITER = 307,
-    TOKEN_DESC = 308,
-    TOKEN_DISTINCT = 309,
-    TOKEN_DOUBLE = 310,
-    TOKEN_DROP = 311,
-    TOKEN_ELSE = 312,
-    TOKEN_END = 313,
-    TOKEN_ESCAPE_STRINGS = 314,
-    TOKEN_EXISTS = 315,
-    TOKEN_EXTRACT = 316,
-    TOKEN_FALSE = 317,
-    TOKEN_FIRST = 318,
-    TOKEN_FLOAT = 319,
-    TOKEN_FOLLOWING = 320,
-    TOKEN_FOR = 321,
-    TOKEN_FOREIGN = 322,
-    TOKEN_FROM = 323,
-    TOKEN_FULL = 324,
-    TOKEN_GROUP = 325,
-    TOKEN_HASH = 326,
-    TOKEN_HAVING = 327,
-    TOKEN_HOUR = 328,
-    TOKEN_IN = 329,
-    TOKEN_INDEX = 330,
-    TOKEN_INNER = 331,
-    TOKEN_INSERT = 332,
-    TOKEN_INTEGER = 333,
-    TOKEN_INTERVAL = 334,
-    TOKEN_INTO = 335,
-    TOKEN_JOIN = 336,
-    TOKEN_KEY = 337,
-    TOKEN_LAST = 338,
-    TOKEN_LEFT = 339,
-    TOKEN_LIMIT = 340,
-    TOKEN_LONG = 341,
-    TOKEN_MINUTE = 342,
-    TOKEN_MONTH = 343,
-    TOKEN_NULL = 344,
-    TOKEN_NULLS = 345,
-    TOKEN_OFF = 346,
-    TOKEN_ON = 347,
-    TOKEN_ORDER = 348,
-    TOKEN_OUTER = 349,
-    TOKEN_OVER = 350,
-    TOKEN_PARTITION = 351,
-    TOKEN_PARTITIONS = 352,
-    TOKEN_PERCENT = 353,
-    TOKEN_PRECEDING = 354,
-    TOKEN_PRIMARY = 355,
-    TOKEN_PRIORITY = 356,
-    TOKEN_QUIT = 357,
-    TOKEN_RANGE = 358,
-    TOKEN_REAL = 359,
-    TOKEN_REFERENCES = 360,
-    TOKEN_RIGHT = 361,
-    TOKEN_ROW = 362,
-    TOKEN_ROW_DELIMITER = 363,
-    TOKEN_ROWS = 364,
-    TOKEN_SECOND = 365,
-    TOKEN_SELECT = 366,
-    TOKEN_SET = 367,
-    TOKEN_SMA = 368,
-    TOKEN_SMALLINT = 369,
+    TOKEN_DESC = 307,
+    TOKEN_DISTINCT = 308,
+    TOKEN_DOUBLE = 309,
+    TOKEN_DROP = 310,
+    TOKEN_ELSE = 311,
+    TOKEN_END = 312,
+    TOKEN_EXISTS = 313,
+    TOKEN_EXTRACT = 314,
+    TOKEN_FALSE = 315,
+    TOKEN_FIRST = 316,
+    TOKEN_FLOAT = 317,
+    TOKEN_FOLLOWING = 318,
+    TOKEN_FOR = 319,
+    TOKEN_FOREIGN = 320,
+    TOKEN_FROM = 321,
+    TOKEN_FULL = 322,
+    TOKEN_GROUP = 323,
+    TOKEN_HASH = 324,
+    TOKEN_HAVING = 325,
+    TOKEN_HOUR = 326,
+    TOKEN_IN = 327,
+    TOKEN_INDEX = 328,
+    TOKEN_INNER = 329,
+    TOKEN_INSERT = 330,
+    TOKEN_INTEGER = 331,
+    TOKEN_INTERVAL = 332,
+    TOKEN_INTO = 333,
+    TOKEN_JOIN = 334,
+    TOKEN_KEY = 335,
+    TOKEN_LAST = 336,
+    TOKEN_LEFT = 337,
+    TOKEN_LIMIT = 338,
+    TOKEN_LONG = 339,
+    TOKEN_MINUTE = 340,
+    TOKEN_MONTH = 341,
+    TOKEN_NULL = 342,
+    TOKEN_NULLS = 343,
+    TOKEN_OFF = 344,
+    TOKEN_ON = 345,
+    TOKEN_ORDER = 346,
+    TOKEN_OUTER = 347,
+    TOKEN_OVER = 348,
+    TOKEN_PARTITION = 349,
+    TOKEN_PARTITIONS = 350,
+    TOKEN_PERCENT = 351,
+    TOKEN_PRECEDING = 352,
+    TOKEN_PRIMARY = 353,
+    TOKEN_PRIORITY = 354,
+    TOKEN_QUIT = 355,
+    TOKEN_RANGE = 356,
+    TOKEN_REAL = 357,
+    TOKEN_REFERENCES = 358,
+    TOKEN_RIGHT = 359,
+    TOKEN_ROW = 360,
+    TOKEN_ROW_DELIMITER = 361,
+    TOKEN_ROWS = 362,
+    TOKEN_SECOND = 363,
+    TOKEN_SELECT = 364,
+    TOKEN_SET = 365,
+    TOKEN_SMA = 366,
+    TOKEN_SMALLINT = 367,
+    TOKEN_STDERR = 368,
+    TOKEN_STDOUT = 369,
     TOKEN_SUBSTRING = 370,
     TOKEN_TABLE = 371,
     TOKEN_THEN = 372,
     TOKEN_TIME = 373,
     TOKEN_TIMESTAMP = 374,
-    TOKEN_TRUE = 375,
-    TOKEN_TUPLESAMPLE = 376,
-    TOKEN_UNBOUNDED = 377,
-    TOKEN_UNIQUE = 378,
-    TOKEN_UPDATE = 379,
-    TOKEN_USING = 380,
-    TOKEN_VALUES = 381,
-    TOKEN_VARCHAR = 382,
-    TOKEN_WHEN = 383,
-    TOKEN_WHERE = 384,
-    TOKEN_WINDOW = 385,
-    TOKEN_WITH = 386,
-    TOKEN_YEAR = 387,
-    TOKEN_YEARMONTH = 388,
-    TOKEN_EOF = 389,
-    TOKEN_LEX_ERROR = 390
+    TOKEN_TO = 375,
+    TOKEN_TRUE = 376,
+    TOKEN_TUPLESAMPLE = 377,
+    TOKEN_UNBOUNDED = 378,
+    TOKEN_UNIQUE = 379,
+    TOKEN_UPDATE = 380,
+    TOKEN_USING = 381,
+    TOKEN_VALUES = 382,
+    TOKEN_VARCHAR = 383,
+    TOKEN_WHEN = 384,
+    TOKEN_WHERE = 385,
+    TOKEN_WINDOW = 386,
+    TOKEN_WITH = 387,
+    TOKEN_YEAR = 388,
+    TOKEN_YEARMONTH = 389,
+    TOKEN_EOF = 390,
+    TOKEN_LEX_ERROR = 391
   };
 #endif
 
@@ -380,8 +381,7 @@ union YYSTYPE
   quickstep::ParseKeyStringValue *key_string_value_;
   quickstep::ParseKeyStringList *key_string_list_;
   quickstep::ParseKeyIntegerValue *key_integer_value_;
-
-  quickstep::ParseCopyFromParams *copy_from_params_;
+  quickstep::ParseKeyBoolValue *key_bool_value_;
 
   quickstep::ParseAssignment *assignment_;
   quickstep::PtrList<quickstep::ParseAssignment> *assignment_list_;
@@ -394,7 +394,7 @@ union YYSTYPE
   quickstep::ParseStatementUpdate *update_statement_;
   quickstep::ParseStatementInsert *insert_statement_;
   quickstep::ParseStatementDelete *delete_statement_;
-  quickstep::ParseStatementCopyFrom *copy_from_statement_;
+  quickstep::ParseStatementCopy *copy_statement_;
   quickstep::ParseStatementCreateTable *create_table_statement_;
   quickstep::ParsePartitionClause *partition_clause_;
   quickstep::ParseBlockProperties *block_properties_;
@@ -460,7 +460,7 @@ int quickstep_yyparse (yyscan_t yyscanner, quickstep::ParseStatement **parsedSta
 #endif /* !YY_QUICKSTEP_YY_SQLPARSER_GEN_HPP_INCLUDED  */
 
 /* Copy the second part of user declarations.  */
-#line 223 "../SqlParser.ypp" /* yacc.c:358  */
+#line 222 "../SqlParser.ypp" /* yacc.c:358  */
 
 /* This header needs YYSTYPE, which is defined by the %union directive above */
 #include "SqlLexer_gen.hpp"
@@ -708,23 +708,23 @@ union yyalloc
 #endif /* !YYCOPY_NEEDED */
 
 /* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  49
+#define YYFINAL  50
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   1207
+#define YYLAST   1391
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  147
+#define YYNTOKENS  148
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  109
+#define YYNNTS  110
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  293
+#define YYNRULES  298
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  543
+#define YYNSTATES  550
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   390
+#define YYMAXUTOK   391
 
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -734,11 +734,11 @@ union yyalloc
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     142,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     143,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,   146,     2,     2,
-     143,   144,    23,    21,   145,    22,    27,    24,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,   141,
+       2,     2,     2,     2,     2,     2,     2,   147,     2,     2,
+     144,   145,    23,    21,   146,    22,    27,    24,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,   142,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -772,43 +772,43 @@ static const yytype_uint8 yytranslate[] =
      110,   111,   112,   113,   114,   115,   116,   117,   118,   119,
      120,   121,   122,   123,   124,   125,   126,   127,   128,   129,
      130,   131,   132,   133,   134,   135,   136,   137,   138,   139,
-     140
+     140,   141
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   639,   639,   643,   647,   651,   655,   658,   665,   668,
-     671,   674,   677,   680,   683,   686,   689,   692,   698,   704,
-     711,   717,   724,   733,   738,   747,   752,   757,   761,   767,
-     772,   775,   778,   783,   786,   789,   792,   795,   798,   801,
-     804,   807,   810,   822,   825,   828,   846,   866,   869,   872,
-     877,   882,   888,   894,   903,   907,   913,   916,   921,   926,
-     931,   938,   945,   949,   955,   958,   963,   966,   971,   974,
-     979,   982,  1001,  1004,  1009,  1013,  1019,  1022,  1025,  1030,
-    1033,  1040,  1045,  1056,  1061,  1065,  1069,  1075,  1078,  1084,
-    1092,  1095,  1098,  1104,  1109,  1112,  1117,  1121,  1125,  1129,
-    1135,  1140,  1145,  1149,  1155,  1164,  1167,  1172,  1175,  1194,
-    1199,  1203,  1209,  1215,  1224,  1229,  1237,  1243,  1249,  1252,
-    1255,  1260,  1263,  1268,  1272,  1278,  1281,  1284,  1289,  1294,
-    1299,  1302,  1305,  1310,  1313,  1316,  1319,  1322,  1325,  1328,
-    1331,  1336,  1339,  1344,  1348,  1352,  1355,  1359,  1362,  1367,
-    1370,  1375,  1378,  1383,  1387,  1393,  1396,  1401,  1404,  1409,
-    1412,  1417,  1420,  1439,  1442,  1447,  1451,  1457,  1463,  1468,
-    1471,  1476,  1479,  1484,  1487,  1492,  1495,  1500,  1501,  1504,
-    1509,  1510,  1513,  1518,  1522,  1528,  1535,  1538,  1541,  1546,
-    1549,  1552,  1558,  1561,  1566,  1571,  1580,  1585,  1594,  1599,
-    1602,  1607,  1610,  1615,  1621,  1627,  1630,  1633,  1636,  1639,
-    1642,  1648,  1657,  1660,  1665,  1668,  1673,  1676,  1681,  1684,
-    1687,  1690,  1694,  1698,  1701,  1704,  1707,  1710,  1715,  1719,
-    1723,  1726,  1731,  1736,  1740,  1746,  1749,  1754,  1758,  1764,
-    1769,  1773,  1779,  1784,  1787,  1792,  1796,  1802,  1805,  1808,
-    1811,  1823,  1827,  1846,  1859,  1874,  1877,  1880,  1883,  1886,
-    1889,  1894,  1898,  1904,  1907,  1912,  1916,  1923,  1926,  1929,
-    1932,  1935,  1938,  1941,  1944,  1947,  1950,  1955,  1966,  1969,
-    1974,  1977,  1980,  1986,  1990,  1996,  1999,  2007,  2010,  2013,
-    2016,  2022,  2027,  2032
+       0,   640,   640,   644,   648,   652,   656,   659,   666,   669,
+     672,   675,   678,   681,   684,   687,   690,   693,   699,   705,
+     712,   718,   725,   734,   739,   748,   753,   758,   762,   768,
+     773,   776,   779,   784,   787,   790,   793,   796,   799,   802,
+     805,   808,   811,   823,   826,   829,   847,   867,   870,   873,
+     878,   883,   889,   895,   904,   908,   914,   917,   922,   927,
+     932,   939,   946,   950,   956,   959,   964,   967,   972,   975,
+     980,   983,  1002,  1005,  1010,  1014,  1020,  1023,  1026,  1029,
+    1034,  1037,  1040,  1047,  1052,  1063,  1068,  1073,  1077,  1081,
+    1087,  1090,  1096,  1104,  1107,  1110,  1116,  1121,  1126,  1130,
+    1136,  1140,  1143,  1148,  1151,  1156,  1161,  1166,  1170,  1176,
+    1185,  1188,  1193,  1196,  1215,  1220,  1224,  1230,  1236,  1245,
+    1250,  1258,  1264,  1270,  1273,  1276,  1281,  1284,  1289,  1293,
+    1299,  1302,  1305,  1310,  1315,  1320,  1323,  1326,  1331,  1334,
+    1337,  1340,  1343,  1346,  1349,  1352,  1357,  1360,  1365,  1369,
+    1373,  1376,  1380,  1383,  1388,  1391,  1396,  1399,  1404,  1408,
+    1414,  1417,  1422,  1425,  1430,  1433,  1438,  1441,  1460,  1463,
+    1468,  1472,  1478,  1484,  1489,  1492,  1497,  1500,  1505,  1508,
+    1513,  1516,  1521,  1522,  1525,  1530,  1531,  1534,  1539,  1543,
+    1549,  1556,  1559,  1562,  1567,  1570,  1573,  1579,  1582,  1587,
+    1592,  1601,  1606,  1615,  1620,  1623,  1628,  1631,  1636,  1642,
+    1648,  1651,  1654,  1657,  1660,  1663,  1669,  1678,  1681,  1686,
+    1689,  1694,  1697,  1702,  1705,  1708,  1711,  1715,  1719,  1722,
+    1725,  1728,  1731,  1736,  1740,  1744,  1747,  1752,  1757,  1761,
+    1767,  1770,  1775,  1779,  1785,  1790,  1794,  1800,  1805,  1808,
+    1813,  1817,  1823,  1826,  1829,  1832,  1844,  1848,  1867,  1880,
+    1895,  1898,  1901,  1904,  1907,  1910,  1915,  1919,  1925,  1928,
+    1933,  1937,  1944,  1947,  1950,  1953,  1956,  1959,  1962,  1965,
+    1968,  1971,  1976,  1987,  1990,  1995,  1998,  2001,  2007,  2011,
+    2017,  2020,  2028,  2031,  2034,  2037,  2043,  2048,  2053
 };
 #endif
 
@@ -830,38 +830,38 @@ static const char *const yytname[] =
   "TOKEN_CHARACTER", "TOKEN_CHECK", "TOKEN_COLUMN", "TOKEN_CONSTRAINT",
   "TOKEN_COPY", "TOKEN_CREATE", "TOKEN_CURRENT", "TOKEN_DATE",
   "TOKEN_DATETIME", "TOKEN_DAY", "TOKEN_DECIMAL", "TOKEN_DEFAULT",
-  "TOKEN_DELETE", "TOKEN_DELIMITER", "TOKEN_DESC", "TOKEN_DISTINCT",
-  "TOKEN_DOUBLE", "TOKEN_DROP", "TOKEN_ELSE", "TOKEN_END",
-  "TOKEN_ESCAPE_STRINGS", "TOKEN_EXISTS", "TOKEN_EXTRACT", "TOKEN_FALSE",
-  "TOKEN_FIRST", "TOKEN_FLOAT", "TOKEN_FOLLOWING", "TOKEN_FOR",
-  "TOKEN_FOREIGN", "TOKEN_FROM", "TOKEN_FULL", "TOKEN_GROUP", "TOKEN_HASH",
-  "TOKEN_HAVING", "TOKEN_HOUR", "TOKEN_IN", "TOKEN_INDEX", "TOKEN_INNER",
-  "TOKEN_INSERT", "TOKEN_INTEGER", "TOKEN_INTERVAL", "TOKEN_INTO",
-  "TOKEN_JOIN", "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LEFT", "TOKEN_LIMIT",
-  "TOKEN_LONG", "TOKEN_MINUTE", "TOKEN_MONTH", "TOKEN_NULL", "TOKEN_NULLS",
-  "TOKEN_OFF", "TOKEN_ON", "TOKEN_ORDER", "TOKEN_OUTER", "TOKEN_OVER",
-  "TOKEN_PARTITION", "TOKEN_PARTITIONS", "TOKEN_PERCENT",
+  "TOKEN_DELETE", "TOKEN_DESC", "TOKEN_DISTINCT", "TOKEN_DOUBLE",
+  "TOKEN_DROP", "TOKEN_ELSE", "TOKEN_END", "TOKEN_EXISTS", "TOKEN_EXTRACT",
+  "TOKEN_FALSE", "TOKEN_FIRST", "TOKEN_FLOAT", "TOKEN_FOLLOWING",
+  "TOKEN_FOR", "TOKEN_FOREIGN", "TOKEN_FROM", "TOKEN_FULL", "TOKEN_GROUP",
+  "TOKEN_HASH", "TOKEN_HAVING", "TOKEN_HOUR", "TOKEN_IN", "TOKEN_INDEX",
+  "TOKEN_INNER", "TOKEN_INSERT", "TOKEN_INTEGER", "TOKEN_INTERVAL",
+  "TOKEN_INTO", "TOKEN_JOIN", "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LEFT",
+  "TOKEN_LIMIT", "TOKEN_LONG", "TOKEN_MINUTE", "TOKEN_MONTH", "TOKEN_NULL",
+  "TOKEN_NULLS", "TOKEN_OFF", "TOKEN_ON", "TOKEN_ORDER", "TOKEN_OUTER",
+  "TOKEN_OVER", "TOKEN_PARTITION", "TOKEN_PARTITIONS", "TOKEN_PERCENT",
   "TOKEN_PRECEDING", "TOKEN_PRIMARY", "TOKEN_PRIORITY", "TOKEN_QUIT",
   "TOKEN_RANGE", "TOKEN_REAL", "TOKEN_REFERENCES", "TOKEN_RIGHT",
   "TOKEN_ROW", "TOKEN_ROW_DELIMITER", "TOKEN_ROWS", "TOKEN_SECOND",
   "TOKEN_SELECT", "TOKEN_SET", "TOKEN_SMA", "TOKEN_SMALLINT",
-  "TOKEN_SUBSTRING", "TOKEN_TABLE", "TOKEN_THEN", "TOKEN_TIME",
-  "TOKEN_TIMESTAMP", "TOKEN_TRUE", "TOKEN_TUPLESAMPLE", "TOKEN_UNBOUNDED",
-  "TOKEN_UNIQUE", "TOKEN_UPDATE", "TOKEN_USING", "TOKEN_VALUES",
-  "TOKEN_VARCHAR", "TOKEN_WHEN", "TOKEN_WHERE", "TOKEN_WINDOW",
-  "TOKEN_WITH", "TOKEN_YEAR", "TOKEN_YEARMONTH", "TOKEN_EOF",
-  "TOKEN_LEX_ERROR", "';'", "'\\n'", "'('", "')'", "','", "'%'", "$accept",
-  "start", "sql_statement", "quit_statement", "alter_table_statement",
-  "create_table_statement", "create_index_statement",
-  "drop_table_statement", "column_def", "column_def_commalist",
-  "data_type", "column_constraint_def", "column_constraint_def_list",
-  "opt_column_constraint_def_list", "table_constraint_def",
-  "table_constraint_def_commalist", "opt_table_constraint_def_commalist",
-  "opt_column_list", "opt_block_properties", "opt_partition_clause",
-  "partition_type", "key_value_list", "key_value", "key_string_value",
-  "key_string_list", "key_integer_value", "index_type",
-  "opt_index_properties", "insert_statement", "copy_from_statement",
-  "opt_copy_from_params", "copy_from_params", "update_statement",
+  "TOKEN_STDERR", "TOKEN_STDOUT", "TOKEN_SUBSTRING", "TOKEN_TABLE",
+  "TOKEN_THEN", "TOKEN_TIME", "TOKEN_TIMESTAMP", "TOKEN_TO", "TOKEN_TRUE",
+  "TOKEN_TUPLESAMPLE", "TOKEN_UNBOUNDED", "TOKEN_UNIQUE", "TOKEN_UPDATE",
+  "TOKEN_USING", "TOKEN_VALUES", "TOKEN_VARCHAR", "TOKEN_WHEN",
+  "TOKEN_WHERE", "TOKEN_WINDOW", "TOKEN_WITH", "TOKEN_YEAR",
+  "TOKEN_YEARMONTH", "TOKEN_EOF", "TOKEN_LEX_ERROR", "';'", "'\\n'", "'('",
+  "')'", "','", "'%'", "$accept", "start", "sql_statement",
+  "quit_statement", "alter_table_statement", "create_table_statement",
+  "create_index_statement", "drop_table_statement", "column_def",
+  "column_def_commalist", "data_type", "column_constraint_def",
+  "column_constraint_def_list", "opt_column_constraint_def_list",
+  "table_constraint_def", "table_constraint_def_commalist",
+  "opt_table_constraint_def_commalist", "opt_column_list",
+  "opt_block_properties", "opt_partition_clause", "partition_type",
+  "key_value_list", "key_value", "key_string_value", "key_string_list",
+  "key_integer_value", "key_bool_value", "index_type",
+  "opt_index_properties", "insert_statement", "copy_statement",
+  "copy_to_target", "opt_copy_params", "update_statement",
   "delete_statement", "assignment_list", "assignment_item",
   "set_operation_statement", "opt_priority_clause", "with_clause",
   "with_list", "with_list_element", "set_operation_union",
@@ -909,16 +909,16 @@ static const yytype_uint16 yytoknum[] =
      360,   361,   362,   363,   364,   365,   366,   367,   368,   369,
      370,   371,   372,   373,   374,   375,   376,   377,   378,   379,
      380,   381,   382,   383,   384,   385,   386,   387,   388,   389,
-     390,    59,    10,    40,    41,    44,    37
+     390,   391,    59,    10,    40,    41,    44,    37
 };
 # endif
 
-#define YYPACT_NINF -244
+#define YYPACT_NINF -395
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-244)))
+  (!!((Yystate) == (-395)))
 
-#define YYTABLE_NINF -134
+#define YYTABLE_NINF -139
 
 #define yytable_value_is_error(Yytable_value) \
   0
@@ -927,61 +927,61 @@ static const yytype_uint16 yytoknum[] =
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     807,  -244,  -244,   -55,   203,   -26,    -2,    -6,    43,  -244,
-      86,   203,   203,  -244,   136,   125,  -244,  -244,  -244,  -244,
-    -244,  -244,  -244,  -244,  -244,  -244,   -22,    -3,   128,  -244,
-     -78,   182,   203,  -244,  -244,   130,   203,   203,   203,   203,
-     203,  -244,  -244,   633,   107,    89,  -244,   209,   120,  -244,
-    -244,  -244,   197,    -3,    86,   161,  -244,   137,  -244,  -244,
-    -244,    27,   265,   180,   141,   170,  -244,   -25,  -244,  -244,
-     301,   313,  -244,  -244,  -244,   660,   188,  -244,   249,  -244,
-    -244,   206,  -244,  -244,   357,  -244,  -244,  -244,  -244,   221,
-    -244,  -244,   222,   282,   783,   366,   299,   231,  -244,  -244,
-     272,     7,  -244,  -244,   277,  -244,  -244,  -244,  -244,  -244,
-     933,    -5,   203,   203,   237,   203,   203,  -244,   137,   374,
-    -244,   233,   239,   246,   203,   203,   551,  -244,  -244,   244,
-     203,  -244,  -244,  -244,   551,    47,    40,  -244,   376,  -244,
-     153,   153,   960,   381,  -244,     8,    24,  -244,    23,   170,
-     960,  -244,  -244,   203,   960,  -244,  -244,  -244,  -244,   960,
-      36,   313,  -244,   203,   363,    94,  -244,   378,  -244,   137,
-    -244,   144,  -244,   137,   128,  -244,   203,   -21,   203,   203,
-     248,  -244,   250,  -244,   147,  1069,   810,   237,   469,   387,
-     388,  -244,  -244,   329,   380,  1042,   152,    45,   960,    48,
-    -244,   960,  -244,   333,   257,  -244,  -244,  -244,  -244,  -244,
-    -244,   330,  -244,   168,   260,  -244,  -244,    19,    66,   146,
-    -244,   264,    66,    51,   335,  -244,  -244,     7,  -244,   304,
-    -244,  -244,   267,   960,  -244,   279,   158,   203,  -244,   960,
-    -244,   203,  -244,  -244,   270,   331,   334,   273,  -244,  -244,
-    -244,   165,   203,   290,   -21,   203,  -244,    77,  -244,  -244,
-       2,    64,   551,   551,   193,  -244,  -244,  -244,  -244,  -244,
-    -244,  -244,  -244,   960,   281,   960,    31,  -244,   162,   294,
-     960,    71,  -244,   364,   279,  -244,  -244,   960,   419,  -244,
-     110,   203,  -244,  -244,   332,  -244,   336,   337,   342,    23,
-    -244,   423,   426,    66,   392,   361,   397,   296,   343,  -244,
-     166,  -244,   960,  -244,   279,  -244,   551,   300,   302,   203,
-     437,   119,   169,  -244,   172,   421,    60,  -244,   305,   316,
-    -244,   355,   310,  1042,  -244,   368,   203,  -244,  -244,    77,
-    -244,  -244,   388,  -244,  -244,  -244,   960,   315,    95,   783,
-    -244,   279,   362,  -244,  -244,  1042,   317,   279,   960,  -244,
-      26,   -15,  -244,  -244,  -244,  -244,  -244,    23,   146,   356,
-     358,  -244,   960,   551,   365,   960,  -244,   420,   111,  -244,
-     279,     4,   203,   203,   174,  -244,  -244,  -244,  -244,  -244,
-    -244,  -244,   201,  -244,   203,  -244,  -244,  -244,  -244,   321,
-     -21,   427,   369,  -244,   551,  -244,  -244,   323,  -244,   238,
-     783,  -244,   960,   179,  -244,  -244,  1042,   279,  -244,   460,
-    -244,   384,  -244,  -244,   326,   387,   435,   394,   326,   960,
-    -244,  -244,  -244,   459,  -244,   181,   183,  -244,   480,   119,
-    -244,   203,  -244,  -244,   345,   447,  -244,     6,   203,   960,
-     185,   279,  -244,   192,   349,   551,   960,   489,   367,   353,
-    -244,   240,    12,   389,  -244,  -244,  -244,   208,  -244,  -244,
-    -244,  -244,    11,   203,    22,  -244,   359,   279,  -244,  -244,
-    -244,   387,   353,  -244,   203,  -244,   367,  -244,   960,  -244,
-    -244,   405,   404,   398,   407,   500,   203,  -244,   203,  -244,
-    -244,   203,  -244,   210,  -244,  -244,   371,  -244,   482,  -244,
-    -244,   129,  -244,  -244,  -244,  -244,    13,   373,  -244,   212,
-    -244,   203,   375,  -244,  -244,   449,   410,   454,  -244,   203,
-    -244,   214,   304,  -244,  -244,  -244,   216,   424,   383,  -244,
-     521,  -244,  -244
+     174,  -395,  -395,   -64,    85,   -26,    14,   -31,   -16,  -395,
+      40,   196,   196,  -395,   109,   102,  -395,  -395,  -395,  -395,
+    -395,  -395,  -395,  -395,  -395,  -395,   148,    -3,    87,  -395,
+     -40,   121,   196,  -395,  -395,     1,    -5,   196,   196,   196,
+     196,   196,  -395,  -395,   716,    82,     2,  -395,   153,    63,
+    -395,  -395,  -395,    98,   152,    -3,    40,   141,  -395,    98,
+    -395,  -395,  -395,    12,    97,   116,   261,   116,   169,   126,
+     138,  -395,   176,  -395,  -395,   270,   274,  -395,  -395,  -395,
+     807,   139,  -395,   210,  -395,  -395,   154,  -395,  -395,   297,
+    -395,  -395,  -395,  -395,   172,  -395,  -395,   177,   231,   901,
+     313,   265,   192,  -395,  -395,   338,    23,  -395,  -395,   243,
+    -395,  -395,  -395,  -395,  -395,  1083,    -7,   196,   196,   214,
+     196,     1,   196,  -395,    98,   363,  -395,   205,   263,  -395,
+    -395,  -395,   255,  -395,   116,  -395,   196,   196,   625,  -395,
+    -395,   262,   196,  -395,  -395,  -395,   625,    33,   -29,  -395,
+     409,  -395,   165,   165,  1174,   411,  -395,   -14,    28,  -395,
+      13,   138,  1174,  -395,  -395,   196,  1174,  -395,  -395,  -395,
+    -395,  1174,    18,   274,  -395,   196,   398,    59,  -395,   417,
+    -395,    98,  -395,   202,  -395,   116,    98,    87,  -395,   196,
+      80,   196,   196,   196,  -395,   285,  -395,   211,  1241,   992,
+     214,   534,   422,   423,  -395,  -395,   312,   415,  1252,   219,
+      43,  1174,    61,  -395,  1174,  -395,   369,   292,  -395,  -395,
+    -395,  -395,  -395,  -395,   367,  -395,   216,   294,  -395,  -395,
+       7,   186,   267,  -395,   298,   186,     3,   372,  -395,  -395,
+      23,  -395,   347,  -395,  -395,   295,  1174,  -395,   351,   229,
+     196,  -395,  1174,  -395,   196,  -395,  -395,  -395,   303,   366,
+     368,   304,  -395,  -395,  -395,   232,  -395,  -395,  -395,  -395,
+    -395,    34,   196,   323,    80,   196,  -395,   188,  -395,  -395,
+       4,    65,   625,   625,   276,  -395,  -395,  -395,  -395,  -395,
+    -395,  -395,  -395,  1174,   311,  1174,    51,  -395,   234,   326,
+    1174,    71,  -395,   399,   351,  -395,  -395,  1174,   453,  -395,
+     160,   196,  -395,  -395,   370,  -395,   373,   374,   379,    13,
+    -395,   457,   462,   186,   430,   400,   431,   329,   380,  -395,
+     236,  -395,  1174,  -395,   351,  -395,   625,   333,   334,   196,
+    -395,   196,  -395,  -395,  -395,  -395,  -395,  -395,  -395,   196,
+    -395,  -395,  -395,   238,   454,   184,  -395,   336,   348,  -395,
+     391,   342,  1252,  -395,   403,   196,  -395,  -395,   188,  -395,
+    -395,   423,  -395,  -395,  -395,  1174,   345,   341,   901,  -395,
+     351,   401,  -395,  -395,  1252,   350,   351,  1174,  -395,    37,
+      35,  -395,  -395,  -395,  -395,  -395,    13,   267,   390,   395,
+    -395,  1174,   625,   396,  1174,  -395,   455,   108,  -395,   351,
+       8,   196,   196,   240,  -395,   242,  -395,   196,  -395,  -395,
+    -395,  -395,   354,    80,   461,   402,  -395,   625,  -395,  -395,
+     356,  -395,   346,   901,  -395,  1174,   245,  -395,  -395,  1252,
+     351,  -395,   495,  -395,   408,  -395,  -395,   358,   422,   464,
+     420,   358,  1174,  -395,  -395,  -395,   490,  -395,   249,   251,
+    -395,  -395,  -395,   196,  -395,  -395,   375,   468,  -395,    19,
+     196,  1174,   264,   351,  -395,   266,   371,   625,  1174,   504,
+     376,   377,  -395,   227,    46,   405,  -395,   269,   196,    -9,
+    -395,   381,   351,  -395,  -395,  -395,   422,   377,  -395,   196,
+    -395,   376,  -395,  1174,  -395,  -395,   421,   418,   407,   425,
+     515,   196,  -395,   277,  -395,  -395,   384,  -395,   496,  -395,
+    -395,    49,  -395,  -395,  -395,  -395,    56,   386,  -395,   196,
+     388,  -395,  -395,   466,   426,   467,  -395,   196,   279,   347,
+    -395,  -395,  -395,   281,   445,   404,  -395,   539,  -395,  -395
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -989,93 +989,93 @@ static const yytype_int16 yypact[] =
      means the default is an error.  */
 static const yytype_uint16 yydefact[] =
 {
-       0,     6,   293,     0,     0,     0,     0,     0,     0,    18,
-     118,     0,     0,     7,     0,     0,    15,     8,    10,    11,
-      13,    14,     9,    17,    12,    16,     0,   107,   114,   116,
-       0,   291,     0,   285,   286,     0,     0,     0,     0,     0,
-       0,   119,   120,     0,     0,   109,   110,     0,   151,     1,
-       3,     2,     0,   107,   118,     0,   105,     0,     5,     4,
-     292,     0,     0,     0,     0,   192,    25,     0,   251,   248,
-       0,   277,   121,    40,    29,     0,     0,    30,    31,    34,
-      36,     0,    37,    39,     0,    41,   247,    35,    38,     0,
-      32,    33,     0,     0,     0,     0,     0,   122,   123,   227,
-     127,   213,   215,   217,   220,   223,   224,   225,   219,   218,
-       0,   263,     0,     0,     0,     0,     0,   106,     0,     0,
-     115,     0,     0,    94,     0,     0,     0,   101,   193,     0,
-       0,    91,   249,   250,     0,     0,   243,   240,     0,    43,
-       0,   252,     0,     0,    44,     0,     0,   254,     0,   192,
-       0,   278,   279,     0,     0,   126,   281,   282,   280,     0,
-       0,     0,   216,     0,     0,   192,   103,     0,   111,     0,
-     112,     0,   283,     0,   113,   108,     0,     0,     0,     0,
-       0,    93,    66,    27,     0,     0,     0,     0,     0,   194,
-     196,   198,   200,     0,   218,     0,     0,     0,     0,   243,
-     237,     0,   241,     0,     0,   257,   258,   259,   256,   260,
-     255,     0,   253,     0,     0,   129,   226,     0,     0,   153,
-     142,   128,   147,   130,   155,   124,   125,   212,   214,   169,
-     221,   264,     0,     0,   228,   245,     0,     0,   100,     0,
-     152,     0,    92,    19,     0,     0,     0,     0,    20,    21,
-      22,     0,     0,     0,    64,     0,    42,    56,   199,   207,
-       0,     0,     0,     0,     0,   267,   269,   270,   271,   272,
-     268,   273,   275,     0,     0,     0,     0,   261,     0,     0,
-       0,     0,   238,     0,   244,   236,    45,     0,     0,    46,
-     133,     0,   143,   149,   139,   134,   135,   137,     0,     0,
-     146,     0,     0,   145,     0,   157,     0,     0,   171,   229,
-       0,   230,     0,   102,   104,   284,     0,     0,     0,     0,
-       0,     0,     0,   265,     0,   263,     0,    63,    65,    68,
-      28,     0,     0,     0,    47,     0,     0,    49,    55,    57,
-      26,   206,   195,   197,   274,   276,     0,     0,     0,     0,
-     208,   205,     0,   204,    90,     0,     0,   242,     0,   235,
-       0,     0,   148,   150,   140,   136,   138,     0,   154,     0,
-       0,   144,     0,     0,   159,     0,   222,     0,   173,   231,
-     246,     0,     0,     0,     0,    96,   289,   290,   288,   287,
-      97,    95,     0,    67,     0,    83,    84,    85,    86,    87,
-       0,     0,    70,    48,     0,    51,    50,     0,    54,     0,
-       0,   210,     0,     0,   203,   262,     0,   239,   232,     0,
-     233,     0,   131,   132,   156,   158,     0,   161,   170,     0,
-     176,   175,   168,     0,    61,     0,     0,    58,     0,     0,
-     266,     0,    24,    62,     0,     0,    23,     0,     0,     0,
-       0,   201,   209,     0,     0,     0,     0,     0,   163,   172,
-     183,   186,     0,     0,    59,    98,    99,     0,    74,    76,
-      77,    78,     0,     0,     0,    52,     0,   202,   211,    89,
-     234,   141,   160,   162,     0,   117,   164,   165,     0,   187,
-     188,   189,     0,     0,     0,     0,     0,    88,     0,    82,
-      80,     0,    79,     0,    72,    73,     0,    53,     0,   166,
-     184,     0,   185,   177,   179,   178,     0,     0,    75,     0,
-      69,     0,     0,   190,   191,     0,     0,     0,   174,     0,
-      81,     0,   169,   180,   182,   181,     0,     0,     0,    60,
-       0,   167,    71
+       0,     6,   298,     0,     0,     0,     0,     0,     0,    18,
+     123,     0,     0,     7,     0,     0,    15,     8,    10,    11,
+      13,    14,     9,    17,    12,    16,     0,   112,   119,   121,
+       0,   296,     0,   290,   291,     0,     0,     0,     0,     0,
+       0,     0,   124,   125,     0,     0,   114,   115,     0,   156,
+       1,     3,     2,     0,     0,   112,   123,     0,   110,     0,
+       5,     4,   297,     0,     0,   103,     0,   103,     0,     0,
+     197,    25,     0,   256,   253,     0,   282,   126,    40,    29,
+       0,     0,    30,    31,    34,    36,     0,    37,    39,     0,
+      41,   252,    35,    38,     0,    32,    33,     0,     0,     0,
+       0,     0,   127,   128,   232,   132,   218,   220,   222,   225,
+     228,   229,   230,   224,   223,     0,   268,     0,     0,     0,
+       0,     0,     0,   111,     0,     0,   120,     0,     0,   100,
+     102,   101,     0,    98,   103,    97,     0,     0,     0,   106,
+     198,     0,     0,    94,   254,   255,     0,     0,   248,   245,
+       0,    43,     0,   257,     0,     0,    44,     0,     0,   259,
+       0,   197,     0,   283,   284,     0,     0,   131,   286,   287,
+     285,     0,     0,     0,   221,     0,     0,   197,   108,     0,
+     116,     0,   117,     0,   288,   103,     0,   118,   113,     0,
+       0,     0,     0,     0,    96,    66,    27,     0,     0,     0,
+       0,     0,   199,   201,   203,   205,     0,   223,     0,     0,
+       0,     0,   248,   242,     0,   246,     0,     0,   262,   263,
+     264,   261,   265,   260,     0,   258,     0,     0,   134,   231,
+       0,     0,   158,   147,   133,   152,   135,   160,   129,   130,
+     217,   219,   174,   226,   269,     0,     0,   233,   250,     0,
+       0,   105,     0,   157,     0,    99,    95,    19,     0,     0,
+       0,     0,    20,    21,    22,     0,    74,    76,    77,    78,
+      79,     0,     0,     0,    64,     0,    42,    56,   204,   212,
+       0,     0,     0,     0,     0,   272,   274,   275,   276,   277,
+     273,   278,   280,     0,     0,     0,     0,   266,     0,     0,
+       0,     0,   243,     0,   249,   241,    45,     0,     0,    46,
+     138,     0,   148,   154,   144,   139,   140,   142,     0,     0,
+     151,     0,     0,   150,     0,   162,     0,     0,   176,   234,
+       0,   235,     0,   107,   109,   289,     0,     0,     0,     0,
+     104,     0,    81,    84,    82,   294,   295,   293,   292,     0,
+      80,    85,   270,     0,   268,     0,    63,    65,    68,    28,
+       0,     0,     0,    47,     0,     0,    49,    55,    57,    26,
+     211,   200,   202,   279,   281,     0,     0,     0,     0,   213,
+     210,     0,   209,    93,     0,     0,   247,     0,   240,     0,
+       0,   153,   155,   145,   141,   143,     0,   159,     0,     0,
+     149,     0,     0,   164,     0,   227,     0,   178,   236,   251,
+       0,     0,     0,     0,    75,     0,    67,     0,    86,    87,
+      88,    89,    90,     0,     0,    70,    48,     0,    51,    50,
+       0,    54,     0,     0,   215,     0,     0,   208,   267,     0,
+     244,   237,     0,   238,     0,   136,   137,   161,   163,     0,
+     166,   175,     0,   181,   180,   173,     0,    61,     0,     0,
+      58,    83,   271,     0,    24,    62,     0,     0,    23,     0,
+       0,     0,     0,   206,   214,     0,     0,     0,     0,     0,
+     168,   177,   188,   191,     0,     0,    59,     0,     0,     0,
+      52,     0,   207,   216,    92,   239,   146,   165,   167,     0,
+     122,   169,   170,     0,   192,   193,   194,     0,     0,     0,
+       0,     0,    91,     0,    72,    73,     0,    53,     0,   171,
+     189,     0,   190,   182,   184,   183,     0,     0,    69,     0,
+       0,   195,   196,     0,     0,     0,   179,     0,     0,   174,
+     185,   187,   186,     0,     0,     0,    60,     0,   172,    71
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -244,  -244,  -244,  -244,  -244,  -244,  -244,  -244,  -132,  -244,
-     346,   191,  -244,  -244,  -243,  -244,  -244,  -244,  -244,  -244,
-    -244,    59,    35,  -244,  -244,  -244,  -244,  -244,  -244,  -244,
-    -244,  -244,  -244,  -244,  -244,   303,  -244,   483,  -244,  -244,
-     428,   200,   425,    -8,   485,  -244,  -244,   395,  -244,   -98,
-    -244,  -244,  -165,   175,  -179,   -10,  -244,  -244,  -244,  -244,
-    -244,  -244,  -244,    58,     5,  -244,  -244,  -244,  -244,  -244,
-    -244,    90,    61,  -244,  -244,    39,  -244,  -133,   285,   287,
-     379,   -37,   400,   403,   438,  -144,  -244,  -244,  -244,  -244,
-     352,  -244,   430,   360,  -212,  -186,   429,   148,  -121,  -244,
-    -244,  -244,  -244,  -244,  -127,    -4,   132,  -244,  -244
+    -395,  -395,  -395,  -395,  -395,  -395,  -395,  -395,  -164,  -395,
+     349,   180,  -395,  -395,  -271,  -395,  -395,  -395,  -395,  -395,
+    -395,  -394,   209,  -395,  -395,  -395,  -395,  -395,  -395,  -395,
+    -395,    24,   -46,  -395,  -395,  -395,   301,  -395,   497,  -395,
+    -395,   435,   259,   433,   -28,   498,  -395,  -395,   397,  -395,
+     -90,  -395,  -395,  -207,   162,  -187,   -10,  -395,  -395,  -395,
+    -395,  -395,  -395,  -395,    60,    21,  -395,  -395,  -395,  -395,
+    -395,  -395,    84,    62,  -395,  -395,   -54,  -395,  -145,   282,
+     280,   382,   -35,   406,   412,   451,  -156,  -395,  -395,  -395,
+    -395,   355,  -395,   427,   359,  -232,  -203,   429,   129,  -128,
+    -395,  -395,  -395,  -395,  -395,  -136,    -4,  -395,  -395,  -395
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,    14,    15,    16,    17,    18,    19,    20,   183,   184,
-      95,   338,   339,   340,   248,   328,   329,   253,   402,   446,
-     506,   467,   468,   469,   470,   471,   399,   442,    21,    22,
-     181,   322,    23,    24,   165,   166,    25,    56,    26,    45,
-      46,   145,    28,    29,    43,    96,    97,    98,   149,    99,
-     303,   298,   219,   220,   292,   293,   221,   305,   374,   427,
-     458,   485,   486,   487,   307,   308,   378,   432,   433,   495,
-     528,   459,   460,   491,   512,   127,   128,   189,   190,   191,
-     192,   193,   101,   102,   103,   104,   105,   106,   107,   199,
-     200,   136,   137,   203,   236,   108,   211,   278,   109,   324,
-     275,   110,   154,   159,   171,   111,   390,    30,    31
+      -1,    14,    15,    16,    17,    18,    19,    20,   196,   197,
+     100,   367,   368,   369,   262,   357,   358,   273,   425,   468,
+     516,   265,   266,   267,   268,   269,   270,   422,   464,    21,
+      22,    65,   133,    23,    24,   177,   178,    25,    58,    26,
+      46,    47,   157,    28,    29,    44,   101,   102,   103,   161,
+     104,   323,   318,   232,   233,   312,   313,   234,   325,   403,
+     450,   480,   500,   501,   502,   327,   328,   407,   455,   456,
+     510,   536,   481,   482,   506,   522,   139,   140,   202,   203,
+     204,   205,   206,   106,   107,   108,   109,   110,   111,   112,
+     212,   213,   148,   149,   216,   249,   113,   224,   298,   114,
+     353,   295,   115,   166,   171,   183,   116,   351,    30,    31
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -1083,348 +1083,386 @@ static const yytype_int16 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      35,   197,    47,   196,   222,   194,   100,    44,    48,   277,
-     262,   327,   262,   194,   262,    33,   170,    34,   499,   492,
-     525,   310,   163,    33,   244,    34,    54,    33,    61,    34,
-     156,   157,    63,    64,    65,    66,    67,    54,   135,   500,
-      33,   352,    34,   300,   243,   151,   152,   151,   152,   120,
-     218,   245,   290,   262,    36,   260,   419,   146,   121,   131,
-      52,    58,   493,   526,    59,   194,    32,   194,   151,   152,
-      33,    38,    34,   222,   264,   265,   266,   267,   268,   269,
-     270,   271,   272,   273,   246,   151,   152,   331,   122,   259,
-     301,    10,   151,   152,    10,    37,   155,   395,   504,   291,
-     396,   397,   201,    47,   412,   213,   129,   247,   167,    48,
-     201,   172,   173,   100,    41,    39,   151,   152,   130,   218,
-     182,   185,   332,   330,   371,   353,   172,   235,    40,   420,
-     505,   323,   333,    55,   368,    10,    49,   413,   164,   494,
-     527,   194,   194,   274,   223,    42,   341,   405,   434,   226,
-     475,   261,   215,   158,   501,   222,   230,   443,    57,   231,
-     424,   281,   217,   428,   284,   242,   217,   280,   216,   415,
-     418,   334,   185,   134,   249,   250,   350,   302,   398,   229,
-     198,   198,   335,   381,   294,    60,   386,   336,   224,   151,
-     152,   295,   384,   358,   164,   194,   235,   523,   450,   296,
-      27,   218,   314,    62,   238,   337,   205,    33,   216,    34,
-     344,   345,   346,   223,    48,   387,   388,   524,    48,   430,
-     294,   297,   320,   222,   112,   431,    53,   295,   126,   321,
-     277,   206,  -133,   167,   113,   296,   348,   315,   351,   237,
-     425,   288,   114,   357,   389,   207,   208,   449,   325,   411,
-     360,   185,   194,    10,   362,   435,   436,   297,   438,   151,
-     152,   151,   152,   115,    50,   439,    51,   119,   209,   218,
-     123,   447,   347,   440,   489,   380,    33,   124,    34,   176,
-     177,   363,   116,   194,   125,   178,   179,    48,   240,   241,
-     210,   254,   255,   151,   152,   223,   279,   241,   490,    48,
-     151,   152,   311,   312,   126,   153,   354,   355,   132,   409,
-     379,   312,   235,   391,   392,   172,   393,   394,   437,   241,
-     133,   417,   481,   452,   312,   463,   241,   464,   241,   478,
-     312,   138,   407,   139,   194,   235,   479,   355,   235,   264,
-     265,   266,   267,   268,   269,   270,   271,   272,   273,   140,
-     151,   152,   497,   498,   520,   498,   530,   241,   537,   241,
-     539,   241,   141,   223,   142,   143,   144,    33,    68,    34,
-      69,   147,   148,   235,   519,   451,   150,   160,   172,   172,
-     169,   175,   180,   204,    70,    71,   232,   195,   214,   239,
-     325,   251,   461,   252,   531,   262,   285,   263,    73,    74,
-     276,   286,   536,   287,   289,   306,    75,    76,   274,   299,
-     304,   309,   477,   316,    77,    78,   319,    79,   317,   461,
-     326,   318,   233,    80,   349,   356,   361,   359,   367,    81,
-     369,   364,    82,   370,   372,   365,   366,   472,   373,   375,
-     376,   377,   385,   382,   476,   383,    83,    84,   163,   403,
-     400,   461,   401,   404,    85,   406,   414,    86,   410,   422,
-     416,   423,   429,   426,   441,   444,   448,   454,   502,   472,
-     445,   312,    87,    33,    68,    34,    69,   456,   462,   186,
-     508,   455,    88,    89,   457,   465,    90,    91,   473,   474,
-      70,    71,   517,   480,   472,    92,   483,   172,   488,   496,
-     511,    93,   484,   507,    73,    74,    94,   234,   513,   516,
-     514,   515,    75,    76,   521,   522,   529,   172,   532,   533,
-      77,    78,   534,    79,   535,   172,   540,   541,   542,    80,
-     408,   257,   503,   518,   187,    81,   117,   538,    82,   118,
-     313,   168,   421,   174,   509,   225,   482,   342,   162,   510,
-     343,   282,    83,    84,   227,    33,    68,    34,    69,   283,
-      85,   186,   228,    86,   453,   258,   202,     0,     0,     0,
-     212,   466,    70,    71,     0,     0,     0,     0,    87,     0,
-       0,     0,     0,     0,     0,    10,    73,    74,    88,    89,
-       0,     0,    90,    91,    75,    76,     0,     0,     0,     0,
-       0,    92,    77,    78,     0,    79,     0,    93,     0,     0,
-       0,    80,   188,     0,     0,     0,   187,    81,     0,     0,
-      82,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    83,    84,     0,    33,    68,    34,
-      69,     0,    85,     0,     0,    86,     0,     0,     0,     0,
-       0,     0,     0,     0,    70,    71,    72,     0,     0,     0,
-      87,     0,     0,     0,    33,    68,    34,    69,    73,    74,
-      88,    89,     0,     0,    90,    91,    75,    76,     0,     0,
-       0,    70,    71,    92,    77,    78,     0,    79,     0,    93,
-       0,     0,     0,    80,   188,    73,    74,     0,     0,    81,
-       0,     0,    82,    75,    76,     0,     0,     0,     0,     0,
-       0,    77,    78,     0,    79,     0,    83,    84,     0,     0,
-      80,     0,     0,     0,    85,     0,    81,    86,     0,    82,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    87,    83,    84,     0,     0,     0,     0,     0,
-       0,    85,    88,    89,    86,     0,    90,    91,     0,     0,
-       0,     0,     0,     0,     0,    92,     0,     0,     0,    87,
-       0,    93,     0,     0,     0,     0,    94,     0,     0,    88,
-      89,     0,     0,    90,    91,     0,     0,    33,    68,    34,
-      69,     0,    92,   134,     0,     0,     0,     0,    93,     0,
-       0,     0,     0,    94,    70,    71,     0,     0,     1,     0,
-       2,     0,     0,     0,    33,    68,    34,    69,    73,    74,
-       0,     0,     0,     0,     0,     0,    75,    76,     0,     0,
-       0,    70,    71,     0,    77,    78,     0,    79,     0,     3,
-       0,     0,     0,    80,     0,    73,    74,     0,     0,    81,
-       0,     0,    82,    75,    76,     4,     5,     0,     0,     0,
-       0,    77,    78,     6,    79,     0,    83,    84,     7,     0,
-      80,     0,     0,     0,    85,   187,    81,    86,     0,    82,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     8,
-       0,     0,    87,    83,    84,     0,     0,     0,     0,    10,
-       0,    85,    88,    89,    86,     0,    90,    91,     0,     0,
-       0,     0,     0,     0,     9,    92,     0,     0,     0,    87,
-       0,    93,     0,    10,     0,     0,    94,     0,     0,    88,
-      89,     0,     0,    90,    91,     0,    11,    33,    68,    34,
-      69,     0,    92,    12,     0,     0,    13,     0,    93,     0,
-       0,     0,     0,   188,    70,   161,     0,     0,     0,     0,
-       0,     0,     0,     0,    33,    68,    34,    69,    73,    74,
-       0,     0,     0,     0,     0,     0,    75,    76,     0,     0,
-       0,    70,    71,     0,    77,    78,     0,    79,     0,     0,
-       0,     0,     0,    80,     0,    73,    74,     0,     0,    81,
-       0,     0,    82,    75,    76,     0,     0,     0,     0,     0,
-       0,    77,    78,     0,    79,     0,    83,    84,     0,     0,
-      80,     0,     0,     0,    85,     0,    81,    86,     0,    82,
+      36,   210,    48,   356,   235,   297,   209,    45,    49,   105,
+     207,    33,   282,    34,   330,    56,   282,    33,   207,    34,
+     175,   135,    33,   310,    34,   257,    56,   282,    63,   182,
+      56,   126,   214,    68,    69,    70,    71,    72,    33,   342,
+      34,   343,   321,   127,   143,   147,   168,   169,   320,   163,
+     164,   282,    37,   507,   163,   164,   280,    32,   163,   164,
+      67,   381,   344,   533,   158,   514,    66,    41,    42,   487,
+     231,   207,   128,   207,   235,   284,   285,   286,   287,   288,
+     289,   290,   291,   292,   293,    39,   163,   164,   194,    33,
+      40,    34,   163,   164,   513,    38,   508,   515,    43,   345,
+      60,   167,   129,    61,   442,   146,   534,   237,    48,    50,
+     279,   359,   397,   179,    49,   531,   184,    59,   186,   226,
+      64,    10,   214,   251,    62,   258,    64,   105,   346,   347,
+     322,   228,   195,   198,    57,   532,   400,   176,   184,   255,
+     231,   248,   294,   382,   352,   185,   436,   176,   118,   370,
+     259,   230,   465,   457,   207,   207,   236,   230,   256,   428,
+     348,   239,   242,   235,   490,   300,   281,   211,   243,   447,
+     170,   244,   451,   229,   509,     1,   301,     2,   349,   304,
+     443,   438,   441,   260,   535,   198,   119,   263,   264,   271,
+      33,   410,    34,   387,   138,   211,    53,   117,   360,    10,
+      33,   472,    34,   413,   379,   250,     3,   120,   207,   261,
+     229,   248,    10,   415,   453,   130,   131,   334,   218,   311,
+     454,   418,     4,     5,   419,   420,   236,    49,    54,   231,
+       6,    49,   314,   361,     7,   122,   297,   163,   164,   315,
+     235,   219,    51,   362,    52,   125,   179,   316,   163,   164,
+     335,   189,   190,   132,     8,   220,   221,   448,   377,    27,
+     380,   504,    10,    35,   136,   386,   134,   350,   354,   317,
+     137,   198,   389,   138,   207,   458,   459,   144,   222,     9,
+     363,   145,   469,   150,   505,    55,   434,   308,    10,   462,
+      10,   364,   151,   373,   374,   375,   365,   409,   152,   207,
+     421,   392,   153,   223,    11,   391,   231,    49,   141,   191,
+     192,    12,   121,   156,    13,   236,   154,   366,   159,    49,
+     142,   155,   284,   285,   286,   287,   288,   289,   290,   291,
+     292,   293,   496,   163,   164,   184,   160,   271,   162,   314,
+     432,   172,    33,   248,    34,   184,   315,   253,   254,   207,
+     435,  -138,   440,   376,   316,   471,   274,   275,   181,   163,
+     164,   430,   163,   164,   299,   254,   248,   163,   164,   248,
+     188,   165,   163,   164,   331,   332,   317,   340,   341,   383,
+     384,   408,   332,   416,   417,   460,   254,   461,   254,   294,
+     474,   332,   236,   538,   485,   254,   486,   254,   248,   193,
+     473,   543,    33,    73,    34,    74,   208,   184,   184,   493,
+     332,   494,   384,   354,   512,   341,   217,   483,   227,    75,
+      76,   245,   528,   341,   544,   254,   546,   254,   252,   272,
+     282,   305,   283,    78,    79,   296,   492,   306,   307,   309,
+     329,    80,    81,   483,   319,   324,   326,   336,   339,    82,
+      83,   337,    84,   338,   355,   378,   246,    85,   385,   271,
+     390,   388,    86,   396,   398,    87,   491,   393,   483,   399,
+     394,   395,   401,   404,   405,   402,   406,   411,   412,    88,
+      89,   175,   423,   426,   271,   424,   427,    90,   429,   433,
+      91,   445,   449,   437,   439,   518,   446,   452,   463,   466,
+     470,   467,   476,   477,   332,    92,   478,   527,   479,   484,
+     489,   498,   499,   511,   521,    93,   495,   524,    94,   488,
+     523,    95,    96,   503,   526,   184,   517,   525,   529,   530,
+     537,    97,   539,   184,   540,   542,   541,    98,    33,    73,
+      34,    74,    99,   247,   199,   547,   549,   277,   431,   548,
+     414,   333,   123,   180,   124,    75,    76,   187,   444,   238,
+     545,   519,   497,   372,   371,   520,   174,   302,   475,    78,
+      79,   303,   240,     0,     0,   215,     0,    80,    81,     0,
+       0,   278,   225,   241,     0,    82,    83,     0,    84,     0,
+       0,     0,     0,    85,     0,     0,     0,   200,    86,     0,
+       0,    87,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    88,    89,     0,     0,     0,
+       0,     0,     0,    90,     0,     0,    91,     0,     0,    33,
+      73,    34,    74,     0,     0,   199,     0,     0,     0,     0,
+       0,    92,     0,     0,     0,     0,    75,    76,    10,     0,
+       0,    93,     0,     0,    94,     0,     0,    95,    96,     0,
+      78,    79,     0,     0,     0,     0,     0,    97,    80,    81,
+       0,     0,     0,    98,     0,     0,    82,    83,   201,    84,
+       0,     0,     0,     0,    85,     0,     0,     0,   200,    86,
+       0,     0,    87,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    88,    89,     0,     0,
+       0,     0,     0,     0,    90,     0,     0,    91,     0,     0,
+      33,    73,    34,    74,     0,     0,     0,     0,     0,     0,
+       0,     0,    92,     0,     0,     0,     0,    75,    76,    77,
+       0,     0,    93,     0,     0,    94,     0,     0,    95,    96,
+       0,    78,    79,     0,     0,     0,     0,     0,    97,    80,
+      81,     0,     0,     0,    98,     0,     0,    82,    83,   201,
+      84,     0,     0,     0,     0,    85,     0,     0,     0,     0,
+      86,     0,     0,    87,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    88,    89,     0,
+       0,     0,     0,     0,     0,    90,     0,     0,    91,     0,
+       0,    33,    73,    34,    74,     0,     0,     0,     0,     0,
+       0,     0,     0,    92,     0,     0,     0,     0,    75,    76,
+       0,     0,     0,    93,     0,     0,    94,     0,     0,    95,
+      96,     0,    78,    79,     0,     0,     0,     0,     0,    97,
+      80,    81,     0,     0,     0,    98,     0,     0,    82,    83,
+      99,    84,     0,     0,     0,     0,    85,     0,     0,     0,
+       0,    86,     0,     0,    87,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    88,    89,
+       0,     0,     0,     0,     0,     0,    90,     0,     0,    91,
+       0,     0,     0,     0,     0,    33,    73,    34,    74,     0,
+       0,     0,     0,     0,    92,     0,     0,     0,     0,     0,
+       0,     0,    75,    76,    93,     0,     0,    94,     0,     0,
+      95,    96,     0,     0,     0,     0,    78,    79,     0,     0,
+      97,   146,     0,     0,    80,    81,    98,     0,     0,     0,
+       0,    99,    82,    83,     0,    84,     0,     0,     0,     0,
+      85,     0,     0,     0,     0,    86,     0,     0,    87,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    87,    83,    84,     0,     0,    68,     0,    69,
-       0,    85,    88,    89,    86,     0,    90,    91,     0,     0,
-       0,     0,     0,    70,   161,    92,     0,     0,     0,    87,
-       0,    93,     0,     0,     0,     0,    94,    73,    74,    88,
-      89,     0,     0,    90,    91,     0,    76,     0,     0,     0,
-       0,     0,    92,    77,    78,     0,    79,     0,    93,     0,
-       0,     0,    80,    94,    73,    74,     0,     0,     0,     0,
-       0,    82,     0,    76,     0,     0,     0,     0,     0,     0,
-      77,    78,     0,    79,     0,    83,    84,     0,     0,    80,
-       0,     0,     0,    85,     0,     0,    86,     0,    82,     0,
+       0,     0,    88,    89,     0,     0,     0,     0,     0,     0,
+      90,     0,     0,    91,     0,     0,    33,    73,    34,    74,
+       0,     0,     0,     0,     0,     0,     0,     0,    92,     0,
+       0,     0,     0,    75,    76,    10,     0,     0,    93,     0,
+       0,    94,     0,     0,    95,    96,     0,    78,    79,     0,
+       0,     0,     0,     0,    97,    80,    81,     0,     0,     0,
+      98,     0,     0,    82,    83,    99,    84,     0,     0,     0,
+       0,    85,     0,     0,     0,   200,    86,     0,     0,    87,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    87,    83,   256,     0,     0,     0,     0,     0,     0,
-      85,    88,     0,     0,     0,    90,    91,     0,     0,     0,
-       0,     0,     0,     0,    92,     0,     0,     0,    87,     0,
-      93,     0,     0,     0,     0,     0,     0,     0,    88,     0,
-       0,     0,    90,    91,     0,     0,     0,     0,     0,     0,
-       0,    92,     0,     0,     0,     0,     0,    93
+       0,     0,     0,    88,    89,     0,     0,     0,     0,     0,
+       0,    90,     0,     0,    91,     0,     0,    33,    73,    34,
+      74,     0,     0,     0,     0,     0,     0,     0,     0,    92,
+       0,     0,     0,     0,    75,   173,     0,     0,     0,    93,
+       0,     0,    94,     0,     0,    95,    96,     0,    78,    79,
+       0,     0,     0,     0,     0,    97,    80,    81,     0,     0,
+       0,    98,     0,     0,    82,    83,   201,    84,     0,     0,
+       0,     0,    85,     0,     0,     0,     0,    86,     0,     0,
+      87,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    88,    89,     0,     0,     0,     0,
+       0,     0,    90,     0,     0,    91,     0,     0,    33,    73,
+      34,    74,     0,     0,     0,     0,     0,     0,     0,     0,
+      92,     0,     0,     0,     0,    75,    76,     0,     0,     0,
+      93,     0,     0,    94,     0,     0,    95,    96,     0,    78,
+      79,     0,     0,     0,     0,     0,    97,    80,    81,     0,
+       0,     0,    98,     0,     0,    82,    83,    99,    84,     0,
+       0,     0,     0,    85,     0,     0,     0,     0,    86,     0,
+       0,    87,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    88,    89,    73,     0,    74,
+       0,     0,     0,    90,     0,     0,    91,     0,     0,     0,
+       0,     0,     0,    75,   173,     0,    78,    79,     0,     0,
+       0,    92,     0,     0,     0,    81,     0,    78,    79,     0,
+       0,    93,    82,    83,    94,    84,    81,    95,    96,     0,
+      85,     0,     0,    82,    83,     0,    84,    97,    87,     0,
+       0,    85,     0,    98,     0,     0,     0,     0,    99,    87,
+       0,     0,    88,   276,     0,     0,     0,     0,     0,     0,
+      90,     0,     0,    88,    89,     0,     0,     0,     0,     0,
+       0,    90,     0,     0,    91,     0,     0,     0,    92,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    93,    92,
+       0,     0,     0,     0,    95,    96,     0,     0,     0,    93,
+       0,     0,     0,     0,    97,    95,    96,     0,     0,     0,
+      98,     0,     0,     0,     0,    97,     0,     0,     0,     0,
+       0,    98
 };
 
 static const yytype_int16 yycheck[] =
 {
-       4,   134,    12,   130,   148,   126,    43,    11,    12,   195,
-       8,   254,     8,   134,     8,     4,   114,     6,     7,     7,
-       7,   233,    27,     4,    45,     6,    29,     4,    32,     6,
-      23,    24,    36,    37,    38,    39,    40,    29,    75,    28,
-       4,    10,     6,   222,   176,    21,    22,    21,    22,    57,
-     148,    72,   217,     8,    80,   188,    71,    94,    31,    67,
-      82,   139,    50,    50,   142,   186,   121,   188,    21,    22,
-       4,    73,     6,   217,    10,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,   105,    21,    22,    10,    61,   187,
-      39,   116,    21,    22,   116,   121,   100,    37,    76,    33,
-      40,    41,    62,   113,     9,   142,   131,   128,   112,   113,
-      62,   115,   116,   150,    28,   121,    21,    22,   143,   217,
-     124,   125,    45,   255,   303,    94,   130,   164,    85,   144,
-     108,   252,    55,   136,   299,   116,     0,   349,   143,   127,
-     127,   262,   263,    79,   148,    59,   144,   333,   144,   153,
-     144,   188,   144,   146,   143,   299,   160,   400,    30,   163,
-     372,   198,   143,   375,   201,   173,   143,   122,   144,   355,
-     144,    94,   176,   133,   178,   179,   274,   126,   118,   143,
-     133,   133,   105,   316,    74,     3,    67,   110,   149,    21,
-      22,    81,   319,   122,   143,   316,   233,    68,   410,    89,
-       0,   299,   239,    73,   165,   128,    53,     4,   144,     6,
-      17,    18,    19,   217,   218,    96,    97,    88,   222,   108,
-      74,   111,    57,   367,   117,   114,    26,    81,   134,    64,
-     416,    78,    86,   237,   145,    89,   273,   241,   275,   145,
-     373,    73,    33,   280,   125,    92,    93,     9,   252,   347,
-     287,   255,   373,   116,   144,   382,   383,   111,    57,    21,
-      22,    21,    22,   143,   139,    64,   141,   106,   115,   367,
-       5,   404,    79,   394,    34,   312,     4,    97,     6,    46,
-      47,   291,    85,   404,   143,    46,    47,   291,   144,   145,
-     137,   144,   145,    21,    22,   299,   144,   145,    58,   303,
-      21,    22,   144,   145,   134,    33,   144,   145,     7,   346,
-     144,   145,   349,   144,   145,   319,   144,   145,   144,   145,
-       7,   358,   455,   144,   145,   144,   145,   144,   145,   144,
-     145,   143,   336,    84,   455,   372,   144,   145,   375,    10,
-      11,    12,    13,    14,    15,    16,    17,    18,    19,   143,
-      21,    22,   144,   145,   144,   145,   144,   145,   144,   145,
-     144,   145,     5,   367,   143,   143,    84,     4,     5,     6,
-       7,     5,    73,   410,   501,   412,   145,   100,   382,   383,
-     143,     7,   136,     7,    21,    22,    23,   143,     7,    11,
-     394,   143,   429,   143,   521,     8,    63,     9,    35,    36,
-      20,   144,   529,    73,   144,   101,    43,    44,    79,   145,
-      75,   144,   449,   143,    51,    52,   143,    54,    87,   456,
-     130,    87,    59,    60,   143,   131,     7,    63,    86,    66,
-       7,    99,    69,     7,    42,    99,    99,   441,    77,    42,
-     144,    98,     5,   143,   448,   143,    83,    84,    27,    94,
-     145,   488,   136,   143,    91,    87,    94,    94,   143,   103,
-     143,   103,    42,    98,   143,    38,   143,     7,   472,   473,
-     101,   145,   109,     4,     5,     6,     7,    42,    19,    10,
-     484,    97,   119,   120,    90,     5,   123,   124,   143,    42,
-      21,    22,   496,   144,   498,   132,     7,   501,   145,   110,
-      95,   138,   135,   144,    35,    36,   143,   144,   104,     9,
-     112,   104,    43,    44,   143,    33,   143,   521,   143,    70,
-      51,    52,   112,    54,    70,   529,   102,   144,     7,    60,
-     339,   185,   473,   498,    65,    66,    53,   532,    69,    54,
-     237,   113,   367,   118,   486,   150,   456,   262,   110,   488,
-     263,   199,    83,    84,   154,     4,     5,     6,     7,   199,
-      91,    10,   159,    94,   416,   186,   136,    -1,    -1,    -1,
-     141,   439,    21,    22,    -1,    -1,    -1,    -1,   109,    -1,
-      -1,    -1,    -1,    -1,    -1,   116,    35,    36,   119,   120,
-      -1,    -1,   123,   124,    43,    44,    -1,    -1,    -1,    -1,
-      -1,   132,    51,    52,    -1,    54,    -1,   138,    -1,    -1,
-      -1,    60,   143,    -1,    -1,    -1,    65,    66,    -1,    -1,
-      69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    83,    84,    -1,     4,     5,     6,
-       7,    -1,    91,    -1,    -1,    94,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    21,    22,    23,    -1,    -1,    -1,
-     109,    -1,    -1,    -1,     4,     5,     6,     7,    35,    36,
-     119,   120,    -1,    -1,   123,   124,    43,    44,    -1,    -1,
-      -1,    21,    22,   132,    51,    52,    -1,    54,    -1,   138,
-      -1,    -1,    -1,    60,   143,    35,    36,    -1,    -1,    66,
-      -1,    -1,    69,    43,    44,    -1,    -1,    -1,    -1,    -1,
-      -1,    51,    52,    -1,    54,    -1,    83,    84,    -1,    -1,
-      60,    -1,    -1,    -1,    91,    -1,    66,    94,    -1,    69,
+       4,   146,    12,   274,   160,   208,   142,    11,    12,    44,
+     138,     4,     8,     6,   246,    29,     8,     4,   146,     6,
+      27,    67,     4,   230,     6,   189,    29,     8,    32,   119,
+      29,    59,    61,    37,    38,    39,    40,    41,     4,     5,
+       6,     7,    39,    31,    72,    80,    23,    24,   235,    21,
+      22,     8,    78,     7,    21,    22,   201,   121,    21,    22,
+      36,    10,    28,     7,    99,    74,    71,    83,    28,   463,
+     160,   199,    60,   201,   230,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    71,    21,    22,   134,     4,
+     121,     6,    21,    22,   488,   121,    50,   106,    58,    65,
+     140,   105,     5,   143,    69,   134,    50,   161,   118,     0,
+     200,   275,   319,   117,   118,    66,   120,    30,   122,   154,
+     125,   114,    61,   177,     3,    45,   125,   162,    94,    95,
+     127,   145,   136,   137,   137,    86,   323,   144,   142,   185,
+     230,   176,    77,    92,   272,   121,   378,   144,   146,   145,
+      70,   144,   423,   145,   282,   283,   160,   144,   186,   362,
+     126,   165,   144,   319,   145,   122,   201,   134,   172,   401,
+     147,   175,   404,   145,   128,     1,   211,     3,   144,   214,
+     145,   384,   145,   103,   128,   189,    33,   191,   192,   193,
+       4,   336,     6,   122,   135,   134,    48,   115,    10,   114,
+       4,   433,     6,   339,   294,   146,    32,   144,   336,   129,
+     145,   246,   114,   349,   106,   118,   119,   252,    53,    33,
+     112,    37,    48,    49,    40,    41,   230,   231,    80,   319,
+      56,   235,    72,    45,    60,    83,   439,    21,    22,    79,
+     396,    76,   140,    55,   142,   104,   250,    87,    21,    22,
+     254,    46,    47,   137,    80,    90,    91,   402,   293,     0,
+     295,    34,   114,     4,    95,   300,     5,   271,   272,   109,
+     144,   275,   307,   135,   402,   411,   412,     7,   113,   105,
+      92,     7,   427,   144,    57,    26,   376,    71,   114,   417,
+     114,   103,    82,    17,    18,    19,   108,   332,   144,   427,
+     116,   311,     5,   138,   130,   145,   396,   311,   132,    46,
+      47,   137,    53,    82,   140,   319,   144,   129,     5,   323,
+     144,   144,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,   477,    21,    22,   339,    71,   341,   146,    72,
+     375,    98,     4,   378,     6,   349,    79,   145,   146,   477,
+       9,    84,   387,    77,    87,     9,   145,   146,   144,    21,
+      22,   365,    21,    22,   145,   146,   401,    21,    22,   404,
+       7,    33,    21,    22,   145,   146,   109,   145,   146,   145,
+     146,   145,   146,   145,   146,   145,   146,   145,   146,    77,
+     145,   146,   396,   529,   145,   146,   145,   146,   433,   144,
+     435,   537,     4,     5,     6,     7,   144,   411,   412,   145,
+     146,   145,   146,   417,   145,   146,     7,   452,     7,    21,
+      22,    23,   145,   146,   145,   146,   145,   146,    11,   144,
+       8,    62,     9,    35,    36,    20,   471,   145,    71,   145,
+     145,    43,    44,   478,   146,    73,    99,   144,   144,    51,
+      52,    85,    54,    85,   131,   144,    58,    59,   132,   463,
+       7,    62,    64,    84,     7,    67,   470,    97,   503,     7,
+      97,    97,    42,    42,   145,    75,    96,   144,   144,    81,
+      82,    27,   146,    92,   488,   137,   144,    89,    85,   144,
+      92,   101,    96,    92,   144,   499,   101,    42,   144,    38,
+     144,    99,     7,    95,   146,   107,    42,   511,    88,    19,
+      42,     7,   136,   108,    93,   117,   145,   110,   120,   144,
+     102,   123,   124,   146,     9,   529,   145,   102,   144,    33,
+     144,   133,   144,   537,    68,    68,   110,   139,     4,     5,
+       6,     7,   144,   145,    10,   100,     7,   198,   368,   145,
+     341,   250,    55,   118,    56,    21,    22,   124,   396,   162,
+     539,   501,   478,   283,   282,   503,   115,   212,   439,    35,
+      36,   212,   166,    -1,    -1,   148,    -1,    43,    44,    -1,
+      -1,   199,   153,   171,    -1,    51,    52,    -1,    54,    -1,
+      -1,    -1,    -1,    59,    -1,    -1,    -1,    63,    64,    -1,
+      -1,    67,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    81,    82,    -1,    -1,    -1,
+      -1,    -1,    -1,    89,    -1,    -1,    92,    -1,    -1,     4,
+       5,     6,     7,    -1,    -1,    10,    -1,    -1,    -1,    -1,
+      -1,   107,    -1,    -1,    -1,    -1,    21,    22,   114,    -1,
+      -1,   117,    -1,    -1,   120,    -1,    -1,   123,   124,    -1,
+      35,    36,    -1,    -1,    -1,    -1,    -1,   133,    43,    44,
+      -1,    -1,    -1,   139,    -1,    -1,    51,    52,   144,    54,
+      -1,    -1,    -1,    -1,    59,    -1,    -1,    -1,    63,    64,
+      -1,    -1,    67,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    81,    82,    -1,    -1,
+      -1,    -1,    -1,    -1,    89,    -1,    -1,    92,    -1,    -1,
+       4,     5,     6,     7,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   107,    -1,    -1,    -1,    -1,    21,    22,    23,
+      -1,    -1,   117,    -1,    -1,   120,    -1,    -1,   123,   124,
+      -1,    35,    36,    -1,    -1,    -1,    -1,    -1,   133,    43,
+      44,    -1,    -1,    -1,   139,    -1,    -1,    51,    52,   144,
+      54,    -1,    -1,    -1,    -1,    59,    -1,    -1,    -1,    -1,
+      64,    -1,    -1,    67,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    81,    82,    -1,
+      -1,    -1,    -1,    -1,    -1,    89,    -1,    -1,    92,    -1,
+      -1,     4,     5,     6,     7,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   107,    -1,    -1,    -1,    -1,    21,    22,
+      -1,    -1,    -1,   117,    -1,    -1,   120,    -1,    -1,   123,
+     124,    -1,    35,    36,    -1,    -1,    -1,    -1,    -1,   133,
+      43,    44,    -1,    -1,    -1,   139,    -1,    -1,    51,    52,
+     144,    54,    -1,    -1,    -1,    -1,    59,    -1,    -1,    -1,
+      -1,    64,    -1,    -1,    67,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    81,    82,
+      -1,    -1,    -1,    -1,    -1,    -1,    89,    -1,    -1,    92,
+      -1,    -1,    -1,    -1,    -1,     4,     5,     6,     7,    -1,
+      -1,    -1,    -1,    -1,   107,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    21,    22,   117,    -1,    -1,   120,    -1,    -1,
+     123,   124,    -1,    -1,    -1,    -1,    35,    36,    -1,    -1,
+     133,   134,    -1,    -1,    43,    44,   139,    -1,    -1,    -1,
+      -1,   144,    51,    52,    -1,    54,    -1,    -1,    -1,    -1,
+      59,    -1,    -1,    -1,    -1,    64,    -1,    -1,    67,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,   109,    83,    84,    -1,    -1,    -1,    -1,    -1,
-      -1,    91,   119,   120,    94,    -1,   123,   124,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,   132,    -1,    -1,    -1,   109,
-      -1,   138,    -1,    -1,    -1,    -1,   143,    -1,    -1,   119,
-     120,    -1,    -1,   123,   124,    -1,    -1,     4,     5,     6,
-       7,    -1,   132,   133,    -1,    -1,    -1,    -1,   138,    -1,
-      -1,    -1,    -1,   143,    21,    22,    -1,    -1,     1,    -1,
-       3,    -1,    -1,    -1,     4,     5,     6,     7,    35,    36,
-      -1,    -1,    -1,    -1,    -1,    -1,    43,    44,    -1,    -1,
-      -1,    21,    22,    -1,    51,    52,    -1,    54,    -1,    32,
-      -1,    -1,    -1,    60,    -1,    35,    36,    -1,    -1,    66,
-      -1,    -1,    69,    43,    44,    48,    49,    -1,    -1,    -1,
-      -1,    51,    52,    56,    54,    -1,    83,    84,    61,    -1,
-      60,    -1,    -1,    -1,    91,    65,    66,    94,    -1,    69,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    82,
-      -1,    -1,   109,    83,    84,    -1,    -1,    -1,    -1,   116,
-      -1,    91,   119,   120,    94,    -1,   123,   124,    -1,    -1,
-      -1,    -1,    -1,    -1,   107,   132,    -1,    -1,    -1,   109,
-      -1,   138,    -1,   116,    -1,    -1,   143,    -1,    -1,   119,
-     120,    -1,    -1,   123,   124,    -1,   129,     4,     5,     6,
-       7,    -1,   132,   136,    -1,    -1,   139,    -1,   138,    -1,
-      -1,    -1,    -1,   143,    21,    22,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,     4,     5,     6,     7,    35,    36,
-      -1,    -1,    -1,    -1,    -1,    -1,    43,    44,    -1,    -1,
-      -1,    21,    22,    -1,    51,    52,    -1,    54,    -1,    -1,
-      -1,    -1,    -1,    60,    -1,    35,    36,    -1,    -1,    66,
-      -1,    -1,    69,    43,    44,    -1,    -1,    -1,    -1,    -1,
-      -1,    51,    52,    -1,    54,    -1,    83,    84,    -1,    -1,
-      60,    -1,    -1,    -1,    91,    -1,    66,    94,    -1,    69,
+      -1,    -1,    81,    82,    -1,    -1,    -1,    -1,    -1,    -1,
+      89,    -1,    -1,    92,    -1,    -1,     4,     5,     6,     7,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   107,    -1,
+      -1,    -1,    -1,    21,    22,   114,    -1,    -1,   117,    -1,
+      -1,   120,    -1,    -1,   123,   124,    -1,    35,    36,    -1,
+      -1,    -1,    -1,    -1,   133,    43,    44,    -1,    -1,    -1,
+     139,    -1,    -1,    51,    52,   144,    54,    -1,    -1,    -1,
+      -1,    59,    -1,    -1,    -1,    63,    64,    -1,    -1,    67,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,   109,    83,    84,    -1,    -1,     5,    -1,     7,
-      -1,    91,   119,   120,    94,    -1,   123,   124,    -1,    -1,
-      -1,    -1,    -1,    21,    22,   132,    -1,    -1,    -1,   109,
-      -1,   138,    -1,    -1,    -1,    -1,   143,    35,    36,   119,
-     120,    -1,    -1,   123,   124,    -1,    44,    -1,    -1,    -1,
-      -1,    -1,   132,    51,    52,    -1,    54,    -1,   138,    -1,
-      -1,    -1,    60,   143,    35,    36,    -1,    -1,    -1,    -1,
-      -1,    69,    -1,    44,    -1,    -1,    -1,    -1,    -1,    -1,
-      51,    52,    -1,    54,    -1,    83,    84,    -1,    -1,    60,
-      -1,    -1,    -1,    91,    -1,    -1,    94,    -1,    69,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   109,    83,    84,    -1,    -1,    -1,    -1,    -1,    -1,
-      91,   119,    -1,    -1,    -1,   123,   124,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,   132,    -1,    -1,    -1,   109,    -1,
-     138,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   119,    -1,
-      -1,    -1,   123,   124,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   132,    -1,    -1,    -1,    -1,    -1,   138
+      -1,    -1,    -1,    81,    82,    -1,    -1,    -1,    -1,    -1,
+      -1,    89,    -1,    -1,    92,    -1,    -1,     4,     5,     6,
+       7,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   107,
+      -1,    -1,    -1,    -1,    21,    22,    -1,    -1,    -1,   117,
+      -1,    -1,   120,    -1,    -1,   123,   124,    -1,    35,    36,
+      -1,    -1,    -1,    -1,    -1,   133,    43,    44,    -1,    -1,
+      -1,   139,    -1,    -1,    51,    52,   144,    54,    -1,    -1,
+      -1,    -1,    59,    -1,    -1,    -1,    -1,    64,    -1,    -1,
+      67,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    81,    82,    -1,    -1,    -1,    -1,
+      -1,    -1,    89,    -1,    -1,    92,    -1,    -1,     4,     5,
+       6,     7,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     107,    -1,    -1,    -1,    -1,    21,    22,    -1,    -1,    -1,
+     117,    -1,    -1,   120,    -1,    -1,   123,   124,    -1,    35,
+      36,    -1,    -1,    -1,    -1,    -1,   133,    43,    44,    -1,
+      -1,    -1,   139,    -1,    -1,    51,    52,   144,    54,    -1,
+      -1,    -1,    -1,    59,    -1,    -1,    -1,    -1,    64,    -1,
+      -1,    67,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    81,    82,     5,    -1,     7,
+      -1,    -1,    -1,    89,    -1,    -1,    92,    -1,    -1,    -1,
+      -1,    -1,    -1,    21,    22,    -1,    35,    36,    -1,    -1,
+      -1,   107,    -1,    -1,    -1,    44,    -1,    35,    36,    -1,
+      -1,   117,    51,    52,   120,    54,    44,   123,   124,    -1,
+      59,    -1,    -1,    51,    52,    -1,    54,   133,    67,    -1,
+      -1,    59,    -1,   139,    -1,    -1,    -1,    -1,   144,    67,
+      -1,    -1,    81,    82,    -1,    -1,    -1,    -1,    -1,    -1,
+      89,    -1,    -1,    81,    82,    -1,    -1,    -1,    -1,    -1,
+      -1,    89,    -1,    -1,    92,    -1,    -1,    -1,   107,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   117,   107,
+      -1,    -1,    -1,    -1,   123,   124,    -1,    -1,    -1,   117,
+      -1,    -1,    -1,    -1,   133,   123,   124,    -1,    -1,    -1,
+     139,    -1,    -1,    -1,    -1,   133,    -1,    -1,    -1,    -1,
+      -1,   139
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
-static const yytype_uint8 yystos[] =
+static const yytype_uint16 yystos[] =
 {
-       0,     1,     3,    32,    48,    49,    56,    61,    82,   107,
-     116,   129,   136,   139,   148,   149,   150,   151,   152,   153,
-     154,   175,   176,   179,   180,   183,   185,   188,   189,   190,
-     254,   255,   121,     4,     6,   252,    80,   121,    73,   121,
-      85,    28,    59,   191,   252,   186,   187,   202,   252,     0,
-     139,   141,    82,   188,    29,   136,   184,    30,   139,   142,
-       3,   252,    73,   252,   252,   252,   252,   252,     5,     7,
-      21,    22,    23,    35,    36,    43,    44,    51,    52,    54,
-      60,    66,    69,    83,    84,    91,    94,   109,   119,   120,
-     123,   124,   132,   138,   143,   157,   192,   193,   194,   196,
-     228,   229,   230,   231,   232,   233,   234,   235,   242,   245,
-     248,   252,   117,   145,    33,   143,    85,   184,   191,   106,
-     190,    31,    61,     5,    97,   143,   134,   222,   223,   131,
-     143,   190,     7,     7,   133,   228,   238,   239,   143,    84,
-     143,     5,   143,   143,    84,   188,   228,     5,    73,   195,
-     145,    21,    22,    33,   249,   252,    23,    24,   146,   250,
-     100,    22,   231,    27,   143,   181,   182,   252,   187,   143,
-     196,   251,   252,   252,   189,     7,    46,    47,    46,    47,
-     136,   177,   252,   155,   156,   252,    10,    65,   143,   224,
-     225,   226,   227,   228,   245,   143,   251,   224,   133,   236,
-     237,    62,   239,   240,     7,    53,    78,    92,    93,   115,
-     137,   243,   243,   228,     7,   144,   144,   143,   196,   199,
-     200,   203,   232,   252,   222,   194,   252,   229,   230,   143,
-     252,   252,    23,    59,   144,   228,   241,   145,   222,    11,
-     144,   145,   190,   155,    45,    72,   105,   128,   161,   252,
-     252,   143,   143,   164,   144,   145,    84,   157,   227,   196,
-     224,   228,     8,     9,    10,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,    79,   247,    20,   242,   244,   144,
-     122,   228,   237,   240,   228,    63,   144,    73,    73,   144,
-     199,    33,   201,   202,    74,    81,    89,   111,   198,   145,
-     201,    39,   126,   197,    75,   204,   101,   211,   212,   144,
-     241,   144,   145,   182,   228,   252,   143,    87,    87,   143,
-      57,    64,   178,   245,   246,   252,   130,   161,   162,   163,
-     155,    10,    45,    55,    94,   105,   110,   128,   158,   159,
-     160,   144,   225,   226,    17,    18,    19,    79,   228,   143,
-     196,   228,    10,    94,   144,   145,   131,   228,   122,    63,
-     228,     7,   144,   202,    99,    99,    99,    86,   199,     7,
-       7,   201,    42,    77,   205,    42,   144,    98,   213,   144,
-     228,   224,   143,   143,   251,     5,    67,    96,    97,   125,
-     253,   144,   145,   144,   145,    37,    40,    41,   118,   173,
-     145,   136,   165,    94,   143,   242,    87,   252,   158,   228,
-     143,   196,     9,   241,    94,   242,   143,   228,   144,    71,
-     144,   200,   103,   103,   241,   224,    98,   206,   241,    42,
-     108,   114,   214,   215,   144,   251,   251,   144,    57,    64,
-     245,   143,   174,   161,    38,   101,   166,   224,   143,     9,
-     241,   228,   144,   244,     7,    97,    42,    90,   207,   218,
-     219,   228,    19,   144,   144,     5,   253,   168,   169,   170,
-     171,   172,   252,   143,    42,   144,   252,   228,   144,   144,
-     144,   224,   218,     7,   135,   208,   209,   210,   145,    34,
-      58,   220,     7,    50,   127,   216,   110,   144,   145,     7,
-      28,   143,   252,   168,    76,   108,   167,   144,   252,   210,
-     219,    95,   221,   104,   112,   104,     9,   252,   169,   251,
-     144,   143,    33,    68,    88,     7,    50,   127,   217,   143,
-     144,   251,   143,    70,   112,    70,   251,   144,   211,   144,
-     102,   144,     7
+       0,     1,     3,    32,    48,    49,    56,    60,    80,   105,
+     114,   130,   137,   140,   149,   150,   151,   152,   153,   154,
+     155,   177,   178,   181,   182,   185,   187,   190,   191,   192,
+     256,   257,   121,     4,     6,   190,   254,    78,   121,    71,
+     121,    83,    28,    58,   193,   254,   188,   189,   204,   254,
+       0,   140,   142,    48,    80,   190,    29,   137,   186,    30,
+     140,   143,     3,   254,   125,   179,    71,   179,   254,   254,
+     254,   254,   254,     5,     7,    21,    22,    23,    35,    36,
+      43,    44,    51,    52,    54,    59,    64,    67,    81,    82,
+      89,    92,   107,   117,   120,   123,   124,   133,   139,   144,
+     158,   194,   195,   196,   198,   230,   231,   232,   233,   234,
+     235,   236,   237,   244,   247,   250,   254,   115,   146,    33,
+     144,   190,    83,   186,   193,   104,   192,    31,    60,     5,
+     118,   119,   137,   180,     5,   180,    95,   144,   135,   224,
+     225,   132,   144,   192,     7,     7,   134,   230,   240,   241,
+     144,    82,   144,     5,   144,   144,    82,   190,   230,     5,
+      71,   197,   146,    21,    22,    33,   251,   254,    23,    24,
+     147,   252,    98,    22,   233,    27,   144,   183,   184,   254,
+     189,   144,   198,   253,   254,   179,   254,   191,     7,    46,
+      47,    46,    47,   144,   180,   254,   156,   157,   254,    10,
+      63,   144,   226,   227,   228,   229,   230,   247,   144,   253,
+     226,   134,   238,   239,    61,   241,   242,     7,    53,    76,
+      90,    91,   113,   138,   245,   245,   230,     7,   145,   145,
+     144,   198,   201,   202,   205,   234,   254,   224,   196,   254,
+     231,   232,   144,   254,   254,    23,    58,   145,   230,   243,
+     146,   224,    11,   145,   146,   180,   192,   156,    45,    70,
+     103,   129,   162,   254,   254,   169,   170,   171,   172,   173,
+     174,   254,   144,   165,   145,   146,    82,   158,   229,   198,
+     226,   230,     8,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    18,    19,    77,   249,    20,   244,   246,   145,
+     122,   230,   239,   242,   230,    62,   145,    71,    71,   145,
+     201,    33,   203,   204,    72,    79,    87,   109,   200,   146,
+     203,    39,   127,   199,    73,   206,    99,   213,   214,   145,
+     243,   145,   146,   184,   230,   254,   144,    85,    85,   144,
+     145,   146,     5,     7,    28,    65,    94,    95,   126,   144,
+     254,   255,   247,   248,   254,   131,   162,   163,   164,   156,
+      10,    45,    55,    92,   103,   108,   129,   159,   160,   161,
+     145,   227,   228,    17,    18,    19,    77,   230,   144,   198,
+     230,    10,    92,   145,   146,   132,   230,   122,    62,   230,
+       7,   145,   204,    97,    97,    97,    84,   201,     7,     7,
+     203,    42,    75,   207,    42,   145,    96,   215,   145,   230,
+     226,   144,   144,   253,   170,   253,   145,   146,    37,    40,
+      41,   116,   175,   146,   137,   166,    92,   144,   244,    85,
+     254,   159,   230,   144,   198,     9,   243,    92,   244,   144,
+     230,   145,    69,   145,   202,   101,   101,   243,   226,    96,
+     208,   243,    42,   106,   112,   216,   217,   145,   253,   253,
+     145,   145,   247,   144,   176,   162,    38,    99,   167,   226,
+     144,     9,   243,   230,   145,   246,     7,    95,    42,    88,
+     209,   220,   221,   230,    19,   145,   145,   169,   144,    42,
+     145,   254,   230,   145,   145,   145,   226,   220,     7,   136,
+     210,   211,   212,   146,    34,    57,   222,     7,    50,   128,
+     218,   108,   145,   169,    74,   106,   168,   145,   254,   212,
+     221,    93,   223,   102,   110,   102,     9,   254,   145,   144,
+      33,    66,    86,     7,    50,   128,   219,   144,   253,   144,
+      68,   110,    68,   253,   145,   213,   145,   100,   145,     7
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
+static const yytype_uint16 yyr1[] =
 {
-       0,   147,   148,   148,   148,   148,   148,   148,   149,   149,
-     149,   149,   149,   149,   149,   149,   149,   149,   150,   151,
-     151,   151,   151,   152,   153,   154,   155,   156,   156,   157,
-     157,   157,   157,   157,   157,   157,   157,   157,   157,   157,
-     157,   157,   157,   157,   157,   157,   157,   158,   158,   158,
-     158,   158,   158,   158,   159,   159,   160,   160,   161,   161,
-     161,   161,   162,   162,   163,   163,   164,   164,   165,   165,
-     166,   166,   167,   167,   168,   168,   169,   169,   169,   170,
-     170,   171,   172,   173,   173,   173,   173,   174,   174,   175,
-     175,   175,   175,   176,   177,   177,   178,   178,   178,   178,
-     179,   180,   181,   181,   182,   183,   183,   184,   184,   185,
-     186,   186,   187,   188,   188,   189,   189,   190,   191,   191,
-     191,   192,   192,   193,   193,   194,   194,   194,   195,   196,
-     197,   197,   197,   198,   198,   198,   198,   198,   198,   198,
-     198,   199,   199,   200,   200,   200,   200,   200,   200,   201,
-     201,   202,   202,   203,   203,   204,   204,   205,   205,   206,
-     206,   207,   207,   208,   208,   209,   209,   210,   211,   212,
-     212,   213,   213,   214,   214,   215,   215,   216,   216,   216,
-     217,   217,   217,   218,   218,   219,   220,   220,   220,   221,
-     221,   221,   222,   222,   223,   224,   224,   225,   225,   226,
-     226,   227,   227,   227,   227,   227,   227,   227,   227,   227,
-     227,   227,   228,   228,   229,   229,   230,   230,   231,   231,
-     231,   231,   231,   231,   231,   231,   231,   231,   232,   232,
-     232,   232,   233,   234,   234,   235,   235,   236,   236,   237,
-     238,   238,   239,   240,   240,   241,   241,   242,   242,   242,
-     242,   242,   242,   242,   242,   243,   243,   243,   243,   243,
-     243,   244,   244,   245,   245,   246,   246,   247,   247,   247,
-     247,   247,   247,   247,   247,   247,   247,   248,   249,   249,
-     250,   250,   250,   251,   251,   252,   252,   253,   253,   253,
-     253,   254,   255,   255
+       0,   148,   149,   149,   149,   149,   149,   149,   150,   150,
+     150,   150,   150,   150,   150,   150,   150,   150,   151,   152,
+     152,   152,   152,   153,   154,   155,   156,   157,   157,   158,
+     158,   158,   158,   158,   158,   158,   158,   158,   158,   158,
+     158,   158,   158,   158,   158,   158,   158,   159,   159,   159,
+     159,   159,   159,   159,   160,   160,   161,   161,   162,   162,
+     162,   162,   163,   163,   164,   164,   165,   165,   166,   166,
+     167,   167,   168,   168,   169,   169,   170,   170,   170,   170,
+     171,   171,   171,   172,   173,   174,   175,   175,   175,   175,
+     176,   176,   177,   177,   177,   177,   178,   178,   178,   178,
+     179,   179,   179,   180,   180,   181,   182,   183,   183,   184,
+     185,   185,   186,   186,   187,   188,   188,   189,   190,   190,
+     191,   191,   192,   193,   193,   193,   194,   194,   195,   195,
+     196,   196,   196,   197,   198,   199,   199,   199,   200,   200,
+     200,   200,   200,   200,   200,   200,   201,   201,   202,   202,
+     202,   202,   202,   202,   203,   203,   204,   204,   205,   205,
+     206,   206,   207,   207,   208,   208,   209,   209,   210,   210,
+     211,   211,   212,   213,   214,   214,   215,   215,   216,   216,
+     217,   217,   218,   218,   218,   219,   219,   219,   220,   220,
+     221,   222,   222,   222,   223,   223,   223,   224,   224,   225,
+     226,   226,   227,   227,   228,   228,   229,   229,   229,   229,
+     229,   229,   229,   229,   229,   229,   229,   230,   230,   231,
+     231,   232,   232,   233,   233,   233,   233,   233,   233,   233,
+     233,   233,   233,   234,   234,   234,   234,   235,   236,   236,
+     237,   237,   238,   238,   239,   240,   240,   241,   242,   242,
+     243,   243,   244,   244,   244,   244,   244,   244,   244,   244,
+     245,   245,   245,   245,   245,   245,   246,   246,   247,   247,
+     248,   248,   249,   249,   249,   249,   249,   249,   249,   249,
+     249,   249,   250,   251,   251,   252,   252,   252,   253,   253,
+     254,   254,   255,   255,   255,   255,   256,   257,   257
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
@@ -1437,29 +1475,29 @@ static const yytype_uint8 yyr2[] =
        1,     1,     1,     2,     2,     4,     4,     1,     2,     1,
        2,     2,     4,     5,     2,     1,     0,     1,     4,    

<TRUNCATED>


[03/12] incubator-quickstep git commit: Added partition_id in WorkOrder.

Posted by ji...@apache.org.
Added partition_id in WorkOrder.


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/32b5b83f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/32b5b83f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/32b5b83f

Branch: refs/heads/copy-to
Commit: 32b5b83f3e37033a3959c935aca102f2db2822fc
Parents: 83c4fe5
Author: Zuyu Zhang <zu...@cs.wisc.edu>
Authored: Thu Aug 24 13:26:04 2017 -0500
Committer: Zuyu Zhang <zu...@cs.wisc.edu>
Committed: Sat Aug 26 16:54:29 2017 -0500

----------------------------------------------------------------------
 query_execution/PolicyEnforcerBase.cpp          |  4 +-
 query_execution/QueryExecutionMessages.proto    |  2 +
 query_execution/QueryManagerBase.cpp            |  6 +-
 query_execution/QueryManagerBase.hpp            |  8 ++-
 query_execution/Worker.cpp                      | 13 ++--
 .../tests/QueryManagerSingleNode_unittest.cpp   | 10 ++-
 relational_operators/AggregationOperator.cpp    |  2 +
 relational_operators/AggregationOperator.hpp    |  4 +-
 .../BuildAggregationExistenceMapOperator.cpp    |  2 +
 .../BuildAggregationExistenceMapOperator.hpp    |  4 +-
 relational_operators/BuildHashOperator.hpp      | 16 +----
 relational_operators/BuildLIPFilterOperator.cpp |  2 +
 relational_operators/BuildLIPFilterOperator.hpp |  4 +-
 relational_operators/CMakeLists.txt             |  1 +
 .../DestroyAggregationStateOperator.cpp         |  2 +-
 .../DestroyAggregationStateOperator.hpp         |  4 +-
 relational_operators/DestroyHashOperator.cpp    |  2 +-
 relational_operators/DestroyHashOperator.hpp    |  4 +-
 .../FinalizeAggregationOperator.cpp             |  1 -
 .../FinalizeAggregationOperator.hpp             |  5 +-
 relational_operators/HashJoinOperator.cpp       |  6 +-
 relational_operators/HashJoinOperator.hpp       | 66 +++-----------------
 .../InitializeAggregationOperator.cpp           |  1 +
 .../InitializeAggregationOperator.hpp           |  4 +-
 .../NestedLoopsJoinOperator.cpp                 |  4 ++
 .../NestedLoopsJoinOperator.hpp                 |  4 +-
 relational_operators/RebuildWorkOrder.hpp       |  6 +-
 relational_operators/SelectOperator.cpp         |  2 +-
 relational_operators/SelectOperator.hpp         |  7 +--
 relational_operators/WorkOrder.hpp              | 21 ++++++-
 relational_operators/WorkOrderFactory.cpp       | 15 ++++-
 31 files changed, 114 insertions(+), 118 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/query_execution/PolicyEnforcerBase.cpp
----------------------------------------------------------------------
diff --git a/query_execution/PolicyEnforcerBase.cpp b/query_execution/PolicyEnforcerBase.cpp
index 32f29a3..f97f711 100644
--- a/query_execution/PolicyEnforcerBase.cpp
+++ b/query_execution/PolicyEnforcerBase.cpp
@@ -72,7 +72,7 @@ void PolicyEnforcerBase::processMessage(const TaggedMessage &tagged_message) {
       DCHECK(admitted_queries_.find(query_id) != admitted_queries_.end());
 
       op_index = proto.operator_index();
-      admitted_queries_[query_id]->processWorkOrderCompleteMessage(op_index);
+      admitted_queries_[query_id]->processWorkOrderCompleteMessage(op_index, proto.partition_id());
       break;
     }
     case kRebuildWorkOrderCompleteMessage: {
@@ -87,7 +87,7 @@ void PolicyEnforcerBase::processMessage(const TaggedMessage &tagged_message) {
       DCHECK(admitted_queries_.find(query_id) != admitted_queries_.end());
 
       op_index = proto.operator_index();
-      admitted_queries_[query_id]->processRebuildWorkOrderCompleteMessage(op_index);
+      admitted_queries_[query_id]->processRebuildWorkOrderCompleteMessage(op_index, proto.partition_id());
       break;
     }
     case kCatalogRelationNewBlockMessage: {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/query_execution/QueryExecutionMessages.proto
----------------------------------------------------------------------
diff --git a/query_execution/QueryExecutionMessages.proto b/query_execution/QueryExecutionMessages.proto
index 6aa8769..abc47cf 100644
--- a/query_execution/QueryExecutionMessages.proto
+++ b/query_execution/QueryExecutionMessages.proto
@@ -31,6 +31,7 @@ import "relational_operators/WorkOrder.proto";
 // order completion message, we may be interested in adding the compression
 // ratio or dictionary size of the rebuilt block.
 
+// Next tag: 9.
 message WorkOrderCompletionMessage {
   enum WorkOrderType {
     NORMAL = 0;
@@ -42,6 +43,7 @@ message WorkOrderCompletionMessage {
   required uint64 operator_index = 2;
   required uint64 worker_thread_index = 3;
   required uint64 query_id = 4;
+  required uint64 partition_id = 8;
 
   // Epoch time in microseconds.
   optional uint64 execution_start_time = 5;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/query_execution/QueryManagerBase.cpp
----------------------------------------------------------------------
diff --git a/query_execution/QueryManagerBase.cpp b/query_execution/QueryManagerBase.cpp
index f353b64..565c6ad 100644
--- a/query_execution/QueryManagerBase.cpp
+++ b/query_execution/QueryManagerBase.cpp
@@ -105,7 +105,8 @@ void QueryManagerBase::processFeedbackMessage(
 }
 
 void QueryManagerBase::processWorkOrderCompleteMessage(
-    const dag_node_index op_index) {
+    const dag_node_index op_index,
+    const partition_id part_id) {
   query_exec_state_->decrementNumQueuedWorkOrders(op_index);
 
   // Check if new work orders are available and fetch them if so.
@@ -144,7 +145,8 @@ void QueryManagerBase::processWorkOrderCompleteMessage(
   }
 }
 
-void QueryManagerBase::processRebuildWorkOrderCompleteMessage(const dag_node_index op_index) {
+void QueryManagerBase::processRebuildWorkOrderCompleteMessage(const dag_node_index op_index,
+                                                              const partition_id part_id) {
   query_exec_state_->decrementNumRebuildWorkOrders(op_index);
 
   if (checkRebuildOver(op_index)) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/query_execution/QueryManagerBase.hpp
----------------------------------------------------------------------
diff --git a/query_execution/QueryManagerBase.hpp b/query_execution/QueryManagerBase.hpp
index b6ed247..78d67cc 100644
--- a/query_execution/QueryManagerBase.hpp
+++ b/query_execution/QueryManagerBase.hpp
@@ -92,16 +92,20 @@ class QueryManagerBase {
    *
    * @param op_index The index of the specified operator node in the query DAG
    *        for the completed WorkOrder.
+   * @param part_id The partition id.
    **/
-  void processWorkOrderCompleteMessage(const dag_node_index op_index);
+  void processWorkOrderCompleteMessage(const dag_node_index op_index,
+                                       const partition_id part_id);
 
   /**
    * @brief Process the received RebuildWorkOrder complete message.
    *
    * @param op_index The index of the specified operator node in the query DAG
    *        for the completed RebuildWorkOrder.
+   * @param part_id The partition id.
    **/
-  void processRebuildWorkOrderCompleteMessage(const dag_node_index op_index);
+  void processRebuildWorkOrderCompleteMessage(const dag_node_index op_index,
+                                              const partition_id part_id);
 
   /**
    * @brief Process the received data pipeline message.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/query_execution/Worker.cpp
----------------------------------------------------------------------
diff --git a/query_execution/Worker.cpp b/query_execution/Worker.cpp
index 1882f2e..44151af 100644
--- a/query_execution/Worker.cpp
+++ b/query_execution/Worker.cpp
@@ -23,6 +23,7 @@
 #include <cstddef>
 #include <cstdint>
 #include <cstdlib>
+#include <memory>
 #include <utility>
 
 #include "query_execution/QueryExecutionMessages.pb.h"
@@ -125,14 +126,17 @@ void Worker::executeWorkOrderHelper(const TaggedMessage &tagged_message,
   std::chrono::time_point<std::chrono::steady_clock> start, end;
   WorkerMessage worker_message(
       *static_cast<const WorkerMessage *>(tagged_message.message()));
-  DCHECK(worker_message.getWorkOrder() != nullptr);
-  const size_t query_id_for_workorder = worker_message.getWorkOrder()->getQueryID();
+  std::unique_ptr<WorkOrder> work_order(worker_message.getWorkOrder());
+  DCHECK(work_order);
+
+  const size_t query_id_for_workorder = work_order->getQueryID();
+  const partition_id part_id = work_order->getPartitionId();
 
   // Start measuring the execution time.
   start = std::chrono::steady_clock::now();
-  worker_message.getWorkOrder()->execute();
+  work_order->execute();
   end = std::chrono::steady_clock::now();
-  delete worker_message.getWorkOrder();
+  work_order.reset();
 
   // Convert the measured timestamps to epoch times in microseconds.
   const uint64_t execution_start_time =
@@ -147,6 +151,7 @@ void Worker::executeWorkOrderHelper(const TaggedMessage &tagged_message,
                                                    : WorkOrderCompletionMessage::NORMAL);
   proto->set_operator_index(worker_message.getRelationalOpIndex());
   proto->set_query_id(query_id_for_workorder);
+  proto->set_partition_id(part_id);
   proto->set_worker_thread_index(worker_thread_index_);
   proto->set_execution_start_time(execution_start_time);
   proto->set_execution_end_time(execution_end_time);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/query_execution/tests/QueryManagerSingleNode_unittest.cpp
----------------------------------------------------------------------
diff --git a/query_execution/tests/QueryManagerSingleNode_unittest.cpp b/query_execution/tests/QueryManagerSingleNode_unittest.cpp
index c65364c..19b42ac 100644
--- a/query_execution/tests/QueryManagerSingleNode_unittest.cpp
+++ b/query_execution/tests/QueryManagerSingleNode_unittest.cpp
@@ -61,6 +61,12 @@ using tmb::client_id;
 
 namespace quickstep {
 
+namespace {
+
+const partition_id kPartitionId = 0;
+
+}  // namespace
+
 class WorkOrderProtosContainer;
 
 class MockWorkOrder : public WorkOrder {
@@ -256,14 +262,14 @@ class QueryManagerTest : public ::testing::Test {
   inline bool placeWorkOrderCompleteMessage(const QueryPlan::DAGNodeIndex index) {
     VLOG(3) << "Place WorkOrderComplete message for Op[" << index << "]";
 
-    query_manager_->processWorkOrderCompleteMessage(index);
+    query_manager_->processWorkOrderCompleteMessage(index, kPartitionId);
     return query_manager_->getQueryExecutionState().hasQueryExecutionFinished();
   }
 
   inline bool placeRebuildWorkOrderCompleteMessage(const QueryPlan::DAGNodeIndex index) {
     VLOG(3) << "Place RebuildWorkOrderComplete message for Op[" << index << "]";
 
-    query_manager_->processRebuildWorkOrderCompleteMessage(index);
+    query_manager_->processRebuildWorkOrderCompleteMessage(index, kPartitionId);
     return query_manager_->getQueryExecutionState().hasQueryExecutionFinished();
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/AggregationOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/AggregationOperator.cpp b/relational_operators/AggregationOperator.cpp
index 2618e01..6833b59 100644
--- a/relational_operators/AggregationOperator.cpp
+++ b/relational_operators/AggregationOperator.cpp
@@ -51,6 +51,7 @@ bool AggregationOperator::getAllWorkOrders(
         container->addNormalWorkOrder(
             new AggregationWorkOrder(
                 query_id_,
+                part_id,
                 input_block_id,
                 query_context->getAggregationState(aggr_state_index_, part_id),
                 CreateLIPFilterAdaptiveProberHelper(lip_deployment_index_, query_context)),
@@ -65,6 +66,7 @@ bool AggregationOperator::getAllWorkOrders(
         container->addNormalWorkOrder(
             new AggregationWorkOrder(
                 query_id_,
+                part_id,
                 input_relation_block_ids_[part_id][num_workorders_generated_[part_id]],
                 query_context->getAggregationState(aggr_state_index_, part_id),
                 CreateLIPFilterAdaptiveProberHelper(lip_deployment_index_, query_context)),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/AggregationOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/AggregationOperator.hpp b/relational_operators/AggregationOperator.hpp
index 1d37e50..2fb620b 100644
--- a/relational_operators/AggregationOperator.hpp
+++ b/relational_operators/AggregationOperator.hpp
@@ -155,15 +155,17 @@ class AggregationWorkOrder : public WorkOrder {
    * @brief Constructor
    *
    * @param query_id The ID of this query.
+   * @param part_id The partition id.
    * @param input_block_id The block id.
    * @param state The AggregationState to use.
    * @param lip_filter_adaptive_prober The attached LIP filter prober.
    **/
   AggregationWorkOrder(const std::size_t query_id,
+                       const partition_id part_id,
                        const block_id input_block_id,
                        AggregationOperationState *state,
                        LIPFilterAdaptiveProber *lip_filter_adaptive_prober)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         input_block_id_(input_block_id),
         state_(DCHECK_NOTNULL(state)),
         lip_filter_adaptive_prober_(lip_filter_adaptive_prober) {}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/BuildAggregationExistenceMapOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/BuildAggregationExistenceMapOperator.cpp b/relational_operators/BuildAggregationExistenceMapOperator.cpp
index 5552b75..61cebe1 100644
--- a/relational_operators/BuildAggregationExistenceMapOperator.cpp
+++ b/relational_operators/BuildAggregationExistenceMapOperator.cpp
@@ -98,6 +98,7 @@ bool BuildAggregationExistenceMapOperator::getAllWorkOrders(
             new BuildAggregationExistenceMapWorkOrder(
                 query_id_,
                 input_relation_,
+                part_id,
                 input_block_id,
                 build_attribute_,
                 query_context->getAggregationState(aggr_state_index_, part_id),
@@ -114,6 +115,7 @@ bool BuildAggregationExistenceMapOperator::getAllWorkOrders(
             new BuildAggregationExistenceMapWorkOrder(
                   query_id_,
                   input_relation_,
+                  part_id,
                   input_relation_block_ids_[part_id][num_workorders_generated_[part_id]],
                   build_attribute_,
                   query_context->getAggregationState(aggr_state_index_, part_id),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/BuildAggregationExistenceMapOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/BuildAggregationExistenceMapOperator.hpp b/relational_operators/BuildAggregationExistenceMapOperator.hpp
index b29ad4a..8791a38 100644
--- a/relational_operators/BuildAggregationExistenceMapOperator.hpp
+++ b/relational_operators/BuildAggregationExistenceMapOperator.hpp
@@ -158,6 +158,7 @@ class BuildAggregationExistenceMapWorkOrder : public WorkOrder {
    *
    * @param query_id The ID of this query.
    * @param input_relation The relation to build the existence map on.
+   * @param part_id The partition id of 'input_relation'.
    * @param build_block_id The block id.
    * @param build_attribute The ID of the attribute to build on.
    * @param state The AggregationState to use.
@@ -165,11 +166,12 @@ class BuildAggregationExistenceMapWorkOrder : public WorkOrder {
    **/
   BuildAggregationExistenceMapWorkOrder(const std::size_t query_id,
                                         const CatalogRelationSchema &input_relation,
+                                        const partition_id part_id,
                                         const block_id build_block_id,
                                         const attribute_id build_attribute,
                                         AggregationOperationState *state,
                                         StorageManager *storage_manager)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         input_relation_(input_relation),
         build_block_id_(build_block_id),
         build_attribute_(build_attribute),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/BuildHashOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/BuildHashOperator.hpp b/relational_operators/BuildHashOperator.hpp
index 50dbc05..d18d9fb 100644
--- a/relational_operators/BuildHashOperator.hpp
+++ b/relational_operators/BuildHashOperator.hpp
@@ -203,11 +203,10 @@ class BuildHashWorkOrder : public WorkOrder {
                      JoinHashTable *hash_table,
                      StorageManager *storage_manager,
                      LIPFilterBuilder *lip_filter_builder)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         input_relation_(input_relation),
         join_key_attributes_(join_key_attributes),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        part_id_(part_id),
         build_block_id_(build_block_id),
         hash_table_(DCHECK_NOTNULL(hash_table)),
         storage_manager_(DCHECK_NOTNULL(storage_manager)),
@@ -236,11 +235,10 @@ class BuildHashWorkOrder : public WorkOrder {
                      JoinHashTable *hash_table,
                      StorageManager *storage_manager,
                      LIPFilterBuilder *lip_filter_builder)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         input_relation_(input_relation),
         join_key_attributes_(std::move(join_key_attributes)),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        part_id_(part_id),
         build_block_id_(build_block_id),
         hash_table_(DCHECK_NOTNULL(hash_table)),
         storage_manager_(DCHECK_NOTNULL(storage_manager)),
@@ -254,20 +252,10 @@ class BuildHashWorkOrder : public WorkOrder {
 
   void execute() override;
 
-  /**
-   * @brief Get the partition id.
-   *
-   * @return The partition id.
-   */
-  partition_id getPartitionId() const {
-    return part_id_;
-  }
-
  private:
   const CatalogRelationSchema &input_relation_;
   const std::vector<attribute_id> join_key_attributes_;
   const bool any_join_key_attributes_nullable_;
-  const partition_id part_id_;
   const block_id build_block_id_;
 
   JoinHashTable *hash_table_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/BuildLIPFilterOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/BuildLIPFilterOperator.cpp b/relational_operators/BuildLIPFilterOperator.cpp
index 925dfb5..9065b85 100644
--- a/relational_operators/BuildLIPFilterOperator.cpp
+++ b/relational_operators/BuildLIPFilterOperator.cpp
@@ -65,6 +65,7 @@ bool BuildLIPFilterOperator::getAllWorkOrders(
             new BuildLIPFilterWorkOrder(
                 query_id_,
                 input_relation_,
+                part_id,
                 input_block_id,
                 build_side_predicate,
                 storage_manager,
@@ -82,6 +83,7 @@ bool BuildLIPFilterOperator::getAllWorkOrders(
             new BuildLIPFilterWorkOrder(
                 query_id_,
                 input_relation_,
+                part_id,
                 input_relation_block_ids_[part_id][num_workorders_generated_[part_id]],
                 build_side_predicate,
                 storage_manager,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/BuildLIPFilterOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/BuildLIPFilterOperator.hpp b/relational_operators/BuildLIPFilterOperator.hpp
index df722ef..9b23dd9 100644
--- a/relational_operators/BuildLIPFilterOperator.hpp
+++ b/relational_operators/BuildLIPFilterOperator.hpp
@@ -171,6 +171,7 @@ class BuildLIPFilterWorkOrder : public WorkOrder {
    *
    * @param query_id The ID of the query to which this WorkOrder belongs.
    * @param input_relation The relation to build LIP filters on.
+   * @param part_id The partition id of 'input_relation'.
    * @param build_block_id The block id.
    * @param build_side_predicate The predicate to be applied to filter the input
    *        relation before building the LIP filters (or nullptr if no predicate
@@ -181,12 +182,13 @@ class BuildLIPFilterWorkOrder : public WorkOrder {
    **/
   BuildLIPFilterWorkOrder(const std::size_t query_id,
                           const CatalogRelationSchema &input_relation,
+                          const partition_id part_id,
                           const block_id build_block_id,
                           const Predicate *build_side_predicate,
                           StorageManager *storage_manager,
                           LIPFilterAdaptiveProber *lip_filter_adaptive_prober,
                           LIPFilterBuilder *lip_filter_builder)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         input_relation_(input_relation),
         build_block_id_(build_block_id),
         build_side_predicate_(build_side_predicate),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/relational_operators/CMakeLists.txt b/relational_operators/CMakeLists.txt
index 6083dd5..c0def6f 100644
--- a/relational_operators/CMakeLists.txt
+++ b/relational_operators/CMakeLists.txt
@@ -565,6 +565,7 @@ target_link_libraries(quickstep_relationaloperators_WindowAggregationOperator
                       tmb)
 target_link_libraries(quickstep_relationaloperators_WorkOrder
                       glog
+                      quickstep_catalog_CatalogTypedefs
                       quickstep_queryexecution_QueryExecutionTypedefs
                       quickstep_utility_Macros
                       tmb)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/DestroyAggregationStateOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/DestroyAggregationStateOperator.cpp b/relational_operators/DestroyAggregationStateOperator.cpp
index 3d36e20..9d8d9f6 100644
--- a/relational_operators/DestroyAggregationStateOperator.cpp
+++ b/relational_operators/DestroyAggregationStateOperator.cpp
@@ -67,7 +67,7 @@ bool DestroyAggregationStateOperator::getAllWorkOrderProtos(WorkOrderProtosConta
 }
 
 void DestroyAggregationStateWorkOrder::execute() {
-  query_context_->destroyAggregationState(aggr_state_index_, part_id_);
+  query_context_->destroyAggregationState(aggr_state_index_, partition_id_);
 }
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/DestroyAggregationStateOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/DestroyAggregationStateOperator.hpp b/relational_operators/DestroyAggregationStateOperator.hpp
index 990160f..c5b092f 100644
--- a/relational_operators/DestroyAggregationStateOperator.hpp
+++ b/relational_operators/DestroyAggregationStateOperator.hpp
@@ -110,9 +110,8 @@ class DestroyAggregationStateWorkOrder : public WorkOrder {
       const QueryContext::aggregation_state_id aggr_state_index,
       const partition_id part_id,
       QueryContext *query_context)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         aggr_state_index_(aggr_state_index),
-        part_id_(part_id),
         query_context_(DCHECK_NOTNULL(query_context)) {}
 
   ~DestroyAggregationStateWorkOrder() override {}
@@ -121,7 +120,6 @@ class DestroyAggregationStateWorkOrder : public WorkOrder {
 
  private:
   const QueryContext::aggregation_state_id aggr_state_index_;
-  const partition_id part_id_;
   QueryContext *query_context_;
 
   DISALLOW_COPY_AND_ASSIGN(DestroyAggregationStateWorkOrder);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/DestroyHashOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/DestroyHashOperator.cpp b/relational_operators/DestroyHashOperator.cpp
index d9ea19b..4b93f0c 100644
--- a/relational_operators/DestroyHashOperator.cpp
+++ b/relational_operators/DestroyHashOperator.cpp
@@ -68,7 +68,7 @@ bool DestroyHashOperator::getAllWorkOrderProtos(WorkOrderProtosContainer *contai
 
 
 void DestroyHashWorkOrder::execute() {
-  query_context_->destroyJoinHashTable(hash_table_index_, part_id_);
+  query_context_->destroyJoinHashTable(hash_table_index_, partition_id_);
 }
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/DestroyHashOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/DestroyHashOperator.hpp b/relational_operators/DestroyHashOperator.hpp
index a65e739..3a6cf0e 100644
--- a/relational_operators/DestroyHashOperator.hpp
+++ b/relational_operators/DestroyHashOperator.hpp
@@ -107,9 +107,8 @@ class DestroyHashWorkOrder : public WorkOrder {
                        const QueryContext::join_hash_table_id hash_table_index,
                        const partition_id part_id,
                        QueryContext *query_context)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         hash_table_index_(hash_table_index),
-        part_id_(part_id),
         query_context_(DCHECK_NOTNULL(query_context)) {}
 
   ~DestroyHashWorkOrder() override {}
@@ -118,7 +117,6 @@ class DestroyHashWorkOrder : public WorkOrder {
 
  private:
   const QueryContext::join_hash_table_id hash_table_index_;
-  const partition_id part_id_;
   QueryContext *query_context_;
 
   DISALLOW_COPY_AND_ASSIGN(DestroyHashWorkOrder);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/FinalizeAggregationOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/FinalizeAggregationOperator.cpp b/relational_operators/FinalizeAggregationOperator.cpp
index efa4cba..68d0ef4 100644
--- a/relational_operators/FinalizeAggregationOperator.cpp
+++ b/relational_operators/FinalizeAggregationOperator.cpp
@@ -96,7 +96,6 @@ bool FinalizeAggregationOperator::getAllWorkOrderProtos(WorkOrderProtosContainer
 }
 
 void FinalizeAggregationWorkOrder::execute() {
-  (void) part_id_;
   state_->finalizeAggregate(state_partition_id_, output_destination_);
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/FinalizeAggregationOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/FinalizeAggregationOperator.hpp b/relational_operators/FinalizeAggregationOperator.hpp
index 12433b9..a6f1ef6 100644
--- a/relational_operators/FinalizeAggregationOperator.hpp
+++ b/relational_operators/FinalizeAggregationOperator.hpp
@@ -139,8 +139,7 @@ class FinalizeAggregationWorkOrder : public WorkOrder {
                                const std::size_t state_partition_id,
                                AggregationOperationState *state,
                                InsertDestination *output_destination)
-      : WorkOrder(query_id),
-        part_id_(part_id),
+      : WorkOrder(query_id, part_id),
         state_partition_id_(state_partition_id),
         state_(DCHECK_NOTNULL(state)),
         output_destination_(DCHECK_NOTNULL(output_destination)) {}
@@ -150,7 +149,7 @@ class FinalizeAggregationWorkOrder : public WorkOrder {
   void execute() override;
 
  private:
-  const std::size_t part_id_, state_partition_id_;
+  const std::size_t state_partition_id_;
   AggregationOperationState *state_;
   InsertDestination *output_destination_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/HashJoinOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/HashJoinOperator.cpp b/relational_operators/HashJoinOperator.cpp
index e385e46..b07e4cb 100644
--- a/relational_operators/HashJoinOperator.cpp
+++ b/relational_operators/HashJoinOperator.cpp
@@ -447,7 +447,7 @@ serialization::WorkOrder* HashJoinOperator::createOuterJoinWorkOrderProto(const
 
 
 void HashInnerJoinWorkOrder::execute() {
-  output_destination_->setInputPartitionId(part_id_);
+  output_destination_->setInputPartitionId(partition_id_);
 
   BlockReference probe_block(
       storage_manager_->getBlock(block_id_, probe_relation_));
@@ -680,7 +680,7 @@ void HashInnerJoinWorkOrder::executeWithCopyElision(ValueAccessor *probe_accesso
 }
 
 void HashSemiJoinWorkOrder::execute() {
-  output_destination_->setInputPartitionId(part_id_);
+  output_destination_->setInputPartitionId(partition_id_);
 
   if (residual_predicate_ == nullptr) {
     executeWithoutResidualPredicate();
@@ -1006,7 +1006,7 @@ void HashAntiJoinWorkOrder::executeWithResidualPredicate() {
 }
 
 void HashOuterJoinWorkOrder::execute() {
-  output_destination_->setInputPartitionId(part_id_);
+  output_destination_->setInputPartitionId(partition_id_);
 
   const relation_id build_relation_id = build_relation_.getID();
   const relation_id probe_relation_id = probe_relation_.getID();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/HashJoinOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/HashJoinOperator.hpp b/relational_operators/HashJoinOperator.hpp
index 23267f8..316be66 100644
--- a/relational_operators/HashJoinOperator.hpp
+++ b/relational_operators/HashJoinOperator.hpp
@@ -338,12 +338,11 @@ class HashInnerJoinWorkOrder : public WorkOrder {
       InsertDestination *output_destination,
       StorageManager *storage_manager,
       LIPFilterAdaptiveProber *lip_filter_adaptive_prober)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         build_relation_(build_relation),
         probe_relation_(probe_relation),
         join_key_attributes_(join_key_attributes),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        part_id_(part_id),
         block_id_(lookup_block_id),
         residual_predicate_(residual_predicate),
         selection_(selection),
@@ -391,12 +390,11 @@ class HashInnerJoinWorkOrder : public WorkOrder {
       InsertDestination *output_destination,
       StorageManager *storage_manager,
       LIPFilterAdaptiveProber *lip_filter_adaptive_prober)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         build_relation_(build_relation),
         probe_relation_(probe_relation),
         join_key_attributes_(std::move(join_key_attributes)),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        part_id_(part_id),
         block_id_(lookup_block_id),
         residual_predicate_(residual_predicate),
         selection_(selection),
@@ -417,15 +415,6 @@ class HashInnerJoinWorkOrder : public WorkOrder {
    **/
   void execute() override;
 
-  /**
-   * @brief Get the partition id.
-   *
-   * @return The partition id.
-   */
-  partition_id getPartitionId() const {
-    return part_id_;
-  }
-
  private:
   void executeWithoutCopyElision(ValueAccessor *probe_accesor);
 
@@ -435,7 +424,6 @@ class HashInnerJoinWorkOrder : public WorkOrder {
   const CatalogRelationSchema &probe_relation_;
   const std::vector<attribute_id> join_key_attributes_;
   const bool any_join_key_attributes_nullable_;
-  const partition_id part_id_;
   const block_id block_id_;
   const Predicate *residual_predicate_;
   const std::vector<std::unique_ptr<const Scalar>> &selection_;
@@ -494,12 +482,11 @@ class HashSemiJoinWorkOrder : public WorkOrder {
       InsertDestination *output_destination,
       StorageManager *storage_manager,
       LIPFilterAdaptiveProber *lip_filter_adaptive_prober)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         build_relation_(build_relation),
         probe_relation_(probe_relation),
         join_key_attributes_(join_key_attributes),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        part_id_(part_id),
         block_id_(lookup_block_id),
         residual_predicate_(residual_predicate),
         selection_(selection),
@@ -547,12 +534,11 @@ class HashSemiJoinWorkOrder : public WorkOrder {
       InsertDestination *output_destination,
       StorageManager *storage_manager,
       LIPFilterAdaptiveProber *lip_filter_adaptive_prober)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         build_relation_(build_relation),
         probe_relation_(probe_relation),
         join_key_attributes_(std::move(join_key_attributes)),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        part_id_(part_id),
         block_id_(lookup_block_id),
         residual_predicate_(residual_predicate),
         selection_(selection),
@@ -565,15 +551,6 @@ class HashSemiJoinWorkOrder : public WorkOrder {
 
   void execute() override;
 
-  /**
-   * @brief Get the partition id.
-   *
-   * @return The partition id.
-   */
-  partition_id getPartitionId() const {
-    return part_id_;
-  }
-
  private:
   void executeWithoutResidualPredicate();
 
@@ -583,7 +560,6 @@ class HashSemiJoinWorkOrder : public WorkOrder {
   const CatalogRelationSchema &probe_relation_;
   const std::vector<attribute_id> join_key_attributes_;
   const bool any_join_key_attributes_nullable_;
-  const partition_id part_id_;
   const block_id block_id_;
   const Predicate *residual_predicate_;
   const std::vector<std::unique_ptr<const Scalar>> &selection_;
@@ -642,12 +618,11 @@ class HashAntiJoinWorkOrder : public WorkOrder {
       InsertDestination *output_destination,
       StorageManager *storage_manager,
       LIPFilterAdaptiveProber *lip_filter_adaptive_prober)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         build_relation_(build_relation),
         probe_relation_(probe_relation),
         join_key_attributes_(join_key_attributes),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        part_id_(part_id),
         block_id_(lookup_block_id),
         residual_predicate_(residual_predicate),
         selection_(selection),
@@ -695,12 +670,11 @@ class HashAntiJoinWorkOrder : public WorkOrder {
       InsertDestination *output_destination,
       StorageManager *storage_manager,
       LIPFilterAdaptiveProber *lip_filter_adaptive_prober)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         build_relation_(build_relation),
         probe_relation_(probe_relation),
         join_key_attributes_(std::move(join_key_attributes)),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        part_id_(part_id),
         block_id_(lookup_block_id),
         residual_predicate_(residual_predicate),
         selection_(selection),
@@ -712,7 +686,7 @@ class HashAntiJoinWorkOrder : public WorkOrder {
   ~HashAntiJoinWorkOrder() override {}
 
   void execute() override {
-    output_destination_->setInputPartitionId(part_id_);
+    output_destination_->setInputPartitionId(partition_id_);
 
     if (residual_predicate_ == nullptr) {
       executeWithoutResidualPredicate();
@@ -721,15 +695,6 @@ class HashAntiJoinWorkOrder : public WorkOrder {
     }
   }
 
-  /**
-   * @brief Get the partition id.
-   *
-   * @return The partition id.
-   */
-  partition_id getPartitionId() const {
-    return part_id_;
-  }
-
  private:
   void executeWithoutResidualPredicate();
 
@@ -739,7 +704,6 @@ class HashAntiJoinWorkOrder : public WorkOrder {
   const CatalogRelationSchema &probe_relation_;
   const std::vector<attribute_id> join_key_attributes_;
   const bool any_join_key_attributes_nullable_;
-  const partition_id part_id_;
   const block_id block_id_;
   const Predicate *residual_predicate_;
   const std::vector<std::unique_ptr<const Scalar>> &selection_;
@@ -796,12 +760,11 @@ class HashOuterJoinWorkOrder : public WorkOrder {
       InsertDestination *output_destination,
       StorageManager *storage_manager,
       LIPFilterAdaptiveProber *lip_filter_adaptive_prober)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         build_relation_(build_relation),
         probe_relation_(probe_relation),
         join_key_attributes_(join_key_attributes),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        part_id_(part_id),
         block_id_(lookup_block_id),
         selection_(selection),
         is_selection_on_build_(is_selection_on_build),
@@ -847,12 +810,11 @@ class HashOuterJoinWorkOrder : public WorkOrder {
       InsertDestination *output_destination,
       StorageManager *storage_manager,
       LIPFilterAdaptiveProber *lip_filter_adaptive_prober)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         build_relation_(build_relation),
         probe_relation_(probe_relation),
         join_key_attributes_(std::move(join_key_attributes)),
         any_join_key_attributes_nullable_(any_join_key_attributes_nullable),
-        part_id_(part_id),
         block_id_(lookup_block_id),
         selection_(selection),
         is_selection_on_build_(std::move(is_selection_on_build)),
@@ -865,21 +827,11 @@ class HashOuterJoinWorkOrder : public WorkOrder {
 
   void execute() override;
 
-  /**
-   * @brief Get the partition id.
-   *
-   * @return The partition id.
-   */
-  partition_id getPartitionId() const {
-    return part_id_;
-  }
-
  private:
   const CatalogRelationSchema &build_relation_;
   const CatalogRelationSchema &probe_relation_;
   const std::vector<attribute_id> join_key_attributes_;
   const bool any_join_key_attributes_nullable_;
-  const partition_id part_id_;
   const block_id block_id_;
   const std::vector<std::unique_ptr<const Scalar>> &selection_;
   const std::vector<bool> is_selection_on_build_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/InitializeAggregationOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/InitializeAggregationOperator.cpp b/relational_operators/InitializeAggregationOperator.cpp
index 136686b..39a6fb4 100644
--- a/relational_operators/InitializeAggregationOperator.cpp
+++ b/relational_operators/InitializeAggregationOperator.cpp
@@ -53,6 +53,7 @@ bool InitializeAggregationOperator::getAllWorkOrders(
          ++state_part_id) {
       container->addNormalWorkOrder(
           new InitializeAggregationWorkOrder(query_id_,
+                                             part_id,
                                              state_part_id,
                                              agg_state),
           op_index_);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/InitializeAggregationOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/InitializeAggregationOperator.hpp b/relational_operators/InitializeAggregationOperator.hpp
index b7e9aae..0b052c7 100644
--- a/relational_operators/InitializeAggregationOperator.hpp
+++ b/relational_operators/InitializeAggregationOperator.hpp
@@ -106,13 +106,15 @@ class InitializeAggregationWorkOrder : public WorkOrder {
    * @brief Constructor.
    *
    * @param query_id The ID of the query to which this operator belongs.
+   * @param part_id The partition id.
    * @param state_partition_id The partition ID for which the work order is issued.
    * @param state The AggregationOperationState to be initialized.
    */
   InitializeAggregationWorkOrder(const std::size_t query_id,
+                                 const partition_id part_id,
                                  const std::size_t state_partition_id,
                                  AggregationOperationState *state)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         state_partition_id_(state_partition_id),
         state_(DCHECK_NOTNULL(state)) {}
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/NestedLoopsJoinOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/NestedLoopsJoinOperator.cpp b/relational_operators/NestedLoopsJoinOperator.cpp
index 1c0bbec..121b1c3 100644
--- a/relational_operators/NestedLoopsJoinOperator.cpp
+++ b/relational_operators/NestedLoopsJoinOperator.cpp
@@ -69,6 +69,7 @@ bool NestedLoopsJoinOperator::getAllWorkOrders(
                   query_id_,
                   left_input_relation_,
                   right_input_relation_,
+                  part_id,
                   left_block_id,
                   right_block_id,
                   query_context->getPredicate(join_predicate_index_),
@@ -244,6 +245,7 @@ std::size_t NestedLoopsJoinOperator::getAllWorkOrdersHelperBothNotStored(WorkOrd
               query_id_,
               left_input_relation_,
               right_input_relation_,
+              part_id,
               left_relation_block_ids_[part_id][left_index],
               right_relation_block_ids_[part_id][right_index],
               query_context->getPredicate(join_predicate_index_),
@@ -280,6 +282,7 @@ bool NestedLoopsJoinOperator::getAllWorkOrdersHelperOneStored(WorkOrdersContaine
                   query_id_,
                   left_input_relation_,
                   right_input_relation_,
+                  part_id,
                   left_block_id,
                   right_relation_block_ids_[part_id][right_index],
                   join_predicate,
@@ -302,6 +305,7 @@ bool NestedLoopsJoinOperator::getAllWorkOrdersHelperOneStored(WorkOrdersContaine
               new NestedLoopsJoinWorkOrder(query_id_,
                                            left_input_relation_,
                                            right_input_relation_,
+                                           part_id,
                                            left_relation_block_ids_[part_id][left_index],
                                            right_block_id,
                                            join_predicate,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/NestedLoopsJoinOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/NestedLoopsJoinOperator.hpp b/relational_operators/NestedLoopsJoinOperator.hpp
index 64711e1..006d496 100644
--- a/relational_operators/NestedLoopsJoinOperator.hpp
+++ b/relational_operators/NestedLoopsJoinOperator.hpp
@@ -338,6 +338,7 @@ class NestedLoopsJoinWorkOrder : public WorkOrder {
    *        actually important).
    * @param right_input_relation The second relation in the join (order is not
    *        actually important).
+   * @param part_id The partition id.
    * @param left_block_id The block id of the first relation.
    * @param right_block_id The block id of the second relation.
    * @param join_predicate The join predicate to evaluate for each pair of
@@ -352,13 +353,14 @@ class NestedLoopsJoinWorkOrder : public WorkOrder {
       const std::size_t query_id,
       const CatalogRelationSchema &left_input_relation,
       const CatalogRelationSchema &right_input_relation,
+      const partition_id part_id,
       const block_id left_block_id,
       const block_id right_block_id,
       const Predicate *join_predicate,
       const std::vector<std::unique_ptr<const Scalar>> &selection,
       InsertDestination *output_destination,
       StorageManager *storage_manager)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         left_input_relation_(left_input_relation),
         right_input_relation_(right_input_relation),
         left_block_id_(left_block_id),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/RebuildWorkOrder.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/RebuildWorkOrder.hpp b/relational_operators/RebuildWorkOrder.hpp
index 8615d74..08b1093 100644
--- a/relational_operators/RebuildWorkOrder.hpp
+++ b/relational_operators/RebuildWorkOrder.hpp
@@ -69,11 +69,10 @@ class RebuildWorkOrder : public WorkOrder {
       const partition_id part_id,
       const client_id scheduler_client_id,
       MessageBus *bus)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         block_ref_(std::move(block_ref)),
         input_operator_index_(input_operator_index),
         input_relation_id_(input_relation_id),
-        part_id_(part_id),
         scheduler_client_id_(scheduler_client_id),
         bus_(bus) {}
 
@@ -91,7 +90,7 @@ class RebuildWorkOrder : public WorkOrder {
     proto.set_block_id(block_ref_->getID());
     proto.set_relation_id(input_relation_id_);
     proto.set_query_id(query_id_);
-    proto.set_partition_id(part_id_);
+    proto.set_partition_id(partition_id_);
 
     // NOTE(zuyu): Using the heap memory to serialize proto as a c-like string.
     const std::size_t proto_length = proto.ByteSize();
@@ -118,7 +117,6 @@ class RebuildWorkOrder : public WorkOrder {
   MutableBlockReference block_ref_;
   const std::size_t input_operator_index_;
   const relation_id input_relation_id_;
-  const partition_id part_id_;
   const client_id scheduler_client_id_;
 
   MessageBus *bus_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/SelectOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/SelectOperator.cpp b/relational_operators/SelectOperator.cpp
index 845c563..3081eac 100644
--- a/relational_operators/SelectOperator.cpp
+++ b/relational_operators/SelectOperator.cpp
@@ -159,7 +159,7 @@ serialization::WorkOrder* SelectOperator::createWorkOrderProto(const partition_i
 }
 
 void SelectWorkOrder::execute() {
-  output_destination_->setInputPartitionId(part_id_);
+  output_destination_->setInputPartitionId(partition_id_);
 
   BlockReference block(
       storage_manager_->getBlock(input_block_id_, input_relation_, getPreferredNUMANodes()[0]));

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/SelectOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/SelectOperator.hpp b/relational_operators/SelectOperator.hpp
index c11d681..f4937b3 100644
--- a/relational_operators/SelectOperator.hpp
+++ b/relational_operators/SelectOperator.hpp
@@ -295,9 +295,8 @@ class SelectWorkOrder : public WorkOrder {
                   StorageManager *storage_manager,
                   LIPFilterAdaptiveProber *lip_filter_adaptive_prober,
                   const numa_node_id numa_node = 0)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         input_relation_(input_relation),
-        part_id_(part_id),
         input_block_id_(input_block_id),
         predicate_(predicate),
         simple_projection_(simple_projection),
@@ -343,9 +342,8 @@ class SelectWorkOrder : public WorkOrder {
                   StorageManager *storage_manager,
                   LIPFilterAdaptiveProber *lip_filter_adaptive_prober,
                   const numa_node_id numa_node = 0)
-      : WorkOrder(query_id),
+      : WorkOrder(query_id, part_id),
         input_relation_(input_relation),
-        part_id_(part_id),
         input_block_id_(input_block_id),
         predicate_(predicate),
         simple_projection_(simple_projection),
@@ -371,7 +369,6 @@ class SelectWorkOrder : public WorkOrder {
 
  private:
   const CatalogRelationSchema &input_relation_;
-  const partition_id part_id_;
   const block_id input_block_id_;
   const Predicate *predicate_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/WorkOrder.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/WorkOrder.hpp b/relational_operators/WorkOrder.hpp
index 97f2a74..c1b3dad 100644
--- a/relational_operators/WorkOrder.hpp
+++ b/relational_operators/WorkOrder.hpp
@@ -27,6 +27,7 @@
 #include <utility>
 #include <vector>
 
+#include "catalog/CatalogTypedefs.hpp"
 #include "query_execution/QueryExecutionTypedefs.hpp"
 #include "utility/Macros.hpp"
 
@@ -295,20 +296,34 @@ class WorkOrder {
   /**
    * @brief Get the ID of the query which this WorkOder belongs to.
    **/
-  inline const std::size_t getQueryID() const {
+  inline std::size_t getQueryID() const {
     return query_id_;
   }
 
+  /**
+   * @brief Get the partition id.
+   *
+   * @return The partition id.
+   */
+  partition_id getPartitionId() const {
+    return partition_id_;
+  }
+
  protected:
   /**
    * @brief Constructor.
    *
    * @param query_id The ID of the query to which this WorkOrder belongs.
+   * @param part_id The partition id.
    **/
-  explicit WorkOrder(const std::size_t query_id)
-      : query_id_(query_id) {}
+  explicit WorkOrder(const std::size_t query_id,
+                     const partition_id part_id = 0)
+      : query_id_(query_id),
+        partition_id_(part_id) {}
 
   const std::size_t query_id_;
+  const partition_id partition_id_;
+
   // A vector of preferred NUMA node IDs where this workorder should be executed.
   // These node IDs typically indicate the NUMA node IDs of the input(s) of the
   // workorder. Derived classes should ensure that there are no duplicate entries

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/32b5b83f/relational_operators/WorkOrderFactory.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/WorkOrderFactory.cpp b/relational_operators/WorkOrderFactory.cpp
index 2b0bae4..68f7f55 100644
--- a/relational_operators/WorkOrderFactory.cpp
+++ b/relational_operators/WorkOrderFactory.cpp
@@ -96,6 +96,7 @@ WorkOrder* WorkOrderFactory::ReconstructFromProto(const serialization::WorkOrder
                 << " in Shiftboss " << shiftboss_index;
       return new AggregationWorkOrder(
           query_id,
+          part_id,
           proto.GetExtension(serialization::AggregationWorkOrder::block_id),
           query_context->getAggregationState(
               proto.GetExtension(serialization::AggregationWorkOrder::aggr_state_index), part_id),
@@ -113,6 +114,7 @@ WorkOrder* WorkOrderFactory::ReconstructFromProto(const serialization::WorkOrder
           query_id,
           catalog_database->getRelationSchemaById(
               proto.GetExtension(serialization::BuildAggregationExistenceMapWorkOrder::relation_id)),
+          part_id,
           proto.GetExtension(serialization::BuildAggregationExistenceMapWorkOrder::build_block_id),
           proto.GetExtension(serialization::BuildAggregationExistenceMapWorkOrder::build_attribute),
           query_context->getAggregationState(
@@ -120,7 +122,10 @@ WorkOrder* WorkOrderFactory::ReconstructFromProto(const serialization::WorkOrder
           storage_manager);
     }
     case serialization::BUILD_LIP_FILTER: {
-      LOG(INFO) << "Creating BuildLIPFilterWorkOrder for Query " << query_id
+      const partition_id part_id =
+          proto.GetExtension(serialization::BuildLIPFilterWorkOrder::partition_id);
+
+      LOG(INFO) << "Creating BuildLIPFilterWorkOrder (Partition " << part_id << ") for Query " << query_id
                 << " in Shiftboss " << shiftboss_index;
 
       const QueryContext::lip_deployment_id lip_deployment_index =
@@ -130,6 +135,7 @@ WorkOrder* WorkOrderFactory::ReconstructFromProto(const serialization::WorkOrder
           query_id,
           catalog_database->getRelationSchemaById(
               proto.GetExtension(serialization::BuildLIPFilterWorkOrder::relation_id)),
+          part_id,
           proto.GetExtension(serialization::BuildLIPFilterWorkOrder::build_block_id),
           query_context->getPredicate(
               proto.GetExtension(serialization::BuildLIPFilterWorkOrder::build_side_predicate_index)),
@@ -379,6 +385,7 @@ WorkOrder* WorkOrderFactory::ReconstructFromProto(const serialization::WorkOrder
           query_context->getAggregationState(
               proto.GetExtension(serialization::InitializeAggregationWorkOrder::aggr_state_index), part_id);
       return new InitializeAggregationWorkOrder(query_id,
+                                                part_id,
                                                 proto.GetExtension(
                                                     serialization::InitializeAggregationWorkOrder::state_partition_id),
                                                 aggr_state);
@@ -393,7 +400,10 @@ WorkOrder* WorkOrderFactory::ReconstructFromProto(const serialization::WorkOrder
               proto.GetExtension(serialization::InsertWorkOrder::tuple_index)));
     }
     case serialization::NESTED_LOOP_JOIN: {
-      LOG(INFO) << "Creating NestedLoopsJoinWorkOrder for Query " << query_id
+      const partition_id part_id =
+          proto.GetExtension(serialization::NestedLoopsJoinWorkOrder::partition_id);
+
+      LOG(INFO) << "Creating NestedLoopsJoinWorkOrder (Partition " << part_id << ") for Query " << query_id
                 << " in Shiftboss " << shiftboss_index;
       return new NestedLoopsJoinWorkOrder(
           query_id,
@@ -401,6 +411,7 @@ WorkOrder* WorkOrderFactory::ReconstructFromProto(const serialization::WorkOrder
               proto.GetExtension(serialization::NestedLoopsJoinWorkOrder::left_relation_id)),
           catalog_database->getRelationSchemaById(
               proto.GetExtension(serialization::NestedLoopsJoinWorkOrder::right_relation_id)),
+          part_id,
           proto.GetExtension(serialization::NestedLoopsJoinWorkOrder::left_block_id),
           proto.GetExtension(serialization::NestedLoopsJoinWorkOrder::right_block_id),
           query_context->getPredicate(


[05/12] incubator-quickstep git commit: Added has_repartition in RelationalOperators.

Posted by ji...@apache.org.
Added has_repartition in RelationalOperators.


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/5f066fa4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/5f066fa4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/5f066fa4

Branch: refs/heads/copy-to
Commit: 5f066fa4bd53ec11d82c4a68bd3a120c65c873e8
Parents: 942a15b
Author: Zuyu Zhang <zu...@cs.wisc.edu>
Authored: Wed Aug 9 14:24:03 2017 -0500
Committer: Zuyu Zhang <zu...@cs.wisc.edu>
Committed: Sun Aug 27 00:59:20 2017 -0500

----------------------------------------------------------------------
 query_optimizer/ExecutionGenerator.cpp          |  18 ++
 query_optimizer/physical/Aggregate.cpp          |   3 +
 query_optimizer/physical/Aggregate.hpp          |  14 +-
 query_optimizer/physical/BinaryJoin.cpp         |   3 +
 query_optimizer/physical/BinaryJoin.hpp         |   4 +-
 query_optimizer/physical/HashJoin.cpp           |   1 +
 query_optimizer/physical/HashJoin.hpp           |  13 +-
 query_optimizer/physical/Join.hpp               |   4 +-
 query_optimizer/physical/NestedLoopsJoin.hpp    |  14 +-
 query_optimizer/physical/Physical.hpp           |  21 ++-
 query_optimizer/physical/Selection.cpp          |   9 +-
 query_optimizer/physical/Selection.hpp          |  13 +-
 query_optimizer/physical/TableGenerator.hpp     |   9 +-
 query_optimizer/physical/TableReference.hpp     |   2 +-
 query_optimizer/rules/Partition.cpp             |  30 +++-
 .../physical_generator/CommonSubexpression.test |  23 ++-
 .../tests/physical_generator/Join.test          |  44 ++---
 .../tests/physical_generator/Select.test        | 164 +++++++++----------
 .../FinalizeAggregationOperator.hpp             |   4 +-
 relational_operators/HashJoinOperator.hpp       |   4 +-
 .../NestedLoopsJoinOperator.hpp                 |   4 +-
 relational_operators/RelationalOperator.hpp     |  15 +-
 relational_operators/SelectOperator.hpp         |   8 +-
 .../tests/AggregationOperator_unittest.cpp      |   3 +
 .../tests/HashJoinOperator_unittest.cpp         |  12 ++
 25 files changed, 281 insertions(+), 158 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/ExecutionGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/ExecutionGenerator.cpp b/query_optimizer/ExecutionGenerator.cpp
index d43432c..d82a0c7 100644
--- a/query_optimizer/ExecutionGenerator.cpp
+++ b/query_optimizer/ExecutionGenerator.cpp
@@ -747,6 +747,8 @@ void ExecutionGenerator::convertSelection(
                                  insert_destination_proto);
 
   // Create and add a Select operator.
+  const bool has_repartition = physical_selection->hasRepartition();
+
   // Use the "simple" form of the selection operator (a pure projection that
   // doesn't require any expression evaluation or intermediate copies) if
   // possible.
@@ -755,6 +757,7 @@ void ExecutionGenerator::convertSelection(
       convertSimpleProjection(project_expressions_group_index, &attributes)
           ? new SelectOperator(query_handle_->query_id(),
                                input_relation,
+                               has_repartition,
                                *output_relation,
                                insert_destination_index,
                                execution_predicate_index,
@@ -762,6 +765,7 @@ void ExecutionGenerator::convertSelection(
                                input_relation_info->isStoredRelation())
           : new SelectOperator(query_handle_->query_id(),
                                input_relation,
+                               has_repartition,
                                *output_relation,
                                insert_destination_index,
                                execution_predicate_index,
@@ -1040,6 +1044,7 @@ void ExecutionGenerator::convertHashJoin(const P::HashJoinPtr &physical_plan) {
               probe_attribute_ids,
               any_probe_attributes_nullable,
               probe_num_partitions,
+              physical_plan->hasRepartition(),
               *output_relation,
               insert_destination_index,
               join_hash_table_index,
@@ -1152,6 +1157,7 @@ void ExecutionGenerator::convertNestedLoopsJoin(
                                       left_relation,
                                       right_relation,
                                       num_partitions,
+                                      physical_plan->hasRepartition(),
                                       *output_relation,
                                       insert_destination_index,
                                       execution_join_predicate_index,
@@ -1539,6 +1545,15 @@ void ExecutionGenerator::convertInsertSelection(
         static_cast<const ScalarAttribute*>(attribute.get())->getAttribute().getID());
   }
 
+  const P::PartitionSchemeHeader *input_physical_partition_scheme_header =
+      physical_plan->selection()->getOutputPartitionSchemeHeader();
+  const P::PartitionSchemeHeader *output_physical_partition_scheme_header =
+      physical_plan->destination()->getOutputPartitionSchemeHeader();
+  const bool has_repartition =
+      (input_physical_partition_scheme_header && output_physical_partition_scheme_header)
+          ? input_physical_partition_scheme_header->equal(*output_physical_partition_scheme_header)
+          : (input_physical_partition_scheme_header || output_physical_partition_scheme_header);
+
   // Create the select operator.
   // TODO(jianqiao): This select operator is actually redundant. That is,
   // we may directly set physical_plan_->selection()'s output relation to be
@@ -1549,6 +1564,7 @@ void ExecutionGenerator::convertInsertSelection(
   SelectOperator *insert_selection_op =
       new SelectOperator(query_handle_->query_id(),
                          selection_relation,
+                         has_repartition,
                          destination_relation,
                          insert_destination_index,
                          QueryContext::kInvalidPredicateId,
@@ -1901,6 +1917,7 @@ void ExecutionGenerator::convertAggregate(
           new FinalizeAggregationOperator(query_handle_->query_id(),
                                           aggr_state_index,
                                           num_partitions,
+                                          physical_plan->hasRepartition(),
                                           aggr_state_num_partitions,
                                           *output_relation,
                                           insert_destination_index));
@@ -2078,6 +2095,7 @@ void ExecutionGenerator::convertCrossReferenceCoalesceAggregate(
           new FinalizeAggregationOperator(query_handle_->query_id(),
                                           aggr_state_index,
                                           num_partitions,
+                                          physical_plan->hasRepartition(),
                                           aggr_state_num_partitions,
                                           *output_relation,
                                           insert_destination_index));

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/Aggregate.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/Aggregate.cpp b/query_optimizer/physical/Aggregate.cpp
index f249e95..94be616 100644
--- a/query_optimizer/physical/Aggregate.cpp
+++ b/query_optimizer/physical/Aggregate.cpp
@@ -96,6 +96,9 @@ void Aggregate::getFieldStringItems(
     std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
     std::vector<std::string> *container_child_field_names,
     std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
+  inline_field_names->push_back("has_repartition");
+  inline_field_values->push_back(has_repartition_ ? "true" : "false");
+
   if (partition_scheme_header_) {
     inline_field_names->push_back("output_partition_scheme_header");
     inline_field_values->push_back(partition_scheme_header_->toString());

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/Aggregate.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/Aggregate.hpp b/query_optimizer/physical/Aggregate.hpp
index c19a951..68f8811 100644
--- a/query_optimizer/physical/Aggregate.hpp
+++ b/query_optimizer/physical/Aggregate.hpp
@@ -89,7 +89,7 @@ class Aggregate : public Physical {
       const std::vector<PhysicalPtr> &new_children) const override {
     DCHECK_EQ(getNumChildren(), new_children.size());
     return Create(new_children[0], grouping_expressions_, aggregate_expressions_, filter_predicate_,
-                  cloneOutputPartitionSchemeHeader());
+                  has_repartition_, cloneOutputPartitionSchemeHeader());
   }
 
   std::vector<expressions::AttributeReferencePtr> getOutputAttributes() const override;
@@ -97,9 +97,10 @@ class Aggregate : public Physical {
   std::vector<expressions::AttributeReferencePtr> getReferencedAttributes() const override;
 
   PhysicalPtr copyWithNewOutputPartitionSchemeHeader(
-      PartitionSchemeHeader *partition_scheme_header) const override {
+      PartitionSchemeHeader *partition_scheme_header,
+      const bool has_repartition = true) const override {
     return Create(input_, grouping_expressions_, aggregate_expressions_, filter_predicate_,
-                  partition_scheme_header);
+                  has_repartition, partition_scheme_header);
   }
 
   bool maybeCopyWithPrunedExpressions(
@@ -125,9 +126,11 @@ class Aggregate : public Physical {
       const std::vector<expressions::NamedExpressionPtr> &grouping_expressions,
       const std::vector<expressions::AliasPtr> &aggregate_expressions,
       const expressions::PredicatePtr &filter_predicate,
+      const bool has_repartition = false,
       PartitionSchemeHeader *partition_scheme_header = nullptr) {
     return AggregatePtr(
-        new Aggregate(input, grouping_expressions, aggregate_expressions, filter_predicate, partition_scheme_header));
+        new Aggregate(input, grouping_expressions, aggregate_expressions, filter_predicate, has_repartition,
+                      partition_scheme_header));
   }
 
  protected:
@@ -145,8 +148,9 @@ class Aggregate : public Physical {
       const std::vector<expressions::NamedExpressionPtr> &grouping_expressions,
       const std::vector<expressions::AliasPtr> &aggregate_expressions,
       const expressions::PredicatePtr &filter_predicate,
+      const bool has_repartition,
       PartitionSchemeHeader *partition_scheme_header)
-      : Physical(partition_scheme_header),
+      : Physical(has_repartition, partition_scheme_header),
         input_(input),
         grouping_expressions_(grouping_expressions),
         aggregate_expressions_(aggregate_expressions),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/BinaryJoin.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/BinaryJoin.cpp b/query_optimizer/physical/BinaryJoin.cpp
index 1928198..b8e8609 100644
--- a/query_optimizer/physical/BinaryJoin.cpp
+++ b/query_optimizer/physical/BinaryJoin.cpp
@@ -40,6 +40,9 @@ void BinaryJoin::getFieldStringItems(
     std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
     std::vector<std::string> *container_child_field_names,
     std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
+  inline_field_names->push_back("has_repartition");
+  inline_field_values->push_back(has_repartition_ ? "true" : "false");
+
   if (partition_scheme_header_) {
     inline_field_names->push_back("output_partition_scheme_header");
     inline_field_values->push_back(partition_scheme_header_->toString());

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/BinaryJoin.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/BinaryJoin.hpp b/query_optimizer/physical/BinaryJoin.hpp
index d1f652f..39d5e31 100644
--- a/query_optimizer/physical/BinaryJoin.hpp
+++ b/query_optimizer/physical/BinaryJoin.hpp
@@ -70,13 +70,15 @@ class BinaryJoin : public Join {
    * @param left The left operand.
    * @param right The right operand.
    * @param project_expressions The project expressions.
+   * @param has_repartition Whether this node has repartition.
    * @param partition_scheme_header The optional output partition scheme header.
    */
   BinaryJoin(const PhysicalPtr &left,
              const PhysicalPtr &right,
              const std::vector<expressions::NamedExpressionPtr> &project_expressions,
+             const bool has_repartition = false,
              PartitionSchemeHeader *partition_scheme_header = nullptr)
-      : Join(project_expressions, partition_scheme_header),
+      : Join(project_expressions, has_repartition, partition_scheme_header),
         left_(left),
         right_(right) {
     addChild(left_);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/HashJoin.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/HashJoin.cpp b/query_optimizer/physical/HashJoin.cpp
index b0ee913..a49bc8e 100644
--- a/query_optimizer/physical/HashJoin.cpp
+++ b/query_optimizer/physical/HashJoin.cpp
@@ -81,6 +81,7 @@ bool HashJoin::maybeCopyWithPrunedExpressions(
                      residual_predicate_,
                      new_project_expressions,
                      join_type_,
+                     has_repartition_,
                      cloneOutputPartitionSchemeHeader());
     return true;
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/HashJoin.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/HashJoin.hpp b/query_optimizer/physical/HashJoin.hpp
index 1804d4b..2ed83af 100644
--- a/query_optimizer/physical/HashJoin.hpp
+++ b/query_optimizer/physical/HashJoin.hpp
@@ -119,15 +119,18 @@ class HashJoin : public BinaryJoin {
                   residual_predicate_,
                   project_expressions(),
                   join_type_,
+                  has_repartition_,
                   cloneOutputPartitionSchemeHeader());
   }
 
   std::vector<expressions::AttributeReferencePtr> getReferencedAttributes() const override;
 
   PhysicalPtr copyWithNewOutputPartitionSchemeHeader(
-      PartitionSchemeHeader *partition_scheme_header) const override {
+      PartitionSchemeHeader *partition_scheme_header,
+      const bool has_repartition = true) const override {
     return Create(left(), right(), left_join_attributes_, right_join_attributes_,
-                  residual_predicate_, project_expressions(), join_type_, partition_scheme_header);
+                  residual_predicate_, project_expressions(), join_type_,
+                  has_repartition, partition_scheme_header);
   }
 
   bool maybeCopyWithPrunedExpressions(
@@ -145,6 +148,7 @@ class HashJoin : public BinaryJoin {
    * @param residual_predicate Optional filtering predicate evaluated after join.
    * @param project_expressions The project expressions.
    * @param Join type of this hash join.
+   * @param has_repartition Whether this node has repartition.
    * @param partition_scheme_header The optional output partition scheme header.
    *
    * @return An immutable physical HashJoin.
@@ -157,6 +161,7 @@ class HashJoin : public BinaryJoin {
       const expressions::PredicatePtr &residual_predicate,
       const std::vector<expressions::NamedExpressionPtr> &project_expressions,
       const JoinType join_type,
+      const bool has_repartition = false,
       PartitionSchemeHeader *partition_scheme_header = nullptr) {
     return HashJoinPtr(
         new HashJoin(left,
@@ -166,6 +171,7 @@ class HashJoin : public BinaryJoin {
                      residual_predicate,
                      project_expressions,
                      join_type,
+                     has_repartition,
                      partition_scheme_header));
   }
 
@@ -187,8 +193,9 @@ class HashJoin : public BinaryJoin {
       const expressions::PredicatePtr &residual_predicate,
       const std::vector<expressions::NamedExpressionPtr> &project_expressions,
       const JoinType join_type,
+      const bool has_repartition,
       PartitionSchemeHeader *partition_scheme_header)
-      : BinaryJoin(left, right, project_expressions, partition_scheme_header),
+      : BinaryJoin(left, right, project_expressions, has_repartition, partition_scheme_header),
         left_join_attributes_(left_join_attributes),
         right_join_attributes_(right_join_attributes),
         residual_predicate_(residual_predicate),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/Join.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/Join.hpp b/query_optimizer/physical/Join.hpp
index d72d072..63f67c8 100644
--- a/query_optimizer/physical/Join.hpp
+++ b/query_optimizer/physical/Join.hpp
@@ -70,12 +70,14 @@ class Join : public Physical {
    * @brief Constructor.
    *
    * @param project_expressions The project expressions.
+   * @param has_repartition Whether this node has repartition.
    * @param partition_scheme_header The optional output partition scheme header.
    */
   explicit Join(
       const std::vector<expressions::NamedExpressionPtr>& project_expressions,
+      const bool has_repartition = false,
       PartitionSchemeHeader *partition_scheme_header = nullptr)
-      : Physical(partition_scheme_header),
+      : Physical(has_repartition, partition_scheme_header),
         project_expressions_(project_expressions) {}
 
  private:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/NestedLoopsJoin.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/NestedLoopsJoin.hpp b/query_optimizer/physical/NestedLoopsJoin.hpp
index f4c3a42..0e0260c 100644
--- a/query_optimizer/physical/NestedLoopsJoin.hpp
+++ b/query_optimizer/physical/NestedLoopsJoin.hpp
@@ -75,6 +75,7 @@ class NestedLoopsJoin : public BinaryJoin {
                   new_children[1],
                   join_predicate_,
                   project_expressions(),
+                  has_repartition_,
                   cloneOutputPartitionSchemeHeader());
   }
 
@@ -85,8 +86,10 @@ class NestedLoopsJoin : public BinaryJoin {
       PhysicalPtr *output) const override;
 
   PhysicalPtr copyWithNewOutputPartitionSchemeHeader(
-      PartitionSchemeHeader *partition_scheme_header) const override {
-    return Create(left(), right(), join_predicate_, project_expressions(), partition_scheme_header);
+      PartitionSchemeHeader *partition_scheme_header,
+      const bool has_repartition = true) const override {
+    return Create(left(), right(), join_predicate_, project_expressions(),
+                  has_repartition, partition_scheme_header);
   }
 
   /**
@@ -105,9 +108,11 @@ class NestedLoopsJoin : public BinaryJoin {
       const PhysicalPtr &right,
       const expressions::PredicatePtr &join_predicate,
       const std::vector<expressions::NamedExpressionPtr> &project_expressions,
+      const bool has_repartition = false,
       PartitionSchemeHeader *partition_scheme_header = nullptr) {
     return NestedLoopsJoinPtr(
-        new NestedLoopsJoin(left, right, join_predicate, project_expressions, partition_scheme_header));
+        new NestedLoopsJoin(left, right, join_predicate, project_expressions,
+                            has_repartition, partition_scheme_header));
   }
 
  protected:
@@ -125,8 +130,9 @@ class NestedLoopsJoin : public BinaryJoin {
       const PhysicalPtr &right,
       const expressions::PredicatePtr &join_predicate,
       const std::vector<expressions::NamedExpressionPtr> &project_expressions,
+      const bool has_repartition,
       PartitionSchemeHeader *partition_scheme_header)
-      : BinaryJoin(left, right, project_expressions, partition_scheme_header),
+      : BinaryJoin(left, right, project_expressions, has_repartition, partition_scheme_header),
         join_predicate_(join_predicate) {
     DCHECK(join_predicate_ != nullptr);
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/Physical.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/Physical.hpp b/query_optimizer/physical/Physical.hpp
index a3a56d0..4491520 100644
--- a/query_optimizer/physical/Physical.hpp
+++ b/query_optimizer/physical/Physical.hpp
@@ -95,12 +95,14 @@ class Physical : public OptimizerTree<Physical> {
    * @param partition_scheme_header The partition scheme header to be
    *        substituted for the existing one, if any. It takes ownership of
    *        'partition_scheme_header'.
+   * @param has_repartition Whether the new node does repartition.
    *
    * @return A copy with \p partition_scheme_header as the partition scheme
    *         header.
    */
   virtual PhysicalPtr copyWithNewOutputPartitionSchemeHeader(
-      PartitionSchemeHeader *partition_scheme_header) const {
+      PartitionSchemeHeader *partition_scheme_header,
+      const bool has_repartition = true) const {
     std::unique_ptr<PartitionSchemeHeader> new_partition_scheme_header(partition_scheme_header);
     LOG(FATAL) << "copyWithNewOutputPartitionSchemeHeader is not implemented for " << getName();
   }
@@ -128,16 +130,29 @@ class Physical : public OptimizerTree<Physical> {
     return nullptr;
   }
 
+  /**
+   * @brief Whether the physical plan node does repartition.
+   *
+   * @return True if this node does repartition. Otherwise, false.
+   **/
+  bool hasRepartition() const {
+    return has_repartition_;
+  }
+
  protected:
   /**
    * @brief Constructor.
    *
+   * @param has_repartition Whether this node does repartition.
    * @param partition_scheme_header The partition scheme header of the relation.
    *        The constructor takes ownership of 'partition_scheme_header'.
    */
-  explicit Physical(PartitionSchemeHeader *partition_scheme_header = nullptr)
-      : partition_scheme_header_(partition_scheme_header) {}
+  explicit Physical(const bool has_repartition = false,
+                    PartitionSchemeHeader *partition_scheme_header = nullptr)
+      : has_repartition_(has_repartition),
+        partition_scheme_header_(partition_scheme_header) {}
 
+  const bool has_repartition_;
   std::unique_ptr<PartitionSchemeHeader> partition_scheme_header_;
 
  private:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/Selection.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/Selection.cpp b/query_optimizer/physical/Selection.cpp
index 3307e9e..b2b3f7e 100644
--- a/query_optimizer/physical/Selection.cpp
+++ b/query_optimizer/physical/Selection.cpp
@@ -45,7 +45,8 @@ namespace E = ::quickstep::optimizer::expressions;
 PhysicalPtr Selection::copyWithNewChildren(
     const std::vector<PhysicalPtr> &new_children) const {
   DCHECK_EQ(children().size(), new_children.size());
-  return Create(new_children[0], project_expressions_, filter_predicate_, cloneOutputPartitionSchemeHeader());
+  return Create(new_children[0], project_expressions_, filter_predicate_,
+                has_repartition_, cloneOutputPartitionSchemeHeader());
 }
 
 std::vector<E::AttributeReferencePtr> Selection::getOutputAttributes() const {
@@ -82,7 +83,8 @@ bool Selection::maybeCopyWithPrunedExpressions(
     }
   }
   if (new_project_expressions.size() != project_expressions_.size()) {
-    *output = Create(input(), new_project_expressions, filter_predicate_, cloneOutputPartitionSchemeHeader());
+    *output = Create(input(), new_project_expressions, filter_predicate_,
+                     has_repartition_, cloneOutputPartitionSchemeHeader());
     return true;
   }
   return false;
@@ -95,6 +97,9 @@ void Selection::getFieldStringItems(
     std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
     std::vector<std::string> *container_child_field_names,
     std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
+  inline_field_names->push_back("has_repartition");
+  inline_field_values->push_back(has_repartition_ ? "true" : "false");
+
   if (partition_scheme_header_) {
     inline_field_names->push_back("output_partition_scheme_header");
     inline_field_values->push_back(partition_scheme_header_->toString());

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/Selection.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/Selection.hpp b/query_optimizer/physical/Selection.hpp
index 4cbc856..2b50061 100644
--- a/query_optimizer/physical/Selection.hpp
+++ b/query_optimizer/physical/Selection.hpp
@@ -85,8 +85,10 @@ class Selection : public Physical {
   std::vector<expressions::AttributeReferencePtr> getReferencedAttributes() const override;
 
   PhysicalPtr copyWithNewOutputPartitionSchemeHeader(
-      PartitionSchemeHeader *partition_scheme_header) const override {
-    return Create(input(), project_expressions_, filter_predicate_, partition_scheme_header);
+      PartitionSchemeHeader *partition_scheme_header,
+      const bool has_repartition = true) const override {
+    return Create(input(), project_expressions_, filter_predicate_,
+                  has_repartition, partition_scheme_header);
   }
 
   bool maybeCopyWithPrunedExpressions(
@@ -109,9 +111,11 @@ class Selection : public Physical {
       const PhysicalPtr &input,
       const std::vector<expressions::NamedExpressionPtr> &project_expressions,
       const expressions::PredicatePtr &filter_predicate,
+      const bool has_repartition = false,
       PartitionSchemeHeader *output_partition_scheme_header = nullptr) {
     return SelectionPtr(
-        new Selection(input, project_expressions, filter_predicate, output_partition_scheme_header));
+        new Selection(input, project_expressions, filter_predicate,
+                      has_repartition, output_partition_scheme_header));
   }
 
   /**
@@ -153,8 +157,9 @@ class Selection : public Physical {
       const PhysicalPtr &input,
       const std::vector<expressions::NamedExpressionPtr> &project_expressions,
       const expressions::PredicatePtr &filter_predicate,
+      const bool has_repartition,
       PartitionSchemeHeader *partition_scheme_header)
-      : Physical(partition_scheme_header),
+      : Physical(has_repartition, partition_scheme_header),
         project_expressions_(project_expressions),
         filter_predicate_(filter_predicate) {
     addChild(input);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/TableGenerator.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/TableGenerator.hpp b/query_optimizer/physical/TableGenerator.hpp
index 4d6419f..0798165 100644
--- a/query_optimizer/physical/TableGenerator.hpp
+++ b/query_optimizer/physical/TableGenerator.hpp
@@ -102,9 +102,11 @@ class TableGenerator : public Physical {
   }
 
   PhysicalPtr copyWithNewOutputPartitionSchemeHeader(
-      PartitionSchemeHeader *partition_scheme_header) const override {
+      PartitionSchemeHeader *partition_scheme_header,
+      const bool has_repartition = true) const override {
     return TableGeneratorPtr(
-        new TableGenerator(generator_function_handle_, table_alias_, attribute_list_, partition_scheme_header));
+        new TableGenerator(generator_function_handle_, table_alias_, attribute_list_,
+                           partition_scheme_header != nullptr, partition_scheme_header));
   }
 
   void getFieldStringItems(
@@ -152,8 +154,9 @@ class TableGenerator : public Physical {
   TableGenerator(const GeneratorFunctionHandlePtr &generator_function_handle,
                  const std::string &table_alias,
                  const std::vector<E::AttributeReferencePtr> &attribute_list,
+                 const bool has_repartition = false,
                  PartitionSchemeHeader *partition_scheme_header = nullptr)
-      : Physical(partition_scheme_header),
+      : Physical(has_repartition, partition_scheme_header),
         generator_function_handle_(generator_function_handle),
         table_alias_(table_alias),
         attribute_list_(attribute_list) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/physical/TableReference.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/TableReference.hpp b/query_optimizer/physical/TableReference.hpp
index bdc0578..85cb76b 100644
--- a/query_optimizer/physical/TableReference.hpp
+++ b/query_optimizer/physical/TableReference.hpp
@@ -114,7 +114,7 @@ class TableReference : public Physical {
       const CatalogRelation *relation, const std::string &alias,
       const std::vector<expressions::AttributeReferencePtr> &attribute_list,
       PartitionSchemeHeader *partition_scheme_header)
-      : Physical(partition_scheme_header),
+      : Physical(false /* has_repartition */, partition_scheme_header),
         relation_(relation),
         alias_(alias),
         attribute_list_(attribute_list) {}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/rules/Partition.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/Partition.cpp b/query_optimizer/rules/Partition.cpp
index fd4deb3..5f8b2c6 100644
--- a/query_optimizer/rules/Partition.cpp
+++ b/query_optimizer/rules/Partition.cpp
@@ -100,7 +100,8 @@ P::PhysicalPtr Repartition(const P::PhysicalPtr &node, P::PartitionSchemeHeader
     // Add a Selection node.
     return P::Selection::Create(node,
                                 CastSharedPtrVector<E::NamedExpression>(node->getOutputAttributes()),
-                                nullptr /* filter_predicate */, repartition_scheme_header);
+                                nullptr /* filter_predicate */,
+                                true /* has_repartition */, repartition_scheme_header);
   } else {
     // Overwrite the output partition scheme header of the node.
     return node->copyWithNewOutputPartitionSchemeHeader(repartition_scheme_header);
@@ -180,7 +181,8 @@ P::PhysicalPtr applyToNestedLoopsJoin(const P::NestedLoopsJoinPtr &nested_loops_
       // Add a Selection node.
       left = P::Selection::Create(left,
                                   CastSharedPtrVector<E::NamedExpression>(left->getOutputAttributes()),
-                                  nullptr /* filter_predicate */, left_repartition_scheme_header.release());
+                                  nullptr /* filter_predicate */,
+                                  true /* has_repartition */, left_repartition_scheme_header.release());
       break;
     default: {
       if (!left_partition_scheme_header) {
@@ -199,7 +201,8 @@ P::PhysicalPtr applyToNestedLoopsJoin(const P::NestedLoopsJoinPtr &nested_loops_
       // Add a Selection node.
       right = P::Selection::Create(right,
                                    CastSharedPtrVector<E::NamedExpression>(right->getOutputAttributes()),
-                                   nullptr /* filter_predicate */, right_repartition_scheme_header.release());
+                                   nullptr /* filter_predicate */,
+                                   true /* has_repartition */, right_repartition_scheme_header.release());
     } else {
       right = right->copyWithNewOutputPartitionSchemeHeader(right_repartition_scheme_header.release());
     }
@@ -227,9 +230,11 @@ P::PhysicalPtr applyToNestedLoopsJoin(const P::NestedLoopsJoinPtr &nested_loops_
   }
 
   std::unique_ptr<P::PartitionSchemeHeader> output_partition_scheme_header;
+  bool has_repartition = false;
   if (left_partition_expr_ids != output_partition_expr_ids) {
     output_partition_scheme_header = make_unique<P::PartitionSchemeHeader>(
         left_partition_scheme_header->partition_type, num_partitions, move(output_partition_expr_ids));
+    has_repartition = true;
   } else {
     output_partition_scheme_header = make_unique<P::PartitionSchemeHeader>(*left_partition_scheme_header);
   }
@@ -237,6 +242,7 @@ P::PhysicalPtr applyToNestedLoopsJoin(const P::NestedLoopsJoinPtr &nested_loops_
   return P::NestedLoopsJoin::Create(left, right,
                                     nested_loops_join->join_predicate(),
                                     nested_loops_join->project_expressions(),
+                                    has_repartition,
                                     output_partition_scheme_header.release());
 }
 
@@ -277,7 +283,8 @@ P::PhysicalPtr Partition::applyToNode(const P::PhysicalPtr &node) {
               input_partition_scheme_header->num_partitions,
               move(output_partition_expr_ids));
 
-          return aggregate->copyWithNewOutputPartitionSchemeHeader(output_partition_scheme_header.release());
+          return aggregate->copyWithNewOutputPartitionSchemeHeader(output_partition_scheme_header.release(),
+                                                                   false /* has_repartition */);
         }
       }
 
@@ -364,7 +371,8 @@ P::PhysicalPtr Partition::applyToNode(const P::PhysicalPtr &node) {
           avg_recompute_expressions.empty()
               ? aggregate->copyWithNewOutputPartitionSchemeHeader(output_partition_scheme_header.release())
               : P::Aggregate::Create(input, grouping_expressions, partial_aggregate_expressions,
-                                     filter_predicate, output_partition_scheme_header.release());
+                                     filter_predicate, true /* has_repartition */,
+                                     output_partition_scheme_header.release());
 
       vector<E::AliasPtr> reaggregate_expressions;
       for (const auto &aggregate_expr : partial_aggregate_expressions) {
@@ -383,7 +391,8 @@ P::PhysicalPtr Partition::applyToNode(const P::PhysicalPtr &node) {
       }
       const P::AggregatePtr reaggregate =
           P::Aggregate::Create(partial_aggregate, grouping_expressions, reaggregate_expressions,
-                               nullptr /* filter_predicate */, output_partition_scheme_header.release());
+                               nullptr /* filter_predicate */, false /* has_repartition */,
+                               output_partition_scheme_header.release());
 
       if (avg_recompute_expressions.empty()) {
         return reaggregate;
@@ -419,7 +428,7 @@ P::PhysicalPtr Partition::applyToNode(const P::PhysicalPtr &node) {
             make_unique<P::PartitionSchemeHeader>(*reaggregate->getOutputPartitionSchemeHeader());
       }
       return P::Selection::Create(reaggregate, project_expressions, nullptr /* filter_predicate */,
-                                  output_partition_scheme_header.release());
+                                  false /* has_repartition */, output_partition_scheme_header.release());
     }
     case P::PhysicalType::kHashJoin: {
       const P::HashJoinPtr hash_join = static_pointer_cast<const P::HashJoin>(node);
@@ -489,10 +498,12 @@ P::PhysicalPtr Partition::applyToNode(const P::PhysicalPtr &node) {
                                    hash_join->residual_predicate(),
                                    hash_join->project_expressions(),
                                    hash_join->join_type(),
+                                   false /* has_repartition */,
                                    output_partition_scheme_header.release());
       }
 
-      return hash_join->copyWithNewOutputPartitionSchemeHeader(output_partition_scheme_header.release());
+      return hash_join->copyWithNewOutputPartitionSchemeHeader(output_partition_scheme_header.release(),
+                                                               false /* has_repartition */);
     }
     case P::PhysicalType::kNestedLoopsJoin: {
       const P::NestedLoopsJoinPtr nested_loops_join = static_pointer_cast<const P::NestedLoopsJoin>(node);
@@ -552,7 +563,8 @@ P::PhysicalPtr Partition::applyToNode(const P::PhysicalPtr &node) {
       // TODO(quickstep-team): Check RangePartitionSchemeHeader against the project expressions.
       DCHECK(input_partition_scheme_header->partition_type != P::PartitionSchemeHeader::PartitionType::kRange);
       auto output_partition_scheme_header = make_unique<P::PartitionSchemeHeader>(*input_partition_scheme_header);
-      return selection->copyWithNewOutputPartitionSchemeHeader(output_partition_scheme_header.release());
+      return selection->copyWithNewOutputPartitionSchemeHeader(output_partition_scheme_header.release(),
+                                                               false /* has_repartition */);
     }
     default:
       break;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/tests/physical_generator/CommonSubexpression.test
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/physical_generator/CommonSubexpression.test b/query_optimizer/tests/physical_generator/CommonSubexpression.test
index b23a97d..147cfeb 100644
--- a/query_optimizer/tests/physical_generator/CommonSubexpression.test
+++ b/query_optimizer/tests/physical_generator/CommonSubexpression.test
@@ -44,7 +44,7 @@ TopLevelPlan
   +-AttributeReference[id=7,name=,alias=(1+int_col),relation=,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=TableReference[relation=Test,alias=test]
 | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -114,8 +114,8 @@ TopLevelPlan
     type=Float NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
-| +-input=Aggregate
++-plan=Selection[has_repartition=false]
+| +-input=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -216,7 +216,7 @@ TopLevelPlan
     type=Float NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashJoin
++-plan=HashJoin[has_repartition=false]
 | +-left=TableGenerator[function_name=generate_series,table_alias=g]
 | | +-AttributeReference[id=6,name=generate_series,alias=g,
 | |   relation=generate_series,type=Int]
@@ -318,7 +318,7 @@ TopLevelPlan
     type=Float NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=NestedLoopsJoin
++-plan=NestedLoopsJoin[has_repartition=false]
 | +-left=TableReference[relation=Test,alias=test]
 | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -416,7 +416,7 @@ TopLevelPlan
   +-AttributeReference[id=7,name=result,relation=,type=Long]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=TableReference[relation=Test,alias=test]
 | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -512,7 +512,7 @@ TopLevelPlan
   +-AttributeReference[id=8,name=,alias=(int_col+1),relation=,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=TableReference[relation=Test,alias=test]
 | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -627,8 +627,8 @@ TopLevelPlan
   +-AttributeReference[id=11,name=,alias=COUNT(*),relation=,type=Long]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
-| +-input=Aggregate
++-plan=Selection[has_repartition=false]
+| +-input=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -731,8 +731,8 @@ TopLevelPlan
     type=Long NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
-| +-input=Aggregate
++-plan=Selection[has_repartition=false]
+| +-input=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -769,4 +769,3 @@ TopLevelPlan
   | type=Long NULL]
   +-AttributeReference[id=9,name=,alias=((SUM((long_col+1))+2)*3),relation=,
     type=Long NULL]
-==

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/tests/physical_generator/Join.test
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/physical_generator/Join.test b/query_optimizer/tests/physical_generator/Join.test
index 4ebbac7..45ea0ed 100644
--- a/query_optimizer/tests/physical_generator/Join.test
+++ b/query_optimizer/tests/physical_generator/Join.test
@@ -23,9 +23,9 @@ FROM a JOIN b ON a.w = b.w
        JOIN d ON a.y = d.y;
 --
 TopLevelPlan
-+-plan=HashJoin
-| +-left=HashJoin
-| | +-left=HashJoin
++-plan=HashJoin[has_repartition=false]
+| +-left=HashJoin[has_repartition=false]
+| | +-left=HashJoin[has_repartition=false]
 | | | +-left=TableReference[relation=a]
 | | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
 | | | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
@@ -71,9 +71,9 @@ FROM a JOIN b ON (a.w = b.w OR a.x > b.x)
        JOIN d ON (a.y = d.y OR a.z > d.z);
 --
 TopLevelPlan
-+-plan=NestedLoopsJoin
-| +-left=HashJoin
-| | +-left=NestedLoopsJoin
++-plan=NestedLoopsJoin[has_repartition=false]
+| +-left=HashJoin[has_repartition=false]
+| | +-left=NestedLoopsJoin[has_repartition=false]
 | | | +-left=TableReference[relation=a]
 | | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
 | | | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
@@ -131,9 +131,9 @@ WHERE a1.x = b1.x
   AND a1.z = d1.z;
 --
 TopLevelPlan
-+-plan=HashJoin
-| +-left=HashJoin
-| | +-left=HashJoin
++-plan=HashJoin[has_repartition=false]
+| +-left=HashJoin[has_repartition=false]
+| | +-left=HashJoin[has_repartition=false]
 | | | +-left=TableReference[relation=a,alias=a1]
 | | | | +-AttributeReference[id=0,name=w,relation=a1,type=Int]
 | | | | +-AttributeReference[id=1,name=x,relation=a1,type=Int]
@@ -188,9 +188,9 @@ WHERE a1.x = b1.x
   AND a1.z = d1.z;
 --
 TopLevelPlan
-+-plan=HashJoin
-| +-left=HashJoin
-| | +-left=HashJoin
++-plan=HashJoin[has_repartition=false]
+| +-left=HashJoin[has_repartition=false]
+| | +-left=HashJoin[has_repartition=false]
 | | | +-left=TableReference[relation=a,alias=a1]
 | | | | +-AttributeReference[id=0,name=w,relation=a1,type=Int]
 | | | | +-AttributeReference[id=1,name=x,relation=a1,type=Int]
@@ -245,9 +245,9 @@ FROM a LEFT JOIN b ON a.w = b.w
        LEFT JOIN d ON a.y = d.y;
 --
 TopLevelPlan
-+-plan=HashLeftOuterJoin
-| +-left=HashLeftOuterJoin
-| | +-left=HashLeftOuterJoin
++-plan=HashLeftOuterJoin[has_repartition=false]
+| +-left=HashLeftOuterJoin[has_repartition=false]
+| | +-left=HashLeftOuterJoin[has_repartition=false]
 | | | +-left=TableReference[relation=a]
 | | | | +-AttributeReference[id=0,name=w,relation=a,type=Int]
 | | | | +-AttributeReference[id=1,name=x,relation=a,type=Int]
@@ -304,10 +304,10 @@ WHERE b.x > 10
   AND c.y > 20;
 --
 TopLevelPlan
-+-plan=HashLeftOuterJoin
-| +-left=HashJoin
-| | +-left=HashLeftOuterJoin
-| | | +-left=Selection
++-plan=HashLeftOuterJoin[has_repartition=false]
+| +-left=HashJoin[has_repartition=false]
+| | +-left=HashLeftOuterJoin[has_repartition=false]
+| | | +-left=Selection[has_repartition=false]
 | | | | +-input=TableReference[relation=b]
 | | | | | +-AttributeReference[id=4,name=w,relation=b,type=Int]
 | | | | | +-AttributeReference[id=5,name=x,relation=b,type=Int]
@@ -331,7 +331,7 @@ TopLevelPlan
 | | | | +-AttributeReference[id=4,name=w,relation=b,type=Int]
 | | | +-right_join_attributes=
 | | |   +-AttributeReference[id=0,name=w,relation=a,type=Int]
-| | +-right=Selection
+| | +-right=Selection[has_repartition=false]
 | | | +-input=TableReference[relation=c]
 | | | | +-AttributeReference[id=6,name=x,relation=c,type=Int]
 | | | | +-AttributeReference[id=7,name=y,relation=c,type=Int]
@@ -373,11 +373,11 @@ SELECT *
 FROM b LEFT JOIN c ON (b.x = c.x AND c.x > 10);
 --
 TopLevelPlan
-+-plan=HashLeftOuterJoin
++-plan=HashLeftOuterJoin[has_repartition=false]
 | +-left=TableReference[relation=b]
 | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
 | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
-| +-right=Selection
+| +-right=Selection[has_repartition=false]
 | | +-input=TableReference[relation=c]
 | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
 | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/query_optimizer/tests/physical_generator/Select.test
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/physical_generator/Select.test b/query_optimizer/tests/physical_generator/Select.test
index dc923ae..8bb6599 100644
--- a/query_optimizer/tests/physical_generator/Select.test
+++ b/query_optimizer/tests/physical_generator/Select.test
@@ -44,7 +44,7 @@ TopLevelPlan
   +-AttributeReference[id=5,name=vchar_col,relation=test,type=VarChar(20) NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=TableReference[relation=Test,alias=test]
 | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -90,7 +90,7 @@ TopLevelPlan
   +-AttributeReference[id=7,name=,alias=2,relation=,type=Int]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=TableReference[relation=Test,alias=test]
 | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -148,7 +148,7 @@ TopLevelPlan
     type=Float NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashJoin
++-plan=HashJoin[has_repartition=false]
 | +-left=TableReference[relation=Test,alias=a]
 | | +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=a,type=Long]
@@ -233,7 +233,7 @@ TopLevelPlan
   +-AttributeReference[id=9,name=int_col,relation=,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=TableReference[relation=Test,alias=test]
 | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -325,7 +325,7 @@ TopLevelPlan
   +-AttributeReference[id=12,name=float_col,relation=b,type=Float]
 [Physical Plan]
 TopLevelPlan
-+-plan=NestedLoopsJoin
++-plan=NestedLoopsJoin[has_repartition=false]
 | +-left=TableReference[relation=Test,alias=a]
 | | +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=a,type=Long]
@@ -421,7 +421,7 @@ TopLevelPlan
   +-AttributeReference[id=8,name=float_col,relation=b,type=Float]
 [Physical Plan]
 TopLevelPlan
-+-plan=NestedLoopsJoin
++-plan=NestedLoopsJoin[has_repartition=false]
 | +-left=TableReference[relation=Test,alias=a]
 | | +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=a,type=Long]
@@ -429,7 +429,7 @@ TopLevelPlan
 | | +-AttributeReference[id=3,name=double_col,relation=a,type=Double NULL]
 | | +-AttributeReference[id=4,name=char_col,relation=a,type=Char(20)]
 | | +-AttributeReference[id=5,name=vchar_col,relation=a,type=VarChar(20) NULL]
-| +-right=Selection
+| +-right=Selection[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=7,name=long_col,relation=test,type=Long]
@@ -518,7 +518,7 @@ TopLevelPlan
   +-AttributeReference[id=12,name=float_col,relation=b,type=Float]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashJoin
++-plan=HashJoin[has_repartition=false]
 | +-left=TableReference[relation=Test,alias=a]
 | | +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=a,type=Long]
@@ -526,7 +526,7 @@ TopLevelPlan
 | | +-AttributeReference[id=3,name=double_col,relation=a,type=Double NULL]
 | | +-AttributeReference[id=4,name=char_col,relation=a,type=Char(20)]
 | | +-AttributeReference[id=5,name=vchar_col,relation=a,type=VarChar(20) NULL]
-| +-right=Selection
+| +-right=Selection[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=7,name=long_col,relation=test,type=Long]
@@ -604,7 +604,7 @@ TopLevelPlan
   +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashJoin
++-plan=HashJoin[has_repartition=false]
 | +-left=TableReference[relation=Test,alias=a]
 | | +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=a,type=Long]
@@ -675,7 +675,7 @@ TopLevelPlan
   +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashJoin
++-plan=HashJoin[has_repartition=false]
 | +-left=TableReference[relation=Test,alias=a]
 | | +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=a,type=Long]
@@ -683,7 +683,7 @@ TopLevelPlan
 | | +-AttributeReference[id=3,name=double_col,relation=a,type=Double NULL]
 | | +-AttributeReference[id=4,name=char_col,relation=a,type=Char(20)]
 | | +-AttributeReference[id=5,name=vchar_col,relation=a,type=VarChar(20) NULL]
-| +-right=Selection
+| +-right=Selection[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=7,name=long_col,relation=test,type=Long]
@@ -755,7 +755,7 @@ TopLevelPlan
   +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashJoin
++-plan=HashJoin[has_repartition=false]
 | +-left=TableReference[relation=Test,alias=a]
 | | +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=a,type=Long]
@@ -835,8 +835,8 @@ TopLevelPlan
   +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=NestedLoopsJoin
-| +-left=HashJoin
++-plan=NestedLoopsJoin[has_repartition=false]
+| +-left=HashJoin[has_repartition=false]
 | | +-left=TableReference[relation=Test,alias=a]
 | | | +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=a,type=Long]
@@ -857,7 +857,7 @@ TopLevelPlan
 | | | +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 | | +-right_join_attributes=
 | |   +-AttributeReference[id=7,name=long_col,relation=b,type=Long]
-| +-right=Selection
+| +-right=Selection[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=c]
 | | | +-AttributeReference[id=12,name=int_col,relation=c,type=Int NULL]
 | | | +-AttributeReference[id=13,name=long_col,relation=c,type=Long]
@@ -916,7 +916,7 @@ TopLevelPlan
   +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=NestedLoopsJoin
++-plan=NestedLoopsJoin[has_repartition=false]
 | +-left=TableReference[relation=Test,alias=a]
 | | +-AttributeReference[id=0,name=int_col,relation=a,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=a,type=Long]
@@ -924,7 +924,7 @@ TopLevelPlan
 | | +-AttributeReference[id=3,name=double_col,relation=a,type=Double NULL]
 | | +-AttributeReference[id=4,name=char_col,relation=a,type=Char(20)]
 | | +-AttributeReference[id=5,name=vchar_col,relation=a,type=VarChar(20) NULL]
-| +-right=Selection
+| +-right=Selection[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=7,name=long_col,relation=test,type=Long]
@@ -1021,8 +1021,8 @@ TopLevelPlan
   +-AttributeReference[id=10,name=col,relation=,type=Double NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
-| +-input=Aggregate
++-plan=Selection[has_repartition=false]
+| +-input=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -1157,8 +1157,8 @@ TopLevelPlan
   +-AttributeReference[id=6,name=col2,relation=,type=Long]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
-| +-input=Aggregate
++-plan=Selection[has_repartition=false]
+| +-input=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -1296,8 +1296,8 @@ TopLevelPlan
   +-AttributeReference[id=4,name=subquery_col3,relation=subquery,type=Char(20)]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
-| +-input=Aggregate
++-plan=Selection[has_repartition=false]
+| +-input=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -1407,8 +1407,8 @@ TopLevelPlan
   +-AttributeReference[id=6,name=,alias=count(*),relation=,type=Long]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
-| +-input=Aggregate
++-plan=Selection[has_repartition=false]
+| +-input=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -1465,8 +1465,8 @@ TopLevelPlan
   +-AttributeReference[id=6,name=,alias=count(*),relation=,type=Long]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
-| +-input=Aggregate
++-plan=Selection[has_repartition=false]
+| +-input=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -1522,8 +1522,8 @@ TopLevelPlan
   +-AttributeReference[id=7,name=,alias=count(*),relation=,type=Long]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
-| +-input=Aggregate
++-plan=Selection[has_repartition=false]
+| +-input=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -1585,7 +1585,7 @@ TopLevelPlan
   +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=SharedSubplanReference[subplan_id=0]
 | | +-referenced_attributes=
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
@@ -1598,7 +1598,7 @@ TopLevelPlan
 | +-project_expressions=
 |   +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
 +-shared_subplans=
-| +-Selection
+| +-Selection[has_repartition=false]
 |   +-input=TableReference[relation=Test,alias=test]
 |   | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 |   | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -1673,8 +1673,8 @@ TopLevelPlan
     type=Double NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
-| +-input=Aggregate
++-plan=Selection[has_repartition=false]
+| +-input=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -1786,9 +1786,9 @@ TopLevelPlan
   +-AttributeReference[id=1,name=i,relation=,type=Int]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashLeftSemiJoin
-| +-left=HashLeftAntiJoin
-| | +-left=Selection
++-plan=HashLeftSemiJoin[has_repartition=false]
+| +-left=HashLeftAntiJoin[has_repartition=false]
+| | +-left=Selection[has_repartition=false]
 | | | +-input=TableGenerator[function_name=generate_series,table_alias=gs1]
 | | | | +-AttributeReference[id=0,name=generate_series,alias=gs1,
 | | | |   relation=generate_series,type=Int]
@@ -1859,7 +1859,7 @@ TopLevelPlan
   +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=TableReference[relation=Test,alias=test]
 | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -1925,7 +1925,7 @@ TopLevelPlan
   +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=TableReference[relation=Test,alias=test]
 | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -2014,7 +2014,7 @@ TopLevelPlan
   +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashLeftSemiJoin
++-plan=HashLeftSemiJoin[has_repartition=false]
 | +-left=TableReference[relation=Test,alias=test]
 | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -2022,8 +2022,8 @@ TopLevelPlan
 | | +-AttributeReference[id=3,name=double_col,relation=test,type=Double NULL]
 | | +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
 | | +-AttributeReference[id=5,name=vchar_col,relation=test,type=VarChar(20) NULL]
-| +-right=Selection
-| | +-input=Aggregate
+| +-right=Selection[has_repartition=false]
+| | +-input=Aggregate[has_repartition=false]
 | | | +-input=TableReference[relation=Test,alias=test]
 | | | | +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
 | | | | +-AttributeReference[id=7,name=long_col,relation=test,type=Long]
@@ -2105,7 +2105,7 @@ TopLevelPlan
   +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashLeftAntiJoin
++-plan=HashLeftAntiJoin[has_repartition=false]
 | +-left=TableReference[relation=Test,alias=test]
 | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -2113,7 +2113,7 @@ TopLevelPlan
 | | +-AttributeReference[id=3,name=double_col,relation=test,type=Double NULL]
 | | +-AttributeReference[id=4,name=char_col,relation=test,type=Char(20)]
 | | +-AttributeReference[id=5,name=vchar_col,relation=test,type=VarChar(20) NULL]
-| +-right=Selection
+| +-right=Selection[has_repartition=false]
 | | +-input=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=7,name=long_col,relation=test,type=Long]
@@ -2179,11 +2179,11 @@ TopLevelPlan
     type=Long NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=NestedLoopsJoin
++-plan=NestedLoopsJoin[has_repartition=false]
 | +-left=TableReference[relation=b]
 | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
 | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
-| +-right=Aggregate
+| +-right=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=c]
 | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
 | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
@@ -2246,8 +2246,8 @@ TopLevelPlan
     type=Long NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashJoin
-| +-left=Aggregate
++-plan=HashJoin[has_repartition=false]
+| +-left=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=c]
 | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
 | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
@@ -2313,11 +2313,11 @@ TopLevelPlan
   +-AttributeReference[id=1,name=x,relation=b,type=Int]
 [Physical Plan]
 TopLevelPlan
-+-plan=NestedLoopsJoin
++-plan=NestedLoopsJoin[has_repartition=false]
 | +-left=TableReference[relation=b]
 | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
 | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
-| +-right=Aggregate
+| +-right=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=c]
 | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
 | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
@@ -2383,8 +2383,8 @@ TopLevelPlan
   +-AttributeReference[id=1,name=x,relation=b,type=Int]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashJoin
-| +-left=Aggregate
++-plan=HashJoin[has_repartition=false]
+| +-left=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=c]
 | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
 | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
@@ -2490,9 +2490,9 @@ TopLevelPlan
     type=Long NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=HashJoin
-| +-left=NestedLoopsJoin
-| | +-left=Aggregate
++-plan=HashJoin[has_repartition=false]
+| +-left=NestedLoopsJoin[has_repartition=false]
+| | +-left=Aggregate[has_repartition=false]
 | | | +-input=TableReference[relation=c]
 | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
 | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
@@ -2505,7 +2505,7 @@ TopLevelPlan
 | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,type=Long NULL]
 | | |     +-AggregateFunction[function=SUM]
 | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
-| | +-right=Aggregate
+| | +-right=Aggregate[has_repartition=false]
 | | | +-input=TableReference[relation=a]
 | | | | +-AttributeReference[id=5,name=w,relation=a,type=Int]
 | | | | +-AttributeReference[id=6,name=x,relation=a,type=Int]
@@ -2606,12 +2606,12 @@ TopLevelPlan
     alias=((x*SubqueryExpression)+SubqueryExpression),relation=,type=Double NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=NestedLoopsJoin
++-plan=NestedLoopsJoin[has_repartition=false]
 | +-left=TableReference[relation=b]
 | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
 | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
-| +-right=NestedLoopsJoin
-| | +-left=Aggregate
+| +-right=NestedLoopsJoin[has_repartition=false]
+| | +-left=Aggregate[has_repartition=false]
 | | | +-input=TableReference[relation=c]
 | | | | +-AttributeReference[id=2,name=x,relation=c,type=Int]
 | | | | +-AttributeReference[id=3,name=y,relation=c,type=Int]
@@ -2621,7 +2621,7 @@ TopLevelPlan
 | | |   +-Alias[id=4,name=,alias=$aggregate0,relation=$aggregate,type=Long NULL]
 | | |     +-AggregateFunction[function=SUM]
 | | |       +-AttributeReference[id=3,name=y,relation=c,type=Int]
-| | +-right=Aggregate
+| | +-right=Aggregate[has_repartition=false]
 | | | +-input=TableReference[relation=d]
 | | | | +-AttributeReference[id=5,name=y,relation=d,type=Int]
 | | | | +-AttributeReference[id=6,name=z,relation=d,type=Int]
@@ -2712,12 +2712,12 @@ TopLevelPlan
     type=Long NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=NestedLoopsJoin
-| +-left=NestedLoopsJoin
++-plan=NestedLoopsJoin[has_repartition=false]
+| +-left=NestedLoopsJoin[has_repartition=false]
 | | +-left=TableReference[relation=b]
 | | | +-AttributeReference[id=0,name=w,relation=b,type=Int]
 | | | +-AttributeReference[id=1,name=x,relation=b,type=Int]
-| | +-right=Aggregate
+| | +-right=Aggregate[has_repartition=false]
 | | | +-input=TableReference[relation=d]
 | | | | +-AttributeReference[id=2,name=y,relation=d,type=Int]
 | | | | +-AttributeReference[id=3,name=z,relation=d,type=Int]
@@ -2734,7 +2734,7 @@ TopLevelPlan
 | | |   type=Double NULL]
 | | +-project_expressions=
 | |   +-AttributeReference[id=1,name=x,relation=b,type=Int]
-| +-right=Aggregate
+| +-right=Aggregate[has_repartition=false]
 | | +-input=TableReference[relation=c]
 | | | +-AttributeReference[id=5,name=x,relation=c,type=Int]
 | | | +-AttributeReference[id=6,name=y,relation=c,type=Int]
@@ -2835,9 +2835,9 @@ TopLevelPlan
   +-AttributeReference[id=6,name=y,relation=,type=Int]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=Sort[is_ascending=[true],nulls_first=[false]]
-| | +-input=HashJoin
+| | +-input=HashJoin[has_repartition=false]
 | | | +-left=SharedSubplanReference[subplan_id=0]
 | | | | +-referenced_attributes=
 | | | | | +-AttributeReference[id=3,name=x,relation=,type=Int]
@@ -2845,7 +2845,7 @@ TopLevelPlan
 | | | | +-output_attributes=
 | | | |   +-AttributeReference[id=5,name=x,relation=,type=Int]
 | | | |   +-AttributeReference[id=6,name=y,relation=,type=Int]
-| | | +-right=Aggregate
+| | | +-right=Aggregate[has_repartition=false]
 | | | | +-input=SharedSubplanReference[subplan_id=0]
 | | | | | +-referenced_attributes=
 | | | | | | +-AttributeReference[id=3,name=x,relation=,type=Int]
@@ -2875,7 +2875,7 @@ TopLevelPlan
 |   +-AttributeReference[id=5,name=x,relation=,type=Int]
 |   +-AttributeReference[id=6,name=y,relation=,type=Int]
 +-shared_subplans=
-| +-Selection
+| +-Selection[has_repartition=false]
 |   +-input=TableGenerator[function_name=generate_series,table_alias=g]
 |   | +-AttributeReference[id=0,name=generate_series,alias=g,
 |   |   relation=generate_series,type=Int]
@@ -2934,7 +2934,7 @@ TopLevelPlan
   +-AttributeReference[id=6,name=,alias=avg(int_col),relation=,type=Double NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=WindowAggregate
 | | +-input=Sort[is_ascending=[true,false],nulls_first=[false,false]]
 | | | +-input=TableReference[relation=Test,alias=test]
@@ -3018,7 +3018,7 @@ TopLevelPlan
     type=Double NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=WindowAggregate
 | | +-input=Sort[is_ascending=[true,true,false,true],
 | | | nulls_first=[false,false,false,true]]
@@ -3113,8 +3113,8 @@ TopLevelPlan
     type=Double NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
-| +-input=Aggregate
++-plan=Selection[has_repartition=false]
+| +-input=Aggregate[has_repartition=false]
 | | +-input=WindowAggregate
 | | | +-input=Sort[is_ascending=[true,true],nulls_first=[false,false]]
 | | | | +-input=TableReference[relation=Test,alias=test]
@@ -3192,10 +3192,10 @@ TopLevelPlan
   +-AttributeReference[id=12,name=int_col,relation=,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Aggregate
++-plan=Aggregate[has_repartition=false]
 | +-input=UnionAll
 | | +-operands=
-| | | +-Selection
+| | | +-Selection[has_repartition=false]
 | | | | +-input=TableReference[relation=Test,alias=test]
 | | | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -3207,7 +3207,7 @@ TopLevelPlan
 | | | | |   type=VarChar(20) NULL]
 | | | | +-project_expressions=
 | | | |   +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
-| | | +-Selection
+| | | +-Selection[has_repartition=false]
 | | |   +-input=TableReference[relation=Test,alias=test]
 | | |   | +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
 | | |   | +-AttributeReference[id=7,name=long_col,relation=test,type=Long]
@@ -3278,10 +3278,10 @@ TopLevelPlan
   +-AttributeReference[id=14,name=intv,relation=,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Selection
++-plan=Selection[has_repartition=false]
 | +-input=UnionAll
 | | +-operands=
-| | | +-Selection
+| | | +-Selection[has_repartition=false]
 | | | | +-input=TableReference[relation=Test,alias=test]
 | | | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -3293,7 +3293,7 @@ TopLevelPlan
 | | | | |   type=VarChar(20) NULL]
 | | | | +-project_expressions=
 | | | |   +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
-| | | +-Selection
+| | | +-Selection[has_repartition=false]
 | | |   +-input=TableReference[relation=Test,alias=test]
 | | |   | +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
 | | |   | +-AttributeReference[id=7,name=long_col,relation=test,type=Long]
@@ -3384,8 +3384,8 @@ TopLevelPlan
   +-AttributeReference[id=22,name=int_col,relation=,type=Int NULL]
 [Physical Plan]
 TopLevelPlan
-+-plan=Aggregate
-| +-input=HashLeftSemiJoin
++-plan=Aggregate[has_repartition=false]
+| +-input=HashLeftSemiJoin[has_repartition=false]
 | | +-left=TableReference[relation=Test,alias=test]
 | | | +-AttributeReference[id=0,name=int_col,relation=test,type=Int NULL]
 | | | +-AttributeReference[id=1,name=long_col,relation=test,type=Long]
@@ -3396,7 +3396,7 @@ TopLevelPlan
 | | |   type=VarChar(20) NULL]
 | | +-right=UnionAll
 | | | +-operands=
-| | | | +-Selection
+| | | | +-Selection[has_repartition=false]
 | | | | | +-input=TableReference[relation=Test,alias=test]
 | | | | | | +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
 | | | | | | +-AttributeReference[id=7,name=long_col,relation=test,type=Long]
@@ -3408,7 +3408,7 @@ TopLevelPlan
 | | | | | |   type=VarChar(20) NULL]
 | | | | | +-project_expressions=
 | | | | |   +-AttributeReference[id=6,name=int_col,relation=test,type=Int NULL]
-| | | | +-Selection
+| | | | +-Selection[has_repartition=false]
 | | | |   +-input=TableReference[relation=Test,alias=test]
 | | | |   | +-AttributeReference[id=12,name=int_col,relation=test,type=Int NULL]
 | | | |   | +-AttributeReference[id=13,name=long_col,relation=test,type=Long]

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/relational_operators/FinalizeAggregationOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/FinalizeAggregationOperator.hpp b/relational_operators/FinalizeAggregationOperator.hpp
index 382a7da..b344c13 100644
--- a/relational_operators/FinalizeAggregationOperator.hpp
+++ b/relational_operators/FinalizeAggregationOperator.hpp
@@ -61,6 +61,7 @@ class FinalizeAggregationOperator : public RelationalOperator {
    * @param aggr_state_index The index of the AggregationState in QueryContext.
    * @param num_partitions The number of partitions of 'input_relation' in a
    *        partitioned aggregation. If no partitions, it is one.
+   * @param has_repartition Whether this operator does repartition.
    * @param output_relation The output relation.
    * @param output_destination_index The index of the InsertDestination in the
    *        QueryContext to insert aggregation results.
@@ -69,10 +70,11 @@ class FinalizeAggregationOperator : public RelationalOperator {
       const std::size_t query_id,
       const QueryContext::aggregation_state_id aggr_state_index,
       const std::size_t num_partitions,
+      const bool has_repartition,
       const std::size_t aggr_state_num_partitions,
       const CatalogRelation &output_relation,
       const QueryContext::insert_destination_id output_destination_index)
-      : RelationalOperator(query_id, num_partitions),
+      : RelationalOperator(query_id, num_partitions, has_repartition),
         aggr_state_index_(aggr_state_index),
         aggr_state_num_partitions_(aggr_state_num_partitions),
         output_relation_(output_relation),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/relational_operators/HashJoinOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/HashJoinOperator.hpp b/relational_operators/HashJoinOperator.hpp
index 519718c..a5e6eb4 100644
--- a/relational_operators/HashJoinOperator.hpp
+++ b/relational_operators/HashJoinOperator.hpp
@@ -104,6 +104,7 @@ class HashJoinOperator : public RelationalOperator {
    * @param any_join_key_attributes_nullable If any attribute is nullable.
    * @param num_partitions The number of partitions in 'probe_relation'.
    *        If no partitions, it is one.
+   * @param has_repartition Whether this operator does repartition.
    * @param output_relation The output relation.
    * @param output_destination_index The index of the InsertDestination in the
    *        QueryContext to insert the join results.
@@ -130,6 +131,7 @@ class HashJoinOperator : public RelationalOperator {
       const std::vector<attribute_id> &join_key_attributes,
       const bool any_join_key_attributes_nullable,
       const std::size_t num_partitions,
+      const bool has_repartition,
       const CatalogRelation &output_relation,
       const QueryContext::insert_destination_id output_destination_index,
       const QueryContext::join_hash_table_id hash_table_index,
@@ -137,7 +139,7 @@ class HashJoinOperator : public RelationalOperator {
       const QueryContext::scalar_group_id selection_index,
       const std::vector<bool> *is_selection_on_build = nullptr,
       const JoinType join_type = JoinType::kInnerJoin)
-      : RelationalOperator(query_id, num_partitions),
+      : RelationalOperator(query_id, num_partitions, has_repartition),
         build_relation_(build_relation),
         probe_relation_(probe_relation),
         probe_relation_is_stored_(probe_relation_is_stored),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/relational_operators/NestedLoopsJoinOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/NestedLoopsJoinOperator.hpp b/relational_operators/NestedLoopsJoinOperator.hpp
index 1b14638..777a737 100644
--- a/relational_operators/NestedLoopsJoinOperator.hpp
+++ b/relational_operators/NestedLoopsJoinOperator.hpp
@@ -74,6 +74,7 @@ class NestedLoopsJoinOperator : public RelationalOperator {
    * @param right_input_relation The second relation in the join (order is not
    *        actually important).
    * @param num_partitions The number of partitions.
+   * @param has_repartition Whether this operator does repartition.
    * @param output_relation The output relation.
    * @param output_destination_index The index of the InsertDestination in the
    *        QueryContext to insert the join results.
@@ -94,13 +95,14 @@ class NestedLoopsJoinOperator : public RelationalOperator {
       const CatalogRelation &left_input_relation,
       const CatalogRelation &right_input_relation,
       const std::size_t num_partitions,
+      const bool has_repartition,
       const CatalogRelation &output_relation,
       const QueryContext::insert_destination_id output_destination_index,
       const QueryContext::predicate_id join_predicate_index,
       const QueryContext::scalar_group_id selection_index,
       const bool left_relation_is_stored,
       const bool right_relation_is_stored)
-      : RelationalOperator(query_id, num_partitions),
+      : RelationalOperator(query_id, num_partitions, has_repartition),
         nested_loops_join_index_(nested_loops_join_index),
         left_input_relation_(left_input_relation),
         right_input_relation_(right_input_relation),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/relational_operators/RelationalOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/RelationalOperator.hpp b/relational_operators/RelationalOperator.hpp
index 29ae194..0541bbd 100644
--- a/relational_operators/RelationalOperator.hpp
+++ b/relational_operators/RelationalOperator.hpp
@@ -269,6 +269,15 @@ class RelationalOperator {
   }
 
   /**
+   * @brief Whether this operator does repartition.
+   *
+   * @return True if this node does repartition. Otherwise, false.
+   */
+  bool hasRepartition() const {
+    return has_repartition_;
+  }
+
+  /**
    * @brief Deploy a group of LIPFilters to this operator.
    */
   void deployLIPFilters(const QueryContext::lip_deployment_id lip_deployment_index,
@@ -284,16 +293,20 @@ class RelationalOperator {
    * @param query_id The ID of the query to which this operator belongs.
    * @param num_partitions The number of partitions of the input relation.
    *        If create table / index, return zero. If no partitions, return one.
+   * @param has_repartition Whether this operator does repartition.
    **/
   explicit RelationalOperator(const std::size_t query_id,
-                              const std::size_t num_partitions = 1u)
+                              const std::size_t num_partitions = 1u,
+                              const bool has_repartition = false)
       : query_id_(query_id),
         num_partitions_(num_partitions),
+        has_repartition_(has_repartition),
         done_feeding_input_relation_(false),
         lip_deployment_index_(QueryContext::kInvalidLIPDeploymentId) {}
 
   const std::size_t query_id_;
   const std::size_t num_partitions_;
+  const bool has_repartition_;
 
   bool done_feeding_input_relation_;
   std::size_t op_index_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/relational_operators/SelectOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/SelectOperator.hpp b/relational_operators/SelectOperator.hpp
index a71f4c1..71dcfca 100644
--- a/relational_operators/SelectOperator.hpp
+++ b/relational_operators/SelectOperator.hpp
@@ -74,6 +74,7 @@ class SelectOperator : public RelationalOperator {
    *
    * @param query_id The ID of the query to which this operator belongs.
    * @param input_relation The relation to perform selection over.
+   * @param has_repartition Whether this operator does repartition.
    * @param output_relation The output relation.
    * @param output_destination_index The index of the InsertDestination in the
    *        QueryContext to insert the selection results.
@@ -89,12 +90,13 @@ class SelectOperator : public RelationalOperator {
   SelectOperator(
       const std::size_t query_id,
       const CatalogRelation &input_relation,
+      const bool has_repartition,
       const CatalogRelation &output_relation,
       const QueryContext::insert_destination_id output_destination_index,
       const QueryContext::predicate_id predicate_index,
       const QueryContext::scalar_group_id selection_index,
       const bool input_relation_is_stored)
-      : RelationalOperator(query_id, input_relation.getNumPartitions()),
+      : RelationalOperator(query_id, input_relation.getNumPartitions(), has_repartition),
         input_relation_(input_relation),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
@@ -129,6 +131,7 @@ class SelectOperator : public RelationalOperator {
    *
    * @param query_id The ID of the query to which this operator belongs.
    * @param input_relation The relation to perform selection over.
+   * @param has_repartition Whether this operator does repartition.
    * @param output_relation The output relation.
    * @param output_destination_index The index of the InsertDestination in the
    *        QueryContext to insert the selection results.
@@ -144,12 +147,13 @@ class SelectOperator : public RelationalOperator {
   SelectOperator(
       const std::size_t query_id,
       const CatalogRelation &input_relation,
+      const bool has_repartition,
       const CatalogRelation &output_relation,
       const QueryContext::insert_destination_id output_destination_index,
       const QueryContext::predicate_id predicate_index,
       std::vector<attribute_id> &&selection,
       const bool input_relation_is_stored)
-      : RelationalOperator(query_id, input_relation.getNumPartitions()),
+      : RelationalOperator(query_id, input_relation.getNumPartitions(), has_repartition),
         input_relation_(input_relation),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/relational_operators/tests/AggregationOperator_unittest.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/tests/AggregationOperator_unittest.cpp b/relational_operators/tests/AggregationOperator_unittest.cpp
index 4cda2d1..5c9cc7a 100644
--- a/relational_operators/tests/AggregationOperator_unittest.cpp
+++ b/relational_operators/tests/AggregationOperator_unittest.cpp
@@ -83,6 +83,7 @@ namespace {
 constexpr std::size_t kQueryId = 0;
 constexpr int kOpIndex = 0;
 constexpr std::size_t kNumPartitions = 1u;
+constexpr bool kNoRepartition = false;
 }  // namespace
 
 class Type;
@@ -293,6 +294,7 @@ class AggregationOperatorTest : public ::testing::Test {
         new FinalizeAggregationOperator(kQueryId,
                                         aggr_state_index,
                                         kNumPartitions,
+                                        kNoRepartition,
                                         kNumPartitions,
                                         *result_table_,
                                         insert_destination_index));
@@ -388,6 +390,7 @@ class AggregationOperatorTest : public ::testing::Test {
         new FinalizeAggregationOperator(kQueryId,
                                         aggr_state_index,
                                         kNumPartitions,
+                                        kNoRepartition,
                                         kNumPartitions,
                                         *result_table_,
                                         insert_destination_index));

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5f066fa4/relational_operators/tests/HashJoinOperator_unittest.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/tests/HashJoinOperator_unittest.cpp b/relational_operators/tests/HashJoinOperator_unittest.cpp
index 89aafe5..1fc84fc 100644
--- a/relational_operators/tests/HashJoinOperator_unittest.cpp
+++ b/relational_operators/tests/HashJoinOperator_unittest.cpp
@@ -104,6 +104,9 @@ constexpr int kOpIndex = 0;
 constexpr std::size_t kSinglePartition = 1;
 constexpr std::size_t kMultiplePartitions = 4;
 
+const bool kHasRepartition = true;
+const bool kNoRepartition = false;
+
 }  // namespace
 
 class HashJoinOperatorTest : public ::testing::TestWithParam<HashTableImplType> {
@@ -454,6 +457,7 @@ TEST_P(HashJoinOperatorTest, LongKeyHashJoinTest) {
       std::vector<attribute_id>(1, fact_col_long.getID()),
       fact_col_long.getType().isNullable(),
       kSinglePartition,
+      kNoRepartition,
       *result_table,
       output_destination_index,
       join_hash_table_index,
@@ -604,6 +608,7 @@ TEST_P(HashJoinOperatorTest, IntDuplicateKeyHashJoinTest) {
       std::vector<attribute_id>(1, fact_col_int.getID()),
       fact_col_int.getType().isNullable(),
       kSinglePartition,
+      kNoRepartition,
       *result_table,
       output_destination_index,
       join_hash_table_index,
@@ -763,6 +768,7 @@ TEST_P(HashJoinOperatorTest, CharKeyCartesianProductHashJoinTest) {
       std::vector<attribute_id>(1, fact_col_char.getID()),
       fact_col_char.getType().isNullable(),
       kSinglePartition,
+      kNoRepartition,
       *result_table,
       output_destination_index,
       join_hash_table_index,
@@ -906,6 +912,7 @@ TEST_P(HashJoinOperatorTest, VarCharDuplicateKeyHashJoinTest) {
       std::vector<attribute_id>(1, fact_col_varchar.getID()),
       fact_col_varchar.getType().isNullable(),
       kSinglePartition,
+      kNoRepartition,
       *result_table,
       output_destination_index,
       join_hash_table_index,
@@ -1085,6 +1092,7 @@ TEST_P(HashJoinOperatorTest, CompositeKeyHashJoinTest) {
       fact_col_long.getType().isNullable() ||
           fact_col_varchar.getType().isNullable(),
       kSinglePartition,
+      kNoRepartition,
       *result_table,
       output_destination_index,
       join_hash_table_index,
@@ -1274,6 +1282,7 @@ TEST_P(HashJoinOperatorTest, CompositeKeyHashJoinWithResidualPredicateTest) {
                            fact_col_long.getType().isNullable() ||
                                fact_col_varchar.getType().isNullable(),
                            kSinglePartition,
+                           kNoRepartition,
                            *result_table,
                            output_destination_index,
                            join_hash_table_index,
@@ -1446,6 +1455,7 @@ TEST_P(HashJoinOperatorTest, SinlgeAttributePartitionedLongKeyHashJoinTest) {
       { fact_col_long.getID() },
       fact_col_long.getType().isNullable(),
       kMultiplePartitions,
+      kHasRepartition,
       *result_table,
       output_destination_index,
       join_hash_table_index,
@@ -1591,6 +1601,7 @@ TEST_P(HashJoinOperatorTest, SinlgeAttributePartitionedCompositeKeyHashJoinTest)
       { fact_col_long.getID(), fact_col_varchar.getID() },
       fact_col_long.getType().isNullable() || fact_col_varchar.getType().isNullable(),
       kMultiplePartitions,
+      kHasRepartition,
       *result_table,
       output_destination_index,
       join_hash_table_index,
@@ -1771,6 +1782,7 @@ TEST_P(HashJoinOperatorTest, SinlgeAttributePartitionedCompositeKeyHashJoinWithR
       { fact_col_long.getID(), fact_col_varchar.getID() },
       fact_col_long.getType().isNullable() || fact_col_varchar.getType().isNullable(),
       kMultiplePartitions,
+      kHasRepartition,
       *result_table,
       output_destination_index,
       join_hash_table_index,


[11/12] incubator-quickstep git commit: Add "COPY TO" operator for exporting data from Quickstep.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1e32afc8/parser/preprocessed/SqlLexer_gen.cpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlLexer_gen.cpp b/parser/preprocessed/SqlLexer_gen.cpp
index bd77ee1..4800cde 100644
--- a/parser/preprocessed/SqlLexer_gen.cpp
+++ b/parser/preprocessed/SqlLexer_gen.cpp
@@ -9,88 +9,244 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 3
+#define YY_FLEX_SUBMINOR_VERSION 4
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
 
-    #define yy_create_buffer quickstep_yy_create_buffer
+#ifdef yy_create_buffer
+#define quickstep_yy_create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer quickstep_yy_create_buffer
+#endif
 
-    #define yy_delete_buffer quickstep_yy_delete_buffer
+#ifdef yy_delete_buffer
+#define quickstep_yy_delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer quickstep_yy_delete_buffer
+#endif
 
-    #define yy_scan_buffer quickstep_yy_scan_buffer
+#ifdef yy_scan_buffer
+#define quickstep_yy_scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer quickstep_yy_scan_buffer
+#endif
 
-    #define yy_scan_string quickstep_yy_scan_string
+#ifdef yy_scan_string
+#define quickstep_yy_scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string quickstep_yy_scan_string
+#endif
 
-    #define yy_scan_bytes quickstep_yy_scan_bytes
+#ifdef yy_scan_bytes
+#define quickstep_yy_scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes quickstep_yy_scan_bytes
+#endif
 
-    #define yy_init_buffer quickstep_yy_init_buffer
+#ifdef yy_init_buffer
+#define quickstep_yy_init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer quickstep_yy_init_buffer
+#endif
 
-    #define yy_flush_buffer quickstep_yy_flush_buffer
+#ifdef yy_flush_buffer
+#define quickstep_yy_flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer quickstep_yy_flush_buffer
+#endif
 
-    #define yy_load_buffer_state quickstep_yy_load_buffer_state
+#ifdef yy_load_buffer_state
+#define quickstep_yy_load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state quickstep_yy_load_buffer_state
+#endif
 
-    #define yy_switch_to_buffer quickstep_yy_switch_to_buffer
+#ifdef yy_switch_to_buffer
+#define quickstep_yy_switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer quickstep_yy_switch_to_buffer
+#endif
 
-    #define yypush_buffer_state quickstep_yypush_buffer_state
+#ifdef yypush_buffer_state
+#define quickstep_yypush_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state quickstep_yypush_buffer_state
+#endif
 
-    #define yypop_buffer_state quickstep_yypop_buffer_state
+#ifdef yypop_buffer_state
+#define quickstep_yypop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state quickstep_yypop_buffer_state
+#endif
 
-    #define yyensure_buffer_stack quickstep_yyensure_buffer_stack
+#ifdef yyensure_buffer_stack
+#define quickstep_yyensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack quickstep_yyensure_buffer_stack
+#endif
 
-    #define yylex quickstep_yylex
+#ifdef yylex
+#define quickstep_yylex_ALREADY_DEFINED
+#else
+#define yylex quickstep_yylex
+#endif
 
-    #define yyrestart quickstep_yyrestart
+#ifdef yyrestart
+#define quickstep_yyrestart_ALREADY_DEFINED
+#else
+#define yyrestart quickstep_yyrestart
+#endif
 
-    #define yylex_init quickstep_yylex_init
+#ifdef yylex_init
+#define quickstep_yylex_init_ALREADY_DEFINED
+#else
+#define yylex_init quickstep_yylex_init
+#endif
 
-    #define yylex_init_extra quickstep_yylex_init_extra
+#ifdef yylex_init_extra
+#define quickstep_yylex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra quickstep_yylex_init_extra
+#endif
 
-    #define yylex_destroy quickstep_yylex_destroy
+#ifdef yylex_destroy
+#define quickstep_yylex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy quickstep_yylex_destroy
+#endif
 
-    #define yyget_debug quickstep_yyget_debug
+#ifdef yyget_debug
+#define quickstep_yyget_debug_ALREADY_DEFINED
+#else
+#define yyget_debug quickstep_yyget_debug
+#endif
 
-    #define yyset_debug quickstep_yyset_debug
+#ifdef yyset_debug
+#define quickstep_yyset_debug_ALREADY_DEFINED
+#else
+#define yyset_debug quickstep_yyset_debug
+#endif
 
-    #define yyget_extra quickstep_yyget_extra
+#ifdef yyget_extra
+#define quickstep_yyget_extra_ALREADY_DEFINED
+#else
+#define yyget_extra quickstep_yyget_extra
+#endif
 
-    #define yyset_extra quickstep_yyset_extra
+#ifdef yyset_extra
+#define quickstep_yyset_extra_ALREADY_DEFINED
+#else
+#define yyset_extra quickstep_yyset_extra
+#endif
 
-    #define yyget_in quickstep_yyget_in
+#ifdef yyget_in
+#define quickstep_yyget_in_ALREADY_DEFINED
+#else
+#define yyget_in quickstep_yyget_in
+#endif
 
-    #define yyset_in quickstep_yyset_in
+#ifdef yyset_in
+#define quickstep_yyset_in_ALREADY_DEFINED
+#else
+#define yyset_in quickstep_yyset_in
+#endif
 
-    #define yyget_out quickstep_yyget_out
+#ifdef yyget_out
+#define quickstep_yyget_out_ALREADY_DEFINED
+#else
+#define yyget_out quickstep_yyget_out
+#endif
 
-    #define yyset_out quickstep_yyset_out
+#ifdef yyset_out
+#define quickstep_yyset_out_ALREADY_DEFINED
+#else
+#define yyset_out quickstep_yyset_out
+#endif
 
-    #define yyget_leng quickstep_yyget_leng
+#ifdef yyget_leng
+#define quickstep_yyget_leng_ALREADY_DEFINED
+#else
+#define yyget_leng quickstep_yyget_leng
+#endif
 
-    #define yyget_text quickstep_yyget_text
+#ifdef yyget_text
+#define quickstep_yyget_text_ALREADY_DEFINED
+#else
+#define yyget_text quickstep_yyget_text
+#endif
 
-    #define yyget_lineno quickstep_yyget_lineno
+#ifdef yyget_lineno
+#define quickstep_yyget_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno quickstep_yyget_lineno
+#endif
 
-    #define yyset_lineno quickstep_yyset_lineno
+#ifdef yyset_lineno
+#define quickstep_yyset_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno quickstep_yyset_lineno
+#endif
 
-        #define yyget_column quickstep_yyget_column
+#ifdef yyget_column
+#define quickstep_yyget_column_ALREADY_DEFINED
+#else
+#define yyget_column quickstep_yyget_column
+#endif
 
-        #define yyset_column quickstep_yyset_column
+#ifdef yyset_column
+#define quickstep_yyset_column_ALREADY_DEFINED
+#else
+#define yyset_column quickstep_yyset_column
+#endif
 
-    #define yywrap quickstep_yywrap
+#ifdef yywrap
+#define quickstep_yywrap_ALREADY_DEFINED
+#else
+#define yywrap quickstep_yywrap
+#endif
 
-    #define yyget_lval quickstep_yyget_lval
+#ifdef yyget_lval
+#define quickstep_yyget_lval_ALREADY_DEFINED
+#else
+#define yyget_lval quickstep_yyget_lval
+#endif
 
-    #define yyset_lval quickstep_yyset_lval
+#ifdef yyset_lval
+#define quickstep_yyset_lval_ALREADY_DEFINED
+#else
+#define yyset_lval quickstep_yyset_lval
+#endif
 
-    #define yyget_lloc quickstep_yyget_lloc
+#ifdef yyget_lloc
+#define quickstep_yyget_lloc_ALREADY_DEFINED
+#else
+#define yyget_lloc quickstep_yyget_lloc
+#endif
 
-    #define yyset_lloc quickstep_yyset_lloc
+#ifdef yyset_lloc
+#define quickstep_yyset_lloc_ALREADY_DEFINED
+#else
+#define yyset_lloc quickstep_yyset_lloc
+#endif
 
-    #define yyalloc quickstep_yyalloc
+#ifdef yyalloc
+#define quickstep_yyalloc_ALREADY_DEFINED
+#else
+#define yyalloc quickstep_yyalloc
+#endif
 
-    #define yyrealloc quickstep_yyrealloc
+#ifdef yyrealloc
+#define quickstep_yyrealloc_ALREADY_DEFINED
+#else
+#define yyrealloc quickstep_yyrealloc
+#endif
 
-    #define yyfree quickstep_yyfree
+#ifdef yyfree
+#define quickstep_yyfree_ALREADY_DEFINED
+#else
+#define yyfree quickstep_yyfree
+#endif
 
 /* First, we deal with  platform-specific or compiler-specific issues. */
 
@@ -162,10 +318,16 @@ typedef unsigned int flex_uint32_t;
 #define UINT32_MAX             (4294967295U)
 #endif
 
+#ifndef SIZE_MAX
+#define SIZE_MAX               (~(size_t)0)
+#endif
+
 #endif /* ! C99 */
 
 #endif /* ! FLEXINT_H */
 
+/* begin standard C++ headers. */
+
 /* TODO: this is always defined, so inline it */
 #define yyconst const
 
@@ -214,7 +376,7 @@ typedef void* yyscan_t;
 /* Action number for EOF rule of a given start state. */
 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
 /* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE quickstep_yyrestart(yyin ,yyscanner )
+#define YY_NEW_FILE yyrestart( yyin , yyscanner )
 #define YY_END_OF_BUFFER_CHAR 0
 
 /* Size of default input buffer. */
@@ -250,7 +412,7 @@ typedef size_t yy_size_t;
     
     /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
      *       access to the local variable yy_act. Since yyless() is a macro, it would break
-     *       existing scanners that call yyless() from OUTSIDE quickstep_yylex.
+     *       existing scanners that call yyless() from OUTSIDE yylex.
      *       One obvious solution it to make yy_act a global. I tried that, and saw
      *       a 5% performance hit in a non-yylineno scanner, because yy_act is
      *       normally declared as a register variable-- so it is not worth it.
@@ -342,7 +504,7 @@ struct yy_buffer_state
 	 * possible backing-up.
 	 *
 	 * When we actually see the EOF, we change the status to "new"
-	 * (via quickstep_yyrestart()), so that the user can continue scanning by
+	 * (via yyrestart()), so that the user can continue scanning by
 	 * just pointing yyin at a new input file.
 	 */
 #define YY_BUFFER_EOF_PENDING 2
@@ -364,43 +526,43 @@ struct yy_buffer_state
  */
 #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
 
-void quickstep_yyrestart ( FILE *input_file , yyscan_t yyscanner );
-void quickstep_yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
-YY_BUFFER_STATE quickstep_yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
-void quickstep_yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
-void quickstep_yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
-void quickstep_yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
-void quickstep_yypop_buffer_state ( yyscan_t yyscanner );
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
 
-static void quickstep_yyensure_buffer_stack ( yyscan_t yyscanner );
-static void quickstep_yy_load_buffer_state ( yyscan_t yyscanner );
-static void quickstep_yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
-#define YY_FLUSH_BUFFER quickstep_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+static void yyensure_buffer_stack ( yyscan_t yyscanner );
+static void yy_load_buffer_state ( yyscan_t yyscanner );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner)
 
-YY_BUFFER_STATE quickstep_yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
-YY_BUFFER_STATE quickstep_yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
-YY_BUFFER_STATE quickstep_yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
 
-void *quickstep_yyalloc ( yy_size_t , yyscan_t yyscanner );
-void *quickstep_yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
-void quickstep_yyfree ( void * , yyscan_t yyscanner );
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
 
-#define yy_new_buffer quickstep_yy_create_buffer
+#define yy_new_buffer yy_create_buffer
 #define yy_set_interactive(is_interactive) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){ \
-        quickstep_yyensure_buffer_stack (yyscanner); \
+        yyensure_buffer_stack (yyscanner); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            quickstep_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+            yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
 	}
 #define yy_set_bol(at_bol) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){\
-        quickstep_yyensure_buffer_stack (yyscanner); \
+        yyensure_buffer_stack (yyscanner); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            quickstep_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+            yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
 	}
@@ -430,8 +592,8 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
 	yyg->yy_hold_char = *yy_cp; \
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 163
-#define YY_END_OF_BUFFER 164
+#define YY_NUM_RULES 164
+#define YY_END_OF_BUFFER 165
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -439,74 +601,72 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static const flex_int16_t yy_accept[599] =
+static const flex_int16_t yy_accept[589] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  164,    2,    2,  162,  162,  161,  160,  162,
-      139,  135,  138,  135,  135,  158,  131,  128,  132,  157,
-      157,  157,  157,  157,  157,  157,  157,  157,  157,  157,
-      157,  157,  157,  157,  157,  157,  157,  157,  157,  157,
-      157,  157,  157,  157,  136,    4,    5,    5,    3,  154,
-      154,  151,  155,  155,  149,  156,  156,  153,    1,  161,
-      129,  159,  158,  158,  158,    0,  133,  130,  134,  157,
-      157,  157,  157,   10,  157,  157,  157,   22,  157,  157,
-      157,  157,  157,  157,  157,  157,  157,  157,  157,  137,
-
-      157,  157,  157,  157,  157,  157,  157,  157,  157,  157,
-      157,  157,  157,   60,   69,  157,  157,  157,  157,  157,
-      157,  157,  157,  157,  157,  157,   83,   84,  157,  157,
-      157,  157,  157,  157,  157,  157,  157,  157,  157,  157,
-      157,  157,  157,  157,  157,  157,  157,  157,  157,  157,
-      157,  157,  157,    4,    5,    3,  154,  150,  155,  148,
-      148,  140,  142,  143,  144,  145,  146,  147,  148,  156,
-      152,  159,  158,    0,  158,    6,    7,  157,    9,   11,
-      157,  157,   15,  157,  157,  157,  157,  157,  157,  157,
-      157,  157,  157,  157,   33,  157,  157,  157,  157,  157,
-
-      157,  157,  157,   44,  157,  157,  157,  157,  157,  157,
-      157,   52,  157,  157,  157,  157,  157,  157,  157,  157,
-      157,   64,  157,   71,  157,  157,  157,  157,  157,  157,
-      157,   79,  157,   82,  157,  157,  157,  157,  157,  157,
-      157,  157,  157,  157,  157,  157,  157,  100,  157,  157,
-      105,  106,  157,  157,  157,  157,  157,  157,  157,  157,
-      157,  157,  157,  157,  157,  157,  157,  157,  140,  142,
-      141,  157,  157,  157,  157,  157,  157,  157,   20,   23,
-      157,  157,  157,   28,  157,  157,  157,   31,  157,  157,
-      157,  157,   38,  157,  157,   42,   43,  157,  157,  157,
-
-      157,  157,  157,  157,  157,   54,   55,  157,   57,  157,
-       59,  157,  157,  157,  157,   68,   70,   72,   73,   74,
-      157,   76,  157,  157,   80,  157,  157,   87,  157,  157,
-      157,  157,  157,   94,  157,   96,  157,  157,  157,  102,
-      157,  157,  157,  157,  157,  157,  110,  111,  113,  157,
-      157,  157,  157,  157,  157,  157,  157,  122,  157,  157,
-      125,  126,  140,  141,    8,  157,  157,  157,  157,  157,
-      157,  157,   25,  157,  157,  157,  157,  157,  157,  157,
-      157,  157,  157,  157,  157,  157,  157,  157,  157,   48,
-       49,   50,  157,  157,   56,  157,   61,   62,  157,  157,
-
-      157,   75,  157,   78,   81,   85,   86,  157,  157,  157,
-      157,  157,   95,  157,  157,   99,  157,  157,  157,  157,
-      157,  109,  157,  157,  157,  116,  157,  157,  119,  157,
-      157,  123,  157,  157,  157,  157,   14,  157,  157,  157,
-      157,  157,   26,  157,   29,  157,  157,  157,  157,  157,
-       36,  157,  157,  157,   41,  157,   46,  157,  157,  157,
-       58,   63,  157,  157,  157,   77,  157,  157,  157,  157,
-      157,  157,   98,  157,  103,  104,  157,  157,  157,  157,
-      157,  117,  118,  120,  157,  124,  157,  157,   13,  157,
-      157,  157,  157,  157,  157,   21,   30,  157,   34,   35,
-
-      157,  157,  157,  157,   47,  157,   53,   65,  157,  157,
-      157,   90,  157,   92,  157,  157,  157,  157,  157,  157,
-      157,  157,  121,  157,  157,  157,  157,  157,  157,  157,
-      157,   32,  157,  157,   40,  157,  157,  157,   67,  157,
-      157,   93,  157,  157,  107,  157,  157,  157,  157,  157,
-       12,  157,  157,  157,  157,   24,  157,   37,  157,  157,
-       51,   66,   88,   91,  157,  157,  108,  112,  157,  115,
-      127,   16,  157,  157,  157,   27,   39,  157,   89,   97,
-      157,  157,  157,   18,   19,  157,  157,  114,  157,  157,
-      157,  157,  157,  101,  157,   45,   17,    0
-
+        0,    0,  165,    2,    2,  163,  163,  162,  161,  163,
+      140,  136,  139,  136,  136,  159,  132,  129,  133,  158,
+      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
+      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
+      158,  158,  158,  158,  137,    4,    5,    5,    3,  155,
+      155,  152,  156,  156,  150,  157,  157,  154,    1,  162,
+      130,  160,  159,  159,  159,    0,  134,  131,  135,  158,
+      158,  158,  158,   10,  158,  158,  158,   22,  158,  158,
+      158,  158,  158,  158,  158,  158,  158,  158,  158,  138,
+
+      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
+      158,  158,   58,   67,  158,  158,  158,  158,  158,  158,
+      158,  158,  158,  158,  158,   81,   82,  158,  158,  158,
+      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
+      158,  158,  158,  158,  113,  158,  158,  158,  158,  158,
+      158,  158,  158,  158,    4,    5,    3,  155,  151,  156,
+      149,  149,  141,  143,  144,  145,  146,  147,  148,  149,
+      157,  153,  160,  159,    0,  159,    6,    7,  158,    9,
+       11,  158,  158,   15,  158,  158,  158,  158,  158,  158,
+      158,  158,  158,  158,  158,   33,  158,  158,  158,  158,
+
+      158,  158,  158,  158,   43,  158,  158,  158,  158,  158,
+      158,   50,  158,  158,  158,  158,  158,  158,  158,  158,
+      158,   62,  158,   69,  158,  158,  158,  158,  158,  158,
+      158,   77,  158,   80,  158,  158,  158,  158,  158,  158,
+      158,  158,  158,  158,  158,  158,  158,   98,  158,  158,
+      103,  104,  158,  158,  158,  158,  158,  158,  158,  158,
+      158,  158,  158,  158,  158,  158,  158,  158,  158,  141,
+      143,  142,  158,  158,  158,  158,  158,  158,  158,   20,
+       23,  158,  158,  158,   28,  158,  158,  158,   31,  158,
+      158,  158,   37,  158,  158,   41,   42,  158,  158,  158,
+
+      158,  158,  158,  158,   52,   53,  158,   55,  158,   57,
+      158,  158,  158,  158,   66,   68,   70,   71,   72,  158,
+       74,  158,  158,   78,  158,  158,   85,  158,  158,  158,
+      158,  158,   92,  158,   94,  158,  158,  158,  100,  158,
+      158,  158,  158,  158,  158,  158,  158,  110,  111,  114,
+      158,  158,  158,  158,  158,  158,  158,  158,  123,  158,
+      158,  126,  127,  141,  142,    8,  158,  158,  158,  158,
+      158,  158,  158,   25,  158,  158,  158,  158,  158,  158,
+      158,  158,  158,  158,  158,  158,  158,  158,   46,   47,
+       48,  158,  158,   54,  158,   59,   60,  158,  158,  158,
+
+       73,  158,   76,   79,   83,   84,  158,  158,  158,  158,
+      158,   93,  158,  158,   97,  158,  158,  158,  158,  158,
+      158,  158,  109,  158,  158,  158,  117,  158,  158,  120,
+      158,  158,  124,  158,  158,  158,  158,   14,  158,  158,
+      158,  158,  158,   26,  158,   29,  158,  158,  158,  158,
+      158,   36,  158,  158,   40,   44,  158,  158,  158,   56,
+       61,  158,  158,  158,   75,  158,  158,  158,  158,  158,
+      158,   96,  158,  101,  102,  158,  106,  107,  158,  158,
+      158,  158,  118,  119,  121,  158,  125,  158,  158,   13,
+      158,  158,  158,  158,  158,  158,   21,   30,  158,   34,
+
+       35,  158,  158,   45,  158,   51,   63,  158,  158,  158,
+       88,  158,   90,  158,  158,  158,  158,  158,  158,  158,
+      158,  122,  158,  158,  158,  158,  158,  158,  158,  158,
+       32,  158,   39,  158,  158,   65,  158,  158,   91,  158,
+      158,  105,  158,  158,  158,  158,  158,   12,  158,  158,
+      158,  158,   24,  158,  158,   49,   64,   86,   89,  158,
+      158,  108,  112,  158,  116,  128,   16,  158,  158,  158,
+       27,   38,   87,   95,  158,  158,  158,   18,   19,  158,
+      115,  158,  158,  158,   99,  158,   17,    0
     } ;
 
 static const YY_CHAR yy_ec[256] =
@@ -553,157 +713,155 @@ static const YY_CHAR yy_meta[72] =
         8
     } ;
 
-static const flex_int16_t yy_base[614] =
+static const flex_int16_t yy_base[604] =
     {   0,
         0,    1,   46,    0,  117,  162,    2,    3,  127,  128,
-        6,   10,  159, 1324, 1324,    0, 1324,   13, 1324,  138,
-     1324, 1324, 1324,  142,    6,  129,    4, 1324,  134,  124,
+        6,   10,  147, 1316, 1316,    0, 1316,   13, 1316,  130,
+     1316, 1316, 1316,  129,    6,  129,    4, 1316,   28,  124,
       159,  213,  165,  167,  263,   92,  158,  163,   96,  107,
-      218,  160,  186,  223,  221,  155,  281,  264,  279,  275,
-      186,  209,    0,  191, 1324,  147,    4,   19,    0,    0,
-        0,  140,    0,    0,  343,    0,    0,  141,    0,   22,
-     1324,    0,  307,  326,  338,   18, 1324, 1324, 1324,    0,
-      220,  315,  234,  239,  234,  288,  261,    0,  280,  335,
-      330,  342,  346,  332,  333,  382,  332,  331,  339, 1324,
-
-      336,  358,  363,  380,  356,  352,  378,  386,  387,  391,
-      390,  387,  386,  406,    0,  399,  386,  393,  407,  408,
-      401,  402,  410,  408,  431,  440,    0,  443,  431,  447,
-      438,  440,  454,  451,  447,  461,  457,  442,  466,  465,
-      468,  469,  468,  461,  456,  463,  502,  479,  475,  498,
-      496,  500,  504,  144,   29,    0,    0, 1324,    0, 1324,
-     1324,   22,   24, 1324, 1324, 1324, 1324, 1324,    0,    0,
-     1324,    0,  522,   26,   28,    0,    0,  504,    0,  514,
-      498,  513,  500,  521,  520,  508,  525,  508,  512,  507,
-      534,  517,  523,  537,    0,  535,  545,  554,  544,  542,
-
-      565,  552,  564,    0,  571,  555,  559,  559,  560,  579,
-      569,  577,  570,  572,  564,  578,  578,  571,  585,  588,
-      589,  590,  585,    0,  580,  582,  599,  608,  613,  600,
-      605,    0,  614,    0,  622,  625,  614,  615,  633,  634,
-      625,  619,  634,  630,  638,  639,  637,  628,  633,  646,
-        0,  640,  634,  646,  646,  657,  658,  663,  663,  668,
-      678,  670,  665,  685,  676,  689,  687,  678,   30,  125,
-        0,  679,  684,  694,  686,  696,  691,  690,    0,  704,
-      695,  696,  690,    0,  691,  698,  713,  700,  708,  712,
-      716,  724,  736,  733,  731,    0,    0,  728,  726,  747,
-
-      746,  732,  733,  739,  746,    0,    0,  740,    0,  743,
-        0,  734,  741,  742,  756,    0,    0,    0,    0,    0,
-      741,    0,  744,  759,  749,  751,  758,    0,  769,  774,
-      786,  793,  777,    0,  794,    0,  782,  777,  782,    0,
-      800,  792,  806,  798,  791,  807,    0,  794,    0,  809,
-      794,  802,  796,  798,  812,  816,  814,    0,  820,  811,
-        0,  814,  131, 1324,    0,  828,  829,  816,  836,  833,
-      847,  854,    0,  844,  841,  855,  857,  850,  858,  867,
-      857,  865,  862,  858,  859,  869,  870,  857,  874,    0,
-        0,    0,  856,  873,    0,  876,    0,    0,  864,  880,
-
-      873,    0,  885,    0,    0,    0,    0,  874,  893,  906,
-      893,  906,    0,  911,  901,    0,  913,  916,  902,  916,
-      908,    0,  907,  909,  915,    0,  925,  926,    0,  913,
-      932,    0,  911,  920,  928,  924,    0,  919,  924,  942,
-      939,  930,    0,  951,    0,  948,  945,  955,  957,  953,
-        0,  954,  971,  973,    0,   93,    0,  958,  971,  969,
-        0,    0,  966,  980,  985,    0,  978,  968,  980,  965,
-      971,  978,    0,  981,    0,    0,  981,  987,  998,  999,
-      997,    0,    0,    0,  988,    0,  994,  996,    0, 1002,
-     1008, 1013, 1015, 1026, 1023,    0,    0, 1028,    0,    0,
-
-     1029, 1027, 1018, 1022,    0, 1028,    0,    0, 1040, 1032,
-     1030,    0, 1032,    0, 1022, 1045, 1040, 1030, 1037, 1040,
-     1041, 1052,    0, 1038, 1052, 1050, 1050, 1052, 1049, 1063,
-     1070,    0, 1067, 1075,    0, 1070, 1084, 1072,    0, 1080,
-     1089,    0, 1094, 1087,    0, 1094, 1086, 1087, 1100, 1097,
-        0, 1099, 1102, 1096, 1104,    0, 1091,    0, 1105, 1097,
-        0,    0, 1097,    0, 1098, 1113,    0,    0, 1112,    0,
-        0,    0, 1108, 1122, 1121,    0,    0, 1133,    0,    0,
-     1123, 1142, 1128,    0,    0, 1135, 1145,    0, 1143, 1147,
-     1139, 1153, 1140,    0, 1141,    0,    0, 1324, 1206, 1216,
-
-     1226, 1236, 1246, 1250, 1253, 1259, 1269, 1279, 1289, 1299,
-     1309, 1314, 1316
+      214,  160,  186,  219,  221,  155,  281,  274,  325,  257,
+      186,  209,    0,  219, 1316,   27,    4,   19,    0,    0,
+        0,   17,    0,    0,  389,    0,    0,    8,    0,   22,
+     1316,    0,  293,  325,  343,   18, 1316, 1316, 1316,    0,
+      223,  265,  234,  242,  260,  292,  288,    0,  299,  330,
+      337,  324,  334,  324,  325,  380,  325,  331,  346, 1316,
+
+      348,  364,  378,  376,  371,  378,  382,  386,  390,  389,
+      386,  385,  435,    0,  402,  389,  400,  435,  433,  431,
+      433,  436,  431,  440,  447,    0,  452,  437,  453,  441,
+      442,  456,  453,  449,  465,  457,  444,  494,  468,  495,
+      500,  501,  499,  492,    0,  486,  492,  507,  506,  502,
+      500,  508,  501,  516,    0,   29,    0,    0, 1316,    0,
+     1316, 1316,   22,   24, 1316, 1316, 1316, 1316, 1316,    0,
+        0, 1316,    0,  524,   26,   28,    0,    0,  517,    0,
+      518,  501,  516,  504,  545,  525,  531,  552,  536,  542,
+      537,  562,  544,  547,  561,    0,  558,  567,  564,  567,
+
+      551,  570,  557,  569,    0,  556,  558,  560,  561,  580,
+      570,  578,  572,  575,  567,  598,  598,  595,  610,  613,
+      614,  615,  607,    0,  602,  603,  619,  616,  619,  606,
+      608,    0,  617,    0,  626,  627,  615,  614,  634,  635,
+      626,  620,  636,  633,  641,  659,  657,  652,  658,  671,
+        0,  665,  673,  660,  668,  668,  678,  679,  673,  671,
+      672,  689,  677,  671,  692,  683,  692,  690,  681,   30,
+      125,    0,  685,  690,  705,  708,  718,  718,  718,    0,
+      733,  724,  723,  717,    0,  718,  722,  736,  722,  730,
+      723,  725,  741,  738,  736,    0,    0,  729,  749,  748,
+
+      734,  735,  741,  748,    0,    0,  743,    0,  747,    0,
+      738,  750,  762,  774,    0,    0,    0,    0,    0,  767,
+        0,  769,  785,  775,  777,  778,    0,  789,  794,  795,
+      800,  784,    0,  798,    0,  786,  781,  786,    0,  803,
+      794,  808,  800,  795,  793,  795,  812,    0,  800,    0,
+      815,  805,  824,  818,  825,  840,  845,  843,    0,  847,
+      838,    0,  841,  131, 1316,    0,  852,  852,  838,  858,
+      844,  855,  859,    0,  850,  847,  861,  864,  856,  862,
+      871,  861,  870,  863,  864,  879,  877,  894,    0,    0,
+        0,  880,  898,    0,  901,    0,    0,  889,  905,  892,
+
+        0,  907,    0,    0,    0,    0,  895,  902,  913,  900,
+      910,    0,  915,  905,    0,  917,  919,  904,  918,  910,
+      909,  912,    0,  911,  914,  921,    0,  931,  937,    0,
+      935,  954,    0,  938,  948,  957,  953,    0,  946,  951,
+      969,  963,  953,    0,  973,    0,  970,  956,  964,  966,
+      959,    0,  976,  978,    0,    0,  962,  976,  972,    0,
+        0,  969,  983,  988,    0,  982,  973,  985,  975,  992,
+      999,    0, 1007,    0,    0, 1007,    0,    0, 1015, 1024,
+     1025, 1023,    0,    0,    0, 1010,    0, 1016, 1017,    0,
+     1023, 1018, 1021, 1023, 1031, 1028,    0,    0, 1033,    0,
+
+        0, 1030, 1020,    0, 1029,    0,    0, 1041, 1033, 1031,
+        0, 1033,    0, 1024, 1048, 1043, 1038, 1056, 1058, 1064,
+     1074,    0, 1062, 1076, 1070, 1069, 1070, 1068, 1071, 1076,
+        0, 1077,    0, 1085, 1073,    0, 1080, 1088,    0, 1091,
+     1084,    0, 1091, 1085, 1086, 1099, 1096,    0, 1098, 1102,
+     1097, 1105,    0, 1096, 1121,    0,    0, 1110,    0, 1116,
+     1128,    0,    0, 1128,    0,    0,    0, 1123, 1137, 1125,
+        0,    0,    0,    0, 1124, 1141, 1127,    0,    0, 1143,
+        0, 1140, 1132, 1146,    0, 1133,    0, 1316, 1198, 1208,
+     1218, 1228, 1238, 1242, 1245, 1251, 1261, 1271, 1281, 1291,
+
+     1301, 1306, 1308
     } ;
 
-static const flex_int16_t yy_def[614] =
+static const flex_int16_t yy_def[604] =
     {   0,
-      599,  599,  598,    3,  600,  600,  601,  601,  602,  602,
-      603,  603,  598,  598,  598,  604,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  598,  598,  598,  598,  606,  607,
-      607,  598,  608,  608,  609,  610,  610,  598,  604,  598,
-      598,  611,  598,  598,  598,  598,  598,  598,  598,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  598,
-
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  598,  598,  606,  607,  598,  608,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  612,  610,
-      598,  611,  598,  598,  598,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  598,  598,
-      613,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  598,  598,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,  605,  605,  605,
-      605,  605,  605,  605,  605,  605,  605,    0,  598,  598,
-
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598
+      589,  589,  588,    3,  590,  590,  591,  591,  592,  592,
+      593,  593,  588,  588,  588,  594,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  588,  588,  588,  588,  596,  597,
+      597,  588,  598,  598,  599,  600,  600,  588,  594,  588,
+      588,  601,  588,  588,  588,  588,  588,  588,  588,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  588,
+
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  588,  588,  596,  597,  588,  598,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  602,
+      600,  588,  601,  588,  588,  588,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  588,
+      588,  603,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  588,  588,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+      595,  595,  595,  595,  595,  595,  595,    0,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+
+      588,  588,  588
     } ;
 
-static const flex_int16_t yy_nxt[1396] =
+static const flex_int16_t yy_nxt[1388] =
     {   0,
-      598,  598,   15,   15,   61,   61,  155,  155,   67,   62,
-       62,   68,   67,  598,   70,   68,   70,   73,   73,   77,
-       78,  155,  155,   70,  598,   70,  174,  174,  598,  175,
-      175,  155,  155,  269,  270,  270,  270,  175,  175,  175,
-      175,  363,  270,  598,   16,   16,   17,   18,   19,   18,
+      588,  155,   15,   15,   61,   61,  156,  156,   67,   62,
+       62,   68,   67,  172,   70,   68,   70,   73,   73,   77,
+       78,  156,  156,   70,  159,   70,  175,  175,  155,  176,
+      176,  156,  156,  270,  271,  271,  271,  176,  176,  176,
+      176,  364,  271,   79,   16,   16,   17,   18,   19,   18,
        20,   21,   22,   23,   22,   24,   25,   26,   26,   17,
        27,   28,   29,   30,   31,   32,   33,   34,   35,   36,
        37,   38,   39,   40,   41,   42,   43,   44,   45,   46,
@@ -712,156 +870,154 @@ static const flex_int16_t yy_nxt[1396] =
 
        38,   39,   40,   41,   42,   43,   44,   45,   46,   47,
        48,   49,   50,   51,   52,   53,   54,   17,   56,   57,
-       58,   17,   17,   17,   17,   17,  111,  116,  117,   64,
-       64,   17,   17,   17,   62,   62,  270,  270,  504,   74,
-       75,   75,  270,  270,   81,  154,  171,  158,  154,   79,
-       76,   72,   82,   71,   83,  111,  116,  117,  598,   84,
+       58,   17,   17,   17,   17,   17,  110,  115,  116,   64,
+       64,   17,   17,   17,   62,   62,  271,  271,   72,   74,
+       75,   75,  271,  271,   81,   71,  588,  588,  588,  588,
+       76,  588,   82,  588,   83,  110,  115,  116,  588,   84,
        17,   17,   17,   56,   57,   58,   17,   17,   17,   17,
-       17,   65,   65,   81,  100,  112,   17,   17,   17,   76,
-       85,   82,   95,   83,   86,  122,   96,   87,   84,  113,
-       97,  123,  134,  114,  598,  101,   98,  102,  115,   99,
-
-       88,  598,  103,  150,  112,   17,   17,  104,  598,   85,
-      598,   95,  153,   86,  122,   96,   87,  124,  113,   97,
-      123,  134,  114,  125,  101,   98,  102,  115,   99,   88,
-       89,  103,  150,  151,  152,  118,  104,   90,  131,  119,
-      176,  153,  132,  120,   91,  126,  124,   92,   93,  121,
-       94,  598,  125,  127,  179,  133,  598,  128,  180,   89,
-      129,  130,  151,  152,  118,  598,   90,  131,  119,  176,
-      181,  132,  120,   91,  126,  598,   92,   93,  121,   94,
-      105,  598,  127,  179,  133,  139,  128,  180,  106,  129,
-      130,  107,  184,  140,  108,  598,  142,  109,  135,  181,
-
-      110,  141,  136,  143,  144,  147,  137,  148,  598,  105,
-      149,  182,  138,  145,  139,  185,  146,  106,   73,   73,
-      107,  184,  140,  108,  183,  142,  109,  135,   76,  110,
-      141,  136,  143,  144,  147,  137,  148,  173,  173,  149,
-      182,  138,  145,  177,  185,  146,  161,   76,   74,   75,
-       75,  178,  186,  183,  162,  163,  187,   76,  188,   76,
-      189,  164,  190,  191,  192,  165,  193,  200,  201,  194,
-      202,  203,  177,  166,  195,  598,   76,  167,  204,  168,
-      178,  186,  205,  169,  208,  187,  209,  188,   76,  189,
-      164,  190,  191,  192,  165,  193,  200,  201,  194,  202,
-
-      203,  196,  166,  195,  197,  206,  167,  204,  168,  210,
-      198,  205,  169,  208,  211,  209,  207,  199,  213,  214,
-      212,  215,  216,  218,  223,  217,  219,  224,  225,  226,
-      196,  229,  230,  197,  206,  227,  220,  228,  210,  198,
-      231,  221,  222,  211,  232,  207,  199,  213,  214,  212,
-      215,  216,  218,  223,  217,  219,  224,  225,  226,  233,
-      229,  230,  234,  235,  227,  220,  228,  236,  237,  231,
-      221,  222,  238,  232,  239,  240,  242,  243,  244,  241,
-      247,  248,  252,  245,  246,  249,  253,  254,  233,  255,
-      256,  234,  235,  257,  250,  258,  236,  237,  598,  261,
-
-      262,  238,  251,  239,  240,  242,  243,  244,  241,  247,
-      248,  252,  245,  246,  249,  253,  254,  265,  255,  256,
-      259,  268,  257,  250,  258,  272,  263,  260,  261,  262,
-      266,  251,  264,  173,  173,  273,  267,  274,  275,  276,
-      277,  279,  280,   76,  281,  282,  265,  283,  284,  259,
-      268,  285,  278,  286,  272,  263,  260,  287,  288,  266,
-      289,  264,  290,  293,  273,  267,  274,  275,  276,  277,
-      279,  280,   76,  281,  282,  291,  283,  284,  294,  292,
-      285,  278,  286,  295,  296,  297,  287,  288,  298,  289,
-      299,  290,  293,  300,  301,  302,  303,  304,  305,  306,
-
-      307,  308,  309,  310,  291,  311,  312,  294,  292,  313,
-      314,  315,  295,  296,  297,  317,  318,  298,  319,  299,
-      320,  316,  300,  301,  302,  303,  304,  305,  306,  307,
-      308,  309,  310,  321,  311,  312,  322,  323,  313,  314,
-      315,  324,  325,  326,  317,  318,  327,  319,  328,  320,
-      316,  329,  330,  331,  332,  334,  333,  335,  336,  337,
-      338,  339,  321,  340,  342,  322,  323,  343,  344,  345,
-      324,  325,  326,  341,  346,  327,  347,  328,  348,  349,
-      329,  330,  331,  332,  334,  333,  335,  336,  337,  338,
-      339,  350,  340,  342,  351,  354,  343,  344,  345,  352,
-
-      355,  353,  356,  346,  357,  347,  358,  348,  349,  360,
-      359,  361,  362,  365,  366,  367,  368,  369,  370,  371,
-      350,  372,  373,  351,  354,  374,  375,  376,  352,  355,
-      353,  356,  377,  357,  378,  358,  379,  380,  360,  359,
-      361,  362,  365,  366,  367,  368,  369,  370,  371,  381,
-      372,  373,  382,  383,  374,  375,  376,  384,  385,  386,
-      387,  377,  388,  378,  389,  379,  380,  390,  391,  392,
-      393,  394,  395,  396,  397,  398,  399,  402,  381,  400,
-      403,  382,  383,  404,  405,  406,  384,  385,  386,  387,
-      401,  388,  407,  389,  408,  409,  390,  391,  392,  393,
-
-      394,  395,  396,  397,  398,  399,  402,  410,  400,  403,
-      411,  412,  404,  405,  406,  413,  414,  415,  416,  401,
-      417,  407,  418,  408,  409,  419,  420,  421,  422,  423,
-      424,  425,  426,  427,  428,  429,  410,  430,  431,  411,
-      412,  432,  433,  434,  413,  414,  415,  416,  435,  417,
-      436,  418,  437,  438,  419,  420,  421,  422,  423,  424,
-      425,  426,  427,  428,  429,  439,  430,  431,  440,  441,
-      432,  433,  434,  442,  443,  444,  445,  435,  446,  436,
-      447,  437,  438,  448,  449,  450,  451,  452,  453,  454,
-      455,  456,  457,  458,  439,  459,  460,  440,  441,  461,
-
-      462,  463,  442,  443,  444,  445,  466,  446,  464,  447,
-      467,  465,  448,  449,  450,  451,  452,  453,  454,  455,
-      456,  457,  458,  468,  459,  460,  469,  470,  461,  462,
-      463,  471,  472,  473,  474,  466,  475,  464,  476,  467,
-      465,  477,  478,  479,  480,  481,  482,  483,  484,  485,
-      486,  487,  468,  488,  489,  469,  470,  490,  491,  492,
-      471,  472,  473,  474,  493,  475,  494,  476,  495,  496,
-      477,  478,  479,  480,  481,  482,  483,  484,  485,  486,
-      487,  497,  488,  489,  498,  499,  490,  491,  492,  500,
-      501,  502,  503,  493,  505,  494,  506,  495,  496,  507,
-
-      508,  509,  510,  511,  512,  513,  514,  515,  516,  517,
-      497,  518,  519,  498,  499,  520,  521,  522,  500,  501,
-      502,  503,  523,  505,  524,  506,  525,  526,  507,  508,
-      509,  510,  511,  512,  513,  514,  515,  516,  517,  527,
-      518,  519,  528,  529,  520,  521,  522,  530,  531,  532,
-      533,  523,  534,  524,  535,  525,  526,  536,  537,  538,
-      539,  540,  541,  542,  543,  544,  545,  546,  527,  547,
-      548,  528,  529,  549,  550,  551,  530,  531,  532,  533,
-      552,  534,  553,  535,  554,  555,  536,  537,  538,  539,
-      540,  541,  542,  543,  544,  545,  546,  556,  547,  548,
-
-      557,  558,  549,  550,  551,  559,  560,  561,  562,  552,
-      563,  553,  564,  554,  555,  565,  566,  567,  568,  569,
-      570,  571,  572,  573,  574,  575,  556,  576,  577,  557,
-      558,  578,  579,  580,  559,  560,  561,  562,  581,  563,
-      582,  564,  583,  584,  565,  566,  567,  568,  569,  570,
-      571,  572,  573,  574,  575,  585,  576,  577,  586,  587,
-      578,  579,  580,  588,  589,  590,  591,  581,  592,  582,
-      593,  583,  584,  594,  595,  596,  597,  598,  598,  598,
-      598,  598,  598,  598,  585,  598,  598,  586,  587,  598,
-      598,  598,  588,  589,  590,  591,  598,  592,  598,  593,
-
-      598,  598,  594,  595,  596,  597,   14,   14,   14,   14,
-       14,   14,   14,   14,   14,   14,   59,   59,   59,   59,
-       59,   59,   59,   59,   59,   59,   60,   60,   60,   60,
-       60,   60,   60,   60,   60,   60,   63,   63,   63,   63,
-       63,   63,   63,   63,   63,   63,   66,   66,   66,   66,
-       66,   66,   66,   66,   66,   66,   69,   69,   80,   80,
-       80,  598,   80,  156,  156,  156,  156,  598,  156,  157,
-      157,  157,  598,  157,  157,  157,  157,  157,  157,  159,
-      159,  159,  598,  159,  159,  159,  159,  598,  159,  160,
-      160,  160,  160,  160,  160,  160,  160,  160,  160,  170,
-
-      170,  598,  170,  170,  170,  170,  170,  170,  170,  172,
-      598,  172,  172,  172,  172,  172,  172,  172,  172,  271,
-      271,  364,  364,   13,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598
-
+       17,   65,   65,   81,  100,  111,   17,   17,   17,   76,
+       85,   82,   95,   83,   86,  121,   96,   87,   84,  112,
+       97,  122,  133,  113,  588,  101,   98,  102,  114,   99,
+
+       88,  588,  588,  151,  111,   17,   17,  103,  588,   85,
+      588,   95,  588,   86,  121,   96,   87,  123,  112,   97,
+      122,  133,  113,  124,  101,   98,  102,  114,   99,   88,
+       89,  117,  151,  152,  153,  118,  103,   90,  130,  119,
+      154,  125,  131,  177,   91,  120,  123,   92,   93,  126,
+       94,  588,  124,  127,  180,  132,  128,  129,  588,   89,
+      117,  181,  152,  153,  118,  588,   90,  130,  119,  154,
+      125,  131,  177,   91,  120,  588,   92,   93,  126,   94,
+      104,  588,  127,  180,  132,  128,  129,  148,  105,  149,
+      181,  106,  150,  178,  107,  138,  182,  108,  134,  588,
+
+      109,  179,  135,  139,   73,   73,  136,  588,  588,  104,
+      140,  141,  137,  588,   76,  183,  148,  105,  149,  185,
+      106,  150,  178,  107,  138,  182,  108,  134,  184,  109,
+      179,  135,  139,  588,  186,  136,  174,  174,  588,  140,
+      141,  137,  142,   76,  183,  192,   76,  187,  185,  143,
+      144,  188,  193,   74,   75,   75,  145,  184,  194,  146,
+      201,  195,  147,  186,   76,  189,  196,  190,  202,  191,
+      588,  142,  588,  588,  192,   76,  187,  203,  143,  144,
+      188,  193,  588,  204,  205,  145,  588,  194,  146,  201,
+      195,  147,  162,   76,  189,  196,  190,  202,  191,  197,
+
+      163,  164,  198,  206,  208,  209,  203,  165,  199,  210,
+      211,  166,  204,  205,  207,  200,  212,  213,  214,  167,
+      215,  216,  218,  168,  217,  169,  588,  223,  197,  170,
+      224,  198,  206,  208,  209,  225,  165,  199,  210,  211,
+      166,  588,  588,  207,  200,  212,  213,  214,  167,  215,
+      216,  218,  168,  217,  169,  219,  223,  226,  170,  224,
+      227,  229,  228,  230,  225,  220,  231,  232,  233,  234,
+      221,  222,  235,  236,  237,  238,  239,  240,  242,  243,
+      247,  241,  244,  248,  219,  252,  226,  245,  246,  227,
+      229,  228,  230,  588,  220,  231,  232,  233,  234,  221,
+
+      222,  235,  236,  237,  238,  239,  240,  242,  243,  247,
+      241,  244,  248,  249,  252,  253,  245,  246,  254,  255,
+      256,  257,  250,  258,  259,  260,  262,  263,  264,  266,
+      251,  267,  261,  269,  265,  174,  174,  268,  273,  274,
+      275,  276,  249,  277,  253,   76,  280,  254,  255,  256,
+      257,  250,  258,  259,  260,  262,  263,  264,  266,  251,
+      267,  261,  269,  265,  278,  281,  268,  273,  274,  275,
+      276,  282,  277,  283,   76,  280,  279,  284,  285,  286,
+      287,  288,  289,  290,  291,  292,  293,  294,  295,  296,
+      297,  298,  299,  278,  281,  300,  301,  302,  303,  304,
+
+      282,  305,  283,  306,  307,  279,  284,  285,  286,  287,
+      288,  289,  290,  291,  292,  293,  294,  295,  296,  297,
+      298,  299,  308,  309,  300,  301,  302,  303,  304,  310,
+      305,  311,  306,  307,  312,  313,  314,  316,  317,  318,
+      319,  320,  321,  322,  323,  324,  315,  325,  326,  327,
+      328,  308,  309,  329,  330,  331,  333,  332,  310,  334,
+      311,  335,  336,  312,  313,  314,  316,  317,  318,  319,
+      320,  321,  322,  323,  324,  315,  325,  326,  327,  328,
+      337,  338,  329,  330,  331,  333,  332,  339,  334,  341,
+      335,  336,  342,  343,  344,  346,  347,  340,  348,  349,
+
+      350,  351,  352,  353,  345,  354,  355,  356,  357,  337,
+      338,  358,  361,  359,  362,  363,  339,  360,  341,  366,
+      367,  342,  343,  344,  346,  347,  368,  348,  349,  350,
+      351,  352,  353,  345,  354,  355,  356,  357,  369,  370,
+      358,  361,  359,  362,  363,  371,  360,  372,  366,  367,
+      373,  374,  375,  376,  377,  368,  378,  379,  380,  381,
+      382,  383,  384,  385,  386,  387,  388,  369,  370,  389,
+      390,  391,  392,  393,  371,  394,  372,  395,  396,  373,
+      374,  375,  376,  377,  397,  378,  379,  380,  381,  382,
+      383,  384,  385,  386,  387,  388,  398,  399,  389,  390,
+
+      391,  392,  393,  401,  394,  402,  395,  396,  400,  403,
+      404,  405,  406,  397,  407,  408,  409,  410,  411,  412,
+      413,  414,  415,  416,  417,  398,  399,  418,  419,  420,
+      421,  422,  401,  423,  402,  424,  425,  400,  403,  404,
+      405,  406,  426,  407,  408,  409,  410,  411,  412,  413,
+      414,  415,  416,  417,  427,  428,  418,  419,  420,  421,
+      422,  429,  423,  430,  424,  425,  431,  432,  433,  434,
+      435,  426,  436,  437,  438,  439,  440,  442,  443,  441,
+      444,  445,  446,  427,  428,  447,  448,  449,  450,  451,
+      429,  452,  430,  453,  454,  431,  432,  433,  434,  435,
+
+      455,  436,  437,  438,  439,  440,  442,  443,  441,  444,
+      445,  446,  456,  457,  447,  448,  449,  450,  451,  458,
+      452,  459,  453,  454,  460,  461,  462,  463,  465,  455,
+      464,  466,  467,  468,  469,  470,  471,  472,  473,  474,
+      475,  456,  457,  476,  477,  478,  479,  480,  458,  481,
+      459,  482,  483,  460,  461,  462,  463,  465,  484,  464,
+      466,  467,  468,  469,  470,  471,  472,  473,  474,  475,
+      485,  486,  476,  477,  478,  479,  480,  487,  481,  488,
+      482,  483,  489,  490,  491,  492,  493,  484,  494,  495,
+      496,  497,  498,  499,  500,  501,  502,  503,  504,  485,
+
+      486,  505,  506,  507,  508,  509,  487,  510,  488,  511,
+      512,  489,  490,  491,  492,  493,  513,  494,  495,  496,
+      497,  498,  499,  500,  501,  502,  503,  504,  514,  515,
+      505,  506,  507,  508,  509,  516,  510,  517,  511,  512,
+      518,  519,  520,  521,  522,  513,  523,  524,  525,  526,
+      527,  528,  529,  530,  531,  532,  533,  514,  515,  534,
+      535,  536,  537,  538,  516,  539,  517,  540,  541,  518,
+      519,  520,  521,  522,  542,  523,  524,  525,  526,  527,
+      528,  529,  530,  531,  532,  533,  543,  544,  534,  535,
+      536,  537,  538,  545,  539,  546,  540,  541,  547,  548,
+
+      549,  550,  551,  542,  552,  553,  554,  555,  556,  557,
+      558,  559,  560,  561,  562,  543,  544,  563,  564,  565,
+      566,  567,  545,  568,  546,  569,  570,  547,  548,  549,
+      550,  551,  571,  552,  553,  554,  555,  556,  557,  558,
+      559,  560,  561,  562,  572,  573,  563,  564,  565,  566,
+      567,  574,  568,  575,  569,  570,  576,  577,  578,  579,
+      580,  571,  581,  582,  583,  584,  585,  586,  587,  588,
+      588,  588,  588,  572,  573,  588,  588,  588,  588,  588,
+      574,  588,  575,  588,  588,  576,  577,  578,  579,  580,
+      588,  581,  582,  583,  584,  585,  586,  587,   14,   14,
+
+       14,   14,   14,   14,   14,   14,   14,   14,   59,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   60,   60,
+       60,   60,   60,   60,   60,   60,   60,   60,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   66,   66,
+       66,   66,   66,   66,   66,   66,   66,   66,   69,   69,
+       80,   80,   80,  588,   80,  157,  157,  157,  157,  588,
+      157,  158,  158,  158,  588,  158,  158,  158,  158,  158,
+      158,  160,  160,  160,  588,  160,  160,  160,  160,  588,
+      160,  161,  161,  161,  161,  161,  161,  161,  161,  161,
+      161,  171,  171,  588,  171,  171,  171,  171,  171,  171,
+
+      171,  173,  588,  173,  173,  173,  173,  173,  173,  173,
+      173,  272,  272,  365,  365,   13,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588
     } ;
 
-static const flex_int16_t yy_chk[1396] =
+static const flex_int16_t yy_chk[1388] =
     {   0,
-        0,    0,    1,    2,    7,    8,   57,   57,   11,    7,
-        8,   11,   12,    0,   18,   12,   18,   25,   25,   27,
-       27,   58,   58,   70,    0,   70,   76,   76,    0,   76,
-       76,  155,  155,  162,  162,  163,  163,  174,  174,  175,
-      175,  269,  269,    0,    1,    2,    3,    3,    3,    3,
+        0,  155,    1,    2,    7,    8,   57,   57,   11,    7,
+        8,   11,   12,   68,   18,   12,   18,   25,   25,   27,
+       27,   58,   58,   70,   62,   70,   76,   76,   56,   76,
+       76,  156,  156,  163,  163,  164,  164,  175,  175,  176,
+      176,  270,  270,   29,    1,    2,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
@@ -871,150 +1027,148 @@ static const flex_int16_t yy_chk[1396] =
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    5,    5,    5,
         5,    5,    5,    5,    5,    5,   36,   39,   40,    9,
-       10,    5,    5,    5,    9,   10,  270,  270,  456,   26,
-       26,   26,  363,  363,   30,  154,   68,   62,   56,   29,
-       26,   24,   30,   20,   30,   36,   39,   40,   13,   30,
+       10,    5,    5,    5,    9,   10,  271,  271,   24,   26,
+       26,   26,  364,  364,   30,   20,   13,    0,    0,    0,
+       26,    0,   30,    0,   30,   36,   39,   40,    0,   30,
         5,    5,    6,    6,    6,    6,    6,    6,    6,    6,
         6,    9,   10,   30,   34,   37,    6,    6,    6,   26,
        31,   30,   33,   30,   31,   42,   33,   31,   30,   37,
        33,   42,   46,   38,    0,   34,   33,   34,   38,   33,
 
-       31,    0,   34,   51,   37,    6,    6,   34,    0,   31,
-        0,   33,   54,   31,   42,   33,   31,   43,   37,   33,
+       31,    0,    0,   51,   37,    6,    6,   34,    0,   31,
+        0,   33,    0,   31,   42,   33,   31,   43,   37,   33,
        42,   46,   38,   43,   34,   33,   34,   38,   33,   31,
-       32,   34,   51,   52,   52,   41,   34,   32,   45,   41,
-       81,   54,   45,   41,   32,   44,   43,   32,   32,   41,
-       32,    0,   43,   44,   83,   45,    0,   44,   84,   32,
-       44,   44,   52,   52,   41,    0,   32,   45,   41,   81,
-       85,   45,   41,   32,   44,    0,   32,   32,   41,   32,
-       35,    0,   44,   83,   45,   48,   44,   84,   35,   44,
-       44,   35,   87,   48,   35,    0,   49,   35,   47,   85,
-
-       35,   48,   47,   49,   49,   50,   47,   50,    0,   35,
-       50,   86,   47,   49,   48,   89,   49,   35,   73,   73,
-       35,   87,   48,   35,   86,   49,   35,   47,   73,   35,
-       48,   47,   49,   49,   50,   47,   50,   74,   74,   50,
-       86,   47,   49,   82,   89,   49,   65,   74,   75,   75,
-       75,   82,   90,   86,   65,   65,   90,   73,   91,   75,
-       91,   65,   91,   92,   93,   65,   94,   97,   98,   95,
-       99,  101,   82,   65,   95,    0,   74,   65,  102,   65,
-       82,   90,  103,   65,  105,   90,  106,   91,   75,   91,
-       65,   91,   92,   93,   65,   94,   97,   98,   95,   99,
-
-      101,   96,   65,   95,   96,  104,   65,  102,   65,  107,
-       96,  103,   65,  105,  108,  106,  104,   96,  109,  110,
-      108,  111,  112,  113,  116,  112,  114,  117,  118,  119,
-       96,  121,  122,   96,  104,  120,  114,  120,  107,   96,
-      123,  114,  114,  108,  124,  104,   96,  109,  110,  108,
-      111,  112,  113,  116,  112,  114,  117,  118,  119,  125,
-      121,  122,  126,  128,  120,  114,  120,  129,  130,  123,
-      114,  114,  131,  124,  132,  133,  134,  135,  136,  133,
-      137,  138,  140,  136,  136,  139,  141,  142,  125,  143,
-      144,  126,  128,  145,  139,  146,  129,  130,    0,  148,
-
-      149,  131,  139,  132,  133,  134,  135,  136,  133,  137,
-      138,  140,  136,  136,  139,  141,  142,  151,  143,  144,
-      147,  153,  145,  139,  146,  178,  150,  147,  148,  149,
-      152,  139,  150,  173,  173,  180,  152,  181,  182,  183,
-      184,  185,  186,  173,  187,  188,  151,  189,  190,  147,
-      153,  191,  184,  192,  178,  150,  147,  193,  194,  152,
-      196,  150,  197,  199,  180,  152,  181,  182,  183,  184,
-      185,  186,  173,  187,  188,  198,  189,  190,  200,  198,
-      191,  184,  192,  201,  202,  203,  193,  194,  205,  196,
-      206,  197,  199,  207,  208,  209,  210,  211,  212,  213,
-
-      214,  215,  216,  217,  198,  218,  219,  200,  198,  220,
-      221,  222,  201,  202,  203,  223,  225,  205,  226,  206,
-      227,  222,  207,  208,  209,  210,  211,  212,  213,  214,
-      215,  216,  217,  228,  218,  219,  229,  230,  220,  221,
-      222,  231,  233,  235,  223,  225,  236,  226,  237,  227,
-      222,  238,  239,  240,  241,  242,  241,  243,  244,  245,
-      246,  247,  228,  248,  249,  229,  230,  250,  252,  253,
-      231,  233,  235,  248,  254,  236,  255,  237,  256,  257,
-      238,  239,  240,  241,  242,  241,  243,  244,  245,  246,
-      247,  258,  248,  249,  259,  261,  250,  252,  253,  260,
-
-      262,  260,  263,  254,  264,  255,  265,  256,  257,  266,
-      265,  267,  268,  272,  273,  274,  275,  276,  277,  278,
-      258,  280,  281,  259,  261,  282,  283,  285,  260,  262,
-      260,  263,  286,  264,  287,  265,  288,  289,  266,  265,
-      267,  268,  272,  273,  274,  275,  276,  277,  278,  290,
-      280,  281,  291,  292,  282,  283,  285,  293,  294,  295,
-      298,  286,  299,  287,  300,  288,  289,  301,  302,  303,
-      304,  305,  308,  310,  312,  313,  314,  321,  290,  315,
-      323,  291,  292,  324,  325,  326,  293,  294,  295,  298,
-      315,  299,  327,  300,  329,  330,  301,  302,  303,  304,
-
-      305,  308,  310,  312,  313,  314,  321,  331,  315,  323,
-      332,  333,  324,  325,  326,  335,  337,  338,  339,  315,
-      341,  327,  342,  329,  330,  343,  344,  345,  346,  348,
-      350,  351,  352,  353,  354,  355,  331,  356,  357,  332,
-      333,  359,  360,  362,  335,  337,  338,  339,  366,  341,
-      367,  342,  368,  369,  343,  344,  345,  346,  348,  350,
-      351,  352,  353,  354,  355,  370,  356,  357,  370,  371,
-      359,  360,  362,  372,  374,  375,  376,  366,  377,  367,
-      378,  368,  369,  379,  380,  381,  382,  383,  384,  385,
-      386,  387,  388,  389,  370,  393,  394,  370,  371,  396,
-
-      399,  400,  372,  374,  375,  376,  403,  377,  401,  378,
-      408,  401,  379,  380,  381,  382,  383,  384,  385,  386,
-      387,  388,  389,  409,  393,  394,  410,  411,  396,  399,
-      400,  412,  414,  415,  417,  403,  418,  401,  419,  408,
-      401,  420,  421,  423,  424,  425,  427,  428,  430,  431,
-      433,  434,  409,  435,  436,  410,  411,  438,  439,  440,
-      412,  414,  415,  417,  441,  418,  442,  419,  444,  446,
-      420,  421,  423,  424,  425,  427,  428,  430,  431,  433,
-      434,  447,  435,  436,  448,  449,  438,  439,  440,  450,
-      452,  453,  454,  441,  458,  442,  459,  444,  446,  460,
-
-      463,  464,  465,  467,  468,  469,  470,  471,  472,  474,
-      447,  477,  478,  448,  449,  479,  480,  481,  450,  452,
-      453,  454,  485,  458,  487,  459,  488,  490,  460,  463,
-      464,  465,  467,  468,  469,  470,  471,  472,  474,  491,
-      477,  478,  492,  493,  479,  480,  481,  494,  495,  498,
-      501,  485,  502,  487,  503,  488,  490,  504,  506,  509,
-      510,  511,  513,  515,  516,  517,  518,  519,  491,  520,
-      521,  492,  493,  522,  524,  525,  494,  495,  498,  501,
-      526,  502,  527,  503,  528,  529,  504,  506,  509,  510,
-      511,  513,  515,  516,  517,  518,  519,  530,  520,  521,
-
-      531,  533,  522,  524,  525,  534,  536,  537,  538,  526,
-      540,  527,  541,  528,  529,  543,  544,  546,  547,  548,
-      549,  550,  552,  553,  554,  555,  530,  557,  559,  531,
-      533,  560,  563,  565,  534,  536,  537,  538,  566,  540,
-      569,  541,  573,  574,  543,  544,  546,  547,  548,  549,
-      550,  552,  553,  554,  555,  575,  557,  559,  578,  581,
-      560,  563,  565,  582,  583,  586,  587,  566,  589,  569,
-      590,  573,  574,  591,  592,  593,  595,    0,    0,    0,
-        0,    0,    0,    0,  575,    0,    0,  578,  581,    0,
-        0,    0,  582,  583,  586,  587,    0,  589,    0,  590,
-
-        0,    0,  591,  592,  593,  595,  599,  599,  599,  599,
-      599,  599,  599,  599,  599,  599,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  601,  601,  601,  601,
-      601,  601,  601,  601,  601,  601,  602,  602,  602,  602,
-      602,  602,  602,  602,  602,  602,  603,  603,  603,  603,
-      603,  603,  603,  603,  603,  603,  604,  604,  605,  605,
-      605,    0,  605,  606,  606,  606,  606,    0,  606,  607,
-      607,  607,    0,  607,  607,  607,  607,  607,  607,  608,
-      608,  608,    0,  608,  608,  608,  608,    0,  608,  609,
-      609,  609,  609,  609,  609,  609,  609,  609,  609,  610,
-
-      610,    0,  610,  610,  610,  610,  610,  610,  610,  611,
-        0,  611,  611,  611,  611,  611,  611,  611,  611,  612,
-      612,  613,  613,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598
-
+       32,   41,   51,   52,   52,   41,   34,   32,   45,   41,
+       54,   44,   45,   81,   32,   41,   43,   32,   32,   44,
+       32,    0,   43,   44,   83,   45,   44,   44,    0,   32,
+       41,   84,   52,   52,   41,    0,   32,   45,   41,   54,
+       44,   45,   81,   32,   41,    0,   32,   32,   44,   32,
+       35,    0,   44,   83,   45,   44,   44,   50,   35,   50,
+       84,   35,   50,   82,   35,   48,   85,   35,   47,    0,
+
+       35,   82,   47,   48,   73,   73,   47,    0,    0,   35,
+       48,   48,   47,    0,   73,   86,   50,   35,   50,   87,
+       35,   50,   82,   35,   48,   85,   35,   47,   86,   35,
+       82,   47,   48,    0,   89,   47,   74,   74,    0,   48,
+       48,   47,   49,   73,   86,   92,   74,   90,   87,   49,
+       49,   90,   93,   75,   75,   75,   49,   86,   94,   49,
+       97,   95,   49,   89,   75,   91,   95,   91,   98,   91,
+        0,   49,    0,    0,   92,   74,   90,   99,   49,   49,
+       90,   93,    0,  101,  102,   49,    0,   94,   49,   97,
+       95,   49,   65,   75,   91,   95,   91,   98,   91,   96,
+
+       65,   65,   96,  103,  104,  105,   99,   65,   96,  106,
+      107,   65,  101,  102,  103,   96,  107,  108,  109,   65,
+      110,  111,  112,   65,  111,   65,    0,  115,   96,   65,
+      116,   96,  103,  104,  105,  117,   65,   96,  106,  107,
+       65,    0,    0,  103,   96,  107,  108,  109,   65,  110,
+      111,  112,   65,  111,   65,  113,  115,  118,   65,  116,
+      119,  120,  119,  121,  117,  113,  122,  123,  124,  125,
+      113,  113,  127,  128,  129,  130,  131,  132,  133,  134,
+      136,  132,  135,  137,  113,  139,  118,  135,  135,  119,
+      120,  119,  121,    0,  113,  122,  123,  124,  125,  113,
+
+      113,  127,  128,  129,  130,  131,  132,  133,  134,  136,
+      132,  135,  137,  138,  139,  140,  135,  135,  141,  142,
+      143,  144,  138,  146,  147,  148,  149,  150,  151,  152,
+      138,  153,  148,  154,  151,  174,  174,  153,  179,  181,
+      182,  183,  138,  184,  140,  174,  186,  141,  142,  143,
+      144,  138,  146,  147,  148,  149,  150,  151,  152,  138,
+      153,  148,  154,  151,  185,  187,  153,  179,  181,  182,
+      183,  188,  184,  189,  174,  186,  185,  190,  191,  192,
+      193,  194,  195,  197,  198,  199,  200,  201,  202,  203,
+      204,  206,  207,  185,  187,  208,  209,  210,  211,  212,
+
+      188,  213,  189,  214,  215,  185,  190,  191,  192,  193,
+      194,  195,  197,  198,  199,  200,  201,  202,  203,  204,
+      206,  207,  216,  217,  208,  209,  210,  211,  212,  218,
+      213,  219,  214,  215,  220,  221,  222,  223,  225,  226,
+      227,  228,  229,  230,  231,  233,  222,  235,  236,  237,
+      238,  216,  217,  239,  240,  241,  242,  241,  218,  243,
+      219,  244,  245,  220,  221,  222,  223,  225,  226,  227,
+      228,  229,  230,  231,  233,  222,  235,  236,  237,  238,
+      246,  247,  239,  240,  241,  242,  241,  248,  243,  249,
+      244,  245,  250,  252,  253,  254,  255,  248,  256,  257,
+
+      258,  259,  260,  261,  253,  261,  262,  263,  264,  246,
+      247,  265,  267,  266,  268,  269,  248,  266,  249,  273,
+      274,  250,  252,  253,  254,  255,  275,  256,  257,  258,
+      259,  260,  261,  253,  261,  262,  263,  264,  276,  277,
+      265,  267,  266,  268,  269,  278,  266,  279,  273,  274,
+      281,  282,  283,  284,  286,  275,  287,  288,  289,  290,
+      291,  292,  293,  294,  295,  298,  299,  276,  277,  300,
+      301,  302,  303,  304,  278,  307,  279,  309,  311,  281,
+      282,  283,  284,  286,  312,  287,  288,  289,  290,  291,
+      292,  293,  294,  295,  298,  299,  313,  314,  300,  301,
+
+      302,  303,  304,  320,  307,  322,  309,  311,  314,  323,
+      324,  325,  326,  312,  328,  329,  330,  331,  332,  334,
+      336,  337,  338,  340,  341,  313,  314,  342,  343,  344,
+      345,  346,  320,  347,  322,  349,  351,  314,  323,  324,
+      325,  326,  352,  328,  329,  330,  331,  332,  334,  336,
+      337,  338,  340,  341,  353,  354,  342,  343,  344,  345,
+      346,  355,  347,  356,  349,  351,  357,  358,  360,  361,
+      363,  352,  367,  368,  369,  370,  371,  372,  373,  371,
+      375,  376,  377,  353,  354,  378,  379,  380,  381,  382,
+      355,  383,  356,  384,  385,  357,  358,  360,  361,  363,
+
+      386,  367,  368,  369,  370,  371,  372,  373,  371,  375,
+      376,  377,  387,  388,  378,  379,  380,  381,  382,  392,
+      383,  393,  384,  385,  395,  398,  399,  400,  402,  386,
+      400,  407,  408,  409,  410,  411,  413,  414,  416,  417,
+      418,  387,  388,  419,  420,  421,  422,  424,  392,  425,
+      393,  426,  428,  395,  398,  399,  400,  402,  429,  400,
+      407,  408,  409,  410,  411,  413,  414,  416,  417,  418,
+      431,  432,  419,  420,  421,  422,  424,  434,  425,  435,
+      426,  428,  436,  437,  439,  440,  441,  429,  442,  443,
+      445,  447,  448,  449,  450,  451,  453,  454,  457,  431,
+
+      432,  458,  459,  462,  463,  464,  434,  466,  435,  467,
+      468,  436,  437,  439,  440,  441,  469,  442,  443,  445,
+      447,  448,  449,  450,  451,  453,  454,  457,  470,  471,
+      458,  459,  462,  463,  464,  473,  466,  476,  467,  468,
+      479,  480,  481,  482,  486,  469,  488,  489,  491,  492,
+      493,  494,  495,  496,  499,  502,  503,  470,  471,  505,
+      508,  509,  510,  512,  473,  514,  476,  515,  516,  479,
+      480,  481,  482,  486,  517,  488,  489,  491,  492,  493,
+      494,  495,  496,  499,  502,  503,  518,  519,  505,  508,
+      509,  510,  512,  520,  514,  521,  515,  516,  523,  524,
+
+      525,  526,  527,  517,  528,  529,  530,  532,  534,  535,
+      537,  538,  540,  541,  543,  518,  519,  544,  545,  546,
+      547,  549,  520,  550,  521,  551,  552,  523,  524,  525,
+      526,  527,  554,  528,  529,  530,  532,  534,  535,  537,
+      538,  540,  541,  543,  555,  558,  544,  545,  546,  547,
+      549,  560,  550,  561,  551,  552,  564,  568,  569,  570,
+      575,  554,  576,  577,  580,  582,  583,  584,  586,    0,
+        0,    0,    0,  555,  558,    0,    0,    0,    0,    0,
+      560,    0,  561,    0,    0,  564,  568,  569,  570,  575,
+        0,  576,  577,  580,  582,  583,  584,  586,  589,  589,
+
+      589,  589,  589,  589,  589,  589,  589,  589,  590,  590,
+      590,  590,  590,  590,  590,  590,  590,  590,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  592,  592,
+      592,  592,  592,  592,  592,  592,  592,  592,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  594,  594,
+      595,  595,  595,    0,  595,  596,  596,  596,  596,    0,
+      596,  597,  597,  597,    0,  597,  597,  597,  597,  597,
+      597,  598,  598,  598,    0,  598,  598,  598,  598,    0,
+      598,  599,  599,  599,  599,  599,  599,  599,  599,  599,
+      599,  600,  600,    0,  600,  600,  600,  600,  600,  600,
+
+      600,  601,    0,  601,  601,  601,  601,  601,  601,  601,
+      601,  602,  602,  603,  603,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  588,  588,  588,  588
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static const flex_int32_t yy_rule_can_match_eol[164] =
+static const flex_int32_t yy_rule_can_match_eol[165] =
     {   0,
 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -1023,8 +1177,8 @@ static const flex_int32_t yy_rule_can_match_eol[164] =
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 
-    1, 0, 0, 0,     };
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 
+    0, 1, 0, 0, 0,     };
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
@@ -1074,13 +1228,13 @@ class ParseAttributeDefinition;
 class ParseBlockProperties;
 class ParseColumnConstraint;
 class ParseCommand;
-struct ParseCopyFromParams;
 class ParseDataType;
 class ParseExpression;
 struct ParseFrameInfo;
 class ParseFunctionCall;
 class ParseGroupBy;
 class ParseHaving;
+class ParseKeyBoolValue;
 class ParseKeyIntegerValue;
 class ParseKeyStringValue;
 class ParseKeyStringList;
@@ -1104,7 +1258,7 @@ class ParseSimpleTableReference;
 class ParseSimpleWhenClause;
 class ParseStringKeyLiteralValues;
 class ParseStatement;
-class ParseStatementCopyFrom;
+class ParseStatementCopy;
 class ParseStatementCreateTable;
 class ParseStatementDelete;
 class ParseStatementDropTable;
@@ -1135,14 +1289,14 @@ class UnaryOperation;
     yycolumn += yyleng;                                   \
   }
 
-#line 1138 "SqlLexer_gen.cpp"
+#line 1292 "SqlLexer_gen.cpp"
 /* FIXME(chasseur, qzeng): Add support for hexadecimal literals. */
 /**
  * These patterns are based on the SQL-2011 standard for syntax of numeric
  * literals (Part 2, Section 5.3 of the standard).
  **/
 
-#line 1145 "SqlLexer_gen.cpp"
+#line 1299 "SqlLexer_gen.cpp"
 
 #define INITIAL 0
 #define CONDITION_SQL 1
@@ -1209,50 +1363,50 @@ static int yy_init_globals ( yyscan_t yyscanner );
     
     #    define yylloc yyg->yylloc_r
     
-int quickstep_yylex_init (yyscan_t* scanner);
+int yylex_init (yyscan_t* scanner);
 
-int quickstep_yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
 
 /* Accessor methods to globals.
    These are made visible to non-reentrant scanners for convenience. */
 
-int quickstep_yylex_destroy ( yyscan_t yyscanner );
+int yylex_destroy ( yyscan_t yyscanner );
 
-int quickstep_yyget_debug ( yyscan_t yyscanner );
+int yyget_debug ( yyscan_t yyscanner );
 
-void quickstep_yyset_debug ( int debug_flag , yyscan_t yyscanner );
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
 
-YY_EXTRA_TYPE quickstep_yyget_extra ( yyscan_t yyscanner );
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
 
-void quickstep_yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
 
-FILE *quickstep_yyget_in ( yyscan_t yyscanner );
+FILE *yyget_in ( yyscan_t yyscanner );
 
-void quickstep_yyset_in  ( FILE * _in_str , yyscan_t yyscanner );
+void yyset_in  ( FILE * _in_str , yyscan_t yyscanner );
 
-FILE *quickstep_yyget_out ( yyscan_t yyscanner );
+FILE *yyget_out ( yyscan_t yyscanner );
 
-void quickstep_yyset_out  ( FILE * _out_str , yyscan_t yyscanner );
+void yyset_out  ( FILE * _out_str , yyscan_t yyscanner );
 
-			int quickstep_yyget_leng ( yyscan_t yyscanner );
+			int yyget_leng ( yyscan_t yyscanner );
 
-char *quickstep_yyget_text ( yyscan_t yyscanner );
+char *yyget_text ( yyscan_t yyscanner );
 
-int quickstep_yyget_lineno ( yyscan_t yyscanner );
+int yyget_lineno ( yyscan_t yyscanner );
 
-void quickstep_yyset_lineno ( int _line_number , yyscan_t yyscanner );
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
 
-int quickstep_yyget_column  ( yyscan_t yyscanner );
+int yyget_column  ( yyscan_t yyscanner );
 
-void quickstep_yyset_column ( int _column_no , yyscan_t yyscanner );
+void yyset_column ( int _column_no , yyscan_t yyscanner );
 
-YYSTYPE * quickstep_yyget_lval ( yyscan_t yyscanner );
+YYSTYPE * yyget_lval ( yyscan_t yyscanner );
 
-void quickstep_yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
+void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
 
-       YYLTYPE *quickstep_yyget_lloc ( yyscan_t yyscanner );
+       YYLTYPE *yyget_lloc ( yyscan_t yyscanner );
     
-        void quickstep_yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner );
+        void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner );
     
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -1260,9 +1414,9 @@ void quickstep_yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
-extern "C" int quickstep_yywrap ( yyscan_t yyscanner );
+extern "C" int yywrap ( yyscan_t yyscanner );
 #else
-extern int quickstep_yywrap ( yyscan_t yyscanner );
+extern int yywrap ( yyscan_t yyscanner );
 #endif
 #endif
 
@@ -1367,10 +1521,10 @@ static int input ( yyscan_t yyscanner );
 #ifndef YY_DECL
 #define YY_DECL_IS_OURS 1
 
-extern int quickstep_yylex \
+extern int yylex \
                (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner);
 
-#define YY_DECL int quickstep_yylex \
+#define YY_DECL int yylex \
                (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
 #endif /* !YY_DECL */
 
@@ -1420,19 +1574,19 @@ YY_DECL
 			yyout = stdout;
 
 		if ( ! YY_CURRENT_BUFFER ) {
-			quickstep_yyensure_buffer_stack (yyscanner);
+			yyensure_buffer_stack (yyscanner);
 			YY_CURRENT_BUFFER_LVALUE =
-				quickstep_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+				yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
 		}
 
-		quickstep_yy_load_buffer_state(yyscanner );
+		yy_load_buffer_state( yyscanner );
 		}
 
 	{
 #line 132 "../SqlLexer.lpp"
 
 
-#line 1435 "SqlLexer_gen.cpp"
+#line 1589 "SqlLexer_gen.cpp"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1459,13 +1613,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 599 )
+				if ( yy_current_state >= 589 )
 					yy_c = yy_meta[yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 598 );
+		while ( yy_current_state != 588 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
@@ -1709,7 +1863,7 @@ return TOKEN_DELETE;
 case 37:
 YY_RULE_SETUP
 #line 203 "../SqlLexer.lpp"
-return TOKEN_DELIMITER;
+return TOKEN_DESC;
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
@@ -1719,347 +1873,347 @@ return TOKEN_DESC;
 case 39:
 YY_RULE_SETUP
 #line 205 "../SqlLexer.lpp"
-return TOKEN_DESC;
+return TOKEN_DISTINCT;
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
 #line 206 "../SqlLexer.lpp"
-return TOKEN_DISTINCT;
+return TOKEN_DOUBLE;
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
 #line 207 "../SqlLexer.lpp"
-return TOKEN_DOUBLE;
+return TOKEN_DROP;
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
 #line 208 "../SqlLexer.lpp"
-return TOKEN_DROP;
+return TOKEN_ELSE;
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
 #line 209 "../SqlLexer.lpp"
-return TOKEN_ELSE;
+return TOKEN_END;
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
 #line 210 "../SqlLexer.lpp"
-return TOKEN_END;
+return TOKEN_EXISTS;
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
 #line 211 "../SqlLexer.lpp"
-return TOKEN_ESCAPE_STRINGS;
+return TOKEN_EXTRACT;
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
 #line 212 "../SqlLexer.lpp"
-return TOKEN_EXISTS;
+return TOKEN_FALSE;
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
 #line 213 "../SqlLexer.lpp"
-return TOKEN_EXTRACT;
+return TOKEN_FIRST;
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
 #line 214 "../SqlLexer.lpp"
-return TOKEN_FALSE;
+return TOKEN_FLOAT;
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
 #line 215 "../SqlLexer.lpp"
-return TOKEN_FIRST;
+return TOKEN_FOLLOWING;
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
 #line 216 "../SqlLexer.lpp"
-return TOKEN_FLOAT;
+return TOKEN_FOR;
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
 #line 217 "../SqlLexer.lpp"
-return TOKEN_FOLLOWING;
+return TOKEN_FOREIGN;
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
 #line 218 "../SqlLexer.lpp"
-return TOKEN_FOR;
+return TOKEN_FROM;
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
 #line 219 "../SqlLexer.lpp"
-return TOKEN_FOREIGN;
+return TOKEN_FULL;
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
 #line 220 "../SqlLexer.lpp"
-return TOKEN_FROM;
+return TOKEN_GROUP;
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
 #line 221 "../SqlLexer.lpp"
-return TOKEN_FULL;
+return TOKEN_HASH;
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
 #line 222 "../SqlLexer.lpp"
-return TOKEN_GROUP;
+return TOKEN_HAVING;
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
 #line 223 "../SqlLexer.lpp"
-return TOKEN_HASH;
+return TOKEN_HOUR;
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
 #line 224 "../SqlLexer.lpp"
-return TOKEN_HAVING;
+return TOKEN_IN;
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
 #line 225 "../SqlLexer.lpp"
-return TOKEN_HOUR;
+return TOKEN_INDEX;
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
 #line 226 "../SqlLexer.lpp"
-return TOKEN_IN;
+return TOKEN_INNER;
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
 #line 227 "../SqlLexer.lpp"
-return TOKEN_INDEX;
+return TOKEN_INSERT;
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
 #line 228 "../SqlLexer.lpp"
-return TOKEN_INNER;
+return TOKEN_INTEGER;
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
 #line 229 "../SqlLexer.lpp"
-return TOKEN_INSERT;
+return TOKEN_INTEGER;
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
 #line 230 "../SqlLexer.lpp"
-return TOKEN_INTEGER;
+return TOKEN_INTERSECT;
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
 #line 231 "../SqlLexer.lpp"
-return TOKEN_INTEGER;
+return TOKEN_INTERVAL;
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
 #line 232 "../SqlLexer.lpp"
-return TOKEN_INTERSECT;
+return TOKEN_INTO;
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
 #line 233 "../SqlLexer.lpp"
-return TOKEN_INTERVAL;
+return TOKEN_IS;
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
 #line 234 "../SqlLexer.lpp"
-return TOKEN_INTO;
+return TOKEN_JOIN;
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
 #line 235 "../SqlLexer.lpp"
-return TOKEN_IS;
+return TOKEN_KEY;
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
 #line 236 "../SqlLexer.lpp"
-return TOKEN_JOIN;
+return TOKEN_LAST;
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
 #line 237 "../SqlLexer.lpp"
-return TOKEN_KEY;
+return TOKEN_LEFT;
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
 #line 238 "../SqlLexer.lpp"
-return TOKEN_LAST;
+return TOKEN_LIKE;
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
 #line 239 "../SqlLexer.lpp"
-return TOKEN_LEFT;
+return TOKEN_LIMIT;
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
 #line 240 "../SqlLexer.lpp"
-return TOKEN_LIKE;
+return TOKEN_LONG;
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
 #line 241 "../SqlLexer.lpp"
-return TOKEN_LIMIT;
+return TOKEN_MINUTE;
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
 #line 242 "../SqlLexer.lpp"
-return TOKEN_LONG;
+return TOKEN_MONTH;
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
 #line 243 "../SqlLexer.lpp"
-return TOKEN_MINUTE;
+return TOKEN_NOT;
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
 #line 244 "../SqlLexer.lpp"
-return TOKEN_MONTH;
+return TOKEN_NULL;
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
 #line 245 "../SqlLexer.lpp"
-return TOKEN_NOT;
+return TOKEN_NULLS;
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
 #line 246 "../SqlLexer.lpp"
-return TOKEN_NULL;
+return TOKEN_OFF;
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
 #line 247 "../SqlLexer.lpp"
-return TOKEN_NULLS;
+return TOKEN_ON;
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
 #line 248 "../SqlLexer.lpp"
-return TOKEN_OFF;
+return TOKEN_OR;
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
 #line 249 "../SqlLexer.lpp"
-return TOKEN_ON;
+return TOKEN_ORDER;
 	YY_BREAK
 case 84:
 YY_RULE_SETUP
 #line 250 "../SqlLexer.lpp"
-return TOKEN_OR;
+return TOKEN_OUTER;
 	YY_BREAK
 case 85:
 YY_RULE_SETUP
 #line 251 "../SqlLexer.lpp"
-return TOKEN_ORDER;
+return TOKEN_OVER;
 	YY_BREAK
 case 86:
 YY_RULE_SETUP
 #line 252 "../SqlLexer.lpp"
-return TOKEN_OUTER;
+return TOKEN_PARTITION;
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
 #line 253 "../SqlLexer.lpp"
-return TOKEN_OVER;
+return TOKEN_PARTITIONS;
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
 #line 254 "../SqlLexer.lpp"
-return TOKEN_PARTITION;
+return TOKEN_PERCENT;
 	YY_BREAK
 case 89:
 YY_RULE_SETUP
 #line 255 "../SqlLexer.lpp"
-return TOKEN_PARTITIONS;
+return TOKEN_PRECEDING;
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
 #line 256 "../SqlLexer.lpp"
-return TOKEN_PERCENT;
+return TOKEN_PRIMARY;
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
 #line 257 "../SqlLexer.lpp"
-return TOKEN_PRECEDING;
+return TOKEN_PRIORITY;
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
 #line 258 "../SqlLexer.lpp"
-return TOKEN_PRIMARY;
+return TOKEN_QUIT;
 	YY_BREAK
 case 93:
 YY_RULE_SETUP
 #line 259 "../SqlLexer.lpp"
-return TOKEN_PRIORITY;
+return TOKEN_RANGE;
 	YY_BREAK
 case 94:
 YY_RULE_SETUP
 #line 260 "../SqlLexer.lpp"
-return TOKEN_QUIT;
+return TOKEN_REAL;
 	YY_BREAK
 case 95:
 YY_RULE_SETUP
 #line 261 "../SqlLexer.lpp"
-return TOKEN_RANGE;
+return TOKEN_REFERENCES;
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
 #line 262 "../SqlLexer.lpp"
-return TOKEN_REAL;
+return TOKEN_REGEXP;
 	YY_BREAK
 case 97:
 YY_RULE_SETUP
 #line 263 "../SqlLexer.lpp"
-return TOKEN_REFERENCES;
+return TOKEN_RIGHT;
 	YY_BREAK
 case 98:
 YY_RULE_SETUP
 #line 264 "../SqlLexer.lpp"
-return TOKEN_REGEXP;
+return TOKEN_ROW;
 	YY_BREAK
 case 99:
 YY_RULE_SETUP
 #line 265 "../SqlLexer.lpp"
-return TOKEN_RIGHT;
+return TOKEN_ROW_DELIMITER;
 	YY_BREAK
 case 100:
 YY_RULE_SETUP
 #line 266 "../SqlLexer.lpp"
-return TOKEN_ROW;
+return TOKEN_ROWS;
 	YY_BREAK
 case 101:
 YY_RULE_SETUP
 #line 267 "../SqlLexer.lpp"
-return TOKEN_ROW_DELIMITER;
+return TOKEN_SECOND;
 	YY_BREAK
 case 102:
 YY_RULE_SETUP
 #line 268 "../SqlLexer.lpp"
-return TOKEN_ROWS;
+return TOKEN_SELECT;
 	YY_BREAK
 case 103:
 YY_RULE_SETUP
 #line 269 "../SqlLexer.lpp"
-return TOKEN_SECOND;
+return TOKEN_SET;
 	YY_BREAK
 case 104:
 YY_RULE_SETUP
 #line 270 "../SqlLexer.lpp"
-return TOKEN_SELECT;
+return TOKEN_SMA;
 	YY_BREAK
 case 105:
 YY_RULE_SETUP
 #line 271 "../SqlLexer.lpp"
-return TOKEN_SET;
+return TOKEN_SMALLINT;
 	YY_BREAK
 case 106:
 YY_RULE_SETUP
 #line 272 "../SqlLexer.lpp"
-return TOKEN_SMA;
+return TOKEN_STDERR;
 	YY_BREAK
 case 107:
 YY_RULE_SETUP
 #line 273 "../SqlLexer.lpp"
-return TOKEN_SMALLINT;
+return TOKEN_STDOUT;
 	YY_BREAK
 case 108:
 YY_RULE_SETUP
@@ -2089,87 +2243,87 @@ return TOKEN_TIMESTAMP;
 case 113:
 YY_RULE_SETUP
 #line 279 "../SqlLexer.lpp"
-return TOKEN_TRUE;
+return TOKEN_TO;
 	YY_BREAK
 case 114:
 YY_RULE_SETUP
 #line 280 "../SqlLexer.lpp"
-return TOKEN_TUPLESAMPLE;
+return TOKEN_TRUE;
 	YY_BREAK
 case 115:
 YY_RULE_SETUP
 #line 281 "../SqlLexer.lpp"
-return TOKEN_UNBOUNDED;
+return TOKEN_TUPLESAMPLE;
 	YY_BREAK
 case 116:
 YY_RULE_SETUP
 #line 282 "../SqlLexer.lpp"
-return TOKEN_UNION;
+return TOKEN_UNBOUNDED;
 	YY_BREAK
 case 117:
 YY_RULE_SETUP
 #line 283 "../SqlLexer.lpp"
-return TOKEN_UNIQUE;
+return TOKEN_UNION;
 	YY_BREAK
 case 118:
 YY_RULE_SETUP
 #line 284 "../SqlLexer.lpp"
-return TOKEN_UPDATE;
+return TOKEN_UNIQUE;
 	YY_BREAK
 case 119:
 YY_RULE_SETUP
 #line 285 "../SqlLexer.lpp"
-return TOKEN_USING;
+return TOKEN_UPDATE;
 	YY_BREAK
 case 120:
 YY_RULE_SETUP
 #line 286 "../SqlLexer.lpp"
-return TOKEN_VALUES;
+return TOKEN_USING;
 	YY_BREAK
 case 121:
 YY_RULE_SETUP
 #line 287 "../SqlLexer.lpp"
-return TOKEN_VARCHAR;
+return TOKEN_VALUES;
 	YY_BREAK
 case 122:
 YY_RULE_SETUP
 #line 288 "../SqlLexer.lpp"
-return TOKEN_WHEN;
+return TOKEN_VARCHAR;
 	YY_BREAK
 case 123:
 YY_RULE_SETUP
 #line 289 "../SqlLexer.lpp"
-return TOKEN_WHERE;
+return TOKEN_WHEN;
 	YY_BREAK
 case 124:
 YY_RULE_SETUP
 #line 290 "../SqlLexer.lpp"
-return TOKEN_WINDOW;
+return TOKEN_WHERE;
 	YY_BREAK
 case 125:
 YY_RULE_SETUP
 #line 291 "../SqlLexer.lpp"
-return TOKEN_WITH;
+return TOKEN_WINDOW;
 	YY_BREAK
 case 126:
 YY_RULE_SETUP
 #line 292 "../SqlLexer.lpp"
-return TOKEN_YEAR;
+return TOKEN_WITH;
 	YY_BREAK
 case 127:
 YY_RULE_SETUP
 #line 293 "../SqlLexer.lpp"
-return TOKEN_YEARMONTH;
+return TOKEN_YEAR;
 	YY_BREAK
 case 128:
 YY_RULE_SETUP
-#line 295 "../SqlLexer.lpp"
-return TOKEN_EQ;
+#line 294 ".

<TRUNCATED>


[02/12] incubator-quickstep git commit: Minor cleanups for the create operators.

Posted by ji...@apache.org.
Minor cleanups for the create operators.


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/83c4fe55
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/83c4fe55
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/83c4fe55

Branch: refs/heads/copy-to
Commit: 83c4fe55707fe8e5934d53b28c60673c8cdf66eb
Parents: 09ccb7c
Author: Zuyu Zhang <zu...@cs.wisc.edu>
Authored: Sat Aug 26 13:46:53 2017 -0500
Committer: Zuyu Zhang <zu...@cs.wisc.edu>
Committed: Sat Aug 26 15:23:51 2017 -0500

----------------------------------------------------------------------
 relational_operators/CMakeLists.txt          |  4 +--
 relational_operators/CreateIndexOperator.cpp | 40 ---------------------
 relational_operators/CreateIndexOperator.hpp |  9 +++--
 relational_operators/CreateTableOperator.cpp | 43 -----------------------
 relational_operators/CreateTableOperator.hpp |  9 +++--
 5 files changed, 16 insertions(+), 89 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/83c4fe55/relational_operators/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/relational_operators/CMakeLists.txt b/relational_operators/CMakeLists.txt
index 5ad9c3b..6083dd5 100644
--- a/relational_operators/CMakeLists.txt
+++ b/relational_operators/CMakeLists.txt
@@ -38,8 +38,8 @@ add_library(quickstep_relationaloperators_BuildAggregationExistenceMapOperator
             BuildAggregationExistenceMapOperator.hpp)
 add_library(quickstep_relationaloperators_BuildHashOperator BuildHashOperator.cpp BuildHashOperator.hpp)
 add_library(quickstep_relationaloperators_BuildLIPFilterOperator BuildLIPFilterOperator.cpp BuildLIPFilterOperator.hpp)
-add_library(quickstep_relationaloperators_CreateIndexOperator CreateIndexOperator.cpp CreateIndexOperator.hpp)
-add_library(quickstep_relationaloperators_CreateTableOperator CreateTableOperator.cpp CreateTableOperator.hpp)
+add_library(quickstep_relationaloperators_CreateIndexOperator ../empty_src.cpp CreateIndexOperator.hpp)
+add_library(quickstep_relationaloperators_CreateTableOperator ../empty_src.cpp CreateTableOperator.hpp)
 add_library(quickstep_relationaloperators_DestroyAggregationStateOperator
             DestroyAggregationStateOperator.cpp
             DestroyAggregationStateOperator.hpp)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/83c4fe55/relational_operators/CreateIndexOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/CreateIndexOperator.cpp b/relational_operators/CreateIndexOperator.cpp
deleted file mode 100644
index ab3624c..0000000
--- a/relational_operators/CreateIndexOperator.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "relational_operators/CreateIndexOperator.hpp"
-
-#include <utility>
-
-#include "tmb/id_typedefs.h"
-
-namespace quickstep {
-
-bool CreateIndexOperator::getAllWorkOrders(WorkOrdersContainer *container,
-                                           QueryContext *query_context,
-                                           StorageManager *storage_manager,
-                                           const tmb::client_id scheduler_client_id,
-                                           tmb::MessageBus *bus) {
-  return true;
-}
-
-void CreateIndexOperator::updateCatalogOnCompletion() {
-  relation_->addIndex(index_name_, std::move(index_description_));
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/83c4fe55/relational_operators/CreateIndexOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/CreateIndexOperator.hpp b/relational_operators/CreateIndexOperator.hpp
index c08947f..09d5d81 100644
--- a/relational_operators/CreateIndexOperator.hpp
+++ b/relational_operators/CreateIndexOperator.hpp
@@ -22,6 +22,7 @@
 
 #include <cstddef>
 #include <string>
+#include <utility>
 
 #include "catalog/CatalogRelation.hpp"
 #include "relational_operators/RelationalOperator.hpp"
@@ -85,7 +86,9 @@ class CreateIndexOperator : public RelationalOperator {
                         QueryContext *query_context,
                         StorageManager *storage_manager,
                         const tmb::client_id scheduler_client_id,
-                        tmb::MessageBus *bus) override;
+                        tmb::MessageBus *bus) override {
+    return true;
+  }
 
   /**
    * @note no WorkOrder proto generated for this operator.
@@ -94,7 +97,9 @@ class CreateIndexOperator : public RelationalOperator {
     return true;
   }
 
-  void updateCatalogOnCompletion() override;
+  void updateCatalogOnCompletion() override {
+    relation_->addIndex(index_name_, std::move(index_description_));
+  }
 
  private:
   CatalogRelation *relation_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/83c4fe55/relational_operators/CreateTableOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/CreateTableOperator.cpp b/relational_operators/CreateTableOperator.cpp
deleted file mode 100644
index 261bec1..0000000
--- a/relational_operators/CreateTableOperator.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "relational_operators/CreateTableOperator.hpp"
-
-#include <memory>
-
-#include "catalog/CatalogDatabase.hpp"
-
-#include "tmb/id_typedefs.h"
-
-namespace quickstep {
-
-bool CreateTableOperator::getAllWorkOrders(
-    WorkOrdersContainer *container,
-    QueryContext *query_context,
-    StorageManager *storage_manager,
-    const tmb::client_id scheduler_client_id,
-    tmb::MessageBus *bus) {
-  return true;
-}
-
-void CreateTableOperator::updateCatalogOnCompletion() {
-  database_->addRelation(relation_.release());
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/83c4fe55/relational_operators/CreateTableOperator.hpp
----------------------------------------------------------------------
diff --git a/relational_operators/CreateTableOperator.hpp b/relational_operators/CreateTableOperator.hpp
index 4b06abc..52c7846 100644
--- a/relational_operators/CreateTableOperator.hpp
+++ b/relational_operators/CreateTableOperator.hpp
@@ -24,6 +24,7 @@
 #include <string>
 #include <memory>
 
+#include "catalog/CatalogDatabase.hpp"
 #include "catalog/CatalogRelation.hpp"
 #include "relational_operators/RelationalOperator.hpp"
 #include "utility/Macros.hpp"
@@ -84,7 +85,9 @@ class CreateTableOperator : public RelationalOperator {
                         QueryContext *query_context,
                         StorageManager *storage_manager,
                         const tmb::client_id scheduler_client_id,
-                        tmb::MessageBus *bus) override;
+                        tmb::MessageBus *bus) override {
+    return true;
+  }
 
   /**
    * @note no WorkOrder proto generated for this operator.
@@ -93,7 +96,9 @@ class CreateTableOperator : public RelationalOperator {
     return true;
   }
 
-  void updateCatalogOnCompletion() override;
+  void updateCatalogOnCompletion() override {
+    database_->addRelation(relation_.release());
+  }
 
  private:
   std::unique_ptr<CatalogRelation> relation_;