http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/959cd0d4/types/operations/unary_operations/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt index 6e1923a..fa47a5c 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,113 @@ 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_TemplateUtil) +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_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_StringUtil quickstep_utility_TemplateUtil) 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 +176,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/959cd0d4/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..a4cb201 --- /dev/null +++ b/types/operations/unary_operations/CMathUnaryOperations.hpp @@ -0,0 +1,109 @@ +/** + * 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/TemplateUtil.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; + +using CMathUnaryFunctorPack = FunctorPack< +// abs + CMathUnaryFunctor<IntType, IntType, + std::abs, StringLiteral<'a','b','s'>>, + CMathUnaryFunctor<LongType, LongType, + std::abs, StringLiteral<'a','b','s'>>, + CMathUnaryFunctor<FloatType, FloatType, + std::fabs, StringLiteral<'a','b','s'>>, + CMathUnaryFunctor<DoubleType, DoubleType, + std::fabs, StringLiteral<'a','b','s'>>, +// sqrt + CMathUnaryFunctor<FloatType, FloatType, + std::sqrt, StringLiteral<'s','q','r','t'>>, + CMathUnaryFunctor<DoubleType, DoubleType, + std::sqrt, StringLiteral<'s','q','r','t'>>, +// exp + CMathUnaryFunctor<FloatType, FloatType, + std::exp, StringLiteral<'e','x','p'>>, + CMathUnaryFunctor<DoubleType, DoubleType, + std::exp, StringLiteral<'e','x','p'>>, +// log + CMathUnaryFunctor<FloatType, FloatType, + std::log, StringLiteral<'l','o','g'>>, + CMathUnaryFunctor<DoubleType, DoubleType, + std::log, StringLiteral<'l','o','g'>>, +// ceil + CMathUnaryFunctor<FloatType, FloatType, + std::ceil, StringLiteral<'c','e','i','l'>>, + CMathUnaryFunctor<DoubleType, DoubleType, + std::ceil, StringLiteral<'c','e','i','l'>>, +// floor + CMathUnaryFunctor<FloatType, FloatType, + std::floor, StringLiteral<'f','l','o','o','r'>>, + CMathUnaryFunctor<DoubleType, DoubleType, + std::floor, StringLiteral<'f','l','o','o','r'>>, +// round + CMathUnaryFunctor<FloatType, LongType, + std::llround, StringLiteral<'r','o','u','n','d'>>, + CMathUnaryFunctor<DoubleType, LongType, + std::llround, 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/959cd0d4/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..b240b23 --- /dev/null +++ b/types/operations/unary_operations/CastOperation.cpp @@ -0,0 +1,285 @@ +/** + * 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" + +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 <> +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 = { + { "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, kInt, kLong, kFloat, kDouble)) { + return InvokeOnTypeID<TypeIDSelectorEqualsAny<kInt, kLong, kFloat, kDouble>>( + argument_type_id, + [&](auto arg_tid) -> UncheckedUnaryOperator* { // NOLINT(build/c++11) + using ArgumentT = typename TypeGenerator<decltype(arg_tid)::value>::type; + + switch (result_type_id) { + case kInt: // Fall through + case kLong: + case kFloat: + case kDouble: { + return InvokeOnTypeID<TypeIDSelectorEqualsAny<kInt, kLong, kFloat, kDouble>>( + result_type_id, + [&](auto result_tid) -> UncheckedUnaryOperator* { // NOLINT(build/c++11) + using ResultT = typename TypeGenerator<decltype(result_tid)::value>::type; + + 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 TypeGenerator<decltype(result_tid)::value>::type; + + 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 TypeGenerator<decltype(arg_tid)::value>::type; + + switch (result_type_id) { + case kInt: // Fall through + case kLong: + case kFloat: + case kDouble: { + return InvokeOnTypeID<TypeIDSelectorEqualsAny<kInt, kLong, kFloat, kDouble>>( + result_type_id, + [&](auto result_tid) -> UncheckedUnaryOperator* { // NOLINT(build/c++11) + using ResultT = typename TypeGenerator<decltype(result_tid)::value>::type; + + 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 TypeGenerator<decltype(result_tid)::value>::type; + + 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/959cd0d4/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..713a89c --- /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 = + { 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/959cd0d4/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/959cd0d4/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/959cd0d4/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_ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/959cd0d4/types/operations/unary_operations/SubstringOperation.cpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/SubstringOperation.cpp b/types/operations/unary_operations/SubstringOperation.cpp index 84f1c8d..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" @@ -40,30 +39,27 @@ namespace quickstep { -serialization::UnaryOperation SubstringOperation::getProto() const { - serialization::UnaryOperation proto; - proto.set_operation_id(serialization::UnaryOperation::SUBSTRING); - proto.SetExtension(serialization::SubstringOperation::start_position, - start_position_); - proto.SetExtension(serialization::SubstringOperation::substring_length, - substring_length_); - return proto; -} +UncheckedUnaryOperator* SubstringOperation::makeUncheckedUnaryOperator( + const Type &type, + const std::vector<TypedValue> &static_arguments) const { + DCHECK(UnaryOperation::canApplyTo(type, static_arguments)); -UncheckedUnaryOperator* SubstringOperation::makeUncheckedUnaryOperatorForType( - const Type &type) const { - DCHECK(type.getSuperTypeID() == Type::kAsciiString); + std::size_t start_position; + std::size_t substring_length; + ExtractStaticArguments(static_arguments, &start_position, &substring_length); const std::size_t input_maximum_length = - static_cast<const AsciiStringSuperType&>(type).getStringLength(); + type.getTypeID() == kChar + ? static_cast<const CharType&>(type).getStringLength() + : static_cast<const VarCharType&>(type).getStringLength(); const bool input_null_terminated = (type.getTypeID() == TypeID::kVarChar); - const Type *result_type = resultTypeForArgumentType(type); + const Type *result_type = getResultType(type, static_arguments); DCHECK(result_type != nullptr); return CreateBoolInstantiatedInstance<SubstringUncheckedOperator, UncheckedUnaryOperator>( - std::forward_as_tuple(start_position_, - computeMaximumSubstringLength(type), + std::forward_as_tuple(start_position, + ComputeMaximumSubstringLength(type, start_position, substring_length), input_maximum_length, *result_type), input_null_terminated, type.isNullable()); @@ -108,23 +104,6 @@ TypedValue SubstringUncheckedOperator<null_terminated, } template <bool null_terminated, bool input_nullable> -TypedValue SubstringUncheckedOperator<null_terminated, - input_nullable> - ::applyToDataPtr(const void *argument) const { - if (input_nullable && argument == nullptr) { - return TypedValue(result_type_.getTypeID()); - } - - char *output_ptr = static_cast<char*>(std::malloc(substring_length_)); - computeSubstring(static_cast<const char*>(argument), - output_ptr); - - return TypedValue::CreateWithOwnedData(result_type_.getTypeID(), - output_ptr, - substring_length_); -} - -template <bool null_terminated, bool input_nullable> ColumnVector* SubstringUncheckedOperator<null_terminated, input_nullable> ::applyToColumnVector(const ColumnVector &argument) const { @@ -180,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