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/03/14 14:55:25 UTC

[2/8] incubator-quickstep git commit: Updates

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/binary_operations/MultiplyBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/MultiplyBinaryOperation.cpp b/types/operations/binary_operations/MultiplyBinaryOperation.cpp
deleted file mode 100644
index a206364..0000000
--- a/types/operations/binary_operations/MultiplyBinaryOperation.cpp
+++ /dev/null
@@ -1,410 +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.
- **/
-
-#include "types/operations/binary_operations/MultiplyBinaryOperation.hpp"
-
-#include <string>
-#include <utility>
-
-#include "types/DateOperatorOverloads.hpp"
-#include "types/DatetimeIntervalType.hpp"
-#include "types/DoubleType.hpp"
-#include "types/FloatType.hpp"
-#include "types/IntType.hpp"
-#include "types/IntervalLit.hpp"
-#include "types/LongType.hpp"
-#include "types/Type.hpp"
-#include "types/TypeErrors.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/YearMonthIntervalType.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperators.hpp"
-#include "utility/EqualsAnyConstant.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-bool MultiplyBinaryOperation::canApplyToTypes(const Type &left, const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      return (right.getSuperTypeID() == Type::kNumeric ||
-              right.getTypeID() == kDatetimeInterval   ||
-              right.getTypeID() == kYearMonthInterval);
-    }
-    case kDatetimeInterval:
-    case kYearMonthInterval: {
-      return (right.getSuperTypeID() == Type::kNumeric);
-    }
-    default:
-      return false;
-  }
-}
-
-const Type* MultiplyBinaryOperation::resultTypeForArgumentTypes(const Type &left, const Type &right) const {
-  if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) {
-    return TypeFactory::GetUnifyingType(left, right);
-  } else if ((left.getSuperTypeID() == Type::kNumeric && right.getTypeID() == kDatetimeInterval) ||
-             (left.getTypeID() == kDatetimeInterval && right.getSuperTypeID() == Type::kNumeric)) {
-    return &(DatetimeIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else if ((left.getSuperTypeID() == Type::kNumeric && right.getTypeID() == kYearMonthInterval) ||
-             (left.getTypeID() == kYearMonthInterval && right.getSuperTypeID() == Type::kNumeric)) {
-    return &(YearMonthIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else {
-    return nullptr;
-  }
-}
-
-const Type* MultiplyBinaryOperation::resultTypeForPartialArgumentTypes(
-    const Type *left,
-    const Type *right) const {
-  if ((left == nullptr) && (right == nullptr)) {
-    return nullptr;
-  }
-
-  if ((left != nullptr) && (right != nullptr)) {
-    return resultTypeForArgumentTypes(*left, *right);
-  }
-
-  // Multiplication is commutative, so we just determine based on the known
-  // type, left or right.
-  const Type *known_type = (left != nullptr) ? left : right;
-  switch (known_type->getTypeID()) {
-    case kDatetimeInterval:
-      // DatetimeInterval can be multiplied against any numeric type, yielding
-      // DatetimeInterval.
-      return &TypeFactory::GetType(kDatetimeInterval, true);
-    case kYearMonthInterval:
-      // Same deal for YearMonthInterval.
-      return &TypeFactory::GetType(kYearMonthInterval, true);
-    default:
-      // Ambiguous or inapplicable. Note that we can't apply numeric precedence
-      // order for a Double argument, because the other argument could be a
-      // numeric type OR an interval type.
-      return nullptr;
-  }
-}
-
-bool MultiplyBinaryOperation::partialTypeSignatureIsPlausible(
-    const Type *result_type,
-    const Type *left_argument_type,
-    const Type *right_argument_type) const {
-  if ((left_argument_type == nullptr) && (right_argument_type == nullptr)) {
-    if (result_type == nullptr) {
-      return true;
-    } else if (!result_type->isNullable()) {
-      // Unknown arguments are assumed to be nullable, since they arise from
-      // untyped NULL literals in the parser. Therefore, a non-nullable result
-      // Type is not plausible with unknown arguments.
-      return false;
-    } else {
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          result_type->getTypeID(),
-          kInt, kLong, kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
-    }
-  }
-
-  if ((left_argument_type != nullptr) && (right_argument_type != nullptr)) {
-    const Type *actual_result_type = resultTypeForArgumentTypes(*left_argument_type,
-                                                                *right_argument_type);
-    if (actual_result_type == nullptr) {
-      // Both argument Types are known, but this operation is NOT applicable to
-      // them. No matter what the result_type is, the signature is not
-      // plausible.
-      return false;
-    } else if (result_type == nullptr) {
-      return true;
-    } else {
-      return result_type->equals(*actual_result_type);
-    }
-  }
-
-  // Multiplication is commutative, so we just determine based on the known
-  // type, left or right.
-  const Type *known_argument_type = (left_argument_type != nullptr)
-                                    ? left_argument_type
-                                    : right_argument_type;
-  if (result_type == nullptr) {
-    return QUICKSTEP_EQUALS_ANY_CONSTANT(
-        known_argument_type->getTypeID(),
-        kInt, kLong, kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
-  }
-
-  if (!result_type->isNullable()) {
-    // One of the arguments is unknown, but it is nevertheless assumed
-    // nullable, since unknown argument Types arise from untyped NULL literals
-    // in the parser. Therefore, a non-nullable result Type is not plausible
-    // with an unknown argument.
-    return false;
-  }
-
-  switch (result_type->getTypeID()) {
-    case kInt:
-      return (known_argument_type->getTypeID() == kInt);
-    case kLong:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kLong);
-    case kFloat:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kFloat);
-    case kDouble:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kLong, kFloat, kDouble);
-    case kDatetimeInterval:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kLong, kFloat, kDouble, kDatetimeInterval);
-    case kYearMonthInterval:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kLong, kFloat, kDouble, kYearMonthInterval);
-    default:
-      return false;
-  }
-}
-
-std::pair<const Type*, const Type*> MultiplyBinaryOperation::pushDownTypeHint(
-    const Type *result_type_hint) const {
-  if (result_type_hint == nullptr) {
-    return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-
-  switch (result_type_hint->getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-      return std::pair<const Type*, const Type*>(result_type_hint, result_type_hint);
-    case kDatetimeInterval:
-    case kYearMonthInterval:
-      // Ambiguous hint. One of the arguments should be the same as the
-      // '*type_hint', the other can be any numeric type, but either order is
-      // OK.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-    default:
-      // Inapplicable.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-}
-
-TypedValue MultiplyBinaryOperation::applyToChecked(const TypedValue &left,
-                                                   const Type &left_type,
-                                                   const TypedValue &right,
-                                                   const Type &right_type) const {
-  switch (left_type.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      if (right_type.getSuperTypeID() == Type::kNumeric) {
-        return applyToCheckedNumericHelper<MultiplyFunctor>(left, left_type,
-                                                            right, right_type);
-      } else if (right_type.getTypeID() == kDatetimeInterval) {
-        return applyToCheckedIntervalMultiplyNumericHelper<DatetimeIntervalType>(right, right_type,
-                                                                                 left, left_type);
-      } else if (right_type.getTypeID() == kYearMonthInterval) {
-        return applyToCheckedIntervalMultiplyNumericHelper<YearMonthIntervalType>(right, right_type,
-                                                                                  left, left_type);
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      if (right_type.getSuperTypeID() == Type::kNumeric) {
-        return applyToCheckedIntervalMultiplyNumericHelper<DatetimeIntervalType>(left, left_type,
-                                                                                 right, right_type);
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      if (right_type.getSuperTypeID() == Type::kNumeric) {
-        return applyToCheckedIntervalMultiplyNumericHelper<YearMonthIntervalType>(left, left_type,
-                                                                                  right, right_type);
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
-             << left_type.getName() << " and " << right_type.getName();
-}
-
-UncheckedBinaryOperator* MultiplyBinaryOperation::makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                                                      const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator>(left, right);
-      } else if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 IntType::cpptype, DatetimeIntervalLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 YearMonthIntervalType,
-                                                 IntType::cpptype, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kLong: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator>(left, right);
-      } else if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 LongType::cpptype, DatetimeIntervalLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 YearMonthIntervalType,
-                                                 LongType::cpptype, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kFloat: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator>(left, right);
-      } else if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 FloatType::cpptype, DatetimeIntervalLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 YearMonthIntervalType,
-                                                 FloatType::cpptype, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kDouble: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator>(left, right);
-      } else if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 DoubleType::cpptype, DatetimeIntervalLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 YearMonthIntervalType,
-                                                 DoubleType::cpptype, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      switch (right.getTypeID()) {
-        case kInt: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, IntType::cpptype>(left, right);
-        }
-        case kLong: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, LongType::cpptype>(left, right);
-        }
-        case kFloat: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, FloatType::cpptype>(left, right);
-        }
-        case kDouble: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, DoubleType::cpptype>(left, right);
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      switch (right.getTypeID()) {
-        case kInt: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, IntType::cpptype>(left, right);
-        }
-        case kLong: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, LongType::cpptype>(left, right);
-        }
-        case kFloat: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, FloatType::cpptype>(left, right);
-        }
-        case kDouble: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, DoubleType::cpptype>(left, right);
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
-}
-
-template <typename IntervalType>
-TypedValue MultiplyBinaryOperation::applyToCheckedIntervalMultiplyNumericHelper(
-    const TypedValue &left,
-    const Type &left_type,
-    const TypedValue &right,
-    const Type &right_type) const {
-  DCHECK(IntervalType::kStaticTypeID == kDatetimeInterval ||
-         IntervalType::kStaticTypeID == kYearMonthInterval);
-  DCHECK(IntervalType::kStaticTypeID == left_type.getTypeID());
-  DCHECK_EQ(Type::kNumeric, right_type.getSuperTypeID());
-
-  if (left.isNull() || right.isNull()) {
-    return TypedValue(IntervalType::kStaticTypeID);
-  }
-
-  switch (right_type.getTypeID()) {
-    case kInt: {
-      return TypedValue(left.getLiteral<typename IntervalType::cpptype>() * right.getLiteral<IntType::cpptype>());
-    }
-    case kLong: {
-      return TypedValue(left.getLiteral<typename IntervalType::cpptype>() * right.getLiteral<LongType::cpptype>());
-    }
-    case kFloat: {
-      return TypedValue(left.getLiteral<typename IntervalType::cpptype>() * right.getLiteral<FloatType::cpptype>());
-    }
-    case kDouble: {
-      return TypedValue(left.getLiteral<typename IntervalType::cpptype>() * right.getLiteral<DoubleType::cpptype>());
-    }
-    default: {
-      LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
-                 << left_type.getName() << " and " << right_type.getName();
-    }
-  }
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/binary_operations/MultiplyBinaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/MultiplyBinaryOperation.hpp b/types/operations/binary_operations/MultiplyBinaryOperation.hpp
deleted file mode 100644
index 6edc999..0000000
--- a/types/operations/binary_operations/MultiplyBinaryOperation.hpp
+++ /dev/null
@@ -1,98 +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_BINARY_OPERATIONS_MULTIPLY_BINARY_OPERATION_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_MULTIPLY_BINARY_OPERATION_HPP_
-
-#include <utility>
-
-#include "types/TypedValue.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-class Type;
-class UncheckedBinaryOperator;
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief The BinaryOperation for multiplication.
- **/
-class MultiplyBinaryOperation : public ArithmeticBinaryOperation {
- public:
-  /**
-   * @brief Get a reference to the singleton instance of this Operation.
-   *
-   * @return A reference to the singleton instance of this Operation.
-   **/
-  static const MultiplyBinaryOperation& Instance() {
-    static MultiplyBinaryOperation instance;
-    return instance;
-  }
-
-  bool canApplyToTypes(const Type &left,
-                       const Type &right) const override;
-
-  const Type* resultTypeForArgumentTypes(const Type &left,
-                                         const Type &right) const override;
-
-  const Type* resultTypeForPartialArgumentTypes(const Type *left,
-                                                const Type *right) const override;
-
-  bool partialTypeSignatureIsPlausible(const Type *result_type,
-                                       const Type *left_argument_type,
-                                       const Type *right_argument_type) const override;
-
-  std::pair<const Type*, const Type*> pushDownTypeHint(
-      const Type *result_type_hint) const override;
-
-  TypedValue applyToChecked(const TypedValue &left,
-                            const Type &left_type,
-                            const TypedValue &right,
-                            const Type &right_type) const override;
-
-  UncheckedBinaryOperator* makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                               const Type &right) const override;
-
- private:
-  MultiplyBinaryOperation()
-      : ArithmeticBinaryOperation(BinaryOperationID::kMultiply) {
-  }
-
-  // NOTE(zuyu): left is an Interval TypedValue, either DatetimeInterval
-  // or YearMonthInterval, while right is a Numeric.
-  template <typename IntervalType>
-  TypedValue applyToCheckedIntervalMultiplyNumericHelper(const TypedValue &left,
-                                                         const Type &left_type,
-                                                         const TypedValue &right,
-                                                         const Type &right_type) const;
-
-  DISALLOW_COPY_AND_ASSIGN(MultiplyBinaryOperation);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_MULTIPLY_BINARY_OPERATION_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/binary_operations/SubtractBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/SubtractBinaryOperation.cpp b/types/operations/binary_operations/SubtractBinaryOperation.cpp
deleted file mode 100644
index 53e4266..0000000
--- a/types/operations/binary_operations/SubtractBinaryOperation.cpp
+++ /dev/null
@@ -1,459 +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.
- **/
-
-#include "types/operations/binary_operations/SubtractBinaryOperation.hpp"
-
-#include <string>
-#include <utility>
-
-#include "types/DateOperatorOverloads.hpp"
-#include "types/DateType.hpp"
-#include "types/DatetimeIntervalType.hpp"
-#include "types/DatetimeLit.hpp"
-#include "types/DatetimeType.hpp"
-#include "types/IntervalLit.hpp"
-#include "types/Type.hpp"
-#include "types/TypeErrors.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/YearMonthIntervalType.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperators.hpp"
-#include "utility/EqualsAnyConstant.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-bool SubtractBinaryOperation::canApplyToTypes(const Type &left, const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      return (right.getSuperTypeID() == Type::kNumeric);
-    }
-    case kDate: {
-      return (right.getTypeID() == kYearMonthInterval);
-    }
-    case kDatetime: {
-      return (right.getTypeID() == kDatetime         ||
-              right.getTypeID() == kDatetimeInterval ||
-              right.getTypeID() == kYearMonthInterval);
-    }
-    case kDatetimeInterval: {
-      return (right.getTypeID() == kDatetimeInterval);
-    }
-    case kYearMonthInterval: {
-      return (right.getTypeID() == kYearMonthInterval ||
-              right.getTypeID() == kDate);
-    }
-    default:
-      return false;
-  }
-}
-
-const Type* SubtractBinaryOperation::resultTypeForArgumentTypes(const Type &left, const Type &right) const {
-  if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) {
-    return TypeFactory::GetUnifyingType(left, right);
-  } else if ((left.getTypeID() == kDate && right.getTypeID() == kYearMonthInterval)) {
-    // For DATE type, only one possibility: DATE - YEAR-MONTH-INTERVAL.
-    return &(DateType::Instance(left.isNullable() || right.isNullable()));
-  } else if ((left.getTypeID() == kDatetime && right.getTypeID() == kDatetime) ||
-             (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetimeInterval)) {
-    // NOTE(zuyu): we set the result type of the Subtract
-    // between two Datetimes as DatetimeInterval, instead of YearMonthInterval.
-    return &(DatetimeIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else if (left.getTypeID() == kDatetime && right.getTypeID() == kDatetimeInterval) {
-    return &(DatetimeType::Instance(left.isNullable() || right.isNullable()));
-  } else if (left.getTypeID() == kDatetime && right.getTypeID() == kYearMonthInterval) {
-    return &(DatetimeType::Instance(left.isNullable() || right.isNullable()));
-  } else if (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kYearMonthInterval) {
-    return &(YearMonthIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else {
-    return nullptr;
-  }
-}
-
-const Type* SubtractBinaryOperation::resultTypeForPartialArgumentTypes(
-    const Type *left,
-    const Type *right) const {
-  if (left == nullptr) {
-    if (right == nullptr) {
-      return nullptr;
-    } else {
-      switch (right->getTypeID()) {
-        case kDouble:
-          // Double has highest precedence of numeric types.
-          return &TypeFactory::GetType(kDouble, true);
-        case kDatetime:
-          // If the subtrahend is Datetime, then the only allowed minuend is
-          // another Datetime, and the result is an interval.
-          return &TypeFactory::GetType(kDatetimeInterval, true);
-        default:
-          // Ambiguous or inapplicable.
-          return nullptr;
-      }
-    }
-  } else {
-    if (right == nullptr) {
-      switch (left->getTypeID()) {
-        case kDouble:
-          // Double has highest precedence of numeric types.
-          return &TypeFactory::GetType(kDouble, true);
-        case kDate:
-          // If left is a Date, right must be a YearMonthInterval and the result
-          // must be a Date.
-          return &TypeFactory::GetType(kDate, true);
-        case kDatetimeInterval:
-          // If minuend is a DatetimeInterval, the subtrahend and result must
-          // also be DatetimeInterval.
-          return &TypeFactory::GetType(kDatetimeInterval, true);
-        case kYearMonthInterval:
-          // Similarly, if minuend is a YearMonthInterval, the subtrahend and
-          // result must also be YearMonthInterval.
-          return &TypeFactory::GetType(kYearMonthInterval, true);
-        default:
-          // Ambiguous or inapplicable.
-          return nullptr;
-      }
-    } else {
-      return resultTypeForArgumentTypes(*left, *right);
-    }
-  }
-}
-
-bool SubtractBinaryOperation::partialTypeSignatureIsPlausible(
-    const Type *result_type,
-    const Type *left_argument_type,
-    const Type *right_argument_type) const {
-  // Early check: if either argument type is nullable or unknown, result type
-  // must also be nullable.
-  if ((left_argument_type == nullptr)
-      || left_argument_type->isNullable()
-      || (right_argument_type == nullptr)
-      || right_argument_type->isNullable()) {
-    if ((result_type != nullptr) && (!result_type->isNullable())) {
-      return false;
-    }
-  }
-
-  if (left_argument_type == nullptr) {
-    if (right_argument_type == nullptr) {
-      if (result_type == nullptr) {
-        // All types unknown.
-        return true;
-      } else {
-        // Only result type is known, just check that it is one of the types
-        // that can possibly be returned.
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(result_type->getTypeID(),
-                                             kInt,
-                                             kLong,
-                                             kFloat,
-                                             kDouble,
-                                             kDate,
-                                             kDatetime,
-                                             kDatetimeInterval,
-                                             kYearMonthInterval);
-      }
-    }
-
-    if (result_type == nullptr) {
-      // Right (minuend) argument type is known, left (subtrahend) argument and
-      // result types are unknown. Just check that right (minuend) type can be
-      // subtracted.
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(right_argument_type->getTypeID(),
-                                           kInt,
-                                           kLong,
-                                           kFloat,
-                                           kDouble,
-                                           kDatetime,
-                                           kDatetimeInterval,
-                                           kYearMonthInterval);
-    }
-
-    // Return type and right (minuend) argument type are known, left
-    // (subtrahend) argument type is unknown. Check that result and subtrahend
-    // are compatible.
-    switch (right_argument_type->getTypeID()) {
-      case kInt:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kInt, kLong, kFloat, kDouble);
-      case kLong:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kLong, kDouble);
-      case kFloat:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kFloat, kDouble);
-      case kDouble:
-        return (result_type->getTypeID() == kDouble);
-      case kDate:
-        return (result_type->getTypeID() == kDate);
-      case kDatetime:
-        return (result_type->getTypeID() == kDatetimeInterval);
-      case kDatetimeInterval:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kDatetime, kDatetimeInterval);
-      case kYearMonthInterval:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kDate, kDatetime, kYearMonthInterval);
-      default:
-        return false;
-    }
-  } else {  // left_argument_type != nullptr
-    if (right_argument_type == nullptr) {
-      if (result_type == nullptr) {
-        // Left (subtrahend) argument type is known, right (minuend) argument
-        // type and result type are unknown. Just check that the left
-        // (subtrahend) type can be subtracted from.
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(left_argument_type->getTypeID(),
-                                             kInt,
-                                             kLong,
-                                             kFloat,
-                                             kDouble,
-                                             kDate,
-                                             kDatetime,
-                                             kDatetimeInterval,
-                                             kYearMonthInterval);
-      }
-
-      // Result type and left (subtrahend) argument type are known, but right
-      // (minuend) argument type is unknown. Check that result and minuend are
-      // compatible.
-      switch (left_argument_type->getTypeID()) {
-        case kInt:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kInt, kLong, kFloat, kDouble);
-        case kLong:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kLong, kDouble);
-        case kFloat:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kFloat, kDouble);
-        case kDouble:
-          return (result_type->getTypeID() == kDouble);
-        case kDate:
-          return (result_type->getTypeID() == kDate);
-        case kDatetime:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kDatetime, kDatetimeInterval);
-        case kDatetimeInterval:
-          return (result_type->getTypeID() == kDatetimeInterval);
-        case kYearMonthInterval:
-          return (result_type->getTypeID() == kYearMonthInterval);
-        default:
-          return false;
-      }
-    }
-
-    // Left and right (subtrahend and minuend) argument types are both known.
-    const Type *actual_result_type = resultTypeForArgumentTypes(*left_argument_type,
-                                                                *right_argument_type);
-    if (actual_result_type == nullptr) {
-      // Both argument Types are known, but this operation is NOT applicable to
-      // them. No matter what the result_type is, the signature is not
-      // plausible.
-      return false;
-    } else if (result_type == nullptr) {
-      return true;
-    } else {
-      // Check if result type matches.
-      return result_type->equals(*actual_result_type);
-    }
-  }
-}
-
-std::pair<const Type*, const Type*> SubtractBinaryOperation::pushDownTypeHint(
-    const Type *result_type_hint) const {
-  if (result_type_hint == nullptr) {
-    return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-
-  switch (result_type_hint->getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-    case kYearMonthInterval:
-      return std::pair<const Type*, const Type*>(result_type_hint, result_type_hint);
-    case kDate:
-      // Left should be a Date, right should be YearMonthInterval.
-      return std::pair<const Type *, const Type *>(
-          result_type_hint, &TypeFactory::GetType(kYearMonthInterval, true));
-    case kDatetime:
-      // Left should be a Datetime, right may be either interval type.
-      return std::pair<const Type*, const Type*>(result_type_hint, nullptr);
-    case kDatetimeInterval:
-      // Ambiguous: could be subtracting two Datetimes or two DatetimeIntervals.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-    default:
-      // Inapplicable.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-}
-
-TypedValue SubtractBinaryOperation::applyToChecked(const TypedValue &left,
-                                                   const Type &left_type,
-                                                   const TypedValue &right,
-                                                   const Type &right_type) const {
-  switch (left_type.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      if (right_type.getSuperTypeID() == Type::kNumeric) {
-        return applyToCheckedNumericHelper<SubtractFunctor>(left, left_type,
-                                                            right, right_type);
-      }
-      break;
-    }
-    case kDate: {
-      if (right_type.getTypeID() == kYearMonthInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDate);
-        }
-
-        return TypedValue(left.getLiteral<DateLit>() - right.getLiteral<YearMonthIntervalLit>());
-      }
-      break;
-    }
-    case kDatetime: {
-      if (right_type.getTypeID() == kDatetime) {
-        // NOTE(zuyu): The result type of the Subtract between two Datetimes is DatetimeInterval,
-        // instead of YearMonthInterval.
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetimeInterval);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeLit>() - right.getLiteral<DatetimeLit>());
-      } else if (right_type.getTypeID() == kDatetimeInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetime);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeLit>() - right.getLiteral<DatetimeIntervalLit>());
-      } else if (right_type.getTypeID() == kYearMonthInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetime);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeLit>() - right.getLiteral<YearMonthIntervalLit>());
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      if (right_type.getTypeID() == kDatetimeInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetimeInterval);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeIntervalLit>() - right.getLiteral<DatetimeIntervalLit>());
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      if (right_type.getTypeID() == kYearMonthInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kYearMonthInterval);
-        }
-
-        return TypedValue(left.getLiteral<YearMonthIntervalLit>() - right.getLiteral<YearMonthIntervalLit>());
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
-             << left_type.getName() << " and " << right_type.getName();
-}
-
-UncheckedBinaryOperator* SubtractBinaryOperation::makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                                                      const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator>(left, right);
-      }
-      break;
-    }
-    case kDate: {
-      if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<
-            SubtractArithmeticUncheckedBinaryOperator,
-            DateType,
-            DateLit,
-            YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kDatetime: {
-      if (right.getTypeID() == kDatetime) {
-        // NOTE(zuyu): The result type of the Subtract between two Datetimes is DatetimeInterval,
-        // instead of YearMonthInterval.
-        return makeDateBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 DatetimeLit, DatetimeLit>(left, right);
-      } else if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator,
-                                                 DatetimeType,
-                                                 DatetimeLit, DatetimeIntervalLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator,
-                                                 DatetimeType,
-                                                 DatetimeLit, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 DatetimeIntervalLit, DatetimeIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator,
-                                                 YearMonthIntervalType,
-                                                 YearMonthIntervalLit, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/binary_operations/SubtractBinaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/SubtractBinaryOperation.hpp b/types/operations/binary_operations/SubtractBinaryOperation.hpp
deleted file mode 100644
index 8e54362..0000000
--- a/types/operations/binary_operations/SubtractBinaryOperation.hpp
+++ /dev/null
@@ -1,93 +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_BINARY_OPERATIONS_SUBTRACT_BINARY_OPERATION_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_SUBTRACT_BINARY_OPERATION_HPP_
-
-#include <utility>
-
-#include "types/TypedValue.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-class Type;
-class UncheckedBinaryOperator;
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief The BinaryOperation for subtraction.
- *
- * @note SubtractBinaryOperation is not commutative: the left argument is the
- *       minuend and the right argument is the subtrahend.
- **/
-class SubtractBinaryOperation : public ArithmeticBinaryOperation {
- public:
-  /**
-   * @brief Get a reference to the singleton instance of this Operation.
-   *
-   * @return A reference to the singleton instance of this Operation.
-   **/
-  static const SubtractBinaryOperation& Instance() {
-    static SubtractBinaryOperation instance;
-    return instance;
-  }
-
-  bool canApplyToTypes(const Type &left,
-                       const Type &right) const override;
-
-  const Type* resultTypeForArgumentTypes(const Type &left,
-                                         const Type &right) const override;
-
-  const Type* resultTypeForPartialArgumentTypes(const Type *left,
-                                                const Type *right) const override;
-
-  bool partialTypeSignatureIsPlausible(const Type *result_type,
-                                       const Type *left_argument_type,
-                                       const Type *right_argument_type) const override;
-
-  std::pair<const Type*, const Type*> pushDownTypeHint(
-      const Type *result_type_hint) const override;
-
-  TypedValue applyToChecked(const TypedValue &left,
-                            const Type &left_type,
-                            const TypedValue &right,
-                            const Type &right_type) const override;
-
-  UncheckedBinaryOperator *makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                               const Type &right) const override;
-
- private:
-  SubtractBinaryOperation()
-      : ArithmeticBinaryOperation(BinaryOperationID::kSubtract) {
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(SubtractBinaryOperation);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_SUBTRACT_BINARY_OPERATION_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/ArithmeticUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/ArithmeticUnaryOperations.hpp b/types/operations/unary_operations/ArithmeticUnaryOperations.hpp
index 089b5a1..4c212c0 100644
--- a/types/operations/unary_operations/ArithmeticUnaryOperations.hpp
+++ b/types/operations/unary_operations/ArithmeticUnaryOperations.hpp
@@ -28,9 +28,8 @@
 #include "types/IntType.hpp"
 #include "types/LongType.hpp"
 #include "types/YearMonthIntervalType.hpp"
-#include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "types/operations/OperationUtil.hpp"
 #include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
-#include "utility/Macros.hpp"
 
 namespace quickstep {
 
@@ -44,19 +43,35 @@ struct NegateFunctor : public UnaryFunctor<ArgumentT, ResultT> {
       const typename ArgumentT::cpptype &argument) const {
     return -argument;
   }
-  inline std::string getName() const {
-    return "Negate";
+  inline static std::string GetName() {
+    return "-";
   }
 };
 
-using ArithmeticUnaryFunctorPack = UnaryFunctorPack<
+template <typename ArgumentT>
+struct SgnFunctor : public UnaryFunctor<ArgumentT, IntType> {
+  inline int apply(const typename ArgumentT::cpptype &argument) const {
+    return (argument > 0) - (argument < 0);
+  }
+  inline static std::string GetName() {
+    return "Sgn";
+  }
+};
+
+using ArithmeticUnaryFunctorPack = FunctorPack<
 // negate
   NegateFunctor<IntType, IntType>,
   NegateFunctor<LongType, LongType>,
   NegateFunctor<FloatType, FloatType>,
   NegateFunctor<DoubleType, DoubleType>,
   NegateFunctor<DatetimeIntervalType, DatetimeIntervalType>,
-  NegateFunctor<YearMonthIntervalType, YearMonthIntervalType>
+  NegateFunctor<YearMonthIntervalType, YearMonthIntervalType>,
+
+// sgn (Sign of a numeric value)
+  SgnFunctor<IntType>,
+  SgnFunctor<LongType>,
+  SgnFunctor<FloatType>,
+  SgnFunctor<DoubleType>
 >;
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/AsciiStringUnaryOperations.hpp b/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
new file mode 100644
index 0000000..8fb2b8f
--- /dev/null
+++ b/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
@@ -0,0 +1,122 @@
+/**
+ * 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_ASCII_STRING_UNARY_OPERATIONS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_UNARY_OPERATIONS_HPP_
+
+#include <cctype>
+#include <cstring>
+#include <string>
+
+#include "types/CharType.hpp"
+#include "types/IntType.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/VarCharType.hpp"
+#include "types/operations/OperationUtil.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/port/strnlen.hpp"
+#include "utility/TemplateUtil.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename ArgumentT>
+struct AsciiStringLengthFunctor : public UnaryFunctor<ArgumentT, IntType> {
+  explicit AsciiStringLengthFunctor(const ArgumentT &argument_type)
+      : max_string_length_(argument_type.getStringLength()) {}
+  inline int apply(const void *argument) const {
+    return strnlen(static_cast<const char*>(argument), max_string_length_);
+  }
+  inline int apply(const TypedValue &argument) const {
+    DCHECK(argument.getTypeID() == kVarChar);
+    return std::strlen(static_cast<const char*>(argument.getOutOfLineData()));
+  }
+  inline static std::string GetName() {
+    return "length";
+  }
+  const std::size_t max_string_length_;
+};
+
+template <typename ArgumentT, int transform(int), typename FunctorNameT>
+struct AsciiStringTranformFunctor : public UnaryFunctor<ArgumentT, ArgumentT> {
+  explicit AsciiStringTranformFunctor(const ArgumentT &argument_type)
+      : max_string_length_(argument_type.getStringLength()) {}
+  inline void apply(const void *argument, void *result) const {
+    DCHECK(ArgumentT::kStaticTypeID == kChar);
+    const char *argument_str = static_cast<const char*>(argument);
+    char *result_str = static_cast<char*>(result);
+    for (std::size_t i = 0; i < max_string_length_; ++i) {
+      if ((result_str[i] = transform(argument_str[i])) == 0) {
+        break;
+      }
+    }
+  }
+  inline TypedValue apply(const TypedValue &argument) const {
+    DCHECK(argument.getTypeID() == kVarChar);
+    const char *argument_str = static_cast<const char*>(argument.getOutOfLineData());
+    const std::size_t length = argument.getDataSize();
+    char *buf = static_cast<char*>(std::malloc(length));
+
+    for (std::size_t i = 0; i < length; ++i) {
+      buf[i] = transform(argument_str[i]);
+    }
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, length);
+  }
+  inline static std::string GetName() {
+    return FunctorNameT::ToString();
+  }
+  inline static const Type* GetResultType(const Type &argument_type) {
+    DCHECK(argument_type.getTypeID() == ArgumentT::kStaticTypeID);
+    return &argument_type;
+  }
+  const std::size_t max_string_length_;
+};
+
+template <typename ArgumentT>
+using AsciiStringToLowerCaseFunctor =
+    AsciiStringTranformFunctor<ArgumentT, std::tolower,
+                               StringLiteral<'t', 'o', 'l', 'o', 'w', 'e', 'r'>>;
+
+template <typename ArgumentT>
+using AsciiStringToUpperCaseFunctor =
+    AsciiStringTranformFunctor<ArgumentT, std::toupper,
+                               StringLiteral<'t', 'o', 'u', 'p', 'p', 'e', 'r'>>;
+
+using AsciiStringUnaryFunctorPack = FunctorPack<
+// length
+    AsciiStringLengthFunctor<CharType>,
+    AsciiStringLengthFunctor<VarCharType>,
+// tolower
+    AsciiStringToLowerCaseFunctor<CharType>,
+    AsciiStringToLowerCaseFunctor<VarCharType>,
+// toupper
+    AsciiStringToUpperCaseFunctor<CharType>,
+    AsciiStringToUpperCaseFunctor<VarCharType>
+>;
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_UNARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt
index fca7070..0f5ea60 100644
--- a/types/operations/unary_operations/CMakeLists.txt
+++ b/types/operations/unary_operations/CMakeLists.txt
@@ -19,6 +19,9 @@
 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)
@@ -30,9 +33,6 @@ 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_UnaryOperationWrapper
             ../../../empty_src.cpp
             UnaryOperationWrapper.hpp)
@@ -45,54 +45,55 @@ target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnary
                       quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
-                      quickstep_types_Type
-                      quickstep_types_TypeErrors
-                      quickstep_types_TypeID
-                      quickstep_types_TypedValue
                       quickstep_types_YearMonthIntervalType
-                      quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_utility_EqualsAnyConstant
-                      quickstep_utility_Macros)
+                      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_VarType
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper)
 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_TemplateUtil)
 target_link_libraries(quickstep_types_operations_unaryoperations_CastOperation
                       glog
-                      quickstep_catalog_CatalogTypedefs
-                      quickstep_storage_ValueAccessor
-                      quickstep_storage_ValueAccessorUtil
+                      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_utility_Macros)
+                      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_StorageBlockInfo
-                      quickstep_storage_ValueAccessor
-                      quickstep_storage_ValueAccessorUtil
+                      quickstep_types_DateType
                       quickstep_types_DatetimeLit
+                      quickstep_types_DatetimeType
                       quickstep_types_IntType
                       quickstep_types_LongType
                       quickstep_types_Type
-                      quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
-                      quickstep_types_containers_ColumnVector
-                      quickstep_types_operations_Operation_proto
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_utility_Macros)
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
 target_link_libraries(quickstep_types_operations_unaryoperations_SubstringOperation
                       quickstep_catalog_CatalogTypedefs
                       quickstep_storage_ValueAccessor
@@ -119,48 +120,31 @@ 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_UnaryOperationFactory
-                      glog
-                      quickstep_types_operations_OperationSignature
-                      quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
-                      quickstep_types_operations_unaryoperations_CMathUnaryOperations
-                      quickstep_types_operations_unaryoperations_CastOperation
-                      quickstep_types_operations_unaryoperations_DateExtractOperation
-                      quickstep_types_operations_unaryoperations_SubstringOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
-                      quickstep_utility_HashPair
-                      quickstep_utility_Macros
-                      quickstep_utility_StringUtil)
 target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationWrapper
                       glog
                       quickstep_catalog_CatalogTypedefs
                       quickstep_storage_ValueAccessor
                       quickstep_storage_ValueAccessorUtil
-                      quickstep_types_CharType
-                      quickstep_types_IntType
-                      quickstep_types_LongType
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
-                      quickstep_types_VarCharType
                       quickstep_types_containers_ColumnVector
-                      quickstep_types_operations_Operation
                       quickstep_types_operations_OperationSignature
-                      quickstep_types_operations_Operation_proto
+                      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_AsciiStringUnaryOperations
                       quickstep_types_operations_unaryoperations_CMathUnaryOperations
                       quickstep_types_operations_unaryoperations_CastOperation
                       quickstep_types_operations_unaryoperations_DateExtractOperation
                       quickstep_types_operations_unaryoperations_SubstringOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationFactory
                       quickstep_types_operations_unaryoperations_UnaryOperationWrapper)
 
 # Tests:
@@ -189,7 +173,6 @@ target_link_libraries(UnaryOperation_tests
                       quickstep_types_operations_unaryoperations_CastOperation
                       quickstep_types_operations_unaryoperations_DateExtractOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationFactory
                       quickstep_utility_EqualsAnyConstant
                       quickstep_utility_Macros)
 add_test(UnaryOperation_tests UnaryOperation_tests)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/CMathUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMathUnaryOperations.hpp b/types/operations/unary_operations/CMathUnaryOperations.hpp
index 7d1625b..43f771e 100644
--- a/types/operations/unary_operations/CMathUnaryOperations.hpp
+++ b/types/operations/unary_operations/CMathUnaryOperations.hpp
@@ -27,6 +27,7 @@
 #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/TemplateUtil.hpp"
 
@@ -45,7 +46,7 @@ struct CMathUnaryFunctorWrapper {
         const typename ArgumentT::cpptype &argument) const {
       return f(argument);
     }
-    inline std::string getName() const {
+    inline static std::string GetName() {
       return FunctorNameT::ToString();
     }
   };
@@ -59,7 +60,7 @@ template <typename ArgumentT, typename ReturnT,
 using CMathUnaryFunctor =
     typename CMathUnaryFunctorWrapper<ArgumentT, ReturnT, f, FunctorNameT>::type;
 
-using CMathUnaryFunctorPack = UnaryFunctorPack<
+using CMathUnaryFunctorPack = FunctorPack<
 // abs
     CMathUnaryFunctor<IntType, IntType,
                       std::abs, StringLiteral<'a','b','s'>>,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/CastOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.cpp b/types/operations/unary_operations/CastOperation.cpp
index ef5b8f8..b240b23 100644
--- a/types/operations/unary_operations/CastOperation.cpp
+++ b/types/operations/unary_operations/CastOperation.cpp
@@ -53,26 +53,28 @@ struct NumericCastToNumericFunctor
 };
 
 template <typename ArgumentT, typename ResultT>
-class NumericCastToAsciiStringFunctor : public UnaryFunctor<ArgumentT, ResultT> {
+class CastToAsciiStringFunctor : public UnaryFunctor<ArgumentT, ResultT> {
  public:
-  explicit NumericCastToAsciiStringFunctor(const std::size_t max_length)
-      : max_length_(max_length) {}
+  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 = std::to_string(argument);
+    std::string str = argument_type_.printValueToString(TypedValue(argument));
     const std::size_t str_len = str.length();
 
-    if (str_len < max_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_length_);
+      std::memcpy(result, str.c_str(), max_string_length_);
     }
   }
 
   inline TypedValue apply(const typename ArgumentT::cpptype &argument) const {
-    std::string str = std::to_string(argument);
-    const std::size_t len = std::min(str.length(), max_length_);
+    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));
@@ -82,10 +84,10 @@ class NumericCastToAsciiStringFunctor : public UnaryFunctor<ArgumentT, ResultT>
   }
 
  private:
-  const std::size_t max_length_;
+  const ArgumentT &argument_type_;
+  const std::size_t max_string_length_;
 };
 
-
 template <typename ResultCppType>
 ResultCppType CastStringToNumericImpl(const char *str);
 
@@ -110,8 +112,8 @@ template <typename ArgumentT, typename ResultT,
           typename ResultT::cpptype f(const char*)>
 struct AsciiStringCastToNumericFunctor
     : public UnaryFunctor<ArgumentT, ResultT> {
-  explicit AsciiStringCastToNumericFunctor(const std::size_t max_length)
-      : max_length_(max_length) {}
+  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()));
@@ -119,12 +121,12 @@ struct AsciiStringCastToNumericFunctor
 
   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_length_));
+    const std::string value(str, strnlen(str, max_string_length_));
     return f(value.c_str());
   }
 
  private:
-  const std::size_t max_length_;
+  const std::size_t max_string_length_;
 };
 
 template <typename ArgumentT, typename ResultT>
@@ -217,8 +219,9 @@ UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
             using ResultT = typename TypeGenerator<decltype(result_tid)::value>::type;
 
             return new UncheckedUnaryOperatorWrapperCodegen<
-                 NumericCastToAsciiStringFunctor<ArgumentT, ResultT>>(
+                 CastToAsciiStringFunctor<ArgumentT, ResultT>>(
                      type, *result_type,
+                     static_cast<const ArgumentT&>(type),
                      static_cast<const ResultT*>(result_type)->getStringLength());
           });
         }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/CastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.hpp b/types/operations/unary_operations/CastOperation.hpp
index 23dbec2..713a89c 100644
--- a/types/operations/unary_operations/CastOperation.hpp
+++ b/types/operations/unary_operations/CastOperation.hpp
@@ -24,6 +24,7 @@
 #include <map>
 #include <string>
 #include <utility>
+#include <vector>
 
 #include "types/IntType.hpp"
 #include "types/Type.hpp"
@@ -77,7 +78,7 @@ class CastOperation : public UnaryOperation {
                   const std::vector<TypedValue> &static_arguments,
                   std::string *message) const override {
     DCHECK_EQ(1u, static_arguments.size());
-    if (parseType(static_arguments.front()) == nullptr) {
+    if (getResultTypeInternal(type, static_arguments.front()) == nullptr) {
       *message = "Invalid target type for CAST";
       return false;
     }
@@ -88,14 +89,10 @@ class CastOperation : public UnaryOperation {
       const Type &type,
       const std::vector<TypedValue> &static_arguments) const override {
     DCHECK_EQ(1u, static_arguments.size());
-    const Type *target_type = parseType(static_arguments.front());
-
+    const Type *target_type =
+        getResultTypeInternal(type, static_arguments.front());
     DCHECK(target_type != nullptr);
-    if (type.isNullable()) {
-      return &target_type->getNullableVersion();
-    } else {
-      return target_type;
-    }
+    return target_type;
   }
 
   UncheckedUnaryOperator* makeUncheckedUnaryOperator(
@@ -103,11 +100,17 @@ class CastOperation : public UnaryOperation {
       const std::vector<TypedValue> &static_arguments) const override;
 
  private:
-  static const Type* parseType(const TypedValue &type_arg) {
+  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;
@@ -130,7 +133,9 @@ class CastOperation : public UnaryOperation {
       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>()));
+            it->second,
+            static_cast<std::size_t>(length_value.getLiteral<int>()),
+            type.isNullable());
       }
     }
     return nullptr;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/DateExtractOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.cpp b/types/operations/unary_operations/DateExtractOperation.cpp
index c09b400..f95e109 100644
--- a/types/operations/unary_operations/DateExtractOperation.cpp
+++ b/types/operations/unary_operations/DateExtractOperation.cpp
@@ -38,8 +38,7 @@
 
 namespace quickstep {
 
-struct DateExtractFunctor
-    : public UnaryFunctor<DateType, IntType> {
+struct DateExtractFunctor : public UnaryFunctor<DateType, IntType> {
   template <typename DateExtractUnitT>
   inline int apply(const DateLit &argument) const {
     switch (DateExtractUnitT::value) {
@@ -55,8 +54,7 @@ struct DateExtractFunctor
   }
 };
 
-struct DatetimeExtractFunctor
-    : public UnaryFunctor<DatetimeType, IntType> {
+struct DatetimeExtractFunctor : public UnaryFunctor<DatetimeType, IntType> {
   template <typename DateExtractUnitT>
   inline std::int64_t apply(const DatetimeLit &argument) const {
     switch (DateExtractUnitT::value) {
@@ -91,7 +89,8 @@ UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperator(
     const Type &type,
     const std::vector<TypedValue> &static_arguments) const {
   DCHECK_EQ(1u, static_arguments.size());
-  DateExtractUnit unit = parseUnit(static_arguments.front());
+
+  const DateExtractUnit unit = parseUnit(static_arguments.front());
   const Type *result_type = getResultType(type, static_arguments);
 
   if (type.getTypeID() == kDate) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/DateExtractOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.hpp b/types/operations/unary_operations/DateExtractOperation.hpp
index 00948a4..577e924 100644
--- a/types/operations/unary_operations/DateExtractOperation.hpp
+++ b/types/operations/unary_operations/DateExtractOperation.hpp
@@ -23,20 +23,11 @@
 #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 "utility/Macros.hpp"
 #include "utility/StringUtil.hpp"
@@ -69,22 +60,37 @@ class DateExtractOperation : public UnaryOperation {
   }
 
   std::vector<OperationSignaturePtr> getSignatures() const override {
-    const std::vector<TypeID> target_type_carrier = { kVarChar };
+    const std::vector<TypeID> unit_carrier = { kVarChar };
     return {
-        OperationSignature::Create(getName(), {kDate}, target_type_carrier),
-        OperationSignature::Create(getName(), {kDatetime}, target_type_carrier)
+        OperationSignature::Create(getName(), {kDate}, unit_carrier),
+        OperationSignature::Create(getName(), {kDatetime}, unit_carrier)
     };
   }
 
   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());
-    if (parseUnit(static_arguments.front()) == DateExtractUnit::kInvalid) {
-      *message = "Invalid extraction unit for DateExtract";
-      return false;
+
+    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 true;
   }
 
   const Type* getResultType(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/SubstringOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/SubstringOperation.cpp b/types/operations/unary_operations/SubstringOperation.cpp
index 408ea2d..3d0d139 100644
--- a/types/operations/unary_operations/SubstringOperation.cpp
+++ b/types/operations/unary_operations/SubstringOperation.cpp
@@ -32,7 +32,6 @@
 #include "types/TypedValue.hpp"
 #include "types/containers/ColumnVector.hpp"
 #include "types/containers/ColumnVectorUtil.hpp"
-#include "types/operations/Operation.pb.h"
 #include "types/port/strnlen.hpp"
 #include "utility/TemplateUtil.hpp"
 
@@ -160,37 +159,5 @@ ColumnVector* SubstringUncheckedOperator<null_terminated,
 }
 #endif
 
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-template <bool null_terminated, bool input_nullable>
-ColumnVector* SubstringUncheckedOperator<null_terminated,
-                                         input_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 {
-  return InvokeOnValueAccessorNotAdapter(
-      accessor,
-      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    NativeColumnVector *result =
-        new NativeColumnVector(result_type_, accessor->getNumTuples());
-
-    for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
-      const char *input_ptr = static_cast<const char *>(
-          accessor->template getUntypedValueAtAbsolutePosition<input_nullable>(
-              argument_attr_id,
-              use_left_relation ? joined_pair.first : joined_pair.second));
-
-      if (input_nullable && input_ptr == nullptr) {
-        result->appendNullValue();
-      } else {
-        this->computeSubstring(input_ptr,
-                               static_cast<char *>(result->getPtrForDirectWrite()));
-      }
-    }
-    return result;
-  });
-}
-#endif
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/UnaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperation.hpp b/types/operations/unary_operations/UnaryOperation.hpp
index 68dc993..70cb6f9 100644
--- a/types/operations/unary_operations/UnaryOperation.hpp
+++ b/types/operations/unary_operations/UnaryOperation.hpp
@@ -115,8 +115,6 @@ class UnaryOperation : public Operation {
     return getName();
   }
 
-  virtual std::vector<OperationSignaturePtr> getSignatures() const = 0;
-
   virtual bool canApplyTo(const Type &argument_type,
                           const std::vector<TypedValue> &static_arguments,
                           std::string *message) const = 0;
@@ -129,9 +127,8 @@ class UnaryOperation : public Operation {
       const Type &argument_type,
       const std::vector<TypedValue> &static_arguments) const = 0;
 
-  bool canApplyTo(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments) const {
+  bool canApplyTo(const Type &argument_type,
+                  const std::vector<TypedValue> &static_arguments) const {
     std::string message;
     return canApplyTo(argument_type, static_arguments, &message);
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/UnaryOperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationFactory.cpp b/types/operations/unary_operations/UnaryOperationFactory.cpp
deleted file mode 100644
index cebf9e2..0000000
--- a/types/operations/unary_operations/UnaryOperationFactory.cpp
+++ /dev/null
@@ -1,74 +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.
- **/
-
-#include "types/operations/unary_operations/UnaryOperationFactory.hpp"
-
-#include <string>
-
-#include "types/operations/OperationSignature.hpp"
-#include "types/operations/unary_operations/ArithmeticUnaryOperations.hpp"
-#include "types/operations/unary_operations/CMathUnaryOperations.hpp"
-#include "types/operations/unary_operations/CastOperation.hpp"
-#include "types/operations/unary_operations/DateExtractOperation.hpp"
-#include "types/operations/unary_operations/SubstringOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
-#include "utility/Macros.hpp"
-#include "utility/StringUtil.hpp"
-
-namespace quickstep {
-
-UnaryOperationFactory::UnaryOperationFactory() {
-  registerUnaryOperation(UnaryOperationPtr(new CastOperation()));
-  registerUnaryOperation(UnaryOperationPtr(new DateExtractOperation()));
-  registerUnaryOperation(UnaryOperationPtr(new SubstringOperation()));
-
-  registerUnaryOperationPack<CMathUnaryFunctorPack>();
-  registerUnaryOperationPack<ArithmeticUnaryFunctorPack>();
-}
-
-void UnaryOperationFactory::registerUnaryOperation(
-    const UnaryOperationPtr &operation) {
-  for (const OperationSignaturePtr op_sig : operation->getSignatures()) {
-    const OperationSignaturePtr normalized_op_sig =
-        OperationSignature::Create(ToLower(op_sig->getName()),
-                                   op_sig->getArgumentTypeIDs(),
-                                   op_sig->getNumStaticArguments());
-
-    // TODO: print error message for collision
-    unary_operations_.emplace(normalized_op_sig, operation);
-
-    const auto name_arity_pair = std::make_pair(normalized_op_sig->getName(),
-                                                normalized_op_sig->getArity());
-    name_arity_index_[name_arity_pair].emplace(normalized_op_sig);
-  }
-}
-
-template <typename UnaryOperationPackT>
-void UnaryOperationFactory::registerUnaryOperationPack() {
-  for (const UnaryOperationPtr &operation : UnaryOperationPackT::GenerateAll()) {
-    registerUnaryOperation(operation);
-  }
-}
-
-const UnaryOperationFactory& UnaryOperationFactory::Instance() {
-  static UnaryOperationFactory instance;
-  return instance;
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/unary_operations/UnaryOperationFactory.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationFactory.hpp b/types/operations/unary_operations/UnaryOperationFactory.hpp
deleted file mode 100644
index c586b62..0000000
--- a/types/operations/unary_operations/UnaryOperationFactory.hpp
+++ /dev/null
@@ -1,97 +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_FACTORY_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_FACTORY_HPP_
-
-#include <set>
-#include <unordered_map>
-#include <utility>
-
-#include "types/operations/OperationSignature.hpp"
-#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "utility/HashPair.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief All-static factory object that provides access to UnaryOperations.
- **/
-class UnaryOperationFactory {
- public:
-  static const UnaryOperationFactory& Instance();
-
-  inline bool hasUnaryOperation(
-      const OperationSignaturePtr &op_signature) const {
-    return unary_operations_.find(op_signature) != unary_operations_.end();
-  }
-
-  inline bool hasUnaryOperation(const std::string &name,
-                                const std::size_t arity) const {
-    const auto it = name_arity_index_.find(std::make_pair(name, arity));
-    return it != name_arity_index_.end();
-  }
-
-  inline const UnaryOperationPtr getUnaryOperation(
-      const OperationSignaturePtr &op_signature) const {
-    DCHECK(hasUnaryOperation(op_signature));
-    return unary_operations_.at(op_signature);
-  }
-
-  inline const std::set<OperationSignaturePtr,
-                        OperationSignatureNumStaticArgumentsGreater>&
-      getUnaryOperations(const std::string &name,
-                         const std::size_t arity) const {
-    DCHECK(hasUnaryOperation(name, arity));
-    return name_arity_index_.at(std::make_pair(name, arity));
-  }
-
- private:
-  UnaryOperationFactory();
-
-  void registerUnaryOperation(const UnaryOperationPtr &operation);
-
-  template <typename UnaryOperationPackT>
-  void registerUnaryOperationPack();
-
-  std::unordered_map<OperationSignaturePtr,
-                     UnaryOperationPtr,
-                     OperationSignatureHash,
-                     OperationSignatureEqual> unary_operations_;
-
-  std::unordered_map<
-      std::pair<std::string, std::size_t>,
-      std::set<OperationSignaturePtr,
-               OperationSignatureNumStaticArgumentsGreater>> name_arity_index_;
-
-  DISALLOW_COPY_AND_ASSIGN(UnaryOperationFactory);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_FACTORY_HPP_