http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt index fbfd091..269d683 100644 --- a/types/operations/unary_operations/CMakeLists.txt +++ b/types/operations/unary_operations/CMakeLists.txt @@ -36,9 +36,9 @@ add_library(quickstep_types_operations_unaryoperations_SubstringOperation SubstringOperation.cpp SubstringOperation.hpp) add_library(quickstep_types_operations_unaryoperations_UnaryOperation UnaryOperation.cpp UnaryOperation.hpp) -add_library(quickstep_types_operations_unaryoperations_UnaryOperationWrapper +add_library(quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer ../../../empty_src.cpp - UnaryOperationWrapper.hpp) + UnaryOperationSynthesizer.hpp) # Link dependencies: target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnaryFunctors @@ -49,7 +49,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnary quickstep_types_IntType quickstep_types_LongType quickstep_types_YearMonthIntervalType - quickstep_types_operations_unaryoperations_UnaryOperationWrapper + quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer quickstep_types_operations_utility_OperationSynthesizeUtil) target_link_libraries(quickstep_types_operations_unaryoperations_AsciiStringUnaryFunctors quickstep_types_CharType @@ -58,7 +58,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_AsciiStringUnar quickstep_types_TypeFactory quickstep_types_TypeID quickstep_types_VarCharType - quickstep_types_operations_unaryoperations_UnaryOperationWrapper + quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer quickstep_types_operations_utility_OperationSynthesizeUtil quickstep_types_port_strnlen quickstep_utility_meta_Common) @@ -67,28 +67,37 @@ target_link_libraries(quickstep_types_operations_unaryoperations_CMathUnaryFunct quickstep_types_FloatType quickstep_types_IntType quickstep_types_LongType - quickstep_types_operations_unaryoperations_UnaryOperationWrapper + quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer quickstep_types_operations_utility_OperationSynthesizeUtil quickstep_utility_meta_Common) +target_link_libraries(quickstep_types_operations_unaryoperations_CastFunctorOverloads + quickstep_types_TypeRegistrar + quickstep_types_TypedValue + quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer + quickstep_utility_meta_TypeList) target_link_libraries(quickstep_types_operations_unaryoperations_CastOperation glog quickstep_types_CharType quickstep_types_DoubleType quickstep_types_FloatType + quickstep_types_GenericValue quickstep_types_IntType quickstep_types_LongType + quickstep_types_MetaType quickstep_types_Type quickstep_types_TypeFactory quickstep_types_TypeID quickstep_types_TypeUtil quickstep_types_TypedValue quickstep_types_VarCharType + quickstep_types_operations_unaryoperations_CastFunctorOverloads quickstep_types_operations_unaryoperations_UnaryOperation - quickstep_types_operations_unaryoperations_UnaryOperationWrapper + quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer quickstep_types_port_strnlen quickstep_utility_EqualsAnyConstant quickstep_utility_Macros - quickstep_utility_StringUtil) + quickstep_utility_StringUtil + quickstep_utility_meta_Common) target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOperation glog quickstep_types_DateType @@ -100,7 +109,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOper quickstep_types_TypeID quickstep_types_TypedValue quickstep_types_operations_unaryoperations_UnaryOperation - quickstep_types_operations_unaryoperations_UnaryOperationWrapper + quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer quickstep_utility_Macros quickstep_utility_StringUtil) target_link_libraries(quickstep_types_operations_unaryoperations_SubstringOperation @@ -126,7 +135,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperation quickstep_types_operations_OperationSignature quickstep_types_operations_Operation_proto quickstep_utility_Macros) -target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationWrapper +target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer glog quickstep_catalog_CatalogTypedefs quickstep_storage_ValueAccessor @@ -152,7 +161,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations quickstep_types_operations_unaryoperations_DateExtractOperation quickstep_types_operations_unaryoperations_SubstringOperation quickstep_types_operations_unaryoperations_UnaryOperation - quickstep_types_operations_unaryoperations_UnaryOperationWrapper) + quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer) # Tests:
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/CMathUnaryFunctors.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/CMathUnaryFunctors.hpp b/types/operations/unary_operations/CMathUnaryFunctors.hpp index 5ed8b50..edece53 100644 --- a/types/operations/unary_operations/CMathUnaryFunctors.hpp +++ b/types/operations/unary_operations/CMathUnaryFunctors.hpp @@ -27,7 +27,7 @@ #include "types/FloatType.hpp" #include "types/IntType.hpp" #include "types/LongType.hpp" -#include "types/operations/unary_operations/UnaryOperationWrapper.hpp" +#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp" #include "types/operations/utility/OperationSynthesizeUtil.hpp" #include "utility/meta/Common.hpp" http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/CastFunctorOverloads.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/CastFunctorOverloads.hpp b/types/operations/unary_operations/CastFunctorOverloads.hpp index 940cab6..0e4b059 100644 --- a/types/operations/unary_operations/CastFunctorOverloads.hpp +++ b/types/operations/unary_operations/CastFunctorOverloads.hpp @@ -26,9 +26,10 @@ #include <type_traits> #include <vector> +#include "types/GenericValue.hpp" #include "types/TypeRegistrar.hpp" #include "types/TypedValue.hpp" -#include "types/operations/unary_operations/UnaryOperationWrapper.hpp" +#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp" #include "utility/meta/TypeList.hpp" namespace quickstep { @@ -62,12 +63,17 @@ struct CastFunctor< // ---------------------------------------------------------------------------- // Implementations of any type to ascii string casts. +using UnsupportedCastToAsciiStringTypes = meta::TypeList<NullType>; + +// TODO(refactor-type): Better implementation of casting among ascii string types. + template <typename SourceType> -struct CastFunctor<SourceType, CharType, - std::enable_if_t<SourceType::kStaticSuperTypeID == SuperTypeID::kNumeric>> +struct CastFunctor< + SourceType, CharType, + std::enable_if_t<!UnsupportedCastToAsciiStringTypes::contains<SourceType>::value>> : public UnaryFunctor<SourceType, CharType> { - explicit CastFunctor(const SourceType &source_type_in, - const CharType &target_type_in) + CastFunctor(const SourceType &source_type_in, + const CharType &target_type_in) : source_type(source_type_in), max_string_length(target_type_in.getStringLength()) {} inline void apply(const typename SourceType::cpptype &argument, void *result) const { @@ -85,11 +91,12 @@ struct CastFunctor<SourceType, CharType, }; template <typename SourceType> -struct CastFunctor<SourceType, VarCharType, - std::enable_if_t<SourceType::kStaticSuperTypeID == SuperTypeID::kNumeric>> +struct CastFunctor< + SourceType, VarCharType, + std::enable_if_t<!UnsupportedCastToAsciiStringTypes::contains<SourceType>::value>> : public UnaryFunctor<SourceType, VarCharType> { - explicit CastFunctor(const SourceType &source_type_in, - const VarCharType &target_type_in) + CastFunctor(const SourceType &source_type_in, + const VarCharType &target_type_in) : source_type(source_type_in), max_string_length(target_type_in.getStringLength()) {} inline TypedValue apply(const typename SourceType::cpptype &argument) const { @@ -105,75 +112,109 @@ struct CastFunctor<SourceType, VarCharType, const std::size_t max_string_length; }; -//template <typename SourceType> -//struct CastFunctor<SourceType, TextType> -// : public UnaryFunctor<SourceType, TextType> { -// explicit CastFunctor(const SourceType &source_type_in, -// const TextType &target_type_in) -// : source_type(source_type_in) {} -// inline std::string apply(const typename SourceType::cpptype &argument) const { -// return source_type.printValueToString(&argument); -// } -// const SourceType &source_type; -//}; -// -// +template <typename SourceType> +struct CastFunctor< + SourceType, TextType, + std::enable_if_t<!UnsupportedCastToAsciiStringTypes::contains<SourceType>::value>> + : public UnaryFunctor<SourceType, TextType> { + CastFunctor(const SourceType &source_type_in, + const TextType &target_type_in) + : source_type(source_type_in) {} + inline std::string apply(const typename SourceType::cpptype &argument) const { + return source_type.printValueToString(&argument); + } + const SourceType &source_type; +}; + + //// ---------------------------------------------------------------------------- -//// Implementations of ascii string to numeric casts. -// -//template <typename T> -//T CastStringToNumericOverload(const char *str); -// -//template <> -//bool CastStringToNumericOverload(const char *str) { -// return ToLower(str) == "true"; -//} -//template <> -//int CastStringToNumericOverload(const char *str) { -// return std::atoi(str); -//} -//template <> -//float CastStringToNumericOverload(const char *str) { -// return static_cast<float>(std::atof(str)); -//} -//template <> -//std::int64_t CastStringToNumericOverload(const char *str) { -// return std::atoll(str); -//} -//template <> -//double CastStringToNumericOverload(const char *str) { -// return std::atof(str); -//} -// -//template <typename TargetType> -//struct CastFunctor<CharType, TargetType, -// std::enable_if_t<NumericTypes::contains<TargetType>::value>> -// : public UnaryFunctor<CharType, TargetType> { -// explicit CastFunctor(const CharType &source_type_in, -// const TargetType &target_type_in) -// : max_string_length(source_type_in.getStringLength()) {} -// inline typename TargetType::cpptype apply(const void *argument) const { -// const char *str = static_cast<const char*>(argument); -// const std::string value(str, strnlen(str, max_string_length)); -// return CastStringToNumericOverload<typename TargetType::cpptype>(value.c_str()); -// } -// const std::size_t max_string_length; -//}; -// -// -//template <typename TargetType> -//struct CastFunctor<VarCharType, TargetType, -// std::enable_if_t<NumericTypes::contains<TargetType>::value>> -// : public UnaryFunctor<VarCharType, TargetType> { -// explicit CastFunctor(const VarCharType &source_type_in, -// const TargetType &target_type_in) -// : max_string_length(source_type_in.getStringLength()) {} -// inline typename TargetType::cpptype apply(const TypedValue &argument) const { -// return CastStringToNumericOverload<typename TargetType::cpptype>( -// static_cast<const char*>(argument.getDataPtr())); -// } -// const std::size_t max_string_length; -//}; +//// Implementations of ascii string to other types casts. + +using UnsupportedParseFromAsciiStringTypes = meta::TypeList<NullType>; + +// TODO(refactor-type): Implement parseTypedValueFromString for other non-numeric types. +// TODO(refactor-type): Possibly return NULL values. + +template <typename TargetType> +struct CastFunctor< + CharType, TargetType, + std::enable_if_t<!UnsupportedParseFromAsciiStringTypes::contains<TargetType>::value && + TargetType::kMemoryLayout == kCxxInlinePod>> + : public UnaryFunctor<CharType, TargetType> { + CastFunctor(const CharType &source_type_in, + const TargetType &target_type_in) + : max_string_length(source_type_in.getStringLength()), + target_type(target_type_in) {} + inline typename TargetType::cpptype apply(const void *argument) const { + // TODO(refactor-type): Implement specialized parseValueFromString. + const char *str = static_cast<const char*>(argument); + const std::string value(str, strnlen(str, max_string_length)); + TypedValue result; + target_type.parseTypedValueFromString(value, &result); + return result.getLiteral<typename TargetType::cpptype>(); + } + const std::size_t max_string_length; + const TargetType &target_type; +}; + + +template <typename TargetType> +struct CastFunctor<VarCharType, TargetType, + std::enable_if_t<NumericTypes::contains<TargetType>::value>> + : public UnaryFunctor<VarCharType, TargetType> { + CastFunctor(const VarCharType &source_type_in, + const TargetType &target_type_in) + : max_string_length(source_type_in.getStringLength()), + target_type(target_type_in) {} + inline typename TargetType::cpptype apply(const TypedValue &argument) const { + const std::string value(static_cast<const char*>(argument.getOutOfLineData())); + TypedValue result; + target_type.parseTypedValueFromString(value, &result); + return result.getLiteral<typename TargetType::cpptype>(); + } + const std::size_t max_string_length; + const Type &target_type; +}; + +template <typename TargetType> +struct CastFunctor< + TextType, TargetType, + std::enable_if_t<!UnsupportedParseFromAsciiStringTypes::contains<TargetType>::value && + TargetType::kMemoryLayout == kCxxInlinePod>> + : public UnaryFunctor<TextType, TargetType> { + CastFunctor(const TextType &source_type_in, + const TargetType &target_type_in) + : target_type(target_type_in) {} + inline typename TargetType::cpptype apply(const std::string &argument) const { + // TODO(refactor-type): Implement specialized parseValueFromString. + TypedValue result; + target_type.parseTypedValueFromString(argument, &result); + return result.getLiteral<typename TargetType::cpptype>(); + } + const TargetType &target_type; +}; + + +//// ---------------------------------------------------------------------------- +//// Implementations of array to array casts. + +template <> +struct CastFunctor<ArrayType, ArrayType> + : public UnaryFunctor<ArrayType, ArrayType> { + CastFunctor(const ArrayType &source_type_in, + const ArrayType &target_type_in) + : source_element_type(source_type_in.getElementType()), + target_element_type(target_type_in.getElementType()) {} + inline ArrayLit apply(const ArrayLit &argument) const { + ArrayLit result(target_element_type); + for (const auto *value : argument) { + result.push_back(target_element_type.coerceValue(value, source_element_type)); + } + return result; + } + const Type &source_element_type; + const Type &target_element_type; +}; /** @} */ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/CastOperation.cpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/CastOperation.cpp b/types/operations/unary_operations/CastOperation.cpp index 8f725e2..f71ae7d 100644 --- a/types/operations/unary_operations/CastOperation.cpp +++ b/types/operations/unary_operations/CastOperation.cpp @@ -38,7 +38,7 @@ #include "types/TypedValue.hpp" #include "types/VarCharType.hpp" #include "types/operations/unary_operations/CastFunctorOverloads.hpp" -#include "types/operations/unary_operations/UnaryOperationWrapper.hpp" +#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp" #include "types/port/strnlen.hpp" #include "utility/EqualsAnyConstant.hpp" #include "utility/StringUtil.hpp" @@ -53,7 +53,7 @@ UncheckedUnaryOperator* MakeUncheckedCastOperatorConstructorSpec( const SourceType &source_type, const TargetType &target_type, decltype(new CastFunctor<SourceType, TargetType>()) * = 0) { - return new UncheckedUnaryOperatorWrapperCodegen< + return new UncheckedUnaryOperatorSynthesizer< CastFunctor<SourceType, TargetType>>( source_type, target_type); } @@ -63,7 +63,7 @@ UncheckedUnaryOperator* MakeUncheckedCastOperatorConstructorSpec( const SourceType &source_type, const TargetType &target_type, decltype(new CastFunctor<SourceType, TargetType>(source_type, target_type)) * = 0) { - return new UncheckedUnaryOperatorWrapperCodegen< + return new UncheckedUnaryOperatorSynthesizer< CastFunctor<SourceType, TargetType>>( source_type, target_type, source_type, target_type); } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/CastOperation.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/CastOperation.hpp b/types/operations/unary_operations/CastOperation.hpp index b8750c0..5a139b0 100644 --- a/types/operations/unary_operations/CastOperation.hpp +++ b/types/operations/unary_operations/CastOperation.hpp @@ -26,10 +26,10 @@ #include <utility> #include <vector> -#include "types/IntType.hpp" #include "types/Type.hpp" #include "types/TypeFactory.hpp" #include "types/TypeID.hpp" +#include "types/TypeRegistrar.hpp" #include "types/TypedValue.hpp" #include "types/operations/unary_operations/UnaryOperation.hpp" #include "utility/Macros.hpp" @@ -63,7 +63,7 @@ class CastOperation : public UnaryOperation { std::vector<OperationSignaturePtr> getSignatures() const override { const std::vector<TypeID> source_type_ids = - { kBool, kInt, kLong, kFloat, kDouble, kChar, kVarChar }; + TypeIDSequenceAll::Instantiate<std::vector<TypeID>>(); const std::vector<TypeID> target_type_carrier = { kMetaType }; std::vector<OperationSignaturePtr> signatures; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/DateExtractOperation.cpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/DateExtractOperation.cpp b/types/operations/unary_operations/DateExtractOperation.cpp index f95e109..16e66a9 100644 --- a/types/operations/unary_operations/DateExtractOperation.cpp +++ b/types/operations/unary_operations/DateExtractOperation.cpp @@ -32,7 +32,7 @@ #include "types/Type.hpp" #include "types/TypeID.hpp" #include "types/TypedValue.hpp" -#include "types/operations/unary_operations/UnaryOperationWrapper.hpp" +#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp" #include "glog/logging.h" @@ -96,17 +96,17 @@ UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperator( if (type.getTypeID() == kDate) { switch (unit) { case DateExtractUnit::kYear: - return new UncheckedUnaryOperatorWrapperCodegen< + return new UncheckedUnaryOperatorSynthesizer< DateExtractFunctor, std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>( type, *result_type); case DateExtractUnit::kMonth: - return new UncheckedUnaryOperatorWrapperCodegen< + return new UncheckedUnaryOperatorSynthesizer< DateExtractFunctor, std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>( type, *result_type); case DateExtractUnit::kDay: - return new UncheckedUnaryOperatorWrapperCodegen< + return new UncheckedUnaryOperatorSynthesizer< DateExtractFunctor, std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>( type, *result_type); @@ -117,32 +117,32 @@ UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperator( } else { switch (unit) { case DateExtractUnit::kYear: - return new UncheckedUnaryOperatorWrapperCodegen< + return new UncheckedUnaryOperatorSynthesizer< DatetimeExtractFunctor, std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>( type, *result_type); case DateExtractUnit::kMonth: - return new UncheckedUnaryOperatorWrapperCodegen< + return new UncheckedUnaryOperatorSynthesizer< DatetimeExtractFunctor, std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>( type, *result_type); case DateExtractUnit::kDay: - return new UncheckedUnaryOperatorWrapperCodegen< + return new UncheckedUnaryOperatorSynthesizer< DatetimeExtractFunctor, std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>( type, *result_type); case DateExtractUnit::kHour: - return new UncheckedUnaryOperatorWrapperCodegen< + return new UncheckedUnaryOperatorSynthesizer< DatetimeExtractFunctor, std::integral_constant<DateExtractUnit, DateExtractUnit::kHour>>( type, *result_type); case DateExtractUnit::kMinute: - return new UncheckedUnaryOperatorWrapperCodegen< + return new UncheckedUnaryOperatorSynthesizer< DatetimeExtractFunctor, std::integral_constant<DateExtractUnit, DateExtractUnit::kMinute>>( type, *result_type); case DateExtractUnit::kSecond: - return new UncheckedUnaryOperatorWrapperCodegen< + return new UncheckedUnaryOperatorSynthesizer< DatetimeExtractFunctor, std::integral_constant<DateExtractUnit, DateExtractUnit::kSecond>>( type, *result_type); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/UnaryOperationSynthesizer.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/UnaryOperationSynthesizer.hpp b/types/operations/unary_operations/UnaryOperationSynthesizer.hpp new file mode 100644 index 0000000..9d46af7 --- /dev/null +++ b/types/operations/unary_operations/UnaryOperationSynthesizer.hpp @@ -0,0 +1,273 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + **/ + +#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_ +#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_ + +#include <cstddef> +#include <string> +#include <type_traits> + +#include "catalog/CatalogTypedefs.hpp" +#include "storage/ValueAccessor.hpp" +#include "storage/ValueAccessorUtil.hpp" +#include "types/Type.hpp" +#include "types/TypeFactory.hpp" +#include "types/TypeID.hpp" +#include "types/TypedValue.hpp" +#include "types/containers/ColumnVector.hpp" +#include "types/operations/OperationSignature.hpp" +#include "types/operations/unary_operations/UnaryOperation.hpp" +#include "types/operations/utility/OperationSynthesizeUtil.hpp" +#include "utility/Macros.hpp" + +#include "glog/logging.h" + +namespace quickstep { + +/** \addtogroup Types + * @{ + */ + +template <typename ArgumentT, typename ResultT> +struct UnaryFunctor { + typedef ArgumentT ArgumentType; + typedef ResultT ResultType; + + static constexpr Operation + ::OperationSuperTypeID kOperationSuperTypeID = Operation::kUnaryOperation; +}; + +template <typename FunctorT, typename ...SpecArgs> +class UncheckedUnaryOperatorSynthesizer : public UncheckedUnaryOperator { + public: + template <typename ...FunctorArgs> + UncheckedUnaryOperatorSynthesizer(const Type &argument_type, + const Type &result_type, + FunctorArgs &&...args) + : functor_(std::forward<FunctorArgs>(args)...), + impl_(functor_, argument_type, result_type) { + DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID); + DCHECK(result_type.getTypeID() == ResultType::kStaticTypeID); + } + + TypedValue applyToTypedValue(const TypedValue &argument) const override { + return impl_.applyToTypedValue(argument); + } + + ColumnVector* applyToColumnVector(const ColumnVector &argument) const override { + using ArgumentCVT = typename ArgumentGen::ColumnVectorType; + DCHECK_EQ(argument.getImplementation(), ArgumentCVT::kImplementation); + + using ArgumentAccessorT = ColumnVectorAccessor<ArgumentCVT>; + ArgumentAccessorT accessor(static_cast<const ArgumentCVT&>(argument)); + return impl_.applyToValueAccessor(&accessor, 0); + } + + ColumnVector* applyToValueAccessor(ValueAccessor *accessor, + const attribute_id attr_id) const override { + return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter( + accessor, + [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11) + return impl_.applyToValueAccessor(accessor, attr_id); + }); + } + + private: + using ArgumentType = typename FunctorT::ArgumentType; + using ResultType = typename FunctorT::ResultType; + + using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type; + using ArgumentGen = OperationCodegen<FuncSpec, ArgumentType>; + using ResultGen = OperationCodegen<FuncSpec, ResultType>; + + template <bool argument_nullable> + struct Implementation; + + const FunctorT functor_; + const Implementation<true> impl_; + + DISALLOW_COPY_AND_ASSIGN(UncheckedUnaryOperatorSynthesizer); +}; + +template <typename FunctorT, typename ...SpecArgs> +template <bool argument_nullable> +struct UncheckedUnaryOperatorSynthesizer<FunctorT, SpecArgs...> + ::Implementation { + Implementation(const FunctorT &functor_in, + const Type &argument_type_in, + const Type &result_type_in) + : functor(functor_in), + argument_type(static_cast<const ArgumentType&>(argument_type_in)), + result_type(static_cast<const ResultType&>(result_type_in)) {} + + inline TypedValue applyToTypedValue(const TypedValue &argument) const { + if (argument_nullable && argument.isNull()) { + return TypedValue(ResultType::kStaticTypeID); + } + + return ResultGen::template ApplyUnaryTypedValue<ArgumentGen>( + ArgumentGen::ToNativeValueConst(argument, argument_type), + result_type, + functor); + } + + template <typename AccessorT> + inline ColumnVector* applyToValueAccessor(AccessorT *accessor, + const attribute_id attr_id) const { + using ResultCVT = typename ResultGen::ColumnVectorType; + ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples()); + + std::unique_ptr<typename ArgumentGen::NativeType> value_cache; + accessor->beginIteration(); + while (accessor->next()) { + typename ArgumentGen::NativeTypeConstPtr arg_value = + ArgumentGen::template GetValuePtr<argument_nullable, AccessorT>( + accessor, attr_id, argument_type, &value_cache); + + if (argument_nullable && ArgumentGen::IsNull(arg_value)) { + result_cv->appendNullValue(); + } else { + ResultGen::template ApplyUnaryColumnVector<ArgumentGen>( + ArgumentGen::Dereference(arg_value), functor, result_cv); + } + } + return result_cv; + } + + const FunctorT &functor; + const ArgumentType &argument_type; + const ResultType &result_type; +}; + +template <typename FunctorT> +class UnaryOperationSynthesizer : public UnaryOperation { + public: + UnaryOperationSynthesizer() + : UnaryOperation(), + operation_name_(FunctorT::GetName()) {} + + std::string getName() const override { + return operation_name_; + } + + std::string getShortName() const override { + return getName(); + } + + std::vector<OperationSignaturePtr> getSignatures() const override { + return { + OperationSignature::Create(getName(), {ArgumentType::kStaticTypeID}, 0) + }; + } + + bool canApplyTo(const Type &argument_type, + const std::vector<TypedValue> &static_arguments, + std::string *message) const override { + DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID); + DCHECK(static_arguments.empty()); + return true; + } + + const Type* getResultType( + const Type &argument_type, + const std::vector<TypedValue> &static_arguments) const override { + DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID); + DCHECK(static_arguments.empty()); + return getResultTypeImpl<HasGetType<FunctorT>::value>( + argument_type, static_arguments); + } + + UncheckedUnaryOperator* makeUncheckedUnaryOperator( + const Type &argument_type, + const std::vector<TypedValue> &static_arguments) const override { + DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID); + DCHECK(static_arguments.empty()); + return makeUncheckedUnaryOperatorImpl< + std::is_default_constructible<FunctorT>::value>( + argument_type, static_arguments); + } + + private: + using ArgumentType = typename FunctorT::ArgumentType; + using ResultType = typename FunctorT::ResultType; + + QUICKSTEP_TRAIT_HAS_STATIC_METHOD(HasGetType, GetType); + + template <bool functor_use_default_constructor> + inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl( + const Type &argument_type, + const std::vector<TypedValue> &static_arguments, + std::enable_if_t<functor_use_default_constructor> * = 0) const { + return new UncheckedUnaryOperatorSynthesizer<FunctorT>( + argument_type, *getResultType(argument_type, static_arguments)); + } + + template <bool functor_use_default_constructor> + inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl( + const Type &argument_type, + const std::vector<TypedValue> &static_arguments, + std::enable_if_t<!functor_use_default_constructor> * = 0) const { + return new UncheckedUnaryOperatorSynthesizer<FunctorT>( + argument_type, *getResultType(argument_type, static_arguments), + static_cast<const ArgumentType&>(argument_type)); + } + + template <bool user_defined_get_type> + inline const Type* getResultTypeImpl( + const Type &argument_type, + const std::vector<TypedValue> &static_arguments, + std::enable_if_t<!user_defined_get_type && + ResultType::kMemoryLayout == kCxxInlinePod> * = 0) const { + return &TypeFactory::GetType(ResultType::kStaticTypeID, + argument_type.isNullable()); + } + + template <bool user_defined_get_type> + inline const Type* getResultTypeImpl( + const Type &argument_type, + const std::vector<TypedValue> &static_arguments, + std::enable_if_t<!user_defined_get_type && + ResultType::kMemoryLayout == kCxxGeneric> * = 0) const { + return &TypeFactory::GetType(ResultType::kStaticTypeID, + std::vector<GenericValue>(), + argument_type.isNullable()); + } + + template <bool user_defined_get_type> + inline const Type* getResultTypeImpl( + const Type &argument_type, + const std::vector<TypedValue> &static_arguments, + std::enable_if_t<user_defined_get_type || + ResultType::kMemoryLayout == kParInlinePod || + ResultType::kMemoryLayout == kParOutOfLinePod> * = 0) const { + // TODO(refactor-type): Specialize with regard to static arguments. + return FunctorT::GetResultType(argument_type); + } + + const std::string operation_name_; + + DISALLOW_COPY_AND_ASSIGN(UnaryOperationSynthesizer); +}; + +/** @} */ + +} // namespace quickstep + +#endif // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/unary_operations/UnaryOperationWrapper.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/UnaryOperationWrapper.hpp b/types/operations/unary_operations/UnaryOperationWrapper.hpp deleted file mode 100644 index 78285fa..0000000 --- a/types/operations/unary_operations/UnaryOperationWrapper.hpp +++ /dev/null @@ -1,250 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - **/ - -#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_ -#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_ - -#include <cstddef> -#include <string> -#include <type_traits> - -#include "catalog/CatalogTypedefs.hpp" -#include "storage/ValueAccessor.hpp" -#include "storage/ValueAccessorUtil.hpp" -#include "types/Type.hpp" -#include "types/TypeFactory.hpp" -#include "types/TypeID.hpp" -#include "types/TypedValue.hpp" -#include "types/containers/ColumnVector.hpp" -#include "types/operations/OperationSignature.hpp" -#include "types/operations/unary_operations/UnaryOperation.hpp" -#include "types/operations/utility/OperationSynthesizeUtil.hpp" -#include "utility/Macros.hpp" - -namespace quickstep { - -/** \addtogroup Types - * @{ - */ - -template <typename ArgumentT, typename ResultT> -struct UnaryFunctor { - typedef ArgumentT ArgumentType; - typedef ResultT ResultType; - - static constexpr Operation - ::OperationSuperTypeID kOperationSuperTypeID = Operation::kUnaryOperation; -}; - -template <typename FunctorT, typename ...SpecArgs> -class UncheckedUnaryOperatorWrapperCodegen : public UncheckedUnaryOperator { - public: - template <typename ...ConstructorArgs> - UncheckedUnaryOperatorWrapperCodegen(const Type &argument_type, - const Type &result_type, - ConstructorArgs &&...args) - : functor_(std::forward<ConstructorArgs>(args)...), - impl_(functor_, argument_type, result_type) {} - - TypedValue applyToTypedValue(const TypedValue &argument) const override { - return impl_.applyToTypedValue(argument); - } - - ColumnVector* applyToColumnVector(const ColumnVector &argument) const override { - using ArgumentCVT = typename ArgumentGen::ColumnVectorType; - DCHECK_EQ(argument.isNative(), ArgumentCVT::kNative); - - using ArgumentAccessorT = ColumnVectorValueAccessor<ArgumentCVT>; - ArgumentAccessorT accessor(static_cast<const ArgumentCVT&>(argument)); - return impl_.applyToValueAccessor(&accessor, 0); - } - - ColumnVector* applyToValueAccessor(ValueAccessor *accessor, - const attribute_id attr_id) const override { - return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter( - accessor, - [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11) - return impl_.applyToValueAccessor(accessor, attr_id); - }); - } - - private: - using ArgumentType = typename FunctorT::ArgumentType; - using ResultType = typename FunctorT::ResultType; - - using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type; - using ArgumentGen = OperationCodegen<FuncSpec, ArgumentType>; - using ResultGen = OperationCodegen<FuncSpec, ResultType>; - - template <bool argument_nullable> - struct Implementation; - - const FunctorT functor_; - const Implementation<true> impl_; - - DISALLOW_COPY_AND_ASSIGN(UncheckedUnaryOperatorWrapperCodegen); -}; - -template <typename FunctorT, typename ...SpecArgs> -template <bool argument_nullable> -struct UncheckedUnaryOperatorWrapperCodegen<FunctorT, SpecArgs...> - ::Implementation { - Implementation(const FunctorT &functor_in, - const Type &argument_type_in, - const Type &result_type_in) - : functor(functor_in), - argument_type(argument_type_in), - result_type(result_type_in) {} - - inline TypedValue applyToTypedValue(const TypedValue &argument) const { - if (argument_nullable && argument.isNull()) { - return TypedValue(ResultType::kStaticTypeID); - } - - return ResultGen::template ApplyUnaryTypedValue<ArgumentGen>( - ArgumentGen::ToNativeValueConst(argument), - result_type, - functor); - } - - template <typename AccessorT> - inline ColumnVector* applyToValueAccessor(AccessorT *accessor, - const attribute_id attr_id) const { - using ResultCVT = typename ResultGen::ColumnVectorType; - ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples()); - - accessor->beginIteration(); - while (accessor->next()) { - typename ArgumentGen::NativeTypeConstPtr arg_value = - ArgumentGen::template GetValuePtr< - argument_nullable, AccessorT>(accessor, attr_id); - - if (argument_nullable && ArgumentGen::IsNull(arg_value)) { - result_cv->appendNullValue(); - } else { - ResultGen::template ApplyUnaryColumnVector<ArgumentGen>( - ArgumentGen::Dereference(arg_value), functor, result_cv); - } - } - return result_cv; - } - - const FunctorT &functor; - const Type &argument_type; - const Type &result_type; -}; - -template <typename FunctorT> -class UnaryOperationWrapper : public UnaryOperation { - public: - UnaryOperationWrapper() - : UnaryOperation(), - operation_name_(FunctorT::GetName()) {} - - std::string getName() const override { - return operation_name_; - } - - std::string getShortName() const override { - return getName(); - } - - std::vector<OperationSignaturePtr> getSignatures() const override { - return { - OperationSignature::Create(getName(), {ArgumentType::kStaticTypeID}, 0) - }; - } - - bool canApplyTo(const Type &argument_type, - const std::vector<TypedValue> &static_arguments, - std::string *message) const override { - DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID); - DCHECK(static_arguments.empty()); - return true; - } - - const Type* getResultType( - const Type &argument_type, - const std::vector<TypedValue> &static_arguments) const override { - DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID); - DCHECK(static_arguments.empty()); - return getResultTypeImpl<ResultType::kIsParPod>( - argument_type, static_arguments); - } - - UncheckedUnaryOperator* makeUncheckedUnaryOperator( - const Type &argument_type, - const std::vector<TypedValue> &static_arguments) const override { - DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID); - DCHECK(static_arguments.empty()); - return makeUncheckedUnaryOperatorImpl< - std::is_default_constructible<FunctorT>::value>( - argument_type, static_arguments); - } - - private: - using ArgumentType = typename FunctorT::ArgumentType; - using ResultType = typename FunctorT::ResultType; - - template <bool functor_use_default_constructor> - inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl( - const Type &argument_type, - const std::vector<TypedValue> &static_arguments, - std::enable_if_t<functor_use_default_constructor>* = 0) const { - return new UncheckedUnaryOperatorWrapperCodegen<FunctorT>( - argument_type, *getResultType(argument_type, static_arguments)); - } - - template <bool functor_use_default_constructor> - inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl( - const Type &argument_type, - const std::vector<TypedValue> &static_arguments, - std::enable_if_t<!functor_use_default_constructor>* = 0) const { - return new UncheckedUnaryOperatorWrapperCodegen<FunctorT>( - argument_type, *getResultType(argument_type, static_arguments), - static_cast<const ArgumentType&>(argument_type)); - } - - template <bool result_type_has_parameter> - inline const Type* getResultTypeImpl( - const Type &argument_type, - const std::vector<TypedValue> &static_arguments, - std::enable_if_t<!result_type_has_parameter>* = 0) const { - return &TypeFactory::GetType(ResultType::kStaticTypeID, - argument_type.isNullable()); - } - - template <bool result_type_has_parameter> - inline const Type* getResultTypeImpl( - const Type &argument_type, - const std::vector<TypedValue> &static_arguments, - std::enable_if_t<result_type_has_parameter>* = 0) const { - return FunctorT::GetResultType(argument_type); - } - - const std::string operation_name_; - - DISALLOW_COPY_AND_ASSIGN(UnaryOperationWrapper); -}; - -/** @} */ - -} // namespace quickstep - -#endif // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/utility/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/types/operations/utility/CMakeLists.txt b/types/operations/utility/CMakeLists.txt index 89b1dc6..4f57387 100644 --- a/types/operations/utility/CMakeLists.txt +++ b/types/operations/utility/CMakeLists.txt @@ -23,12 +23,19 @@ add_library(quickstep_types_operations_utility_OperationSynthesizeUtil # Link dependencies: target_link_libraries(quickstep_types_operations_utility_CastUtil - glog) + quickstep_types_TypeID + quickstep_types_TypeRegistrar + quickstep_types_operations_unaryoperations_CastFunctorOverloads + quickstep_utility_Macros + quickstep_utility_meta_Common + quickstep_utility_meta_TypeList) target_link_libraries(quickstep_types_operations_utility_OperationSynthesizeUtil quickstep_catalog_CatalogTypedefs quickstep_types_Type quickstep_types_TypedValue - quickstep_types_containers_ColumnVector) + quickstep_types_containers_ColumnVector + quickstep_utility_Macros + quickstep_utility_meta_TypeList) # Module all-in-one library: add_library(quickstep_types_operations_utility ../../../empty_src.cpp) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/utility/CastUtil.cpp ---------------------------------------------------------------------- diff --git a/types/operations/utility/CastUtil.cpp b/types/operations/utility/CastUtil.cpp index e69de29..697a9c0 100644 --- a/types/operations/utility/CastUtil.cpp +++ b/types/operations/utility/CastUtil.cpp @@ -0,0 +1,66 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + **/ + +#include "types/operations/utility/CastUtil.hpp" + +#include <vector> + +#include "types/TypeID.hpp" +#include "types/TypeRegistrar.hpp" +#include "types/TypeUtil.hpp" +#include "types/operations/unary_operations/CastFunctorOverloads.hpp" +#include "utility/meta/Common.hpp" +#include "utility/meta/TypeList.hpp" + +namespace quickstep { + +namespace { + +template <typename T> +struct GetTypeClass { + using type = typename TypeIDTrait<T::value>::TypeClass; +}; + +template <typename TL> +struct HasCast : meta::IsCompleteType< + CastFunctor<typename TL::template at<0>, typename TL::template at<1>>> {}; + +template <typename TL> +struct GetSourceTypeID { + inline TypeID operator()() const { + return TL::head::kStaticTypeID; + } +}; + +} // namespace + +std::vector<TypeID> CastUtil::GetCoercibleSourceTypeIDs(const TypeID target_type_id) { + return InvokeOnTypeID( + target_type_id, + [](auto tid) -> std::vector<TypeID> { + using TargetType = typename TypeIDTrait<decltype(tid)::value>::TypeClass; + return TypeIDSequenceAll::template bind_to<meta::TypeList> + ::template map<GetTypeClass> + ::template cartesian_product<meta::TypeList<TargetType>> + ::template filter<HasCast> + ::template Instantiate<std::vector<TypeID>, GetSourceTypeID>(); + }); +} + +} // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/utility/CastUtil.hpp ---------------------------------------------------------------------- diff --git a/types/operations/utility/CastUtil.hpp b/types/operations/utility/CastUtil.hpp index e69de29..e45b06e 100644 --- a/types/operations/utility/CastUtil.hpp +++ b/types/operations/utility/CastUtil.hpp @@ -0,0 +1,50 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + **/ + +#ifndef QUICKSTEP_TYPES_OPERATIONS_UTILITY_CAST_UTIL_HPP_ +#define QUICKSTEP_TYPES_OPERATIONS_UTILITY_CAST_UTIL_HPP_ + +#include <type_traits> +#include <vector> + +#include "types/TypeID.hpp" +#include "utility/Macros.hpp" + +namespace quickstep { + +/** \addtogroup Types + * @{ + */ + +class CastUtil { + public: + static std::vector<TypeID> GetCoercibleSourceTypeIDs(const TypeID target_type_id); + + + private: + CastUtil() {} + + DISALLOW_COPY_AND_ASSIGN(CastUtil); +}; + +/** @} */ + +} // namespace quickstep + +#endif // QUICKSTEP_TYPES_OPERATIONS_UTILITY_CAST_UTIL_HPP_ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/utility/OperationSynthesizeUtil.hpp ---------------------------------------------------------------------- diff --git a/types/operations/utility/OperationSynthesizeUtil.hpp b/types/operations/utility/OperationSynthesizeUtil.hpp index 2b910b3..50a5863 100644 --- a/types/operations/utility/OperationSynthesizeUtil.hpp +++ b/types/operations/utility/OperationSynthesizeUtil.hpp @@ -17,11 +17,12 @@ * under the License. **/ -#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_ -#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_ +#ifndef QUICKSTEP_TYPES_OPERATIONS_UTILITY_OPERATION_SYNTHESIZE_UTIL_HPP_ +#define QUICKSTEP_TYPES_OPERATIONS_UTILITY_OPERATION_SYNTHESIZE_UTIL_HPP_ #include <cstddef> #include <list> +#include <memory> #include <string> #include <type_traits> @@ -29,6 +30,8 @@ #include "types/Type.hpp" #include "types/TypedValue.hpp" #include "types/containers/ColumnVector.hpp" +#include "utility/Macros.hpp" +#include "utility/meta/TypeList.hpp" namespace quickstep { @@ -68,35 +71,48 @@ struct FunctorSpecializer<FunctorT, SpecArgs...> }; template <typename ColumnVectorT> -struct ColumnVectorValueAccessor { - explicit ColumnVectorValueAccessor(const ColumnVectorT &column_vector_in) - : column_vector(column_vector_in), - length(column_vector.size()) {} +class ColumnVectorAccessor { + public: + constexpr static bool kIsGenericColumnVectorAccessor = + (ColumnVectorT::kImplementation == ColumnVector::kGeneric); + + inline explicit ColumnVectorAccessor(const ColumnVectorT &column_vector) + : column_vector_(column_vector), + length_(column_vector.size()) {} inline void beginIteration() { - pos = static_cast<std::size_t>(-1); + pos_ = static_cast<std::size_t>(-1); } inline bool next() { - return (++pos) < length; + return (++pos_) < length_; } inline std::size_t getNumTuples() const { - return length; + return length_; } - template <bool nullable> + template <bool check_null> inline const void* getUntypedValue(const attribute_id) const { - return column_vector.template getUntypedValue<nullable>(pos); + return column_vector_.template getUntypedValue<check_null>(pos_); } inline TypedValue getTypedValue(const attribute_id) const { - return column_vector.getTypedValue(pos); + return column_vector_.getTypedValue(pos_); + } + + template <bool check_null, bool generic> + inline typename std::enable_if_t<generic, ColumnVectorT>::cpptype + getLiteralValue() const { + return column_vector_.template getLiteralValue<check_null>(pos_); } - const ColumnVectorT &column_vector; - const std::size_t length; - std::size_t pos; + private: + const ColumnVectorT &column_vector_; + const std::size_t length_; + std::size_t pos_; + + DISALLOW_COPY_AND_ASSIGN(ColumnVectorAccessor); }; template <typename FuncSpec, typename T, typename EnableT = void> @@ -105,11 +121,12 @@ struct OperationCodegen; template <typename FuncSpec, typename T> struct OperationCodegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kCxxInlinePod>> { + using ValueType = T; using ColumnVectorType = NativeColumnVector; using FunctorSpecializer = FuncSpec; using NativeType = typename T::cpptype; - using NativeTypeConst = const typename T::cpptype; + using NativeTypeConst = const NativeType; using NativeTypeConstRef = const NativeType&; using NativeTypeConstPtr = const NativeType*; @@ -151,7 +168,8 @@ struct OperationCodegen<FuncSpec, T, template <bool nullable, typename AccessorT> inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor, - const attribute_id attr_id) { + const attribute_id attr_id, + const Type &, void *) { return static_cast<NativeTypeConstPtr>( accessor->template getUntypedValue<nullable>(attr_id)); } @@ -165,7 +183,8 @@ struct OperationCodegen<FuncSpec, T, return *value; } - inline static const NativeType ToNativeValueConst(const TypedValue &value) { + inline static const NativeType ToNativeValueConst(const TypedValue &value, + const Type &) { return value.getLiteral<NativeType>(); } }; @@ -173,6 +192,7 @@ struct OperationCodegen<FuncSpec, T, template <typename FuncSpec, typename T> struct OperationCodegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kParInlinePod>> { + using ValueType = T; using ColumnVectorType = NativeColumnVector; using FunctorSpecializer = FuncSpec; @@ -223,9 +243,11 @@ struct OperationCodegen<FuncSpec, T, FuncSpec::Invoke(functor, left, right, cv->getPtrForDirectWrite()); } + // TODO(refactor-type): Use ColumnAccessor to improve performance. template <bool nullable, typename AccessorT> inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor, - const attribute_id attr_id) { + const attribute_id attr_id, + const Type &, void *) { return accessor->template getUntypedValue<nullable>(attr_id); } @@ -238,7 +260,8 @@ struct OperationCodegen<FuncSpec, T, return value; } - inline static const void* ToNativeValueConst(const TypedValue &value) { + inline static const void* ToNativeValueConst(const TypedValue &value, + const Type &) { return value.getDataPtr(); } }; @@ -246,6 +269,7 @@ struct OperationCodegen<FuncSpec, T, template <typename FuncSpec, typename T> struct OperationCodegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kParOutOfLinePod>> { + using ValueType = T; using ColumnVectorType = IndirectColumnVector; using FunctorSpecializer = FuncSpec; @@ -289,9 +313,9 @@ struct OperationCodegen<FuncSpec, T, } template <bool nullable, typename AccessorT> - inline static NativeTypeConstPtr GetValuePtr( - const AccessorT *accessor, - const attribute_id attr_id) { + inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor, + const attribute_id attr_id, + const Type &, void *) { return accessor->getTypedValue(attr_id); } @@ -304,11 +328,121 @@ struct OperationCodegen<FuncSpec, T, return value; } - inline static const NativeType& ToNativeValueConst(const TypedValue &value) { + inline static const NativeType& ToNativeValueConst(const TypedValue &value, + const Type &) { return value; } }; + +// TODO(refactor-type): Remove this. +namespace internal { + +template <typename T> +std::enable_if_t<T::kIsGenericColumnVectorAccessor, + std::true_type> IsGenericColumnVectorAccessorImpl(int); +template <typename> +std::false_type IsGenericColumnVectorAccessorImpl(...); + +} // namespace internal + +template <typename T> +using IsGenericColumnVectorAccessor = + decltype(internal::IsGenericColumnVectorAccessorImpl<T>()); + +template <typename FuncSpec, typename T> +struct OperationCodegen<FuncSpec, T, + std::enable_if_t<T::kMemoryLayout == kCxxGeneric>> { + using ValueType = T; + using ColumnVectorType = GenericColumnVector<T>; + using FunctorSpecializer = FuncSpec; + + using NativeType = typename T::cpptype; + using NativeTypeConst = const NativeType; + using NativeTypeConstRef = const NativeType&; + using NativeTypeConstPtr = const NativeType*; + + template <typename ArgumentGen, typename ResultType> + inline static TypedValue ApplyUnaryTypedValue( + typename ArgumentGen::NativeTypeConstRef argument, + const ResultType &result_type, + const typename FuncSpec::FunctorType &functor) { + const NativeType result = FuncSpec::Invoke(functor, argument); + return result_type.marshallValue(&result); + } + + template <typename ArgumentGen> + inline static void ApplyUnaryColumnVector( + const typename ArgumentGen::NativeTypeConstRef argument, + const typename FuncSpec::FunctorType &functor, + ColumnVectorType *cv) { + cv->appendLiteralValue(FuncSpec::Invoke(functor, argument)); + } + + template <typename LeftGen, typename RightGen, typename ResultType> + inline static TypedValue ApplyBinaryTypedValue( + typename LeftGen::NativeTypeConstRef left, + typename RightGen::NativeTypeConstRef right, + const ResultType &result_type, + const typename FuncSpec::FunctorType &functor) { + const NativeType result = FuncSpec::Invoke(functor, left, right); + return result_type.marshallValue(&result); + } + + template <typename LeftGen, typename RightGen> + inline static void ApplyBinaryColumnVector( + const typename LeftGen::NativeTypeConstRef left, + const typename RightGen::NativeTypeConstRef right, + const typename FuncSpec::FunctorType &functor, + ColumnVectorType *cv) { + cv->appendLiteralValue(FuncSpec::Invoke(functor, left, right)); + } + + // TODO(refactor-type): Use ColumnAccessor to handle the more general case. + template <bool nullable, typename AccessorT> + inline static NativeTypeConstPtr GetValuePtr( + const AccessorT *accessor, + const attribute_id attr_id, + const Type &, void *, + std::enable_if_t<IsGenericColumnVectorAccessor<AccessorT>::value> * = 0) { + return &accessor->template getLiteralValue<nullable, true>(); + } + + // TODO(refactor-type): Use ColumnAccessor to handle the more general case. + template <bool nullable, typename AccessorT> + inline static NativeTypeConstPtr GetValuePtr( + const AccessorT *accessor, + const attribute_id attr_id, + const ValueType &value_type, + std::unique_ptr<NativeType> *cache, + std::enable_if_t<!IsGenericColumnVectorAccessor<AccessorT>::value> * = 0) { + static_assert(std::is_same<NativeType, typename ValueType::cpptype>::value, + "Unexpected value type in OperationCodegen::GetValuePtr for " + "CxxGeneric types."); + cache->reset(static_cast<NativeType*>( + value_type.unmarshallTypedValue(accessor->getTypedValue(attr_id)))); + return cache->get(); + } + + inline static bool IsNull(NativeTypeConstPtr &value) { + return value == nullptr; + } + + // Dereference: NativeTypeConstPtr& -> const NativeType& + inline static const NativeType& Dereference(NativeTypeConstPtr &value) { + return *value; + } + + inline static const NativeType ToNativeValueConst(const TypedValue &value, + const ValueType &value_type) { + // TODO(refactor-type): Improve performance. + std::unique_ptr<NativeType> cache( + static_cast<NativeType*>(value_type.unmarshallTypedValue(value))); + return *cache; + } +}; + + template <typename ...FunctorTypes> struct FunctorPack { template <typename Dispatcher> @@ -332,4 +466,4 @@ struct OperationPack { } // namespace quickstep -#endif // QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_ +#endif // QUICKSTEP_TYPES_OPERATIONS_OPERATION_UTILITY_SYNTHESIZE_UTIL_HPP_ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/utility/Cast.hpp ---------------------------------------------------------------------- diff --git a/utility/Cast.hpp b/utility/Cast.hpp index 7d2a8c0..88bdc72 100644 --- a/utility/Cast.hpp +++ b/utility/Cast.hpp @@ -36,7 +36,7 @@ namespace quickstep { * @param source_ptrs The vector of shared_ptr objects to be casted. * @return target_ptrs The casted vector of shared_ptr with pointers of type const TargetType. */ -template<class TargetType, class SourceType> +template <class TargetType, class SourceType> static std::vector<std::shared_ptr<const TargetType>> CastSharedPtrVector( const std::vector<std::shared_ptr<const SourceType>> &source_ptrs) { std::vector<std::shared_ptr<const TargetType>> target_ptrs; @@ -46,6 +46,11 @@ static std::vector<std::shared_ptr<const TargetType>> CastSharedPtrVector( return target_ptrs; } +template <class TargetContainer, class SourceContainer> +static TargetContainer CastSTLContainer(const SourceContainer &source_container) { + return TargetContainer(source_container.begin(), source_container.end()); +} + /** @} */ } // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/utility/meta/Common.hpp ---------------------------------------------------------------------- diff --git a/utility/meta/Common.hpp b/utility/meta/Common.hpp index cbad665..bc259da 100644 --- a/utility/meta/Common.hpp +++ b/utility/meta/Common.hpp @@ -58,8 +58,8 @@ struct Sequence { using contains = EqualsAny<std::integral_constant<T, v>, std::integral_constant<T, s>...>; - template <typename CollectionT> - inline static CollectionT Instantiate() { + template <typename Collection> + inline static Collection Instantiate() { return { s... }; } }; @@ -168,6 +168,22 @@ template <> struct UnsignedInteger<8u> { using type = std::uint64_t; }; + +//// ---------------------------------------------------------------------------- +//// Macros. + +#define QUICKSTEP_TRAIT_HAS_STATIC_METHOD(traitname, methodname) \ + template <typename C> \ + class traitname { \ + private: \ + template <typename T> \ + static std::true_type Impl(int, decltype(T::methodname) * = 0); \ + template <typename T> \ + static std::false_type Impl(...); \ + public: \ + static constexpr bool value = decltype(Impl<C>(0))::value; \ + } + /** @} */ } // namespace meta http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/utility/meta/TypeList.hpp ---------------------------------------------------------------------- diff --git a/utility/meta/TypeList.hpp b/utility/meta/TypeList.hpp index 5f4c4d9..47b03c8 100644 --- a/utility/meta/TypeList.hpp +++ b/utility/meta/TypeList.hpp @@ -31,25 +31,22 @@ namespace meta { */ template <typename ...Ts> -class TypeList; +struct TypeList; namespace internal { using EmptyList = TypeList<>; template <typename ...Ts> -class TypeListBase { - private: - template <typename ...Tail> struct AppendHelper { - using type = TypeList<Ts..., Tail...>; - }; - - public: +struct TypeListBase { static constexpr std::size_t length = sizeof...(Ts); using type = TypeList<Ts...>; using self = type; + // --------------------------------------------------------------------------- + // Meta-methods. + template <template <typename ...> class Host> using bind_to = Host<Ts...>; @@ -76,7 +73,7 @@ class TypeListBase { using unique = typename UniqueImpl<EmptyList, self, DumbT...>::type; template <typename TL> - using append = typename TL::template bind_to<AppendHelper>::type; + using append = typename AppendImpl<self, TL>::type; template <typename TL> using cartesian_product = typename CartesianProductImpl<self, TL>::type; @@ -113,19 +110,32 @@ class TypeListBase { template <typename T> using as_sequence = typename AsSequenceImpl<T, Ts...>::type; + + // --------------------------------------------------------------------------- + // Methods. + + template <typename Collection, typename Instantiator> + static Collection Instantiate(const Instantiator &functor) { + return { functor(Ts())... }; + } + + template <typename Collection, template <typename ...> class Instantiator> + static Collection Instantiate() { + return { Instantiator<Ts>()()... }; + } }; } // namespace internal template <typename T, typename ...Ts> -class TypeList<T, Ts...> : public internal::TypeListBase<T, Ts...> { +struct TypeList<T, Ts...> : public internal::TypeListBase<T, Ts...> { public: using head = T; using tail = TypeList<Ts...>; }; template <> -class TypeList<> : public internal::TypeListBase<> {}; +struct TypeList<> : public internal::TypeListBase<> {}; /** @} */ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/utility/meta/TypeListMetaFunctions.hpp ---------------------------------------------------------------------- diff --git a/utility/meta/TypeListMetaFunctions.hpp b/utility/meta/TypeListMetaFunctions.hpp index baebe91..ba3a419 100644 --- a/utility/meta/TypeListMetaFunctions.hpp +++ b/utility/meta/TypeListMetaFunctions.hpp @@ -30,7 +30,7 @@ namespace meta { */ template <typename ...Ts> -class TypeList; +struct TypeList; template <typename T> @@ -112,6 +112,15 @@ struct UniqueImpl<Out, Rest, typename Rest::tail> {}; +template <typename TL, typename UL> +struct AppendImpl; + +template <typename ...Ts, typename ...Us> +struct AppendImpl<meta::TypeList<Ts...>, meta::TypeList<Us...>> { + using type = meta::TypeList<Ts..., Us...>; +}; + + template <typename Out, typename Rest, typename Subtrahend, typename Enable = void> struct SubtractImpl;
