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/10 18:25:35 UTC

[05/38] incubator-quickstep git commit: Updates for array type

Updates for array type


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

Branch: refs/heads/refactor-type
Commit: 0780fa2e29fa70fb8ad8c8fc03f4ee3913bc5d7b
Parents: a7ccb46
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Mon Oct 2 23:46:48 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 query_optimizer/expressions/CMakeLists.txt    |   1 +
 query_optimizer/expressions/ScalarLiteral.hpp |   3 +-
 query_optimizer/resolver/CMakeLists.txt       |   4 +
 query_optimizer/resolver/Resolver.cpp         |  70 ++-
 types/GenericValue.hpp                        |  18 +-
 types/Type.cpp                                |  18 +
 types/Type.hpp                                |  23 +-
 types/Type.proto                              |   2 +-
 types/TypeSynthesizer.hpp                     | 479 ++++++++++++---------
 utility/CharStream.hpp                        |  34 +-
 utility/meta/Common.hpp                       |  58 ++-
 validate_cmakelists.py                        |   8 +-
 12 files changed, 450 insertions(+), 268 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/query_optimizer/expressions/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt
index dc722e7..cf2727f 100644
--- a/query_optimizer/expressions/CMakeLists.txt
+++ b/query_optimizer/expressions/CMakeLists.txt
@@ -97,6 +97,7 @@ target_link_libraries(quickstep_queryoptimizer_expressions_BinaryExpression
                       quickstep_queryoptimizer_expressions_PatternMatcher
                       quickstep_queryoptimizer_expressions_Scalar
                       quickstep_queryoptimizer_expressions_ScalarLiteral
+                      quickstep_types_GenericValue
                       quickstep_types_operations_OperationSignature
                       quickstep_types_operations_binaryoperations_BinaryOperation
                       quickstep_utility_HashPair

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/query_optimizer/expressions/ScalarLiteral.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/ScalarLiteral.hpp b/query_optimizer/expressions/ScalarLiteral.hpp
index 180ae39..f6a14f4 100644
--- a/query_optimizer/expressions/ScalarLiteral.hpp
+++ b/query_optimizer/expressions/ScalarLiteral.hpp
@@ -108,7 +108,8 @@ class ScalarLiteral : public Scalar {
   ScalarLiteral(const GenericValue &literal_value)
       : value_(literal_value) {}
 
-  const GenericValue &value_;
+  const GenericValue value_;
+
   DISALLOW_COPY_AND_ASSIGN(ScalarLiteral);
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/query_optimizer/resolver/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/CMakeLists.txt b/query_optimizer/resolver/CMakeLists.txt
index a759ce3..8a1116a 100644
--- a/query_optimizer/resolver/CMakeLists.txt
+++ b/query_optimizer/resolver/CMakeLists.txt
@@ -120,7 +120,11 @@ target_link_libraries(quickstep_queryoptimizer_resolver_Resolver
                       quickstep_queryoptimizer_resolver_NameResolver
                       quickstep_storage_StorageBlockLayout_proto
                       quickstep_storage_StorageConstants
+                      quickstep_types_ArrayType
+                      quickstep_types_GenericValue
                       quickstep_types_IntType
+                      quickstep_types_MetaType
+                      quickstep_types_NullType
                       quickstep_types_Type
                       quickstep_types_TypeUtil
                       quickstep_types_TypedValue

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 1ed6b2e..d97bf63 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -115,8 +115,11 @@
 #include "query_optimizer/resolver/NameResolver.hpp"
 #include "storage/StorageBlockLayout.pb.h"
 #include "storage/StorageConstants.hpp"
+#include "types/ArrayType.hpp"
 #include "types/GenericValue.hpp"
 #include "types/IntType.hpp"
+#include "types/MetaType.hpp"
+#include "types/NullType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeUtil.hpp"
@@ -2489,21 +2492,58 @@ E::ScalarPtr Resolver::resolveArray(
     const ParseArray &parse_array,
     const Type *type_hint,
     ExpressionResolutionInfo *expression_resolution_info) {
-//  std::vector<E::ScalarPtr> elements;
-//  const auto &parse_elements = parse_array.elements();
-//  if (parse_elements.empty()) {
-//    // TODO(jianqiao): Figure out how to handle empty array.
-//
-//  } else {
-//    elements.reserve(parse_elements.size());
-//    for (const auto &parse_element : parse_elements) {
-//      elements.emplace_back(
-//          resolveExpression(*parse_element, nullptr, expression_resolution_info));
-//    }
-//
-//    // Currently we only support homogeneous array with literal values.
-//  }
-  LOG(FATAL) << "Not supported";
+  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());
+    return E::ScalarLiteral::Create(
+        GenericValue(ArrayType::InstanceNonNullable({meta_null_type_value}),
+                     ArrayLiteral()));
+  } else {
+    // Currently we only support homogeneous array with literal values.
+    std::vector<E::ScalarLiteralPtr> literals;
+    const Type *element_type = nullptr;
+    for (const auto &parse_element : parse_elements) {
+      const E::ScalarPtr scalar =
+          resolveExpression(*parse_element, nullptr, expression_resolution_info);
+      E::ScalarLiteralPtr literal;
+      if (E::SomeScalarLiteral::MatchesWithConditionalCast(scalar, &literal)) {
+        const GenericValue &value = literal->value();
+        if (element_type == nullptr) {
+          element_type = &value.getType();
+        } else {
+          if (!element_type->equals(value.getType())) {
+            THROW_SQL_ERROR_AT(parse_element)
+                << "Heterogeneous array is not supported: "
+                << "array contains elements of at least two types "
+                << element_type->getName() << " and "
+                << value.getType().getName();
+          }
+        }
+        literals.emplace_back(literal);
+      } else {
+        THROW_SQL_ERROR_AT(parse_element)
+            << "Non-static array element is not supported yet";
+      }
+    }
+    DCHECK(element_type != nullptr);
+
+    const GenericValue meta_element_type_value(
+        MetaType::InstanceNonNullable(), element_type);
+    const Type &array_type =
+        ArrayType::InstanceNonNullable({meta_element_type_value});
+
+    // NOTE(refactor-type): Possibly memory leak region, noexcept.
+    std::unique_ptr<ArrayLiteral> array_literal = std::make_unique<ArrayLiteral>();
+    for (const auto &literal : literals) {
+      array_literal->emplace_back(
+          element_type->cloneValue(literal->value().getValue()));
+    }
+    return E::ScalarLiteral::Create(GenericValue(array_type,
+                                                 array_literal.release(),
+                                                 true /* take_ownership */));
+  }
 }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/types/GenericValue.hpp
----------------------------------------------------------------------
diff --git a/types/GenericValue.hpp b/types/GenericValue.hpp
index 1fcdcd6..62dd9a3 100644
--- a/types/GenericValue.hpp
+++ b/types/GenericValue.hpp
@@ -46,8 +46,10 @@ class GenericValue {
   GenericValue(const Type &type)
       : type_(type), value_(nullptr), owns_(true) {}
 
-  GenericValue(const Type &type, const UntypedLiteral *value, const bool owns)
-      : type_(type), value_(value), owns_(owns) {}
+  GenericValue(const Type &type,
+               const UntypedLiteral *value,
+               const bool take_ownership)
+      : type_(type), value_(value), owns_(take_ownership) {}
 
   GenericValue(const Type &type, const TypedValue &value)
       : type_(type), value_(type.unmarshallTypedValue(value)), owns_(true) {}
@@ -76,7 +78,13 @@ class GenericValue {
   }
 
   serialization::GenericValue getProto() const {
-    LOG(FATAL) << "Not implemented";
+    serialization::GenericValue proto;
+    proto.mutable_type()->MergeFrom(type_.getProto());
+    if (!isNull()) {
+      TypedValue tv = type_.marshallValue(value_);
+      proto.set_data(tv.getDataPtr(), tv.getDataSize());
+    }
+    return proto;
   }
 
   inline bool isNull() const {
@@ -131,7 +139,9 @@ class GenericValue {
   }
 
   inline GenericValue coerce(const Type &other_type) const {
-    LOG(FATAL) << "Not implemented";
+    return GenericValue(other_type,
+                        other_type.coerceValue(value_, type_),
+                        true /* take_ownership */);
   }
 
   inline TypedValue toTypedValue() const {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index b0b781a..41780f8 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -77,4 +77,22 @@ TypedValue Type::coerceTypedValue(const TypedValue &original_value,
   return original_value;
 }
 
+UntypedLiteral* Type::coerceValue(const UntypedLiteral *original_value,
+                                  const Type &original_type) const {
+  DCHECK(isCoercibleFrom(original_type))
+      << "Can't coerce value of Type " << original_type.getName()
+      << " to Type " << getName();
+
+  if (original_type.getTypeID() == kNullType) {
+    return nullptr;
+  }
+
+  DCHECK(equals(original_type) || equals(original_type.getNullableVersion()))
+      << "Base version of Type::coerceValue() called for a non-trivial "
+      << "coercion from Type " << original_type.getName()
+      << " to Type " << getName();
+
+  return cloneValue(original_value);
+}
+
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index d4ed993..e5d5528 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -401,42 +401,33 @@ class Type {
   virtual TypedValue coerceTypedValue(const TypedValue &original_value,
                                       const Type &original_type) const;
 
-
   virtual std::size_t getHash() const = 0;
 
   virtual bool checkValuesEqual(const UntypedLiteral *lhs,
                                 const UntypedLiteral *rhs,
-                                const Type &rhs_type) const {
-    LOG(FATAL) << "Not implemented";
-  }
+                                const Type &rhs_type) const = 0;
 
   inline bool checkValuesEqual(const UntypedLiteral *lhs,
                                const UntypedLiteral *rhs) const {
     return checkValuesEqual(lhs, rhs, *this);
   }
 
+  virtual UntypedLiteral* coerceValue(const UntypedLiteral *original_value,
+                                      const Type &original_type) const;
+
   virtual UntypedLiteral* cloneValue(const UntypedLiteral *value) const = 0;
 
   virtual void destroyValue(UntypedLiteral *value) const = 0;
 
-  virtual std::size_t hashValue(const UntypedLiteral *value) const {
-    LOG(FATAL) << "Not implemented";
-  }
+  virtual std::size_t hashValue(const UntypedLiteral *value) const = 0;
 
-  virtual TypedValue marshallValue(const UntypedLiteral *value) const {
-    LOG(FATAL) << "Not implemented";
-  }
+  virtual TypedValue marshallValue(const UntypedLiteral *value) const = 0;
 
   virtual UntypedLiteral* unmarshallValue(const void *data,
-                                          const std::size_t length) const {
-    LOG(FATAL) << "Not implemented";
-
-  }
+                                          const std::size_t length) const = 0;
 
   virtual UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const = 0;
 
-  virtual UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const = 0;
-
  protected:
   Type(const SuperTypeID super_type_id,
        const TypeID type_id,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/types/Type.proto
----------------------------------------------------------------------
diff --git a/types/Type.proto b/types/Type.proto
index b93f894..e449ee6 100644
--- a/types/Type.proto
+++ b/types/Type.proto
@@ -32,5 +32,5 @@ message Type {
 
 message GenericValue {
   required Type type = 1;
-  required bytes data = 2;
+  optional bytes data = 2;
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index 08ab67a..cebbd6b 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -38,6 +38,9 @@
 #include "types/TypedValue.hpp"
 #include "utility/HashPair.hpp"
 #include "utility/Macros.hpp"
+#include "utility/meta/Common.hpp"
+
+#include "third_party/src/farmhash/farmhash.h"
 
 #include "glog/logging.h"
 
@@ -51,142 +54,13 @@ template <TypeID type_id, typename Enable = void>
 class TypeSynthesizePolicy;
 
 
-template <TypeID type_id>
-class TypeSynthesizer
-    : public Type,
-      public TypeSynthesizePolicy<type_id> {
- private:
-  using Trait = TypeIDTrait<type_id>;
-  using SynthesizePolicy = TypeSynthesizePolicy<type_id>;
-
- public:
-  static constexpr SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID;
-  static constexpr TypeID kStaticTypeID = Trait::kStaticTypeID;
-  static constexpr bool kIsParPod = Trait::kIsParPod;
-  static constexpr MemoryLayout kMemoryLayout = Trait::kMemoryLayout;
-
-  using TypeClass = typename Trait::TypeClass;
-  using cpptype = typename Trait::cpptype;
-
-  serialization::Type getProto() const override {
-    serialization::Type proto;
-
-    proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
-    proto.set_nullable(nullable_);
-    SynthesizePolicy::mergeIntoProto(&proto);
-
-    return proto;
-  }
-
-  const Type& getNullableVersion() const override {
-    return SynthesizePolicy::getInstance(true);
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return SynthesizePolicy::getInstance(false);
-  }
-
-  std::size_t getHash() const override {
-    return SynthesizePolicy::getHash();
-  }
-
-  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
-    return SynthesizePolicy::cloneValue(value);
-  }
-
-  void destroyValue(UntypedLiteral *value) const override {
-    return SynthesizePolicy::destroyValue(value);
-  }
-
-  UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override {
-    return SynthesizePolicy::unmarshallTypedValue(value);
-  }
-
-  UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const override {
-    return SynthesizePolicy::unmarshallTypedValue(std::move(value));
-  }
-
-  std::string printTypedValueToString(const TypedValue &value) const override {
-    return SynthesizePolicy::invokeOnUnmarshalledTypedValue(
-        value,
-        [&](const UntypedLiteral *value) -> std::string {
-      return this->printValueToString(value);
-    });
-  }
-
-  void printTypedValueToFile(const TypedValue &value,
-                             FILE *file,
-                             const int padding = 0) const override {
-    SynthesizePolicy::invokeOnUnmarshalledTypedValue(
-        value,
-        [&](const UntypedLiteral *value) -> void {
-      this->printValueToFile(value, file, padding);
-    });
-  }
-
-  const cpptype& castValueToLiteral(const UntypedLiteral *value) const {
-    return *static_cast<const cpptype*>(value);
-  }
-
-  cpptype& castValueToLiteral(UntypedLiteral *value) const {
-    return *static_cast<cpptype*>(value);
-  }
-
- protected:
-  template <MemoryLayout layout = kMemoryLayout>
-  explicit TypeSynthesizer(const bool nullable,
-                           std::enable_if_t<layout == kCxxInlinePod>* = 0)
-      : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
-             sizeof(cpptype), sizeof(cpptype)),
-        TypeSynthesizePolicy<type_id>(this) {
-  }
-
-  template <MemoryLayout layout = kMemoryLayout>
-  TypeSynthesizer(const bool nullable,
-                  const std::size_t minimum_byte_length,
-                  const std::size_t maximum_byte_length,
-                  const std::size_t parameter,
-                  std::enable_if_t<layout == kParInlinePod ||
-                                   layout == kParOutOfLinePod>* = 0)
-      : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
-             minimum_byte_length, maximum_byte_length),
-        TypeSynthesizePolicy<type_id>(this, parameter) {
-  }
-
-  template <MemoryLayout layout = kMemoryLayout>
-  TypeSynthesizer(const bool nullable,
-                  const std::size_t minimum_byte_length,
-                  const std::size_t maximum_byte_length,
-                  const std::vector<GenericValue> &parameters = {},
-                  std::enable_if_t<layout == kCxxGeneric>* = 0)
-      : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
-             minimum_byte_length, maximum_byte_length),
-        TypeSynthesizePolicy<type_id>(this, parameters) {
-  }
-
- private:
-  template <TypeID, typename> friend class TypeSynthesizePolicy;
-
-  DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
-};
-
-template <TypeID type_id>
-constexpr SuperTypeID TypeSynthesizer<type_id>::kStaticSuperTypeID;
-
-template <TypeID type_id>
-constexpr TypeID TypeSynthesizer<type_id>::kStaticTypeID;
-
-template <TypeID type_id>
-constexpr bool TypeSynthesizer<type_id>::kIsParPod;
-
-template <TypeID type_id>
-constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout;
-
-
+////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////  CxxInlinePod  ///////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 template <TypeID type_id>
 class TypeSynthesizePolicy<
     type_id,
-    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxInlinePod>> {
+    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxInlinePod>> : public Type {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
@@ -209,34 +83,63 @@ class TypeSynthesizePolicy<
     }
   }
 
- protected:
-  explicit TypeSynthesizePolicy(const Type *base)
-      : base_(*base) {}
-
-  inline const Type& getInstance(const bool nullable) const {
-    return nullable ? InstanceNullable() : InstanceNonNullable();
+  std::size_t getHash() const override {
+    return static_cast<std::size_t>(getTypeID());
   }
 
-  inline void mergeIntoProto(serialization::Type *proto) const {}
-
-  inline std::size_t getHash() const {
-    return static_cast<std::size_t>(base_.getTypeID());
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override {
+    // TODO(refactor-type): Operator == overloading.
+    if (type_id_ != rhs_type.getTypeID()) {
+      return false;
+    }
+    return !std::memcmp(lhs, rhs, sizeof(cpptype));
   }
 
-  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
     DCHECK(value != nullptr);
     UntypedLiteral* clone = std::malloc(sizeof(cpptype));
     std::memcpy(clone, value, sizeof(cpptype));
     return clone;
   }
 
-  inline void destroyValue(UntypedLiteral *value) const {
+  void destroyValue(UntypedLiteral *value) const override {
     DCHECK(value != nullptr);
     std::free(value);
   }
 
-  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
-    return base_.cloneValue(value.getDataPtr());
+  std::size_t hashValue(const UntypedLiteral *value) const override {
+    return hashValueInl<sizeof(cpptype)>(value);
+  }
+
+  TypedValue marshallValue(const UntypedLiteral *value) const override {
+    TypedValue ret = makeValue(value, sizeof(cpptype));
+    ret.ensureNotReference();
+    return ret;
+  }
+
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override {
+    DCHECK_EQ(sizeof(cpptype), length);
+    UntypedLiteral *value = std::malloc(sizeof(cpptype));
+    std::memcpy(value, data, sizeof(cpptype));
+    return value;
+  }
+
+ protected:
+  explicit TypeSynthesizePolicy(const bool nullable)
+      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+             sizeof(cpptype), sizeof(cpptype)) {}
+
+  inline const Type& getInstance(const bool nullable) const {
+    return nullable ? InstanceNullable() : InstanceNonNullable();
+  }
+
+  inline void mergeIntoProto(serialization::Type *proto) const {}
+
+  inline UntypedLiteral* unmarshallTypedValueInl(const TypedValue &value) const {
+    return cloneValue(value.getDataPtr());
   }
 
   template <typename Functor>
@@ -252,14 +155,35 @@ class TypeSynthesizePolicy<
     return instance;
   }
 
-  const Type &base_;
+  template <std::size_t size>
+  inline std::size_t hashValueInl(
+      const UntypedLiteral *value,
+      std::enable_if_t<meta::CxxSupportedIntegerSizes
+                           ::template contains<size>::value> * = 0) const {
+    using CxxUIntType = typename meta::UnsignedInteger<size>::type;
+    CxxUIntType buffer;
+    std::memcpy(&buffer, value, size);
+    return buffer;
+  }
+
+  template <std::size_t size>
+  inline std::size_t hashValueInl(
+      const UntypedLiteral *value,
+      std::enable_if_t<!meta::CxxSupportedIntegerSizes
+                            ::template contains<size>::value> * = 0) const {
+    return util::Hash(static_cast<const char*>(value), size);
+  }
 };
 
+
+////////////////////////////////////////////////////////////////////////////////
+///////////////////////  ParInlinePod & ParOutOfLinePod  ///////////////////////
+////////////////////////////////////////////////////////////////////////////////
 template <TypeID type_id>
 class TypeSynthesizePolicy<
     type_id,
     std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kParInlinePod ||
-                     TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> {
+                     TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> : public Type {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
@@ -285,45 +209,70 @@ class TypeSynthesizePolicy<
     }
   }
 
-  inline std::size_t length() const {
+  std::size_t length() const {
     return length_;
   }
 
- protected:
-  TypeSynthesizePolicy(const Type *base, const std::size_t length)
-      : length_(length),
-        base_(*base) {}
-
-  const std::size_t length_;
-
-  inline const Type& getInstance(const bool nullable) const {
-    return nullable ? InstanceNullable(length_) : InstanceNonNullable(length_);
+  std::size_t getHash() const override {
+    return CombineHashes(static_cast<std::size_t>(type_id), length_);
   }
 
-  inline void mergeIntoProto(serialization::Type *proto) const {
-    proto->set_length(length_);
+  std::size_t hashValue(const UntypedLiteral *value) const override {
+    // TODO(refactor-type): Better implementation.
+    return static_cast<const TypedValue*>(value)->getHash();
   }
 
-  inline std::size_t getHash() const {
-    return CombineHashes(static_cast<std::size_t>(base_.getTypeID()), length_);
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override {
+    // TODO(refactor-type): Better implementation.
+    const TypedValue *lhs_value = static_cast<const TypedValue*>(lhs);
+    const TypedValue *rhs_value = static_cast<const TypedValue*>(rhs);
+    return lhs_value->fastEqualCheck(*rhs_value);
   }
 
-  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
     DCHECK(value != nullptr);
     return new TypedValue(*static_cast<const TypedValue*>(value));
   }
 
-  inline void destroyValue(UntypedLiteral *value) const {
+  void destroyValue(UntypedLiteral *value) const override {
     DCHECK(value != nullptr);
     delete static_cast<TypedValue*>(value);
   }
 
-  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
-    return base_.cloneValue(&value);
+  TypedValue marshallValue(const UntypedLiteral *value) const override {
+    return *static_cast<const TypedValue*>(value);
   }
 
-  inline UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const {
-    return new TypedValue(std::move(value));
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override {
+    TypedValue *value = new TypedValue(makeValue(data, length));
+    value->ensureNotReference();
+    return value;
+  }
+
+ protected:
+  TypeSynthesizePolicy(const bool nullable,
+                       const std::size_t minimum_byte_length,
+                       const std::size_t maximum_byte_length,
+                       const std::size_t length)
+      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+             minimum_byte_length, maximum_byte_length),
+        length_(length) {}
+
+  const std::size_t length_;
+
+  inline const Type& getInstance(const bool nullable) const {
+    return nullable ? InstanceNullable(length_) : InstanceNonNullable(length_);
+  }
+
+  inline void mergeIntoProto(serialization::Type *proto) const {
+    proto->set_length(length_);
+  }
+
+  inline UntypedLiteral* unmarshallTypedValueInl(const TypedValue &value) const {
+    return new TypedValue(value);
   }
 
   template <typename Functor>
@@ -343,14 +292,16 @@ class TypeSynthesizePolicy<
     }
     return *(imit->second);
   }
-
-  const Type &base_;
 };
 
+
+////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////  CxxGeneric  ////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 template <TypeID type_id>
 class TypeSynthesizePolicy<
     type_id,
-    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxGeneric>> {
+    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxGeneric>> : public Type {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
@@ -377,15 +328,53 @@ class TypeSynthesizePolicy<
     }
   }
 
-  inline const std::vector<GenericValue>& parameters() const {
+  const std::vector<GenericValue>& parameters() const {
     return parameters_;
   }
 
+  std::size_t getHash() const override {
+    return CombineHashes(static_cast<std::size_t>(type_id_),
+                         ParametersHasher::ComputeHash(parameters_));
+  }
+
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
+    return new cpptype(*static_cast<const cpptype*>(value));
+  }
+
+  void destroyValue(UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
+    delete static_cast<cpptype*>(value);
+  }
+
+  std::size_t hashValue(const UntypedLiteral *value) const override {
+    // TODO(refactor-type): Add note that it is a shallow hash.
+    return util::Hash(static_cast<const char*>(value), sizeof(cpptype));
+  }
+
+  TypedValue marshallValue(const UntypedLiteral *value) const override {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override {
+    LOG(FATAL) << "Not implemented";
+  }
+
  protected:
-  TypeSynthesizePolicy(const Type *base,
+  TypeSynthesizePolicy(const bool nullable,
+                       const std::size_t minimum_byte_length,
+                       const std::size_t maximum_byte_length,
                        const std::vector<GenericValue> &parameters)
-      : parameters_(parameters),
-        base_(*base) {}
+      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+             minimum_byte_length, maximum_byte_length),
+        parameters_(parameters) {}
 
   inline const Type& getInstance(const bool nullable) const {
     return nullable ? InstanceNullable(parameters_)
@@ -398,32 +387,16 @@ class TypeSynthesizePolicy<
     }
   }
 
-  inline std::size_t getHash() const {
-    return CombineHashes(static_cast<std::size_t>(base_.getTypeID()),
-                         ParametersHasher::ComputeHash(parameters_));
-  }
-
-  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
-    DCHECK(value != nullptr);
-    return new cpptype(*static_cast<const cpptype*>(value));
-  }
-
-  inline void destroyValue(UntypedLiteral *value) const {
-    DCHECK(value != nullptr);
-    delete static_cast<cpptype*>(value);
-  }
-
-  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
-    return base_.unmarshallValue(value.getOutOfLineData(), value.getDataSize());
+  inline UntypedLiteral* unmarshallTypedValueInl(const TypedValue &value) const {
+    return unmarshallValue(value.getOutOfLineData(), value.getDataSize());
   }
 
   template <typename Functor>
   inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value,
                                              const Functor &functor) const {
-    std::unique_ptr<typename Trait::cpptype> literal(
-        static_cast<typename Trait::cpptype*>(
-            base_.unmarshallValue(value.getOutOfLineData(),
-                                  value.getDataSize())));
+    std::unique_ptr<cpptype> literal(
+        static_cast<cpptype*>(unmarshallValue(value.getOutOfLineData(),
+                                              value.getDataSize())));
     return functor(literal.get());
   }
 
@@ -477,10 +450,120 @@ class TypeSynthesizePolicy<
     }
     return *(imit->second);
   }
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////  TypeSynthesizer  //////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+template <TypeID type_id>
+class TypeSynthesizer : public TypeSynthesizePolicy<type_id> {
+ private:
+  using Trait = TypeIDTrait<type_id>;
+  using SynthesizePolicy = TypeSynthesizePolicy<type_id>;
+
+ public:
+  static constexpr SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID;
+  static constexpr TypeID kStaticTypeID = Trait::kStaticTypeID;
+  static constexpr bool kIsParPod = Trait::kIsParPod;
+  static constexpr MemoryLayout kMemoryLayout = Trait::kMemoryLayout;
+
+  using TypeClass = typename Trait::TypeClass;
+  using cpptype = typename Trait::cpptype;
+
+  serialization::Type getProto() const override {
+    serialization::Type proto;
+    proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(Type::type_id_));
+    proto.set_nullable(Type::nullable_);
+    SynthesizePolicy::mergeIntoProto(&proto);
+    return proto;
+  }
+
+  const Type& getNullableVersion() const override {
+    return SynthesizePolicy::getInstance(true);
+  }
+
+  const Type& getNonNullableVersion() const override {
+    return SynthesizePolicy::getInstance(false);
+  }
+
+  UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override {
+    return SynthesizePolicy::unmarshallTypedValueInl(value);
+  }
+
+  std::string printTypedValueToString(const TypedValue &value) const override {
+    return SynthesizePolicy::invokeOnUnmarshalledTypedValue(
+        value,
+        [&](const UntypedLiteral *value) -> std::string {
+      return this->printValueToString(value);
+    });
+  }
+
+  void printTypedValueToFile(const TypedValue &value,
+                             FILE *file,
+                             const int padding = 0) const override {
+    SynthesizePolicy::invokeOnUnmarshalledTypedValue(
+        value,
+        [&](const UntypedLiteral *value) -> void {
+      this->printValueToFile(value, file, padding);
+    });
+  }
+
+  const cpptype& castValueToLiteral(const UntypedLiteral *value) const {
+    return *static_cast<const cpptype*>(value);
+  }
+
+  cpptype& castValueToLiteral(UntypedLiteral *value) const {
+    return *static_cast<cpptype*>(value);
+  }
+
+ protected:
+  template <MemoryLayout layout = kMemoryLayout>
+  explicit TypeSynthesizer(const bool nullable,
+                           std::enable_if_t<layout == kCxxInlinePod>* = 0)
+      : TypeSynthesizePolicy<type_id>(nullable) {
+  }
+
+  template <MemoryLayout layout = kMemoryLayout>
+  TypeSynthesizer(const bool nullable,
+                  const std::size_t minimum_byte_length,
+                  const std::size_t maximum_byte_length,
+                  const std::size_t parameter,
+                  std::enable_if_t<layout == kParInlinePod ||
+                                   layout == kParOutOfLinePod>* = 0)
+      : TypeSynthesizePolicy<type_id>(nullable, minimum_byte_length,
+                                      maximum_byte_length, parameter) {
+  }
+
+  template <MemoryLayout layout = kMemoryLayout>
+  TypeSynthesizer(const bool nullable,
+                  const std::size_t minimum_byte_length,
+                  const std::size_t maximum_byte_length,
+                  const std::vector<GenericValue> &parameters = {},
+                  std::enable_if_t<layout == kCxxGeneric>* = 0)
+      : TypeSynthesizePolicy<type_id>(nullable, minimum_byte_length,
+                                      maximum_byte_length, parameters) {
+  }
+
+ private:
+  template <TypeID, typename> friend class TypeSynthesizePolicy;
 
-  const Type &base_;
+  DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
 };
 
+template <TypeID type_id>
+constexpr SuperTypeID TypeSynthesizer<type_id>::kStaticSuperTypeID;
+
+template <TypeID type_id>
+constexpr TypeID TypeSynthesizer<type_id>::kStaticTypeID;
+
+template <TypeID type_id>
+constexpr bool TypeSynthesizer<type_id>::kIsParPod;
+
+template <TypeID type_id>
+constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout;
+
+
 #define QUICKSTEP_SYNTHESIZE_TYPE(type) \
   template <TypeID, typename> friend class TypeSynthesizePolicy; \
   DISALLOW_COPY_AND_ASSIGN(type)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/utility/CharStream.hpp
----------------------------------------------------------------------
diff --git a/utility/CharStream.hpp b/utility/CharStream.hpp
index 060b1a6..5d6ed0b 100644
--- a/utility/CharStream.hpp
+++ b/utility/CharStream.hpp
@@ -40,32 +40,45 @@ class CharStream {
   template <typename T>
   CharStream(const T &value,
              std::enable_if_t<std::is_pod<T>::value && sizeof(T) <= sizeof(std::uint64_t)> * = 0)
-      : length_(sizeof(T)),
+      : object_(nullptr),
+        length_(sizeof(T)),
         delete_function_(nullptr) {
     std::memcpy(&value_union_.inline_data, &value, sizeof(T));
   }
 
-  CharStream(std::vector<char> &&value)
-      : length_(value.size()),
+  CharStream(const std::vector<char> *value)
+      : object_(const_cast<std::vector<char>*>(value)),
+        length_(value->size()),
         delete_function_(&DeleteObject<std::vector<char>>) {
-    value_union_.out_of_line_data = new std::vector<char>(std::move(value));
+    value_union_.out_of_line_data = value->data();
   }
 
-  CharStream(const void *value, const std::size_t length, const bool take_ownership)
+  CharStream(const void *value,
+             const std::size_t length,
+             const bool take_ownership)
       : length_(length),
         delete_function_(std::free) {
     if (take_ownership) {
-      value_union_.out_of_line_data = value;
+      object_ = const_cast<void*>(value);
     } else {
-      void *copy_of_value = std::malloc(length);
-      std::memcpy(copy_of_value, value, length);
-      value_union_.out_of_line_data = copy_of_value;
+      object_ = std::malloc(length);
+      std::memcpy(object_, value, length);
     }
+    value_union_.out_of_line_data = object_;
+  }
+
+  CharStream(CharStream &&other)
+      : object_(other.object_),
+        length_(other.length_),
+        value_union_(other.value_union_),
+        delete_function_(other.delete_function_) {
+    other.delete_function_ = nullptr;
   }
 
   ~CharStream() {
     if (delete_function_ != nullptr) {
-      delete_function_(const_cast<void*>(value_union_.out_of_line_data));
+      DCHECK(object_ != nullptr);
+      delete_function_(object_);
     }
   }
 
@@ -91,6 +104,7 @@ class CharStream {
     delete static_cast<T*>(object);
   }
 
+  void *object_;
   std::size_t length_;
   ValueUnion value_union_;
   DeleterFunction delete_function_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/utility/meta/Common.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/Common.hpp b/utility/meta/Common.hpp
index 39c513e..901b65c 100644
--- a/utility/meta/Common.hpp
+++ b/utility/meta/Common.hpp
@@ -27,6 +27,22 @@ namespace meta {
  *  @{
  */
 
+template <typename ...> struct Conjunction : std::true_type {};
+template <typename B> struct Conjunction<B> : B {};
+template <typename B, typename ...Bs>
+struct Conjunction<B, Bs...>
+    : std::conditional_t<B::value, Conjunction<Bs...>, B> {};
+
+template <typename ...> struct Disjunction : std::false_type {};
+template <typename B> struct Disjunction<B> : B {};
+template <typename B, typename ...Bs>
+struct Disjunction<B, Bs...>
+    : std::conditional_t<B::value, B, Disjunction<Bs...>> {};
+
+template <typename check, typename ...cases>
+struct EqualsAny : Disjunction<std::is_same<check, cases>...> {};
+
+
 template <typename T, T ...s>
 struct Sequence {
   template <template <typename ...> class Host>
@@ -38,6 +54,10 @@ struct Sequence {
   template <typename U>
   using cast_to = Sequence<U, static_cast<U>(s)...>;
 
+  template <T v>
+  using contains = EqualsAny<std::integral_constant<T, v>,
+                             std::integral_constant<T, s>...>;
+
   template <typename CollectionT>
   inline static CollectionT Instantiate() {
     return { s... };
@@ -57,25 +77,6 @@ struct MakeSequence<0, s...> {
 };
 
 
-template <typename ...> struct Conjunction : std::true_type {};
-template <typename B> struct Conjunction<B> : B {};
-template <typename B, typename ...Bs>
-struct Conjunction<B, Bs...>
-    : std::conditional_t<B::value, Conjunction<Bs...>, B> {};
-
-template <typename ...> struct Disjunction : std::false_type {};
-template <typename B> struct Disjunction<B> : B {};
-template <typename B, typename ...Bs>
-struct Disjunction<B, Bs...>
-    : std::conditional_t<B::value, B, Disjunction<Bs...>> {};
-
-template <typename check, typename ...cases>
-struct EqualsAny {
-  static constexpr bool value =
-     Disjunction<std::is_same<check, cases>...>::value;
-};
-
-
 template <typename T, typename Enable = void>
 struct IsTrait {
   static constexpr bool value = false;
@@ -135,6 +136,25 @@ struct TraitUnwrapper {
   using type = typename Op<ArgTypes...>::type;
 };
 
+
+using CxxSupportedIntegerSizes = meta::IntegerSequence<1u, 2u, 4u, 8u>;
+
+template <std::size_t size>
+struct UnsignedInteger;
+
+template <> struct UnsignedInteger<1u> {
+  using type = std::uint8_t;
+};
+template <> struct UnsignedInteger<2u> {
+  using type = std::uint16_t;
+};
+template <> struct UnsignedInteger<4u> {
+  using type = std::uint32_t;
+};
+template <> struct UnsignedInteger<8u> {
+  using type = std::uint64_t;
+};
+
 /** @} */
 
 }  // namespace meta

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/validate_cmakelists.py
----------------------------------------------------------------------
diff --git a/validate_cmakelists.py b/validate_cmakelists.py
index f5f2f89..4de44c9 100755
--- a/validate_cmakelists.py
+++ b/validate_cmakelists.py
@@ -415,7 +415,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs):
                     validation_failed_targets.add(target)
                     print("Missing target_link_libraries() for " + target + ":")
                     for dep in sorted(include_deps):
-                        print("\t" + dep)
+                        print("                      " + dep)
             else:
                 missing_deps = (include_deps
                                 - deps_in_cmake[target]
@@ -424,7 +424,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs):
                     validation_failed_targets.add(target)
                     print("Missing target_link_libraries() for " + target + ":")
                     for dep in sorted(missing_deps):
-                        print("\t" + dep)
+                        print("                      " + dep)
         elif target == module_targetname:
             # Special case hack for module all-in-one library
             missing_deps = (frozenset(deps_from_includes.keys())
@@ -438,7 +438,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs):
                 validation_failed_targets.add(target)
                 print("Missing target_link_libraries() for " + target + ":")
                 for dep in sorted(true_missing_deps):
-                    print("\t" + dep)
+                    print("                      " + dep)
     # Also report possibly superfluous extra dependencies.
     for target, cmake_deps in iter(deps_in_cmake.items()):
         if (target not in skipped_targets) and (target in deps_from_includes):
@@ -450,7 +450,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs):
                 print("Possibly superfluous target_link_libraries() for "
                        + target + ":")
                 for dep in sorted(extra_deps):
-                    print("\t" + dep)
+                    print("                      " + dep)
     return (validation_failed_targets, skipped_targets, generated_targets)
 
 def main(cmakelists_to_process):