quickstep-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jianq...@apache.org
Subject [21/27] incubator-quickstep git commit: Support Multiple Tuple Inserts
Date Fri, 17 Nov 2017 19:41:01 GMT
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0fe838df/parser/preprocessed/SqlParser_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.hpp b/parser/preprocessed/SqlParser_gen.hpp
index f6b5247..142059d 100644
--- a/parser/preprocessed/SqlParser_gen.hpp
+++ b/parser/preprocessed/SqlParser_gen.hpp
@@ -198,6 +198,7 @@ union YYSTYPE
   quickstep::NumericParseLiteralValue *numeric_literal_value_;
   quickstep::ParseLiteralValue *literal_value_;
   quickstep::PtrList<quickstep::ParseScalarLiteral> *literal_value_list_;
+  quickstep::PtrList<quickstep::PtrList<quickstep::ParseScalarLiteral>> *literal_value_list_multiple_;
 
   quickstep::ParseExpression *expression_;
 
@@ -288,7 +289,7 @@ union YYSTYPE
 
   quickstep::ParsePriority *opt_priority_clause_;
 
-#line 292 "SqlParser_gen.hpp" /* yacc.c:1915  */
+#line 293 "SqlParser_gen.hpp" /* yacc.c:1915  */
 };
 
 typedef union YYSTYPE YYSTYPE;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0fe838df/query_optimizer/ExecutionGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/ExecutionGenerator.cpp b/query_optimizer/ExecutionGenerator.cpp
index 372d576..14d8949 100644
--- a/query_optimizer/ExecutionGenerator.cpp
+++ b/query_optimizer/ExecutionGenerator.cpp
@@ -1461,70 +1461,72 @@ void ExecutionGenerator::convertInsertTuple(
       *catalog_database_->getRelationById(
           input_relation_info->relation->getID());
 
-  // Construct the tuple proto to be inserted.
-  const QueryContext::tuple_id tuple_index = query_context_proto_->tuples_size();
+  for (const std::vector<expressions::ScalarLiteralPtr> &tuple : physical_plan->column_values())
{
+    // Construct the tuple proto to be inserted.
+    const QueryContext::tuple_id tuple_index = query_context_proto_->tuples_size();
 
-  S::Tuple *tuple_proto = query_context_proto_->add_tuples();
-  for (const E::ScalarLiteralPtr &literal : physical_plan->column_values()) {
-    tuple_proto->add_attribute_values()->CopyFrom(literal->value().getProto());
-  }
+    S::Tuple *tuple_proto = query_context_proto_->add_tuples();
+    for (const E::ScalarLiteralPtr &literal : tuple) {
+      tuple_proto->add_attribute_values()->CopyFrom(literal->value().getProto());
+    }
 
-  // FIXME(qzeng): A better way is using a traits struct to look up whether a storage
-  //               block supports ad-hoc insertion instead of hard-coding the block types.
-  const StorageBlockLayout &storage_block_layout =
-      input_relation.getDefaultStorageBlockLayout();
-  if (storage_block_layout.getDescription().tuple_store_description().sub_block_type() ==
-      TupleStorageSubBlockDescription::COMPRESSED_COLUMN_STORE ||
-      storage_block_layout.getDescription().tuple_store_description().sub_block_type() ==
-            TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE) {
-    THROW_SQL_ERROR() << "INSERT statement is not supported for the relation "
-                      << input_relation.getName()
-                      << ", because its storage blocks do not support ad-hoc insertion";
-  }
+    // FIXME(qzeng): A better way is using a traits struct to look up whether a storage
+    //               block supports ad-hoc insertion instead of hard-coding the block types.
+    const StorageBlockLayout &storage_block_layout =
+        input_relation.getDefaultStorageBlockLayout();
+    if (storage_block_layout.getDescription().tuple_store_description().sub_block_type()
==
+        TupleStorageSubBlockDescription::COMPRESSED_COLUMN_STORE ||
+        storage_block_layout.getDescription().tuple_store_description().sub_block_type()
==
+              TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE) {
+      THROW_SQL_ERROR() << "INSERT statement is not supported for the relation "
+                        << input_relation.getName()
+                        << ", because its storage blocks do not support ad-hoc insertion";
+    }
 
-  // Create InsertDestination proto.
-  const QueryContext::insert_destination_id insert_destination_index =
-      query_context_proto_->insert_destinations_size();
-  S::InsertDestination *insert_destination_proto = query_context_proto_->add_insert_destinations();
+    // Create InsertDestination proto.
+    const QueryContext::insert_destination_id insert_destination_index =
+        query_context_proto_->insert_destinations_size();
+    S::InsertDestination *insert_destination_proto = query_context_proto_->add_insert_destinations();
 
-  insert_destination_proto->set_relation_id(input_relation.getID());
-  insert_destination_proto->mutable_layout()->MergeFrom(
-      input_relation.getDefaultStorageBlockLayout().getDescription());
+    insert_destination_proto->set_relation_id(input_relation.getID());
+    insert_destination_proto->mutable_layout()->MergeFrom(
+        input_relation.getDefaultStorageBlockLayout().getDescription());
 
-  if (input_relation.hasPartitionScheme()) {
-    insert_destination_proto->set_insert_destination_type(S::InsertDestinationType::PARTITION_AWARE);
-    insert_destination_proto->MutableExtension(S::PartitionAwareInsertDestination::partition_scheme)
-        ->MergeFrom(input_relation.getPartitionScheme()->getProto());
-  } else {
-    insert_destination_proto->set_insert_destination_type(S::InsertDestinationType::BLOCK_POOL);
+    if (input_relation.hasPartitionScheme()) {
+      insert_destination_proto->set_insert_destination_type(S::InsertDestinationType::PARTITION_AWARE);
+      insert_destination_proto->MutableExtension(S::PartitionAwareInsertDestination::partition_scheme)
+          ->MergeFrom(input_relation.getPartitionScheme()->getProto());
+    } else {
+      insert_destination_proto->set_insert_destination_type(S::InsertDestinationType::BLOCK_POOL);
 
-    const vector<block_id> blocks(input_relation.getBlocksSnapshot());
-    for (const block_id block : blocks) {
-      insert_destination_proto->AddExtension(S::BlockPoolInsertDestination::blocks, block);
+      const vector<block_id> blocks(input_relation.getBlocksSnapshot());
+      for (const block_id block : blocks) {
+        insert_destination_proto->AddExtension(S::BlockPoolInsertDestination::blocks,
block);
+      }
     }
-  }
 
-  const QueryPlan::DAGNodeIndex insert_operator_index =
-      execution_plan_->addRelationalOperator(
-          new InsertOperator(query_handle_->query_id(),
-                             input_relation,
-                             insert_destination_index,
-                             tuple_index));
-  insert_destination_proto->set_relational_op_index(insert_operator_index);
+    const QueryPlan::DAGNodeIndex insert_operator_index =
+        execution_plan_->addRelationalOperator(
+            new InsertOperator(query_handle_->query_id(),
+                               input_relation,
+                               insert_destination_index,
+                               tuple_index));
+    insert_destination_proto->set_relational_op_index(insert_operator_index);
 
-  CatalogRelation *mutable_relation =
-      catalog_database_->getRelationByIdMutable(input_relation.getID());
-  const QueryPlan::DAGNodeIndex save_blocks_index =
-      execution_plan_->addRelationalOperator(
-          new SaveBlocksOperator(query_handle_->query_id(), mutable_relation));
-  if (!input_relation_info->isStoredRelation()) {
-    execution_plan_->addDirectDependency(insert_operator_index,
-                                         input_relation_info->producer_operator_index,
-                                         true /* is_pipeline_breaker */);
+    CatalogRelation *mutable_relation =
+        catalog_database_->getRelationByIdMutable(input_relation.getID());
+    const QueryPlan::DAGNodeIndex save_blocks_index =
+        execution_plan_->addRelationalOperator(
+            new SaveBlocksOperator(query_handle_->query_id(), mutable_relation));
+    if (!input_relation_info->isStoredRelation()) {
+      execution_plan_->addDirectDependency(insert_operator_index,
+                                           input_relation_info->producer_operator_index,
+                                           true /* is_pipeline_breaker */);
+    }
+    execution_plan_->addDirectDependency(save_blocks_index,
+                                         insert_operator_index,
+                                         false /* is_pipeline_breaker */);
   }
-  execution_plan_->addDirectDependency(save_blocks_index,
-                                       insert_operator_index,
-                                       false /* is_pipeline_breaker */);
 }
 
 void ExecutionGenerator::convertInsertSelection(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0fe838df/query_optimizer/logical/InsertTuple.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/logical/InsertTuple.cpp b/query_optimizer/logical/InsertTuple.cpp
index e5ffa35..e2ce196 100644
--- a/query_optimizer/logical/InsertTuple.cpp
+++ b/query_optimizer/logical/InsertTuple.cpp
@@ -41,8 +41,10 @@ void InsertTuple::getFieldStringItems(
   non_container_child_field_names->push_back("input");
   non_container_child_fields->push_back(input_);
 
-  container_child_field_names->push_back("column_values");
-  container_child_fields->push_back(CastSharedPtrVector<OptimizerTreeBase>(column_values_));
+  for (const auto &column_values : column_values_) {
+    container_child_field_names->push_back("column_values");
+    container_child_fields->push_back(CastSharedPtrVector<OptimizerTreeBase>(column_values));
+  }
 }
 
 }  // namespace logical

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0fe838df/query_optimizer/logical/InsertTuple.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/logical/InsertTuple.hpp b/query_optimizer/logical/InsertTuple.hpp
index fd0301e..dd35510 100644
--- a/query_optimizer/logical/InsertTuple.hpp
+++ b/query_optimizer/logical/InsertTuple.hpp
@@ -61,7 +61,7 @@ class InsertTuple : public Logical {
   /**
    * @return Column values to be used to compose a new tuple.
    */
-  const std::vector<expressions::ScalarLiteralPtr>& column_values() const {
+  const std::vector<std::vector<expressions::ScalarLiteralPtr>>& column_values()
const {
     return column_values_;
   }
 
@@ -83,12 +83,12 @@ class InsertTuple : public Logical {
    * @brief Creates an InsertTuple logical node.
    *
    * @param input The input produces the relation to insert the tuple to.
-   * @param column_values The column values of the tuple to be inserted.
+   * @param column_values The column values of the tuples to be inserted.
    * @return An immutable InsertTuple node.
    */
   static InsertTuplePtr Create(
       const LogicalPtr &input,
-      const std::vector<expressions::ScalarLiteralPtr> &column_values) {
+      const std::vector<std::vector<expressions::ScalarLiteralPtr>> &column_values)
{
     return InsertTuplePtr(new InsertTuple(input, column_values));
   }
 
@@ -103,13 +103,13 @@ class InsertTuple : public Logical {
 
  private:
   InsertTuple(const LogicalPtr &input,
-              const std::vector<expressions::ScalarLiteralPtr> &column_values)
+              const std::vector<std::vector<expressions::ScalarLiteralPtr>> &column_values)
       : input_(input), column_values_(column_values) {
     addChild(input_);
   }
 
   LogicalPtr input_;
-  std::vector<expressions::ScalarLiteralPtr> column_values_;
+  std::vector<std::vector<expressions::ScalarLiteralPtr>> column_values_;
 
   DISALLOW_COPY_AND_ASSIGN(InsertTuple);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0fe838df/query_optimizer/physical/InsertTuple.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/InsertTuple.cpp b/query_optimizer/physical/InsertTuple.cpp
index 3085389..b209aa0 100644
--- a/query_optimizer/physical/InsertTuple.cpp
+++ b/query_optimizer/physical/InsertTuple.cpp
@@ -40,8 +40,10 @@ void InsertTuple::getFieldStringItems(
   non_container_child_field_names->push_back("input");
   non_container_child_fields->push_back(input_);
 
-  container_child_field_names->push_back("column_values");
-  container_child_fields->push_back(CastSharedPtrVector<OptimizerTreeBase>(column_values_));
+  for (const auto &column_values : column_values_) {
+    container_child_field_names->push_back("column_values");
+    container_child_fields->push_back(CastSharedPtrVector<OptimizerTreeBase>(column_values));
+  }
 }
 
 }  // namespace physical

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0fe838df/query_optimizer/physical/InsertTuple.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/physical/InsertTuple.hpp b/query_optimizer/physical/InsertTuple.hpp
index 40f2582..10c7c5b 100644
--- a/query_optimizer/physical/InsertTuple.hpp
+++ b/query_optimizer/physical/InsertTuple.hpp
@@ -69,7 +69,7 @@ class InsertTuple : public Physical {
   /**
    * @return Column values to be used to compose a new tuple.
    */
-  const std::vector<expressions::ScalarLiteralPtr>& column_values() const {
+  const std::vector<std::vector<expressions::ScalarLiteralPtr>>& column_values()
const {
     return column_values_;
   }
 
@@ -103,7 +103,7 @@ class InsertTuple : public Physical {
    */
   static InsertTuplePtr Create(
       const PhysicalPtr &input,
-      const std::vector<expressions::ScalarLiteralPtr> &column_values) {
+      const std::vector<std::vector<expressions::ScalarLiteralPtr>> &column_values)
{
     return InsertTuplePtr(new InsertTuple(input, column_values));
   }
 
@@ -118,13 +118,13 @@ class InsertTuple : public Physical {
 
  private:
   InsertTuple(const PhysicalPtr &input,
-              const std::vector<expressions::ScalarLiteralPtr> &column_values)
+              const std::vector<std::vector<expressions::ScalarLiteralPtr>> &column_values)
       : input_(input), column_values_(column_values) {
     addChild(input_);
   }
 
   PhysicalPtr input_;
-  std::vector<expressions::ScalarLiteralPtr> column_values_;
+  std::vector<std::vector<expressions::ScalarLiteralPtr>> column_values_;
 
   DISALLOW_COPY_AND_ASSIGN(InsertTuple);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0fe838df/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 2991568..0b6dc22 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -1060,73 +1060,81 @@ L::LogicalPtr Resolver::resolveInsertTuple(
   // Resolve column values.
   const std::vector<E::AttributeReferencePtr> relation_attributes =
       input_logical->getOutputAttributes();
-  const PtrList<ParseScalarLiteral> &parse_column_values =
+  const PtrList<PtrList<ParseScalarLiteral>> &parse_column_values_list =
       insert_statement.getLiteralValues();
-  DCHECK_GT(parse_column_values.size(), 0u);
 
-  if (parse_column_values.size() > relation_attributes.size()) {
-    THROW_SQL_ERROR_AT(insert_statement.relation_name())
-        << "The relation " << insert_statement.relation_name()->value()
-        << " has " << std::to_string(relation_attributes.size())
-        << " columns, but " << std::to_string(parse_column_values.size())
-        << " values are provided";
-  }
+  std::vector<std::vector<E::ScalarLiteralPtr>> resolved_column_values_list;
+  DCHECK_GT(parse_column_values_list.size(), 0u);
 
-  std::vector<E::ScalarLiteralPtr> resolved_column_values;
-  std::vector<E::AttributeReferencePtr>::size_type aid = 0;
-  for (const ParseScalarLiteral &parse_literal_value : parse_column_values) {
-    E::ScalarLiteralPtr resolved_literal_value;
-    ExpressionResolutionInfo expr_resolution_info(
-        name_resolver,
-        "INSERT statement" /* clause_name */,
-        nullptr /* select_list_info */);
-    // When resolving the literal, use the attribute's Type as a hint.
-    CHECK(E::SomeScalarLiteral::MatchesWithConditionalCast(
-        resolveExpression(parse_literal_value,
-                          &(relation_attributes[aid]->getValueType()),
-                          &expr_resolution_info),
-        &resolved_literal_value));
-
-    // Check that the resolved Type is safely coercible to the attribute's
-    // Type.
-    if (!relation_attributes[aid]->getValueType().isSafelyCoercibleFrom(
-            resolved_literal_value->getValueType())) {
-      THROW_SQL_ERROR_AT(&parse_literal_value)
-          << "The assigned value for the column "
-          << relation_attributes[aid]->attribute_name() << " has the type
"
-          << resolved_literal_value->getValueType().getName()
-          << ", which cannot be safely coerced to the column's type "
-          << relation_attributes[aid]->getValueType().getName();
-    }
+  for (const PtrList<ParseScalarLiteral> &parse_column_values : parse_column_values_list)
{
+    DCHECK_GT(parse_column_values.size(), 0u);
 
-    // If the Type is not exactly right (but is safely coercible), coerce it.
-    if (!resolved_literal_value->getValueType().equals(
-            relation_attributes[aid]->getValueType())) {
-      resolved_literal_value = E::ScalarLiteral::Create(
-          relation_attributes[aid]->getValueType().coerceValue(
-              resolved_literal_value->value(),
-              resolved_literal_value->getValueType()),
-          relation_attributes[aid]->getValueType());
+    if (parse_column_values.size() > relation_attributes.size()) {
+      THROW_SQL_ERROR_AT(insert_statement.relation_name())
+          << "The relation " << insert_statement.relation_name()->value()
+          << " has " << std::to_string(relation_attributes.size())
+          << " columns, but " << std::to_string(parse_column_values.size())
+          << " values are provided";
     }
 
-    resolved_column_values.push_back(resolved_literal_value);
-    ++aid;
-  }
+    std::vector<E::ScalarLiteralPtr> resolved_column_values;
+    std::vector<E::AttributeReferencePtr>::size_type aid = 0;
+    for (const ParseScalarLiteral &parse_literal_value : parse_column_values) {
+      E::ScalarLiteralPtr resolved_literal_value;
+      ExpressionResolutionInfo expr_resolution_info(
+          name_resolver,
+          "INSERT statement" /* clause_name */,
+          nullptr /* select_list_info */);
+      // When resolving the literal, use the attribute's Type as a hint.
+      CHECK(E::SomeScalarLiteral::MatchesWithConditionalCast(
+          resolveExpression(parse_literal_value,
+                            &(relation_attributes[aid]->getValueType()),
+                            &expr_resolution_info),
+          &resolved_literal_value));
+
+      // Check that the resolved Type is safely coercible to the attribute's
+      // Type.
+      if (!relation_attributes[aid]->getValueType().isSafelyCoercibleFrom(
+              resolved_literal_value->getValueType())) {
+        THROW_SQL_ERROR_AT(&parse_literal_value)
+            << "The assigned value for the column "
+            << relation_attributes[aid]->attribute_name() << " has the type
"
+            << resolved_literal_value->getValueType().getName()
+            << ", which cannot be safely coerced to the column's type "
+            << relation_attributes[aid]->getValueType().getName();
+      }
 
-  while (aid < relation_attributes.size()) {
-    if (!relation_attributes[aid]->getValueType().isNullable()) {
-      THROW_SQL_ERROR_AT(insert_statement.relation_name())
-          << "Must assign a non-NULL value to column "
-          << relation_attributes[aid]->attribute_name();
+      // If the Type is not exactly right (but is safely coercible), coerce it.
+      if (!resolved_literal_value->getValueType().equals(
+              relation_attributes[aid]->getValueType())) {
+        resolved_literal_value = E::ScalarLiteral::Create(
+            relation_attributes[aid]->getValueType().coerceValue(
+                resolved_literal_value->value(),
+                resolved_literal_value->getValueType()),
+            relation_attributes[aid]->getValueType());
+      }
+
+      resolved_column_values.push_back(resolved_literal_value);
+      ++aid;
+    }
+
+    while (aid < relation_attributes.size()) {
+      if (!relation_attributes[aid]->getValueType().isNullable()) {
+        THROW_SQL_ERROR_AT(insert_statement.relation_name())
+            << "Must assign a non-NULL value to column "
+            << relation_attributes[aid]->attribute_name();
+      }
+      // Create a NULL value.
+      resolved_column_values.push_back(E::ScalarLiteral::Create(
+          relation_attributes[aid]->getValueType().makeNullValue(),
+          relation_attributes[aid]->getValueType()));
+      ++aid;
     }
-    // Create a NULL value.
-    resolved_column_values.push_back(E::ScalarLiteral::Create(
-        relation_attributes[aid]->getValueType().makeNullValue(),
-        relation_attributes[aid]->getValueType()));
-    ++aid;
+
+    resolved_column_values_list.push_back(std::move(resolved_column_values));
   }
 
-  return L::InsertTuple::Create(input_logical, resolved_column_values);
+  return L::InsertTuple::Create(input_logical, resolved_column_values_list);
 }
 
 L::LogicalPtr Resolver::resolveUpdate(


Mime
View raw message