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 &param : 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> &parameters) {
+  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> &parameters);
+
  private:
   ArrayType(const bool nullable, const std::vector<GenericValue> &parameters)
       : 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> &parameters) {
-    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> &parameters);
+
   /**
    * @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> &parameters) {
+  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> &parameters,
+                                     decltype(new T(true)) * = 0) {
+    return parameters.empty();
+  }
+
  protected:
   TypeSynthesizePolicy(const bool nullable,
                        const std::size_t minimum_byte_length,