You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by ji...@apache.org on 2017/10/10 18:26:00 UTC

[30/38] incubator-quickstep git commit: Continue the work

Continue the work


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

Branch: refs/heads/refactor-type
Commit: a7ccb4679fd9f183244a2c471cfacc346d8fa13a
Parents: 1792b9f
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Mon Oct 2 15:36:22 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 expressions/table_generator/GenerateSeries.hpp  |  10 +-
 parser/ParseLiteralValue.cpp                    |  12 +-
 .../expressions/BinaryExpression.cpp            |  14 +-
 .../expressions/BinaryExpression.hpp            |  22 +-
 query_optimizer/expressions/Scalar.hpp          |  14 +
 query_optimizer/expressions/ScalarLiteral.cpp   |  16 +-
 query_optimizer/expressions/ScalarLiteral.hpp   |  18 +-
 query_optimizer/expressions/UnaryExpression.cpp |  14 +-
 query_optimizer/expressions/UnaryExpression.hpp |  20 +-
 query_optimizer/resolver/Resolver.cpp           |  45 ++--
 relational_operators/TextScanOperator.cpp       |   2 +-
 storage/SMAIndexSubBlock.cpp                    |   2 +-
 types/ArrayType.hpp                             |   4 +-
 types/BoolType.cpp                              |   4 +-
 types/BoolType.hpp                              |   4 +-
 types/CharType.cpp                              |   8 +-
 types/CharType.hpp                              |   8 +-
 types/DateType.cpp                              |   4 +-
 types/DateType.hpp                              |   4 +-
 types/DatetimeIntervalType.cpp                  |   4 +-
 types/DatetimeIntervalType.hpp                  |   4 +-
 types/DatetimeType.cpp                          |   4 +-
 types/DatetimeType.hpp                          |   4 +-
 types/DoubleType.cpp                            |   4 +-
 types/DoubleType.hpp                            |   4 +-
 types/FloatType.cpp                             |   4 +-
 types/FloatType.hpp                             |   4 +-
 types/GenericValue.hpp                          |  51 +++-
 types/IntType.cpp                               |   4 +-
 types/IntType.hpp                               |   4 +-
 types/LongType.cpp                              |   4 +-
 types/LongType.hpp                              |   4 +-
 types/MetaType.hpp                              |   4 +-
 types/NullType.hpp                              |   4 +-
 types/NumericSuperType.hpp                      |   4 +-
 types/Type.cpp                                  |   4 +-
 types/Type.hpp                                  |  38 +--
 types/TypeSynthesizer.hpp                       | 257 ++++++++++++-------
 types/VarCharType.cpp                           |   8 +-
 types/VarCharType.hpp                           |   8 +-
 types/YearMonthIntervalType.cpp                 |   4 +-
 types/YearMonthIntervalType.hpp                 |   4 +-
 types/operations/OperationFactory.cpp           |  52 ++--
 types/operations/OperationFactory.hpp           |  20 +-
 .../operations/comparisons/BasicComparison.hpp  |   4 +-
 .../unary_operations/CastOperation.hpp          |   2 +-
 46 files changed, 413 insertions(+), 324 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/expressions/table_generator/GenerateSeries.hpp
----------------------------------------------------------------------
diff --git a/expressions/table_generator/GenerateSeries.hpp b/expressions/table_generator/GenerateSeries.hpp
index d749810..19523f5 100644
--- a/expressions/table_generator/GenerateSeries.hpp
+++ b/expressions/table_generator/GenerateSeries.hpp
@@ -118,11 +118,11 @@ class GenerateSeries : public GeneratorFunction {
     DCHECK(args.size() == 2 || args.size() == 3);
 
     // Coerce all arguments to the unified type.
-    TypedValue start = type.coerceValue(args[0], *arg_types[0]);
-    TypedValue end = type.coerceValue(args[1], *arg_types[1]);
-    TypedValue step =
-        args.size() > 2 ? type.coerceValue(args[2], *arg_types[2])
-                        : type.coerceValue(TypedValue(1), TypeFactory::GetType(TypeID::kInt));
+    TypedValue start = type.coerceTypedValue(args[0], *arg_types[0]);
+    TypedValue end = type.coerceTypedValue(args[1], *arg_types[1]);
+    TypedValue step = args.size() > 2
+        ? type.coerceTypedValue(args[2], *arg_types[2])
+        : type.coerceTypedValue(TypedValue(1), TypeFactory::GetType(TypeID::kInt));
 
     // Check that step is not 0, and (end - start) / step is positive
     const GreaterComparison &gt_comparator = GreaterComparison::Instance();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/parser/ParseLiteralValue.cpp
----------------------------------------------------------------------
diff --git a/parser/ParseLiteralValue.cpp b/parser/ParseLiteralValue.cpp
index 04e8a55..caa21e3 100644
--- a/parser/ParseLiteralValue.cpp
+++ b/parser/ParseLiteralValue.cpp
@@ -88,14 +88,14 @@ TypedValue NumericParseLiteralValue::concretize(
   TypedValue parsed_value;
   if ((type_hint != nullptr)
       && (type_hint->getSuperTypeID() == SuperTypeID::kNumeric)
-      && (type_hint->parseValueFromString(numeric_string_, &parsed_value))) {
+      && (type_hint->parseTypedValueFromString(numeric_string_, &parsed_value))) {
     *concretized_type = &(type_hint->getNonNullableVersion());
     return parsed_value;
   }
 
   if (float_like_) {
     *concretized_type = &DoubleType::InstanceNonNullable();
-    CHECK((*concretized_type)->parseValueFromString(numeric_string_, &parsed_value))
+    CHECK((*concretized_type)->parseTypedValueFromString(numeric_string_, &parsed_value))
         << "Failed to parse double from numeric string \""
         << numeric_string_ << "\"";
     return parsed_value;
@@ -153,7 +153,7 @@ TypedValue StringParseLiteralValue::concretize(const Type *type_hint,
   if (explicit_type_ != nullptr) {
     if ((type_hint != nullptr) && (type_hint->isSafelyCoercibleFrom(*explicit_type_))) {
       *concretized_type = type_hint;
-      return type_hint->coerceValue(explicit_parsed_value_, *explicit_type_);
+      return type_hint->coerceTypedValue(explicit_parsed_value_, *explicit_type_);
     } else {
       *concretized_type = explicit_type_;
       return explicit_parsed_value_;
@@ -161,12 +161,12 @@ TypedValue StringParseLiteralValue::concretize(const Type *type_hint,
   } else {
     TypedValue parsed_value;
     if ((type_hint != nullptr)
-        && (type_hint->parseValueFromString(value_->value(), &parsed_value))) {
+        && (type_hint->parseTypedValueFromString(value_->value(), &parsed_value))) {
       *concretized_type = &(type_hint->getNonNullableVersion());
       return parsed_value;
     } else {
       *concretized_type = &VarCharType::InstanceNonNullable(value_->value().length());
-      CHECK((*concretized_type)->parseValueFromString(value_->value(), &parsed_value));
+      CHECK((*concretized_type)->parseTypedValueFromString(value_->value(), &parsed_value));
       return parsed_value;
     }
   }
@@ -189,7 +189,7 @@ std::string StringParseLiteralValue::generateName() const {
 
 bool StringParseLiteralValue::tryExplicitTypeParse() {
   DCHECK(explicit_type_ != nullptr);
-  return explicit_type_->parseValueFromString(value_->value(), &explicit_parsed_value_);
+  return explicit_type_->parseTypedValueFromString(value_->value(), &explicit_parsed_value_);
 }
 
 void StringParseLiteralValue::getFieldStringItems(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/BinaryExpression.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/BinaryExpression.cpp b/query_optimizer/expressions/BinaryExpression.cpp
index 24fee40..634c189 100644
--- a/query_optimizer/expressions/BinaryExpression.cpp
+++ b/query_optimizer/expressions/BinaryExpression.cpp
@@ -58,8 +58,7 @@ ExpressionPtr BinaryExpression::copyWithNewChildren(
       operation_,
       std::static_pointer_cast<const Scalar>(new_children[0]),
       std::static_pointer_cast<const Scalar>(new_children[1]),
-      static_arguments_,
-      static_argument_types_);
+      static_arguments_);
 }
 
 std::vector<AttributeReferencePtr> BinaryExpression::getReferencedAttributes() const {
@@ -80,7 +79,7 @@ std::vector<AttributeReferencePtr> BinaryExpression::getReferencedAttributes() c
       operation_,
       left_->concretize(substitution_map),
       right_->concretize(substitution_map),
-      static_arguments_);
+      static_arguments_cache_);
 }
 
 std::size_t BinaryExpression::computeHash() const {
@@ -94,10 +93,8 @@ std::size_t BinaryExpression::computeHash() const {
   hash_code = CombineHashes(hash_code, left_hash);
   hash_code = CombineHashes(hash_code, right_hash);
 
-  for (const TypedValue &st_arg : *static_arguments_) {
-    if (!st_arg.isNull()) {
-      hash_code = CombineHashes(hash_code, st_arg.getHash());
-    }
+  for (const GenericValue &st_arg : *static_arguments_) {
+    hash_code = CombineHashes(hash_code, st_arg.getHash());
   }
   return hash_code;
 }
@@ -147,8 +144,7 @@ void BinaryExpression::getFieldStringItems(
     container_child_fields->emplace_back();
     for (std::size_t i = 0; i < static_arguments_->size(); ++i) {
       container_child_fields->back().emplace_back(
-          ScalarLiteral::Create(static_arguments_->at(i),
-                                *static_argument_types_->at(i)));
+          ScalarLiteral::Create(static_arguments_->at(i)));
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/BinaryExpression.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/BinaryExpression.hpp b/query_optimizer/expressions/BinaryExpression.hpp
index 6ee6690..5e59e48 100644
--- a/query_optimizer/expressions/BinaryExpression.hpp
+++ b/query_optimizer/expressions/BinaryExpression.hpp
@@ -31,6 +31,7 @@
 #include "query_optimizer/expressions/Expression.hpp"
 #include "query_optimizer/expressions/ExpressionType.hpp"
 #include "query_optimizer/expressions/Scalar.hpp"
+#include "types/GenericValue.hpp"
 #include "types/operations/OperationSignature.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
 #include "utility/Macros.hpp"
@@ -101,15 +102,13 @@ class BinaryExpression : public Scalar {
       const BinaryOperationPtr &operation,
       const ScalarPtr &left,
       const ScalarPtr &right,
-      const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
-      const std::shared_ptr<const std::vector<const Type*>> &static_argument_types) {
+      const std::shared_ptr<const std::vector<GenericValue>> &static_arguments) {
     return BinaryExpressionPtr(
         new BinaryExpression(op_signature,
                              operation,
                              left,
                              right,
-                             static_arguments,
-                             static_argument_types));
+                             static_arguments));
   }
 
   static BinaryExpressionPtr Create(
@@ -122,8 +121,7 @@ class BinaryExpression : public Scalar {
                              operation,
                              left,
                              right,
-                             std::make_shared<const std::vector<TypedValue>>(),
-                             std::make_shared<const std::vector<const Type*>>()));
+                             std::make_shared<const std::vector<GenericValue>>()));
   }
 
  protected:
@@ -142,17 +140,16 @@ class BinaryExpression : public Scalar {
                    const BinaryOperationPtr &operation,
                    const ScalarPtr &left,
                    const ScalarPtr &right,
-                   const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
-                   const std::shared_ptr<const std::vector<const Type*>> &static_argument_types)
+                   const std::shared_ptr<const std::vector<GenericValue>> &static_arguments)
       : op_signature_(op_signature),
         operation_(operation),
         left_(left),
         right_(right),
         static_arguments_(static_arguments),
-        static_argument_types_(static_argument_types),
+        static_arguments_cache_(ToTypedValue(*static_arguments_)),
         result_type_(*(operation_->getResultType(left_->getValueType(),
                                                  right_->getValueType(),
-                                                 *static_arguments))) {
+                                                 *static_arguments_cache_))) {
     addChild(left);
     addChild(right);
   }
@@ -161,8 +158,9 @@ class BinaryExpression : public Scalar {
   const BinaryOperationPtr operation_;
   const ScalarPtr left_;
   const ScalarPtr right_;
-  const std::shared_ptr<const std::vector<TypedValue>> static_arguments_;
-  const std::shared_ptr<const std::vector<const Type*>> static_argument_types_;
+  const std::shared_ptr<const std::vector<GenericValue>> static_arguments_;
+  // TODO(refactor-type): Remove this.
+  const std::shared_ptr<const std::vector<TypedValue>> static_arguments_cache_;
   const Type &result_type_;
 
   DISALLOW_COPY_AND_ASSIGN(BinaryExpression);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/Scalar.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/Scalar.hpp b/query_optimizer/expressions/Scalar.hpp
index a163b21..23df7c1 100644
--- a/query_optimizer/expressions/Scalar.hpp
+++ b/query_optimizer/expressions/Scalar.hpp
@@ -29,6 +29,10 @@
 #include "utility/HashError.hpp"
 #include "utility/Macros.hpp"
 
+// TODO(refactor-type): Remove this.
+#include "types/TypedValue.hpp"
+#include "types/GenericValue.hpp"
+
 namespace quickstep {
 
 class CatalogAttribute;
@@ -107,6 +111,16 @@ class Scalar : public Expression {
     throw HashNotSupported("Unsupported computeHash() in " + getName());
   }
 
+  // TODO(refactor-type): Remove this.
+  inline static std::shared_ptr<const std::vector<TypedValue>> ToTypedValue(
+      const std::vector<GenericValue> &input) {
+    std::vector<TypedValue> values;
+    for (const auto &item : input) {
+      values.emplace_back(item.toTypedValue());
+    }
+    return std::make_shared<const std::vector<TypedValue>>(std::move(values));
+  }
+
  private:
   mutable std::unique_ptr<std::size_t> hash_cache_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/ScalarLiteral.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/ScalarLiteral.cpp b/query_optimizer/expressions/ScalarLiteral.cpp
index 278e2cc..4dd7ba3 100644
--- a/query_optimizer/expressions/ScalarLiteral.cpp
+++ b/query_optimizer/expressions/ScalarLiteral.cpp
@@ -40,18 +40,18 @@ namespace optimizer {
 namespace expressions {
 
 const Type& ScalarLiteral::getValueType() const {
-  return value_type_;
+  return value_.getType();
 }
 
 ExpressionPtr ScalarLiteral::copyWithNewChildren(
     const std::vector<ExpressionPtr> &new_children) const {
   DCHECK_EQ(new_children.size(), children().size());
-  return ScalarLiteral::Create(value_, value_type_);
+  return ScalarLiteral::Create(value_);
 }
 
 ::quickstep::Scalar *ScalarLiteral::concretize(
     const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const {
-  return new ::quickstep::ScalarLiteral(value_, value_type_);
+  return new ::quickstep::ScalarLiteral(value_.toTypedValue(), value_.getType());
 }
 
 std::size_t ScalarLiteral::computeHash() const {
@@ -64,12 +64,8 @@ std::size_t ScalarLiteral::computeHash() const {
 
 bool ScalarLiteral::equals(const ScalarPtr &other) const {
   ScalarLiteralPtr lit;
-  if (SomeScalarLiteral::MatchesWithConditionalCast(other, &lit) &&
-      value_type_.equals(lit->value_type_)) {
-    if (value_.isNull() || lit->value_.isNull()) {
-      return value_.isNull() && lit->value_.isNull();
-    }
-    return value_.fastEqualCheck(lit->value_);
+  if (SomeScalarLiteral::MatchesWithConditionalCast(other, &lit)) {
+    return value_.equals(lit->value_);
   }
   return false;
 }
@@ -85,7 +81,7 @@ void ScalarLiteral::getFieldStringItems(
   if (value_.isNull()) {
     inline_field_values->push_back("NULL");
   } else {
-    inline_field_values->push_back(value_type_.printTypedValueToString(value_));
+    inline_field_values->push_back(value_.toString());
   }
 
   inline_field_names->push_back("type");

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/ScalarLiteral.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/ScalarLiteral.hpp b/query_optimizer/expressions/ScalarLiteral.hpp
index bff52bb..180ae39 100644
--- a/query_optimizer/expressions/ScalarLiteral.hpp
+++ b/query_optimizer/expressions/ScalarLiteral.hpp
@@ -32,7 +32,7 @@
 #include "query_optimizer/expressions/Expression.hpp"
 #include "query_optimizer/expressions/ExpressionType.hpp"
 #include "query_optimizer/expressions/Scalar.hpp"
-#include "types/TypedValue.hpp"
+#include "types/GenericValue.hpp"
 #include "utility/Macros.hpp"
 
 namespace quickstep {
@@ -70,7 +70,7 @@ class ScalarLiteral : public Scalar {
   /**
    * @return The literal value.
    */
-  const TypedValue& value() const { return value_; }
+  const GenericValue& value() const { return value_; }
 
   ExpressionPtr copyWithNewChildren(
       const std::vector<ExpressionPtr> &new_children) const override;
@@ -89,9 +89,8 @@ class ScalarLiteral : public Scalar {
    * @param literal_value The literal value.
    * @return An immutable ScalarLiteral with the given literal value.
    */
-  static const ScalarLiteralPtr Create(const TypedValue &literal_value,
-                                       const Type &literal_value_type) {
-    return ScalarLiteralPtr(new ScalarLiteral(literal_value, literal_value_type));
+  static const ScalarLiteralPtr Create(const GenericValue &literal_value) {
+    return ScalarLiteralPtr(new ScalarLiteral(literal_value));
   }
 
  protected:
@@ -106,13 +105,10 @@ class ScalarLiteral : public Scalar {
       std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
 
  private:
-  ScalarLiteral(const TypedValue &literal_value,
-                const Type &literal_value_type)
-      : value_(literal_value),
-        value_type_(literal_value_type) {}
+  ScalarLiteral(const GenericValue &literal_value)
+      : value_(literal_value) {}
 
-  const TypedValue value_;
-  const Type &value_type_;
+  const GenericValue &value_;
   DISALLOW_COPY_AND_ASSIGN(ScalarLiteral);
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/UnaryExpression.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/UnaryExpression.cpp b/query_optimizer/expressions/UnaryExpression.cpp
index e1ad014..38cb65c 100644
--- a/query_optimizer/expressions/UnaryExpression.cpp
+++ b/query_optimizer/expressions/UnaryExpression.cpp
@@ -52,8 +52,7 @@ ExpressionPtr UnaryExpression::copyWithNewChildren(
       op_signature_,
       operation_,
       std::static_pointer_cast<const Scalar>(new_children[0]),
-      static_arguments_,
-      static_argument_types_);
+      static_arguments_);
 }
 
 ::quickstep::Scalar* UnaryExpression::concretize(
@@ -62,16 +61,14 @@ ExpressionPtr UnaryExpression::copyWithNewChildren(
       op_signature_,
       operation_,
       operand_->concretize(substitution_map),
-      static_arguments_);
+      static_arguments_cache_);
 }
 
 std::size_t UnaryExpression::computeHash() const {
   std::size_t hash_code = CombineHashes(op_signature_->hash(),
                                         operand_->hash());
-  for (const TypedValue &st_arg : *static_arguments_) {
-    if (!st_arg.isNull()) {
-      hash_code = CombineHashes(hash_code, st_arg.getHash());
-    }
+  for (const GenericValue &st_arg : *static_arguments_) {
+    hash_code = CombineHashes(hash_code, st_arg.getHash());
   }
   return hash_code;
 }
@@ -107,8 +104,7 @@ void UnaryExpression::getFieldStringItems(
     container_child_fields->emplace_back();
     for (std::size_t i = 0; i < static_arguments_->size(); ++i) {
       container_child_fields->back().emplace_back(
-          ScalarLiteral::Create(static_arguments_->at(i),
-                                *static_argument_types_->at(i)));
+          ScalarLiteral::Create(static_arguments_->at(i)));
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/UnaryExpression.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/UnaryExpression.hpp b/query_optimizer/expressions/UnaryExpression.hpp
index bbb1841..9c3bf17 100644
--- a/query_optimizer/expressions/UnaryExpression.hpp
+++ b/query_optimizer/expressions/UnaryExpression.hpp
@@ -31,6 +31,7 @@
 #include "query_optimizer/expressions/Expression.hpp"
 #include "query_optimizer/expressions/ExpressionType.hpp"
 #include "query_optimizer/expressions/Scalar.hpp"
+#include "types/GenericValue.hpp"
 #include "types/operations/OperationSignature.hpp"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
 #include "utility/Macros.hpp"
@@ -101,14 +102,12 @@ class UnaryExpression : public Scalar {
       const OperationSignaturePtr &op_signature,
       const UnaryOperationPtr &operation,
       const ScalarPtr &operand,
-      const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
-      const std::shared_ptr<const std::vector<const Type*>> &static_argument_types) {
+      const std::shared_ptr<const std::vector<GenericValue>> &static_arguments) {
     return UnaryExpressionPtr(
         new UnaryExpression(op_signature,
                             operation,
                             operand,
-                            static_arguments,
-                            static_argument_types));
+                            static_arguments));
   }
 
  protected:
@@ -126,22 +125,23 @@ class UnaryExpression : public Scalar {
   UnaryExpression(const OperationSignaturePtr &op_signature,
                   const UnaryOperationPtr &operation,
                   const ScalarPtr &operand,
-                  const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
-                  const std::shared_ptr<const std::vector<const Type*>> &static_argument_types)
+                  const std::shared_ptr<const std::vector<GenericValue>> &static_arguments)
       : op_signature_(op_signature),
         operation_(operation),
         operand_(operand),
         static_arguments_(static_arguments),
-        static_argument_types_(static_argument_types),
-        result_type_(*(operation_->getResultType(operand_->getValueType(), *static_arguments_))) {
+        static_arguments_cache_(ToTypedValue(*static_arguments_)),
+        result_type_(*(operation_->getResultType(operand_->getValueType(),
+                                                 *static_arguments_cache_))) {
     addChild(operand);
   }
 
   const OperationSignaturePtr op_signature_;
   const UnaryOperationPtr operation_;
   const ScalarPtr operand_;
-  const std::shared_ptr<const std::vector<TypedValue>> static_arguments_;
-  const std::shared_ptr<const std::vector<const Type*>> static_argument_types_;
+  const std::shared_ptr<const std::vector<GenericValue>> static_arguments_;
+  // TODO(refactor-type): Remove this.
+  const std::shared_ptr<const std::vector<TypedValue>> static_arguments_cache_;
   const Type &result_type_;
 
   DISALLOW_COPY_AND_ASSIGN(UnaryExpression);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 7c257bb..1ed6b2e 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -115,6 +115,7 @@
 #include "query_optimizer/resolver/NameResolver.hpp"
 #include "storage/StorageBlockLayout.pb.h"
 #include "storage/StorageConstants.hpp"
+#include "types/GenericValue.hpp"
 #include "types/IntType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
@@ -1070,6 +1071,7 @@ L::LogicalPtr Resolver::resolveInsertTuple(
   std::vector<E::ScalarLiteralPtr> resolved_column_values;
   std::vector<E::AttributeReferencePtr>::size_type aid = 0;
   for (const ParseScalarLiteral &parse_literal_value : parse_column_values) {
+    const Type &attribute_type = relation_attributes[aid]->getValueType();
     E::ScalarLiteralPtr resolved_literal_value;
     ExpressionResolutionInfo expr_resolution_info(
         name_resolver,
@@ -1078,30 +1080,25 @@ L::LogicalPtr Resolver::resolveInsertTuple(
     // When resolving the literal, use the attribute's Type as a hint.
     CHECK(E::SomeScalarLiteral::MatchesWithConditionalCast(
         resolveExpression(parse_literal_value,
-                          &(relation_attributes[aid]->getValueType()),
+                          &attribute_type,
                           &expr_resolution_info),
         &resolved_literal_value));
 
     // Check that the resolved Type is safely coercible to the attribute's
     // Type.
-    if (!relation_attributes[aid]->getValueType().isSafelyCoercibleFrom(
-            resolved_literal_value->getValueType())) {
+    if (!attribute_type.isSafelyCoercibleFrom(resolved_literal_value->getValueType())) {
       THROW_SQL_ERROR_AT(&parse_literal_value)
           << "The assigned value for the column "
           << relation_attributes[aid]->attribute_name() << " has the type "
           << resolved_literal_value->getValueType().getName()
           << ", which cannot be safely coerced to the column's type "
-          << relation_attributes[aid]->getValueType().getName();
+          << attribute_type.getName();
     }
 
     // If the Type is not exactly right (but is safely coercible), coerce it.
-    if (!resolved_literal_value->getValueType().equals(
-            relation_attributes[aid]->getValueType())) {
+    if (!resolved_literal_value->getValueType().equals(attribute_type)) {
       resolved_literal_value = E::ScalarLiteral::Create(
-          relation_attributes[aid]->getValueType().coerceValue(
-              resolved_literal_value->value(),
-              resolved_literal_value->getValueType()),
-          relation_attributes[aid]->getValueType());
+          resolved_literal_value->value().coerce(attribute_type));
     }
 
     resolved_column_values.push_back(resolved_literal_value);
@@ -1116,8 +1113,7 @@ L::LogicalPtr Resolver::resolveInsertTuple(
     }
     // Create a NULL value.
     resolved_column_values.push_back(E::ScalarLiteral::Create(
-        relation_attributes[aid]->getValueType().makeNullValue(),
-        relation_attributes[aid]->getValueType()));
+        GenericValue(relation_attributes[aid]->getValueType())));
     ++aid;
   }
 
@@ -2452,7 +2448,7 @@ E::ScalarPtr Resolver::resolveExpression(
       const Type *concrete_type = nullptr;
       TypedValue concrete = parse_literal_scalar.literal_value()
           ->concretize(type_hint, &concrete_type);
-      return E::ScalarLiteral::Create(std::move(concrete), *concrete_type);
+      return E::ScalarLiteral::Create(GenericValue(*concrete_type, concrete));
     }
     case ParseExpression::kSearchedCaseExpression: {
       const ParseSearchedCaseExpression &parse_searched_case_expression =
@@ -2507,7 +2503,6 @@ E::ScalarPtr Resolver::resolveArray(
 //
 //    // Currently we only support homogeneous array with literal values.
 //  }
-
   LOG(FATAL) << "Not supported";
 }
 
@@ -2785,22 +2780,22 @@ E::ScalarPtr Resolver::resolveScalarFunction(
     argument_types.emplace_back(&argument->getValueType());
   }
 
-  std::vector<TypedValue> static_arguments;
+  std::vector<GenericValue> static_arguments;
   for (std::size_t i = first_static_argument_position; i < arity; ++i) {
     static_arguments.emplace_back(
         std::static_pointer_cast<const E::ScalarLiteral>(
             resolved_arguments[i])->value());
-    DCHECK(static_arguments.back().getTypeID() == argument_types[i]->getTypeID());
+    DCHECK(static_arguments.back().getType().getTypeID() == argument_types[i]->getTypeID());
   }
 
   std::shared_ptr<const std::vector<const Type*>> coerced_argument_types;
-  std::shared_ptr<const std::vector<TypedValue>> coerced_static_arguments;
+  std::shared_ptr<const std::vector<GenericValue>> coerced_static_arguments;
   std::string message;
   const OperationSignaturePtr op_signature =
       OperationFactory::Instance().resolveOperation(
           function_name,
           std::make_shared<const std::vector<const Type*>>(std::move(argument_types)),
-          std::make_shared<const std::vector<TypedValue>>(std::move(static_arguments)),
+          std::make_shared<const std::vector<GenericValue>>(std::move(static_arguments)),
           &coerced_argument_types,
           &coerced_static_arguments,
           &message);
@@ -2815,11 +2810,7 @@ E::ScalarPtr Resolver::resolveScalarFunction(
   }
 
   // TODO: add cast if neccessary.
-
-  const auto coerced_static_argument_types =
-      std::make_shared<const std::vector<const Type*>>(
-          coerced_argument_types->begin() + op_signature->getNonStaticArity(),
-          coerced_argument_types->end());
+  (void)coerced_argument_types;
 
   const OperationPtr operation =
       OperationFactory::Instance().getOperation(op_signature);
@@ -2829,16 +2820,14 @@ E::ScalarPtr Resolver::resolveScalarFunction(
           op_signature,
           std::static_pointer_cast<const UnaryOperation>(operation),
           resolved_arguments[0],
-          coerced_static_arguments,
-          coerced_static_argument_types);
+          coerced_static_arguments);
     case Operation::kBinaryOperation:
       return E::BinaryExpression::Create(
           op_signature,
           std::static_pointer_cast<const BinaryOperation>(operation),
           resolved_arguments[0],
           resolved_arguments[1],
-          coerced_static_arguments,
-          coerced_static_argument_types);
+          coerced_static_arguments);
     default: {
       const auto operation_id =
          static_cast<std::underlying_type_t<Operation::OperationSuperTypeID>>(
@@ -3337,7 +3326,7 @@ void Resolver::rewriteIfOrdinalReference(
   if (E::SomeScalarLiteral::MatchesWithConditionalCast(*expression, &literal) &&
       literal->getValueType().getTypeID() == kInt &&
       !literal->value().isNull()) {
-    int position = literal->value().getLiteral<int>();
+    int position = literal->value().getLiteral<kInt>();
     if (position < 1 ||
         position > static_cast<int>(
                        select_list_info->select_list_expressions.size())) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/relational_operators/TextScanOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/TextScanOperator.cpp b/relational_operators/TextScanOperator.cpp
index 66137d8..3885888 100644
--- a/relational_operators/TextScanOperator.cpp
+++ b/relational_operators/TextScanOperator.cpp
@@ -474,7 +474,7 @@ std::vector<TypedValue> TextScanWorkOrder::parseRow(const char **row_ptr,
       attribute_values.emplace_back(attr.getType().makeNullValue());
     } else {
       attribute_values.emplace_back();
-      if (!attr.getType().parseValueFromString(value_str, &(attribute_values.back()))) {
+      if (!attr.getType().parseTypedValueFromString(value_str, &(attribute_values.back()))) {
         // Do not abort if one of the row is faulty.
         *is_faulty = true;
         LOG(INFO) << "Failed to parse value.";

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/storage/SMAIndexSubBlock.cpp
----------------------------------------------------------------------
diff --git a/storage/SMAIndexSubBlock.cpp b/storage/SMAIndexSubBlock.cpp
index 96a744e..5a8a747 100644
--- a/storage/SMAIndexSubBlock.cpp
+++ b/storage/SMAIndexSubBlock.cpp
@@ -640,7 +640,7 @@ Selectivity SMAIndexSubBlock::getSelectivityForPredicate(const ComparisonPredica
       SMAPredicate *replacement = new SMAPredicate(
           sma_predicate->attribute,
           sma_predicate->comparison,
-          attribute_type.coerceValue(sma_predicate->literal, literal_type));
+          attribute_type.coerceTypedValue(sma_predicate->literal, literal_type));
       sma_predicate.reset(replacement);
     } else {
       // The literal type cannot be converted, so do not evaluate with the SMA.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/ArrayType.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp
index 1c66ed2..fe81c3e 100644
--- a/types/ArrayType.hpp
+++ b/types/ArrayType.hpp
@@ -46,8 +46,8 @@ class ArrayType : public TypeSynthesizer<kArray> {
 
   std::string printValueToString(const UntypedLiteral *value) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override {
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override {
     return false;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/BoolType.cpp
----------------------------------------------------------------------
diff --git a/types/BoolType.cpp b/types/BoolType.cpp
index 9680770..7687f06 100644
--- a/types/BoolType.cpp
+++ b/types/BoolType.cpp
@@ -47,8 +47,8 @@ void BoolType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value) ? "true" : "false");
 }
 
-bool BoolType::parseValueFromString(const std::string &value_string,
-                                    TypedValue *value) const {
+bool BoolType::parseTypedValueFromString(const std::string &value_string,
+                                         TypedValue *value) const {
   const std::string lo_value = ToLower(value_string);
   if (lo_value == "true") {
     *value = TypedValue(true);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/BoolType.hpp
----------------------------------------------------------------------
diff --git a/types/BoolType.hpp b/types/BoolType.hpp
index 2ba380a..ed819ae 100644
--- a/types/BoolType.hpp
+++ b/types/BoolType.hpp
@@ -54,8 +54,8 @@ class BoolType : public NumericSuperType<kBool> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit BoolType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/CharType.cpp
----------------------------------------------------------------------
diff --git a/types/CharType.cpp b/types/CharType.cpp
index ea3d00e..eb3f64a 100644
--- a/types/CharType.cpp
+++ b/types/CharType.cpp
@@ -87,8 +87,8 @@ void CharType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value).getOutOfLineData());
 }
 
-bool CharType::parseValueFromString(const std::string &value_string,
-                                    TypedValue *value) const {
+bool CharType::parseTypedValueFromString(const std::string &value_string,
+                                         TypedValue *value) const {
   if (value_string.length() > length_) {
     return false;
   }
@@ -102,8 +102,8 @@ bool CharType::parseValueFromString(const std::string &value_string,
   return true;
 }
 
-TypedValue CharType::coerceValue(const TypedValue &original_value,
-                                 const Type &original_type) const {
+TypedValue CharType::coerceTypedValue(const TypedValue &original_value,
+                                      const Type &original_type) const {
   DCHECK(isCoercibleFrom(original_type))
       << "Can't coerce value of Type " << original_type.getName()
       << " to Type " << getName();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/CharType.hpp
----------------------------------------------------------------------
diff --git a/types/CharType.hpp b/types/CharType.hpp
index 32b0c7a..81a32ff 100644
--- a/types/CharType.hpp
+++ b/types/CharType.hpp
@@ -59,11 +59,11 @@ class CharType : public AsciiStringSuperType<kChar> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
-  TypedValue coerceValue(const TypedValue &original_value,
-                         const Type &original_type) const override;
+  TypedValue coerceTypedValue(const TypedValue &original_value,
+                              const Type &original_type) const override;
 
  private:
   CharType(const bool nullable, const std::size_t length)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DateType.cpp
----------------------------------------------------------------------
diff --git a/types/DateType.cpp b/types/DateType.cpp
index dcd779d..a88b5bd 100644
--- a/types/DateType.cpp
+++ b/types/DateType.cpp
@@ -75,8 +75,8 @@ std::string DateType::printValueToString(const UntypedLiteral *value) const {
   return std::string(datebuf);
 }
 
-bool DateType::parseValueFromString(const std::string &value_string,
-                                    TypedValue *value) const {
+bool DateType::parseTypedValueFromString(const std::string &value_string,
+                                         TypedValue *value) const {
   std::int32_t year;
   std::uint32_t month, day;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DateType.hpp
----------------------------------------------------------------------
diff --git a/types/DateType.hpp b/types/DateType.hpp
index b7d1820..1c9eaf9 100644
--- a/types/DateType.hpp
+++ b/types/DateType.hpp
@@ -61,8 +61,8 @@ class DateType : public TypeSynthesizer<kDate> {
    *       fail if there are any "extra" characters at the end of the string
    *       after a parsable ISO-8601 date.
    **/
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit DateType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DatetimeIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.cpp b/types/DatetimeIntervalType.cpp
index e419ce3..a4b2896 100644
--- a/types/DatetimeIntervalType.cpp
+++ b/types/DatetimeIntervalType.cpp
@@ -110,8 +110,8 @@ std::string DatetimeIntervalType::printValueToString(const UntypedLiteral *value
   return std::string(interval_buf);
 }
 
-bool DatetimeIntervalType::parseValueFromString(const std::string &value_string,
-                                                TypedValue *value) const {
+bool DatetimeIntervalType::parseTypedValueFromString(const std::string &value_string,
+                                                     TypedValue *value) const {
   // Try simple-format parse first.
   std::int64_t count;
   std::string units;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DatetimeIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp
index bf36609..cb2534d 100644
--- a/types/DatetimeIntervalType.hpp
+++ b/types/DatetimeIntervalType.hpp
@@ -53,8 +53,8 @@ class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> {
     return TypedValue(DatetimeIntervalLit{0});
   }
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit DatetimeIntervalType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DatetimeType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.cpp b/types/DatetimeType.cpp
index 11ffae9..6d5fc2d 100644
--- a/types/DatetimeType.cpp
+++ b/types/DatetimeType.cpp
@@ -103,8 +103,8 @@ std::string DatetimeType::printValueToString(const UntypedLiteral *value) const
   return std::string(datebuf);
 }
 
-bool DatetimeType::parseValueFromString(const std::string &value_string,
-                                        TypedValue *value) const {
+bool DatetimeType::parseTypedValueFromString(const std::string &value_string,
+                                             TypedValue *value) const {
   int year;
   int month;
   int day;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DatetimeType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp
index 924ff35..d0ac1e2 100644
--- a/types/DatetimeType.hpp
+++ b/types/DatetimeType.hpp
@@ -70,8 +70,8 @@ class DatetimeType
    *       fail if there are any "extra" characters at the end of the string
    *       after a parsable ISO-8601 date/time.
    **/
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit DatetimeType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DoubleType.cpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.cpp b/types/DoubleType.cpp
index fb50957..8219955 100644
--- a/types/DoubleType.cpp
+++ b/types/DoubleType.cpp
@@ -66,8 +66,8 @@ void DoubleType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value));
 }
 
-bool DoubleType::parseValueFromString(const std::string &value_string,
-                                      TypedValue *value) const {
+bool DoubleType::parseTypedValueFromString(const std::string &value_string,
+                                           TypedValue *value) const {
   double parsed_double;
   int read_chars;
   int matched = std::sscanf(value_string.c_str(),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DoubleType.hpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp
index ddba4e3..6959817 100644
--- a/types/DoubleType.hpp
+++ b/types/DoubleType.hpp
@@ -52,8 +52,8 @@ class DoubleType : public NumericSuperType<kDouble> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   static_assert((std::numeric_limits<double>::max_exponent10 < 1000)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/FloatType.cpp
----------------------------------------------------------------------
diff --git a/types/FloatType.cpp b/types/FloatType.cpp
index ca741a6..5fcefc9 100644
--- a/types/FloatType.cpp
+++ b/types/FloatType.cpp
@@ -66,8 +66,8 @@ void FloatType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value));
 }
 
-bool FloatType::parseValueFromString(const std::string &value_string,
-                                     TypedValue *value) const {
+bool FloatType::parseTypedValueFromString(const std::string &value_string,
+                                          TypedValue *value) const {
   float parsed_float;
   int read_chars;
   int matched = std::sscanf(value_string.c_str(),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/FloatType.hpp
----------------------------------------------------------------------
diff --git a/types/FloatType.hpp b/types/FloatType.hpp
index 68a636b..3a7aa41 100644
--- a/types/FloatType.hpp
+++ b/types/FloatType.hpp
@@ -52,8 +52,8 @@ class FloatType : public NumericSuperType<kFloat> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   static_assert((std::numeric_limits<float>::max_exponent10 < 100)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/GenericValue.hpp
----------------------------------------------------------------------
diff --git a/types/GenericValue.hpp b/types/GenericValue.hpp
index 61529d6..1fcdcd6 100644
--- a/types/GenericValue.hpp
+++ b/types/GenericValue.hpp
@@ -26,8 +26,10 @@
 #include <string>
 
 #include "types/Type.hpp"
+#include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 #include "types/TypeRegistrar.hpp"
+#include "types/TypedValue.hpp"
 #include "utility/HashPair.hpp"
 #include "utility/Macros.hpp"
 
@@ -41,16 +43,23 @@ namespace quickstep {
 
 class GenericValue {
  public:
+  GenericValue(const Type &type)
+      : type_(type), value_(nullptr), owns_(true) {}
+
   GenericValue(const Type &type, const UntypedLiteral *value, const bool owns)
       : type_(type), value_(value), owns_(owns) {}
 
+  GenericValue(const Type &type, const TypedValue &value)
+      : type_(type), value_(type.unmarshallTypedValue(value)), owns_(true) {}
+
   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_),
+        value_((other.owns_ && !other.isNull()) ? type_.cloneValue(other.value_)
+                                                : other.value_),
         owns_(other.owns_) {}
 
   GenericValue(GenericValue &&other)
@@ -61,11 +70,15 @@ class GenericValue {
   }
 
   ~GenericValue() {
-    if (owns_ && value_ != nullptr) {
+    if (owns_ && !isNull()) {
       type_.destroyValue(const_cast<void*>(value_));
     }
   }
 
+  serialization::GenericValue getProto() const {
+    LOG(FATAL) << "Not implemented";
+  }
+
   inline bool isNull() const {
     DCHECK(value_ != nullptr || type_.isNullable());
     return value_ == nullptr;
@@ -86,23 +99,47 @@ class GenericValue {
   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_);
+    return *static_cast<const typename TypeIDTrait<type_id>::cpptype*>(value_);
   }
 
   inline void ensureNotReference() {
     if (isReference()) {
-      value_ = type_.cloneValue(value_);
+      if (!isNull()) {
+        value_ = type_.cloneValue(value_);
+      }
       owns_ = true;
     }
   }
 
+  inline GenericValue makeReferenceToThis() const {
+    return GenericValue(type_, value_, false);
+  }
+
+  inline bool equals(const GenericValue &other) const {
+    if (isNull() || other.isNull()) {
+      return isNull() && other.isNull();
+    }
+    return type_.checkValuesEqual(value_, other.value_, other.type_);
+  }
+
   inline bool operator==(const GenericValue &other) const {
-    return type_.equals(other.type_) &&
-           type_.checkValuesEqual(value_, other.value_);
+    return equals(other);
   }
 
   inline std::size_t getHash() const {
-    return CombineHashes(type_.getHash(), type_.hashValue(value_));
+    return isNull() ? 0  : type_.hashValue(value_);
+  }
+
+  inline GenericValue coerce(const Type &other_type) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  inline TypedValue toTypedValue() const {
+    return isNull() ? type_.makeNullValue() : type_.marshallValue(value_);
+  }
+
+  inline std::string toString() const {
+    return isNull() ? "NULL" : type_.printValueToString(value_);
   }
 
  private:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/IntType.cpp
----------------------------------------------------------------------
diff --git a/types/IntType.cpp b/types/IntType.cpp
index 8e3aff1..07db133 100644
--- a/types/IntType.cpp
+++ b/types/IntType.cpp
@@ -46,8 +46,8 @@ void IntType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value));
 }
 
-bool IntType::parseValueFromString(const std::string &value_string,
-                                   TypedValue *value) const {
+bool IntType::parseTypedValueFromString(const std::string &value_string,
+                                        TypedValue *value) const {
   int parsed_int;
   int read_chars;
   int matched = std::sscanf(value_string.c_str(),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/IntType.hpp
----------------------------------------------------------------------
diff --git a/types/IntType.hpp b/types/IntType.hpp
index d83c257..eb5e5aa 100644
--- a/types/IntType.hpp
+++ b/types/IntType.hpp
@@ -54,8 +54,8 @@ class IntType : public NumericSuperType<kInt> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit IntType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/LongType.cpp
----------------------------------------------------------------------
diff --git a/types/LongType.cpp b/types/LongType.cpp
index 82dce39..ffb9eb7 100644
--- a/types/LongType.cpp
+++ b/types/LongType.cpp
@@ -52,8 +52,8 @@ void LongType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value));
 }
 
-bool LongType::parseValueFromString(const std::string &value_string,
-                                    TypedValue *value) const {
+bool LongType::parseTypedValueFromString(const std::string &value_string,
+                                         TypedValue *value) const {
   std::int64_t parsed_long;
   int read_chars;
   int matched = std::sscanf(value_string.c_str(),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/LongType.hpp
----------------------------------------------------------------------
diff --git a/types/LongType.hpp b/types/LongType.hpp
index 7561975..dc75310 100644
--- a/types/LongType.hpp
+++ b/types/LongType.hpp
@@ -55,8 +55,8 @@ class LongType : public NumericSuperType<kLong> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit LongType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/MetaType.hpp
----------------------------------------------------------------------
diff --git a/types/MetaType.hpp b/types/MetaType.hpp
index 0c3952b..c046771 100644
--- a/types/MetaType.hpp
+++ b/types/MetaType.hpp
@@ -46,8 +46,8 @@ class MetaType : public TypeSynthesizer<kMetaType> {
 
   std::string printValueToString(const UntypedLiteral *value) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override {
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override {
     return false;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/NullType.hpp
----------------------------------------------------------------------
diff --git a/types/NullType.hpp b/types/NullType.hpp
index 8dd237e..1aa8a1c 100644
--- a/types/NullType.hpp
+++ b/types/NullType.hpp
@@ -79,8 +79,8 @@ class NullType : public TypeSynthesizer<kNullType> {
     LOG(FATAL) << "NullType is not printable";
   }
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override {
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override {
     return false;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index 6576cbf..f474d52 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -62,8 +62,8 @@ class NumericSuperType : public TypeSynthesizer<type_id> {
     return TypedValue(static_cast<typename TypeIDTrait<type_id>::cpptype>(0));
   }
 
-  TypedValue coerceValue(const TypedValue &original_value,
-                         const Type &original_type) const override {
+  TypedValue coerceTypedValue(const TypedValue &original_value,
+                              const Type &original_type) const override {
     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/a7ccb467/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index 34678c7..b0b781a 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -59,8 +59,8 @@ void Type::printValueToFile(const UntypedLiteral *value,
   std::fprintf(file, "%*s", padding, printValueToString(value).c_str());
 }
 
-TypedValue Type::coerceValue(const TypedValue &original_value,
-                             const Type &original_type) const {
+TypedValue Type::coerceTypedValue(const TypedValue &original_value,
+                                  const Type &original_type) const {
   DCHECK(isCoercibleFrom(original_type))
       << "Can't coerce value of Type " << original_type.getName()
       << " to Type " << getName();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index 47f00e6..d4ed993 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -293,13 +293,13 @@ class Type {
 
   virtual std::string printValueToString(const UntypedLiteral *value) const = 0;
 
+  virtual std::string printTypedValueToString(const TypedValue &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;
@@ -379,8 +379,8 @@ class Type {
    * @return true if value_string was successfully parsed and value was
    *         written. false if value_string was not in the correct format.
    **/
-  virtual bool parseValueFromString(const std::string &value_string,
-                                    TypedValue *value) const = 0;
+  virtual bool parseTypedValueFromString(const std::string &value_string,
+                                         TypedValue *value) const = 0;
 
   /**
    * @brief Coerce a value of another Type to this Type.
@@ -398,32 +398,32 @@ class Type {
    * @return A new TypedValue that represents original_value as an instance of
    *         this Type.
    **/
-  virtual TypedValue coerceValue(const TypedValue &original_value,
-                                 const Type &original_type) const;
+  virtual TypedValue coerceTypedValue(const TypedValue &original_value,
+                                      const Type &original_type) const;
 
-  virtual std::size_t getHash() const {
-    LOG(FATAL) << "Not implemented";
-  }
 
+  virtual std::size_t getHash() const = 0;
 
   virtual bool checkValuesEqual(const UntypedLiteral *lhs,
-                                const UntypedLiteral *rhs) const {
+                                const UntypedLiteral *rhs,
+                                const Type &rhs_type) const {
     LOG(FATAL) << "Not implemented";
   }
 
-  virtual UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
-    LOG(FATAL) << "Not implemented";
+  inline bool checkValuesEqual(const UntypedLiteral *lhs,
+                               const UntypedLiteral *rhs) const {
+    return checkValuesEqual(lhs, rhs, *this);
   }
 
-  virtual std::size_t hashValue(const UntypedLiteral *value) const {
-    LOG(FATAL) << "Not implemented";
-  }
+  virtual UntypedLiteral* cloneValue(const UntypedLiteral *value) const = 0;
+
+  virtual void destroyValue(UntypedLiteral *value) const = 0;
 
-  virtual void destroyValue(UntypedLiteral *value_ptr) const {
+  virtual std::size_t hashValue(const UntypedLiteral *value) const {
     LOG(FATAL) << "Not implemented";
   }
 
-  virtual CharStream marshallValue(const UntypedLiteral *value) const {
+  virtual TypedValue marshallValue(const UntypedLiteral *value) const {
     LOG(FATAL) << "Not implemented";
   }
 
@@ -433,9 +433,9 @@ class Type {
 
   }
 
-  virtual UntypedLiteral* unmarshallValue(const TypedValue &value) const = 0;
+  virtual UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const = 0;
 
-  virtual UntypedLiteral* unmarshallValue(TypedValue &&value) const = 0;
+  virtual UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const = 0;
 
  protected:
   Type(const SuperTypeID super_type_id,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index 7c39e47..08ab67a 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -22,6 +22,8 @@
 
 #include <cstddef>
 #include <cstdio>
+#include <cstdlib>
+#include <cstring>
 #include <memory>
 #include <string>
 #include <type_traits>
@@ -46,16 +48,16 @@ namespace quickstep {
  */
 
 template <TypeID type_id, typename Enable = void>
-class TypeInstancePolicy;
+class TypeSynthesizePolicy;
 
 
 template <TypeID type_id>
 class TypeSynthesizer
     : public Type,
-      public TypeInstancePolicy<type_id> {
+      public TypeSynthesizePolicy<type_id> {
  private:
   using Trait = TypeIDTrait<type_id>;
-  using InstancePolicy = TypeInstancePolicy<type_id>;
+  using SynthesizePolicy = TypeSynthesizePolicy<type_id>;
 
  public:
   static constexpr SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID;
@@ -71,38 +73,41 @@ class TypeSynthesizer
 
     proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
     proto.set_nullable(nullable_);
-
-    InstancePolicy::fillProto(&proto);
+    SynthesizePolicy::mergeIntoProto(&proto);
 
     return proto;
   }
 
   const Type& getNullableVersion() const override {
-    return InstancePolicy::getInstance(true);
+    return SynthesizePolicy::getInstance(true);
   }
 
   const Type& getNonNullableVersion() const override {
-    return InstancePolicy::getInstance(false);
+    return SynthesizePolicy::getInstance(false);
   }
 
-  const cpptype& castValueToLiteral(const UntypedLiteral *value) const {
-    return *static_cast<const cpptype*>(value);
+  std::size_t getHash() const override {
+    return SynthesizePolicy::getHash();
   }
 
-  cpptype& castValueToLiteral(UntypedLiteral *value) const {
-    return *static_cast<cpptype*>(value);
+  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
+    return SynthesizePolicy::cloneValue(value);
   }
 
-  UntypedLiteral* unmarshallValue(const TypedValue &value) const override {
-    return unmarshallInternal<kMemoryLayout>(value);
+  void destroyValue(UntypedLiteral *value) const override {
+    return SynthesizePolicy::destroyValue(value);
   }
 
-  UntypedLiteral* unmarshallValue(TypedValue &&value) const override {
-    return unmarshallInternal<kMemoryLayout>(std::move(value));
+  UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override {
+    return SynthesizePolicy::unmarshallTypedValue(value);
+  }
+
+  UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const override {
+    return SynthesizePolicy::unmarshallTypedValue(std::move(value));
   }
 
   std::string printTypedValueToString(const TypedValue &value) const override {
-    return invokeOnUnmarshalledValue<kMemoryLayout>(
+    return SynthesizePolicy::invokeOnUnmarshalledTypedValue(
         value,
         [&](const UntypedLiteral *value) -> std::string {
       return this->printValueToString(value);
@@ -112,20 +117,28 @@ class TypeSynthesizer
   void printTypedValueToFile(const TypedValue &value,
                              FILE *file,
                              const int padding = 0) const override {
-    invokeOnUnmarshalledValue<kMemoryLayout>(
+    SynthesizePolicy::invokeOnUnmarshalledTypedValue(
         value,
         [&](const UntypedLiteral *value) -> void {
       this->printValueToFile(value, file, padding);
     });
   }
 
+  const cpptype& castValueToLiteral(const UntypedLiteral *value) const {
+    return *static_cast<const cpptype*>(value);
+  }
+
+  cpptype& castValueToLiteral(UntypedLiteral *value) const {
+    return *static_cast<cpptype*>(value);
+  }
+
  protected:
   template <MemoryLayout layout = kMemoryLayout>
   explicit TypeSynthesizer(const bool nullable,
                            std::enable_if_t<layout == kCxxInlinePod>* = 0)
       : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
              sizeof(cpptype), sizeof(cpptype)),
-        TypeInstancePolicy<type_id>() {
+        TypeSynthesizePolicy<type_id>(this) {
   }
 
   template <MemoryLayout layout = kMemoryLayout>
@@ -133,10 +146,11 @@ class TypeSynthesizer
                   const std::size_t minimum_byte_length,
                   const std::size_t maximum_byte_length,
                   const std::size_t parameter,
-                  std::enable_if_t<layout == kParInlinePod || layout == kParOutOfLinePod>* = 0)
+                  std::enable_if_t<layout == kParInlinePod ||
+                                   layout == kParOutOfLinePod>* = 0)
       : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
              minimum_byte_length, maximum_byte_length),
-        TypeInstancePolicy<type_id>(parameter) {
+        TypeSynthesizePolicy<type_id>(this, parameter) {
   }
 
   template <MemoryLayout layout = kMemoryLayout>
@@ -147,70 +161,11 @@ class TypeSynthesizer
                   std::enable_if_t<layout == kCxxGeneric>* = 0)
       : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
              minimum_byte_length, maximum_byte_length),
-        TypeInstancePolicy<type_id>(parameters) {
+        TypeSynthesizePolicy<type_id>(this, parameters) {
   }
 
  private:
-  template <MemoryLayout layout>
-  inline UntypedLiteral* unmarshallInternal(
-      const TypedValue &value,
-      std::enable_if_t<layout == kCxxInlinePod> * = 0) const {
-    return cloneValue(value.getDataPtr());
-  }
-
-  template <MemoryLayout layout>
-  inline UntypedLiteral* unmarshallInternal(
-      const TypedValue &value,
-      std::enable_if_t<layout == kParInlinePod ||
-                       layout == kParOutOfLinePod> * = 0) const {
-    return cloneValue(&value);
-  }
-
-  template <MemoryLayout layout>
-  inline UntypedLiteral* unmarshallInternal(
-      TypedValue &&value,
-      std::enable_if_t<layout == kParInlinePod ||
-                       layout == kParOutOfLinePod> * = 0) const {
-    return new TypedValue(std::move(value));
-  }
-
-  template <MemoryLayout layout>
-  inline UntypedLiteral* unmarshallInternal(
-      const TypedValue &value,
-      std::enable_if_t<layout == kCxxGeneric> * = 0) const {
-    return Type::unmarshallValue(value.getOutOfLineData(), value.getDataSize());
-  }
-
-
-  template <MemoryLayout layout, typename Functor>
-  inline auto invokeOnUnmarshalledValue(
-      const TypedValue &value,
-      const Functor &functor,
-      std::enable_if_t<layout == kCxxInlinePod> * = 0) const {
-    return functor(value.getDataPtr());
-  }
-
-  template <MemoryLayout layout, typename Functor>
-  inline auto invokeOnUnmarshalledValue(
-      const TypedValue &value,
-      const Functor &functor,
-      std::enable_if_t<layout == kParInlinePod ||
-                       layout == kParOutOfLinePod> * = 0) const {
-    return functor(&value);
-  }
-
-  template <MemoryLayout layout, typename Functor>
-  inline auto invokeOnUnmarshalledValue(
-      const TypedValue &value,
-      const Functor &functor,
-      std::enable_if_t<layout == kCxxGeneric> * = 0) const {
-    std::unique_ptr<cpptype> literal(
-        static_cast<cpptype*>(Type::unmarshallValue(value.getOutOfLineData(),
-                                                    value.getDataSize())));
-    return functor(literal.get());
-  }
-
-  template <TypeID, typename> friend class TypeInstancePolicy;
+  template <TypeID, typename> friend class TypeSynthesizePolicy;
 
   DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
 };
@@ -229,12 +184,13 @@ constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout;
 
 
 template <TypeID type_id>
-class TypeInstancePolicy<
+class TypeSynthesizePolicy<
     type_id,
     std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxInlinePod>> {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
+  using cpptype = typename Trait::cpptype;
 
  public:
   static const TypeClass& InstanceNonNullable() {
@@ -254,13 +210,40 @@ class TypeInstancePolicy<
   }
 
  protected:
-  TypeInstancePolicy() {}
+  explicit TypeSynthesizePolicy(const Type *base)
+      : base_(*base) {}
 
   inline const Type& getInstance(const bool nullable) const {
     return nullable ? InstanceNullable() : InstanceNonNullable();
   }
 
-  inline void fillProto(serialization::Type *proto) const {}
+  inline void mergeIntoProto(serialization::Type *proto) const {}
+
+  inline std::size_t getHash() const {
+    return static_cast<std::size_t>(base_.getTypeID());
+  }
+
+  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    UntypedLiteral* clone = std::malloc(sizeof(cpptype));
+    std::memcpy(clone, value, sizeof(cpptype));
+    return clone;
+  }
+
+  inline void destroyValue(UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    std::free(value);
+  }
+
+  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
+    return base_.cloneValue(value.getDataPtr());
+  }
+
+  template <typename Functor>
+  inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value,
+                                             const Functor &functor) const {
+    return functor(value.getDataPtr());
+  }
 
  private:
   template <bool nullable>
@@ -268,16 +251,22 @@ class TypeInstancePolicy<
     static TypeClass instance(nullable);
     return instance;
   }
+
+  const Type &base_;
 };
 
 template <TypeID type_id>
-class TypeInstancePolicy<
+class TypeSynthesizePolicy<
     type_id,
     std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kParInlinePod ||
                      TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
+  using cpptype = typename Trait::cpptype;
+
+  static_assert(std::is_same<cpptype, TypedValue>::value,
+                "Unexpected cpptype for paramerized PODs.");
 
  public:
   static const TypeClass& InstanceNonNullable(const std::size_t length) {
@@ -301,8 +290,9 @@ class TypeInstancePolicy<
   }
 
  protected:
-  TypeInstancePolicy(const std::size_t length)
-      : length_(length) {}
+  TypeSynthesizePolicy(const Type *base, const std::size_t length)
+      : length_(length),
+        base_(*base) {}
 
   const std::size_t length_;
 
@@ -310,10 +300,38 @@ class TypeInstancePolicy<
     return nullable ? InstanceNullable(length_) : InstanceNonNullable(length_);
   }
 
-  inline void fillProto(serialization::Type *proto) const {
+  inline void mergeIntoProto(serialization::Type *proto) const {
     proto->set_length(length_);
   }
 
+  inline std::size_t getHash() const {
+    return CombineHashes(static_cast<std::size_t>(base_.getTypeID()), length_);
+  }
+
+  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    return new TypedValue(*static_cast<const TypedValue*>(value));
+  }
+
+  inline void destroyValue(UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    delete static_cast<TypedValue*>(value);
+  }
+
+  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
+    return base_.cloneValue(&value);
+  }
+
+  inline UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const {
+    return new TypedValue(std::move(value));
+  }
+
+  template <typename Functor>
+  inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value,
+                                             const Functor &functor) const {
+    return functor(&value);
+  }
+
  private:
   template <bool nullable>
   inline static const TypeClass& InstanceInternal(const std::size_t length) {
@@ -325,15 +343,18 @@ class TypeInstancePolicy<
     }
     return *(imit->second);
   }
+
+  const Type &base_;
 };
 
 template <TypeID type_id>
-class TypeInstancePolicy<
+class TypeSynthesizePolicy<
     type_id,
     std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxGeneric>> {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
+  using cpptype = typename Trait::cpptype;
 
  public:
   static const TypeClass& InstanceNonNullable(
@@ -361,29 +382,67 @@ class TypeInstancePolicy<
   }
 
  protected:
-  TypeInstancePolicy(const std::vector<GenericValue> &parameters)
-      : parameters_(parameters) {}
-
-  const std::vector<GenericValue> parameters_;
+  TypeSynthesizePolicy(const Type *base,
+                       const std::vector<GenericValue> &parameters)
+      : parameters_(parameters),
+        base_(*base) {}
 
   inline const Type& getInstance(const bool nullable) const {
     return nullable ? InstanceNullable(parameters_)
                     : InstanceNonNullable(parameters_);
   }
 
-  inline void fillProto(serialization::Type *proto) const {
-    LOG(FATAL) << "TODO";
+  inline void mergeIntoProto(serialization::Type *proto) const {
+    for (const auto &param : parameters_) {
+      proto->add_parameters()->MergeFrom(param.getProto());
+    }
+  }
+
+  inline std::size_t getHash() const {
+    return CombineHashes(static_cast<std::size_t>(base_.getTypeID()),
+                         ParametersHasher::ComputeHash(parameters_));
+  }
+
+  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    return new cpptype(*static_cast<const cpptype*>(value));
+  }
+
+  inline void destroyValue(UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    delete static_cast<cpptype*>(value);
   }
 
+  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
+    return base_.unmarshallValue(value.getOutOfLineData(), value.getDataSize());
+  }
+
+  template <typename Functor>
+  inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value,
+                                             const Functor &functor) const {
+    std::unique_ptr<typename Trait::cpptype> literal(
+        static_cast<typename Trait::cpptype*>(
+            base_.unmarshallValue(value.getOutOfLineData(),
+                                  value.getDataSize())));
+    return functor(literal.get());
+  }
+
+  const std::vector<GenericValue> parameters_;
+
  private:
   struct ParametersHasher {
-    inline std::size_t operator()(const std::vector<GenericValue> &parameters) const {
+    inline static std::size_t ComputeHash(
+        const std::vector<GenericValue> &parameters) {
       std::size_t hash_code = 0;
       for (const GenericValue &value : parameters) {
         hash_code = CombineHashes(hash_code, value.getHash());
       }
       return hash_code;
     }
+    inline std::size_t operator()(
+        const std::vector<GenericValue> &parameters) const {
+      return ComputeHash(parameters);
+    }
   };
 
   template <typename T>
@@ -412,16 +471,18 @@ class TypeInstancePolicy<
     auto imit = instance_map.find(parameters);
     if (imit == instance_map.end()) {
       std::unique_ptr<TypeClass> instance(
-          TypeInstancePolicy<type_id>::template CreateInstance<TypeClass>(
+          TypeSynthesizePolicy<type_id>::template CreateInstance<TypeClass>(
               nullable, parameters));
       imit = instance_map.emplace(parameters, std::move(instance)).first;
     }
     return *(imit->second);
   }
+
+  const Type &base_;
 };
 
 #define QUICKSTEP_SYNTHESIZE_TYPE(type) \
-  template <TypeID, typename> friend class TypeInstancePolicy; \
+  template <TypeID, typename> friend class TypeSynthesizePolicy; \
   DISALLOW_COPY_AND_ASSIGN(type)
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/VarCharType.cpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.cpp b/types/VarCharType.cpp
index f0f677d..6f5f9fb 100644
--- a/types/VarCharType.cpp
+++ b/types/VarCharType.cpp
@@ -103,8 +103,8 @@ void VarCharType::printValueToFile(const UntypedLiteral *value,
                static_cast<const char*>(castValueToLiteral(value).getOutOfLineData()));
 }
 
-bool VarCharType::parseValueFromString(const std::string &value_string,
-                                       TypedValue *value) const {
+bool VarCharType::parseTypedValueFromString(const std::string &value_string,
+                                            TypedValue *value) const {
   if (value_string.length() > length_) {
     return false;
   }
@@ -114,8 +114,8 @@ bool VarCharType::parseValueFromString(const std::string &value_string,
   return true;
 }
 
-TypedValue VarCharType::coerceValue(const TypedValue &original_value,
-                                    const Type &original_type) const {
+TypedValue VarCharType::coerceTypedValue(const TypedValue &original_value,
+                                         const Type &original_type) const {
   DCHECK(isCoercibleFrom(original_type))
       << "Can't coerce value of Type " << original_type.getName()
       << " to Type " << getName();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/VarCharType.hpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp
index 47a2874..0b16061 100644
--- a/types/VarCharType.hpp
+++ b/types/VarCharType.hpp
@@ -66,11 +66,11 @@ class VarCharType : public AsciiStringSuperType<kVarChar> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
-  TypedValue coerceValue(const TypedValue &original_value,
-                         const Type &original_type) const override;
+  TypedValue coerceTypedValue(const TypedValue &original_value,
+                              const Type &original_type) const override;
 
  private:
   VarCharType(const bool nullable, const std::size_t length)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/YearMonthIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.cpp b/types/YearMonthIntervalType.cpp
index b395dff..f266bf1 100644
--- a/types/YearMonthIntervalType.cpp
+++ b/types/YearMonthIntervalType.cpp
@@ -116,8 +116,8 @@ std::string YearMonthIntervalType::printValueToString(const UntypedLiteral *valu
   return std::string(interval_buf);
 }
 
-bool YearMonthIntervalType::parseValueFromString(const std::string &value_string,
-                                                 TypedValue *value) const {
+bool YearMonthIntervalType::parseTypedValueFromString(const std::string &value_string,
+                                                      TypedValue *value) const {
   // Try simple-format parse first.
   std::int64_t count;
   std::string units;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/YearMonthIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp
index ab06911..ee1eb97 100644
--- a/types/YearMonthIntervalType.hpp
+++ b/types/YearMonthIntervalType.hpp
@@ -52,8 +52,8 @@ class YearMonthIntervalType : public TypeSynthesizer<kYearMonthInterval> {
     return TypedValue(YearMonthIntervalLit{0});
   }
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit YearMonthIntervalType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/operations/OperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.cpp b/types/operations/OperationFactory.cpp
index 531318b..253a75d 100644
--- a/types/operations/OperationFactory.cpp
+++ b/types/operations/OperationFactory.cpp
@@ -24,11 +24,11 @@
 #include <string>
 #include <vector>
 
+#include "types/GenericValue.hpp"
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypeUtil.hpp"
-#include "types/TypedValue.hpp"
 #include "types/operations/Operation.hpp"
 #include "types/operations/OperationSignature.hpp"
 #include "types/operations/binary_operations/ArithmeticBinaryOperations.hpp"
@@ -68,6 +68,16 @@ struct FunctorPackDispatcher {
   }
 };
 
+// TODO(refactor-type): Remove this.
+inline static std::shared_ptr<const std::vector<TypedValue>> ToTypedValue(
+    const std::vector<GenericValue> &input) {
+  std::vector<TypedValue> values;
+  for (const auto &item : input) {
+    values.emplace_back(item.toTypedValue());
+  }
+  return std::make_shared<const std::vector<TypedValue>>(std::move(values));
+}
+
 }  // namespace
 
 OperationFactory::OperationFactory() {
@@ -87,9 +97,9 @@ OperationFactory::OperationFactory() {
 OperationSignaturePtr OperationFactory::resolveOperation(
     const std::string &operation_name,
     const std::shared_ptr<const std::vector<const Type*>> &argument_types,
-    const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
+    const std::shared_ptr<const std::vector<GenericValue>> &static_arguments,
     std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
-    std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+    std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
     std::string *message) const {
   const std::string lower_case_name = ToLower(operation_name);
   const std::size_t arity = argument_types->size();
@@ -151,8 +161,8 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithFullTypeMa
     const PartialSignatureIndex &secondary_index,
     const std::vector<TypeID> &argument_type_ids,
     const std::vector<const Type*> &argument_types,
-    const std::vector<TypedValue> &static_arguments,
-    std::shared_ptr<const std::vector<TypedValue>> *partial_static_arguments,
+    const std::vector<GenericValue> &static_arguments,
+    std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
     OperationSignaturePtr *resolved_op_signature,
     std::string *message) const {
   const std::size_t max_num_static_arguments = static_arguments.size();
@@ -163,15 +173,15 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithFullTypeMa
     const OperationSignaturePtr op_signature = it->second;
     const OperationPtr operation = getOperation(op_signature);
 
-    *partial_static_arguments =
-        std::make_shared<const std::vector<TypedValue>>(
+    *coerced_static_arguments =
+        std::make_shared<const std::vector<GenericValue>>(
             static_arguments.begin()
                 + (max_num_static_arguments - op_signature->getNumStaticArguments()),
             static_arguments.end());
 
     if (canApplyOperationTo(operation,
                             argument_types,
-                            **partial_static_arguments,
+                            **coerced_static_arguments,
                             message)) {
       *resolved_op_signature = op_signature;
       return ResolveStatus::kSuccess;
@@ -187,9 +197,9 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
     const PartialSignatureIndex &secondary_index,
     const std::vector<TypeID> &argument_type_ids,
     const std::vector<const Type*> &argument_types,
-    const std::vector<TypedValue> &static_arguments,
+    const std::vector<GenericValue> &static_arguments,
     std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
-    std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+    std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
     OperationSignaturePtr *resolved_op_signature,
     std::string *message) const {
   const std::size_t arity = argument_types.size();
@@ -211,18 +221,16 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
     }
 
     // Coerce static arguments
-    std::vector<const Type*> coerced_static_arg_types;
-    std::vector<TypedValue> coerced_static_args;
+    std::vector<GenericValue> coerced_static_args;
 
     bool is_coercible = true;
     for (std::size_t i = num_non_static_arguments; i < arity; ++i) {
       const Type &arg_type = *argument_types.at(i);
-      const TypedValue &arg_value =
+      const GenericValue &arg_value =
           static_arguments.at(i - first_static_argument_position);
       const TypeID &expected_type_id = expected_type_ids.at(i);
 
       if (arg_type.getTypeID() == expected_type_id) {
-        coerced_static_arg_types.emplace_back(&arg_type);
         coerced_static_args.emplace_back(arg_value);
       } else {
         const Type *expected_type = nullptr;
@@ -240,9 +248,7 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
         }
 
         if (expected_type != nullptr && expected_type->isSafelyCoercibleFrom(arg_type)) {
-          coerced_static_arg_types.emplace_back(expected_type);
-          coerced_static_args.emplace_back(
-              expected_type->coerceValue(arg_value, arg_type));
+          coerced_static_args.emplace_back(arg_value.coerce(*expected_type));
         } else {
           is_coercible = false;
           break;
@@ -254,8 +260,8 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
       std::vector<const Type*> coerced_arg_types(
           argument_types.begin(),
           argument_types.begin() + num_non_static_arguments);
-      for (const Type *type : coerced_static_arg_types) {
-        coerced_arg_types.emplace_back(type);
+      for (const auto &value : coerced_static_args) {
+        coerced_arg_types.emplace_back(&value.getType());
       }
 
       const OperationPtr operation = getOperation(it->second);
@@ -266,7 +272,7 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
         *coerced_argument_types =
             std::make_shared<const std::vector<const Type*>>(std::move(coerced_arg_types));
         *coerced_static_arguments =
-            std::make_shared<const std::vector<TypedValue>>(std::move(coerced_static_args));
+            std::make_shared<const std::vector<GenericValue>>(std::move(coerced_static_args));
         *resolved_op_signature = it->second;
         return ResolveStatus::kSuccess;
       }
@@ -281,14 +287,14 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
 bool OperationFactory::canApplyOperationTo(
     const OperationPtr operation,
     const std::vector<const Type*> &argument_types,
-    const std::vector<TypedValue> &static_arguments,
+    const std::vector<GenericValue> &static_arguments,
     std::string *message) const {
   switch (operation->getOperationSuperTypeID()) {
     case Operation::kUnaryOperation: {
       const UnaryOperationPtr unary_operation =
           std::static_pointer_cast<const UnaryOperation>(operation);
       return unary_operation->canApplyTo(*argument_types[0],
-                                         static_arguments,
+                                         *ToTypedValue(static_arguments),
                                          message);
     }
     case Operation::kBinaryOperation: {
@@ -296,7 +302,7 @@ bool OperationFactory::canApplyOperationTo(
           std::static_pointer_cast<const BinaryOperation>(operation);
       return binary_operation->canApplyTo(*argument_types[0],
                                           *argument_types[1],
-                                          static_arguments,
+                                          *ToTypedValue(static_arguments),
                                           message);
     }
     default: {