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

[38/41] incubator-quickstep git commit: Updates to casts

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt
index fbfd091..269d683 100644
--- a/types/operations/unary_operations/CMakeLists.txt
+++ b/types/operations/unary_operations/CMakeLists.txt
@@ -36,9 +36,9 @@ add_library(quickstep_types_operations_unaryoperations_SubstringOperation
             SubstringOperation.cpp
             SubstringOperation.hpp)
 add_library(quickstep_types_operations_unaryoperations_UnaryOperation UnaryOperation.cpp UnaryOperation.hpp)
-add_library(quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+add_library(quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
             ../../../empty_src.cpp
-            UnaryOperationWrapper.hpp)
+            UnaryOperationSynthesizer.hpp)
 
 # Link dependencies:
 target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnaryFunctors
@@ -49,7 +49,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnary
                       quickstep_types_IntType
                       quickstep_types_LongType
                       quickstep_types_YearMonthIntervalType
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_types_operations_utility_OperationSynthesizeUtil)
 target_link_libraries(quickstep_types_operations_unaryoperations_AsciiStringUnaryFunctors
                       quickstep_types_CharType
@@ -58,7 +58,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_AsciiStringUnar
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_VarCharType
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_types_port_strnlen
                       quickstep_utility_meta_Common)
@@ -67,28 +67,37 @@ target_link_libraries(quickstep_types_operations_unaryoperations_CMathUnaryFunct
                       quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_operations_unaryoperations_CastFunctorOverloads
+                      quickstep_types_TypeRegistrar
+                      quickstep_types_TypedValue
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
+                      quickstep_utility_meta_TypeList)
 target_link_libraries(quickstep_types_operations_unaryoperations_CastOperation
                       glog
                       quickstep_types_CharType
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
+                      quickstep_types_GenericValue
                       quickstep_types_IntType
                       quickstep_types_LongType
+                      quickstep_types_MetaType
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypeUtil
                       quickstep_types_TypedValue
                       quickstep_types_VarCharType
+                      quickstep_types_operations_unaryoperations_CastFunctorOverloads
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_types_port_strnlen
                       quickstep_utility_EqualsAnyConstant
                       quickstep_utility_Macros
-                      quickstep_utility_StringUtil)
+                      quickstep_utility_StringUtil
+                      quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOperation
                       glog
                       quickstep_types_DateType
@@ -100,7 +109,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOper
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_utility_Macros
                       quickstep_utility_StringUtil)
 target_link_libraries(quickstep_types_operations_unaryoperations_SubstringOperation
@@ -126,7 +135,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_types_operations_OperationSignature
                       quickstep_types_operations_Operation_proto
                       quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       glog
                       quickstep_catalog_CatalogTypedefs
                       quickstep_storage_ValueAccessor
@@ -152,7 +161,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations
                       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)
 
 # Tests:
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/CMathUnaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMathUnaryFunctors.hpp b/types/operations/unary_operations/CMathUnaryFunctors.hpp
index 5ed8b50..edece53 100644
--- a/types/operations/unary_operations/CMathUnaryFunctors.hpp
+++ b/types/operations/unary_operations/CMathUnaryFunctors.hpp
@@ -27,7 +27,7 @@
 #include "types/FloatType.hpp"
 #include "types/IntType.hpp"
 #include "types/LongType.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 #include "types/operations/utility/OperationSynthesizeUtil.hpp"
 #include "utility/meta/Common.hpp"
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/CastFunctorOverloads.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastFunctorOverloads.hpp b/types/operations/unary_operations/CastFunctorOverloads.hpp
index 940cab6..0e4b059 100644
--- a/types/operations/unary_operations/CastFunctorOverloads.hpp
+++ b/types/operations/unary_operations/CastFunctorOverloads.hpp
@@ -26,9 +26,10 @@
 #include <type_traits>
 #include <vector>
 
+#include "types/GenericValue.hpp"
 #include "types/TypeRegistrar.hpp"
 #include "types/TypedValue.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 #include "utility/meta/TypeList.hpp"
 
 namespace quickstep {
@@ -62,12 +63,17 @@ struct CastFunctor<
 // ----------------------------------------------------------------------------
 // Implementations of any type to ascii string casts.
 
+using UnsupportedCastToAsciiStringTypes = meta::TypeList<NullType>;
+
+// TODO(refactor-type): Better implementation of casting among ascii string types.
+
 template <typename SourceType>
-struct CastFunctor<SourceType, CharType,
-                   std::enable_if_t<SourceType::kStaticSuperTypeID == SuperTypeID::kNumeric>>
+struct CastFunctor<
+    SourceType, CharType,
+    std::enable_if_t<!UnsupportedCastToAsciiStringTypes::contains<SourceType>::value>>
     : public UnaryFunctor<SourceType, CharType> {
-  explicit CastFunctor(const SourceType &source_type_in,
-                       const CharType &target_type_in)
+  CastFunctor(const SourceType &source_type_in,
+              const CharType &target_type_in)
       : source_type(source_type_in),
         max_string_length(target_type_in.getStringLength()) {}
   inline void apply(const typename SourceType::cpptype &argument, void *result) const {
@@ -85,11 +91,12 @@ struct CastFunctor<SourceType, CharType,
 };
 
 template <typename SourceType>
-struct CastFunctor<SourceType, VarCharType,
-                   std::enable_if_t<SourceType::kStaticSuperTypeID == SuperTypeID::kNumeric>>
+struct CastFunctor<
+    SourceType, VarCharType,
+    std::enable_if_t<!UnsupportedCastToAsciiStringTypes::contains<SourceType>::value>>
     : public UnaryFunctor<SourceType, VarCharType> {
-  explicit CastFunctor(const SourceType &source_type_in,
-                       const VarCharType &target_type_in)
+  CastFunctor(const SourceType &source_type_in,
+              const VarCharType &target_type_in)
       : source_type(source_type_in),
         max_string_length(target_type_in.getStringLength()) {}
   inline TypedValue apply(const typename SourceType::cpptype &argument) const {
@@ -105,75 +112,109 @@ struct CastFunctor<SourceType, VarCharType,
   const std::size_t max_string_length;
 };
 
-//template <typename SourceType>
-//struct CastFunctor<SourceType, TextType>
-//    : public UnaryFunctor<SourceType, TextType> {
-//  explicit CastFunctor(const SourceType &source_type_in,
-//                       const TextType &target_type_in)
-//      : source_type(source_type_in) {}
-//  inline std::string apply(const typename SourceType::cpptype &argument) const {
-//    return source_type.printValueToString(&argument);
-//  }
-//  const SourceType &source_type;
-//};
-//
-//
+template <typename SourceType>
+struct CastFunctor<
+    SourceType, TextType,
+    std::enable_if_t<!UnsupportedCastToAsciiStringTypes::contains<SourceType>::value>>
+    : public UnaryFunctor<SourceType, TextType> {
+  CastFunctor(const SourceType &source_type_in,
+              const TextType &target_type_in)
+      : source_type(source_type_in) {}
+  inline std::string apply(const typename SourceType::cpptype &argument) const {
+    return source_type.printValueToString(&argument);
+  }
+  const SourceType &source_type;
+};
+
+
 //// ----------------------------------------------------------------------------
-//// Implementations of ascii string to numeric casts.
-//
-//template <typename T>
-//T CastStringToNumericOverload(const char *str);
-//
-//template <>
-//bool CastStringToNumericOverload(const char *str) {
-//  return ToLower(str) == "true";
-//}
-//template <>
-//int CastStringToNumericOverload(const char *str) {
-//  return std::atoi(str);
-//}
-//template <>
-//float CastStringToNumericOverload(const char *str) {
-//  return static_cast<float>(std::atof(str));
-//}
-//template <>
-//std::int64_t CastStringToNumericOverload(const char *str) {
-//  return std::atoll(str);
-//}
-//template <>
-//double CastStringToNumericOverload(const char *str) {
-//  return std::atof(str);
-//}
-//
-//template <typename TargetType>
-//struct CastFunctor<CharType, TargetType,
-//                   std::enable_if_t<NumericTypes::contains<TargetType>::value>>
-//    : public UnaryFunctor<CharType, TargetType> {
-//  explicit CastFunctor(const CharType &source_type_in,
-//                       const TargetType &target_type_in)
-//      : max_string_length(source_type_in.getStringLength()) {}
-//  inline typename TargetType::cpptype apply(const void *argument) const {
-//    const char *str = static_cast<const char*>(argument);
-//    const std::string value(str, strnlen(str, max_string_length));
-//    return CastStringToNumericOverload<typename TargetType::cpptype>(value.c_str());
-//  }
-//  const std::size_t max_string_length;
-//};
-//
-//
-//template <typename TargetType>
-//struct CastFunctor<VarCharType, TargetType,
-//                   std::enable_if_t<NumericTypes::contains<TargetType>::value>>
-//    : public UnaryFunctor<VarCharType, TargetType> {
-//  explicit CastFunctor(const VarCharType &source_type_in,
-//                       const TargetType &target_type_in)
-//      : max_string_length(source_type_in.getStringLength()) {}
-//  inline typename TargetType::cpptype apply(const TypedValue &argument) const {
-//    return CastStringToNumericOverload<typename TargetType::cpptype>(
-//        static_cast<const char*>(argument.getDataPtr()));
-//  }
-//  const std::size_t max_string_length;
-//};
+//// Implementations of ascii string to other types casts.
+
+using UnsupportedParseFromAsciiStringTypes = meta::TypeList<NullType>;
+
+// TODO(refactor-type): Implement parseTypedValueFromString for other non-numeric types.
+// TODO(refactor-type): Possibly return NULL values.
+
+template <typename TargetType>
+struct CastFunctor<
+    CharType, TargetType,
+    std::enable_if_t<!UnsupportedParseFromAsciiStringTypes::contains<TargetType>::value &&
+                     TargetType::kMemoryLayout == kCxxInlinePod>>
+    : public UnaryFunctor<CharType, TargetType> {
+  CastFunctor(const CharType &source_type_in,
+              const TargetType &target_type_in)
+      : max_string_length(source_type_in.getStringLength()),
+        target_type(target_type_in) {}
+  inline typename TargetType::cpptype apply(const void *argument) const {
+    // TODO(refactor-type): Implement specialized parseValueFromString.
+    const char *str = static_cast<const char*>(argument);
+    const std::string value(str, strnlen(str, max_string_length));
+    TypedValue result;
+    target_type.parseTypedValueFromString(value, &result);
+    return result.getLiteral<typename TargetType::cpptype>();
+  }
+  const std::size_t max_string_length;
+  const TargetType &target_type;
+};
+
+
+template <typename TargetType>
+struct CastFunctor<VarCharType, TargetType,
+                   std::enable_if_t<NumericTypes::contains<TargetType>::value>>
+    : public UnaryFunctor<VarCharType, TargetType> {
+  CastFunctor(const VarCharType &source_type_in,
+              const TargetType &target_type_in)
+      : max_string_length(source_type_in.getStringLength()),
+        target_type(target_type_in) {}
+  inline typename TargetType::cpptype apply(const TypedValue &argument) const {
+    const std::string value(static_cast<const char*>(argument.getOutOfLineData()));
+    TypedValue result;
+    target_type.parseTypedValueFromString(value, &result);
+    return result.getLiteral<typename TargetType::cpptype>();
+  }
+  const std::size_t max_string_length;
+  const Type &target_type;
+};
+
+template <typename TargetType>
+struct CastFunctor<
+    TextType, TargetType,
+    std::enable_if_t<!UnsupportedParseFromAsciiStringTypes::contains<TargetType>::value &&
+                     TargetType::kMemoryLayout == kCxxInlinePod>>
+    : public UnaryFunctor<TextType, TargetType> {
+  CastFunctor(const TextType &source_type_in,
+              const TargetType &target_type_in)
+      : target_type(target_type_in) {}
+  inline typename TargetType::cpptype apply(const std::string &argument) const {
+    // TODO(refactor-type): Implement specialized parseValueFromString.
+    TypedValue result;
+    target_type.parseTypedValueFromString(argument, &result);
+    return result.getLiteral<typename TargetType::cpptype>();
+  }
+  const TargetType &target_type;
+};
+
+
+//// ----------------------------------------------------------------------------
+//// Implementations of array to array casts.
+
+template <>
+struct CastFunctor<ArrayType, ArrayType>
+    : public UnaryFunctor<ArrayType, ArrayType> {
+  CastFunctor(const ArrayType &source_type_in,
+              const ArrayType &target_type_in)
+      : source_element_type(source_type_in.getElementType()),
+        target_element_type(target_type_in.getElementType()) {}
+  inline ArrayLit apply(const ArrayLit &argument) const {
+    ArrayLit result(target_element_type);
+    for (const auto *value : argument) {
+      result.push_back(target_element_type.coerceValue(value, source_element_type));
+    }
+    return result;
+  }
+  const Type &source_element_type;
+  const Type &target_element_type;
+};
 
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/CastOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.cpp b/types/operations/unary_operations/CastOperation.cpp
index 8f725e2..f71ae7d 100644
--- a/types/operations/unary_operations/CastOperation.cpp
+++ b/types/operations/unary_operations/CastOperation.cpp
@@ -38,7 +38,7 @@
 #include "types/TypedValue.hpp"
 #include "types/VarCharType.hpp"
 #include "types/operations/unary_operations/CastFunctorOverloads.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 #include "types/port/strnlen.hpp"
 #include "utility/EqualsAnyConstant.hpp"
 #include "utility/StringUtil.hpp"
@@ -53,7 +53,7 @@ UncheckedUnaryOperator* MakeUncheckedCastOperatorConstructorSpec(
     const SourceType &source_type,
     const TargetType &target_type,
     decltype(new CastFunctor<SourceType, TargetType>()) * = 0) {
-  return new UncheckedUnaryOperatorWrapperCodegen<
+  return new UncheckedUnaryOperatorSynthesizer<
       CastFunctor<SourceType, TargetType>>(
           source_type, target_type);
 }
@@ -63,7 +63,7 @@ UncheckedUnaryOperator* MakeUncheckedCastOperatorConstructorSpec(
     const SourceType &source_type,
     const TargetType &target_type,
     decltype(new CastFunctor<SourceType, TargetType>(source_type, target_type)) * = 0) {
-  return new UncheckedUnaryOperatorWrapperCodegen<
+  return new UncheckedUnaryOperatorSynthesizer<
       CastFunctor<SourceType, TargetType>>(
           source_type, target_type, source_type, target_type);
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/CastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.hpp b/types/operations/unary_operations/CastOperation.hpp
index b8750c0..5a139b0 100644
--- a/types/operations/unary_operations/CastOperation.hpp
+++ b/types/operations/unary_operations/CastOperation.hpp
@@ -26,10 +26,10 @@
 #include <utility>
 #include <vector>
 
-#include "types/IntType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
 #include "types/TypedValue.hpp"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
 #include "utility/Macros.hpp"
@@ -63,7 +63,7 @@ class CastOperation : public UnaryOperation {
 
   std::vector<OperationSignaturePtr> getSignatures() const override {
     const std::vector<TypeID> source_type_ids =
-        { kBool, kInt, kLong, kFloat, kDouble, kChar, kVarChar };
+        TypeIDSequenceAll::Instantiate<std::vector<TypeID>>();
     const std::vector<TypeID> target_type_carrier = { kMetaType };
 
     std::vector<OperationSignaturePtr> signatures;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/DateExtractOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.cpp b/types/operations/unary_operations/DateExtractOperation.cpp
index f95e109..16e66a9 100644
--- a/types/operations/unary_operations/DateExtractOperation.cpp
+++ b/types/operations/unary_operations/DateExtractOperation.cpp
@@ -32,7 +32,7 @@
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 
 #include "glog/logging.h"
 
@@ -96,17 +96,17 @@ UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperator(
   if (type.getTypeID() == kDate) {
     switch (unit) {
       case DateExtractUnit::kYear:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DateExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>(
                  type, *result_type);
       case DateExtractUnit::kMonth:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DateExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>(
                  type, *result_type);
       case DateExtractUnit::kDay:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DateExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>(
                  type, *result_type);
@@ -117,32 +117,32 @@ UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperator(
   } else {
     switch (unit) {
       case DateExtractUnit::kYear:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>(
                  type, *result_type);
       case DateExtractUnit::kMonth:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>(
                  type, *result_type);
       case DateExtractUnit::kDay:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>(
                  type, *result_type);
       case DateExtractUnit::kHour:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kHour>>(
                  type, *result_type);
       case DateExtractUnit::kMinute:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kMinute>>(
                  type, *result_type);
       case DateExtractUnit::kSecond:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kSecond>>(
                  type, *result_type);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/UnaryOperationSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationSynthesizer.hpp b/types/operations/unary_operations/UnaryOperationSynthesizer.hpp
new file mode 100644
index 0000000..9d46af7
--- /dev/null
+++ b/types/operations/unary_operations/UnaryOperationSynthesizer.hpp
@@ -0,0 +1,273 @@
+/**
+ * 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_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_
+
+#include <cstddef>
+#include <string>
+#include <type_traits>
+
+#include "catalog/CatalogTypedefs.hpp"
+#include "storage/ValueAccessor.hpp"
+#include "storage/ValueAccessorUtil.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/containers/ColumnVector.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "types/operations/utility/OperationSynthesizeUtil.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename ArgumentT, typename ResultT>
+struct UnaryFunctor {
+  typedef ArgumentT ArgumentType;
+  typedef ResultT ResultType;
+
+  static constexpr Operation
+      ::OperationSuperTypeID kOperationSuperTypeID = Operation::kUnaryOperation;
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+class UncheckedUnaryOperatorSynthesizer : public UncheckedUnaryOperator {
+ public:
+  template <typename ...FunctorArgs>
+  UncheckedUnaryOperatorSynthesizer(const Type &argument_type,
+                                    const Type &result_type,
+                                    FunctorArgs &&...args)
+      : functor_(std::forward<FunctorArgs>(args)...),
+        impl_(functor_, argument_type, result_type) {
+    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
+    DCHECK(result_type.getTypeID() == ResultType::kStaticTypeID);
+  }
+
+  TypedValue applyToTypedValue(const TypedValue &argument) const override {
+    return impl_.applyToTypedValue(argument);
+  }
+
+  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override {
+    using ArgumentCVT = typename ArgumentGen::ColumnVectorType;
+    DCHECK_EQ(argument.getImplementation(), ArgumentCVT::kImplementation);
+
+    using ArgumentAccessorT = ColumnVectorAccessor<ArgumentCVT>;
+    ArgumentAccessorT accessor(static_cast<const ArgumentCVT&>(argument));
+    return impl_.applyToValueAccessor(&accessor, 0);
+  }
+
+  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
+                                     const attribute_id attr_id) const override {
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        accessor,
+        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+      return impl_.applyToValueAccessor(accessor, attr_id);
+    });
+  }
+
+ private:
+  using ArgumentType = typename FunctorT::ArgumentType;
+  using ResultType = typename FunctorT::ResultType;
+
+  using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type;
+  using ArgumentGen = OperationCodegen<FuncSpec, ArgumentType>;
+  using ResultGen = OperationCodegen<FuncSpec, ResultType>;
+
+  template <bool argument_nullable>
+  struct Implementation;
+
+  const FunctorT functor_;
+  const Implementation<true> impl_;
+
+  DISALLOW_COPY_AND_ASSIGN(UncheckedUnaryOperatorSynthesizer);
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+template <bool argument_nullable>
+struct UncheckedUnaryOperatorSynthesizer<FunctorT, SpecArgs...>
+    ::Implementation {
+  Implementation(const FunctorT &functor_in,
+                 const Type &argument_type_in,
+                 const Type &result_type_in)
+      : functor(functor_in),
+        argument_type(static_cast<const ArgumentType&>(argument_type_in)),
+        result_type(static_cast<const ResultType&>(result_type_in)) {}
+
+  inline TypedValue applyToTypedValue(const TypedValue &argument) const {
+    if (argument_nullable && argument.isNull()) {
+      return TypedValue(ResultType::kStaticTypeID);
+    }
+
+    return ResultGen::template ApplyUnaryTypedValue<ArgumentGen>(
+        ArgumentGen::ToNativeValueConst(argument, argument_type),
+        result_type,
+        functor);
+  }
+
+  template <typename AccessorT>
+  inline ColumnVector* applyToValueAccessor(AccessorT *accessor,
+                                            const attribute_id attr_id) const {
+    using ResultCVT = typename ResultGen::ColumnVectorType;
+    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
+
+    std::unique_ptr<typename ArgumentGen::NativeType> value_cache;
+    accessor->beginIteration();
+    while (accessor->next()) {
+      typename ArgumentGen::NativeTypeConstPtr arg_value =
+          ArgumentGen::template GetValuePtr<argument_nullable, AccessorT>(
+              accessor, attr_id, argument_type, &value_cache);
+
+      if (argument_nullable && ArgumentGen::IsNull(arg_value)) {
+        result_cv->appendNullValue();
+      } else {
+        ResultGen::template ApplyUnaryColumnVector<ArgumentGen>(
+            ArgumentGen::Dereference(arg_value), functor, result_cv);
+      }
+    }
+    return result_cv;
+  }
+
+  const FunctorT &functor;
+  const ArgumentType &argument_type;
+  const ResultType &result_type;
+};
+
+template <typename FunctorT>
+class UnaryOperationSynthesizer : public UnaryOperation {
+ public:
+  UnaryOperationSynthesizer()
+      : UnaryOperation(),
+        operation_name_(FunctorT::GetName()) {}
+
+  std::string getName() const override {
+    return operation_name_;
+  }
+
+  std::string getShortName() const override {
+    return getName();
+  }
+
+  std::vector<OperationSignaturePtr> getSignatures() const override {
+    return {
+        OperationSignature::Create(getName(), {ArgumentType::kStaticTypeID}, 0)
+    };
+  }
+
+  bool canApplyTo(const Type &argument_type,
+                  const std::vector<TypedValue> &static_arguments,
+                  std::string *message) const override {
+    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return true;
+  }
+
+  const Type* getResultType(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return getResultTypeImpl<HasGetType<FunctorT>::value>(
+        argument_type, static_arguments);
+  }
+
+  UncheckedUnaryOperator* makeUncheckedUnaryOperator(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return makeUncheckedUnaryOperatorImpl<
+        std::is_default_constructible<FunctorT>::value>(
+            argument_type, static_arguments);
+  }
+
+ private:
+  using ArgumentType = typename FunctorT::ArgumentType;
+  using ResultType = typename FunctorT::ResultType;
+
+  QUICKSTEP_TRAIT_HAS_STATIC_METHOD(HasGetType, GetType);
+
+  template <bool functor_use_default_constructor>
+  inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<functor_use_default_constructor> * = 0) const {
+    return new UncheckedUnaryOperatorSynthesizer<FunctorT>(
+        argument_type, *getResultType(argument_type, static_arguments));
+  }
+
+  template <bool functor_use_default_constructor>
+  inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!functor_use_default_constructor> * = 0) const {
+    return new UncheckedUnaryOperatorSynthesizer<FunctorT>(
+        argument_type, *getResultType(argument_type, static_arguments),
+        static_cast<const ArgumentType&>(argument_type));
+  }
+
+  template <bool user_defined_get_type>
+  inline const Type* getResultTypeImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!user_defined_get_type &&
+                       ResultType::kMemoryLayout == kCxxInlinePod> * = 0) const {
+    return &TypeFactory::GetType(ResultType::kStaticTypeID,
+                                 argument_type.isNullable());
+  }
+
+  template <bool user_defined_get_type>
+  inline const Type* getResultTypeImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!user_defined_get_type &&
+                       ResultType::kMemoryLayout == kCxxGeneric> * = 0) const {
+    return &TypeFactory::GetType(ResultType::kStaticTypeID,
+                                 std::vector<GenericValue>(),
+                                 argument_type.isNullable());
+  }
+
+  template <bool user_defined_get_type>
+  inline const Type* getResultTypeImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<user_defined_get_type ||
+                       ResultType::kMemoryLayout == kParInlinePod ||
+                       ResultType::kMemoryLayout == kParOutOfLinePod> * = 0) const {
+    // TODO(refactor-type): Specialize with regard to static arguments.
+    return FunctorT::GetResultType(argument_type);
+  }
+
+  const std::string operation_name_;
+
+  DISALLOW_COPY_AND_ASSIGN(UnaryOperationSynthesizer);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/UnaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationWrapper.hpp b/types/operations/unary_operations/UnaryOperationWrapper.hpp
deleted file mode 100644
index 78285fa..0000000
--- a/types/operations/unary_operations/UnaryOperationWrapper.hpp
+++ /dev/null
@@ -1,250 +0,0 @@
-/**
- * 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_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_
-
-#include <cstddef>
-#include <string>
-#include <type_traits>
-
-#include "catalog/CatalogTypedefs.hpp"
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
-#include "types/Type.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-#include "types/operations/OperationSignature.hpp"
-#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/utility/OperationSynthesizeUtil.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-template <typename ArgumentT, typename ResultT>
-struct UnaryFunctor {
-  typedef ArgumentT ArgumentType;
-  typedef ResultT ResultType;
-
-  static constexpr Operation
-      ::OperationSuperTypeID kOperationSuperTypeID = Operation::kUnaryOperation;
-};
-
-template <typename FunctorT, typename ...SpecArgs>
-class UncheckedUnaryOperatorWrapperCodegen : public UncheckedUnaryOperator {
- public:
-  template <typename ...ConstructorArgs>
-  UncheckedUnaryOperatorWrapperCodegen(const Type &argument_type,
-                                       const Type &result_type,
-                                       ConstructorArgs &&...args)
-      : functor_(std::forward<ConstructorArgs>(args)...),
-        impl_(functor_, argument_type, result_type) {}
-
-  TypedValue applyToTypedValue(const TypedValue &argument) const override {
-    return impl_.applyToTypedValue(argument);
-  }
-
-  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override {
-    using ArgumentCVT = typename ArgumentGen::ColumnVectorType;
-    DCHECK_EQ(argument.isNative(), ArgumentCVT::kNative);
-
-    using ArgumentAccessorT = ColumnVectorValueAccessor<ArgumentCVT>;
-    ArgumentAccessorT accessor(static_cast<const ArgumentCVT&>(argument));
-    return impl_.applyToValueAccessor(&accessor, 0);
-  }
-
-  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
-                                     const attribute_id attr_id) const override {
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        accessor,
-        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      return impl_.applyToValueAccessor(accessor, attr_id);
-    });
-  }
-
- private:
-  using ArgumentType = typename FunctorT::ArgumentType;
-  using ResultType = typename FunctorT::ResultType;
-
-  using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type;
-  using ArgumentGen = OperationCodegen<FuncSpec, ArgumentType>;
-  using ResultGen = OperationCodegen<FuncSpec, ResultType>;
-
-  template <bool argument_nullable>
-  struct Implementation;
-
-  const FunctorT functor_;
-  const Implementation<true> impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(UncheckedUnaryOperatorWrapperCodegen);
-};
-
-template <typename FunctorT, typename ...SpecArgs>
-template <bool argument_nullable>
-struct UncheckedUnaryOperatorWrapperCodegen<FunctorT, SpecArgs...>
-    ::Implementation {
-  Implementation(const FunctorT &functor_in,
-                 const Type &argument_type_in,
-                 const Type &result_type_in)
-      : functor(functor_in),
-        argument_type(argument_type_in),
-        result_type(result_type_in) {}
-
-  inline TypedValue applyToTypedValue(const TypedValue &argument) const {
-    if (argument_nullable && argument.isNull()) {
-      return TypedValue(ResultType::kStaticTypeID);
-    }
-
-    return ResultGen::template ApplyUnaryTypedValue<ArgumentGen>(
-        ArgumentGen::ToNativeValueConst(argument),
-        result_type,
-        functor);
-  }
-
-  template <typename AccessorT>
-  inline ColumnVector* applyToValueAccessor(AccessorT *accessor,
-                                            const attribute_id attr_id) const {
-    using ResultCVT = typename ResultGen::ColumnVectorType;
-    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
-
-    accessor->beginIteration();
-    while (accessor->next()) {
-      typename ArgumentGen::NativeTypeConstPtr arg_value =
-          ArgumentGen::template GetValuePtr<
-              argument_nullable, AccessorT>(accessor, attr_id);
-
-      if (argument_nullable && ArgumentGen::IsNull(arg_value)) {
-        result_cv->appendNullValue();
-      } else {
-        ResultGen::template ApplyUnaryColumnVector<ArgumentGen>(
-            ArgumentGen::Dereference(arg_value), functor, result_cv);
-      }
-    }
-    return result_cv;
-  }
-
-  const FunctorT &functor;
-  const Type &argument_type;
-  const Type &result_type;
-};
-
-template <typename FunctorT>
-class UnaryOperationWrapper : public UnaryOperation {
- public:
-  UnaryOperationWrapper()
-      : UnaryOperation(),
-        operation_name_(FunctorT::GetName()) {}
-
-  std::string getName() const override {
-    return operation_name_;
-  }
-
-  std::string getShortName() const override {
-    return getName();
-  }
-
-  std::vector<OperationSignaturePtr> getSignatures() const override {
-    return {
-        OperationSignature::Create(getName(), {ArgumentType::kStaticTypeID}, 0)
-    };
-  }
-
-  bool canApplyTo(const Type &argument_type,
-                  const std::vector<TypedValue> &static_arguments,
-                  std::string *message) const override {
-    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
-    DCHECK(static_arguments.empty());
-    return true;
-  }
-
-  const Type* getResultType(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments) const override {
-    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
-    DCHECK(static_arguments.empty());
-    return getResultTypeImpl<ResultType::kIsParPod>(
-        argument_type, static_arguments);
-  }
-
-  UncheckedUnaryOperator* makeUncheckedUnaryOperator(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments) const override {
-    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
-    DCHECK(static_arguments.empty());
-    return makeUncheckedUnaryOperatorImpl<
-        std::is_default_constructible<FunctorT>::value>(
-            argument_type, static_arguments);
-  }
-
- private:
-  using ArgumentType = typename FunctorT::ArgumentType;
-  using ResultType = typename FunctorT::ResultType;
-
-  template <bool functor_use_default_constructor>
-  inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<functor_use_default_constructor>* = 0) const {
-    return new UncheckedUnaryOperatorWrapperCodegen<FunctorT>(
-        argument_type, *getResultType(argument_type, static_arguments));
-  }
-
-  template <bool functor_use_default_constructor>
-  inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<!functor_use_default_constructor>* = 0) const {
-    return new UncheckedUnaryOperatorWrapperCodegen<FunctorT>(
-        argument_type, *getResultType(argument_type, static_arguments),
-        static_cast<const ArgumentType&>(argument_type));
-  }
-
-  template <bool result_type_has_parameter>
-  inline const Type* getResultTypeImpl(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<!result_type_has_parameter>* = 0) const {
-    return &TypeFactory::GetType(ResultType::kStaticTypeID,
-                                 argument_type.isNullable());
-  }
-
-  template <bool result_type_has_parameter>
-  inline const Type* getResultTypeImpl(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<result_type_has_parameter>* = 0) const {
-    return FunctorT::GetResultType(argument_type);
-  }
-
-  const std::string operation_name_;
-
-  DISALLOW_COPY_AND_ASSIGN(UnaryOperationWrapper);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/utility/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/utility/CMakeLists.txt b/types/operations/utility/CMakeLists.txt
index 89b1dc6..4f57387 100644
--- a/types/operations/utility/CMakeLists.txt
+++ b/types/operations/utility/CMakeLists.txt
@@ -23,12 +23,19 @@ add_library(quickstep_types_operations_utility_OperationSynthesizeUtil
 
 # Link dependencies:
 target_link_libraries(quickstep_types_operations_utility_CastUtil
-                      glog)
+                      quickstep_types_TypeID
+                      quickstep_types_TypeRegistrar
+                      quickstep_types_operations_unaryoperations_CastFunctorOverloads
+                      quickstep_utility_Macros
+                      quickstep_utility_meta_Common
+                      quickstep_utility_meta_TypeList)
 target_link_libraries(quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_catalog_CatalogTypedefs
                       quickstep_types_Type
                       quickstep_types_TypedValue
-                      quickstep_types_containers_ColumnVector)
+                      quickstep_types_containers_ColumnVector
+                      quickstep_utility_Macros
+                      quickstep_utility_meta_TypeList)
 
 # Module all-in-one library:
 add_library(quickstep_types_operations_utility ../../../empty_src.cpp)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/utility/CastUtil.cpp
----------------------------------------------------------------------
diff --git a/types/operations/utility/CastUtil.cpp b/types/operations/utility/CastUtil.cpp
index e69de29..697a9c0 100644
--- a/types/operations/utility/CastUtil.cpp
+++ b/types/operations/utility/CastUtil.cpp
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/operations/utility/CastUtil.hpp"
+
+#include <vector>
+
+#include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "types/TypeUtil.hpp"
+#include "types/operations/unary_operations/CastFunctorOverloads.hpp"
+#include "utility/meta/Common.hpp"
+#include "utility/meta/TypeList.hpp"
+
+namespace quickstep {
+
+namespace {
+
+template <typename T>
+struct GetTypeClass {
+  using type = typename TypeIDTrait<T::value>::TypeClass;
+};
+
+template <typename TL>
+struct HasCast : meta::IsCompleteType<
+    CastFunctor<typename TL::template at<0>, typename TL::template at<1>>> {};
+
+template <typename TL>
+struct GetSourceTypeID {
+  inline TypeID operator()() const {
+    return TL::head::kStaticTypeID;
+  }
+};
+
+}  // namespace
+
+std::vector<TypeID> CastUtil::GetCoercibleSourceTypeIDs(const TypeID target_type_id) {
+  return InvokeOnTypeID(
+      target_type_id,
+      [](auto tid) -> std::vector<TypeID> {
+    using TargetType = typename TypeIDTrait<decltype(tid)::value>::TypeClass;
+    return TypeIDSequenceAll::template bind_to<meta::TypeList>
+                            ::template map<GetTypeClass>
+                            ::template cartesian_product<meta::TypeList<TargetType>>
+                            ::template filter<HasCast>
+                            ::template Instantiate<std::vector<TypeID>, GetSourceTypeID>();
+  });
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/utility/CastUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/utility/CastUtil.hpp b/types/operations/utility/CastUtil.hpp
index e69de29..e45b06e 100644
--- a/types/operations/utility/CastUtil.hpp
+++ b/types/operations/utility/CastUtil.hpp
@@ -0,0 +1,50 @@
+/**
+ * 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_OPERATIONS_UTILITY_CAST_UTIL_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UTILITY_CAST_UTIL_HPP_
+
+#include <type_traits>
+#include <vector>
+
+#include "types/TypeID.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class CastUtil {
+ public:
+  static std::vector<TypeID> GetCoercibleSourceTypeIDs(const TypeID target_type_id);
+
+
+ private:
+  CastUtil() {}
+
+  DISALLOW_COPY_AND_ASSIGN(CastUtil);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UTILITY_CAST_UTIL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/utility/OperationSynthesizeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/utility/OperationSynthesizeUtil.hpp b/types/operations/utility/OperationSynthesizeUtil.hpp
index 2b910b3..50a5863 100644
--- a/types/operations/utility/OperationSynthesizeUtil.hpp
+++ b/types/operations/utility/OperationSynthesizeUtil.hpp
@@ -17,11 +17,12 @@
  * under the License.
  **/
 
-#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UTILITY_OPERATION_SYNTHESIZE_UTIL_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UTILITY_OPERATION_SYNTHESIZE_UTIL_HPP_
 
 #include <cstddef>
 #include <list>
+#include <memory>
 #include <string>
 #include <type_traits>
 
@@ -29,6 +30,8 @@
 #include "types/Type.hpp"
 #include "types/TypedValue.hpp"
 #include "types/containers/ColumnVector.hpp"
+#include "utility/Macros.hpp"
+#include "utility/meta/TypeList.hpp"
 
 namespace quickstep {
 
@@ -68,35 +71,48 @@ struct FunctorSpecializer<FunctorT, SpecArgs...>
 };
 
 template <typename ColumnVectorT>
-struct ColumnVectorValueAccessor {
-  explicit ColumnVectorValueAccessor(const ColumnVectorT &column_vector_in)
-      : column_vector(column_vector_in),
-        length(column_vector.size()) {}
+class ColumnVectorAccessor {
+ public:
+  constexpr static bool kIsGenericColumnVectorAccessor =
+      (ColumnVectorT::kImplementation == ColumnVector::kGeneric);
+
+  inline explicit ColumnVectorAccessor(const ColumnVectorT &column_vector)
+      : column_vector_(column_vector),
+        length_(column_vector.size()) {}
 
   inline void beginIteration() {
-    pos = static_cast<std::size_t>(-1);
+    pos_ = static_cast<std::size_t>(-1);
   }
 
   inline bool next() {
-    return (++pos) < length;
+    return (++pos_) < length_;
   }
 
   inline std::size_t getNumTuples() const {
-    return length;
+    return length_;
   }
 
-  template <bool nullable>
+  template <bool check_null>
   inline const void* getUntypedValue(const attribute_id) const {
-    return column_vector.template getUntypedValue<nullable>(pos);
+    return column_vector_.template getUntypedValue<check_null>(pos_);
   }
 
   inline TypedValue getTypedValue(const attribute_id) const {
-    return column_vector.getTypedValue(pos);
+    return column_vector_.getTypedValue(pos_);
+  }
+
+  template <bool check_null, bool generic>
+  inline typename std::enable_if_t<generic, ColumnVectorT>::cpptype
+      getLiteralValue() const {
+    return column_vector_.template getLiteralValue<check_null>(pos_);
   }
 
-  const ColumnVectorT &column_vector;
-  const std::size_t length;
-  std::size_t pos;
+ private:
+  const ColumnVectorT &column_vector_;
+  const std::size_t length_;
+  std::size_t pos_;
+
+  DISALLOW_COPY_AND_ASSIGN(ColumnVectorAccessor);
 };
 
 template <typename FuncSpec, typename T, typename EnableT = void>
@@ -105,11 +121,12 @@ struct OperationCodegen;
 template <typename FuncSpec, typename T>
 struct OperationCodegen<FuncSpec, T,
                         std::enable_if_t<T::kMemoryLayout == kCxxInlinePod>> {
+  using ValueType = T;
   using ColumnVectorType = NativeColumnVector;
   using FunctorSpecializer = FuncSpec;
 
   using NativeType = typename T::cpptype;
-  using NativeTypeConst = const typename T::cpptype;
+  using NativeTypeConst = const NativeType;
   using NativeTypeConstRef = const NativeType&;
   using NativeTypeConstPtr = const NativeType*;
 
@@ -151,7 +168,8 @@ struct OperationCodegen<FuncSpec, T,
 
   template <bool nullable, typename AccessorT>
   inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor,
-                                               const attribute_id attr_id) {
+                                               const attribute_id attr_id,
+                                               const Type &, void *) {
     return static_cast<NativeTypeConstPtr>(
         accessor->template getUntypedValue<nullable>(attr_id));
   }
@@ -165,7 +183,8 @@ struct OperationCodegen<FuncSpec, T,
     return *value;
   }
 
-  inline static const NativeType ToNativeValueConst(const TypedValue &value) {
+  inline static const NativeType ToNativeValueConst(const TypedValue &value,
+                                                    const Type &) {
     return value.getLiteral<NativeType>();
   }
 };
@@ -173,6 +192,7 @@ struct OperationCodegen<FuncSpec, T,
 template <typename FuncSpec, typename T>
 struct OperationCodegen<FuncSpec, T,
                         std::enable_if_t<T::kMemoryLayout == kParInlinePod>> {
+  using ValueType = T;
   using ColumnVectorType = NativeColumnVector;
   using FunctorSpecializer = FuncSpec;
 
@@ -223,9 +243,11 @@ struct OperationCodegen<FuncSpec, T,
     FuncSpec::Invoke(functor, left, right, cv->getPtrForDirectWrite());
   }
 
+  // TODO(refactor-type): Use ColumnAccessor to improve performance.
   template <bool nullable, typename AccessorT>
   inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor,
-                                               const attribute_id attr_id) {
+                                               const attribute_id attr_id,
+                                               const Type &, void *) {
     return accessor->template getUntypedValue<nullable>(attr_id);
   }
 
@@ -238,7 +260,8 @@ struct OperationCodegen<FuncSpec, T,
     return value;
   }
 
-  inline static const void* ToNativeValueConst(const TypedValue &value) {
+  inline static const void* ToNativeValueConst(const TypedValue &value,
+                                               const Type &) {
     return value.getDataPtr();
   }
 };
@@ -246,6 +269,7 @@ struct OperationCodegen<FuncSpec, T,
 template <typename FuncSpec, typename T>
 struct OperationCodegen<FuncSpec, T,
                         std::enable_if_t<T::kMemoryLayout == kParOutOfLinePod>> {
+  using ValueType = T;
   using ColumnVectorType = IndirectColumnVector;
   using FunctorSpecializer = FuncSpec;
 
@@ -289,9 +313,9 @@ struct OperationCodegen<FuncSpec, T,
   }
 
   template <bool nullable, typename AccessorT>
-  inline static NativeTypeConstPtr GetValuePtr(
-      const AccessorT *accessor,
-      const attribute_id attr_id) {
+  inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor,
+                                               const attribute_id attr_id,
+                                               const Type &, void *) {
     return accessor->getTypedValue(attr_id);
   }
 
@@ -304,11 +328,121 @@ struct OperationCodegen<FuncSpec, T,
     return value;
   }
 
-  inline static const NativeType& ToNativeValueConst(const TypedValue &value) {
+  inline static const NativeType& ToNativeValueConst(const TypedValue &value,
+                                                     const Type &) {
     return value;
   }
 };
 
+
+// TODO(refactor-type): Remove this.
+namespace internal {
+
+template <typename T>
+std::enable_if_t<T::kIsGenericColumnVectorAccessor,
+                 std::true_type> IsGenericColumnVectorAccessorImpl(int);
+template <typename>
+std::false_type IsGenericColumnVectorAccessorImpl(...);
+
+}  // namespace internal
+
+template <typename T>
+using IsGenericColumnVectorAccessor =
+    decltype(internal::IsGenericColumnVectorAccessorImpl<T>());
+
+template <typename FuncSpec, typename T>
+struct OperationCodegen<FuncSpec, T,
+                        std::enable_if_t<T::kMemoryLayout == kCxxGeneric>> {
+  using ValueType = T;
+  using ColumnVectorType = GenericColumnVector<T>;
+  using FunctorSpecializer = FuncSpec;
+
+  using NativeType = typename T::cpptype;
+  using NativeTypeConst = const NativeType;
+  using NativeTypeConstRef = const NativeType&;
+  using NativeTypeConstPtr = const NativeType*;
+
+  template <typename ArgumentGen, typename ResultType>
+  inline static TypedValue ApplyUnaryTypedValue(
+      typename ArgumentGen::NativeTypeConstRef argument,
+      const ResultType &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    const NativeType result = FuncSpec::Invoke(functor, argument);
+    return result_type.marshallValue(&result);
+  }
+
+  template <typename ArgumentGen>
+  inline static void ApplyUnaryColumnVector(
+      const typename ArgumentGen::NativeTypeConstRef argument,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    cv->appendLiteralValue(FuncSpec::Invoke(functor, argument));
+  }
+
+  template <typename LeftGen, typename RightGen, typename ResultType>
+  inline static TypedValue ApplyBinaryTypedValue(
+      typename LeftGen::NativeTypeConstRef left,
+      typename RightGen::NativeTypeConstRef right,
+      const ResultType &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    const NativeType result = FuncSpec::Invoke(functor, left, right);
+    return result_type.marshallValue(&result);
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static void ApplyBinaryColumnVector(
+      const typename LeftGen::NativeTypeConstRef left,
+      const typename RightGen::NativeTypeConstRef right,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    cv->appendLiteralValue(FuncSpec::Invoke(functor, left, right));
+  }
+
+  // TODO(refactor-type): Use ColumnAccessor to handle the more general case.
+  template <bool nullable, typename AccessorT>
+  inline static NativeTypeConstPtr GetValuePtr(
+      const AccessorT *accessor,
+      const attribute_id attr_id,
+      const Type &, void *,
+      std::enable_if_t<IsGenericColumnVectorAccessor<AccessorT>::value> * = 0) {
+    return &accessor->template getLiteralValue<nullable, true>();
+  }
+
+  // TODO(refactor-type): Use ColumnAccessor to handle the more general case.
+  template <bool nullable, typename AccessorT>
+  inline static NativeTypeConstPtr GetValuePtr(
+      const AccessorT *accessor,
+      const attribute_id attr_id,
+      const ValueType &value_type,
+      std::unique_ptr<NativeType> *cache,
+      std::enable_if_t<!IsGenericColumnVectorAccessor<AccessorT>::value> * = 0) {
+    static_assert(std::is_same<NativeType, typename ValueType::cpptype>::value,
+                  "Unexpected value type in OperationCodegen::GetValuePtr for "
+                  "CxxGeneric types.");
+    cache->reset(static_cast<NativeType*>(
+        value_type.unmarshallTypedValue(accessor->getTypedValue(attr_id))));
+    return cache->get();
+  }
+
+  inline static bool IsNull(NativeTypeConstPtr &value) {
+    return value == nullptr;
+  }
+
+  // Dereference: NativeTypeConstPtr& -> const NativeType&
+  inline static const NativeType& Dereference(NativeTypeConstPtr &value) {
+    return *value;
+  }
+
+  inline static const NativeType ToNativeValueConst(const TypedValue &value,
+                                                    const ValueType &value_type) {
+    // TODO(refactor-type): Improve performance.
+    std::unique_ptr<NativeType> cache(
+        static_cast<NativeType*>(value_type.unmarshallTypedValue(value)));
+    return *cache;
+  }
+};
+
+
 template <typename ...FunctorTypes>
 struct FunctorPack {
   template <typename Dispatcher>
@@ -332,4 +466,4 @@ struct OperationPack {
 
 }  // namespace quickstep
 
-#endif  // QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
+#endif  // QUICKSTEP_TYPES_OPERATIONS_OPERATION_UTILITY_SYNTHESIZE_UTIL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/utility/Cast.hpp
----------------------------------------------------------------------
diff --git a/utility/Cast.hpp b/utility/Cast.hpp
index 7d2a8c0..88bdc72 100644
--- a/utility/Cast.hpp
+++ b/utility/Cast.hpp
@@ -36,7 +36,7 @@ namespace quickstep {
  * @param source_ptrs The vector of shared_ptr objects to be casted.
  * @return target_ptrs The casted vector of shared_ptr with pointers of type const TargetType.
  */
-template<class TargetType, class SourceType>
+template <class TargetType, class SourceType>
 static std::vector<std::shared_ptr<const TargetType>> CastSharedPtrVector(
     const std::vector<std::shared_ptr<const SourceType>> &source_ptrs) {
   std::vector<std::shared_ptr<const TargetType>> target_ptrs;
@@ -46,6 +46,11 @@ static std::vector<std::shared_ptr<const TargetType>> CastSharedPtrVector(
   return target_ptrs;
 }
 
+template <class TargetContainer, class SourceContainer>
+static TargetContainer CastSTLContainer(const SourceContainer &source_container) {
+  return TargetContainer(source_container.begin(), source_container.end());
+}
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/utility/meta/Common.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/Common.hpp b/utility/meta/Common.hpp
index cbad665..bc259da 100644
--- a/utility/meta/Common.hpp
+++ b/utility/meta/Common.hpp
@@ -58,8 +58,8 @@ struct Sequence {
   using contains = EqualsAny<std::integral_constant<T, v>,
                              std::integral_constant<T, s>...>;
 
-  template <typename CollectionT>
-  inline static CollectionT Instantiate() {
+  template <typename Collection>
+  inline static Collection Instantiate() {
     return { s... };
   }
 };
@@ -168,6 +168,22 @@ template <> struct UnsignedInteger<8u> {
   using type = std::uint64_t;
 };
 
+
+//// ----------------------------------------------------------------------------
+//// Macros.
+
+#define QUICKSTEP_TRAIT_HAS_STATIC_METHOD(traitname, methodname) \
+  template <typename C> \
+  class traitname { \
+   private: \
+    template <typename T> \
+    static std::true_type Impl(int, decltype(T::methodname) * = 0); \
+    template <typename T> \
+    static std::false_type Impl(...); \
+   public: \
+    static constexpr bool value = decltype(Impl<C>(0))::value; \
+  }
+
 /** @} */
 
 }  // namespace meta

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/utility/meta/TypeList.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TypeList.hpp b/utility/meta/TypeList.hpp
index 5f4c4d9..47b03c8 100644
--- a/utility/meta/TypeList.hpp
+++ b/utility/meta/TypeList.hpp
@@ -31,25 +31,22 @@ namespace meta {
  */
 
 template <typename ...Ts>
-class TypeList;
+struct TypeList;
 
 namespace internal {
 
 using EmptyList = TypeList<>;
 
 template <typename ...Ts>
-class TypeListBase {
- private:
-  template <typename ...Tail> struct AppendHelper {
-    using type = TypeList<Ts..., Tail...>;
-  };
-
- public:
+struct TypeListBase {
   static constexpr std::size_t length = sizeof...(Ts);
 
   using type = TypeList<Ts...>;
   using self = type;
 
+  // ---------------------------------------------------------------------------
+  // Meta-methods.
+
   template <template <typename ...> class Host>
   using bind_to = Host<Ts...>;
 
@@ -76,7 +73,7 @@ class TypeListBase {
   using unique = typename UniqueImpl<EmptyList, self, DumbT...>::type;
 
   template <typename TL>
-  using append = typename TL::template bind_to<AppendHelper>::type;
+  using append = typename AppendImpl<self, TL>::type;
 
   template <typename TL>
   using cartesian_product = typename CartesianProductImpl<self, TL>::type;
@@ -113,19 +110,32 @@ class TypeListBase {
 
   template <typename T>
   using as_sequence = typename AsSequenceImpl<T, Ts...>::type;
+
+  // ---------------------------------------------------------------------------
+  // Methods.
+
+  template <typename Collection, typename Instantiator>
+  static Collection Instantiate(const Instantiator &functor) {
+    return { functor(Ts())... };
+  }
+
+  template <typename Collection, template <typename ...> class Instantiator>
+  static Collection Instantiate() {
+    return { Instantiator<Ts>()()... };
+  }
 };
 
 }  // namespace internal
 
 template <typename T, typename ...Ts>
-class TypeList<T, Ts...> : public internal::TypeListBase<T, Ts...> {
+struct TypeList<T, Ts...> : public internal::TypeListBase<T, Ts...> {
  public:
   using head = T;
   using tail = TypeList<Ts...>;
 };
 
 template <>
-class TypeList<> : public internal::TypeListBase<> {};
+struct TypeList<> : public internal::TypeListBase<> {};
 
 /** @} */
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/utility/meta/TypeListMetaFunctions.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TypeListMetaFunctions.hpp b/utility/meta/TypeListMetaFunctions.hpp
index baebe91..ba3a419 100644
--- a/utility/meta/TypeListMetaFunctions.hpp
+++ b/utility/meta/TypeListMetaFunctions.hpp
@@ -30,7 +30,7 @@ namespace meta {
  */
 
 template <typename ...Ts>
-class TypeList;
+struct TypeList;
 
 
 template <typename T>
@@ -112,6 +112,15 @@ struct UniqueImpl<Out, Rest,
                  typename Rest::tail> {};
 
 
+template <typename TL, typename UL>
+struct AppendImpl;
+
+template <typename ...Ts, typename ...Us>
+struct AppendImpl<meta::TypeList<Ts...>, meta::TypeList<Us...>> {
+  using type = meta::TypeList<Ts..., Us...>;
+};
+
+
 template <typename Out, typename Rest, typename Subtrahend, typename Enable = void>
 struct SubtractImpl;