quickstep-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jianq...@apache.org
Subject [03/38] incubator-quickstep git commit: Updates to casts
Date Tue, 10 Oct 2017 18:25:33 GMT
Updates to casts


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

Branch: refs/heads/refactor-type
Commit: 4bf0857c57ef2f9fed8fad5a35255b471341918c
Parents: f9e32e6
Author: Jianqiao Zhu <jianqiao@cs.wisc.edu>
Authored: Tue Oct 10 13:20:17 2017 -0500
Committer: Jianqiao Zhu <jianqiao@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 expressions/ExpressionFactories.cpp             |   4 +-
 .../aggregation/AggregateFunctionAvg.cpp        |  13 +-
 .../aggregation/AggregateFunctionSum.cpp        |   4 +-
 .../aggregation/AggregationHandleAvg.cpp        |  16 +-
 .../aggregation/AggregationHandleSum.cpp        |   8 +-
 expressions/scalar/ScalarCaseExpression.cpp     |   8 +-
 .../WindowAggregateFunctionAvg.cpp              |   3 +-
 .../WindowAggregateFunctionSum.cpp              |   2 +-
 .../WindowAggregationHandle.cpp                 |   4 +-
 .../WindowAggregationHandleAvg.cpp              |   4 +-
 query_optimizer/expressions/CMakeLists.txt      |  11 +-
 query_optimizer/expressions/Cast.cpp            |   2 +-
 query_optimizer/resolver/Resolver.cpp           |  80 ++-
 query_optimizer/rules/Partition.cpp             |   2 +-
 .../rules/ReuseAggregateExpressions.cpp         |   2 +-
 storage/SMAIndexSubBlock.cpp                    |   7 +-
 storage/WindowAggregationOperationState.cpp     |   4 +-
 types/ArrayLit.hpp                              | 112 ++++
 types/ArrayType.cpp                             |  30 +-
 types/ArrayType.hpp                             |  10 +-
 types/AsciiStringSuperType.hpp                  |   8 -
 types/BoolType.hpp                              |   2 +-
 types/CMakeLists.txt                            |   7 +-
 types/CharType.hpp                              |   2 +-
 types/DateType.hpp                              |   2 +-
 types/DatetimeIntervalType.hpp                  |   2 +-
 types/DatetimeType.hpp                          |   3 +-
 types/DoubleType.hpp                            |   2 +-
 types/FloatType.hpp                             |   2 +-
 types/IntType.hpp                               |   2 +-
 types/LongType.hpp                              |   2 +-
 types/MetaType-decl.hpp                         |   2 +-
 types/MetaType.cpp                              |   2 +-
 types/NullType.hpp                              |   2 +-
 types/NumericSuperType.hpp                      |   5 -
 types/TextType.hpp                              |   2 +-
 types/Type.cpp                                  |  22 +-
 types/Type.hpp                                  |   9 +-
 types/Type.proto                                |   4 +-
 types/TypeRegistrar.hpp                         |  16 +-
 types/TypeSynthesizer.hpp                       |  34 +-
 types/VarCharType.hpp                           |   2 +-
 types/YearMonthIntervalType.hpp                 |   2 +-
 types/containers/CMakeLists.txt                 |   1 +
 types/containers/ColumnVector.cpp               |  43 +-
 types/containers/ColumnVector.hpp               | 124 +++-
 types/containers/ColumnVectorUtil.hpp           |   6 +-
 types/containers/ColumnVectorsValueAccessor.hpp |  41 +-
 types/operations/CMakeLists.txt                 |   5 +-
 types/operations/OperationFactory.cpp           | 160 ++++-
 types/operations/OperationFactory.hpp           | 138 ++--
 .../ArithmeticBinaryFunctors.hpp                |   2 +-
 .../AsciiStringBinaryFunctors.hpp               |  24 +-
 .../BinaryOperationSynthesizer.hpp              | 660 +++++++++++++++++++
 .../BinaryOperationWrapper.hpp                  | 629 ------------------
 .../operations/binary_operations/CMakeLists.txt |  15 +-
 .../binary_operations/CMathBinaryFunctors.hpp   |   2 +-
 .../operations/comparisons/BasicComparison.hpp  |  23 +-
 .../comparisons/LiteralComparators-inl.hpp      |  10 +-
 .../ArithmeticUnaryFunctors.hpp                 |   2 +-
 .../AsciiStringUnaryFunctors.hpp                |   2 +-
 .../operations/unary_operations/CMakeLists.txt  |  29 +-
 .../unary_operations/CMathUnaryFunctors.hpp     |   2 +-
 .../unary_operations/CastFunctorOverloads.hpp   | 195 +++---
 .../unary_operations/CastOperation.cpp          |   6 +-
 .../unary_operations/CastOperation.hpp          |   4 +-
 .../unary_operations/DateExtractOperation.cpp   |  20 +-
 .../UnaryOperationSynthesizer.hpp               | 273 ++++++++
 .../unary_operations/UnaryOperationWrapper.hpp  | 250 -------
 types/operations/utility/CMakeLists.txt         |  11 +-
 types/operations/utility/CastUtil.cpp           |  66 ++
 types/operations/utility/CastUtil.hpp           |  50 ++
 .../utility/OperationSynthesizeUtil.hpp         | 184 +++++-
 utility/Cast.hpp                                |   7 +-
 utility/meta/Common.hpp                         |  20 +-
 utility/meta/TypeList.hpp                       |  32 +-
 utility/meta/TypeListMetaFunctions.hpp          |  11 +-
 77 files changed, 2168 insertions(+), 1341 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/ExpressionFactories.cpp
----------------------------------------------------------------------
diff --git a/expressions/ExpressionFactories.cpp b/expressions/ExpressionFactories.cpp
index f8913ba..2dd5124 100644
--- a/expressions/ExpressionFactories.cpp
+++ b/expressions/ExpressionFactories.cpp
@@ -181,7 +181,7 @@ Scalar* ScalarFactory::ReconstructFromProto(const serialization::Scalar &proto,
               proto.GetExtension(serialization::ScalarUnaryExpression::op_signature));
       return new ScalarUnaryExpression(
           op_signature,
-          OperationFactory::Instance().getUnaryOperation(op_signature),
+          OperationFactory::GetUnaryOperation(op_signature),
           ReconstructFromProto(proto.GetExtension(serialization::ScalarUnaryExpression::operand), database),
           std::make_shared<std::vector<TypedValue>>(std::move(static_arguments)));
     }
@@ -199,7 +199,7 @@ Scalar* ScalarFactory::ReconstructFromProto(const serialization::Scalar &proto,
               proto.GetExtension(serialization::ScalarBinaryExpression::op_signature));
       return new ScalarBinaryExpression(
           op_signature,
-          OperationFactory::Instance().getBinaryOperation(op_signature),
+          OperationFactory::GetBinaryOperation(op_signature),
           ReconstructFromProto(
               proto.GetExtension(serialization::ScalarBinaryExpression::left_operand), database),
           ReconstructFromProto(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/aggregation/AggregateFunctionAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregateFunctionAvg.cpp b/expressions/aggregation/AggregateFunctionAvg.cpp
index b2b99c7..3acdb5b 100644
--- a/expressions/aggregation/AggregateFunctionAvg.cpp
+++ b/expressions/aggregation/AggregateFunctionAvg.cpp
@@ -41,14 +41,11 @@ bool AggregateFunctionAvg::canApplyToTypes(
 
   // Argument must be addable and divisible.
   const Type &type = *argument_types.front();
-  if (!OperationFactory::Instance()
-          .getBinaryOperation("+", {type.getTypeID(), type.getTypeID()})
-              ->canApplyTo(type, type)) {
+  if (!OperationFactory::CanApplyAddOperation(type, type)) {
     return false;
   }
-  return OperationFactory::Instance()
-      .getBinaryOperation("/", {type.getTypeID(), kDouble})
-          ->canApplyTo(type, TypeFactory::GetType(kDouble));
+  return OperationFactory::CanApplyDivideOperation(
+      type, TypeFactory::GetType(kDouble));
 }
 
 const Type* AggregateFunctionAvg::resultTypeForArgumentTypes(
@@ -71,8 +68,8 @@ const Type* AggregateFunctionAvg::resultTypeForArgumentTypes(
       break;
   }
 
-  return OperationFactory::Instance()
-      .getBinaryOperation("/", {sum_type->getTypeID(), kDouble})
+  return OperationFactory::GetDivideOperation(
+      sum_type->getTypeID(), kDouble)
           ->getResultType(*sum_type, TypeFactory::GetType(kDouble));
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/aggregation/AggregateFunctionSum.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregateFunctionSum.cpp b/expressions/aggregation/AggregateFunctionSum.cpp
index 11b33c0..b8c94b3 100644
--- a/expressions/aggregation/AggregateFunctionSum.cpp
+++ b/expressions/aggregation/AggregateFunctionSum.cpp
@@ -41,9 +41,7 @@ bool AggregateFunctionSum::canApplyToTypes(
 
   // Argument must be addable.
   const Type &type = *argument_types.front();
-  return OperationFactory::Instance()
-      .getBinaryOperation("+", {type.getTypeID(), type.getTypeID()})
-          ->canApplyTo(type, type);
+  return OperationFactory::CanApplyAddOperation(type, type);
 }
 
 const Type* AggregateFunctionSum::resultTypeForArgumentTypes(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/aggregation/AggregationHandleAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleAvg.cpp b/expressions/aggregation/AggregationHandleAvg.cpp
index 1324fd8..6ec59c7 100644
--- a/expressions/aggregation/AggregationHandleAvg.cpp
+++ b/expressions/aggregation/AggregationHandleAvg.cpp
@@ -67,22 +67,22 @@ AggregationHandleAvg::AggregationHandleAvg(const Type &type)
 
   // Make operators to do arithmetic:
   // Add operator for summing argument values.
-  fast_add_operator_.reset(OperationFactory::Instance()
-      .getBinaryOperation("+", {type_precision_id, argument_type_.getTypeID()})
+  fast_add_operator_.reset(
+      OperationFactory::GetAddOperation(type_precision_id, argument_type_.getTypeID())
           ->makeUncheckedBinaryOperator(sum_type, argument_type_));
   // Add operator for merging states.
-  merge_add_operator_.reset(OperationFactory::Instance()
-      .getBinaryOperation("+", {type_precision_id, type_precision_id})
+  merge_add_operator_.reset(
+      OperationFactory::GetAddOperation(type_precision_id, type_precision_id)
           ->makeUncheckedBinaryOperator(sum_type, sum_type));
   // Divide operator for dividing sum by count to get final average.
-  divide_operator_.reset(OperationFactory::Instance()
-      .getBinaryOperation("/", {type_precision_id, kDouble})
+  divide_operator_.reset(
+      OperationFactory::GetDivideOperation(type_precision_id, kDouble)
           ->makeUncheckedBinaryOperator(sum_type, TypeFactory::GetType(kDouble)));
 
   // Result is nullable, because AVG() over 0 values (or all NULL values) is
   // NULL.
-  result_type_ = &OperationFactory::Instance()
-      .getBinaryOperation("/", {type_precision_id, kDouble})
+  result_type_ =
+      &OperationFactory::GetDivideOperation(type_precision_id, kDouble)
           ->getResultType(sum_type, TypeFactory::GetType(kDouble))
               ->getNullableVersion();
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/aggregation/AggregationHandleSum.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleSum.cpp b/expressions/aggregation/AggregationHandleSum.cpp
index c7ee776..9fdbab7 100644
--- a/expressions/aggregation/AggregationHandleSum.cpp
+++ b/expressions/aggregation/AggregationHandleSum.cpp
@@ -66,12 +66,12 @@ AggregationHandleSum::AggregationHandleSum(const Type &type)
 
   // Make operators to do arithmetic:
   // Add operator for summing argument values.
-  fast_operator_.reset(OperationFactory::Instance()
-      .getBinaryOperation("+", {type_precision_id, argument_type_.getTypeID()})
+  fast_operator_.reset(
+      OperationFactory::GetAddOperation(type_precision_id, argument_type_.getTypeID())
           ->makeUncheckedBinaryOperator(sum_type, argument_type_));
   // Add operator for merging states.
-  merge_operator_.reset(OperationFactory::Instance()
-      .getBinaryOperation("+", {type_precision_id, type_precision_id})
+  merge_operator_.reset(
+      OperationFactory::GetAddOperation(type_precision_id, type_precision_id)
           ->makeUncheckedBinaryOperator(sum_type, sum_type));
 
   // Result is nullable, because SUM() over 0 values (or all NULL values) is

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/scalar/ScalarCaseExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarCaseExpression.cpp b/expressions/scalar/ScalarCaseExpression.cpp
index 6fd2c0f..4a0cc72 100644
--- a/expressions/scalar/ScalarCaseExpression.cpp
+++ b/expressions/scalar/ScalarCaseExpression.cpp
@@ -470,7 +470,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors(
     for (std::vector<std::unique_ptr<TupleIdSequence>>::size_type case_idx = 0;
          case_idx < case_matches.size();
          ++case_idx) {
-      DCHECK(case_results[case_idx]->isNative());
+      DCHECK(case_results[case_idx]->getImplementation() == ColumnVector::kNative);
       if (!case_matches[case_idx]->empty()) {
         MultiplexNativeColumnVector(
             source_sequence,
@@ -481,7 +481,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors(
     }
 
     if (else_result != nullptr) {
-      DCHECK(else_result->isNative());
+      DCHECK(else_result->getImplementation() == ColumnVector::kNative);
       DCHECK(!else_matches.empty());
       MultiplexNativeColumnVector(source_sequence,
                                   else_matches,
@@ -498,7 +498,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors(
     for (std::vector<std::unique_ptr<TupleIdSequence>>::size_type case_idx = 0;
          case_idx < case_matches.size();
          ++case_idx) {
-      DCHECK(!case_results[case_idx]->isNative());
+      DCHECK(case_results[case_idx]->getImplementation() == ColumnVector::kIndirect);
       if (!case_matches[case_idx]->empty()) {
         MultiplexIndirectColumnVector(
             source_sequence,
@@ -509,7 +509,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors(
     }
 
     if (else_result != nullptr) {
-      DCHECK(!else_result->isNative());
+      DCHECK(else_result->getImplementation() == ColumnVector::kIndirect);
       DCHECK(!else_matches.empty());
       MultiplexIndirectColumnVector(source_sequence,
                                     else_matches,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp b/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
index a70a8bc..fcd737e 100644
--- a/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
+++ b/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
@@ -39,6 +39,7 @@ bool WindowAggregateFunctionAvg::canApplyToTypes(
   }
 
   // Argument must be addable and divisible.
+  // TODO(refactor-type): Fix this.
 //  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
 //             .canApplyTo(*argument_types.front(), *argument_types.front()) &&
 //         BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
@@ -66,7 +67,7 @@ const Type* WindowAggregateFunctionAvg::resultTypeForArgumentTypes(
       break;
   }
 
-// TODO
+  // TODO(refactor-type): Fix this.
 //  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
 //             .getResultType(*sum_type, TypeFactory::GetType(kDouble));
   return nullptr;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregateFunctionSum.cpp b/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
index e383c63..09bc4e9 100644
--- a/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
+++ b/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
@@ -39,7 +39,7 @@ bool WindowAggregateFunctionSum::canApplyToTypes(
   }
 
   // Argument must be addable.
-// TODO
+  // TODO(refactor-type): Fix this.
 //  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
 //             .canApplyTo(*argument_types.front(), *argument_types.front());
   return false;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/window_aggregation/WindowAggregationHandle.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregationHandle.cpp b/expressions/window_aggregation/WindowAggregationHandle.cpp
index 7621726..e327a4f 100644
--- a/expressions/window_aggregation/WindowAggregationHandle.cpp
+++ b/expressions/window_aggregation/WindowAggregationHandle.cpp
@@ -82,8 +82,8 @@ WindowAggregationHandle::WindowAggregationHandle(
         TypeFactory::GetUnifyingType(*first_order_key_type, long_type);
 
     range_add_operator_.reset(
-        OperationFactory::Instance().getBinaryOperation(
-            "+", {first_order_key_type->getTypeID(), kLong}, 0)
+        OperationFactory::GetAddOperation(
+            first_order_key_type->getTypeID(), kLong)
                 ->makeUncheckedBinaryOperator(*first_order_key_type, long_type));
     range_comparator_.reset(
         ComparisonFactory::GetComparison(ComparisonID::kLessOrEqual)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregationHandleAvg.cpp b/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
index 3539d03..10272a9 100644
--- a/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
+++ b/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
@@ -69,7 +69,7 @@ WindowAggregationHandleAvg::WindowAggregationHandleAvg(
 
   sum_type_ = &(TypeFactory::GetType(type_id));
 
-// TODO
+  LOG(FATAL) << "TODO(refactor-type)";
 //  // Result is nullable, because AVG() over 0 values (or all NULL values) is
 //  // NULL.
 //  result_type_
@@ -98,7 +98,7 @@ ColumnVector* WindowAggregationHandleAvg::calculate(
     ColumnVectorsValueAccessor *tuple_accessor,
     const std::vector<ColumnVector*> &arguments) const {
   DCHECK_EQ(1u, arguments.size());
-  DCHECK(arguments[0]->isNative());
+  DCHECK(arguments[0]->getImplementation() == ColumnVector::kNative);
   DCHECK_EQ(static_cast<std::size_t>(tuple_accessor->getNumTuples()),
             static_cast<const NativeColumnVector*>(arguments[0])->size());
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/query_optimizer/expressions/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt
index b51a0a8..889c450 100644
--- a/query_optimizer/expressions/CMakeLists.txt
+++ b/query_optimizer/expressions/CMakeLists.txt
@@ -113,8 +113,11 @@ target_link_libraries(quickstep_queryoptimizer_expressions_Cast
                       quickstep_queryoptimizer_expressions_ExpressionType
                       quickstep_queryoptimizer_expressions_PatternMatcher
                       quickstep_queryoptimizer_expressions_Scalar
+                      quickstep_types_MetaType
                       quickstep_types_Type
-                      quickstep_types_operations_unaryoperations_CastOperation
+                      quickstep_types_operations_OperationFactory
+                      quickstep_types_operations_OperationSignature
+                      quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_utility_HashPair
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_expressions_CommonSubexpression
@@ -255,6 +258,8 @@ target_link_libraries(quickstep_queryoptimizer_expressions_Scalar
                       glog
                       quickstep_queryoptimizer_expressions_ExprId
                       quickstep_queryoptimizer_expressions_Expression
+                      quickstep_types_GenericValue
+                      quickstep_types_TypedValue
                       quickstep_utility_HashError
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_expressions_ScalarLiteral
@@ -267,8 +272,8 @@ target_link_libraries(quickstep_queryoptimizer_expressions_ScalarLiteral
                       quickstep_queryoptimizer_expressions_ExpressionType
                       quickstep_queryoptimizer_expressions_PatternMatcher
                       quickstep_queryoptimizer_expressions_Scalar
+                      quickstep_types_GenericValue
                       quickstep_types_Type
-                      quickstep_types_TypedValue
                       quickstep_utility_HashPair
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_expressions_SearchedCase
@@ -327,6 +332,7 @@ target_link_libraries(quickstep_queryoptimizer_expressions_UnaryExpression
                       quickstep_queryoptimizer_expressions_PatternMatcher
                       quickstep_queryoptimizer_expressions_Scalar
                       quickstep_queryoptimizer_expressions_ScalarLiteral
+                      quickstep_types_GenericValue
                       quickstep_types_operations_OperationSignature
                       quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_utility_HashPair
@@ -352,6 +358,7 @@ target_link_libraries(quickstep_queryoptimizer_expressions
                       quickstep_queryoptimizer_expressions_Alias
                       quickstep_queryoptimizer_expressions_AttributeReference
                       quickstep_queryoptimizer_expressions_BinaryExpression
+                      quickstep_queryoptimizer_expressions_Cast
                       quickstep_queryoptimizer_expressions_CommonSubexpression
                       quickstep_queryoptimizer_expressions_ComparisonExpression
                       quickstep_queryoptimizer_expressions_Exists

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/query_optimizer/expressions/Cast.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/Cast.cpp b/query_optimizer/expressions/Cast.cpp
index 6b2015f..2315f92 100644
--- a/query_optimizer/expressions/Cast.cpp
+++ b/query_optimizer/expressions/Cast.cpp
@@ -61,7 +61,7 @@ ExpressionPtr Cast::copyWithNewChildren(
       OperationSignature::Create(
           "cast", {operand_->getValueType().getTypeID(), kMetaType}, 1);
   const UnaryOperationPtr cast_operation =
-      OperationFactory::Instance().getUnaryOperation(op_signature);
+      OperationFactory::GetUnaryOperation(op_signature);
 
   std::vector<TypedValue> meta_type_value =
       { GenericValue::CreateWithLiteral(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 40b460d..b3e8c2c 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -1021,19 +1021,15 @@ 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() == SuperTypeID::kNumeric &&
-          selection_type.getSuperTypeID() == SuperTypeID::kNumeric &&
-          destination_type.isSafelyCoercibleFrom(selection_type)) {
+      if (destination_type.isSafelyCoercibleFrom(selection_type)) {
         // Add cast operation
-//        const E::AttributeReferencePtr attr = selection_attributes[aid];
-//        const E::ExpressionPtr cast_expr =
-//            E::Cast::Create(attr, destination_type);
-//        cast_expressions.emplace_back(
-//            E::Alias::Create(context_->nextExprId(),
-//                             cast_expr,
-//                             attr->attribute_name(),
-//                             attr->attribute_alias()));
-        THROW_SQL_ERROR_AT(insert_statement.relation_name()) << "TODO: not handled";
+        const E::AttributeReferencePtr attr = selection_attributes[aid];
+        const E::ExpressionPtr cast_expr = E::Cast::Create(attr, destination_type);
+        cast_expressions.emplace_back(
+            E::Alias::Create(context_->nextExprId(),
+                             cast_expr,
+                             attr->attribute_name(),
+                             attr->attribute_alias()));
       } else {
         THROW_SQL_ERROR_AT(insert_statement.relation_name())
             << "The assigned value for the column "
@@ -1166,9 +1162,8 @@ L::LogicalPtr Resolver::resolveUpdate(
     // Coerce the assignment expression if its Type is not equal to that of the
     // assigned attribute.
     if (!assignment_expression->getValueType().equals(attribute->getValueType())) {
-//      assignment_expression =
-//          E::Cast::Create(assignment_expression, attribute->getValueType());
-      THROW_SQL_ERROR_AT(&assignment) << "TODO: not handled";
+      assignment_expression =
+          E::Cast::Create(assignment_expression, attribute->getValueType());
     }
     if (assignee_ids.find(attribute->id()) != assignee_ids.end()) {
       THROW_SQL_ERROR_AT(&assignment) << "Multiple assignments to the column "
@@ -1652,12 +1647,11 @@ L::LogicalPtr Resolver::resolveSetOperations(
       if (possible_type.equals(current_type)) {
         cast_expressions.emplace_back(current_attr);
       } else {
-//        cast_expressions.emplace_back(
-//            E::Alias::Create(context_->nextExprId(),
-//                             E::Cast::Create(current_attr, possible_type),
-//                             current_attr->attribute_name(),
-//                             current_attr->attribute_alias()));
-        LOG(FATAL) << "TODO: not handled";
+        cast_expressions.emplace_back(
+            E::Alias::Create(context_->nextExprId(),
+                             E::Cast::Create(current_attr, possible_type),
+                             current_attr->attribute_name(),
+                             current_attr->attribute_alias()));
       }
     }
     resolved_operations[opid] = L::Project::Create(resolved_operations[opid], cast_expressions);
@@ -2555,11 +2549,19 @@ E::ScalarPtr Resolver::resolveExpression(
     case ParseExpression::kTypeCast: {
       const ParseTypeCast &parse_type_cast =
           static_cast<const ParseTypeCast&>(parse_expression);
-      return E::Cast::Create(
+      const E::ScalarPtr operand =
           resolveExpression(parse_type_cast.operand(),
                             nullptr /* type_hint */,
-                            expression_resolution_info),
-          resolveDataType(parse_type_cast.target_type()));
+                            expression_resolution_info);
+      const Type &target_type =
+          resolveDataType(parse_type_cast.target_type());
+      if (!OperationFactory::CanApplyCastOperation(operand->getValueType(),
+                                                   target_type)) {
+        THROW_SQL_ERROR_AT(&parse_type_cast)
+            << "Cannot cast from " << operand->getValueType().getName()
+            << " type to " << target_type.getName() << " type";
+      }
+      return E::Cast::Create(operand, target_type);
     }
     default:
       LOG(FATAL) << "Unknown scalar type: "
@@ -2580,7 +2582,7 @@ E::ScalarPtr Resolver::resolveArray(
     return E::ScalarLiteral::Create(
         GenericValue::CreateWithLiteral(
             ArrayType::InstanceNonNullable({meta_null_type_value}),
-            ArrayLiteral()));
+            ArrayLit(NullType::InstanceNullable())));
   } else {
     // Currently we only support homogeneous array with literal values.
     std::vector<E::ScalarLiteralPtr> literals;
@@ -2617,9 +2619,9 @@ E::ScalarPtr Resolver::resolveArray(
         ArrayType::InstanceNonNullable({meta_element_type_value});
 
     // NOTE(refactor-type): Possibly memory leak region, noexcept.
-    std::unique_ptr<ArrayLiteral> array_literal = std::make_unique<ArrayLiteral>();
+    std::unique_ptr<ArrayLit> array_literal = std::make_unique<ArrayLit>(*element_type);
     for (const auto &literal : literals) {
-      array_literal->emplace_back(
+      array_literal->push_back(
           element_type->cloneValue(literal->value().getValue()));
     }
     return E::ScalarLiteral::Create(
@@ -2715,15 +2717,13 @@ E::ScalarPtr Resolver::resolveSearchedCaseExpression(
   // Cast all the result expressions to the same type.
   for (E::ScalarPtr &conditional_result_expression : conditional_result_expressions) {
     if (conditional_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-//      conditional_result_expression =
-//          E::Cast::Create(conditional_result_expression, *result_data_type);
-      LOG(FATAL) << "TODO: not handled";
+      conditional_result_expression =
+          E::Cast::Create(conditional_result_expression, *result_data_type);
     }
   }
   if (else_result_expression != nullptr
       && else_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-//    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
-    LOG(FATAL) << "TODO: not handled";
+    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
   }
 
   if (else_result_expression == nullptr) {
@@ -2861,15 +2861,13 @@ E::ScalarPtr Resolver::resolveSimpleCaseExpression(
   // Cast all the result expressions to the same type.
   for (E::ScalarPtr &conditional_result_expression : conditional_result_expressions) {
     if (conditional_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-//      conditional_result_expression =
-//          E::Cast::Create(conditional_result_expression, *result_data_type);
-      LOG(FATAL) << "TODO: not handled";
+      conditional_result_expression =
+          E::Cast::Create(conditional_result_expression, *result_data_type);
     }
   }
   if (else_result_expression != nullptr
       && else_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-//    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
-    LOG(FATAL) << "TODO: not handled";
+    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
   }
 
   if (else_result_expression == nullptr) {
@@ -2913,7 +2911,7 @@ E::ScalarPtr Resolver::resolveScalarFunction(
   std::shared_ptr<const std::vector<GenericValue>> coerced_static_arguments;
   std::string message;
   const OperationSignaturePtr op_signature =
-      OperationFactory::Instance().resolveOperation(
+      OperationFactory::ResolveOperation(
           function_name,
           std::make_shared<const std::vector<const Type*>>(std::move(argument_types)),
           std::make_shared<const std::vector<GenericValue>>(std::move(static_arguments)),
@@ -2933,8 +2931,7 @@ E::ScalarPtr Resolver::resolveScalarFunction(
   // TODO: add cast if neccessary.
   (void)coerced_argument_types;
 
-  const OperationPtr operation =
-      OperationFactory::Instance().getOperation(op_signature);
+  const OperationPtr operation = OperationFactory::GetOperation(op_signature);
   switch (operation->getOperationSuperTypeID()) {
     case Operation::kUnaryOperation:
       return E::UnaryExpression::Create(
@@ -3005,8 +3002,7 @@ E::ScalarPtr Resolver::resolveFunctionCall(
     }
   }
 
-  if (OperationFactory::Instance().hasOperation(function_name,
-                                                resolved_arguments.size())) {
+  if (OperationFactory::HasOperation(function_name, resolved_arguments.size())) {
     E::ScalarPtr scalar = resolveScalarFunction(parse_function_call,
                                                 function_name,
                                                 resolved_arguments,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/query_optimizer/rules/Partition.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/Partition.cpp b/query_optimizer/rules/Partition.cpp
index d55d296..0e21b98 100644
--- a/query_optimizer/rules/Partition.cpp
+++ b/query_optimizer/rules/Partition.cpp
@@ -416,7 +416,7 @@ P::PhysicalPtr Partition::applyToNode(const P::PhysicalPtr &node) {
                   get<2>(avg_recompute_expression)->getValueType().getTypeID() },
                 0);
         const BinaryOperationPtr divide_op =
-            OperationFactory::Instance().getBinaryOperation(op_sig);
+            OperationFactory::GetBinaryOperation(op_sig);
         const E::BinaryExpressionPtr new_avg_expr =
             E::BinaryExpression::Create(op_sig,
                                         divide_op,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/query_optimizer/rules/ReuseAggregateExpressions.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/ReuseAggregateExpressions.cpp b/query_optimizer/rules/ReuseAggregateExpressions.cpp
index d63715a..65832e7 100644
--- a/query_optimizer/rules/ReuseAggregateExpressions.cpp
+++ b/query_optimizer/rules/ReuseAggregateExpressions.cpp
@@ -324,7 +324,7 @@ P::PhysicalPtr ReuseAggregateExpressions::applyToNode(
               OperationSignature::Create("/", operand_tids, 0);
 
           const BinaryOperationPtr &divide_op =
-              OperationFactory::Instance().getBinaryOperation(op_sig);
+              OperationFactory::GetBinaryOperation(op_sig);
           const E::BinaryExpressionPtr avg_expr =
               E::BinaryExpression::Create(op_sig,
                                           divide_op,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/storage/SMAIndexSubBlock.cpp
----------------------------------------------------------------------
diff --git a/storage/SMAIndexSubBlock.cpp b/storage/SMAIndexSubBlock.cpp
index 5a8a747..2f7c474 100644
--- a/storage/SMAIndexSubBlock.cpp
+++ b/storage/SMAIndexSubBlock.cpp
@@ -358,10 +358,9 @@ SMAIndexSubBlock::SMAIndexSubBlock(const TupleStorageSubBlock &tuple_store,
       TypeID attr_sum_typeid = sma_internal::getTypeForSum(attr_typeid);
       if (add_operations_.elementIsNullAt(attr_typeid)) {
         add_operations_.replaceElement(attr_typeid,
-            OperationFactory::Instance().getBinaryOperation(
-                "+", {attr_typeid, attr_sum_typeid})
-                    ->makeUncheckedBinaryOperator(TypeFactory::GetType(attr_typeid),
-                                                  TypeFactory::GetType(attr_sum_typeid)));
+            OperationFactory::GetAddOperation(attr_typeid, attr_sum_typeid)
+                ->makeUncheckedBinaryOperator(TypeFactory::GetType(attr_typeid),
+                                              TypeFactory::GetType(attr_sum_typeid)));
       }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/storage/WindowAggregationOperationState.cpp
----------------------------------------------------------------------
diff --git a/storage/WindowAggregationOperationState.cpp b/storage/WindowAggregationOperationState.cpp
index 30d91db..2b63a6c 100644
--- a/storage/WindowAggregationOperationState.cpp
+++ b/storage/WindowAggregationOperationState.cpp
@@ -261,7 +261,7 @@ void WindowAggregationOperationState::windowAggregateBlocks(
 
         for (std::size_t attr_id = 0; attr_id < attribute_vecs.size(); ++attr_id) {
           ColumnVector *attr_vec = attribute_vecs[attr_id];
-          if (attr_vec->isNative()) {
+          if (attr_vec->getImplementation() == ColumnVector::kNative) {
             static_cast<NativeColumnVector*>(attr_vec)->appendTypedValue(
                 tuple_accessor->getTypedValue(attr_id));
           } else {
@@ -274,7 +274,7 @@ void WindowAggregationOperationState::windowAggregateBlocks(
              argument_idx < argument_vecs.size();
              ++argument_idx) {
           ColumnVector *argument = argument_vecs[argument_idx];
-          if (argument->isNative()) {
+          if (argument->getImplementation() == ColumnVector::kNative) {
             static_cast<NativeColumnVector*>(argument)->appendTypedValue(
                 argument_accessor->getTypedValue(argument_idx));
           } else {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/ArrayLit.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayLit.hpp b/types/ArrayLit.hpp
new file mode 100644
index 0000000..b5d3548
--- /dev/null
+++ b/types/ArrayLit.hpp
@@ -0,0 +1,112 @@
+/**
+ * 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_LIT_HPP_
+#define QUICKSTEP_TYPES_ARRAY_LIT_HPP_
+
+#include <cstddef>
+#include <vector>
+
+#include "types/Type.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+typedef void UntypedLiteral;
+
+class ArrayLit {
+ public:
+  using const_iterator = std::vector<UntypedLiteral*>::const_iterator;
+
+  ArrayLit(const Type &type)
+      : type_(type) {
+  }
+
+  ArrayLit(const ArrayLit &other)
+      : type_(other.type_) {
+    for (const UntypedLiteral *value :other.elements_) {
+      elements_.emplace_back(type_.cloneValue(value));
+    }
+  }
+
+  ArrayLit(ArrayLit &&other)
+      : type_(other.type_),
+        elements_(std::move(other.elements_)) {
+  }
+
+  ~ArrayLit() {
+    clear();
+  }
+
+  void clear() {
+    for (UntypedLiteral *value : elements_) {
+      type_.destroyValue(value);
+    }
+    elements_.clear();
+  }
+
+  bool empty() const {
+    return elements_.empty();
+  }
+
+  std::size_t size() const {
+    return elements_.size();
+  }
+
+
+  void push_back(UntypedLiteral *value) {
+    elements_.emplace_back(value);
+  }
+
+  const UntypedLiteral* operator[](const std::size_t idx) const {
+    DCHECK_LT(idx, elements_.size());
+    return elements_[idx];
+  }
+
+  const_iterator begin() const {
+    return elements_.begin();
+  }
+
+  const_iterator end() const {
+    return elements_.end();
+  }
+
+  const UntypedLiteral* front() const {
+    return elements_.front();
+  }
+
+  const UntypedLiteral* back() const {
+    return elements_.back();
+  }
+
+ private:
+  const Type &type_;
+  std::vector<UntypedLiteral*> elements_;
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_NULL_LIT_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/ArrayType.cpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.cpp b/types/ArrayType.cpp
index 765a1a0..8d8313f 100644
--- a/types/ArrayType.cpp
+++ b/types/ArrayType.cpp
@@ -22,6 +22,7 @@
 #include <cstdlib>
 #include <string>
 
+#include "types/ArrayLit.hpp"
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 
@@ -39,6 +40,15 @@ std::string ArrayType::getName() const {
   return name;
 }
 
+bool ArrayType::isCoercibleFrom(const Type &original_type) const {
+  if (original_type.getTypeID() != kArray) {
+    return false;
+  }
+  const Type &original_element_type =
+      static_cast<const ArrayType&>(original_type).element_type_;
+  return element_type_.isCoercibleFrom(original_element_type);
+}
+
 bool ArrayType::TypeParametersAreValid(const std::vector<GenericValue> &parameters) {
   if (parameters.size() != 1u) {
     return false;
@@ -52,13 +62,13 @@ bool ArrayType::checkValuesEqual(const UntypedLiteral *lhs,
   if (!equals(rhs_type)) {
     return false;
   }
-  const ArrayLiteral &lhs_array = castValueToLiteral(lhs);
-  const ArrayLiteral &rhs_array = castValueToLiteral(rhs);
+  const ArrayLit &lhs_array = castValueToLiteral(lhs);
+  const ArrayLit &rhs_array = castValueToLiteral(rhs);
   if (lhs_array.size() != rhs_array.size()) {
     return false;
   }
   for (std::size_t i = 0; i < lhs_array.size(); ++i) {
-    if (!element_type_.checkValuesEqual(lhs_array.at(i), rhs_array.at(i))) {
+    if (!element_type_.checkValuesEqual(lhs_array[i], rhs_array[i])) {
       return false;
     }
   }
@@ -66,8 +76,8 @@ bool ArrayType::checkValuesEqual(const UntypedLiteral *lhs,
 }
 
 TypedValue ArrayType::marshallValue(const UntypedLiteral *value) const {
-  const ArrayLiteral &array = *static_cast<const ArrayLiteral*>(value);
-  serialization::ArrayLiteral proto;
+  const ArrayLit &array = *static_cast<const ArrayLit*>(value);
+  serialization::ArrayLit proto;
   for (const auto &element : array) {
     // TODO(refactor-type): Improve performance.
     TypedValue value = element_type_.marshallValue(element);
@@ -81,12 +91,12 @@ TypedValue ArrayType::marshallValue(const UntypedLiteral *value) const {
 
 UntypedLiteral* ArrayType::unmarshallValue(const void *data,
                                            const std::size_t data_size) const {
-  std::unique_ptr<ArrayLiteral> array = std::make_unique<ArrayLiteral>();
-  serialization::ArrayLiteral proto;
+  std::unique_ptr<ArrayLit> array = std::make_unique<ArrayLit>(element_type_);
+  serialization::ArrayLit proto;
   proto.ParseFromArray(data, data_size);
   for (int i = 0; i < proto.data_size(); ++i) {
     const std::string &element_data = proto.data(i);
-    array->emplace_back(
+    array->push_back(
         element_type_.unmarshallValue(element_data.c_str(), element_data.size()));
   }
   return array.release();
@@ -95,13 +105,13 @@ UntypedLiteral* ArrayType::unmarshallValue(const void *data,
 std::string ArrayType::printValueToString(const UntypedLiteral *value) const {
   DCHECK(value != nullptr);
 
-  const std::vector<UntypedLiteral*> &literals = castValueToLiteral(value);
+  const ArrayLit &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(element_type_.printValueToString(literals[i]));
     }
   }
   ret.append("}");

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/ArrayType.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp
index 5eaff92..e79e389 100644
--- a/types/ArrayType.hpp
+++ b/types/ArrayType.hpp
@@ -39,7 +39,7 @@ class TypedValue;
  *  @{
  */
 
-class ArrayType : public TypeSynthesizer<kArray> {
+class ArrayType final : public TypeSynthesizer<kArray> {
  public:
   int getPrintWidth() const override {
     return 32;
@@ -47,6 +47,8 @@ class ArrayType : public TypeSynthesizer<kArray> {
 
   std::string getName() const override;
 
+  bool isCoercibleFrom(const Type &original_type) const override;
+
   bool checkValuesEqual(const UntypedLiteral *lhs,
                         const UntypedLiteral *rhs,
                         const Type &rhs_type) const override;
@@ -63,6 +65,10 @@ class ArrayType : public TypeSynthesizer<kArray> {
     return false;
   }
 
+  const Type &getElementType() const {
+    return element_type_;
+  }
+
   static bool TypeParametersAreValid(const std::vector<GenericValue> &parameters);
 
  private:
@@ -73,7 +79,7 @@ class ArrayType : public TypeSynthesizer<kArray> {
 
   static const Type& ExtractType(const std::vector<GenericValue> &parameters) {
     DCHECK(TypeParametersAreValid(parameters));
-    return **static_cast<const MetaTypeLiteral*>(parameters.front().getValue());
+    return **static_cast<const MetaTypeLit*>(parameters.front().getValue());
   }
 
   const Type &element_type_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/AsciiStringSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/AsciiStringSuperType.hpp b/types/AsciiStringSuperType.hpp
index 7de550f..252a1a7 100644
--- a/types/AsciiStringSuperType.hpp
+++ b/types/AsciiStringSuperType.hpp
@@ -38,14 +38,6 @@ namespace quickstep {
 template <TypeID type_id>
 class AsciiStringSuperType : public TypeSynthesizer<type_id> {
  public:
-  bool isCoercibleFrom(const Type &original_type) const override {
-    if (original_type.isNullable() && !this->nullable_) {
-      return false;
-    }
-    return (original_type.getSuperTypeID() == SuperTypeID::kAsciiString)
-           || (original_type.getTypeID() == kNullType);
-  }
-
   /**
    * @brief Get the character-length of this string type.
    *

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/BoolType.hpp
----------------------------------------------------------------------
diff --git a/types/BoolType.hpp b/types/BoolType.hpp
index ed819ae..49fbfa3 100644
--- a/types/BoolType.hpp
+++ b/types/BoolType.hpp
@@ -41,7 +41,7 @@ class TypedValue;
 /**
  * @brief A type representing a 8-bit bool.
  **/
-class BoolType : public NumericSuperType<kBool> {
+class BoolType final : public NumericSuperType<kBool> {
  public:
   int getPrintWidth() const override {
     // "true" or "false"

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 0ee4f26..271700b 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_ArrayLit ../empty_src.cpp ArrayLit.hpp)
 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)
@@ -185,6 +186,7 @@ target_link_libraries(quickstep_types_MetaType-decl
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypeSynthesizer
+                      quickstep_types_TypedValue
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_NullType
                       glog
@@ -203,6 +205,7 @@ target_link_libraries(quickstep_types_NumericSuperType
                       quickstep_utility_Macros
                       quickstep_utility_meta_TMP)
 target_link_libraries(quickstep_types_NumericTypeSafeCoercibility
+                      quickstep_types_TypeRegistrar
                       quickstep_utility_meta_TMP)
 target_link_libraries(quickstep_types_NumericTypeUnifier
                       quickstep_types_NumericTypeSafeCoercibility)
@@ -228,7 +231,8 @@ target_link_libraries(quickstep_types_TypeFactory
                       quickstep_types_TypeSynthesizer
                       quickstep_types_TypeUtil
                       quickstep_types_Type_proto
-                      quickstep_utility_Macros)
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
 target_link_libraries(quickstep_types_TypeFactory-decl
                       glog
                       quickstep_types_GenericValue
@@ -254,6 +258,7 @@ target_link_libraries(quickstep_types_TypeSynthesizer
                       quickstep_types_TypeRegistrar
                       quickstep_types_TypedValue
                       quickstep_types_Type_proto
+                      quickstep_types_operations_utility_CastUtil
                       quickstep_utility_HashPair
                       quickstep_utility_Macros
                       quickstep_utility_meta_Common)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/CharType.hpp
----------------------------------------------------------------------
diff --git a/types/CharType.hpp b/types/CharType.hpp
index 3355243..cfd695e 100644
--- a/types/CharType.hpp
+++ b/types/CharType.hpp
@@ -43,7 +43,7 @@ namespace quickstep {
  *       represented WITHOUT a null-terminator character. Any strings shorter
  *       than the maximum length will have a null-terminator.
  **/
-class CharType : public AsciiStringSuperType<kChar> {
+class CharType final : public AsciiStringSuperType<kChar> {
  public:
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/DateType.hpp
----------------------------------------------------------------------
diff --git a/types/DateType.hpp b/types/DateType.hpp
index 1c9eaf9..b88bb82 100644
--- a/types/DateType.hpp
+++ b/types/DateType.hpp
@@ -41,7 +41,7 @@ class TypedValue;
 /**
  * @brief A type representing the date.
  **/
-class DateType : public TypeSynthesizer<kDate> {
+class DateType final : public TypeSynthesizer<kDate> {
  public:
   int getPrintWidth() const override {
     return DateLit::kIsoChars;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/DatetimeIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp
index cb2534d..b80b2a7 100644
--- a/types/DatetimeIntervalType.hpp
+++ b/types/DatetimeIntervalType.hpp
@@ -41,7 +41,7 @@ namespace quickstep {
 /**
  * @brief A type representing the datetime interval.
  **/
-class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> {
+class DatetimeIntervalType final : public TypeSynthesizer<kDatetimeInterval> {
  public:
   int getPrintWidth() const override {
     return DatetimeIntervalLit::kPrintingChars;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/DatetimeType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp
index d0ac1e2..dbad0e2 100644
--- a/types/DatetimeType.hpp
+++ b/types/DatetimeType.hpp
@@ -41,8 +41,7 @@ class TypedValue;
 /**
  * @brief A type representing the datetime.
  **/
-class DatetimeType
-    : public TypeSynthesizer<kDatetime> {
+class DatetimeType final : public TypeSynthesizer<kDatetime> {
  public:
   int getPrintWidth() const override {
     return DatetimeLit::kIsoChars;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/DoubleType.hpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp
index 6959817..3e906db 100644
--- a/types/DoubleType.hpp
+++ b/types/DoubleType.hpp
@@ -40,7 +40,7 @@ class TypedValue;
 /**
  * @brief A type representing a double-precision floating-point number.
  **/
-class DoubleType : public NumericSuperType<kDouble> {
+class DoubleType final : public NumericSuperType<kDouble> {
  public:
   int getPrintWidth() const override {
     return kPrintWidth;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/FloatType.hpp
----------------------------------------------------------------------
diff --git a/types/FloatType.hpp b/types/FloatType.hpp
index 3a7aa41..e9062e0 100644
--- a/types/FloatType.hpp
+++ b/types/FloatType.hpp
@@ -40,7 +40,7 @@ class TypedValue;
 /**
  * @brief A type representing a single-precision floating-point number.
  **/
-class FloatType : public NumericSuperType<kFloat> {
+class FloatType final : public NumericSuperType<kFloat> {
  public:
   int getPrintWidth() const override {
     return kPrintWidth;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/IntType.hpp
----------------------------------------------------------------------
diff --git a/types/IntType.hpp b/types/IntType.hpp
index eb5e5aa..7b42906 100644
--- a/types/IntType.hpp
+++ b/types/IntType.hpp
@@ -40,7 +40,7 @@ class TypedValue;
 /**
  * @brief A type representing a 32-bit integer.
  **/
-class IntType : public NumericSuperType<kInt> {
+class IntType final : public NumericSuperType<kInt> {
  public:
   int getPrintWidth() const override {
     // Fully represented digits, single leading digit, and possible '-'

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/LongType.hpp
----------------------------------------------------------------------
diff --git a/types/LongType.hpp b/types/LongType.hpp
index dc75310..3cd3fc0 100644
--- a/types/LongType.hpp
+++ b/types/LongType.hpp
@@ -41,7 +41,7 @@ class TypedValue;
 /**
  * @brief A type representing a 64-bit integer.
  **/
-class LongType : public NumericSuperType<kLong> {
+class LongType final : public NumericSuperType<kLong> {
  public:
   // Fully represented digits, single leading digit, and possible '-'
   // character.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/MetaType-decl.hpp
----------------------------------------------------------------------
diff --git a/types/MetaType-decl.hpp b/types/MetaType-decl.hpp
index 80c5956..569c956 100644
--- a/types/MetaType-decl.hpp
+++ b/types/MetaType-decl.hpp
@@ -37,7 +37,7 @@ namespace quickstep {
  *  @{
  */
 
-class MetaType : public TypeSynthesizer<kMetaType> {
+class MetaType final : public TypeSynthesizer<kMetaType> {
  public:
   int getPrintWidth() const override {
     return 16;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/MetaType.cpp
----------------------------------------------------------------------
diff --git a/types/MetaType.cpp b/types/MetaType.cpp
index 16a86c2..f3da71b 100644
--- a/types/MetaType.cpp
+++ b/types/MetaType.cpp
@@ -51,7 +51,7 @@ UntypedLiteral* MetaType::unmarshallValue(const void *data,
                                           const std::size_t data_size) const {
   serialization::Type proto;
   proto.ParseFromArray(data, data_size);
-  return new MetaTypeLiteral(&TypeFactory::ReconstructFromProto(proto));
+  return new MetaTypeLit(&TypeFactory::ReconstructFromProto(proto));
 }
 
 std::string MetaType::printValueToString(const UntypedLiteral *value) const {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/NullType.hpp
----------------------------------------------------------------------
diff --git a/types/NullType.hpp b/types/NullType.hpp
index 1aa8a1c..ae448ea 100644
--- a/types/NullType.hpp
+++ b/types/NullType.hpp
@@ -49,7 +49,7 @@ class TypedValue;
  *       a particular operation may accept. It is also assumed that applying
  *       any operation to an argument of NullType always yields NULL values.
  **/
-class NullType : public TypeSynthesizer<kNullType> {
+class NullType final : public TypeSynthesizer<kNullType> {
  public:
   static const NullType& InstanceNonNullable() {
     LOG(FATAL) << "Called NullType::InstanceNonNullable(), "

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index f474d52..6a6ad96 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -53,11 +53,6 @@ class NumericSuperType : public TypeSynthesizer<type_id> {
     return it != safe_coerce_cache_.end();
   }
 
-  bool isCoercibleFrom(const Type &original_type) const override {
-    QUICKSTEP_NULL_COERCIBILITY_CHECK();
-    return (original_type.getSuperTypeID() == SuperTypeID::kNumeric);
-  }
-
   TypedValue makeZeroValue() const override {
     return TypedValue(static_cast<typename TypeIDTrait<type_id>::cpptype>(0));
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/TextType.hpp
----------------------------------------------------------------------
diff --git a/types/TextType.hpp b/types/TextType.hpp
index 9ceea35..a1fc04e 100644
--- a/types/TextType.hpp
+++ b/types/TextType.hpp
@@ -36,7 +36,7 @@ namespace quickstep {
  *  @{
  */
 
-class TextType : public TypeSynthesizer<kText> {
+class TextType final : public TypeSynthesizer<kText> {
  public:
   int getPrintWidth() const override {
     return 32;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index 41780f8..cbfd8dd 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -28,10 +28,6 @@
 
 namespace quickstep {
 
-bool Type::isCoercibleFrom(const Type &original_type) const {
-  return isSafelyCoercibleFrom(original_type);
-}
-
 bool Type::isSafelyCoercibleFrom(const Type &original_type) const {
   if (original_type.isNullable() && !this->nullable_) {
     return false;
@@ -79,20 +75,10 @@ TypedValue Type::coerceTypedValue(const TypedValue &original_value,
 
 UntypedLiteral* Type::coerceValue(const UntypedLiteral *original_value,
                                   const Type &original_type) const {
-  DCHECK(isCoercibleFrom(original_type))
-      << "Can't coerce value of Type " << original_type.getName()
-      << " to Type " << getName();
-
-  if (original_type.getTypeID() == kNullType) {
-    return nullptr;
-  }
-
-  DCHECK(equals(original_type) || equals(original_type.getNullableVersion()))
-      << "Base version of Type::coerceValue() called for a non-trivial "
-      << "coercion from Type " << original_type.getName()
-      << " to Type " << getName();
-
-  return cloneValue(original_value);
+  // TODO(refactor-type): Implement coerceValue based on CastFunctor.
+  TypedValue original_tv = original_type.marshallValue(original_value);
+  TypedValue target_tv = coerceTypedValue(original_tv, original_type);
+  return unmarshallTypedValue(target_tv);
 }
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index e5d5528..0929bc7 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -126,6 +126,10 @@ class Type {
     return type_id_;
   }
 
+  inline MemoryLayout getMemoryLayout() const {
+    return memory_layout_;
+  }
+
   /**
    * @brief Determine whether this Type allows NULL values.
    *
@@ -223,7 +227,7 @@ class Type {
    * @param original_type The original Type for coercion to this Type.
    * @return true if coercion is supported, false otherwise.
    **/
-  virtual bool isCoercibleFrom(const Type &original_type) const;
+  virtual bool isCoercibleFrom(const Type &original_type) const = 0;
 
   /**
    * @brief Determine whether data items of another type can be coerced (used
@@ -431,11 +435,13 @@ class Type {
  protected:
   Type(const SuperTypeID super_type_id,
        const TypeID type_id,
+       const MemoryLayout memory_layout,
        const bool nullable,
        const std::size_t minimum_byte_length,
        const std::size_t maximum_byte_length)
       : super_type_id_(super_type_id),
         type_id_(type_id),
+        memory_layout_(memory_layout),
         nullable_(nullable),
         minimum_byte_length_(minimum_byte_length),
         maximum_byte_length_(maximum_byte_length) {
@@ -443,6 +449,7 @@ class Type {
 
   const SuperTypeID super_type_id_;
   const TypeID type_id_;
+  const MemoryLayout memory_layout_;
   const bool nullable_;
   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/4bf0857c/types/Type.proto
----------------------------------------------------------------------
diff --git a/types/Type.proto b/types/Type.proto
index 8092953..5882b8c 100644
--- a/types/Type.proto
+++ b/types/Type.proto
@@ -35,6 +35,6 @@ message GenericValue {
   optional bytes data = 2;
 }
 
-message ArrayLiteral {
+message ArrayLit {
   repeated bytes data = 1;
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/TypeRegistrar.hpp
----------------------------------------------------------------------
diff --git a/types/TypeRegistrar.hpp b/types/TypeRegistrar.hpp
index bb6c40d..d72788b 100644
--- a/types/TypeRegistrar.hpp
+++ b/types/TypeRegistrar.hpp
@@ -43,13 +43,13 @@ namespace quickstep {
 
 class Type;
 class TypedValue;
+class ArrayLit;
 
 using UntypedLiteral = void;
 
-using ArrayLiteral = std::vector<UntypedLiteral*>;
-using MetaTypeLiteral = const Type*;
-using ParInlinePodLiteral = const void*;
-using ParOutOfLinePodLiteral = TypedValue;
+using MetaTypeLit = const Type*;
+using ParInlinePodLit = const void*;
+using ParOutOfLinePodLit = TypedValue;
 
 template <TypeID type_id>
 struct TypeIDTrait;
@@ -85,15 +85,15 @@ REGISTER_TYPE(DatetimeIntervalType, kDatetimeInterval,
 REGISTER_TYPE(YearMonthIntervalType, kYearMonthInterval,
               SuperTypeID::kOther, kCxxInlinePod, YearMonthIntervalLit);
 REGISTER_TYPE(CharType, kChar,
-              SuperTypeID::kAsciiString, kParInlinePod, ParInlinePodLiteral);
+              SuperTypeID::kAsciiString, kParInlinePod, ParInlinePodLit);
 REGISTER_TYPE(VarCharType, kVarChar,
-              SuperTypeID::kAsciiString, kParOutOfLinePod, ParOutOfLinePodLiteral);
+              SuperTypeID::kAsciiString, kParOutOfLinePod, ParOutOfLinePodLit);
 REGISTER_TYPE(TextType, kText,
               SuperTypeID::kOther, kCxxGeneric, std::string);
 REGISTER_TYPE(ArrayType, kArray,
-              SuperTypeID::kOther, kCxxGeneric, ArrayLiteral);
+              SuperTypeID::kOther, kCxxGeneric, ArrayLit);
 REGISTER_TYPE(MetaType, kMetaType,
-              SuperTypeID::kOther, kCxxGeneric, MetaTypeLiteral);
+              SuperTypeID::kOther, kCxxGeneric, MetaTypeLit);
 REGISTER_TYPE(NullType, kNullType,
               SuperTypeID::kOther, kCxxInlinePod, NullLit);
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index d69b1b4..23d072c 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -30,12 +30,15 @@
 #include <unordered_map>
 #include <vector>
 
+#include "types/ArrayLit.hpp"
 #include "types/GenericValue.hpp"
 #include "types/Type.hpp"
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 #include "types/TypeRegistrar.hpp"
 #include "types/TypedValue.hpp"
+#include "types/operations/utility/CastUtil.hpp"
+#include "utility/Cast.hpp"
 #include "utility/HashPair.hpp"
 #include "utility/Macros.hpp"
 #include "utility/meta/Common.hpp"
@@ -90,6 +93,8 @@ class TypeSynthesizePolicy<
   bool checkValuesEqual(const UntypedLiteral *lhs,
                         const UntypedLiteral *rhs,
                         const Type &rhs_type) const override {
+    DCHECK(lhs != nullptr);
+    DCHECK(rhs != nullptr);
     // TODO(refactor-type): Operator == overloading.
     if (type_id_ != rhs_type.getTypeID()) {
       return false;
@@ -110,15 +115,18 @@ class TypeSynthesizePolicy<
   }
 
   std::size_t hashValue(const UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
     return hashValueInl<sizeof(cpptype)>(value);
   }
 
   TypedValue marshallValue(const UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
     return makeValue(value, sizeof(cpptype)).ensureNotReference();
   }
 
   UntypedLiteral* unmarshallValue(const void *data,
                                   const std::size_t length) const override {
+    DCHECK(data != nullptr);
     DCHECK_EQ(sizeof(cpptype), length);
     UntypedLiteral *value = std::malloc(sizeof(cpptype));
     std::memcpy(value, data, sizeof(cpptype));
@@ -127,7 +135,7 @@ class TypeSynthesizePolicy<
 
  protected:
   explicit TypeSynthesizePolicy(const bool nullable)
-      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+      : Type(Trait::kStaticSuperTypeID, type_id, kCxxInlinePod, nullable,
              sizeof(cpptype), sizeof(cpptype)) {}
 
   inline const Type& getInstance(const bool nullable) const {
@@ -216,6 +224,7 @@ class TypeSynthesizePolicy<
 
   std::size_t hashValue(const UntypedLiteral *value) const override {
     // TODO(refactor-type): Implementation.
+    DCHECK(value != nullptr);
     return TypedValue(type_id_,
                       *static_cast<const cpptype*>(value),
                       maximum_byte_length_).getHash();
@@ -224,6 +233,8 @@ class TypeSynthesizePolicy<
   bool checkValuesEqual(const UntypedLiteral *lhs,
                         const UntypedLiteral *rhs,
                         const Type &rhs_type) const override {
+    DCHECK(lhs != nullptr);
+    DCHECK(rhs != nullptr);
     if (!equals(rhs_type)) {
       return false;
     }
@@ -254,6 +265,7 @@ class TypeSynthesizePolicy<
 
   UntypedLiteral* unmarshallValue(const void *data,
                                   const std::size_t length) const override {
+    DCHECK(data != nullptr);
     DCHECK_EQ(maximum_byte_length_, length);
     void *value = std::malloc(maximum_byte_length_);
     std::memcpy(value, data, length);
@@ -265,7 +277,7 @@ class TypeSynthesizePolicy<
                        const std::size_t minimum_byte_length,
                        const std::size_t maximum_byte_length,
                        const std::size_t length)
-      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+      : Type(Trait::kStaticSuperTypeID, type_id, kParInlinePod, nullable,
              minimum_byte_length, maximum_byte_length),
         length_(length) {}
 
@@ -345,6 +357,7 @@ class TypeSynthesizePolicy<
 
   std::size_t hashValue(const UntypedLiteral *value) const override {
     // TODO(refactor-type): Better implementation.
+    DCHECK(value != nullptr);
     return static_cast<const TypedValue*>(value)->getHash();
   }
 
@@ -368,11 +381,13 @@ class TypeSynthesizePolicy<
   }
 
   TypedValue marshallValue(const UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
     return *static_cast<const TypedValue*>(value);
   }
 
   UntypedLiteral* unmarshallValue(const void *data,
                                   const std::size_t length) const override {
+    DCHECK(data != nullptr);
     TypedValue *value = new TypedValue(makeValue(data, length));
     value->ensureNotReference();
     return value;
@@ -383,7 +398,7 @@ class TypeSynthesizePolicy<
                        const std::size_t minimum_byte_length,
                        const std::size_t maximum_byte_length,
                        const std::size_t length)
-      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+      : Type(Trait::kStaticSuperTypeID, type_id, kParOutOfLinePod, nullable,
              minimum_byte_length, maximum_byte_length),
         length_(length) {}
 
@@ -504,7 +519,7 @@ class TypeSynthesizePolicy<
                        const std::size_t minimum_byte_length,
                        const std::size_t maximum_byte_length,
                        const std::vector<GenericValue> &parameters)
-      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+      : Type(Trait::kStaticSuperTypeID, type_id, kCxxGeneric, nullable,
              minimum_byte_length, maximum_byte_length),
         parameters_(parameters) {}
 
@@ -619,6 +634,11 @@ class TypeSynthesizer : public TypeSynthesizePolicy<type_id> {
     return SynthesizePolicy::getInstance(false);
   }
 
+  bool isCoercibleFrom(const Type &original_type) const override {
+    auto it = kCoercibleSourceTypeIDs.find(original_type.getTypeID());
+    return it != kCoercibleSourceTypeIDs.end();
+  };
+
   UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override {
     return SynthesizePolicy::unmarshallTypedValueInl(value);
   }
@@ -680,6 +700,8 @@ class TypeSynthesizer : public TypeSynthesizePolicy<type_id> {
  private:
   template <TypeID, typename> friend class TypeSynthesizePolicy;
 
+  static const std::unordered_set<TypeID> kCoercibleSourceTypeIDs;
+
   DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
 };
 
@@ -695,6 +717,10 @@ constexpr bool TypeSynthesizer<type_id>::kIsParPod;
 template <TypeID type_id>
 constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout;
 
+template <TypeID type_id>
+const std::unordered_set<TypeID> TypeSynthesizer<type_id>::kCoercibleSourceTypeIDs =
+    CastSTLContainer<std::unordered_set<TypeID>>(
+        CastUtil::GetCoercibleSourceTypeIDs(type_id));
 
 #define QUICKSTEP_SYNTHESIZE_TYPE(type) \
   template <TypeID, typename> friend class TypeSynthesizePolicy; \

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/VarCharType.hpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp
index 0b16061..639d0fb 100644
--- a/types/VarCharType.hpp
+++ b/types/VarCharType.hpp
@@ -43,7 +43,7 @@ namespace quickstep {
  *       character. This means that the VARCHAR(X) type requires from 1 to X+1
  *       bytes of storage, depending on string length.
  **/
-class VarCharType : public AsciiStringSuperType<kVarChar> {
+class VarCharType final : public AsciiStringSuperType<kVarChar> {
  public:
   /**
    * @note Includes an extra byte for a terminating null character.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/YearMonthIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp
index ee1eb97..c729411 100644
--- a/types/YearMonthIntervalType.hpp
+++ b/types/YearMonthIntervalType.hpp
@@ -40,7 +40,7 @@ namespace quickstep {
 /**
  * @brief A type representing the year-month interval.
  **/
-class YearMonthIntervalType : public TypeSynthesizer<kYearMonthInterval> {
+class YearMonthIntervalType final : public TypeSynthesizer<kYearMonthInterval> {
  public:
   int getPrintWidth() const override {
     return YearMonthIntervalLit::kPrintingChars;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/containers/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/containers/CMakeLists.txt b/types/containers/CMakeLists.txt
index 97841c2..675805a 100644
--- a/types/containers/CMakeLists.txt
+++ b/types/containers/CMakeLists.txt
@@ -29,6 +29,7 @@ add_library(quickstep_types_containers_Tuple_proto ${types_containers_Tuple_prot
 target_link_libraries(quickstep_types_containers_ColumnVector
                       glog
                       quickstep_types_Type
+                      quickstep_types_TypeRegistrar
                       quickstep_types_TypedValue
                       quickstep_utility_BitVector
                       quickstep_utility_Macros)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/containers/ColumnVector.cpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.cpp b/types/containers/ColumnVector.cpp
index ef3587e..476accc 100644
--- a/types/containers/ColumnVector.cpp
+++ b/types/containers/ColumnVector.cpp
@@ -21,6 +21,12 @@
 
 #include <cstddef>
 
+#include "types/TypeID.hpp"
+#include "types/TypeUtil.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "types/TypeIDSelectors.hpp"
+#include "utility/Macros.hpp"
+
 namespace quickstep {
 
 class Type;
@@ -30,19 +36,36 @@ ColumnVector* ColumnVector::MakeVectorOfValue(
     const Type &value_type,
     const TypedValue &value,
     const std::size_t num_copies) {
-  if (NativeColumnVector::UsableForType(value_type)) {
-    NativeColumnVector *result = new NativeColumnVector(value_type, num_copies);
-    result->fillWithValue(value);
-    return result;
-  } else {
-    IndirectColumnVector *result = new IndirectColumnVector(value_type, num_copies);
-    result->fillWithValue(value);
-    return result;
+  switch (value_type.getMemoryLayout()) {
+    case kCxxInlinePod:  // Fall through
+    case kParInlinePod: {
+      NativeColumnVector *result = new NativeColumnVector(value_type, num_copies);
+      result->fillWithValue(value);
+      return result;
+    }
+    case kParOutOfLinePod: {
+      IndirectColumnVector *result = new IndirectColumnVector(value_type, num_copies);
+      result->fillWithValue(value);
+      return result;
+    }
+    case kCxxGeneric: {
+      // TODO(refactor-type): Omit non-supported types.
+      return InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxGeneric>>(
+          value_type.getTypeID(),
+          [&](auto tid) -> ColumnVector* {
+        using TypeClass = typename TypeIDTrait<decltype(tid)::value>::TypeClass;
+        GenericColumnVector<TypeClass> *result =
+            new GenericColumnVector<TypeClass>(value_type, num_copies);
+        result->fillWithValue(value);
+        return result;
+      });
+    }
   }
+  QUICKSTEP_UNREACHABLE();
 }
 
-constexpr bool NativeColumnVector::kNative;
+constexpr ColumnVector::Implementation NativeColumnVector::kImplementation;
 
-constexpr bool IndirectColumnVector::kNative;
+constexpr ColumnVector::Implementation IndirectColumnVector::kImplementation;
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/containers/ColumnVector.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.hpp b/types/containers/ColumnVector.hpp
index d524ff5..18b8b86 100644
--- a/types/containers/ColumnVector.hpp
+++ b/types/containers/ColumnVector.hpp
@@ -28,6 +28,7 @@
 #include <vector>
 
 #include "types/Type.hpp"
+#include "types/TypeRegistrar.hpp"
 #include "types/TypedValue.hpp"
 #include "utility/BitVector.hpp"
 #include "utility/Macros.hpp"
@@ -123,18 +124,6 @@ class ColumnVector {
     return implementation_;
   }
 
-  inline bool isNative() const {
-    return implementation_ == kNative;
-  }
-
-  inline bool isIndrect() const {
-    return implementation_ == kIndirect;
-  }
-
-  inline bool isGeneric() const {
-    return implementation_ == kGeneric;
-  }
-
   /**
    * @brief Get the number of values in this ColumnVector.
    *
@@ -142,6 +131,10 @@ class ColumnVector {
    **/
   virtual std::size_t size() const = 0;
 
+  virtual TypedValue getTypedValueVirtual(const std::size_t position) const {
+    LOG(FATAL) << "Unexpected call to ColumnVector::getTypedValueVirtual()";
+  }
+
  protected:
   const Implementation implementation_;
   const Type &type_;
@@ -155,7 +148,7 @@ class ColumnVector {
  **/
 class NativeColumnVector : public ColumnVector {
  public:
-  static constexpr bool kNative = true;
+  static constexpr Implementation kImplementation = ColumnVector::kNative;
 
   /**
    * @brief Constructor for a NativeColumnVector which owns its own array of
@@ -166,16 +159,13 @@ class NativeColumnVector : public ColumnVector {
    *        NativeColumnVector will hold.
    **/
   NativeColumnVector(const Type &type, const std::size_t reserved_length)
-      : ColumnVector(ColumnVector::kNative, type),
+      : ColumnVector(kImplementation, type),
         type_length_(type.maximumByteLength()),
         reserved_length_(reserved_length),
         values_(std::malloc(type.maximumByteLength() * reserved_length)),
         actual_length_(0u),
         null_bitmap_(type.isNullable() ? new BitVector<false>(reserved_length) : nullptr) {
     DCHECK(UsableForType(type_));
-    if (null_bitmap_) {
-      null_bitmap_->clear();
-    }
   }
 
   /**
@@ -193,7 +183,8 @@ class NativeColumnVector : public ColumnVector {
    *         IndirectColumnVector must be used instead.
    **/
   static bool UsableForType(const Type &type) {
-    return !type.isVariableLength();
+    return type.getMemoryLayout() == kCxxInlinePod ||
+           type.getMemoryLayout() == kParInlinePod;
   }
 
   /**
@@ -437,7 +428,7 @@ class NativeColumnVector : public ColumnVector {
  **/
 class IndirectColumnVector : public ColumnVector {
  public:
-  static constexpr bool kNative = false;
+  static constexpr Implementation kImplementation = ColumnVector::kIndirect;
 
   /**
    * @brief Constructor.
@@ -446,7 +437,7 @@ class IndirectColumnVector : public ColumnVector {
    * @param reserved_length The number of values to reserve space for.
    **/
   IndirectColumnVector(const Type &type, const std::size_t reserved_length)
-      : ColumnVector(ColumnVector::kIndirect, type),
+      : ColumnVector(kImplementation, type),
         type_is_nullable_(type.isNullable()),
         reserved_length_(reserved_length) {
     values_.reserve(reserved_length);
@@ -616,11 +607,102 @@ class IndirectColumnVector : public ColumnVector {
   DISALLOW_COPY_AND_ASSIGN(IndirectColumnVector);
 };
 
-class GenericColumnVector {
+template <typename TypeClass>
+class GenericColumnVector : public ColumnVector {
+ public:
+  static constexpr Implementation kImplementation = ColumnVector::kGeneric;
+
+  using cpptype = typename TypeClass::cpptype;
+
+  GenericColumnVector(const Type &type, const std::size_t reserved_length)
+      : ColumnVector(kImplementation, type),
+        type_(static_cast<const TypeClass&>(type)),
+        reserved_length_(reserved_length) {
+    DCHECK(TypeClass::kStaticTypeID == type.getTypeID());
+    values_.reserve(reserved_length_);
+    if (type.isNullable()) {
+      null_bitmap_ = std::make_unique<BitVector<false>>(reserved_length_);
+    }
+  }
+
+  static bool UsableForType(const Type &type) {
+    return type.getMemoryLayout() == kCxxGeneric;
+  }
+
+  inline bool typeIsNullable() const {
+    return null_bitmap_.get() != nullptr;
+  }
 
+  inline std::size_t size() const override {
+    return values_.size();
+  }
 
+  template <bool check_null = true>
+  inline cpptype& getLiteralValue(const std::size_t position) const {
+    DCHECK_LT(position, values_.size());
+    return (check_null && null_bitmap_ && null_bitmap_->getBit(position))
+        ? nullptr
+        : values_[position];
+  }
+
+  TypedValue getTypedValueVirtual(const std::size_t position) const override {
+    return getTypedValue(position);
+  }
+
+  inline TypedValue getTypedValue(const std::size_t position) const {
+    DCHECK_LT(position, values_.size());
+    // TODO(refactor-type): Implement marshallValueMaybeReference() to improve performance.
+    return (null_bitmap_ && null_bitmap_->getBit(position))
+        ? type_.makeNullValue()
+        : type_.marshallValue(&values_[position]);
+  }
+
+  inline void appendNullValue() {
+    DCHECK_LT(values_.size(), reserved_length_);
+    DCHECK(null_bitmap_);
+    null_bitmap_->setBit(values_.size(), true);
+    // TODO(refactor-type): Specialize nullable GenericColumnVector.
+    LOG(FATAL) << "Not implemented";
+  }
+
+  inline void fillWithNulls() {
+    DCHECK(null_bitmap_);
+    null_bitmap_->setBitRange(0, reserved_length_, true);
+    // TODO(refactor-type): Specialize nullable GenericColumnVector.
+    LOG(FATAL) << "Not implemented";
+  }
+
+  inline void fillWithValue(const TypedValue &value) {
+    std::unique_ptr<cpptype> cppvalue = std::unique_ptr<cpptype>(
+        static_cast<cpptype*>(type_.unmarshallTypedValue(value)));
+    for (std::size_t i = 0; i < reserved_length_; ++i) {
+      values_.emplace_back(*cppvalue);
+    }
+  }
+
+  inline void appendLiteralValue(const cpptype &value) {
+    DCHECK_LT(values_.size(), reserved_length_);
+    values_.emplace_back(value);
+  }
+
+  inline void appendLiteralValue(cpptype &&value) {
+    DCHECK_LT(values_.size(), reserved_length_);
+    values_.emplace_back(std::move(value));
+  }
+
+ private:
+  const TypeClass &type_;
+  const std::size_t reserved_length_;
+
+  std::vector<cpptype> values_;
+  std::unique_ptr<BitVector<false>> null_bitmap_;
+
+  DISALLOW_COPY_AND_ASSIGN(GenericColumnVector);
 };
 
+template <typename TypeClass>
+constexpr ColumnVector::Implementation GenericColumnVector<TypeClass>::kImplementation;
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/containers/ColumnVectorUtil.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVectorUtil.hpp b/types/containers/ColumnVectorUtil.hpp
index 5a560a4..e241a21 100644
--- a/types/containers/ColumnVectorUtil.hpp
+++ b/types/containers/ColumnVectorUtil.hpp
@@ -22,6 +22,8 @@
 
 #include "types/containers/ColumnVector.hpp"
 
+#include "glog/logging.h"
+
 namespace quickstep {
 
 /** \addtogroup Types
@@ -43,9 +45,11 @@ namespace quickstep {
 template <typename FunctorT>
 auto InvokeOnColumnVector(const ColumnVector &column_vector,
                           const FunctorT &functor) {
-  if (column_vector.isNative()) {
+  // TODO(refactor-type):
+  if (column_vector.getImplementation() == ColumnVector::kNative) {
     return functor(static_cast<const NativeColumnVector&>(column_vector));
   } else {
+    DCHECK(column_vector.getImplementation() == ColumnVector::kIndirect);
     return functor(static_cast<const IndirectColumnVector&>(column_vector));
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/containers/ColumnVectorsValueAccessor.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVectorsValueAccessor.hpp b/types/containers/ColumnVectorsValueAccessor.hpp
index 0ea6d50..bec232f 100644
--- a/types/containers/ColumnVectorsValueAccessor.hpp
+++ b/types/containers/ColumnVectorsValueAccessor.hpp
@@ -38,6 +38,7 @@
 namespace quickstep {
 
 class TupleIdSequence;
+typedef void UntypedLiteral;
 
 /**
  * @brief Implementation of ValueAccessor as a group of equal-length
@@ -77,9 +78,8 @@ class ColumnVectorsValueAccessor : public ValueAccessor {
     // If this is not the first column to be added, make sure it is the same
     // length as the others.
     DCHECK(columns_.empty() || column->size() == column_length_);
-    DCHECK(column->isNative() || column->isIndrect());
-    columns_.push_back(column);
-    column_native_.push_back(column->isNative());
+    columns_.emplace_back(column);
+    column_impl_.emplace_back(column->getImplementation());
     column_length_ = column->size();
   }
 
@@ -152,10 +152,15 @@ class ColumnVectorsValueAccessor : public ValueAccessor {
                                                        const tuple_id tid) const {
     DCHECK(attributeIdInRange(attr_id));
     DCHECK(tupleIdInRange(tid));
-    if (column_native_[attr_id]) {
-      return static_cast<const NativeColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid);
-    } else {
-      return static_cast<const IndirectColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid);
+    // TODO(jianqiao): Implement specialized column accessors to improve performance.
+    switch (column_impl_[attr_id]) {
+      case ColumnVector::kNative:
+        return static_cast<const NativeColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid);
+      case ColumnVector::kIndirect:
+        return static_cast<const IndirectColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid);
+      default:
+        LOG(FATAL) << "Can not apply getUntypedValueAtAbsolutionPosition() to "
+                   << "GenericColumnVector";
     }
   }
 
@@ -163,14 +168,18 @@ class ColumnVectorsValueAccessor : public ValueAccessor {
                                                     const tuple_id tid) const {
     DCHECK(attributeIdInRange(attr_id));
     DCHECK(tupleIdInRange(tid));
-    if (column_native_[attr_id]) {
-      return static_cast<const NativeColumnVector&>(*columns_[attr_id])
-          .getTypedValue(tid)
-          .makeReferenceToThis();
-    } else {
-      return static_cast<const IndirectColumnVector&>(*columns_[attr_id])
-          .getTypedValue(tid)
-          .makeReferenceToThis();
+    // TODO(jianqiao): Implement specialized column accessors to improve performance.
+    switch (column_impl_[attr_id]) {
+      case ColumnVector::kNative:
+        return static_cast<const NativeColumnVector&>(*columns_[attr_id])
+            .getTypedValue(tid)
+            .makeReferenceToThis();
+      case ColumnVector::kIndirect:
+        return static_cast<const IndirectColumnVector&>(*columns_[attr_id])
+            .getTypedValue(tid)
+            .makeReferenceToThis();
+      case ColumnVector::kGeneric:
+        return columns_[attr_id]->getTypedValueVirtual(tid);
     }
   }
 
@@ -305,7 +314,7 @@ class ColumnVectorsValueAccessor : public ValueAccessor {
   }
 
   std::vector<ColumnVectorPtr> columns_;
-  std::vector<bool> column_native_;
+  std::vector<ColumnVector::Implementation> column_impl_;
   std::size_t column_length_;
   std::size_t current_position_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/CMakeLists.txt b/types/operations/CMakeLists.txt
index caf5f72..1e622dd 100644
--- a/types/operations/CMakeLists.txt
+++ b/types/operations/CMakeLists.txt
@@ -39,13 +39,12 @@ target_link_libraries(quickstep_types_operations_OperationFactory
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypeUtil
-                      quickstep_types_TypedValue
                       quickstep_types_operations_Operation
                       quickstep_types_operations_OperationSignature
                       quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctors
                       quickstep_types_operations_binaryoperations_AsciiStringBinaryFunctors
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+                      quickstep_types_operations_binaryoperations_BinaryOperationSynthesizer
                       quickstep_types_operations_binaryoperations_CMathBinaryFunctors
                       quickstep_types_operations_unaryoperations_ArithmeticUnaryFunctors
                       quickstep_types_operations_unaryoperations_AsciiStringUnaryFunctors
@@ -54,7 +53,7 @@ target_link_libraries(quickstep_types_operations_OperationFactory
                       quickstep_types_operations_unaryoperations_DateExtractOperation
                       quickstep_types_operations_unaryoperations_SubstringOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_utility_HashPair
                       quickstep_utility_Macros
                       quickstep_utility_StringUtil)



Mime
View raw message