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/10/05 22:17:45 UTC
[40/40] incubator-quickstep git commit: More updates to types
More updates to types
Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/580eb002
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/580eb002
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/580eb002
Branch: refs/heads/new-op
Commit: 580eb002c33054fe14d7d90cb3034b6b13362f84
Parents: 65978e2
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Wed Oct 4 03:21:44 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Thu Oct 5 17:03:11 2017 -0500
----------------------------------------------------------------------
parser/ParseDataType.cpp | 6 +-
parser/ParseDataType.hpp | 12 ++--
query_optimizer/resolver/Resolver.cpp | 108 ++++++++++++++++++++++++-----
query_optimizer/resolver/Resolver.hpp | 3 +
types/ArrayType.cpp | 7 ++
types/ArrayType.hpp | 10 ++-
types/GenericValue.hpp | 35 +++++++---
types/TypeFactory-decl.hpp | 12 ++++
types/TypeFactory.cpp | 45 ++++++++++--
types/TypeSynthesizer.hpp | 6 ++
10 files changed, 197 insertions(+), 47 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/580eb002/parser/ParseDataType.cpp
----------------------------------------------------------------------
diff --git a/parser/ParseDataType.cpp b/parser/ParseDataType.cpp
index b960961..7892122 100644
--- a/parser/ParseDataType.cpp
+++ b/parser/ParseDataType.cpp
@@ -33,11 +33,11 @@ void ParseDataType::getFieldStringItems(
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 {
- inline_field_names->emplace_back("name");
- inline_field_values->emplace_back(name_->value());
+ inline_field_names->emplace_back("type_name");
+ inline_field_values->emplace_back(type_name_->value());
inline_field_names->emplace_back("nullable");
-
+ inline_field_values->emplace_back(nullable_ ? "true" : "false");
container_child_field_names->emplace_back("parameters");
container_child_fields->emplace_back();
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/580eb002/parser/ParseDataType.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseDataType.hpp b/parser/ParseDataType.hpp
index 96b7b96..b554011 100644
--- a/parser/ParseDataType.hpp
+++ b/parser/ParseDataType.hpp
@@ -41,7 +41,7 @@ class Type;
class ParseDataTypeParameter : public ParseTreeNode {
public:
- enum class ParameterType {
+ enum ParameterType {
kDataType,
kLiteralValue
};
@@ -64,15 +64,19 @@ class ParseDataType : public ParseTreeNode {
public:
ParseDataType(const int line_number,
const int column_number,
- ParseString *name)
+ ParseString *type_name)
: ParseTreeNode(line_number, column_number),
- name_(name),
+ type_name_(type_name),
nullable_(false) {}
std::string getName() const override {
return "DataType";
}
+ const ParseString& type_name() const {
+ return *type_name_;
+ }
+
const std::vector<std::unique_ptr<ParseDataTypeParameter>>& parameters() const {
return parameters_;
}
@@ -99,7 +103,7 @@ class ParseDataType : public ParseTreeNode {
std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
private:
- const std::unique_ptr<ParseString> name_;
+ const std::unique_ptr<ParseString> type_name_;
std::vector<std::unique_ptr<ParseDataTypeParameter>> parameters_;
bool nullable_;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/580eb002/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 37a93fb..cf3ca6e 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -43,6 +43,7 @@
#include "parser/ParseBasicExpressions.hpp"
#include "parser/ParseBlockProperties.hpp"
#include "parser/ParseCaseExpressions.hpp"
+#include "parser/ParseDataType.hpp"
#include "parser/ParseExpression.hpp"
#include "parser/ParseGeneratorTableReference.hpp"
#include "parser/ParseGroupBy.hpp"
@@ -118,6 +119,7 @@
#include "types/ArrayType.hpp"
#include "types/GenericValue.hpp"
#include "types/IntType.hpp"
+#include "types/LongType.hpp"
#include "types/MetaType.hpp"
#include "types/NullType.hpp"
#include "types/Type.hpp"
@@ -639,14 +641,13 @@ L::LogicalPtr Resolver::resolveCreateTable(
<< "Column " << attribute_definition.name()->value()
<< " is specified more than once";
}
- LOG(FATAL) << "TODO(refactor-type): To implement";
-// attributes.emplace_back(
-// E::AttributeReference::Create(context_->nextExprId(),
-// attribute_definition.name()->value(),
-// attribute_definition.name()->value(),
-// relation_name,
-// attribute_definition.data_type().getType(),
-// E::AttributeReferenceScope::kLocal));
+ attributes.emplace_back(
+ E::AttributeReference::Create(context_->nextExprId(),
+ attribute_definition.name()->value(),
+ attribute_definition.name()->value(),
+ relation_name,
+ resolveDataType(attribute_definition.data_type()),
+ E::AttributeReferenceScope::kLocal));
attribute_name_set.insert(lower_attribute_name);
}
@@ -1117,7 +1118,7 @@ L::LogicalPtr Resolver::resolveInsertTuple(
}
// Create a NULL value.
resolved_column_values.push_back(E::ScalarLiteral::Create(
- GenericValue(relation_attributes[aid]->getValueType())));
+ GenericValue::CreateNullValue(relation_attributes[aid]->getValueType())));
++aid;
}
@@ -1193,6 +1194,72 @@ L::LogicalPtr Resolver::resolveUpdate(
resolved_where_predicate);
}
+const Type& Resolver::resolveDataType(const ParseDataType &parse_data_type) {
+ const std::string &type_name = ToLower(parse_data_type.type_name().value());
+ if (!TypeFactory::TypeNameIsValid(type_name)) {
+ THROW_SQL_ERROR_AT(&parse_data_type.type_name())
+ << "Unrecognized type name: " << type_name;
+ }
+
+ const TypeID type_id = TypeFactory::GetTypeIDForName(type_name);
+ const MemoryLayout memory_layout = TypeUtil::GetMemoryLayout(type_id);
+
+ const auto &parse_parameters = parse_data_type.parameters();
+ if (memory_layout == kCxxInlinePod) {
+ if (!parse_parameters.empty()) {
+ THROW_SQL_ERROR_AT(parse_parameters.front())
+ << "Invalid parameter to type " << type_name;
+ }
+ return TypeFactory::GetType(type_id, parse_data_type.nullable());
+ }
+
+ std::vector<GenericValue> values;
+ for (const auto ¶m : parse_parameters) {
+ if (param->getParameterType() == ParseDataTypeParameter::kLiteralValue) {
+ const ParseLiteralValue &literal_value =
+ static_cast<const ParseDataTypeParameterLiteralValue&>(*param).literal_value();
+ const Type *value_type = nullptr;
+ TypedValue value = literal_value.concretize(nullptr, &value_type);
+ DCHECK(value_type != nullptr);
+ values.emplace_back(GenericValue::CreateWithTypedValue(*value_type, value));
+ } else {
+ DCHECK(param->getParameterType() == ParseDataTypeParameter::kDataType);
+ const ParseDataType &element_type =
+ static_cast<const ParseDataTypeParameterDataType&>(*param).data_type();
+ values.emplace_back(
+ GenericValue::CreateWithLiteral(MetaType::InstanceNonNullable(),
+ &resolveDataType(element_type)));
+ }
+ }
+
+ if (memory_layout == kParInlinePod || memory_layout == kParOutOfLinePod) {
+ if (values.size() != 1) {
+ THROW_SQL_ERROR_AT(parse_parameters.front())
+ << "Invalid parameter to type " << type_name;
+ }
+ const GenericValue &value = values.front();
+ const Type &value_type = value.getType();
+
+ std::size_t length = 0;
+ if (value_type.getTypeID() == kInt) {
+ length = value.getLiteral<kInt>();
+ } else if (value_type.getTypeID() == kLong) {
+ length = value.getLiteral<kLong>();
+ } else {
+ THROW_SQL_ERROR_AT(parse_parameters.front())
+ << "Invalid parameter to type " << type_name;
+ }
+ return TypeFactory::GetType(type_id, length);
+ }
+
+ DCHECK(memory_layout == kCxxGeneric);
+ if (!TypeFactory::TypeParametersAreValid(type_id, values)) {
+ THROW_SQL_ERROR_AT(parse_parameters.front())
+ << "Invalid parameter to type " << type_name;
+ }
+ return TypeFactory::GetType(type_id, values);
+}
+
L::LogicalPtr Resolver::resolveSelect(
const ParseSelect &select_query,
const std::string &select_name,
@@ -2452,7 +2519,8 @@ E::ScalarPtr Resolver::resolveExpression(
const Type *concrete_type = nullptr;
TypedValue concrete = parse_literal_scalar.literal_value()
->concretize(type_hint, &concrete_type);
- return E::ScalarLiteral::Create(GenericValue(*concrete_type, concrete));
+ return E::ScalarLiteral::Create(
+ GenericValue::CreateWithTypedValue(*concrete_type, concrete));
}
case ParseExpression::kSearchedCaseExpression: {
const ParseSearchedCaseExpression &parse_searched_case_expression =
@@ -2496,11 +2564,13 @@ E::ScalarPtr Resolver::resolveArray(
const auto &parse_elements = parse_array.elements();
if (parse_elements.empty()) {
// TODO(jianqiao): Figure out how to handle empty array.
- const GenericValue meta_null_type_value(
- MetaType::InstanceNonNullable(), &NullType::InstanceNullable());
+ const GenericValue meta_null_type_value =
+ GenericValue::CreateWithLiteral(MetaType::InstanceNonNullable(),
+ &NullType::InstanceNullable());
return E::ScalarLiteral::Create(
- GenericValue(ArrayType::InstanceNonNullable({meta_null_type_value}),
- ArrayLiteral()));
+ GenericValue::CreateWithLiteral(
+ ArrayType::InstanceNonNullable({meta_null_type_value}),
+ ArrayLiteral()));
} else {
// Currently we only support homogeneous array with literal values.
std::vector<E::ScalarLiteralPtr> literals;
@@ -2530,8 +2600,9 @@ E::ScalarPtr Resolver::resolveArray(
}
DCHECK(element_type != nullptr);
- const GenericValue meta_element_type_value(
- MetaType::InstanceNonNullable(), element_type);
+ const GenericValue meta_element_type_value =
+ GenericValue::CreateWithLiteral(MetaType::InstanceNonNullable(),
+ element_type);
const Type &array_type =
ArrayType::InstanceNonNullable({meta_element_type_value});
@@ -2541,9 +2612,8 @@ E::ScalarPtr Resolver::resolveArray(
array_literal->emplace_back(
element_type->cloneValue(literal->value().getValue()));
}
- return E::ScalarLiteral::Create(GenericValue(array_type,
- array_literal.release(),
- true /* take_ownership */));
+ return E::ScalarLiteral::Create(
+ GenericValue::CreateWithOwnedData(array_type, array_literal.release()));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/580eb002/query_optimizer/resolver/Resolver.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.hpp b/query_optimizer/resolver/Resolver.hpp
index c44d8ef..1844493 100644
--- a/query_optimizer/resolver/Resolver.hpp
+++ b/query_optimizer/resolver/Resolver.hpp
@@ -42,6 +42,7 @@ class CatalogDatabase;
class CatalogRelation;
class Comparison;
class ParseArray;
+class ParseDataType;
class ParseExpression;
class ParseFunctionCall;
class ParseGeneratorTableReference;
@@ -581,6 +582,8 @@ class Resolver {
*/
const CatalogRelation *resolveRelationName(const ParseString *relation_name);
+ const Type& resolveDataType(const ParseDataType &parse_data_type);
+
/**
* @brief Determines whether \p op can apply to \p left_operand and \p
* right_operand.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/580eb002/types/ArrayType.cpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.cpp b/types/ArrayType.cpp
index 30cc4a5..765a1a0 100644
--- a/types/ArrayType.cpp
+++ b/types/ArrayType.cpp
@@ -39,6 +39,13 @@ std::string ArrayType::getName() const {
return name;
}
+bool ArrayType::TypeParametersAreValid(const std::vector<GenericValue> ¶meters) {
+ if (parameters.size() != 1u) {
+ return false;
+ }
+ return parameters.front().getType().getTypeID() == kMetaType;
+}
+
bool ArrayType::checkValuesEqual(const UntypedLiteral *lhs,
const UntypedLiteral *rhs,
const Type &rhs_type) const {
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/580eb002/types/ArrayType.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp
index f7e2212..5eaff92 100644
--- a/types/ArrayType.hpp
+++ b/types/ArrayType.hpp
@@ -63,19 +63,17 @@ class ArrayType : public TypeSynthesizer<kArray> {
return false;
}
+ static bool TypeParametersAreValid(const std::vector<GenericValue> ¶meters);
+
private:
ArrayType(const bool nullable, const std::vector<GenericValue> ¶meters)
: TypeSynthesizer<kArray>(nullable, 0, 0x1000, parameters),
element_type_(ExtractType(parameters)) {
- // TODO(refactor-type): Possibly infinite maximum size.
- // TODO(refactor-type): Validate parameters.
}
static const Type& ExtractType(const std::vector<GenericValue> ¶meters) {
- DCHECK_EQ(1u, parameters.size());
- const GenericValue &value = parameters.front();
- DCHECK(value.getType().getTypeID() == kMetaType);
- return **static_cast<const MetaTypeLiteral*>(value.getValue());
+ DCHECK(TypeParametersAreValid(parameters));
+ return **static_cast<const MetaTypeLiteral*>(parameters.front().getValue());
}
const Type &element_type_;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/580eb002/types/GenericValue.hpp
----------------------------------------------------------------------
diff --git a/types/GenericValue.hpp b/types/GenericValue.hpp
index 62dd9a3..3e8045b 100644
--- a/types/GenericValue.hpp
+++ b/types/GenericValue.hpp
@@ -43,20 +43,30 @@ namespace quickstep {
class GenericValue {
public:
- GenericValue(const Type &type)
- : type_(type), value_(nullptr), owns_(true) {}
+ static GenericValue CreateNullValue(const Type &type) {
+ return GenericValue(type, nullptr, true);
+ }
- GenericValue(const Type &type,
- const UntypedLiteral *value,
- const bool take_ownership)
- : type_(type), value_(value), owns_(take_ownership) {}
+ static GenericValue CreateWithOwnedData(const Type &type,
+ const UntypedLiteral *value) {
+ return GenericValue(type, value, true);
+ }
- GenericValue(const Type &type, const TypedValue &value)
- : type_(type), value_(type.unmarshallTypedValue(value)), owns_(true) {}
+ static GenericValue CreateReference(const Type &type,
+ const UntypedLiteral *value) {
+ return GenericValue(type, value, false);
+ }
+
+ static GenericValue CreateWithTypedValue(const Type &type,
+ const TypedValue &value) {
+ return GenericValue(type, type.unmarshallTypedValue(value), true);
+ }
template <typename TypeClass>
- GenericValue(const TypeClass &type, const typename TypeClass::cpptype &value)
- : type_(type), value_(type.cloneValue(&value)), owns_(true) {}
+ static GenericValue CreateWithLiteral(const TypeClass &type,
+ const typename TypeClass::cpptype &value) {
+ return GenericValue(type, type.cloneValue(&value), true);
+ }
GenericValue(const GenericValue &other)
: type_(other.type_),
@@ -153,6 +163,11 @@ class GenericValue {
}
private:
+ GenericValue(const Type &type,
+ const UntypedLiteral *value,
+ const bool take_ownership)
+ : type_(type), value_(value), owns_(take_ownership) {}
+
const Type &type_;
const UntypedLiteral *value_;
bool owns_;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/580eb002/types/TypeFactory-decl.hpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory-decl.hpp b/types/TypeFactory-decl.hpp
index 6edc05b..f67208e 100644
--- a/types/TypeFactory-decl.hpp
+++ b/types/TypeFactory-decl.hpp
@@ -21,6 +21,9 @@
#define QUICKSTEP_TYPES_TYPE_FACTORY_DECL_HPP_
#include <cstddef>
+#include <string>
+#include <unordered_map>
+#include <vector>
#include "types/GenericValue.hpp"
#include "types/TypeID.hpp"
@@ -42,6 +45,10 @@ namespace serialization { class Type; }
**/
class TypeFactory {
public:
+ static bool TypeNameIsValid(const std::string &type_name);
+
+ static TypeID GetTypeIDForName(const std::string &type_name);
+
/**
* @brief Determine if a length parameter is required when getting a Type of
* the specified TypeID.
@@ -51,6 +58,9 @@ class TypeFactory {
**/
static bool TypeRequiresLengthParameter(const TypeID id);
+ static bool TypeParametersAreValid(const TypeID id,
+ const std::vector<GenericValue> ¶meters);
+
/**
* @brief Factory method to get a Type by its TypeID.
* @note This version is for Types without a length parameter (currently
@@ -131,6 +141,8 @@ class TypeFactory {
// instantiated.
TypeFactory();
+ static const std::unordered_map<std::string, TypeID>& GetTypeNameMap();
+
DISALLOW_COPY_AND_ASSIGN(TypeFactory);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/580eb002/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index 45202f1..9029408 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -21,6 +21,7 @@
#include <cstddef>
#include <string>
+#include <unordered_map>
#include <vector>
#include "types/GenericValue.hpp"
@@ -30,15 +31,41 @@
#include "types/TypeSynthesizer.hpp"
#include "types/TypeUtil.hpp"
#include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
#include "glog/logging.h"
namespace quickstep {
+bool TypeFactory::TypeNameIsValid(const std::string &type_name) {
+ const auto &type_name_map = GetTypeNameMap();
+ return type_name_map.find(type_name) != type_name_map.end();
+}
+
+TypeID TypeFactory::GetTypeIDForName(const std::string &type_name) {
+ DCHECK(TypeNameIsValid(type_name));
+ return GetTypeNameMap().at(type_name);
+}
+
bool TypeFactory::TypeRequiresLengthParameter(const TypeID id) {
return TypeUtil::IsParameterizedPod(id);
}
+bool TypeFactory::TypeParametersAreValid(
+ const TypeID id, const std::vector<GenericValue> ¶meters) {
+ if (TypeUtil::GetMemoryLayout(id) != kCxxGeneric) {
+ return false;
+ }
+
+ return InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxGeneric>>(
+ id,
+ [&](auto id) -> bool { // NOLINT(build/c++11)
+ using TypeClass = typename TypeIDTrait<decltype(id)::value>::TypeClass;
+ return TypeClass::TypeParametersAreValid(parameters);
+ });
+}
+
+
const Type& TypeFactory::GetType(const TypeID id,
const bool nullable) {
DCHECK(TypeUtil::GetMemoryLayout(id) == kCxxInlinePod)
@@ -124,12 +151,10 @@ GenericValue TypeFactory::ReconstructValueFromProto(
const serialization::GenericValue &proto) {
const Type &type = ReconstructFromProto(proto.type());
if (proto.has_data()) {
- return GenericValue(type,
- type.unmarshallValue(proto.data().c_str(),
- proto.data().size()),
- true /* take_ownership */);
+ return GenericValue::CreateWithOwnedData(
+ type, type.unmarshallValue(proto.data().c_str(), proto.data().size()));
} else {
- return GenericValue(type);
+ return GenericValue::CreateNullValue(type);
}
}
@@ -168,4 +193,14 @@ const Type* TypeFactory::GetUnifyingType(const Type &first, const Type &second)
return unifier;
}
+const std::unordered_map<std::string, TypeID>& TypeFactory::GetTypeNameMap() {
+ static std::unordered_map<std::string, TypeID> type_name_map;
+ if (type_name_map.empty()) {
+ for (std::size_t i = 0; i < static_cast<std::size_t>(kNumTypeIDs); ++i) {
+ type_name_map.emplace(ToLower(kTypeNames[i]), static_cast<TypeID>(i));
+ }
+ }
+ return type_name_map;
+}
+
} // namespace quickstep
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/580eb002/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index f0761d1..0b5842f 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -365,6 +365,12 @@ class TypeSynthesizePolicy<
// LOG(FATAL) << "Not implemented";
// }
+ template <typename T = TypeClass>
+ static bool TypeParametersAreValid(const std::vector<GenericValue> ¶meters,
+ decltype(new T(true)) * = 0) {
+ return parameters.empty();
+ }
+
protected:
TypeSynthesizePolicy(const bool nullable,
const std::size_t minimum_byte_length,