Repository: incubator-quickstep
Updated Branches:
  refs/heads/new-op 959cd0d40 -> db611137e


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/9db9fc86
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/9db9fc86
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/9db9fc86

Branch: refs/heads/new-op
Commit: 9db9fc869d808fba49274a3729113c6dcc80d147
Parents: 959cd0d
Author: Jianqiao Zhu <jianq...@cs.wisc.edu>
Authored: Wed Mar 29 20:13:48 2017 -0500
Committer: Jianqiao Zhu <jianq...@cs.wisc.edu>
Committed: Wed Mar 29 20:13:48 2017 -0500

----------------------------------------------------------------------
 query_optimizer/LogicalGenerator.cpp            |   7 +-
 types/AsciiStringSuperType.hpp                  |  77 +++++++++++
 types/CMakeLists.txt                            |  12 +-
 types/CharType.cpp                              |  13 --
 types/CharType.hpp                              |  33 +----
 types/DateType.cpp                              |  19 ---
 types/DateType.hpp                              |  20 +--
 types/DatetimeIntervalType.cpp                  |  19 ---
 types/DatetimeIntervalType.hpp                  |  22 +---
 types/DatetimeType.cpp                          |  19 ---
 types/DatetimeType.hpp                          |  21 +--
 types/DoubleType.hpp                            |  12 +-
 types/FloatType.hpp                             |  12 +-
 types/IntType.hpp                               |  12 +-
 types/LongType.hpp                              |  12 +-
 types/NullType.hpp                              |  17 +--
 types/NumericSuperType.hpp                      |   7 +-
 types/Type.cpp                                  |  22 +++-
 types/Type.hpp                                  | 128 ++++++++-----------
 types/Type.proto                                |  18 +--
 types/TypeFactory.cpp                           | 116 ++++++-----------
 types/TypeFactory.hpp                           |  20 +--
 types/TypeID.hpp                                |   2 +-
 types/TypeUtil.hpp                              |  24 ++--
 types/VarCharType.cpp                           |  13 --
 types/VarCharType.hpp                           |  33 +----
 types/YearMonthIntervalType.cpp                 |  19 ---
 types/YearMonthIntervalType.hpp                 |  22 +---
 types/operations/OperationFactory.cpp           |   2 +-
 .../unary_operations/CMathUnaryOperations.hpp   |  11 +-
 .../unary_operations/CastOperation.cpp          |  12 +-
 31 files changed, 273 insertions(+), 503 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/query_optimizer/LogicalGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/LogicalGenerator.cpp 
b/query_optimizer/LogicalGenerator.cpp
index 940b728..01af806 100644
--- a/query_optimizer/LogicalGenerator.cpp
+++ b/query_optimizer/LogicalGenerator.cpp
@@ -51,10 +51,11 @@ L::LogicalPtr LogicalGenerator::generatePlan(
     const CatalogDatabase &catalog_database,
     const ParseStatement &parse_statement) {
   resolver::Resolver resolver(catalog_database, optimizer_context_);
-//  DVLOG(4) << "Parse tree:\n" << parse_statement.toString();
-  std::cerr << "Parse tree:\n" << parse_statement.toString();
+  DVLOG(4) << "Parse tree:\n" << parse_statement.toString();
+//  std::cerr << "Parse tree:\n" << parse_statement.toString();
   logical_plan_ = resolver.resolve(parse_statement);
-  std::cerr << "Initial logical plan:\n" << logical_plan_->toString();
+  DVLOG(4) << "Initial logical plan:\n" << logical_plan_->toString();
+//  std::cerr << "Initial logical plan:\n" << logical_plan_->toString();
 //  exit(0);
 
   optimizePlan();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/AsciiStringSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/AsciiStringSuperType.hpp b/types/AsciiStringSuperType.hpp
new file mode 100644
index 0000000..82396b2
--- /dev/null
+++ b/types/AsciiStringSuperType.hpp
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_ASCII_STRING_SUPER_TYPE_HPP_
+#define QUICKSTEP_TYPES_ASCII_STRING_SUPER_TYPE_HPP_
+
+#include <cstddef>
+
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+/**
+ * @brief A superclass for ASCII string types.
+ **/
+template <typename TypeClass, TypeID type_id, TypeStorageLayout layout>
+class AsciiStringSuperType : public TypeSynthesizer<TypeClass, type_id, true, 
layout> {
+ public:
+  bool isCoercibleFrom(const Type &original_type) const override {
+    if (original_type.isNullable() && !this->nullable_) {
+      return false;
+    }
+    return (original_type.getSuperTypeID() == Type::kAsciiString)
+           || (original_type.getTypeID() == kNullType);
+  }
+
+  /**
+   * @brief Get the character-length of this string type.
+   *
+   * @return The maximum length of a string of this type.
+   **/
+  inline std::size_t getStringLength() const {
+    return length_;
+  }
+
+ protected:
+  AsciiStringSuperType(const bool nullable,
+                       const std::size_t minimum_byte_length,
+                       const std::size_t maximum_byte_length,
+                       const std::size_t string_length)
+      : TypeSynthesizer<TypeClass, type_id, true, layout>(
+            Type::kAsciiString, type_id, nullable, minimum_byte_length, 
maximum_byte_length),
+        length_(string_length) {
+  }
+
+  const std::size_t length_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AsciiStringSuperType);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_ASCII_STRING_SUPER_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 0c7ee07..96aea8c 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -32,6 +32,7 @@ QS_PROTOBUF_GENERATE_CPP(types_TypedValue_proto_srcs 
types_TypedValue_proto_hdrs
 QS_PROTOBUF_GENERATE_CPP(types_Type_proto_srcs types_Type_proto_hdrs 
Type.proto)
 
 # Declare micro-libs:
+add_library(quickstep_types_AsciiStringSuperType ../empty_src.cpp 
AsciiStringSuperType.hpp)
 add_library(quickstep_types_CharType CharType.cpp CharType.hpp)
 add_library(quickstep_types_DateOperatorOverloads ../empty_src.cpp 
DateOperatorOverloads.hpp)
 add_library(quickstep_types_DateType DateType.cpp DateType.hpp)
@@ -60,6 +61,9 @@ add_library(quickstep_types_VarCharType VarCharType.cpp 
VarCharType.hpp)
 add_library(quickstep_types_YearMonthIntervalType YearMonthIntervalType.cpp 
YearMonthIntervalType.hpp)
 
 # Link dependencies:
+target_link_libraries(quickstep_types_AsciiStringSuperType
+                      quickstep_types_Type
+                      quickstep_types_TypeID)
 target_link_libraries(quickstep_types_CharType
                       glog
                       quickstep_types_NullCoercibilityCheckMacro
@@ -78,7 +82,6 @@ target_link_libraries(quickstep_types_DateOperatorOverloads
 target_link_libraries(quickstep_types_DateType
                       glog
                       quickstep_types_DatetimeLit
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
@@ -88,7 +91,6 @@ target_link_libraries(quickstep_types_DatetimeIntervalType
                       glog
                       quickstep_types_IntervalLit
                       quickstep_types_IntervalParser
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
@@ -99,7 +101,6 @@ target_link_libraries(quickstep_types_DatetimeLit
 target_link_libraries(quickstep_types_DatetimeType
                       glog
                       quickstep_types_DatetimeLit
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
@@ -146,9 +147,6 @@ target_link_libraries(quickstep_types_LongType
                       quickstep_types_TypedValue
                       quickstep_utility_EqualsAnyConstant
                       quickstep_utility_Macros)
-target_link_libraries(quickstep_types_NullCoercibilityCheckMacro
-                      quickstep_types_Type
-                      quickstep_types_TypeID)
 target_link_libraries(quickstep_types_NullType
                       glog
                       quickstep_types_Type
@@ -232,7 +230,6 @@ target_link_libraries(quickstep_types_VarCharType
 target_link_libraries(quickstep_types_YearMonthIntervalType
                       quickstep_types_IntervalLit
                       quickstep_types_IntervalParser
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
@@ -242,6 +239,7 @@ target_link_libraries(quickstep_types_YearMonthIntervalType
 # Module all-in-one library:
 add_library(quickstep_types ../empty_src.cpp TypesModule.hpp)
 target_link_libraries(quickstep_types
+                      quickstep_types_AsciiStringSuperType
                       quickstep_types_CharType
                       quickstep_types_DateOperatorOverloads
                       quickstep_types_DateType

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/CharType.cpp
----------------------------------------------------------------------
diff --git a/types/CharType.cpp b/types/CharType.cpp
index bc05711..c92d33e 100644
--- a/types/CharType.cpp
+++ b/types/CharType.cpp
@@ -60,19 +60,6 @@ const CharType& CharType::InstanceNullable(const std::size_t 
length) {
   return InstanceInternal<true>(length);
 }
 
-const CharType& CharType::InstanceFromProto(const serialization::Type &proto) {
-  return Instance(proto.GetExtension(serialization::CharType::length), 
proto.nullable());
-}
-
-serialization::Type CharType::getProto() const {
-  serialization::Type proto;
-  proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
-  proto.set_nullable(nullable_);
-
-  proto.SetExtension(serialization::CharType::length, length_);
-  return proto;
-}
-
 bool CharType::isSafelyCoercibleFrom(const Type &original_type) const {
   QUICKSTEP_NULL_COERCIBILITY_CHECK();
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/CharType.hpp
----------------------------------------------------------------------
diff --git a/types/CharType.hpp b/types/CharType.hpp
index e591953..fab0f61 100644
--- a/types/CharType.hpp
+++ b/types/CharType.hpp
@@ -24,8 +24,8 @@
 #include <cstdio>
 #include <string>
 
+#include "types/AsciiStringSuperType.hpp"
 #include "types/Type.hpp"
-#include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
 #include "utility/Macros.hpp"
@@ -43,7 +43,7 @@ namespace quickstep {
  *       represented WITHOUT a null-terminator character. Any strings shorter
  *       than the maximum length will have a null-terminator.
  **/
-class CharType : public AsciiStringSuperType<kChar, kNonNativeInline> {
+class CharType : public AsciiStringSuperType<CharType, kChar, 
kNonNativeInline> {
  public:
   /**
    * @brief Get a reference to the non-nullable singleton instance of this Type
@@ -82,32 +82,6 @@ class CharType : public AsciiStringSuperType<kChar, 
kNonNativeInline> {
     }
   }
 
-  /**
-   * @brief Get a reference to the singleton instance of this Type described
-   *        by the given Protocol Buffer serialization.
-   *
-   * @param proto The serialized Protocol Buffer representation of the desired
-   *        CharType.
-   * @return A reference to the singleton instance of this Type for the given
-   *         Protocol Buffer.
-   **/
-  static const CharType& InstanceFromProto(const serialization::Type &proto);
-
-  /**
-   * @brief Generate a serialized Protocol Buffer representation of this Type.
-   *
-   * @return The serialized Protocol Buffer representation of this Type.
-   **/
-  serialization::Type getProto() const override;
-
-  const Type& getNullableVersion() const override {
-    return InstanceNullable(length_);
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable(length_);
-  }
-
   std::size_t estimateAverageByteLength() const override {
     return length_;
   }
@@ -134,7 +108,8 @@ class CharType : public AsciiStringSuperType<kChar, 
kNonNativeInline> {
 
  private:
   CharType(const std::size_t length, const bool nullable)
-      : AsciiStringSuperType<kChar, kNonNativeInline>(nullable, length, 
length, length) {
+      : AsciiStringSuperType<CharType, kChar, kNonNativeInline>(
+            nullable, length, length, length) {
   }
 
   template <bool nullable_internal>

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/DateType.cpp
----------------------------------------------------------------------
diff --git a/types/DateType.cpp b/types/DateType.cpp
index 5bb982c..de1e554 100644
--- a/types/DateType.cpp
+++ b/types/DateType.cpp
@@ -30,7 +30,6 @@
 #include <string>
 
 #include "types/DatetimeLit.hpp"
-#include "types/NullCoercibilityCheckMacro.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
@@ -46,16 +45,6 @@ using std::snprintf;
 
 namespace quickstep {
 
-bool DateType::isCoercibleFrom(const Type &original_type) const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kDate);
-}
-
-bool DateType::isSafelyCoercibleFrom(const Type &original_type) const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kDate);
-}
-
 std::string DateType::printValueToString(const TypedValue &value) const {
   DCHECK(!value.isNull());
 
@@ -86,14 +75,6 @@ std::string DateType::printValueToString(const TypedValue 
&value) const {
   return std::string(datebuf);
 }
 
-void DateType::printValueToFile(const TypedValue &value,
-                                FILE *file,
-                                const int padding) const {
-  // We simply re-use the logic from printValueToString(), as trying to do
-  // padding on-the fly with so many different fields is too much of a hassle.
-  std::fprintf(file, "%*s", padding, printValueToString(value).c_str());
-}
-
 bool DateType::parseValueFromString(const std::string &value_string,
                                     TypedValue *value) const {
   std::int32_t year;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/DateType.hpp
----------------------------------------------------------------------
diff --git a/types/DateType.hpp b/types/DateType.hpp
index a39a28c..11e9908 100644
--- a/types/DateType.hpp
+++ b/types/DateType.hpp
@@ -40,7 +40,7 @@ class TypedValue;
 /**
  * @brief A type representing the date.
  **/
-class DateType : public TypeConcept<kDate, false, kNativeEmbedded, DateLit> {
+class DateType : public TypeSynthesizer<DateType, kDate, false, 
kNativeEmbedded, DateLit> {
  public:
   /**
    * @brief Get a reference to the non-nullable singleton instance of this
@@ -77,32 +77,16 @@ class DateType : public TypeConcept<kDate, false, 
kNativeEmbedded, DateLit> {
     }
   }
 
-  const Type& getNullableVersion() const override {
-    return InstanceNullable();
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable();
-  }
-
   std::size_t estimateAverageByteLength() const override {
     return sizeof(DateLit);
   }
 
-  bool isCoercibleFrom(const Type &original_type) const override;
-
-  bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
   int getPrintWidth() const override {
     return DateLit::kIsoChars;
   }
 
   std::string printValueToString(const TypedValue &value) const override;
 
-  void printValueToFile(const TypedValue &value,
-                        FILE *file,
-                        const int padding = 0) const override;
-
   /**
    * @note value_string is expected to be in (possibly extended) ISO-8601
    *       format. Extended ISO-8601 date format is "YYYY-MM-DD". YYYY is an
@@ -120,7 +104,7 @@ class DateType : public TypeConcept<kDate, false, 
kNativeEmbedded, DateLit> {
 
  private:
   explicit DateType(const bool nullable)
-      : TypeConcept<kDate, false, kNativeEmbedded, DateLit>(
+      : TypeSynthesizer<DateType, kDate, false, kNativeEmbedded, DateLit>(
              Type::kOther, kStaticTypeID, nullable,
              sizeof(DateLit), sizeof(DateLit)) {
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/DatetimeIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.cpp b/types/DatetimeIntervalType.cpp
index 1eae03a..2c77f89 100644
--- a/types/DatetimeIntervalType.cpp
+++ b/types/DatetimeIntervalType.cpp
@@ -31,7 +31,6 @@
 
 #include "types/IntervalLit.hpp"
 #include "types/IntervalParser.hpp"
-#include "types/NullCoercibilityCheckMacro.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
@@ -47,16 +46,6 @@ using std::snprintf;
 
 namespace quickstep {
 
-bool DatetimeIntervalType::isCoercibleFrom(const Type &original_type) const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kDatetimeInterval);
-}
-
-bool DatetimeIntervalType::isSafelyCoercibleFrom(const Type &original_type) 
const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kDatetimeInterval);
-}
-
 std::string DatetimeIntervalType::printValueToString(const TypedValue &value) 
const {
   DCHECK(!value.isNull());
 
@@ -121,14 +110,6 @@ std::string DatetimeIntervalType::printValueToString(const 
TypedValue &value) co
   return std::string(interval_buf);
 }
 
-void DatetimeIntervalType::printValueToFile(const TypedValue &value,
-                                            FILE *file,
-                                            const int padding) const {
-  // We simply re-use the logic from printValueToString(), as trying to do
-  // padding on-the fly with so many different fields is too much of a hassle.
-  std::fprintf(file, "%*s", padding, printValueToString(value).c_str());
-}
-
 bool DatetimeIntervalType::parseValueFromString(const std::string 
&value_string,
                                                 TypedValue *value) const {
   // Try simple-format parse first.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/DatetimeIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp
index 3b22471..ba05dce 100644
--- a/types/DatetimeIntervalType.hpp
+++ b/types/DatetimeIntervalType.hpp
@@ -41,7 +41,8 @@ namespace quickstep {
  * @brief A type representing the datetime interval.
  **/
 class DatetimeIntervalType :
-    public TypeConcept<kDatetimeInterval, false, kNativeEmbedded, 
DatetimeIntervalLit> {
+    public TypeSynthesizer<DatetimeIntervalType, kDatetimeInterval,
+                           false, kNativeEmbedded, DatetimeIntervalLit> {
  public:
   /**
    * @brief Get a reference to the non-nullable singleton instance of this
@@ -78,32 +79,16 @@ class DatetimeIntervalType :
     }
   }
 
-  const Type& getNullableVersion() const override {
-    return InstanceNullable();
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable();
-  }
-
   std::size_t estimateAverageByteLength() const override {
     return sizeof(DatetimeIntervalLit);
   }
 
-  bool isCoercibleFrom(const Type &original_type) const override;
-
-  bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
   int getPrintWidth() const override {
     return DatetimeIntervalLit::kPrintingChars;
   }
 
   std::string printValueToString(const TypedValue &value) const override;
 
-  void printValueToFile(const TypedValue &value,
-                        FILE *file,
-                        const int padding = 0) const override;
-
   TypedValue makeZeroValue() const override {
     return TypedValue(DatetimeIntervalLit{0});
   }
@@ -113,7 +98,8 @@ class DatetimeIntervalType :
 
  private:
   explicit DatetimeIntervalType(const bool nullable)
-      : TypeConcept<kDatetimeInterval, false, kNativeEmbedded, 
DatetimeIntervalLit>(
+      : TypeSynthesizer<DatetimeIntervalType, kDatetimeInterval,
+                        false, kNativeEmbedded, DatetimeIntervalLit>(
              Type::kOther, kStaticTypeID, nullable,
              sizeof(DatetimeIntervalLit), sizeof(DatetimeIntervalLit)) {
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/DatetimeType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.cpp b/types/DatetimeType.cpp
index f54f318..723da61 100644
--- a/types/DatetimeType.cpp
+++ b/types/DatetimeType.cpp
@@ -33,7 +33,6 @@
 #include <string>
 
 #include "types/DatetimeLit.hpp"
-#include "types/NullCoercibilityCheckMacro.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
@@ -51,16 +50,6 @@ using std::snprintf;
 
 namespace quickstep {
 
-bool DatetimeType::isCoercibleFrom(const Type &original_type) const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kDatetime);
-}
-
-bool DatetimeType::isSafelyCoercibleFrom(const Type &original_type) const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kDatetime);
-}
-
 std::string DatetimeType::printValueToString(const TypedValue &value) const {
   DCHECK(!value.isNull());
 
@@ -114,14 +103,6 @@ std::string DatetimeType::printValueToString(const 
TypedValue &value) const {
   return std::string(datebuf);
 }
 
-void DatetimeType::printValueToFile(const TypedValue &value,
-                                    FILE *file,
-                                    const int padding) const {
-  // We simply re-use the logic from printValueToString(), as trying to do
-  // padding on-the fly with so many different fields is too much of a hassle.
-  std::fprintf(file, "%*s", padding, printValueToString(value).c_str());
-}
-
 bool DatetimeType::parseValueFromString(const std::string &value_string,
                                         TypedValue *value) const {
   int year;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/DatetimeType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp
index b6742f9..2189d22 100644
--- a/types/DatetimeType.hpp
+++ b/types/DatetimeType.hpp
@@ -40,7 +40,8 @@ class TypedValue;
 /**
  * @brief A type representing the datetime.
  **/
-class DatetimeType : public TypeConcept<kDatetime, false, kNativeEmbedded, 
DatetimeLit> {
+class DatetimeType
+    : public TypeSynthesizer<DatetimeType, kDatetime, false, kNativeEmbedded, 
DatetimeLit> {
  public:
   /**
    * @brief Get a reference to the non-nullable singleton instance of this
@@ -77,32 +78,16 @@ class DatetimeType : public TypeConcept<kDatetime, false, 
kNativeEmbedded, Datet
     }
   }
 
-  const Type& getNullableVersion() const override {
-    return InstanceNullable();
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable();
-  }
-
   std::size_t estimateAverageByteLength() const override {
     return sizeof(DatetimeLit);
   }
 
-  bool isCoercibleFrom(const Type &original_type) const override;
-
-  bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
   int getPrintWidth() const override {
     return DatetimeLit::kIsoChars;
   }
 
   std::string printValueToString(const TypedValue &value) const override;
 
-  void printValueToFile(const TypedValue &value,
-                        FILE *file,
-                        const int padding = 0) const override;
-
   /**
    * @note value_string is expected to be in (possibly extended) ISO-8601
    *       format. Extended ISO-8601 format is one of the following:
@@ -128,7 +113,7 @@ class DatetimeType : public TypeConcept<kDatetime, false, 
kNativeEmbedded, Datet
 
  private:
   explicit DatetimeType(const bool nullable)
-      : TypeConcept<kDatetime, false, kNativeEmbedded, quickstep::DatetimeLit>(
+      : TypeSynthesizer<DatetimeType, kDatetime, false, kNativeEmbedded, 
DatetimeLit>(
              Type::kOther, kStaticTypeID, nullable,
              sizeof(DatetimeLit), sizeof(DatetimeLit)) {
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/DoubleType.hpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp
index 4d1dd7e..e8bb97a 100644
--- a/types/DoubleType.hpp
+++ b/types/DoubleType.hpp
@@ -40,7 +40,7 @@ class Type;
 /**
  * @brief A type representing a double-precision floating-point number.
  **/
-class DoubleType : public NumericSuperType<kDouble, double> {
+class DoubleType : public NumericSuperType<DoubleType, kDouble, double> {
  public:
   /**
    * @brief Get a reference to the non-nullable singleton instance of this
@@ -77,14 +77,6 @@ class DoubleType : public NumericSuperType<kDouble, double> {
     }
   }
 
-  const Type& getNullableVersion() const override {
-    return InstanceNullable();
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable();
-  }
-
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 
   int getPrintWidth() const override {
@@ -120,7 +112,7 @@ class DoubleType : public NumericSuperType<kDouble, double> 
{
               // exponent never takes more than 3 base-10 digits to represent.
 
   explicit DoubleType(const bool nullable)
-      : NumericSuperType<kDouble, double>(nullable) {
+      : NumericSuperType<DoubleType, kDouble, double>(nullable) {
   }
 
   DISALLOW_COPY_AND_ASSIGN(DoubleType);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/FloatType.hpp
----------------------------------------------------------------------
diff --git a/types/FloatType.hpp b/types/FloatType.hpp
index ee9c45c..c1428b0 100644
--- a/types/FloatType.hpp
+++ b/types/FloatType.hpp
@@ -40,7 +40,7 @@ class Type;
 /**
  * @brief A type representing a single-precision floating-point number.
  **/
-class FloatType : public NumericSuperType<kFloat, float> {
+class FloatType : public NumericSuperType<FloatType, kFloat, float> {
  public:
   /**
    * @brief Get a reference to the non-nullable singleton instance of this
@@ -77,14 +77,6 @@ class FloatType : public NumericSuperType<kFloat, float> {
     }
   }
 
-  const Type& getNullableVersion() const override {
-    return InstanceNullable();
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable();
-  }
-
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 
   int getPrintWidth() const override {
@@ -120,7 +112,7 @@ class FloatType : public NumericSuperType<kFloat, float> {
               // never takes more than 2 base-10 digits to represent.
 
   explicit FloatType(const bool nullable)
-      : NumericSuperType<kFloat, float>(nullable) {
+      : NumericSuperType<FloatType, kFloat, float>(nullable) {
   }
 
   DISALLOW_COPY_AND_ASSIGN(FloatType);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/IntType.hpp
----------------------------------------------------------------------
diff --git a/types/IntType.hpp b/types/IntType.hpp
index 25ce3c8..dda89bb 100644
--- a/types/IntType.hpp
+++ b/types/IntType.hpp
@@ -40,7 +40,7 @@ class Type;
 /**
  * @brief A type representing a 32-bit integer.
  **/
-class IntType : public NumericSuperType<kInt, int> {
+class IntType : public NumericSuperType<IntType, kInt, int> {
  public:
   /**
    * @brief Get a reference to the non-nullable singleton instance of this
@@ -77,14 +77,6 @@ class IntType : public NumericSuperType<kInt, int> {
     }
   }
 
-  const Type& getNullableVersion() const override {
-    return InstanceNullable();
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable();
-  }
-
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 
   int getPrintWidth() const override {
@@ -107,7 +99,7 @@ class IntType : public NumericSuperType<kInt, int> {
 
  private:
   explicit IntType(const bool nullable)
-      : NumericSuperType<kInt, int>(nullable) {
+      : NumericSuperType<IntType, kInt, int>(nullable) {
   }
 
   DISALLOW_COPY_AND_ASSIGN(IntType);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/LongType.hpp
----------------------------------------------------------------------
diff --git a/types/LongType.hpp b/types/LongType.hpp
index 52244a7..f2814bf 100644
--- a/types/LongType.hpp
+++ b/types/LongType.hpp
@@ -41,7 +41,7 @@ class Type;
 /**
  * @brief A type representing a 64-bit integer.
  **/
-class LongType : public NumericSuperType<kLong, std::int64_t> {
+class LongType : public NumericSuperType<LongType, kLong, std::int64_t> {
  public:
   /**
    * @brief Get a reference to the non-nullable singleton instance of this
@@ -78,14 +78,6 @@ class LongType : public NumericSuperType<kLong, 
std::int64_t> {
     }
   }
 
-  const Type& getNullableVersion() const override {
-    return InstanceNullable();
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable();
-  }
-
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 
   // Fully represented digits, single leading digit, and possible '-'
@@ -108,7 +100,7 @@ class LongType : public NumericSuperType<kLong, 
std::int64_t> {
 
  private:
   explicit LongType(const bool nullable)
-      : NumericSuperType<kLong, std::int64_t>(nullable) {
+      : NumericSuperType<LongType, kLong, std::int64_t>(nullable) {
   }
 
   DISALLOW_COPY_AND_ASSIGN(LongType);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/NullType.hpp
----------------------------------------------------------------------
diff --git a/types/NullType.hpp b/types/NullType.hpp
index 6c6dd06..0b9381c 100644
--- a/types/NullType.hpp
+++ b/types/NullType.hpp
@@ -48,7 +48,7 @@ class TypedValue;
  *       a particular operation may accept. It is also assumed that applying
  *       any operation to an argument of NullType always yields NULL values.
  **/
-class NullType : public TypeConcept<kNullType, false, kNativeEmbedded> {
+class NullType : public TypeSynthesizer<NullType, kNullType, false, 
kNativeEmbedded> {
  public:
   /**
    * @brief Get a reference to the nullable singleton instance of this Type.
@@ -62,12 +62,13 @@ class NullType : public TypeConcept<kNullType, false, 
kNativeEmbedded> {
     return instance;
   }
 
-  const Type& getNullableVersion() const override {
-    return InstanceNullable();
-  }
-
-  const Type& getNonNullableVersion() const override {
-    LOG(FATAL) << "Called NullType::getNonNullableVersion(), which is not 
allowed.";
+  static const NullType& Instance(const bool nullable) {
+    if (nullable) {
+      return InstanceNullable();
+    } else {
+      LOG(FATAL) << "Called NullType::Instance(nullable = true), "
+                 << "which is not allowed.";
+    }
   }
 
   std::size_t estimateAverageByteLength() const override {
@@ -105,7 +106,7 @@ class NullType : public TypeConcept<kNullType, false, 
kNativeEmbedded> {
   // NOTE(chasseur): NullType requires 0 bytes of inherent storage. It does,
   // however, require a bit in NULL bitmaps.
   NullType()
-      : TypeConcept<kNullType, false, kNativeEmbedded>(
+      : TypeSynthesizer<NullType, kNullType, false, kNativeEmbedded>(
             Type::kOther, kStaticTypeID, true, 0, 0) {
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index 77f028a..a3f1808 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -38,8 +38,9 @@ namespace quickstep {
  * @brief Templatized superclass for Numeric types. Contains code common to all
  *        Numeric types.
  **/
-template <TypeID type_id, typename CppType>
-class NumericSuperType : public TypeConcept<type_id, false, kNativeEmbedded, 
CppType> {
+template <typename TypeClass, TypeID type_id, typename CppType>
+class NumericSuperType
+    : public TypeSynthesizer<TypeClass, type_id, false, kNativeEmbedded, 
CppType> {
  public:
   std::size_t estimateAverageByteLength() const override {
     return sizeof(CppType);
@@ -56,7 +57,7 @@ class NumericSuperType : public TypeConcept<type_id, false, 
kNativeEmbedded, Cpp
 
  protected:
   explicit NumericSuperType(const bool nullable)
-      : TypeConcept<type_id, false, kNativeEmbedded, CppType>(
+      : TypeSynthesizer<TypeClass, type_id, false, kNativeEmbedded, CppType>(
             Type::kNumeric, type_id, nullable, sizeof(CppType), 
sizeof(CppType)) {
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index 144f39a..af6503b 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -28,12 +28,24 @@
 
 namespace quickstep {
 
-serialization::Type Type::getProto() const {
-  serialization::Type proto;
-  proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
-  proto.set_nullable(nullable_);
+bool Type::isCoercibleFrom(const Type &original_type) const {
+  return isSafelyCoercibleFrom(original_type);
+}
+
+bool Type::isSafelyCoercibleFrom(const Type &original_type) const {
+  if (original_type.isNullable() && !this->nullable_) {
+    return false;
+  }
+  if (original_type.getTypeID() == kNullType) {
+    return true;
+  }
+  return (original_type.getTypeID() == type_id_);
+}
 
-  return proto;
+void Type::printValueToFile(const TypedValue &value,
+                            FILE *file,
+                            const int padding) const {
+  std::fprintf(file, "%*s", padding, printValueToString(value).c_str());
 }
 
 TypedValue Type::coerceValue(const TypedValue &original_value,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index 066b2b5..e293766 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -24,6 +24,7 @@
 #include <cstdint>
 #include <cstdio>
 #include <string>
+#include <type_traits>
 
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
@@ -112,7 +113,7 @@ class Type {
    *
    * @return The serialized Protocol Buffer representation of this Type.
    **/
-  virtual serialization::Type getProto() const;
+  virtual serialization::Type getProto() const = 0;
 
   /**
    * @brief Determine what supertype this type belongs to.
@@ -154,16 +155,7 @@ class Type {
     TypeSignature sig;
     sig.id = type_id_;
     sig.nullable = nullable_;
-    switch (type_id_) {
-      case kChar:
-        sig.length = maximum_byte_length_;
-        break;
-      case kVarChar:
-        sig.length = maximum_byte_length_ - 1;
-        break;
-      default:
-        sig.length = 0;
-    }
+    sig.length = parameter_;
     return sig;
   }
 
@@ -255,7 +247,7 @@ class Type {
    * @param original_type The original Type for coercion to this Type.
    * @return true if coercion is supported, false otherwise.
    **/
-  virtual bool isCoercibleFrom(const Type &original_type) const = 0;
+  virtual bool isCoercibleFrom(const Type &original_type) const;
 
   /**
    * @brief Determine whether data items of another type can be coerced (used
@@ -277,7 +269,7 @@ class Type {
    * @param original_type The original Type for coercion to this Type.
    * @return true if coercion is supported, false otherwise.
    **/
-  virtual bool isSafelyCoercibleFrom(const Type &original_type) const = 0;
+  virtual bool isSafelyCoercibleFrom(const Type &original_type) const;
 
   /**
    * @brief Determine whether data items of this type are always guaranteed to
@@ -348,7 +340,7 @@ class Type {
    **/
   virtual void printValueToFile(const TypedValue &value,
                                 FILE *file,
-                                const int padding = 0) const = 0;
+                                const int padding = 0) const;
 
   /**
    * @brief Make a TypedValue of this Type.
@@ -453,10 +445,12 @@ class Type {
        const TypeID type_id,
        const bool nullable,
        const std::size_t minimum_byte_length,
-       const std::size_t maximum_byte_length)
+       const std::size_t maximum_byte_length,
+       const std::size_t parameter = 0)
       : super_type_id_(super_type_id),
         type_id_(type_id),
         nullable_(nullable),
+        parameter_(parameter),
         minimum_byte_length_(minimum_byte_length),
         maximum_byte_length_(maximum_byte_length) {
   }
@@ -464,6 +458,7 @@ class Type {
   const SuperTypeID super_type_id_;
   const TypeID type_id_;
   const bool nullable_;
+  const std::size_t parameter_;
   const std::size_t minimum_byte_length_;
   const std::size_t maximum_byte_length_;
 
@@ -471,11 +466,10 @@ class Type {
   DISALLOW_COPY_AND_ASSIGN(Type);
 };
 
-template <TypeID type_id,
-          bool parameterized,
-          TypeStorageLayout layout,
+template <typename TypeClass, TypeID type_id,
+          bool parameterized, TypeStorageLayout layout,
           typename CppType = void>
-class TypeConcept : public Type {
+class TypeSynthesizer : public Type {
  public:
   static constexpr TypeID kStaticTypeID = type_id;
   static constexpr bool kParameterized = parameterized;
@@ -483,73 +477,63 @@ class TypeConcept : public Type {
 
   typedef CppType cpptype;
 
- protected:
-  template <typename ...ArgTypes>
-  explicit TypeConcept(ArgTypes &&...args)
-      : Type(std::forward<ArgTypes>(args)...) {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TypeConcept);
-};
+  serialization::Type getProto() const override {
+    serialization::Type proto;
 
+    proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
+    proto.set_nullable(nullable_);
 
-template <TypeID type_id,
-          bool parameterized,
-          TypeStorageLayout layout,
-          typename CppType>
-constexpr TypeID TypeConcept<type_id, parameterized, layout, 
CppType>::kStaticTypeID;
-
-template <TypeID type_id,
-          bool parameterized,
-          TypeStorageLayout layout,
-          typename CppType>
-constexpr bool TypeConcept<type_id, parameterized, layout, 
CppType>::kParameterized;
+    if (kParameterized) {
+      proto.set_length(parameter_);
+    }
 
-template <TypeID type_id,
-          bool parameterized,
-          TypeStorageLayout layout,
-          typename CppType>
-constexpr TypeStorageLayout TypeConcept<type_id, parameterized, layout, 
CppType>::kLayout;
+    return proto;
+  }
 
-/**
- * @brief A superclass for ASCII string types.
- **/
-template <TypeID type_id, TypeStorageLayout layout>
-class AsciiStringSuperType : public TypeConcept<type_id, true, layout> {
- public:
-  bool isCoercibleFrom(const Type &original_type) const override {
-    if (original_type.isNullable() && !this->nullable_) {
-      return false;
-    }
-    return (original_type.getSuperTypeID() == Type::kAsciiString)
-           || (original_type.getTypeID() == kNullType);
+  const Type& getNullableVersion() const override {
+    return getInstance<kParameterized>(true);
   }
 
-  /**
-   * @brief Get the character-length of this string type.
-   *
-   * @return The maximum length of a string of this type.
-   **/
-  inline std::size_t getStringLength() const {
-    return length_;
+  const Type& getNonNullableVersion() const override {
+    return getInstance<kParameterized>(false);
   }
 
  protected:
-  AsciiStringSuperType(const bool nullable,
-                       const std::size_t minimum_byte_length,
-                       const std::size_t maximum_byte_length,
-                       const std::size_t string_length)
-      : TypeConcept<type_id, true, layout>(
-            Type::kAsciiString, type_id, nullable, minimum_byte_length, 
maximum_byte_length),
-        length_(string_length) {
+  template <typename ...ArgTypes>
+  explicit TypeSynthesizer(ArgTypes &&...args)
+      : Type(std::forward<ArgTypes>(args)...) {}
+
+ private:
+  template <bool has_param>
+  inline const Type& getInstance(const bool nullable,
+                                 std::enable_if_t<has_param>* = 0) const {
+    return TypeClass::Instance(parameter_, nullable);
   }
 
-  const std::size_t length_;
+  template <bool has_param>
+  inline const Type& getInstance(const bool nullable,
+                                 std::enable_if_t<!has_param>* = 0) const {
+    return TypeClass::Instance(nullable);
+  }
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(AsciiStringSuperType);
+  DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
 };
 
+template <typename TypeClass, TypeID type_id,
+          bool parameterized, TypeStorageLayout layout, typename CppType>
+constexpr TypeID TypeSynthesizer<
+    TypeClass, type_id, parameterized, layout, CppType>::kStaticTypeID;
+
+template <typename TypeClass, TypeID type_id,
+          bool parameterized, TypeStorageLayout layout, typename CppType>
+constexpr bool TypeSynthesizer<
+    TypeClass, type_id, parameterized, layout, CppType>::kParameterized;
+
+template <typename TypeClass, TypeID type_id,
+          bool parameterized, TypeStorageLayout layout, typename CppType>
+constexpr TypeStorageLayout TypeSynthesizer<
+    TypeClass, type_id, parameterized, layout, CppType>::kLayout;
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/Type.proto
----------------------------------------------------------------------
diff --git a/types/Type.proto b/types/Type.proto
index d454923..ed8df36 100644
--- a/types/Type.proto
+++ b/types/Type.proto
@@ -26,22 +26,6 @@ message TypeID {
 message Type {
   required TypeID type_id = 1;
   required bool nullable = 2;
-
-  // The convention for extension numbering is that extensions for a particular
-  // TypeID should begin from (type_id + 1) * 32.
-  extensions 32 to max;
-}
-
-message CharType {
-  extend Type {
-    // Required when type_id == CHAR.
-    optional uint64 length = 160;
-  }
+  optional uint64 length = 3;
 }
 
-message VarCharType {
-  extend Type {
-    // Required when type_id == VAR_CHAR.
-    optional uint64 length = 192;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index df21d50..4a24cc6 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -34,6 +34,7 @@
 #include "types/Type.hpp"
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
+#include "types/TypeUtil.hpp"
 #include "types/VarCharType.hpp"
 #include "types/YearMonthIntervalType.hpp"
 #include "utility/Macros.hpp"
@@ -42,46 +43,35 @@
 
 namespace quickstep {
 
+bool TypeFactory::TypeRequiresLengthParameter(const TypeID id) {
+  return TypeUtil::IsParameterized(id);
+}
+
 const Type& TypeFactory::GetType(const TypeID id,
                                  const bool nullable) {
-  switch (id) {
-    case kInt:
-      return IntType::Instance(nullable);
-    case kLong:
-      return LongType::Instance(nullable);
-    case kFloat:
-      return FloatType::Instance(nullable);
-    case kDouble:
-      return DoubleType::Instance(nullable);
-    case kDate:
-      return DateType::Instance(nullable);
-    case kDatetime:
-      return DatetimeType::Instance(nullable);
-    case kDatetimeInterval:
-      return DatetimeIntervalType::Instance(nullable);
-    case kYearMonthInterval:
-      return YearMonthIntervalType::Instance(nullable);
-    case kNullType:
-      DCHECK(nullable);
-      return NullType::InstanceNullable();
-    default:
-      FATAL_ERROR("Called TypeFactory::GetType() for a type which requires "
-                  " a length parameter without specifying one.");
-  }
+  DCHECK(!TypeRequiresLengthParameter(id))
+      << "Called TypeFactory::GetType() for a type which requires "
+      << " a length parameter without specifying one.";
+
+  return *InvokeOnTypeID<TypeIDSelectorNonParameterized>(
+      id,
+      [&](auto id) -> const Type* {  // NOLINT(build/c++11)
+    return &TypeClass<decltype(id)::value>::type::Instance(nullable);
+  });
 }
 
 const Type& TypeFactory::GetType(const TypeID id,
                                  const std::size_t length,
                                  const bool nullable) {
-  switch (id) {
-    case kChar:
-      return CharType::Instance(length, nullable);
-    case kVarChar:
-      return VarCharType::Instance(length, nullable);
-    default:
-      FATAL_ERROR("Provided a length parameter to TypeFactory::GetType() for "
-                  "a type which does not take one.");
-  }
+  DCHECK(TypeRequiresLengthParameter(id))
+      << "Provided a length parameter to TypeFactory::GetType() for "
+      << "a type which does not take one.";
+
+  return *InvokeOnTypeID<TypeIDSelectorParameterized>(
+      id,
+      [&](auto id) -> const Type* {  // NOLINT(build/c++11)
+    return &TypeClass<decltype(id)::value>::type::Instance(nullable, length);
+  });
 }
 
 bool TypeFactory::ProtoIsValid(const serialization::Type &proto) {
@@ -90,27 +80,18 @@ bool TypeFactory::ProtoIsValid(const serialization::Type 
&proto) {
     return false;
   }
 
-  // Check that the type_id is valid, and extensions if any.
+  // Check that the type_id is valid, and has length if parameterized.
   const TypeID type_id = TypeIDFactory::ReconstructFromProto(proto.type_id());
-  switch (type_id) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-    case kDate:
-    case kDatetime:
-    case kDatetimeInterval:
-    case kYearMonthInterval:
-      return true;
-    case kChar:
-      return proto.HasExtension(serialization::CharType::length);
-    case kVarChar:
-      return proto.HasExtension(serialization::VarCharType::length);
-    case kNullType:
-      return proto.nullable();
-    default:
-      return false;
+
+  if (type_id == kNullType) {
+    return proto.nullable();
+  }
+
+  if (TypeRequiresLengthParameter(type_id)) {
+    return proto.has_length();
   }
+
+  return true;
 }
 
 const Type& TypeFactory::ReconstructFromProto(const serialization::Type 
&proto) {
@@ -119,32 +100,11 @@ const Type& TypeFactory::ReconstructFromProto(const 
serialization::Type &proto)
       << proto.DebugString();
 
   const TypeID type_id = TypeIDFactory::ReconstructFromProto(proto.type_id());
-  switch (type_id) {
-    case kInt:
-      return IntType::Instance(proto.nullable());
-    case kLong:
-      return LongType::Instance(proto.nullable());
-    case kFloat:
-      return FloatType::Instance(proto.nullable());
-    case kDouble:
-      return DoubleType::Instance(proto.nullable());
-    case kDate:
-      return DateType::Instance(proto.nullable());
-    case kDatetime:
-      return DatetimeType::Instance(proto.nullable());
-    case kDatetimeInterval:
-      return DatetimeIntervalType::Instance(proto.nullable());
-    case kYearMonthInterval:
-      return YearMonthIntervalType::Instance(proto.nullable());
-    case kChar:
-      return CharType::InstanceFromProto(proto);
-    case kVarChar:
-      return VarCharType::InstanceFromProto(proto);
-    case kNullType:
-      DCHECK(proto.nullable());
-      return NullType::InstanceNullable();
-    default:
-      FATAL_ERROR("Unrecognized TypeID in TypeFactory::ReconstructFromProto");
+
+  if (TypeRequiresLengthParameter(type_id)) {
+    return GetType(type_id, proto.length(), proto.nullable());
+  } else {
+    return GetType(type_id, proto.nullable());
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/TypeFactory.hpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.hpp b/types/TypeFactory.hpp
index 742348e..89ff497 100644
--- a/types/TypeFactory.hpp
+++ b/types/TypeFactory.hpp
@@ -48,25 +48,7 @@ class TypeFactory {
    * @param id The id of the desired Type.
    * @return Whether a length must be specified for Types of the given id.
    **/
-  static bool TypeRequiresLengthParameter(const TypeID id) {
-    switch (id) {
-      case kInt:
-      case kLong:
-      case kFloat:
-      case kDouble:
-      case kDate:
-      case kDatetime:
-      case kDatetimeInterval:
-      case kYearMonthInterval:
-      case kNullType:
-        return false;
-      case kChar:
-      case kVarChar:
-        return true;
-      default:
-        FATAL_ERROR("Unrecognized TypeID in 
TypeFactory::TypeRequiresLengthParameter");
-    }
-  }
+  static bool TypeRequiresLengthParameter(const TypeID id);
 
   /**
    * @brief Factory method to get a Type by its TypeID.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/TypeID.hpp
----------------------------------------------------------------------
diff --git a/types/TypeID.hpp b/types/TypeID.hpp
index 26731b9..e5f023e 100644
--- a/types/TypeID.hpp
+++ b/types/TypeID.hpp
@@ -49,7 +49,7 @@ enum TypeID : int {
 };
 
 enum TypeStorageLayout {
-  kNativeEmbedded,
+  kNativeEmbedded = 0,
   kNativeInline,
   kNonNativeInline,
   kOutOfLine

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/TypeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/TypeUtil.hpp b/types/TypeUtil.hpp
index 6c58ef1..d2183e8 100644
--- a/types/TypeUtil.hpp
+++ b/types/TypeUtil.hpp
@@ -44,10 +44,10 @@
 namespace quickstep {
 
 template <TypeID type_id>
-struct TypeGenerator {};
+struct TypeClass {};
 
 #define REGISTER_TYPE(T) \
-  template <> struct TypeGenerator<T::kStaticTypeID> { typedef T type; };
+  template <> struct TypeClass<T::kStaticTypeID> { typedef T type; };
 
 REGISTER_TYPE(IntType);
 REGISTER_TYPE(LongType);
@@ -69,11 +69,14 @@ template <bool require_parameterized>
 struct TypeIDSelectorParameterizedHelper {
   template <typename TypeIDConstant, typename FunctorT, typename EnableT = 
void>
   struct Implementation {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wreturn-type"
     inline static auto Invoke(const FunctorT &functor)
         -> decltype(functor(TypeIDConstant())) {
-      DLOG(FATAL) << "Unexpected TypeID: "
-                  << kTypeNames[static_cast<int>(TypeIDConstant::value)];
+      LOG(FATAL) << "Unexpected TypeID: "
+                 << kTypeNames[static_cast<int>(TypeIDConstant::value)];
     }
+#pragma GCC diagnostic pop
   };
 };
 
@@ -81,7 +84,7 @@ template <bool require_non_parameterized>
 template <typename TypeIDConstant, typename FunctorT>
 struct 
TypeIDSelectorParameterizedHelper<require_non_parameterized>::Implementation<
     TypeIDConstant, FunctorT,
-    std::enable_if_t<TypeGenerator<TypeIDConstant::value>::type::kParameterized
+    std::enable_if_t<TypeClass<TypeIDConstant::value>::type::kParameterized
                          ^ require_non_parameterized>> {
   inline static auto Invoke(const FunctorT &functor) {
     return functor(TypeIDConstant());
@@ -109,11 +112,14 @@ template <TypeID ...candidates>
 struct TypeIDSelectorEqualsAny {
   template <typename TypeIDConstant, typename FunctorT, typename EnableT = 
void>
   struct Implementation {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wreturn-type"
     inline static auto Invoke(const FunctorT &functor)
         -> decltype(functor(TypeIDConstant())) {
-      DLOG(FATAL) << "Unexpected TypeID: "
-                  << kTypeNames[static_cast<int>(TypeIDConstant::value)];
+      LOG(FATAL) << "Unexpected TypeID: "
+                 << kTypeNames[static_cast<int>(TypeIDConstant::value)];
     }
+#pragma GCC diagnostic pop
   };
 };
 
@@ -150,7 +156,7 @@ inline auto InvokeOnTypeID(const TypeID type_id,
     REGISTER_TYPE_ID(kVarChar);
     REGISTER_TYPE_ID(kNullType);
     default:
-      FATAL_ERROR("Unrecognized TypeID in InvokeOnTypeID()");
+      LOG(FATAL) << "Unrecognized TypeID in InvokeOnTypeID()";
   }
 
 #undef REGISTER_TYPE_ID
@@ -162,7 +168,7 @@ class TypeUtil {
     return InvokeOnTypeID(
         type_id,
         [&](auto tid) -> bool {  // NOLINT(build/c++11)
-      return TypeGenerator<decltype(tid)::value>::type::kParameterized;
+      return TypeClass<decltype(tid)::value>::type::kParameterized;
     });
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/VarCharType.cpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.cpp b/types/VarCharType.cpp
index 05162cf..61fd88e 100644
--- a/types/VarCharType.cpp
+++ b/types/VarCharType.cpp
@@ -60,19 +60,6 @@ const VarCharType& VarCharType::InstanceNullable(const 
std::size_t length) {
   return InstanceInternal<true>(length);
 }
 
-const VarCharType& VarCharType::InstanceFromProto(const serialization::Type 
&proto) {
-  return Instance(proto.GetExtension(serialization::VarCharType::length), 
proto.nullable());
-}
-
-serialization::Type VarCharType::getProto() const {
-  serialization::Type proto;
-  proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
-  proto.set_nullable(nullable_);
-
-  proto.SetExtension(serialization::VarCharType::length, length_);
-  return proto;
-}
-
 size_t VarCharType::estimateAverageByteLength() const {
   if (length_ > 160) {
     return 80;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/VarCharType.hpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp
index af3ab64..5ca1bc1 100644
--- a/types/VarCharType.hpp
+++ b/types/VarCharType.hpp
@@ -24,8 +24,8 @@
 #include <cstdio>
 #include <string>
 
+#include "types/AsciiStringSuperType.hpp"
 #include "types/Type.hpp"
-#include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
 #include "utility/Macros.hpp"
@@ -43,7 +43,7 @@ namespace quickstep {
  *       character. This means that the VARCHAR(X) type requires from 1 to X+1
  *       bytes of storage, depending on string length.
  **/
-class VarCharType : public AsciiStringSuperType<kVarChar, kOutOfLine> {
+class VarCharType : public AsciiStringSuperType<VarCharType, kVarChar, 
kOutOfLine> {
  public:
   /**
    * @brief Get a reference to the non-nullable singleton instance of this Type
@@ -83,32 +83,6 @@ class VarCharType : public AsciiStringSuperType<kVarChar, 
kOutOfLine> {
   }
 
   /**
-   * @brief Get a reference to the singleton instance of this Type described
-   *        by the given Protocol Buffer serialization.
-   *
-   * @param type The serialized Protocol Buffer representation of the desired
-   *        VarCharType.
-   * @return A reference to the singleton instance of this Type for the given
-   *         Protocol Buffer.
-   **/
-  static const VarCharType& InstanceFromProto(const serialization::Type &type);
-
-  /**
-   * @brief Generate a serialized Protocol Buffer representation of this Type.
-   *
-   * @return The serialized Protocol Buffer representation of this Type.
-   **/
-  serialization::Type getProto() const override;
-
-  const Type& getNullableVersion() const override {
-    return InstanceNullable(length_);
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable(length_);
-  }
-
-  /**
    * @note Includes an extra byte for a terminating null character.
    **/
   std::size_t estimateAverageByteLength() const override;
@@ -137,7 +111,8 @@ class VarCharType : public AsciiStringSuperType<kVarChar, 
kOutOfLine> {
 
  private:
   VarCharType(const std::size_t length, const bool nullable)
-      : AsciiStringSuperType<kVarChar, kOutOfLine>(nullable, 1, length + 1, 
length) {
+      : AsciiStringSuperType<VarCharType, kVarChar, kOutOfLine>(
+            nullable, 1, length + 1, length) {
   }
 
   template <bool nullable_internal>

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/YearMonthIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.cpp b/types/YearMonthIntervalType.cpp
index 3c15a91..d656fca 100644
--- a/types/YearMonthIntervalType.cpp
+++ b/types/YearMonthIntervalType.cpp
@@ -30,7 +30,6 @@
 
 #include "types/IntervalLit.hpp"
 #include "types/IntervalParser.hpp"
-#include "types/NullCoercibilityCheckMacro.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
@@ -46,16 +45,6 @@ using std::snprintf;
 
 namespace quickstep {
 
-bool YearMonthIntervalType::isCoercibleFrom(const Type &original_type) const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kYearMonthInterval);
-}
-
-bool YearMonthIntervalType::isSafelyCoercibleFrom(const Type &original_type) 
const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kYearMonthInterval);
-}
-
 std::string YearMonthIntervalType::printValueToString(const TypedValue &value) 
const {
   DCHECK(!value.isNull());
 
@@ -127,14 +116,6 @@ std::string 
YearMonthIntervalType::printValueToString(const TypedValue &value) c
   return std::string(interval_buf);
 }
 
-void YearMonthIntervalType::printValueToFile(const TypedValue &value,
-                                             FILE *file,
-                                             const int padding) const {
-  // We simply re-use the logic from printValueToString(), as trying to do
-  // padding on-the fly with so many different fields is too much of a hassle.
-  std::fprintf(file, "%*s", static_cast<int>(padding), 
printValueToString(value).c_str());
-}
-
 bool YearMonthIntervalType::parseValueFromString(const std::string 
&value_string,
                                                  TypedValue *value) const {
   // Try simple-format parse first.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/YearMonthIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp
index f768046..a13b05f 100644
--- a/types/YearMonthIntervalType.hpp
+++ b/types/YearMonthIntervalType.hpp
@@ -40,7 +40,8 @@ namespace quickstep {
  * @brief A type representing the year-month interval.
  **/
 class YearMonthIntervalType :
-    public TypeConcept<kYearMonthInterval, false, kNativeEmbedded, 
YearMonthIntervalLit> {
+    public TypeSynthesizer<YearMonthIntervalType, kYearMonthInterval,
+                           false, kNativeEmbedded, YearMonthIntervalLit> {
  public:
   /**
    * @brief Get a reference to the non-nullable singleton instance of this
@@ -77,32 +78,16 @@ class YearMonthIntervalType :
     }
   }
 
-  const Type& getNullableVersion() const override {
-    return InstanceNullable();
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable();
-  }
-
   std::size_t estimateAverageByteLength() const override {
     return sizeof(YearMonthIntervalLit);
   }
 
-  bool isCoercibleFrom(const Type &original_type) const override;
-
-  bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
   int getPrintWidth() const override {
     return YearMonthIntervalLit::kPrintingChars;
   }
 
   std::string printValueToString(const TypedValue &value) const override;
 
-  void printValueToFile(const TypedValue &value,
-                        FILE *file,
-                        const int padding = 0) const override;
-
   TypedValue makeZeroValue() const override {
     return TypedValue(YearMonthIntervalLit{0});
   }
@@ -112,7 +97,8 @@ class YearMonthIntervalType :
 
  private:
   explicit YearMonthIntervalType(const bool nullable)
-      : TypeConcept<kYearMonthInterval, false, kNativeEmbedded, 
YearMonthIntervalLit>(
+      : TypeSynthesizer<YearMonthIntervalType, kYearMonthInterval,
+                        false, kNativeEmbedded, YearMonthIntervalLit>(
             Type::kOther, kStaticTypeID, nullable,
             sizeof(YearMonthIntervalLit), sizeof(YearMonthIntervalLit)) {
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/operations/OperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.cpp 
b/types/operations/OperationFactory.cpp
index 5d4295a..521e3ad 100644
--- a/types/operations/OperationFactory.cpp
+++ b/types/operations/OperationFactory.cpp
@@ -226,7 +226,7 @@ OperationFactory::ResolveStatus 
OperationFactory::resolveOperationWithPartialTyp
         coerced_static_args.emplace_back(arg_value);
       } else {
         const Type *expected_type = nullptr;
-        if (TypeUtil::IsParameterized(expected_type_id)) {
+        if (TypeFactory::TypeRequiresLengthParameter(expected_type_id)) {
           // TODO: refactor type system to make this coercion extensible.
           if (expected_type_id == kChar && arg_type.getTypeID() == kVarChar) {
             expected_type = &TypeFactory::GetType(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/operations/unary_operations/CMathUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMathUnaryOperations.hpp 
b/types/operations/unary_operations/CMathUnaryOperations.hpp
index a4cb201..8e54c03 100644
--- a/types/operations/unary_operations/CMathUnaryOperations.hpp
+++ b/types/operations/unary_operations/CMathUnaryOperations.hpp
@@ -60,6 +60,13 @@ template <typename ArgumentT, typename ResultT,
 using CMathUnaryFunctor =
     typename CMathUnaryFunctorWrapper<ArgumentT, ResultT, f, 
FunctorNameT>::type;
 
+inline std::int64_t CMathRound(const float arg) {
+  return std::llround(arg);
+}
+inline std::int64_t CMathRound(const double arg) {
+  return std::llround(arg);
+}
+
 using CMathUnaryFunctorPack = FunctorPack<
 // abs
     CMathUnaryFunctor<IntType, IntType,
@@ -97,9 +104,9 @@ using CMathUnaryFunctorPack = FunctorPack<
                       std::floor, StringLiteral<'f','l','o','o','r'>>,
 // round
     CMathUnaryFunctor<FloatType, LongType,
-                      std::llround, StringLiteral<'r','o','u','n','d'>>,
+                      CMathRound, StringLiteral<'r','o','u','n','d'>>,
     CMathUnaryFunctor<DoubleType, LongType,
-                      std::llround, StringLiteral<'r','o','u','n','d'>>
+                      CMathRound, StringLiteral<'r','o','u','n','d'>>
 >;
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9db9fc86/types/operations/unary_operations/CastOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.cpp 
b/types/operations/unary_operations/CastOperation.cpp
index b240b23..21378e4 100644
--- a/types/operations/unary_operations/CastOperation.cpp
+++ b/types/operations/unary_operations/CastOperation.cpp
@@ -195,7 +195,7 @@ UncheckedUnaryOperator* 
CastOperation::makeUncheckedUnaryOperator(
     return InvokeOnTypeID<TypeIDSelectorEqualsAny<kInt, kLong, kFloat, 
kDouble>>(
         argument_type_id,
         [&](auto arg_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-      using ArgumentT = typename TypeGenerator<decltype(arg_tid)::value>::type;
+      using ArgumentT = typename TypeClass<decltype(arg_tid)::value>::type;
 
       switch (result_type_id) {
         case kInt:  // Fall through
@@ -205,7 +205,7 @@ UncheckedUnaryOperator* 
CastOperation::makeUncheckedUnaryOperator(
           return InvokeOnTypeID<TypeIDSelectorEqualsAny<kInt, kLong, kFloat, 
kDouble>>(
               result_type_id,
               [&](auto result_tid) -> UncheckedUnaryOperator* {  // 
NOLINT(build/c++11)
-            using ResultT = typename 
TypeGenerator<decltype(result_tid)::value>::type;
+            using ResultT = typename 
TypeClass<decltype(result_tid)::value>::type;
 
             return new UncheckedUnaryOperatorWrapperCodegen<
                 NumericCastToNumericFunctor<ArgumentT, ResultT>>(type, 
*result_type);
@@ -216,7 +216,7 @@ UncheckedUnaryOperator* 
CastOperation::makeUncheckedUnaryOperator(
           return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
               result_type_id,
               [&](auto result_tid) -> UncheckedUnaryOperator* {  // 
NOLINT(build/c++11)
-            using ResultT = typename 
TypeGenerator<decltype(result_tid)::value>::type;
+            using ResultT = typename 
TypeClass<decltype(result_tid)::value>::type;
 
             return new UncheckedUnaryOperatorWrapperCodegen<
                  CastToAsciiStringFunctor<ArgumentT, ResultT>>(
@@ -235,7 +235,7 @@ UncheckedUnaryOperator* 
CastOperation::makeUncheckedUnaryOperator(
     return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
         argument_type_id,
         [&](auto arg_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-      using ArgumentT = typename TypeGenerator<decltype(arg_tid)::value>::type;
+      using ArgumentT = typename TypeClass<decltype(arg_tid)::value>::type;
 
       switch (result_type_id) {
         case kInt:  // Fall through
@@ -245,7 +245,7 @@ UncheckedUnaryOperator* 
CastOperation::makeUncheckedUnaryOperator(
           return InvokeOnTypeID<TypeIDSelectorEqualsAny<kInt, kLong, kFloat, 
kDouble>>(
               result_type_id,
               [&](auto result_tid) -> UncheckedUnaryOperator* {  // 
NOLINT(build/c++11)
-            using ResultT = typename 
TypeGenerator<decltype(result_tid)::value>::type;
+            using ResultT = typename 
TypeClass<decltype(result_tid)::value>::type;
 
             return new UncheckedUnaryOperatorWrapperCodegen<
                 AsciiStringCastToNumericFunctor<
@@ -260,7 +260,7 @@ UncheckedUnaryOperator* 
CastOperation::makeUncheckedUnaryOperator(
           return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
               result_type_id,
               [&](auto result_tid) -> UncheckedUnaryOperator* {  // 
NOLINT(build/c++11)
-            using ResultT = typename 
TypeGenerator<decltype(result_tid)::value>::type;
+            using ResultT = typename 
TypeClass<decltype(result_tid)::value>::type;
 
             return new UncheckedUnaryOperatorWrapperCodegen<
                  AsciiStringCastToAsciiStringFunctor<ArgumentT, ResultT>>(

Reply via email to