quickstep-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jianq...@apache.org
Subject [17/27] incubator-quickstep git commit: Refactor type system and operations.
Date Wed, 12 Apr 2017 19:34:20 GMT
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt
index 6e1923a..bcd756e 100644
--- a/types/operations/unary_operations/CMakeLists.txt
+++ b/types/operations/unary_operations/CMakeLists.txt
@@ -16,14 +16,26 @@
 # under the License.
 
 # Declare micro-libs:
-add_library(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations ArithmeticUnaryOperations.cpp ArithmeticUnaryOperations.hpp)
-add_library(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperators ../../../empty_src.cpp ArithmeticUnaryOperators.hpp)
-add_library(quickstep_types_operations_unaryoperations_DateExtractOperation DateExtractOperation.cpp DateExtractOperation.hpp)
-add_library(quickstep_types_operations_unaryoperations_NumericCastOperation ../../../empty_src.cpp NumericCastOperation.hpp)
-add_library(quickstep_types_operations_unaryoperations_SubstringOperation SubstringOperation.cpp SubstringOperation.hpp)
+add_library(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
+            ../../../empty_src.cpp
+            ArithmeticUnaryOperations.hpp)
+add_library(quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
+            ../../../empty_src.cpp
+            AsciiStringUnaryOperations.hpp)
+add_library(quickstep_types_operations_unaryoperations_CMathUnaryOperations
+            ../../../empty_src.cpp
+            CMathUnaryOperations.hpp)
+add_library(quickstep_types_operations_unaryoperations_CastOperation CastOperation.cpp CastOperation.hpp)
+add_library(quickstep_types_operations_unaryoperations_DateExtractOperation
+            DateExtractOperation.cpp
+            DateExtractOperation.hpp)
+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_UnaryOperationFactory UnaryOperationFactory.cpp UnaryOperationFactory.hpp)
-add_library(quickstep_types_operations_unaryoperations_UnaryOperationID UnaryOperationID.cpp UnaryOperationID.hpp)
+add_library(quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+            ../../../empty_src.cpp
+            UnaryOperationWrapper.hpp)
 
 # Link dependencies:
 target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
@@ -33,109 +45,110 @@ target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnary
                       quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
+                      quickstep_types_YearMonthIntervalType
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper)
+target_link_libraries(quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
+                      quickstep_types_CharType
+                      quickstep_types_IntType
                       quickstep_types_Type
-                      quickstep_types_TypeErrors
+                      quickstep_types_TypeFactory
                       quickstep_types_TypeID
-                      quickstep_types_TypedValue
-                      quickstep_types_YearMonthIntervalType
-                      quickstep_types_operations_unaryoperations_ArithmeticUnaryOperators
-                      quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
-                      quickstep_utility_EqualsAnyConstant
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperators
-                      glog
-                      quickstep_catalog_CatalogTypedefs
-                      quickstep_storage_StorageBlockInfo
-                      quickstep_storage_ValueAccessor
-                      quickstep_storage_ValueAccessorUtil
-                      quickstep_types_TypedValue
-                      quickstep_types_containers_ColumnVector
-                      quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOperation
+                      quickstep_types_VarCharType
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_port_strnlen
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_operations_unaryoperations_CMathUnaryOperations
+                      quickstep_types_DoubleType
+                      quickstep_types_FloatType
+                      quickstep_types_IntType
+                      quickstep_types_LongType
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_operations_unaryoperations_CastOperation
                       glog
-                      quickstep_catalog_CatalogTypedefs
-                      quickstep_storage_StorageBlockInfo
-                      quickstep_storage_ValueAccessor
-                      quickstep_storage_ValueAccessorUtil
-                      quickstep_types_DatetimeLit
+                      quickstep_types_CharType
+                      quickstep_types_DoubleType
+                      quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
+                      quickstep_types_TypeUtil
                       quickstep_types_TypedValue
-                      quickstep_types_containers_ColumnVector
-                      quickstep_types_operations_Operation_proto
+                      quickstep_types_VarCharType
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_unaryoperations_NumericCastOperation
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_port_strnlen
+                      quickstep_utility_EqualsAnyConstant
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
+target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOperation
                       glog
-                      quickstep_catalog_CatalogTypedefs
-                      quickstep_storage_ValueAccessor
-                      quickstep_storage_ValueAccessorUtil
-                      quickstep_types_DoubleType
-                      quickstep_types_FloatType
+                      quickstep_types_DateType
+                      quickstep_types_DatetimeLit
+                      quickstep_types_DatetimeType
                       quickstep_types_IntType
                       quickstep_types_LongType
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
-                      quickstep_types_containers_ColumnVector
-                      quickstep_types_operations_Operation_proto
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
                       quickstep_utility_Macros
-                      quickstep_utility_PtrMap)
+                      quickstep_utility_StringUtil)
 target_link_libraries(quickstep_types_operations_unaryoperations_SubstringOperation
                       quickstep_catalog_CatalogTypedefs
                       quickstep_storage_ValueAccessor
                       quickstep_storage_ValueAccessorUtil
+                      quickstep_types_CharType
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
+                      quickstep_types_VarCharType
                       quickstep_types_containers_ColumnVector
                       quickstep_types_containers_ColumnVectorUtil
-                      quickstep_types_operations_Operation_proto
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
                       quickstep_types_port_strnlen
-                      quickstep_utility_HashPair
                       quickstep_utility_Macros
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_Dispatchers)
 target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_catalog_CatalogTypedefs
-                      quickstep_storage_StorageBlockInfo
                       quickstep_types_TypedValue
                       quickstep_types_operations_Operation
+                      quickstep_types_operations_OperationSignature
                       quickstep_types_operations_Operation_proto
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
                       quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationFactory
+target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationWrapper
                       glog
+                      quickstep_catalog_CatalogTypedefs
+                      quickstep_storage_ValueAccessor
+                      quickstep_storage_ValueAccessorUtil
+                      quickstep_types_Type
                       quickstep_types_TypeFactory
-                      quickstep_types_operations_Operation_proto
-                      quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
-                      quickstep_types_operations_unaryoperations_DateExtractOperation
-                      quickstep_types_operations_unaryoperations_NumericCastOperation
-                      quickstep_types_operations_unaryoperations_SubstringOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
+                      quickstep_types_TypeID
+                      quickstep_types_TypedValue
+                      quickstep_types_containers_ColumnVector
+                      quickstep_types_operations_OperationSignature
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_utility_Macros)
 
 # Module all-in-one library:
 add_library(quickstep_types_operations_unaryoperations ../../../empty_src.cpp)
 target_link_libraries(quickstep_types_operations_unaryoperations
                       quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
-                      quickstep_types_operations_unaryoperations_ArithmeticUnaryOperators
+                      quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
+                      quickstep_types_operations_unaryoperations_CMathUnaryOperations
+                      quickstep_types_operations_unaryoperations_CastOperation
                       quickstep_types_operations_unaryoperations_DateExtractOperation
-                      quickstep_types_operations_unaryoperations_NumericCastOperation
                       quickstep_types_operations_unaryoperations_SubstringOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationFactory
-                      quickstep_types_operations_unaryoperations_UnaryOperationID)
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper)
 
 # Tests:
 
@@ -160,11 +173,9 @@ target_link_libraries(UnaryOperation_tests
                       quickstep_types_containers_ColumnVector
                       quickstep_types_operations_Operation_proto
                       quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
+                      quickstep_types_operations_unaryoperations_CastOperation
                       quickstep_types_operations_unaryoperations_DateExtractOperation
-                      quickstep_types_operations_unaryoperations_NumericCastOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationFactory
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
                       quickstep_utility_EqualsAnyConstant
                       quickstep_utility_Macros)
 add_test(UnaryOperation_tests UnaryOperation_tests)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/CMathUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMathUnaryOperations.hpp b/types/operations/unary_operations/CMathUnaryOperations.hpp
new file mode 100644
index 0000000..7a372e0
--- /dev/null
+++ b/types/operations/unary_operations/CMathUnaryOperations.hpp
@@ -0,0 +1,116 @@
+/**
+ * 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_CMATH_UNARY_OPERATIONS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_OPERATIONS_HPP_
+
+#include <cmath>
+#include <string>
+
+#include "types/DoubleType.hpp"
+#include "types/FloatType.hpp"
+#include "types/IntType.hpp"
+#include "types/LongType.hpp"
+#include "types/operations/OperationUtil.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename ArgumentT, typename ResultT,
+          typename ResultT::cpptype f(typename ArgumentT::cpptype),
+          typename FunctorNameT>
+struct CMathUnaryFunctorWrapper {
+  struct Implemenation : public UnaryFunctor<ArgumentT, ResultT> {
+    inline typename ResultT::cpptype apply(
+        const typename ArgumentT::cpptype &argument) const {
+      return f(argument);
+    }
+    inline static std::string GetName() {
+      return FunctorNameT::ToString();
+    }
+  };
+
+  typedef Implemenation type;
+};
+
+template <typename ArgumentT, typename ResultT,
+          typename ResultT::cpptype f(typename ArgumentT::cpptype),
+          typename FunctorNameT>
+using CMathUnaryFunctor =
+    typename CMathUnaryFunctorWrapper<ArgumentT, ResultT, f, FunctorNameT>::type;
+
+inline std::int64_t CMathRound(const float arg) {
+  return std::llround(arg);
+}
+inline std::int64_t CMathRound(const double arg) {
+  return std::llround(arg);
+}
+
+using CMathUnaryFunctorPack = FunctorPack<
+// abs
+    CMathUnaryFunctor<IntType, IntType,
+                      std::abs, meta::StringLiteral<'a','b','s'>>,
+    CMathUnaryFunctor<LongType, LongType,
+                      std::abs, meta::StringLiteral<'a','b','s'>>,
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::fabs, meta::StringLiteral<'a','b','s'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::fabs, meta::StringLiteral<'a','b','s'>>,
+// sqrt
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::sqrt, meta::StringLiteral<'s','q','r','t'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::sqrt, meta::StringLiteral<'s','q','r','t'>>,
+// exp
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::exp, meta::StringLiteral<'e','x','p'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::exp, meta::StringLiteral<'e','x','p'>>,
+// log
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::log, meta::StringLiteral<'l','o','g'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::log, meta::StringLiteral<'l','o','g'>>,
+// ceil
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::ceil, meta::StringLiteral<'c','e','i','l'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::ceil, meta::StringLiteral<'c','e','i','l'>>,
+// floor
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::floor, meta::StringLiteral<'f','l','o','o','r'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::floor, meta::StringLiteral<'f','l','o','o','r'>>,
+// round
+    CMathUnaryFunctor<FloatType, LongType,
+                      CMathRound, meta::StringLiteral<'r','o','u','n','d'>>,
+    CMathUnaryFunctor<DoubleType, LongType,
+                      CMathRound, meta::StringLiteral<'r','o','u','n','d'>>
+>;
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/CastOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.cpp b/types/operations/unary_operations/CastOperation.cpp
new file mode 100644
index 0000000..5091e89
--- /dev/null
+++ b/types/operations/unary_operations/CastOperation.cpp
@@ -0,0 +1,298 @@
+/**
+ * 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/unary_operations/CastOperation.hpp"
+
+#include <algorithm>
+#include <map>
+#include <cstdint>
+#include <cstdlib>
+#include <string>
+#include <vector>
+
+#include "types/CharType.hpp"
+#include "types/DoubleType.hpp"
+#include "types/FloatType.hpp"
+#include "types/IntType.hpp"
+#include "types/LongType.hpp"
+#include "types/Type.hpp"
+#include "types/TypeUtil.hpp"
+#include "types/TypedValue.hpp"
+#include "types/VarCharType.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/port/strnlen.hpp"
+#include "utility/EqualsAnyConstant.hpp"
+#include "utility/StringUtil.hpp"
+
+namespace quickstep {
+
+namespace {
+
+template <typename ArgumentT, typename ResultT>
+struct NumericCastToNumericFunctor
+    : public UnaryFunctor<ArgumentT, ResultT> {
+  inline typename ResultT::cpptype apply(
+      const typename ArgumentT::cpptype &argument) const {
+    return static_cast<typename ResultT::cpptype>(argument);
+  }
+};
+
+template <typename ArgumentT, typename ResultT>
+class CastToAsciiStringFunctor : public UnaryFunctor<ArgumentT, ResultT> {
+ public:
+  explicit CastToAsciiStringFunctor(const ArgumentT &argument_type,
+                                    const std::size_t max_string_length)
+      : argument_type_(argument_type),
+        max_string_length_(max_string_length) {}
+
+  inline void apply(const typename ArgumentT::cpptype &argument, void *result) const {
+    std::string str = argument_type_.printValueToString(TypedValue(argument));
+    const std::size_t str_len = str.length();
+
+    if (str_len < max_string_length_) {
+      std::memcpy(result, str.c_str(), str_len);
+      static_cast<char *>(result)[str_len] = 0;
+    } else {
+      std::memcpy(result, str.c_str(), max_string_length_);
+    }
+  }
+
+  inline TypedValue apply(const typename ArgumentT::cpptype &argument) const {
+    std::string str = argument_type_.printValueToString(TypedValue(argument));
+    const std::size_t len = std::min(str.length(), max_string_length_);
+    const std::size_t buf_len = len + 1;
+
+    char *buf = static_cast<char *>(std::malloc(buf_len));
+    std::memcpy(buf, str.c_str(), len);
+    buf[len] = 0;
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
+  }
+
+ private:
+  const ArgumentT &argument_type_;
+  const std::size_t max_string_length_;
+};
+
+template <typename ResultCppType>
+ResultCppType CastStringToNumericImpl(const char *str);
+
+template <>
+bool CastStringToNumericImpl(const char *str) {
+  const std::string lo_str = ToLower(str);
+  if (lo_str == "true") {
+    return true;
+  } else {
+    return false;
+  }
+}
+template <>
+int CastStringToNumericImpl(const char *str) {
+  return std::atoi(str);
+}
+template <>
+float CastStringToNumericImpl(const char *str) {
+  return static_cast<float>(std::atof(str));
+}
+template <>
+std::int64_t CastStringToNumericImpl(const char *str) {
+  return std::atoll(str);
+}
+template <>
+double CastStringToNumericImpl(const char *str) {
+  return std::atof(str);
+}
+
+template <typename ArgumentT, typename ResultT,
+          typename ResultT::cpptype f(const char*)>
+struct AsciiStringCastToNumericFunctor
+    : public UnaryFunctor<ArgumentT, ResultT> {
+  explicit AsciiStringCastToNumericFunctor(const std::size_t max_string_length)
+      : max_string_length_(max_string_length) {}
+
+  inline typename ResultT::cpptype apply(const TypedValue &argument) const {
+    return f(static_cast<const char*>(argument.getDataPtr()));
+  }
+
+  inline typename ResultT::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 f(value.c_str());
+  }
+
+ private:
+  const std::size_t max_string_length_;
+};
+
+template <typename ArgumentT, typename ResultT>
+struct AsciiStringCastToAsciiStringFunctor
+    : public UnaryFunctor<ArgumentT, ResultT> {
+  explicit AsciiStringCastToAsciiStringFunctor(const std::size_t max_string_length)
+      : max_string_length_(max_string_length) {}
+
+  inline void apply(const void *argument, void *result) const {
+    std::memcpy(result, argument, max_string_length_);
+  }
+
+  inline void apply(const TypedValue &argument, void *result) const {
+    std::memcpy(result,
+                argument.getOutOfLineData(),
+                std::min(argument.getDataSize(), max_string_length_));
+  }
+
+  inline TypedValue apply(const void *argument) const {
+    const std::size_t len =
+        strnlen(static_cast<const char*>(argument), max_string_length_);
+
+    char *buf = static_cast<char *>(std::malloc(len+1));
+    std::memcpy(buf, argument, len);
+    buf[len] = 0;
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, len+1);
+  }
+
+  inline TypedValue apply(const TypedValue &argument) const {
+    const std::size_t len =
+        std::min(argument.getDataSize() - 1, max_string_length_);
+
+    char *buf = static_cast<char *>(std::malloc(len+1));
+    std::memcpy(buf, argument.getDataPtr(), len);
+    buf[len] = 0;
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, len+1);
+  }
+
+ private:
+  const std::size_t max_string_length_;
+};
+
+}  // namespace
+
+const re2::RE2 CastOperation::kTypePattern("([a-z]+)(\\(([0-9]+)\\))?");
+
+const std::map<std::string, TypeID> CastOperation::kNameToTypeIDMap = {
+    { "bool",    kBool },
+    { "int",     kInt },
+    { "long",    kLong },
+    { "float",   kFloat },
+    { "double",  kDouble },
+    { "char",    kChar },
+    { "varchar", kVarChar }
+};
+
+UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
+    const Type &type,
+    const std::vector<TypedValue> &static_arguments) const {
+  const Type *result_type = getResultType(type, static_arguments);
+  DCHECK(result_type != nullptr);
+
+  const TypeID argument_type_id = type.getTypeID();
+  const TypeID result_type_id = result_type->getTypeID();
+
+  if (QUICKSTEP_EQUALS_ANY_CONSTANT(argument_type_id, kBool, kInt, kLong, kFloat, kDouble)) {
+    return InvokeOnTypeID<TypeIDSelectorNumeric>(
+        argument_type_id,
+        [&](auto arg_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+      using ArgumentT = typename TypeIDTrait<decltype(arg_tid)::value>::TypeClass;
+
+      switch (result_type_id) {
+        case kBool:  // Fall through
+        case kInt:
+        case kLong:
+        case kFloat:
+        case kDouble: {
+          return InvokeOnTypeID<TypeIDSelectorNumeric>(
+              result_type_id,
+              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
+
+            return new UncheckedUnaryOperatorWrapperCodegen<
+                NumericCastToNumericFunctor<ArgumentT, ResultT>>(type, *result_type);
+          });
+        }
+        case kChar:  // Fall through
+        case kVarChar: {
+          return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
+              result_type_id,
+              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
+
+            return new UncheckedUnaryOperatorWrapperCodegen<
+                 CastToAsciiStringFunctor<ArgumentT, ResultT>>(
+                     type, *result_type,
+                     static_cast<const ArgumentT&>(type),
+                     static_cast<const ResultT*>(result_type)->getStringLength());
+          });
+        }
+        default:
+          LOG(FATAL) << "Unexpected result type " << result_type->getName()
+                     << " in CastOperation::makeUncheckedUnaryOperator "
+                     << "for argument type " << type.getName();
+      }
+    });
+  } else if (QUICKSTEP_EQUALS_ANY_CONSTANT(argument_type_id, kChar, kVarChar)) {
+    return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
+        argument_type_id,
+        [&](auto arg_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+      using ArgumentT = typename TypeIDTrait<decltype(arg_tid)::value>::TypeClass;
+
+      switch (result_type_id) {
+        case kBool:  // Fall through
+        case kInt:
+        case kLong:
+        case kFloat:
+        case kDouble: {
+          return InvokeOnTypeID<TypeIDSelectorNumeric>(
+              result_type_id,
+              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
+
+            return new UncheckedUnaryOperatorWrapperCodegen<
+                AsciiStringCastToNumericFunctor<
+                    ArgumentT, ResultT,
+                    CastStringToNumericImpl<typename ResultT::cpptype>>>(
+                        type, *result_type,
+                        static_cast<const ArgumentT&>(type).getStringLength());
+          });
+        }
+        case kChar:  // Fall through
+        case kVarChar: {
+          return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
+              result_type_id,
+              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
+
+            return new UncheckedUnaryOperatorWrapperCodegen<
+                 AsciiStringCastToAsciiStringFunctor<ArgumentT, ResultT>>(
+                     type, *result_type,
+                     std::min(static_cast<const ArgumentT&>(type).getStringLength(),
+                              static_cast<const ResultT*>(result_type)->getStringLength()));
+          });
+        }
+        default:
+          LOG(FATAL) << "Unexpected result type " << result_type->getName()
+                     << " in CastOperation::makeUncheckedUnaryOperator "
+                     << "for argument type " << type.getName();
+      }
+    });
+  }
+
+  LOG(FATAL) << "Unexpected argument type in "
+             << "CastOperation::makeUncheckedUnaryOperator: "
+             << result_type->getName();
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/CastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.hpp b/types/operations/unary_operations/CastOperation.hpp
new file mode 100644
index 0000000..140c152
--- /dev/null
+++ b/types/operations/unary_operations/CastOperation.hpp
@@ -0,0 +1,154 @@
+/**
+ * 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_NUMERIC_CAST_OPERATION_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_
+
+#include <cstddef>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "types/IntType.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
+
+#include "glog/logging.h"
+
+#include "re2/stringpiece.h"
+#include "re2/re2.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+/**
+ * @brief UnaryOperation for CAST.
+ */
+class CastOperation : public UnaryOperation {
+ public:
+  CastOperation() {}
+
+  std::string getName() const override {
+    return "Cast";
+  }
+
+  std::string getShortName() const override {
+    return "Cast";
+  }
+
+  std::vector<OperationSignaturePtr> getSignatures() const override {
+    const std::vector<TypeID> source_type_ids =
+        { kBool, kInt, kLong, kFloat, kDouble, kChar, kVarChar };
+    const std::vector<TypeID> target_type_carrier = { kVarChar };
+
+    std::vector<OperationSignaturePtr> signatures;
+    for (const TypeID source_type_id : source_type_ids) {
+      signatures.emplace_back(
+          OperationSignature::Create(getName(), {source_type_id}, target_type_carrier));
+    }
+    return signatures;
+  }
+
+  bool canApplyTo(const Type &type,
+                  const std::vector<TypedValue> &static_arguments,
+                  std::string *message) const override {
+    DCHECK_EQ(1u, static_arguments.size());
+    if (getResultTypeInternal(type, static_arguments.front()) == nullptr) {
+      *message = "Invalid target type for CAST";
+      return false;
+    }
+    return true;
+  }
+
+  const Type* getResultType(
+      const Type &type,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK_EQ(1u, static_arguments.size());
+    const Type *target_type =
+        getResultTypeInternal(type, static_arguments.front());
+    DCHECK(target_type != nullptr);
+    return target_type;
+  }
+
+  UncheckedUnaryOperator* makeUncheckedUnaryOperator(
+      const Type &type,
+      const std::vector<TypedValue> &static_arguments) const override;
+
+ private:
+  static const Type* getResultTypeInternal(const Type &type,
+                                           const TypedValue &type_arg) {
+    DCHECK(type_arg.getTypeID() == kVarChar);
+    const std::string type_str =
+        ToLower(std::string(static_cast<const char*>(type_arg.getOutOfLineData())));
+
+    if (type_str == "text") {
+      return &TypeFactory::GetType(
+          kVarChar, type.getPrintWidth(), type.isNullable());
+    }
+
+    const re2::StringPiece type_piece(type_str);
+    std::string type_name;
+    std::string length_str;
+    if (!re2::RE2::FullMatch(type_piece,
+                             kTypePattern,
+                             &type_name,
+                             static_cast<void *>(nullptr),
+                             &length_str)) {
+      return nullptr;
+    }
+
+    auto it = kNameToTypeIDMap.find(type_name);
+    if (it == kNameToTypeIDMap.end()) {
+      return nullptr;
+    }
+
+    if (length_str.empty()) {
+      return &TypeFactory::GetType(it->second);
+    } else {
+      TypedValue length_value;
+      if (IntType::InstanceNonNullable().parseValueFromString(length_str, &length_value)) {
+        return &TypeFactory::GetType(
+            it->second,
+            static_cast<std::size_t>(length_value.getLiteral<int>()),
+            type.isNullable());
+      }
+    }
+    return nullptr;
+  }
+
+  static const re2::RE2 kTypePattern;
+  static const std::map<std::string, TypeID> kNameToTypeIDMap;
+
+  DISALLOW_COPY_AND_ASSIGN(CastOperation);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/DateExtractOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.cpp b/types/operations/unary_operations/DateExtractOperation.cpp
index c99e403..f95e109 100644
--- a/types/operations/unary_operations/DateExtractOperation.cpp
+++ b/types/operations/unary_operations/DateExtractOperation.cpp
@@ -21,521 +21,135 @@
 
 #include <cstddef>
 #include <cstdint>
-#include <memory>
+#include <map>
 #include <string>
 #include <type_traits>
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-#include <utility>
 #include <vector>
 
-#include "storage/StorageBlockInfo.hpp"
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-#include "catalog/CatalogTypedefs.hpp"
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
+#include "types/DateType.hpp"
 #include "types/DatetimeLit.hpp"
-#include "types/IntType.hpp"
-#include "types/LongType.hpp"
+#include "types/DatetimeType.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/Operation.pb.h"
-#include "utility/Macros.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
 
 #include "glog/logging.h"
 
-using std::int32_t;
-using std::int64_t;
-
 namespace quickstep {
 
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToTypedValue(
-    const TypedValue &argument) const {
-  if (argument_nullable && argument.isNull()) {
-    return TypedValue(kLong);
-  }
-
-  return TypedValue(dateExtract(argument.getLiteral<DatetimeLit>()));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToTypedValue(
-    const TypedValue &argument) const {
-  if (argument_nullable && argument.isNull()) {
-    return TypedValue(kInt);
-  }
-
-  return TypedValue(dateExtract(argument.getLiteral<DateLit>()));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr(const void *argument) const {
-  if (argument_nullable && argument == nullptr) {
-    return TypedValue(kLong);
-  }
-
-  return TypedValue(dateExtract(*static_cast<const DatetimeLit*>(argument)));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr(const void *argument) const {
-  if (argument_nullable && argument == nullptr) {
-    return TypedValue(kInt);
-  }
-
-  return TypedValue(dateExtract(*static_cast<const DateLit*>(argument)));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToColumnVector(
-    const ColumnVector &argument) const {
-  // Datetime are usable with NativeColumnVector, so 'argument' should always
-  // be native.
-  DCHECK(argument.isNative());
-
-  const NativeColumnVector &native_argument = static_cast<const NativeColumnVector&>(argument);
-  std::unique_ptr<NativeColumnVector> result(
-      new NativeColumnVector(LongType::Instance(argument_nullable), native_argument.size()));
-
-  for (std::size_t pos = 0;
-       pos < native_argument.size();
-       ++pos) {
-    const DatetimeLit *datetime_arg =
-        static_cast<const DatetimeLit*>(native_argument.getUntypedValue<argument_nullable>(pos));
-    if (argument_nullable && (datetime_arg == nullptr)) {
-      result->appendNullValue();
-    } else {
-      *static_cast<int64_t*>(result->getPtrForDirectWrite())
-          = dateExtract(*datetime_arg);
-    }
-  }
-
-  return result.release();
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToColumnVector(
-    const ColumnVector &argument) const {
-  // Date is usable with NativeColumnVector, so 'argument' should always
-  // be native.
-  DCHECK(argument.isNative());
-
-  const NativeColumnVector &native_argument = static_cast<const NativeColumnVector&>(argument);
-  std::unique_ptr<NativeColumnVector> result(
-      new NativeColumnVector(IntType::Instance(argument_nullable), native_argument.size()));
-
-  for (std::size_t pos = 0;
-       pos < native_argument.size();
-       ++pos) {
-    const DateLit *date_arg =
-        static_cast<const DateLit*>(native_argument.getUntypedValue<argument_nullable>(pos));
-    if (argument_nullable && (date_arg == nullptr)) {
-      result->appendNullValue();
-    } else {
-      *static_cast<int32_t*>(result->getPtrForDirectWrite())
-          = dateExtract(*date_arg);
-    }
-  }
-
-  return result.release();
-}
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessor(
-    ValueAccessor *accessor,
-    const attribute_id argument_attr_id) const {
-  return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-      accessor,
-      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    std::unique_ptr<NativeColumnVector> result(
-        new NativeColumnVector(LongType::Instance(argument_nullable), accessor->getNumTuples()));
-    accessor->beginIteration();
-    while (accessor->next()) {
-      const DatetimeLit *datetime_arg =
-          static_cast<const DatetimeLit*>(
-              accessor->template getUntypedValue<argument_nullable>(argument_attr_id));
-      if (argument_nullable && (datetime_arg == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<int64_t*>(result->getPtrForDirectWrite())
-            = this->dateExtract(*datetime_arg);
-      }
-    }
-    return result.release();
-  });
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessor(
-    ValueAccessor *accessor,
-    const attribute_id argument_attr_id) const {
-  return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-      accessor,
-      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    std::unique_ptr<NativeColumnVector> result(
-        new NativeColumnVector(IntType::Instance(argument_nullable), accessor->getNumTuples()));
-    accessor->beginIteration();
-    while (accessor->next()) {
-      const DateLit *date_arg =
-          static_cast<const DateLit*>(
-              accessor->template getUntypedValue<argument_nullable>(argument_attr_id));
-      if (argument_nullable && (date_arg == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<int32_t*>(result->getPtrForDirectWrite())
-            = this->dateExtract(*date_arg);
-      }
-    }
-    return result.release();
-  });
-}
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessorForJoin(
-    ValueAccessor *accessor,
-    const bool use_left_relation,
-    const attribute_id argument_attr_id,
-    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const {
-  std::unique_ptr<NativeColumnVector> result(
-      new NativeColumnVector(LongType::Instance(argument_nullable), joined_tuple_ids.size()));
-  return InvokeOnValueAccessorNotAdapter(
-      accessor,
-      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
-      const DatetimeLit *datetime_arg =
-          static_cast<const DatetimeLit*>(
-              accessor->template getUntypedValueAtAbsolutePosition<argument_nullable>(
-                  argument_attr_id,
-                  use_left_relation ? joined_pair.first : joined_pair.second));
-      if (argument_nullable && (datetime_arg == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<int64_t*>(result->getPtrForDirectWrite())
-            = this->dateExtract(*datetime_arg);
-      }
-    }
-    return result.release();
-  });
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessorForJoin(
-    ValueAccessor *accessor,
-    const bool use_left_relation,
-    const attribute_id argument_attr_id,
-    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const {
-  std::unique_ptr<NativeColumnVector> result(
-      new NativeColumnVector(IntType::Instance(argument_nullable), joined_tuple_ids.size()));
-  return InvokeOnValueAccessorNotAdapter(
-      accessor,
-      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
-      const DateLit *date_arg =
-          static_cast<const DateLit*>(
-              accessor->template getUntypedValueAtAbsolutePosition<argument_nullable>(
-                  argument_attr_id,
-                  use_left_relation ? joined_pair.first : joined_pair.second));
-      if (argument_nullable && (date_arg == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<int32_t*>(result->getPtrForDirectWrite())
-            = this->dateExtract(*date_arg);
-      }
-    }
-    return result.release();
-  });
-}
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-template <DateExtractUnit unit, bool argument_nullable>
-inline int64_t
-DatetimeExtractUncheckedOperator<unit, argument_nullable>::dateExtract(
-    const DatetimeLit &argument) const {
-  switch (unit) {
-    case DateExtractUnit::kYear:
-      return argument.yearField();
-    case DateExtractUnit::kMonth:
-      return argument.monthField();
-    case DateExtractUnit::kDay:
-      return argument.dayField();
-    case DateExtractUnit::kHour:
-      return argument.hourField();
-    case DateExtractUnit::kMinute:
-      return argument.minuteField();
-    case DateExtractUnit::kSecond:
-      return argument.secondField();
-    default:
-      FATAL_ERROR("Unsupported DateExtractUnit in DatetimeExtractUncheckedOperator::dateExtract.");
-  }
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-inline int32_t DateExtractUncheckedOperator<unit, argument_nullable>::dateExtract(const DateLit &argument) const {
-  switch (unit) {
-    case DateExtractUnit::kYear:
-      return argument.yearField();
-    case DateExtractUnit::kMonth:
-      return argument.monthField();
-    default:
-      FATAL_ERROR("Unsupported DateExtractUnit in DateExtractUncheckedOperator::dateExtract.");
-  }
-}
-
-const DateExtractOperation& DateExtractOperation::Instance(const DateExtractUnit unit) {
-  switch (unit) {
-    case DateExtractUnit::kYear: {
-      static DateExtractOperation instance(DateExtractUnit::kYear);
-      return instance;
-    }
-    case DateExtractUnit::kMonth: {
-      static DateExtractOperation instance(DateExtractUnit::kMonth);
-      return instance;
-    }
-    case DateExtractUnit::kDay: {
-      static DateExtractOperation instance(DateExtractUnit::kDay);
-      return instance;
-    }
-    case DateExtractUnit::kHour: {
-      static DateExtractOperation instance(DateExtractUnit::kHour);
-      return instance;
-    }
-    case DateExtractUnit::kMinute: {
-      static DateExtractOperation instance(DateExtractUnit::kMinute);
-      return instance;
-    }
-    case DateExtractUnit::kSecond: {
-      static DateExtractOperation instance(DateExtractUnit::kSecond);
-      return instance;
-    }
-    default: {
-      FATAL_ERROR("Unsupported DateExtractUnit in DateExtractOperation::Instance.");
+struct DateExtractFunctor : public UnaryFunctor<DateType, IntType> {
+  template <typename DateExtractUnitT>
+  inline int apply(const DateLit &argument) const {
+    switch (DateExtractUnitT::value) {
+      case DateExtractUnit::kYear:
+        return argument.yearField();
+      case DateExtractUnit::kMonth:
+        return argument.monthField();
+      case DateExtractUnit::kDay:
+        return argument.dayField();
+      default:
+        DLOG(FATAL) << "Unsupported DateExtractUnit in DateExtractFunctor::apply";
     }
   }
-}
-
-serialization::UnaryOperation DateExtractOperation::getProto() const {
-  serialization::UnaryOperation proto;
-  proto.set_operation_id(serialization::UnaryOperation::DATE_EXTRACT);
-
-  switch (unit_) {
-    case DateExtractUnit::kYear:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::YEAR);
-      break;
-    case DateExtractUnit::kMonth:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::MONTH);
-      break;
-    case DateExtractUnit::kDay:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::DAY);
-      break;
-    case DateExtractUnit::kHour:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::HOUR);
-      break;
-    case DateExtractUnit::kMinute:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::MINUTE);
-      break;
-    case DateExtractUnit::kSecond:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::SECOND);
-      break;
-    default:
-      FATAL_ERROR("Unsupported DateExtractUnit in DateExtractOperation::getProto.");
-  }
-
-  return proto;
-}
-
-std::string DateExtractOperation::getName() const {
-  std::string name(kUnaryOperationNames[static_cast<std::size_t>(operation_id_)]);
-  name.push_back('(');
-  switch (unit_) {
-    case DateExtractUnit::kYear:
-      name.append("YEAR)");
-      break;
-    case DateExtractUnit::kMonth:
-      name.append("MONTH)");
-      break;
-    case DateExtractUnit::kDay:
-      name.append("DAY)");
-      break;
-    case DateExtractUnit::kHour:
-      name.append("HOUR)");
-      break;
-    case DateExtractUnit::kMinute:
-      name.append("MINUTE)");
-      break;
-    case DateExtractUnit::kSecond:
-      name.append("SECOND)");
-      break;
-    default:
-      name.append("UNKNOWN)");
-      break;
-  }
-  return name;
-}
-
-const Type* DateExtractOperation::pushDownTypeHint(const Type *type_hint) const {
-  if (type_hint == nullptr) {
-    return nullptr;
-  }
+};
 
-  if (type_hint->getTypeID() == kLong) {
-    switch (unit_) {
-      case DateExtractUnit::kYear:  // Fall through.
+struct DatetimeExtractFunctor : public UnaryFunctor<DatetimeType, IntType> {
+  template <typename DateExtractUnitT>
+  inline std::int64_t apply(const DatetimeLit &argument) const {
+    switch (DateExtractUnitT::value) {
+      case DateExtractUnit::kYear:
+        return argument.yearField();
       case DateExtractUnit::kMonth:
-        // There are two possibilities for the return type, based on whether we
-        // have Datetime or Date as the underlying date implementation.
-        return nullptr;
-      case DateExtractUnit::kDay:  // Fall through.
+        return argument.monthField();
+      case DateExtractUnit::kDay:
+        return argument.dayField();
       case DateExtractUnit::kHour:
+        return argument.hourField();
       case DateExtractUnit::kMinute:
+        return argument.minuteField();
       case DateExtractUnit::kSecond:
-        return &TypeFactory::GetType(kDatetime, type_hint->isNullable());
+        return argument.secondField();
       default:
-        return nullptr;
+        DLOG(FATAL) << "Unsupported DateExtractUnit in DatetimeExtractFunctor::apply";
+    }
+  }
+};
+
+const std::map<std::string, DateExtractUnit> DateExtractOperation::kNameToUnitMap = {
+    { "year",   DateExtractUnit::kYear },
+    { "month",  DateExtractUnit::kMonth },
+    { "day",    DateExtractUnit::kDay },
+    { "hour",   DateExtractUnit::kHour },
+    { "minute", DateExtractUnit::kMinute },
+    { "second", DateExtractUnit::kSecond }
+};
+
+UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperator(
+    const Type &type,
+    const std::vector<TypedValue> &static_arguments) const {
+  DCHECK_EQ(1u, static_arguments.size());
+
+  const DateExtractUnit unit = parseUnit(static_arguments.front());
+  const Type *result_type = getResultType(type, static_arguments);
+
+  if (type.getTypeID() == kDate) {
+    switch (unit) {
+      case DateExtractUnit::kYear:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DateExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>(
+                 type, *result_type);
+      case DateExtractUnit::kMonth:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DateExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>(
+                 type, *result_type);
+      case DateExtractUnit::kDay:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DateExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>(
+                 type, *result_type);
+      default:
+        LOG(FATAL) << "Unsupported DateExtractUnit for DateType in "
+                   << "DateExtractOperation::makeUncheckedUnaryOperator";
     }
   } else {
-    return nullptr;
-  }
-}
-
-TypedValue DateExtractOperation::applyToChecked(const TypedValue &argument,
-                                                const Type &argument_type) const {
-  if (((argument.getTypeID() != TypeID::kDatetime) ||
-       (argument_type.getTypeID() != TypeID::kDatetime)) &&
-      ((argument.getTypeID() != TypeID::kDate) ||
-       (argument_type.getTypeID() != TypeID::kDate))) {
-    LOG(FATAL) << "UnaryOperation " << getName() << " is only applicable to Type "
-               << kTypeNames[TypeID::kDatetime] << ", but applyToChecked() was "
-               << "called with 'argument' of Type " << kTypeNames[argument.getTypeID()]
-               << " and explicit 'argument_type' parameter of "
-               << argument_type.getName();
-  }
-
-  if (argument.isNull()) {
-    if (argument.getTypeID() == TypeID::kDatetime) {
-      return TypedValue(kLong);
-    } else {
-      // argument type is kDate.
-      DCHECK_EQ(TypeID::kDate, argument.getTypeID());
-      return TypedValue(kInt);
-    }
-  }
-
-  switch (unit_) {
-    case DateExtractUnit::kYear: {
-      if (argument.getTypeID() == TypeID::kDatetime) {
-        return TypedValue(argument.getLiteral<DatetimeLit>().yearField());
-      } else {
-        // argument type is kDate.
-        DCHECK_EQ(TypeID::kDate, argument.getTypeID());
-        return TypedValue(argument.getLiteral<DateLit>().yearField());
-      }
-    }
-    case DateExtractUnit::kMonth: {
-      if (argument.getTypeID() == TypeID::kDatetime) {
-        return TypedValue(argument.getLiteral<DatetimeLit>().monthField());
-      } else {
-        // argument type is kDate.
-        DCHECK_EQ(TypeID::kDate, argument.getTypeID());
-        return TypedValue(argument.getLiteral<DateLit>().monthField());
-      }
-    }
-    case DateExtractUnit::kDay:
-      return TypedValue(argument.getLiteral<DatetimeLit>().dayField());
-    case DateExtractUnit::kHour:
-      return TypedValue(argument.getLiteral<DatetimeLit>().hourField());
-    case DateExtractUnit::kMinute:
-      return TypedValue(argument.getLiteral<DatetimeLit>().minuteField());
-    case DateExtractUnit::kSecond:
-      return TypedValue(argument.getLiteral<DatetimeLit>().secondField());
-    default: {
-      LOG(FATAL) << "Unsupported DateExtractUnit in DateExtractOperation::applyToChecked().";
-    }
-  }
-}
-
-UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperatorForTypeHelper(const Type &type) const {
-  switch (unit_) {
-    case DateExtractUnit::kYear: {
-      if (type.getTypeID() == TypeID::kDatetime) {
-        if (type.isNullable()) {
-          return new DatetimeExtractUncheckedOperator<DateExtractUnit::kYear, true>();
-        } else {
-          return new DatetimeExtractUncheckedOperator<DateExtractUnit::kYear, false>();
-        }
-      } else {
-        DCHECK_EQ(TypeID::kDate, type.getTypeID());
-        // type is kDate.
-        if (type.isNullable()) {
-          return new DateExtractUncheckedOperator<DateExtractUnit::kYear, true>();
-        } else {
-          return new DateExtractUncheckedOperator<DateExtractUnit::kYear, false>();
-        }
-      }
-    }
-    case DateExtractUnit::kMonth: {
-      if (type.getTypeID() == TypeID::kDatetime) {
-        if (type.isNullable()) {
-          return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMonth, true>();
-        } else {
-          return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMonth, false>();
-        }
-      } else {
-        // type is kDate.
-        DCHECK_EQ(TypeID::kDate, type.getTypeID());
-        if (type.isNullable()) {
-          return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, true>();
-        } else {
-          return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, false>();
-        }
-      }
-    }
-    case DateExtractUnit::kDay:
-      if (type.isNullable()) {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kDay, true>();
-      } else {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kDay, false>();
-      }
-    case DateExtractUnit::kHour:
-      if (type.isNullable()) {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kHour, true>();
-      } else {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kHour, false>();
-      }
-    case DateExtractUnit::kMinute:
-      if (type.isNullable()) {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMinute, true>();
-      } else {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMinute, false>();
-      }
-    case DateExtractUnit::kSecond:
-      if (type.isNullable()) {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kSecond, true>();
-      } else {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kSecond, false>();
-      }
-    default:
-      FATAL_ERROR("Unsupported DateExtractUnit in DateExtractOperation::makeUncheckedUnaryOperatorForTypeHelper.");
-  }
-}
-
-const Type* DateExtractOperation::resultTypeForArgumentType(const Type &type) const {
-  if (canApplyToType(type)) {
-    if (type.getTypeID() == kDatetime) {
-      return &LongType::Instance(type.isNullable());
-    } else {
-      DCHECK_EQ(kDate, type.getTypeID());
-      return &IntType::Instance(type.isNullable());
+    switch (unit) {
+      case DateExtractUnit::kYear:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>(
+                 type, *result_type);
+      case DateExtractUnit::kMonth:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>(
+                 type, *result_type);
+      case DateExtractUnit::kDay:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>(
+                 type, *result_type);
+      case DateExtractUnit::kHour:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kHour>>(
+                 type, *result_type);
+      case DateExtractUnit::kMinute:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kMinute>>(
+                 type, *result_type);
+      case DateExtractUnit::kSecond:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kSecond>>(
+                 type, *result_type);
+      default:
+        LOG(FATAL) << "Unsupported DateExtractUnit for DatetimeType in "
+                   << "DateExtractOperation::makeUncheckedUnaryOperator";
     }
-  } else {
-    return nullptr;
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/DateExtractOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.hpp b/types/operations/unary_operations/DateExtractOperation.hpp
index f8c091b..577e924 100644
--- a/types/operations/unary_operations/DateExtractOperation.hpp
+++ b/types/operations/unary_operations/DateExtractOperation.hpp
@@ -23,109 +23,25 @@
 #include <cstdint>
 #include <string>
 
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-#include <utility>
-#include <vector>
-
-#include "storage/StorageBlockInfo.hpp"
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-#include "catalog/CatalogTypedefs.hpp"
+#include "types/IntType.hpp"
 #include "types/LongType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
-#include "types/operations/Operation.pb.h"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
 #include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
 
 namespace quickstep {
 
-class ColumnVector;
-class ValueAccessor;
-
-struct DatetimeLit;
-
-/** \addtogroup Types
- *  @{
- */
-
 enum class DateExtractUnit {
   kYear = 0,
   kMonth,
   kDay,
   kHour,
   kMinute,
-  kSecond
-};
-
-/**
- * @brief UncheckedUnaryOperator for Datetime Extract.
- */
-template <DateExtractUnit unit, bool argument_nullable>
-class DatetimeExtractUncheckedOperator : public UncheckedUnaryOperator {
- public:
-  DatetimeExtractUncheckedOperator()
-      : UncheckedUnaryOperator() {}
-
-  TypedValue applyToTypedValue(const TypedValue &argument) const override;
-
-  TypedValue applyToDataPtr(const void *argument) const override;
-
-  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override;
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
-                                     const attribute_id argument_attr_id) const override;
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-  ColumnVector* applyToValueAccessorForJoin(
-      ValueAccessor *accessor,
-      const bool use_left_relation,
-      const attribute_id argument_attr_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override;
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
- private:
-  inline std::int64_t dateExtract(const DatetimeLit &argument) const;
-
-  DISALLOW_COPY_AND_ASSIGN(DatetimeExtractUncheckedOperator);
-};
-
-/**
- * @brief UncheckedUnaryOperator for Date Extract.
- */
-template <DateExtractUnit unit, bool argument_nullable>
-class DateExtractUncheckedOperator : public UncheckedUnaryOperator {
- public:
-  DateExtractUncheckedOperator()
-      : UncheckedUnaryOperator() {}
-
-  TypedValue applyToTypedValue(const TypedValue &argument) const override;
-
-  TypedValue applyToDataPtr(const void *argument) const override;
-
-  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override;
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
-                                     const attribute_id argument_attr_id) const override;
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-  ColumnVector* applyToValueAccessorForJoin(
-      ValueAccessor *accessor,
-      const bool use_left_relation,
-      const attribute_id argument_attr_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override;
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
- private:
-  inline std::int32_t dateExtract(const DateLit &argument) const;
-
-  DISALLOW_COPY_AND_ASSIGN(DateExtractUncheckedOperator);
+  kSecond,
+  kInvalid
 };
 
 /**
@@ -133,55 +49,82 @@ class DateExtractUncheckedOperator : public UncheckedUnaryOperator {
  */
 class DateExtractOperation : public UnaryOperation {
  public:
-  /**
-   * @brief Get a reference to the singleton instance of this Operation for a
-   *        particular DateExtractUnit.
-   *
-   * @param unit The date unit to extract.
-   * @return A reference to the singleton instance of this Operation for the
-   *         specified DateExtractUnit.
-   **/
-  static const DateExtractOperation& Instance(const DateExtractUnit unit);
-
-  serialization::UnaryOperation getProto() const override;
-
-  std::string getName() const override;
-
-  bool canApplyToType(const Type &type) const override {
-    return type.getTypeID() == TypeID::kDatetime || type.getTypeID() == kDate;
-  }
-
-  const Type* resultTypeForArgumentType(const Type &type) const override;
+  DateExtractOperation() {}
 
-  const Type* fixedNullableResultType() const override {
-    return nullptr;
+  std::string getName() const override {
+    return "DateExtract";
   }
 
-  bool resultTypeIsPlausible(const Type &result_type) const override {
-    return result_type.getTypeID() == kLong || result_type.getTypeID() == kInt;
+  std::string getShortName() const override {
+    return "DateExtract";
   }
 
-  const Type* pushDownTypeHint(const Type *type_hint) const override;
-
-  TypedValue applyToChecked(const TypedValue &argument,
-                            const Type &argument_type) const override;
+  std::vector<OperationSignaturePtr> getSignatures() const override {
+    const std::vector<TypeID> unit_carrier = { kVarChar };
+    return {
+        OperationSignature::Create(getName(), {kDate}, unit_carrier),
+        OperationSignature::Create(getName(), {kDatetime}, unit_carrier)
+    };
+  }
 
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const override {
-    DCHECK(canApplyToType(type));
+  bool canApplyTo(const Type &type,
+                  const std::vector<TypedValue> &static_arguments,
+                  std::string *message) const override {
+    DCHECK(type.getTypeID() == kDate || type.getTypeID() == kDatetime);
+    DCHECK_EQ(1u, static_arguments.size());
+
+    const DateExtractUnit unit = parseUnit(static_arguments.front());
+    switch (unit) {
+      case DateExtractUnit::kYear:  // Fall through
+      case DateExtractUnit::kMonth:
+      case DateExtractUnit::kDay:
+        return true;
+      case DateExtractUnit::kHour:  // Fall through
+      case DateExtractUnit::kMinute:
+      case DateExtractUnit::kSecond:
+        if (type.getTypeID() == kDate) {
+          *message = "Invalid extraction unit for argument of DATE type";
+        } else {
+          return true;
+        }
+      default:
+        *message = "Invalid extraction unit for DateExtract";
+        return false;
+    }
+  }
 
-    return makeUncheckedUnaryOperatorForTypeHelper(type);
+  const Type* getResultType(
+      const Type &type,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(UnaryOperation::canApplyTo(type, static_arguments));
+    if (type.getTypeID() == kDatetime) {
+      return &LongType::Instance(type.isNullable());
+    } else {
+      DCHECK_EQ(kDate, type.getTypeID());
+      return &IntType::Instance(type.isNullable());
+    }
   }
 
- private:
-  explicit DateExtractOperation(const DateExtractUnit unit)
-      : UnaryOperation(UnaryOperationID::kDateExtract),
-        unit_(unit) {}
+  UncheckedUnaryOperator* makeUncheckedUnaryOperator(
+      const Type &type,
+      const std::vector<TypedValue> &static_arguments) const override;
 
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorForTypeHelper(const Type &type) const;
+ private:
+  static DateExtractUnit parseUnit(const TypedValue &unit_arg) {
+    DCHECK(unit_arg.getTypeID() == kVarChar);
+    const std::string unit_str =
+        ToLower(std::string(static_cast<const char*>(unit_arg.getOutOfLineData())));
+
+    auto it = kNameToUnitMap.find(unit_str);
+    if (it != kNameToUnitMap.end()) {
+      return it->second;
+    } else {
+      return DateExtractUnit::kInvalid;
+    }
+  }
 
-  const DateExtractUnit unit_;
+  static const std::map<std::string, DateExtractUnit> kNameToUnitMap;
 
- private:
   DISALLOW_COPY_AND_ASSIGN(DateExtractOperation);
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/NumericCastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/NumericCastOperation.hpp b/types/operations/unary_operations/NumericCastOperation.hpp
deleted file mode 100644
index 1c5e3d4..0000000
--- a/types/operations/unary_operations/NumericCastOperation.hpp
+++ /dev/null
@@ -1,313 +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_NUMERIC_CAST_OPERATION_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_
-
-#include <cstddef>
-#include <string>
-#include <utility>
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-#include <vector>
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-#include "catalog/CatalogTypedefs.hpp"
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
-#include "types/DoubleType.hpp"
-#include "types/FloatType.hpp"
-#include "types/IntType.hpp"
-#include "types/LongType.hpp"
-#include "types/Type.hpp"
-#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-#include "types/operations/Operation.pb.h"
-#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
-#include "utility/Macros.hpp"
-#include "utility/PtrMap.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-// TODO(quickstep-team): Support CAST on Datetime, YearMonthInterval, DatetimeInterval, VarChar, Char.
-//                       Currently we only need cast operations on numeric values.
-
-/**
- * @brief UncheckedUnaryOperator for CAST.
- */
-template <class SourceType, bool source_nullability, class TargetType, bool target_nullability>
-class UncheckedNumericCastOperator : public UncheckedUnaryOperator {
- public:
-  UncheckedNumericCastOperator()
-      : UncheckedUnaryOperator(),
-        target_type_(TargetType::Instance(target_nullability)) {
-  }
-
-  TypedValue applyToTypedValue(const TypedValue &argument) const override {
-    if (source_nullability && argument.isNull()) {
-      return TypedValue(TargetType::kStaticTypeID);
-    }
-
-    return TypedValue(static_cast<typename TargetType::cpptype>(
-        argument.getLiteral<typename SourceType::cpptype>()));
-  }
-
-  TypedValue applyToDataPtr(const void *argument) const override {
-    if (source_nullability && argument == nullptr) {
-      return TypedValue(TargetType::kStaticTypeID);
-    }
-
-    return TypedValue(
-        static_cast<const typename TargetType::cpptype>(
-            *static_cast<const typename SourceType::cpptype*>(argument)));
-  }
-
-  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override {
-    DCHECK(NativeColumnVector::UsableForType(target_type_));
-    DCHECK(argument.isNative());
-    const NativeColumnVector &native_argument = static_cast<const NativeColumnVector&>(argument);
-    NativeColumnVector *result = new NativeColumnVector(
-        target_type_,
-        native_argument.size());
-    for (std::size_t pos = 0;
-         pos < native_argument.size();
-         ++pos) {
-      const typename SourceType::cpptype *scalar_arg
-          = static_cast<const typename SourceType::cpptype*>(
-              native_argument.getUntypedValue<source_nullability>(pos));
-      if (source_nullability && (scalar_arg == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<typename TargetType::cpptype*>(result->getPtrForDirectWrite())
-            = static_cast<typename TargetType::cpptype>(*scalar_arg);
-      }
-    }
-    return result;
-  }
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
-                                     const attribute_id argument_attr_id) const override {
-    DCHECK(NativeColumnVector::UsableForType(target_type_));
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        accessor,
-        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      NativeColumnVector *result = new NativeColumnVector(
-          target_type_,
-          accessor->getNumTuples());
-      accessor->beginIteration();
-      while (accessor->next()) {
-        const typename SourceType::cpptype *scalar_arg
-            = static_cast<const typename SourceType::cpptype*>(
-                accessor->template getUntypedValue<source_nullability>(argument_attr_id));
-        if (source_nullability && (scalar_arg == nullptr)) {
-          result->appendNullValue();
-        } else {
-          *static_cast<typename TargetType::cpptype*>(result->getPtrForDirectWrite())
-              = static_cast<typename TargetType::cpptype>(*scalar_arg);
-        }
-      }
-      return result;
-    });
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-  ColumnVector* applyToValueAccessorForJoin(
-      ValueAccessor *accessor,
-      const bool use_left_relation,
-      const attribute_id argument_attr_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override {
-    DCHECK(NativeColumnVector::UsableForType(target_type_));
-    NativeColumnVector *result = new NativeColumnVector(target_type_,
-                                                        joined_tuple_ids.size());
-    InvokeOnValueAccessorNotAdapter(
-        accessor,
-        [&](auto *accessor) -> void {  // NOLINT(build/c++11)
-      for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
-        const typename SourceType::cpptype *scalar_arg
-            = static_cast<const typename SourceType::cpptype*>(
-                accessor->template getUntypedValueAtAbsolutePosition<source_nullability>(
-                    argument_attr_id,
-                    use_left_relation ? joined_pair.first : joined_pair.second));
-        if (source_nullability && (scalar_arg == nullptr)) {
-          result->appendNullValue();
-        } else {
-          *static_cast<typename TargetType::cpptype*>(result->getPtrForDirectWrite())
-              = static_cast<typename TargetType::cpptype>(*scalar_arg);
-        }
-      }
-    });
-    return result;
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
- private:
-  const Type &target_type_;
-
-  DISALLOW_COPY_AND_ASSIGN(UncheckedNumericCastOperator);
-};
-
-/**
- * @brief UnaryOperation for CAST.
- */
-class NumericCastOperation : public UnaryOperation {
- public:
-  serialization::UnaryOperation getProto() const override {
-    serialization::UnaryOperation proto;
-    proto.set_operation_id(serialization::UnaryOperation::CAST);
-    proto.MutableExtension(serialization::CastOperation::target_type)
-        ->CopyFrom(getTargetType().getProto());
-
-    return proto;
-  }
-
-  /**
-   * @brief Get a reference to the singleton instance of this Operation.
-   *
-   * @param target_type The target type to coerce input values to.
-   * @return A reference to the singleton instance of this Operation.
-   **/
-  static const NumericCastOperation& Instance(const Type &target_type) {
-    static PtrMap<const Type*, NumericCastOperation> instance_map;
-    PtrMap<const Type*, NumericCastOperation>::iterator instance_map_it =
-        instance_map.find(&target_type);
-    if (instance_map_it == instance_map.end()) {
-      instance_map_it = instance_map.insert(&target_type,
-                                            new NumericCastOperation(target_type)).first;
-    }
-    return *(instance_map_it->second);
-  }
-
-  /**
-   * @return The target type for coercion.
-   */
-  const Type& getTargetType() const {
-    return target_type_;
-  }
-
-  std::string getName() const override {
-    return std::string(kUnaryOperationNames[static_cast<std::size_t>(operation_id_)])
-        .append("(")
-        .append(target_type_.getName())
-        .append(")");
-  }
-
-  bool canApplyToType(const Type &type) const override {
-    return target_type_.isCoercibleFrom(type);
-  }
-
-  const Type* resultTypeForArgumentType(const Type &type) const override {
-    if (canApplyToType(type)) {
-      return &target_type_;
-    } else {
-      return nullptr;
-    }
-  }
-
-  const Type* fixedNullableResultType() const override {
-    return &target_type_.getNullableVersion();
-  }
-
-  bool resultTypeIsPlausible(const Type &result_type) const override {
-    return result_type.equals(target_type_)
-           || result_type.equals(target_type_.getNullableVersion());
-  }
-
-  const Type* pushDownTypeHint(const Type *type_hint) const override {
-    return &target_type_;
-  }
-
-  TypedValue applyToChecked(const TypedValue &argument,
-                            const Type &argument_type) const override {
-    return target_type_.coerceValue(argument, argument_type);
-  }
-
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const override {
-    switch (type.getTypeID()) {
-      case kInt:
-        return makeUncheckedUnaryOperatorHelperForSourceNullability<IntType>(type);
-      case kLong:
-        return makeUncheckedUnaryOperatorHelperForSourceNullability<LongType>(type);
-      case kFloat:
-        return makeUncheckedUnaryOperatorHelperForSourceNullability<FloatType>(type);
-      case kDouble:
-        return makeUncheckedUnaryOperatorHelperForSourceNullability<DoubleType>(type);
-      default:
-        FATAL_ERROR("Unhandled type " << kTypeNames[type.getTypeID()]);
-    }
-  }
-
- private:
-  explicit NumericCastOperation(const Type &target_type)
-      : UnaryOperation(UnaryOperationID::kCast),
-        target_type_(target_type) {}
-
-  template <class SourceType>
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorHelperForSourceNullability(const Type &type) const {
-    if (type.isNullable()) {
-      return makeUncheckedUnaryOperatorHelperForTargetType<SourceType, true>();
-    } else {
-      return makeUncheckedUnaryOperatorHelperForTargetType<SourceType, false>();
-    }
-  }
-
-  template <class SourceType, bool source_nullability>
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorHelperForTargetType() const {
-    switch (target_type_.getTypeID()) {
-      case kInt:
-        return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, IntType>();
-      case kLong:
-        return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, LongType>();
-      case kFloat:
-        return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, FloatType>();
-      case kDouble:
-        return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, DoubleType>();
-      default:
-        FATAL_ERROR("Unhandled type " << kTypeNames[target_type_.getTypeID()]);
-    }
-  }
-
-  template <class SourceType, bool source_nullability, class TargetType>
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorHelperForTargetNullability() const {
-    if (target_type_.isNullable()) {
-      return new UncheckedNumericCastOperator<SourceType, source_nullability, TargetType, true>();
-    } else {
-      return new UncheckedNumericCastOperator<SourceType, source_nullability, TargetType, false>();
-    }
-  }
-
-  const Type& target_type_;
-
-  DISALLOW_COPY_AND_ASSIGN(NumericCastOperation);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_


Mime
View raw message