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/11 18:38:49 UTC

[25/41] incubator-quickstep git commit: Updates for adding generic types

Updates for adding generic 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/ebf44cd2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/ebf44cd2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/ebf44cd2

Branch: refs/heads/refactor-type
Commit: ebf44cd2dd230bd45c849cb008005ad9c07b2d60
Parents: 0200550
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Mon Oct 2 00:26:05 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Wed Oct 11 13:37:54 2017 -0500

----------------------------------------------------------------------
 cli/PrintToScreen.cpp                           |   2 +-
 compression/CompressionDictionaryBuilder.cpp    |   3 +-
 compression/CompressionDictionaryBuilder.hpp    |   6 +-
 .../aggregation/AggregationHandleAvg.hpp        |   8 +-
 .../aggregation/AggregationHandleMax.hpp        |   6 +-
 .../aggregation/AggregationHandleMin.hpp        |   6 +-
 .../aggregation/AggregationHandleSum.hpp        |   7 +-
 expressions/scalar/ScalarBinaryExpression.cpp   |   2 +-
 expressions/scalar/ScalarCaseExpression.cpp     |   2 +-
 expressions/scalar/ScalarLiteral.cpp            |   2 +-
 expressions/scalar/ScalarUnaryExpression.cpp    |   2 +-
 parser/ParseLiteralValue.cpp                    |   2 +-
 parser/SqlLexer.lpp                             |   2 +
 parser/SqlParser.ypp                            |   2 +
 query_optimizer/expressions/ScalarLiteral.cpp   |   2 +-
 query_optimizer/resolver/Resolver.cpp           |  10 +-
 relational_operators/TableExportOperator.cpp    |   2 +-
 storage/LinearOpenAddressingHashTable.hpp       |  18 +-
 storage/SeparateChainingHashTable.hpp           |  18 +-
 .../SimpleScalarSeparateChainingHashTable.hpp   |  18 +-
 storage/TupleStorageSubBlock.cpp                |   3 +-
 types/ArrayType.cpp                             |  46 +++
 types/ArrayType.hpp                             |  78 +++++
 types/AsciiStringSuperType.hpp                  |   2 +-
 types/BoolType.cpp                              |  12 +-
 types/BoolType.hpp                              |   8 +-
 types/CMakeLists.txt                            |   4 +
 types/CharType.cpp                              |  12 +-
 types/CharType.hpp                              |  10 +-
 types/DateType.cpp                              |   6 +-
 types/DateType.hpp                              |   6 +-
 types/DatetimeIntervalType.cpp                  |   6 +-
 types/DatetimeIntervalType.hpp                  |   6 +-
 types/DatetimeType.cpp                          |   6 +-
 types/DatetimeType.hpp                          |   6 +-
 types/DoubleType.cpp                            |  12 +-
 types/DoubleType.hpp                            |   8 +-
 types/FloatType.cpp                             |  12 +-
 types/FloatType.hpp                             |   8 +-
 types/GenericValue.cpp                          |   0
 types/GenericValue.hpp                          | 118 +++++++
 types/IntType.cpp                               |  12 +-
 types/IntType.hpp                               |   8 +-
 types/LongType.cpp                              |  12 +-
 types/LongType.hpp                              |   8 +-
 types/MetaType.cpp                              |  36 +++
 types/MetaType.hpp                              |  67 ++++
 types/NullType.hpp                              |  14 +-
 types/NumericSuperType.hpp                      |   5 +-
 types/ParameterizedPodLit.hpp                   |   0
 types/Type.cpp                                  |   2 +-
 types/Type.hpp                                  | 103 +++---
 types/Type.proto                                |   5 +
 types/TypeFactory.cpp                           |   5 +-
 types/TypeID.cpp                                |   2 +
 types/TypeID.hpp                                |  32 +-
 types/TypeIDSelectors.hpp                       |  62 ++--
 types/TypeRegistrar.hpp                         |  81 +++--
 types/TypeSynthesizer.hpp                       | 314 ++++++++++++++++---
 types/TypeUtil.hpp                              |   4 +-
 types/TypedValue.hpp                            |  22 ++
 types/VarCharType.cpp                           |  12 +-
 types/VarCharType.hpp                           |  10 +-
 types/YearMonthIntervalType.cpp                 |   6 +-
 types/YearMonthIntervalType.hpp                 |   6 +-
 types/containers/ColumnVector.hpp               |  24 +-
 types/operations/OperationUtil.hpp              |  12 +-
 .../BinaryOperationWrapper.hpp                  |   6 +-
 .../operations/comparisons/BasicComparison.hpp  |  23 +-
 .../unary_operations/CastOperation.cpp          |  10 +-
 .../unary_operations/UnaryOperationWrapper.hpp  |   2 +-
 utility/CMakeLists.txt                          |   7 +-
 utility/CharStream.hpp                          | 106 +++++++
 73 files changed, 1154 insertions(+), 353 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/cli/PrintToScreen.cpp
----------------------------------------------------------------------
diff --git a/cli/PrintToScreen.cpp b/cli/PrintToScreen.cpp
index bb64c93..59f3454 100644
--- a/cli/PrintToScreen.cpp
+++ b/cli/PrintToScreen.cpp
@@ -158,7 +158,7 @@ void PrintToScreen::printTuple(const TupleStorageSubBlock &tuple_store,
               *width_it,
               "NULL");
     } else {
-      attr_it->getType().printValueToFile(value, out, *width_it);
+      attr_it->getType().printTypedValueToFile(value, out, *width_it);
     }
 
     fputc('|', out);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/compression/CompressionDictionaryBuilder.cpp
----------------------------------------------------------------------
diff --git a/compression/CompressionDictionaryBuilder.cpp b/compression/CompressionDictionaryBuilder.cpp
index 905af91..4123541 100644
--- a/compression/CompressionDictionaryBuilder.cpp
+++ b/compression/CompressionDictionaryBuilder.cpp
@@ -121,7 +121,8 @@ void CompressionDictionaryBuilder::buildDictionary(void *location) {
 bool CompressionDictionaryBuilder::insertEntryInternal(const TypedValue &value,
                                                        bool by_reference) {
   DCHECK(!built_);
-  DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//  DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (type_is_nullable_ && value.isNull()) {
     last_insert_was_null_ = !null_value_present_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/compression/CompressionDictionaryBuilder.hpp
----------------------------------------------------------------------
diff --git a/compression/CompressionDictionaryBuilder.hpp b/compression/CompressionDictionaryBuilder.hpp
index cad6852..9c92ecc 100644
--- a/compression/CompressionDictionaryBuilder.hpp
+++ b/compression/CompressionDictionaryBuilder.hpp
@@ -114,7 +114,8 @@ class CompressionDictionaryBuilder {
    *        value.
    **/
   bool containsValue(const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     if (value.isNull()) {
       return null_value_present_;
     }
@@ -133,7 +134,8 @@ class CompressionDictionaryBuilder {
    * @return The code that maps to value.
    **/
   inline std::uint32_t getCodeForValue(const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     DCHECK(containsValue(value));
     DCHECK(built_);
     if (value.isNull()) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/expressions/aggregation/AggregationHandleAvg.hpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleAvg.hpp b/expressions/aggregation/AggregationHandleAvg.hpp
index 970561c..5dd4205 100644
--- a/expressions/aggregation/AggregationHandleAvg.hpp
+++ b/expressions/aggregation/AggregationHandleAvg.hpp
@@ -117,7 +117,8 @@ class AggregationHandleAvg : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(AggregationStateAvg *state,
                               const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     if (value.isNull()) return;
 
     SpinMutexLock lock(state->mutex_);
@@ -127,8 +128,9 @@ class AggregationHandleAvg : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(const TypedValue &value,
                               std::uint8_t *byte_ptr) const {
-    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
-    if (value.isNull()) return;
+//    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+   // TODO(refactor-type): fix signature.
+   if (value.isNull()) return;
     TypedValue *sum_ptr =
         reinterpret_cast<TypedValue *>(byte_ptr + blank_state_.sum_offset_);
     std::int64_t *count_ptr =

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/expressions/aggregation/AggregationHandleMax.hpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleMax.hpp b/expressions/aggregation/AggregationHandleMax.hpp
index 8f8c0d8..7f55cc7 100644
--- a/expressions/aggregation/AggregationHandleMax.hpp
+++ b/expressions/aggregation/AggregationHandleMax.hpp
@@ -98,13 +98,15 @@ class AggregationHandleMax : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(AggregationStateMax *state,
                               const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     compareAndUpdate(static_cast<AggregationStateMax *>(state), value);
   }
 
   inline void iterateUnaryInl(const TypedValue &value,
                               std::uint8_t *byte_ptr) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     TypedValue *max_ptr = reinterpret_cast<TypedValue *>(byte_ptr);
     compareAndUpdate(max_ptr, value);
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/expressions/aggregation/AggregationHandleMin.hpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleMin.hpp b/expressions/aggregation/AggregationHandleMin.hpp
index 0e62be5..c997788 100644
--- a/expressions/aggregation/AggregationHandleMin.hpp
+++ b/expressions/aggregation/AggregationHandleMin.hpp
@@ -100,13 +100,15 @@ class AggregationHandleMin : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(AggregationStateMin *state,
                               const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     compareAndUpdate(state, value);
   }
 
   inline void iterateUnaryInl(const TypedValue &value,
                               std::uint8_t *byte_ptr) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     TypedValue *min_ptr = reinterpret_cast<TypedValue *>(byte_ptr);
     compareAndUpdate(min_ptr, value);
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/expressions/aggregation/AggregationHandleSum.hpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleSum.hpp b/expressions/aggregation/AggregationHandleSum.hpp
index ba4fa9b..72a4673 100644
--- a/expressions/aggregation/AggregationHandleSum.hpp
+++ b/expressions/aggregation/AggregationHandleSum.hpp
@@ -113,7 +113,8 @@ class AggregationHandleSum : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(AggregationStateSum *state,
                               const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     if (value.isNull()) return;
 
     SpinMutexLock lock(state->mutex_);
@@ -123,8 +124,10 @@ class AggregationHandleSum : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(const TypedValue &value,
                               std::uint8_t *byte_ptr) const {
-    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     if (value.isNull()) return;
+
     TypedValue *sum_ptr =
         reinterpret_cast<TypedValue *>(byte_ptr + blank_state_.sum_offset_);
     bool *null_ptr =

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/expressions/scalar/ScalarBinaryExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarBinaryExpression.cpp b/expressions/scalar/ScalarBinaryExpression.cpp
index 2f0a0d4..78d16a3 100644
--- a/expressions/scalar/ScalarBinaryExpression.cpp
+++ b/expressions/scalar/ScalarBinaryExpression.cpp
@@ -427,7 +427,7 @@ void ScalarBinaryExpression::getFieldStringItems(
     if (static_value_->isNull()) {
       inline_field_values->emplace_back("NULL");
     } else {
-      inline_field_values->emplace_back(type_.printValueToString(*static_value_));
+      inline_field_values->emplace_back(type_.printTypedValueToString(*static_value_));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/expressions/scalar/ScalarCaseExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarCaseExpression.cpp b/expressions/scalar/ScalarCaseExpression.cpp
index 6847425..6fd2c0f 100644
--- a/expressions/scalar/ScalarCaseExpression.cpp
+++ b/expressions/scalar/ScalarCaseExpression.cpp
@@ -540,7 +540,7 @@ void ScalarCaseExpression::getFieldStringItems(
     if (static_value_.isNull()) {
       inline_field_values->emplace_back("NULL");
     } else {
-      inline_field_values->emplace_back(type_.printValueToString(static_value_));
+      inline_field_values->emplace_back(type_.printTypedValueToString(static_value_));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/expressions/scalar/ScalarLiteral.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarLiteral.cpp b/expressions/scalar/ScalarLiteral.cpp
index 808953d..53ba827 100644
--- a/expressions/scalar/ScalarLiteral.cpp
+++ b/expressions/scalar/ScalarLiteral.cpp
@@ -89,7 +89,7 @@ void ScalarLiteral::getFieldStringItems(
   if (internal_literal_.isNull()) {
     inline_field_values->emplace_back("NULL");
   } else {
-    inline_field_values->emplace_back(type_.printValueToString(internal_literal_));
+    inline_field_values->emplace_back(type_.printTypedValueToString(internal_literal_));
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/expressions/scalar/ScalarUnaryExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarUnaryExpression.cpp b/expressions/scalar/ScalarUnaryExpression.cpp
index c2fd931..3e83a6a 100644
--- a/expressions/scalar/ScalarUnaryExpression.cpp
+++ b/expressions/scalar/ScalarUnaryExpression.cpp
@@ -183,7 +183,7 @@ void ScalarUnaryExpression::getFieldStringItems(
     if (static_value_->isNull()) {
       inline_field_values->emplace_back("NULL");
     } else {
-      inline_field_values->emplace_back(type_.printValueToString(*static_value_));
+      inline_field_values->emplace_back(type_.printTypedValueToString(*static_value_));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/parser/ParseLiteralValue.cpp
----------------------------------------------------------------------
diff --git a/parser/ParseLiteralValue.cpp b/parser/ParseLiteralValue.cpp
index d4753ab..04e8a55 100644
--- a/parser/ParseLiteralValue.cpp
+++ b/parser/ParseLiteralValue.cpp
@@ -87,7 +87,7 @@ TypedValue NumericParseLiteralValue::concretize(
     const Type **concretized_type) const {
   TypedValue parsed_value;
   if ((type_hint != nullptr)
-      && (type_hint->getSuperTypeID() == Type::kNumeric)
+      && (type_hint->getSuperTypeID() == SuperTypeID::kNumeric)
       && (type_hint->parseValueFromString(numeric_string_, &parsed_value))) {
     *concretized_type = &(type_hint->getNonNullableVersion());
     return parsed_value;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/parser/SqlLexer.lpp
----------------------------------------------------------------------
diff --git a/parser/SqlLexer.lpp b/parser/SqlLexer.lpp
index 020673c..9a63483 100644
--- a/parser/SqlLexer.lpp
+++ b/parser/SqlLexer.lpp
@@ -302,6 +302,8 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "<="               return TOKEN_LEQ;
   ">="               return TOKEN_GEQ;
   "::"               return TOKEN_DOUBLECOLON;
+  "{"                return TOKEN_LBRACE;
+  "}"                return TOKEN_RBRACE;
 
   [-+*/%(),.;]       return yytext[0];
   [\[\]]             return yytext[0];

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/parser/SqlParser.ypp
----------------------------------------------------------------------
diff --git a/parser/SqlParser.ypp b/parser/SqlParser.ypp
index 0d19a4c..156e9e7 100644
--- a/parser/SqlParser.ypp
+++ b/parser/SqlParser.ypp
@@ -301,6 +301,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_JOIN;
 %token TOKEN_KEY;
 %token TOKEN_LAST;
+%token TOKEN_LBRACE;
 %token TOKEN_LEFT;
 %token TOKEN_LIMIT;
 %token TOKEN_LONG;
@@ -323,6 +324,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_PRIORITY;
 %token TOKEN_QUIT;
 %token TOKEN_RANGE;
+%token TOKEN_RBRACE;
 %token TOKEN_REAL;
 %token TOKEN_REFERENCES;
 %token TOKEN_REGEXP;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/query_optimizer/expressions/ScalarLiteral.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/ScalarLiteral.cpp b/query_optimizer/expressions/ScalarLiteral.cpp
index d2ab527..278e2cc 100644
--- a/query_optimizer/expressions/ScalarLiteral.cpp
+++ b/query_optimizer/expressions/ScalarLiteral.cpp
@@ -85,7 +85,7 @@ void ScalarLiteral::getFieldStringItems(
   if (value_.isNull()) {
     inline_field_values->push_back("NULL");
   } else {
-    inline_field_values->push_back(value_type_.printValueToString(value_));
+    inline_field_values->push_back(value_type_.printTypedValueToString(value_));
   }
 
   inline_field_names->push_back("type");

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index ca3a874..fdd132d 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -1017,8 +1017,8 @@ L::LogicalPtr Resolver::resolveInsertSelection(
       cast_expressions.emplace_back(selection_attributes[aid]);
     } else {
       // TODO(jianqiao): implement Cast operation for non-numeric types.
-      if (destination_type.getSuperTypeID() == Type::SuperTypeID::kNumeric &&
-          selection_type.getSuperTypeID() == Type::SuperTypeID::kNumeric &&
+      if (destination_type.getSuperTypeID() == SuperTypeID::kNumeric &&
+          selection_type.getSuperTypeID() == SuperTypeID::kNumeric &&
           destination_type.isSafelyCoercibleFrom(selection_type)) {
         // Add cast operation
 //        const E::AttributeReferencePtr attr = selection_attributes[aid];
@@ -1550,8 +1550,8 @@ L::LogicalPtr Resolver::resolveSetOperations(
       const Type &current_type = attribute_matrix[opid][aid]->getValueType();
       const Type &possible_type = possible_attribute->getValueType();
       if (!possible_type.equals(current_type)) {
-        if (possible_type.getSuperTypeID() == Type::SuperTypeID::kNumeric &&
-            current_type.getSuperTypeID() == Type::SuperTypeID::kNumeric) {
+        if (possible_type.getSuperTypeID() == SuperTypeID::kNumeric &&
+            current_type.getSuperTypeID() == SuperTypeID::kNumeric) {
           if (possible_type.isSafelyCoercibleFrom(current_type)) {
             // Cast current_type to possible_type.
             // Possible_attribute remain the same, nothing needs to change.
@@ -2075,7 +2075,7 @@ E::WindowInfo Resolver::resolveWindow(const ParseWindow &parse_window,
     // needed because -1 might not make sense in this case.
     if (!parse_frame_info->is_row &&
         (order_by_attributes.empty() ||
-         order_by_attributes[0]->getValueType().getSuperTypeID() != Type::SuperTypeID::kNumeric)) {
+         order_by_attributes[0]->getValueType().getSuperTypeID() != SuperTypeID::kNumeric)) {
       THROW_SQL_ERROR_AT(&parse_window)
           << "A numeric attribute should be specified as the first ORDER BY "
           << "attribute in FRAME mode";

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/relational_operators/TableExportOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/TableExportOperator.cpp b/relational_operators/TableExportOperator.cpp
index f6a73bf..419398f 100644
--- a/relational_operators/TableExportOperator.cpp
+++ b/relational_operators/TableExportOperator.cpp
@@ -326,7 +326,7 @@ void TableExportToStringWorkOrder::writeToString(ValueAccessor *accessor,
       if (value.isNull()) {
         return null_string_;
       } else {
-        return value_types[idx]->printValueToString(value);
+        return value_types[idx]->printTypedValueToString(value);
       }
     });
     output->push_back('\n');

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/storage/LinearOpenAddressingHashTable.hpp
----------------------------------------------------------------------
diff --git a/storage/LinearOpenAddressingHashTable.hpp b/storage/LinearOpenAddressingHashTable.hpp
index 044ec6f..34e60d6 100644
--- a/storage/LinearOpenAddressingHashTable.hpp
+++ b/storage/LinearOpenAddressingHashTable.hpp
@@ -567,7 +567,8 @@ const ValueT* LinearOpenAddressingHashTable<ValueT, resizable, serializable, for
     ::getSingle(const TypedValue &key) const {
   DEBUG_ASSERT(!allow_duplicate_keys);
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = this->AdjustHash(key.getHash());
   for (std::size_t bucket_num = hash_code % header_->num_buckets;
@@ -639,7 +640,8 @@ template <typename ValueT,
 void LinearOpenAddressingHashTable<ValueT, resizable, serializable, force_key_copy, allow_duplicate_keys>
     ::getAll(const TypedValue &key, std::vector<const ValueT*> *values) const {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = this->AdjustHash(key.getHash());
   for (std::size_t bucket_num = hash_code % header_->num_buckets;
@@ -714,7 +716,8 @@ HashTablePutResult
                       const ValueT &value,
                       HashTablePreallocationState *prealloc_state) {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
   DEBUG_ASSERT(prealloc_state == nullptr);
 
   // TODO(chasseur): If allow_duplicate_keys is true, avoid storing more than
@@ -831,7 +834,8 @@ ValueT* LinearOpenAddressingHashTable<ValueT, resizable, serializable, force_key
                      const ValueT &initial_value) {
   DEBUG_ASSERT(!allow_duplicate_keys);
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   // Block is do/while(false) so we can use break.
   do {
@@ -1040,7 +1044,8 @@ bool LinearOpenAddressingHashTable<ValueT, resizable, serializable, force_key_co
                          const ValueT **value,
                          std::size_t *entry_num) const {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (*entry_num == 0) {
     *entry_num = hash_code % header_->num_buckets;
@@ -1116,7 +1121,8 @@ template <typename ValueT,
 bool LinearOpenAddressingHashTable<ValueT, resizable, serializable, force_key_copy, allow_duplicate_keys>
     ::hasKey(const TypedValue &key) const {
   DCHECK_EQ(1u, this->key_types_.size());
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = this->AdjustHash(key.getHash());
   for (std::size_t bucket_num = hash_code % header_->num_buckets;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/storage/SeparateChainingHashTable.hpp
----------------------------------------------------------------------
diff --git a/storage/SeparateChainingHashTable.hpp b/storage/SeparateChainingHashTable.hpp
index 2403623..d60e40b 100644
--- a/storage/SeparateChainingHashTable.hpp
+++ b/storage/SeparateChainingHashTable.hpp
@@ -565,7 +565,8 @@ const ValueT* SeparateChainingHashTable<ValueT, resizable, serializable, force_k
     ::getSingle(const TypedValue &key) const {
   DEBUG_ASSERT(!allow_duplicate_keys);
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHash();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -621,7 +622,8 @@ template <typename ValueT,
 void SeparateChainingHashTable<ValueT, resizable, serializable, force_key_copy, allow_duplicate_keys>
     ::getAll(const TypedValue &key, std::vector<const ValueT*> *values) const {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHash();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -680,7 +682,8 @@ HashTablePutResult
                       const ValueT &value,
                       HashTablePreallocationState *prealloc_state) {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (prealloc_state == nullptr) {
     // Early check for a free bucket.
@@ -822,7 +825,8 @@ ValueT* SeparateChainingHashTable<ValueT, resizable, serializable, force_key_cop
                      const ValueT &initial_value) {
   DEBUG_ASSERT(!allow_duplicate_keys);
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (variable_key_size > 0) {
     // Don't allocate yet, since the key may already be present. However, we
@@ -988,7 +992,8 @@ bool SeparateChainingHashTable<ValueT, resizable, serializable, force_key_copy,
                          const ValueT **value,
                          std::size_t *entry_num) const {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (*entry_num == 0) {
     *entry_num = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -1066,7 +1071,8 @@ template <typename ValueT,
 bool SeparateChainingHashTable<ValueT, resizable, serializable, force_key_copy, allow_duplicate_keys>
     ::hasKey(const TypedValue &key) const {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHash();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/storage/SimpleScalarSeparateChainingHashTable.hpp
----------------------------------------------------------------------
diff --git a/storage/SimpleScalarSeparateChainingHashTable.hpp b/storage/SimpleScalarSeparateChainingHashTable.hpp
index 81f2044..1a515e3 100644
--- a/storage/SimpleScalarSeparateChainingHashTable.hpp
+++ b/storage/SimpleScalarSeparateChainingHashTable.hpp
@@ -563,7 +563,8 @@ const ValueT* SimpleScalarSeparateChainingHashTable<ValueT,
                                                     allow_duplicate_keys>
     ::getSingle(const TypedValue &key) const {
   DCHECK(!allow_duplicate_keys);
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHashScalarLiteral();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -593,7 +594,8 @@ void SimpleScalarSeparateChainingHashTable<ValueT,
                                            force_key_copy,
                                            allow_duplicate_keys>
     ::getAll(const TypedValue &key, std::vector<const ValueT*> *values) const {
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHashScalarLiteral();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -626,7 +628,8 @@ HashTablePutResult
                       const std::size_t variable_key_size,
                       const ValueT &value,
                       HashTablePreallocationState *prealloc_state) {
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (prealloc_state == nullptr) {
     // Early check for a free bucket.
@@ -682,7 +685,8 @@ ValueT* SimpleScalarSeparateChainingHashTable<ValueT,
                      const std::size_t variable_key_size,
                      const ValueT &initial_value) {
   DCHECK(!allow_duplicate_keys);
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
   DCHECK_EQ(0u, variable_key_size);
 
   const std::size_t hash_code = key.getHashScalarLiteral();
@@ -752,7 +756,8 @@ bool SimpleScalarSeparateChainingHashTable<ValueT,
                          const std::size_t hash_code,
                          const ValueT **value,
                          std::size_t *entry_num) const {
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (*entry_num == 0) {
     *entry_num = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -792,7 +797,8 @@ bool SimpleScalarSeparateChainingHashTable<ValueT,
                                            allow_duplicate_keys>
     ::hasKey(const TypedValue &key) const {
   DCHECK_EQ(1u, this->key_types_.size());
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHashScalarLiteral();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/storage/TupleStorageSubBlock.cpp
----------------------------------------------------------------------
diff --git a/storage/TupleStorageSubBlock.cpp b/storage/TupleStorageSubBlock.cpp
index f2eef49..50b84ca 100644
--- a/storage/TupleStorageSubBlock.cpp
+++ b/storage/TupleStorageSubBlock.cpp
@@ -101,7 +101,8 @@ void TupleStorageSubBlock::paranoidInsertTypeCheck(const Tuple &tuple) {
   CatalogRelationSchema::const_iterator attr_it = relation_.begin();
 
   while (value_it != tuple.end()) {
-    assert(value_it->isPlausibleInstanceOf(attr_it->getType().getSignature()));
+//    assert(value_it->isPlausibleInstanceOf(attr_it->getType().getSignature()));
+    // TODO(refactor-type): fix signature.
 
     ++value_it;
     ++attr_it;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/ArrayType.cpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.cpp b/types/ArrayType.cpp
new file mode 100644
index 0000000..198e580
--- /dev/null
+++ b/types/ArrayType.cpp
@@ -0,0 +1,46 @@
+/**
+ * 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.
+ **/
+
+#include "types/ArrayType.hpp"
+
+#include <string>
+
+#include "types/TypeID.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+std::string ArrayType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
+
+  const std::vector<UntypedLiteral*> &literals = castValueToLiteral(value);
+  std::string ret = "{";
+  if (!literals.empty()) {
+    ret.append(element_type_.printValueToString(literals.front()));
+    for (std::size_t i = 1; i < literals.size(); ++i) {
+      ret.append(", ");
+      ret.append(element_type_.printValueToString(literals.at(i)));
+    }
+  }
+  ret.append("}");
+  return ret;
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/ArrayType.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp
new file mode 100644
index 0000000..1c66ed2
--- /dev/null
+++ b/types/ArrayType.hpp
@@ -0,0 +1,78 @@
+/**
+ * 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_ARRAY_TYPE_HPP_
+#define QUICKSTEP_TYPES_ARRAY_TYPE_HPP_
+
+#include <cstddef>
+#include <string>
+
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class TypedValue;
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class ArrayType : public TypeSynthesizer<kArray> {
+ public:
+  int getPrintWidth() const override {
+    return 16;
+  }
+
+  std::string printValueToString(const UntypedLiteral *value) const override;
+
+  bool parseValueFromString(const std::string &value_string,
+                            TypedValue *value) const override {
+    return false;
+  }
+
+ private:
+  ArrayType(const bool nullable, const std::vector<GenericValue> &parameters)
+      : TypeSynthesizer<kArray>(nullable, 0, 0x1000, parameters),
+        element_type_(ExtractType(parameters)) {
+    // TODO(refactor-type): Possibly infinite maximum size.
+    // TODO(refactor-type): Validate parameters.
+  }
+
+  static const Type& ExtractType(const std::vector<GenericValue> &parameters) {
+    DCHECK_EQ(1u, parameters.size());
+    const GenericValue &value = parameters.front();
+    DCHECK(value.getType().getTypeID() == kMetaType);
+    return *static_cast<const Type*>(value.getValue());
+  }
+
+  const Type &element_type_;
+
+  QUICKSTEP_SYNTHESIZE_TYPE(ArrayType);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_ARRAY_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/AsciiStringSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/AsciiStringSuperType.hpp b/types/AsciiStringSuperType.hpp
index 959c288..b6abcdf 100644
--- a/types/AsciiStringSuperType.hpp
+++ b/types/AsciiStringSuperType.hpp
@@ -42,7 +42,7 @@ class AsciiStringSuperType : public TypeSynthesizer<type_id> {
     if (original_type.isNullable() && !this->nullable_) {
       return false;
     }
-    return (original_type.getSuperTypeID() == Type::kAsciiString)
+    return (original_type.getSuperTypeID() == SuperTypeID::kAsciiString)
            || (original_type.getTypeID() == kNullType);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/BoolType.cpp
----------------------------------------------------------------------
diff --git a/types/BoolType.cpp b/types/BoolType.cpp
index 83cf060..9680770 100644
--- a/types/BoolType.cpp
+++ b/types/BoolType.cpp
@@ -30,21 +30,21 @@
 
 namespace quickstep {
 
-std::string BoolType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string BoolType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  return value.getLiteral<bool>() ? "true" : "false";
+  return castValueToLiteral(value) ? "true" : "false";
 }
 
-void BoolType::printValueToFile(const TypedValue &value,
+void BoolType::printValueToFile(const UntypedLiteral *value,
                                 FILE *file,
                                 const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
 
   std::fprintf(file,
                "%*s",
                static_cast<int>(padding),
-               value.getLiteral<bool>() ? "true" : "false");
+               castValueToLiteral(value) ? "true" : "false");
 }
 
 bool BoolType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/BoolType.hpp
----------------------------------------------------------------------
diff --git a/types/BoolType.hpp b/types/BoolType.hpp
index f149e76..2ba380a 100644
--- a/types/BoolType.hpp
+++ b/types/BoolType.hpp
@@ -48,9 +48,9 @@ class BoolType : public NumericSuperType<kBool> {
     return 5;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -61,9 +61,7 @@ class BoolType : public NumericSuperType<kBool> {
   explicit BoolType(const bool nullable)
       : NumericSuperType<kBool>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(BoolType);
+  QUICKSTEP_SYNTHESIZE_TYPE(BoolType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 325c6ea..07f9d97 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_ArrayType ArrayType.cpp ArrayType.hpp)
 add_library(quickstep_types_AsciiStringSuperType ../empty_src.cpp AsciiStringSuperType.hpp)
 add_library(quickstep_types_BoolType BoolType.cpp BoolType.hpp)
 add_library(quickstep_types_CharType CharType.cpp CharType.hpp)
@@ -42,16 +43,19 @@ add_library(quickstep_types_DatetimeLit ../empty_src.cpp DatetimeLit.hpp)
 add_library(quickstep_types_DatetimeType DatetimeType.cpp DatetimeType.hpp)
 add_library(quickstep_types_DoubleType DoubleType.cpp DoubleType.hpp)
 add_library(quickstep_types_FloatType FloatType.cpp FloatType.hpp)
+add_library(quickstep_types_GenericValue GenericValue.cpp GenericValue.hpp)
 add_library(quickstep_types_IntType IntType.cpp IntType.hpp)
 add_library(quickstep_types_IntervalLit ../empty_src.cpp IntervalLit.hpp)
 add_library(quickstep_types_IntervalParser IntervalParser.cpp IntervalParser.hpp)
 add_library(quickstep_types_LongType LongType.cpp LongType.hpp)
+add_library(quickstep_types_MetaType MetaType.cpp MetaType.hpp)
 add_library(quickstep_types_NullCoercibilityCheckMacro ../empty_src.cpp NullCoercibilityCheckMacro.hpp)
 add_library(quickstep_types_NullLit ../empty_src.cpp NullLit.hpp)
 add_library(quickstep_types_NullType ../empty_src.cpp NullType.hpp)
 add_library(quickstep_types_NumericSuperType ../empty_src.cpp NumericSuperType.hpp)
 add_library(quickstep_types_NumericTypeSafeCoercibility ../empty_src.cpp NumericTypeSafeCoercibility.hpp)
 add_library(quickstep_types_NumericTypeUnifier ../empty_src.cpp NumericTypeUnifier.hpp)
+add_library(quickstep_types_ParameterizedPodLit ../empty_src.cpp ParameterizedPodLit.hpp)
 add_library(quickstep_types_Type Type.cpp Type.hpp)
 add_library(quickstep_types_TypeErrors ../empty_src.cpp TypeErrors.hpp)
 add_library(quickstep_types_TypeFactory TypeFactory.cpp TypeFactory.hpp)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/CharType.cpp
----------------------------------------------------------------------
diff --git a/types/CharType.cpp b/types/CharType.cpp
index 2ed469b..ea3d00e 100644
--- a/types/CharType.cpp
+++ b/types/CharType.cpp
@@ -65,17 +65,17 @@ string CharType::getName() const {
   return name;
 }
 
-std::string CharType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string CharType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  const char *cstr = static_cast<const char*>(value.getOutOfLineData());
+  const char *cstr = static_cast<const char*>(castValueToLiteral(value).getOutOfLineData());
   return std::string(cstr, strnlen(cstr, length_));
 }
 
-void CharType::printValueToFile(const TypedValue &value,
+void CharType::printValueToFile(const UntypedLiteral *value,
                                 FILE *file,
                                 const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
   DCHECK_EQ(length_, static_cast<decltype(length_)>(static_cast<int>(length_)))
       << "Can not convert CHAR Type's maximum length " << length_
       << " to int for fprintf()";
@@ -84,7 +84,7 @@ void CharType::printValueToFile(const TypedValue &value,
                "%*.*s",
                padding,
                static_cast<int>(length_),
-               static_cast<const char*>(value.getOutOfLineData()));
+               castValueToLiteral(value).getOutOfLineData());
 }
 
 bool CharType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/CharType.hpp
----------------------------------------------------------------------
diff --git a/types/CharType.hpp b/types/CharType.hpp
index c90a8da..32b0c7a 100644
--- a/types/CharType.hpp
+++ b/types/CharType.hpp
@@ -53,9 +53,9 @@ class CharType : public AsciiStringSuperType<kChar> {
     return length_;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -66,12 +66,10 @@ class CharType : public AsciiStringSuperType<kChar> {
                          const Type &original_type) const override;
 
  private:
-  CharType(const std::size_t length, const bool nullable)
+  CharType(const bool nullable, const std::size_t length)
       : AsciiStringSuperType<kChar>(nullable, length, length, length) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(CharType);
+  QUICKSTEP_SYNTHESIZE_TYPE(CharType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/DateType.cpp
----------------------------------------------------------------------
diff --git a/types/DateType.cpp b/types/DateType.cpp
index de1e554..dcd779d 100644
--- a/types/DateType.cpp
+++ b/types/DateType.cpp
@@ -45,10 +45,10 @@ using std::snprintf;
 
 namespace quickstep {
 
-std::string DateType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string DateType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  const DateLit literal = value.getLiteral<DateLit>();
+  const DateLit &literal = castValueToLiteral(value);
   const std::int32_t year = literal.year;
 
   char datebuf[DateLit::kIsoChars + 1];

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/DateType.hpp
----------------------------------------------------------------------
diff --git a/types/DateType.hpp b/types/DateType.hpp
index 088c125..b7d1820 100644
--- a/types/DateType.hpp
+++ b/types/DateType.hpp
@@ -47,7 +47,7 @@ class DateType : public TypeSynthesizer<kDate> {
     return DateLit::kIsoChars;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
   /**
    * @note value_string is expected to be in (possibly extended) ISO-8601
@@ -68,9 +68,7 @@ class DateType : public TypeSynthesizer<kDate> {
   explicit DateType(const bool nullable)
       : TypeSynthesizer<kDate>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(DateType);
+  QUICKSTEP_SYNTHESIZE_TYPE(DateType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/DatetimeIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.cpp b/types/DatetimeIntervalType.cpp
index 2c77f89..e419ce3 100644
--- a/types/DatetimeIntervalType.cpp
+++ b/types/DatetimeIntervalType.cpp
@@ -46,10 +46,10 @@ using std::snprintf;
 
 namespace quickstep {
 
-std::string DatetimeIntervalType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string DatetimeIntervalType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  std::int64_t subseconds = value.getLiteral<DatetimeIntervalLit>().interval_ticks;
+  std::int64_t subseconds = castValueToLiteral(value).interval_ticks;
   const bool negative_interval = subseconds < 0;
   if (negative_interval) {
     subseconds = -subseconds;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/DatetimeIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp
index d22f965..bf36609 100644
--- a/types/DatetimeIntervalType.hpp
+++ b/types/DatetimeIntervalType.hpp
@@ -47,7 +47,7 @@ class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> {
     return DatetimeIntervalLit::kPrintingChars;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
   TypedValue makeZeroValue() const override {
     return TypedValue(DatetimeIntervalLit{0});
@@ -60,9 +60,7 @@ class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> {
   explicit DatetimeIntervalType(const bool nullable)
       : TypeSynthesizer<kDatetimeInterval>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(DatetimeIntervalType);
+  QUICKSTEP_SYNTHESIZE_TYPE(DatetimeIntervalType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/DatetimeType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.cpp b/types/DatetimeType.cpp
index 723da61..11ffae9 100644
--- a/types/DatetimeType.cpp
+++ b/types/DatetimeType.cpp
@@ -50,10 +50,10 @@ using std::snprintf;
 
 namespace quickstep {
 
-std::string DatetimeType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string DatetimeType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  const DatetimeLit literal = value.getLiteral<DatetimeLit>();
+  const DatetimeLit &literal = castValueToLiteral(value);
   const std::time_t timestamp = literal.epochTime();
   struct tm timeinfo;
   quickstep::gmtime_r(&timestamp, &timeinfo);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/DatetimeType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp
index 6ee15c6..924ff35 100644
--- a/types/DatetimeType.hpp
+++ b/types/DatetimeType.hpp
@@ -48,7 +48,7 @@ class DatetimeType
     return DatetimeLit::kIsoChars;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
   /**
    * @note value_string is expected to be in (possibly extended) ISO-8601
@@ -77,9 +77,7 @@ class DatetimeType
   explicit DatetimeType(const bool nullable)
       : TypeSynthesizer<kDatetime>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(DatetimeType);
+  QUICKSTEP_SYNTHESIZE_TYPE(DatetimeType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/DoubleType.cpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.cpp b/types/DoubleType.cpp
index f5c2650..fb50957 100644
--- a/types/DoubleType.cpp
+++ b/types/DoubleType.cpp
@@ -38,15 +38,15 @@ using std::snprintf;
 
 namespace quickstep {
 
-std::string DoubleType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string DoubleType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
   char printbuffer[kPrintWidth + 1];
   int written = snprintf(printbuffer,
                          sizeof(printbuffer),
                          "%.*g",
                          std::numeric_limits<double>::max_digits10,
-                         value.getLiteral<double>());
+                         castValueToLiteral(value));
   DCHECK_GE(written, 0) << "snprintf() encountered an encoding error";
   DCHECK_LT(static_cast<std::size_t>(written), sizeof(printbuffer))
       << "snprintf() would have written a string of length " << written
@@ -54,16 +54,16 @@ std::string DoubleType::printValueToString(const TypedValue &value) const {
   return std::string(printbuffer);
 }
 
-void DoubleType::printValueToFile(const TypedValue &value,
+void DoubleType::printValueToFile(const UntypedLiteral *value,
                                   FILE *file,
                                   const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
 
   std::fprintf(file,
                "%*.*g",
                padding,
                std::numeric_limits<double>::max_digits10,
-               value.getLiteral<double>());
+               castValueToLiteral(value));
 }
 
 bool DoubleType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/DoubleType.hpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp
index 05bec64..ddba4e3 100644
--- a/types/DoubleType.hpp
+++ b/types/DoubleType.hpp
@@ -46,9 +46,9 @@ class DoubleType : public NumericSuperType<kDouble> {
     return kPrintWidth;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -74,9 +74,7 @@ class DoubleType : public NumericSuperType<kDouble> {
   explicit DoubleType(const bool nullable)
       : NumericSuperType<kDouble>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(DoubleType);
+  QUICKSTEP_SYNTHESIZE_TYPE(DoubleType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/FloatType.cpp
----------------------------------------------------------------------
diff --git a/types/FloatType.cpp b/types/FloatType.cpp
index be22770..ca741a6 100644
--- a/types/FloatType.cpp
+++ b/types/FloatType.cpp
@@ -38,15 +38,15 @@ using std::snprintf;
 
 namespace quickstep {
 
-std::string FloatType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string FloatType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
   char printbuffer[kPrintWidth + 1];
   int written = snprintf(printbuffer,
                          sizeof(printbuffer),
                          "%.*g",
                          std::numeric_limits<float>::max_digits10,
-                         value.getLiteral<float>());
+                         castValueToLiteral(value));
   DCHECK_GE(written, 0) << "snprintf() encountered an encoding error";
   DCHECK_LT(static_cast<std::size_t>(written), sizeof(printbuffer))
       << "snprintf() would have written a string of length " << written
@@ -54,16 +54,16 @@ std::string FloatType::printValueToString(const TypedValue &value) const {
   return std::string(printbuffer);
 }
 
-void FloatType::printValueToFile(const TypedValue &value,
+void FloatType::printValueToFile(const UntypedLiteral *value,
                                  FILE *file,
                                  const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
 
   std::fprintf(file,
                "%*.*g",
                static_cast<int>(padding),
                std::numeric_limits<float>::max_digits10,
-               value.getLiteral<float>());
+               castValueToLiteral(value));
 }
 
 bool FloatType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/FloatType.hpp
----------------------------------------------------------------------
diff --git a/types/FloatType.hpp b/types/FloatType.hpp
index 6c8466d..68a636b 100644
--- a/types/FloatType.hpp
+++ b/types/FloatType.hpp
@@ -46,9 +46,9 @@ class FloatType : public NumericSuperType<kFloat> {
     return kPrintWidth;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -74,9 +74,7 @@ class FloatType : public NumericSuperType<kFloat> {
   explicit FloatType(const bool nullable)
       : NumericSuperType<kFloat>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(FloatType);
+  QUICKSTEP_SYNTHESIZE_TYPE(FloatType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/GenericValue.cpp
----------------------------------------------------------------------
diff --git a/types/GenericValue.cpp b/types/GenericValue.cpp
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/GenericValue.hpp
----------------------------------------------------------------------
diff --git a/types/GenericValue.hpp b/types/GenericValue.hpp
new file mode 100644
index 0000000..61529d6
--- /dev/null
+++ b/types/GenericValue.hpp
@@ -0,0 +1,118 @@
+/**
+ * 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_GENERIC_VALUE_HPP_
+#define QUICKSTEP_TYPES_GENERIC_VALUE_HPP_
+
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <string>
+
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "utility/HashPair.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class GenericValue {
+ public:
+  GenericValue(const Type &type, const UntypedLiteral *value, const bool owns)
+      : type_(type), value_(value), owns_(owns) {}
+
+  template <typename TypeClass>
+  GenericValue(const TypeClass &type, const typename TypeClass::cpptype &value)
+      : type_(type), value_(type.cloneValue(&value)), owns_(true) {}
+
+  GenericValue(const GenericValue &other)
+      : type_(other.type_),
+        value_(other.owns_ ? type_.cloneValue(other.value_) : other.value_),
+        owns_(other.owns_) {}
+
+  GenericValue(GenericValue &&other)
+      : type_(other.type_),
+        value_(other.value_),
+        owns_(other.owns_) {
+    other.owns_ = false;
+  }
+
+  ~GenericValue() {
+    if (owns_ && value_ != nullptr) {
+      type_.destroyValue(const_cast<void*>(value_));
+    }
+  }
+
+  inline bool isNull() const {
+    DCHECK(value_ != nullptr || type_.isNullable());
+    return value_ == nullptr;
+  }
+
+  inline bool isReference() const {
+    return !owns_;
+  }
+
+  inline const Type& getType() const {
+    return type_;
+  }
+
+  inline const UntypedLiteral* getValue() const {
+    return value_;
+  }
+
+  template <TypeID type_id>
+  inline const typename TypeIDTrait<type_id>::cpptype& getLiteral() const {
+    DCHECK_EQ(type_id, type_.getTypeID());
+    return *static_cast<typename TypeIDTrait<type_id>::cpptype*>(value_);
+  }
+
+  inline void ensureNotReference() {
+    if (isReference()) {
+      value_ = type_.cloneValue(value_);
+      owns_ = true;
+    }
+  }
+
+  inline bool operator==(const GenericValue &other) const {
+    return type_.equals(other.type_) &&
+           type_.checkValuesEqual(value_, other.value_);
+  }
+
+  inline std::size_t getHash() const {
+    return CombineHashes(type_.getHash(), type_.hashValue(value_));
+  }
+
+ private:
+  const Type &type_;
+  const UntypedLiteral *value_;
+  bool owns_;
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_GENERIC_VALUE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/IntType.cpp
----------------------------------------------------------------------
diff --git a/types/IntType.cpp b/types/IntType.cpp
index 1005aa9..8e3aff1 100644
--- a/types/IntType.cpp
+++ b/types/IntType.cpp
@@ -29,21 +29,21 @@
 
 namespace quickstep {
 
-std::string IntType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string IntType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  return std::to_string(value.getLiteral<int>());
+  return std::to_string(castValueToLiteral(value));
 }
 
-void IntType::printValueToFile(const TypedValue &value,
+void IntType::printValueToFile(const UntypedLiteral *value,
                                FILE *file,
                                const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
 
   std::fprintf(file,
                "%*d",
                static_cast<int>(padding),
-               value.getLiteral<int>());
+               castValueToLiteral(value));
 }
 
 bool IntType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/IntType.hpp
----------------------------------------------------------------------
diff --git a/types/IntType.hpp b/types/IntType.hpp
index 84cc7ce..d83c257 100644
--- a/types/IntType.hpp
+++ b/types/IntType.hpp
@@ -48,9 +48,9 @@ class IntType : public NumericSuperType<kInt> {
     return std::numeric_limits<int>::digits10 + 2;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -61,9 +61,7 @@ class IntType : public NumericSuperType<kInt> {
   explicit IntType(const bool nullable)
       : NumericSuperType<kInt>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(IntType);
+  QUICKSTEP_SYNTHESIZE_TYPE(IntType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/LongType.cpp
----------------------------------------------------------------------
diff --git a/types/LongType.cpp b/types/LongType.cpp
index 334821d..82dce39 100644
--- a/types/LongType.cpp
+++ b/types/LongType.cpp
@@ -35,21 +35,21 @@
 
 namespace quickstep {
 
-std::string LongType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string LongType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  return std::to_string(value.getLiteral<std::int64_t>());
+  return std::to_string(castValueToLiteral(value));
 }
 
-void LongType::printValueToFile(const TypedValue &value,
+void LongType::printValueToFile(const UntypedLiteral *value,
                                 FILE *file,
                                 const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
 
   std::fprintf(file,
                "%*" PRId64,
                static_cast<int>(padding),
-               value.getLiteral<std::int64_t>());
+               castValueToLiteral(value));
 }
 
 bool LongType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/LongType.hpp
----------------------------------------------------------------------
diff --git a/types/LongType.hpp b/types/LongType.hpp
index e52a166..7561975 100644
--- a/types/LongType.hpp
+++ b/types/LongType.hpp
@@ -49,9 +49,9 @@ class LongType : public NumericSuperType<kLong> {
     return std::numeric_limits<std::int64_t>::digits10 + 2;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -62,9 +62,7 @@ class LongType : public NumericSuperType<kLong> {
   explicit LongType(const bool nullable)
       : NumericSuperType<kLong>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(LongType);
+  QUICKSTEP_SYNTHESIZE_TYPE(LongType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/MetaType.cpp
----------------------------------------------------------------------
diff --git a/types/MetaType.cpp b/types/MetaType.cpp
new file mode 100644
index 0000000..01fc3a0
--- /dev/null
+++ b/types/MetaType.cpp
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ **/
+
+#include "types/MetaType.hpp"
+
+#include <string>
+
+#include "types/TypeID.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+std::string MetaType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
+
+  return castValueToLiteral(value)->getName();
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/MetaType.hpp
----------------------------------------------------------------------
diff --git a/types/MetaType.hpp b/types/MetaType.hpp
new file mode 100644
index 0000000..0c3952b
--- /dev/null
+++ b/types/MetaType.hpp
@@ -0,0 +1,67 @@
+/**
+ * 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_META_TYPE_HPP_
+#define QUICKSTEP_TYPES_META_TYPE_HPP_
+
+#include <cstddef>
+#include <string>
+
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class TypedValue;
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class MetaType : public TypeSynthesizer<kMetaType> {
+ public:
+  int getPrintWidth() const override {
+    return 16;
+  }
+
+  std::string printValueToString(const UntypedLiteral *value) const override;
+
+  bool parseValueFromString(const std::string &value_string,
+                            TypedValue *value) const override {
+    return false;
+  }
+
+ private:
+  MetaType(const bool nullable)
+      : TypeSynthesizer<kMetaType>(nullable, sizeof(TypeID), 0x100) {
+    // TODO(refactor-type): Possibly infinite maximum size.
+  }
+
+  QUICKSTEP_SYNTHESIZE_TYPE(MetaType);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_META_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/NullType.hpp
----------------------------------------------------------------------
diff --git a/types/NullType.hpp b/types/NullType.hpp
index 7491ca7..8dd237e 100644
--- a/types/NullType.hpp
+++ b/types/NullType.hpp
@@ -17,8 +17,8 @@
  * under the License.
  **/
 
-#ifndef QUICKSTEP_TYPES_NULLTYPE_HPP_
-#define QUICKSTEP_TYPES_NULLTYPE_HPP_
+#ifndef QUICKSTEP_TYPES_NULL_TYPE_HPP_
+#define QUICKSTEP_TYPES_NULL_TYPE_HPP_
 
 #include <cstddef>
 #include <cstdio>
@@ -69,11 +69,11 @@ class NullType : public TypeSynthesizer<kNullType> {
     return 0;
   }
 
-  std::string printValueToString(const TypedValue &value) const override {
+  std::string printValueToString(const UntypedLiteral *value) const override {
     LOG(FATAL) << "NullType is not printable";
   }
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override {
     LOG(FATAL) << "NullType is not printable";
@@ -92,13 +92,11 @@ class NullType : public TypeSynthesizer<kNullType> {
     DCHECK(nullable);
   }
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(NullType);
+  QUICKSTEP_SYNTHESIZE_TYPE(NullType);
 };
 
 /** @} */
 
 }  // namespace quickstep
 
-#endif  // QUICKSTEP_TYPES_NULLTYPE_HPP_
+#endif  // QUICKSTEP_TYPES_NULL_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index abe8b87..6576cbf 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -22,6 +22,7 @@
 
 #include <cstddef>
 #include <unordered_set>
+#include <utility>
 
 #include "types/NullCoercibilityCheckMacro.hpp"
 #include "types/NumericTypeSafeCoercibility.hpp"
@@ -54,7 +55,7 @@ class NumericSuperType : public TypeSynthesizer<type_id> {
 
   bool isCoercibleFrom(const Type &original_type) const override {
     QUICKSTEP_NULL_COERCIBILITY_CHECK();
-    return (original_type.getSuperTypeID() == Type::kNumeric);
+    return (original_type.getSuperTypeID() == SuperTypeID::kNumeric);
   }
 
   TypedValue makeZeroValue() const override {
@@ -63,7 +64,7 @@ class NumericSuperType : public TypeSynthesizer<type_id> {
 
   TypedValue coerceValue(const TypedValue &original_value,
                          const Type &original_type) const override {
-    if (original_type.getSuperTypeID() != Type::kNumeric) {
+    if (original_type.getSuperTypeID() != SuperTypeID::kNumeric) {
       LOG(FATAL) << "Attempted to coerce Type " << original_type.getName()
                  << " (not recognized as a numeric Type) to " << Type::getName();
     }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/ParameterizedPodLit.hpp
----------------------------------------------------------------------
diff --git a/types/ParameterizedPodLit.hpp b/types/ParameterizedPodLit.hpp
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index b69cb65..34678c7 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -53,7 +53,7 @@ std::size_t Type::estimateAverageByteLength() const {
   }
 }
 
-void Type::printValueToFile(const TypedValue &value,
+void Type::printValueToFile(const UntypedLiteral *value,
                             FILE *file,
                             const int padding) const {
   std::fprintf(file, "%*s", padding, printValueToString(value).c_str());

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index bf6c167..47f00e6 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -24,10 +24,13 @@
 #include <cstdint>
 #include <cstdio>
 #include <string>
+#include <vector>
 
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
 #include "types/TypedValue.hpp"
+#include "utility/CharStream.hpp"
 #include "utility/Macros.hpp"
 
 #include "glog/logging.h"
@@ -93,15 +96,6 @@ struct YearMonthIntervalLit;
 class Type {
  public:
   /**
-   * @brief Categories of intermediate supertypes.
-   **/
-  enum SuperTypeID {
-    kNumeric = 0,  // Fixed-length numeric types (Int, Long, Float, Double)
-    kAsciiString,  // ASCII strings (Char, VarChar)
-    kOther         // Others (Date, Datetime, DatetimeInterval, YearMonthInterval)
-  };
-
-  /**
    * @brief Virtual destructor.
    **/
   virtual ~Type() {
@@ -142,23 +136,6 @@ class Type {
   }
 
   /**
-   * @brief Get this Type's signature.
-   *
-   * @note The signature does not necessarily uniquely identify this Type. It
-   *       merely provides some basic information for debugging that can be
-   *       passed to TypedValue::isPlausibleInstanceOf().
-   *
-   * @return This Type's signature.
-   **/
-  inline TypeSignature getSignature() const {
-    TypeSignature sig;
-    sig.id = type_id_;
-    sig.nullable = nullable_;
-    sig.length = parameter_;
-    return sig;
-  }
-
-  /**
    * @brief Get a nullable (but otherwise identical) version of this type.
    *
    * @return This Type's nullable counterpart (or this Type itself if already
@@ -313,34 +290,19 @@ class Type {
    **/
   virtual int getPrintWidth() const = 0;
 
-  /**
-   * @brief "Print" a value of this Type as a human-readable string.
-   * @warning It is an error to call this with a NULL value. This method prints
-   *          non-NULL values only.
-   *
-   * @param value A value of this Type.
-   * @return The human-readable string representation of value.
-   **/
-  virtual std::string printValueToString(const TypedValue &value) const = 0;
 
-  /**
-   * @brief Print the human-readable string representation of a value of this
-   *        type to a FILE stream.
-   * @warning It is an error to call this with a NULL value. This method prints
-   *          non-NULL values only.
-   *
-   * @param value A value of this Type.
-   * @param file An open FILE stream to print to.
-   * @param padding If nonzero, left-pad the printed value with spaces up to
-   *        this length. If padding is less than the number of characters
-   *        needed to print the value, then more than padding characters will
-   *        be printed (see getPrintWidth() for information about how long a
-   *        printed string may be).
-   **/
-  virtual void printValueToFile(const TypedValue &value,
+  virtual std::string printValueToString(const UntypedLiteral *value) const = 0;
+
+
+  virtual void printValueToFile(const UntypedLiteral *value,
                                 FILE *file,
                                 const int padding = 0) const;
 
+  virtual std::string printTypedValueToString(const TypedValue &value) const = 0;
+
+  virtual void printTypedValueToFile(const TypedValue &value,
+                                     FILE *file,
+                                     const int padding = 0) const = 0;
   /**
    * @brief Make a TypedValue of this Type.
    *
@@ -439,17 +401,51 @@ class Type {
   virtual TypedValue coerceValue(const TypedValue &original_value,
                                  const Type &original_type) const;
 
+  virtual std::size_t getHash() const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+
+  virtual bool checkValuesEqual(const UntypedLiteral *lhs,
+                                const UntypedLiteral *rhs) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  virtual UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  virtual std::size_t hashValue(const UntypedLiteral *value) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  virtual void destroyValue(UntypedLiteral *value_ptr) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  virtual CharStream marshallValue(const UntypedLiteral *value) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  virtual UntypedLiteral* unmarshallValue(const void *data,
+                                          const std::size_t length) const {
+    LOG(FATAL) << "Not implemented";
+
+  }
+
+  virtual UntypedLiteral* unmarshallValue(const TypedValue &value) const = 0;
+
+  virtual UntypedLiteral* unmarshallValue(TypedValue &&value) const = 0;
+
  protected:
   Type(const SuperTypeID super_type_id,
        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 parameter = 0)
+       const std::size_t maximum_byte_length)
       : 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) {
   }
@@ -457,7 +453,6 @@ 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_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/Type.proto
----------------------------------------------------------------------
diff --git a/types/Type.proto b/types/Type.proto
index ed8df36..b93f894 100644
--- a/types/Type.proto
+++ b/types/Type.proto
@@ -27,5 +27,10 @@ message Type {
   required TypeID type_id = 1;
   required bool nullable = 2;
   optional uint64 length = 3;
+  repeated GenericValue parameters = 4;
 }
 
+message GenericValue {
+  required Type type = 1;
+  required bytes data = 2;
+}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index 223d487..d60f701 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -22,6 +22,7 @@
 #include <cstddef>
 #include <string>
 
+#include "types/GenericValue.hpp"
 #include "types/Type.hpp"
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
@@ -42,7 +43,7 @@ const Type& TypeFactory::GetType(const TypeID id,
       << "Called TypeFactory::GetType() for a type which requires "
       << " a length parameter without specifying one.";
 
-  return *InvokeOnTypeID<TypeIDSelectorNonParameterized>(
+  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxInlinePod>>(
       id,
       [&](auto id) -> const Type* {  // NOLINT(build/c++11)
     return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable);
@@ -56,7 +57,7 @@ const Type& TypeFactory::GetType(const TypeID id,
       << "Provided a length parameter to TypeFactory::GetType() for "
       << "a type which does not take one.";
 
-  return *InvokeOnTypeID<TypeIDSelectorParameterized>(
+  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kParInlinePod, kParOutOfLinePod>>(
       id,
       [&](auto id) -> const Type* {  // NOLINT(build/c++11)
     return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable, length);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/TypeID.cpp
----------------------------------------------------------------------
diff --git a/types/TypeID.cpp b/types/TypeID.cpp
index afc9c2b..ce29455 100644
--- a/types/TypeID.cpp
+++ b/types/TypeID.cpp
@@ -33,6 +33,8 @@ const char *kTypeNames[] = {
   "Datetime",
   "DatetimeInterval",
   "YearMonthInterval",
+  "Array",
+  "MetaType",
   "NullType"
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/TypeID.hpp
----------------------------------------------------------------------
diff --git a/types/TypeID.hpp b/types/TypeID.hpp
index ecbdc9b..8203253 100644
--- a/types/TypeID.hpp
+++ b/types/TypeID.hpp
@@ -29,11 +29,20 @@
 namespace quickstep {
 
 /**
+ * @brief Categories of intermediate supertypes.
+ **/
+enum class SuperTypeID {
+  kNumeric = 0,  // Fixed-length numeric types (Int, Long, Float, Double)
+  kAsciiString,  // ASCII strings (Char, VarChar)
+  kOther         // Others (Date, Datetime, DatetimeInterval, YearMonthInterval)
+};
+
+/**
  * @brief Concrete Types.
  *
  * @note TypedValue assumes that this doesn't exceed 64 TypeIDs.
  **/
-enum TypeID : int {
+enum TypeID {
   kBool = 0,
   kInt,
   kLong,
@@ -45,15 +54,17 @@ enum TypeID : int {
   kDatetime,
   kDatetimeInterval,
   kYearMonthInterval,
+  kArray,
+  kMetaType,
   kNullType,
   kNumTypeIDs  // Not a real TypeID, exists for counting purposes.
 };
 
 enum MemoryLayout {
-  kCxxNativePod,
-  kParNativePod,
-  kParIndirectPod,
-  kGeneric
+  kCxxInlinePod,
+  kParInlinePod,
+  kParOutOfLinePod,
+  kCxxGeneric
 };
 
 /**
@@ -99,4 +110,15 @@ class TypeIDFactory {
 
 }  // namespace quickstep
 
+namespace std {
+
+template <>
+struct hash<quickstep::TypeID> {
+  size_t operator()(const quickstep::TypeID &arg) const {
+    return static_cast<typename std::underlying_type<quickstep::TypeID>::type>(arg);
+  }
+};
+
+}  // namespace std
+
 #endif  // QUICKSTEP_TYPES_TYPE_ID_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/ebf44cd2/types/TypeIDSelectors.hpp
----------------------------------------------------------------------
diff --git a/types/TypeIDSelectors.hpp b/types/TypeIDSelectors.hpp
index d75a887..6e4a2b0 100644
--- a/types/TypeIDSelectors.hpp
+++ b/types/TypeIDSelectors.hpp
@@ -23,6 +23,7 @@
 #include <type_traits>
 
 #include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
 #include "utility/meta/Common.hpp"
 
 #include "glog/logging.h"
@@ -42,7 +43,7 @@ struct TypeIDSelectorParameterized;
 struct TypeIDSelectorNonParameterized;
 
 template <TypeID ...candidates>
-struct TypeIDSelectorEqualsAny;
+struct TypeIDSelector;
 
 
 // Forward declaration
@@ -76,14 +77,14 @@ template <typename TypeIDConstant, typename FunctorT>
 struct TypeIDSelectorNumeric::Implementation<
     TypeIDConstant, FunctorT,
     std::enable_if_t<TypeIDTrait<TypeIDConstant::value>
-                         ::kStaticSuperTypeID == Type::kNumeric>> {
+                         ::kStaticSuperTypeID == SuperTypeID::kNumeric>> {
   inline static auto Invoke(const FunctorT &functor) {
     return functor(TypeIDConstant());
   }
 };
 
 template <TypeID ...candidates>
-struct TypeIDSelectorEqualsAny {
+struct TypeIDSelector {
   template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
   struct Implementation {
 #pragma GCC diagnostic push
@@ -99,7 +100,7 @@ struct TypeIDSelectorEqualsAny {
 
 template <TypeID ...candidates>
 template <typename TypeIDConstant, typename FunctorT>
-struct TypeIDSelectorEqualsAny<candidates...>::Implementation<
+struct TypeIDSelector<candidates...>::Implementation<
     TypeIDConstant, FunctorT,
     std::enable_if_t<
         meta::EqualsAny<TypeIDConstant,
@@ -109,10 +110,8 @@ struct TypeIDSelectorEqualsAny<candidates...>::Implementation<
   }
 };
 
-namespace internal {
-
-template <bool require_parameterized>
-struct TypeIDSelectorParameterizedHelper {
+template <MemoryLayout ...candidates>
+struct TypeIDSelectorMemoryLayout {
   template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
   struct Implementation {
 #pragma GCC diagnostic push
@@ -126,24 +125,49 @@ struct TypeIDSelectorParameterizedHelper {
   };
 };
 
-template <bool require_non_parameterized>
+template <MemoryLayout ...candidates>
 template <typename TypeIDConstant, typename FunctorT>
-struct TypeIDSelectorParameterizedHelper<require_non_parameterized>::Implementation<
+struct TypeIDSelectorMemoryLayout<candidates...>::Implementation<
     TypeIDConstant, FunctorT,
-    std::enable_if_t<TypeIDTrait<TypeIDConstant::value>::kParameterized
-                         ^ require_non_parameterized>> {
+    std::enable_if_t<
+        meta::EqualsAny<
+            std::integral_constant<MemoryLayout,
+                                   TypeIDTrait<TypeIDConstant::value>::kMemoryLayout>,
+            std::integral_constant<MemoryLayout, candidates>...>::value>> {
   inline static auto Invoke(const FunctorT &functor) {
     return functor(TypeIDConstant());
   }
 };
 
-}  // namespace internal
-
-struct TypeIDSelectorNonParameterized
-    : internal::TypeIDSelectorParameterizedHelper<true> {};
-
-struct TypeIDSelectorParameterized
-    : internal::TypeIDSelectorParameterizedHelper<false> {};
+//namespace internal {
+//
+//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)];
+//    }
+//#pragma GCC diagnostic pop
+//  };
+//};
+//
+//template <bool require_non_parameterized>
+//template <typename TypeIDConstant, typename FunctorT>
+//struct TypeIDSelectorParameterizedHelper<require_non_parameterized>::Implementation<
+//    TypeIDConstant, FunctorT,
+//    std::enable_if_t<TypeIDTrait<TypeIDConstant::value>::kIsParPod
+//                         ^ require_non_parameterized>> {
+//  inline static auto Invoke(const FunctorT &functor) {
+//    return functor(TypeIDConstant());
+//  }
+//};
+//
+//}  // namespace internal
 
 /** @} */