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/11/17 19:41:01 UTC
[21/27] incubator-quickstep git commit: Support Multiple Tuple Inserts
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(