Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id CDC8A200C78 for ; Wed, 12 Apr 2017 21:34:27 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id CC2A0160BA8; Wed, 12 Apr 2017 19:34:27 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 42613160B95 for ; Wed, 12 Apr 2017 21:34:25 +0200 (CEST) Received: (qmail 11350 invoked by uid 500); 12 Apr 2017 19:34:24 -0000 Mailing-List: contact commits-help@quickstep.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@quickstep.incubator.apache.org Delivered-To: mailing list commits@quickstep.incubator.apache.org Received: (qmail 11295 invoked by uid 99); 12 Apr 2017 19:34:23 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 12 Apr 2017 19:34:23 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id 9924CC1812 for ; Wed, 12 Apr 2017 19:34:22 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.212 X-Spam-Level: X-Spam-Status: No, score=-4.212 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001, T_FILL_THIS_FORM_SHORT=0.01] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id 076Jvjm3ZUmk for ; Wed, 12 Apr 2017 19:34:10 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with SMTP id 06F365FE64 for ; Wed, 12 Apr 2017 19:34:05 +0000 (UTC) Received: (qmail 9669 invoked by uid 99); 12 Apr 2017 19:34:05 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 12 Apr 2017 19:34:05 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 170EAE9687; Wed, 12 Apr 2017 19:34:05 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jianqiao@apache.org To: commits@quickstep.incubator.apache.org Date: Wed, 12 Apr 2017 19:34:19 -0000 Message-Id: In-Reply-To: <891420e3e4274aaeb9faea9d2e2dc5d6@git.apache.org> References: <891420e3e4274aaeb9faea9d2e2dc5d6@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [16/27] incubator-quickstep git commit: Refactor type system and operations. archived-at: Wed, 12 Apr 2017 19:34:28 -0000 http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/SubstringOperation.cpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/SubstringOperation.cpp b/types/operations/unary_operations/SubstringOperation.cpp index 84f1c8d..1cc8912 100644 --- a/types/operations/unary_operations/SubstringOperation.cpp +++ b/types/operations/unary_operations/SubstringOperation.cpp @@ -19,198 +19,48 @@ #include "types/operations/unary_operations/SubstringOperation.hpp" -#include -#include -#include +#include #include -#include "catalog/CatalogTypedefs.hpp" -#include "storage/ValueAccessor.hpp" -#include "storage/ValueAccessorUtil.hpp" #include "types/Type.hpp" #include "types/TypeID.hpp" #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" +#include "utility/meta/Dispatchers.hpp" #include "glog/logging.h" 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 &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(type).getStringLength(); + type.getTypeID() == kChar + ? static_cast(type).getStringLength() + : static_cast(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( - std::forward_as_tuple(start_position_, - computeMaximumSubstringLength(type), - input_maximum_length, - *result_type), - input_null_terminated, type.isNullable()); -} - -template -inline void SubstringUncheckedOperator - ::computeSubstring(const char *input, - char *output) const { - std::size_t string_length = - (null_terminated ? strlen(input) : strnlen(input, maximum_input_length_)); - - if (start_position_ >= string_length) { - *output = '\0'; - return; - } - - const std::size_t actual_substring_length = - std::min(string_length - start_position_, substring_length_); - std::memcpy(output, input + start_position_, actual_substring_length); - - if (actual_substring_length < substring_length_) { - output[actual_substring_length] = '\0'; - } -} - -template -TypedValue SubstringUncheckedOperator - ::applyToTypedValue(const TypedValue& argument) const { - if (input_nullable && argument.isNull()) { - return TypedValue(result_type_.getTypeID()); - } - - char *output_ptr = static_cast(std::malloc(substring_length_)); - computeSubstring(static_cast(argument.getOutOfLineData()), - output_ptr); - - return TypedValue::CreateWithOwnedData(result_type_.getTypeID(), - output_ptr, - substring_length_); -} - -template -TypedValue SubstringUncheckedOperator - ::applyToDataPtr(const void *argument) const { - if (input_nullable && argument == nullptr) { - return TypedValue(result_type_.getTypeID()); - } - - char *output_ptr = static_cast(std::malloc(substring_length_)); - computeSubstring(static_cast(argument), - output_ptr); - - return TypedValue::CreateWithOwnedData(result_type_.getTypeID(), - output_ptr, - substring_length_); -} - -template -ColumnVector* SubstringUncheckedOperator - ::applyToColumnVector(const ColumnVector &argument) const { - return InvokeOnColumnVector( - argument, - [&](const auto &column_vector) -> ColumnVector* { // NOLINT(build/c++11) - NativeColumnVector *result = - new NativeColumnVector(result_type_, column_vector.size()); - - for (std::size_t cv_pos = 0; - cv_pos < column_vector.size(); - ++cv_pos) { - const char *input_ptr = static_cast( - column_vector.template getUntypedValue(cv_pos)); - - if (input_nullable && input_ptr == nullptr) { - result->appendNullValue(); - } else { - this->computeSubstring(input_ptr, - static_cast(result->getPtrForDirectWrite())); - } - } - return result; - }); -} - -#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION -template -ColumnVector* SubstringUncheckedOperator - ::applyToValueAccessor(ValueAccessor *accessor, - const attribute_id argument_attr_id) const { - return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter( - accessor, - [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11) - NativeColumnVector *result = - new NativeColumnVector(result_type_, accessor->getNumTuples()); - - accessor->beginIteration(); - while (accessor->next()) { - const char *input_ptr = static_cast( - accessor->template getUntypedValue(argument_attr_id)); - - if (input_nullable && (input_ptr == nullptr)) { - result->appendNullValue(); - } else { - this->computeSubstring(input_ptr, - static_cast(result->getPtrForDirectWrite())); - } - } - return result; - }); -} -#endif - -#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN -template -ColumnVector* SubstringUncheckedOperator - ::applyToValueAccessorForJoin( - ValueAccessor *accessor, - const bool use_left_relation, - const attribute_id argument_attr_id, - const std::vector> &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 &joined_pair : joined_tuple_ids) { - const char *input_ptr = static_cast( - accessor->template getUntypedValueAtAbsolutePosition( - 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(result->getPtrForDirectWrite())); - } - } - return result; + return meta::InvokeOnBools( + input_null_terminated, type.isNullable(), + [&](auto is_null_terminated, // NOLINT(build/c++11) + auto is_nullable) -> UncheckedUnaryOperator* { + return new SubstringUncheckedOperator< + decltype(is_null_terminated)::value, + decltype(is_nullable)::value>( + start_position, + ComputeMaximumSubstringLength(type, start_position, substring_length), + input_maximum_length, + *result_type); }); } -#endif } // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/SubstringOperation.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/SubstringOperation.hpp b/types/operations/unary_operations/SubstringOperation.hpp index 66f311f..afaf74d 100644 --- a/types/operations/unary_operations/SubstringOperation.hpp +++ b/types/operations/unary_operations/SubstringOperation.hpp @@ -22,22 +22,27 @@ #include #include +#include #include #include +#include #include -#include #include #include #include "catalog/CatalogTypedefs.hpp" +#include "storage/ValueAccessor.hpp" +#include "storage/ValueAccessorUtil.hpp" +#include "types/CharType.hpp" #include "types/Type.hpp" #include "types/TypeFactory.hpp" #include "types/TypeID.hpp" #include "types/TypedValue.hpp" -#include "types/operations/Operation.pb.h" +#include "types/VarCharType.hpp" +#include "types/containers/ColumnVector.hpp" +#include "types/containers/ColumnVectorUtil.hpp" #include "types/operations/unary_operations/UnaryOperation.hpp" -#include "types/operations/unary_operations/UnaryOperationID.hpp" -#include "utility/HashPair.hpp" +#include "types/port/strnlen.hpp" #include "utility/Macros.hpp" #include "glog/logging.h" @@ -53,116 +58,81 @@ class ValueAccessor; */ class SubstringOperation : public UnaryOperation { public: - /** - * @brief Get a reference to the singleton instance of this Operation for - * the given (start_position, substring_length) pair. - **/ - static const SubstringOperation& Instance(const std::size_t start_position, - const std::size_t substring_length) { - // TODO(jianqiao): This is a temporary solution that creates a new instance - // for each distinct pair of start_position and substring_length arguments. - // The number of instances may be unbounded if quickstep continuously accepts - // queries that call SUBSTRING with different arguments. It still remains to - // design a better long-term solution. - const auto hash = [](const auto &pair) { - return hash_combine_detail::HashCombiner::CombineHashes(pair.first, pair.second); - }; - static std::unordered_map, - std::unique_ptr, - decltype(hash)> instance_map(10, hash); - - const std::pair key_pair = - std::make_pair(start_position, substring_length); - auto imit = instance_map.find(key_pair); - if (imit != instance_map.end()) { - return *imit->second; - } else { - const SubstringOperation *instance = - new SubstringOperation(start_position, substring_length); - instance_map.emplace(key_pair, - std::unique_ptr(instance)); - return *instance; - } - } - - serialization::UnaryOperation getProto() const override; + SubstringOperation() {} - bool canApplyToType(const Type &type) const override { - return (type.getSuperTypeID() == Type::kAsciiString); + std::string getName() const override { + return "Substring"; } - const Type *resultTypeForArgumentType(const Type &type) const override { - if (type.getSuperTypeID() == Type::kAsciiString) { - // Result is a Char string. - return &TypeFactory::GetType(TypeID::kChar, - computeMaximumSubstringLength(type), - type.isNullable()); - } - return nullptr; + std::string getShortName() const override { + return "Substring"; } - const Type* fixedNullableResultType() const override { - // Result type is not fixed (i.e. can have various lengths). - return nullptr; + std::vector getSignatures() const override { + return { + OperationSignature::Create(getName(), {kChar}, {kLong, kLong}), + OperationSignature::Create(getName(), {kVarChar}, {kLong, kLong}) + }; } - bool resultTypeIsPlausible(const Type &result_type) const override { - // Result can be coerced to Char or VarChar. - return (result_type.getSuperTypeID() == Type::kAsciiString); - } + bool canApplyTo(const Type &type, + const std::vector &static_arguments, + std::string *message) const override { + DCHECK(type.getTypeID() == kChar || type.getTypeID() == kVarChar); + DCHECK(!static_arguments.empty() && static_arguments[0].getTypeID() == kLong); + DCHECK(static_arguments.size() <= 2); - const Type* pushDownTypeHint(const Type *type_hint) const override { - // Input can only be a string, but we don't know the length. - return nullptr; - } + if (static_arguments[0].getLiteral() <= 0) { + *message = "The start position must be greater than 0"; + return false; + } - TypedValue applyToChecked(const TypedValue &argument, - const Type &argument_type) const override { - DCHECK(canApplyToType(argument_type)); + if (static_arguments.size() == 2) { + DCHECK(static_arguments[1].getTypeID() == kLong); + if (static_arguments[1].getLiteral() <= 0) { + *message = "The substring length must be greater than 0"; + return false; + } + } - const Type *result_type = resultTypeForArgumentType(argument_type); - DCHECK(result_type != nullptr); + return true; + } - if (argument_type.isNullable() && argument.isNull()) { - return result_type->makeNullValue(); - } else { - const std::size_t result_length = computeMaximumSubstringLength(argument_type); - char *output_ptr = static_cast(std::malloc(result_length)); - const char *input_ptr = static_cast(argument.getOutOfLineData()); + const Type* getResultType( + const Type &type, + const std::vector &static_arguments) const override { + DCHECK(UnaryOperation::canApplyTo(type, static_arguments)); - const std::size_t string_length = argument.getAsciiStringLength(); - if (start_position_ >= string_length) { - *output_ptr = '\0'; - } else { - const std::size_t actual_substring_length = - std::min(string_length - start_position_, substring_length_); - std::memcpy(output_ptr, input_ptr + start_position_, actual_substring_length); - if (actual_substring_length < result_length) { - output_ptr[actual_substring_length] = '\0'; - } - } + std::size_t start_position; + std::size_t substring_length; + ExtractStaticArguments(static_arguments, &start_position, &substring_length); - return TypedValue::CreateWithOwnedData(result_type->getTypeID(), - output_ptr, - result_length); - } + return &TypeFactory::GetType(TypeID::kChar, + ComputeMaximumSubstringLength(type, start_position, substring_length), + type.isNullable()); } - UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const override; + UncheckedUnaryOperator* makeUncheckedUnaryOperator( + const Type &type, + const std::vector &static_arguments) const override; private: - /** - * @brief Constructor. - * - * @param input_type The data type of the input argument for substring. - * @param start_position The 0-base starting position of the substring. - * @param substring_length The substring length. - */ - SubstringOperation(const std::size_t start_position, - const std::size_t substring_length) - : UnaryOperation(UnaryOperationID::kSubstring), - start_position_(start_position), - substring_length_(substring_length) { + inline static void ExtractStaticArguments( + const std::vector &static_arguments, + std::size_t *start_position, + std::size_t *substring_length) { + DCHECK_LE(1u, static_arguments.size()); + DCHECK_GE(2u, static_arguments.size()); + + DCHECK(static_arguments[0].getTypeID() == kLong); + *start_position = + static_cast(static_arguments[0].getLiteral() - 1); + + DCHECK(static_arguments.size() < 2u || static_arguments[1].getTypeID() == kLong); + *substring_length = + static_arguments.size() < 2u + ? std::numeric_limits::max() + : static_cast(static_arguments[1].getLiteral()); } /** @@ -171,19 +141,23 @@ class SubstringOperation : public UnaryOperation { * * @param type The type of the input, must be either CharType or VarCharType. */ - inline std::size_t computeMaximumSubstringLength(const Type& type) const { - DCHECK(type.getSuperTypeID() == Type::kAsciiString); - - // Substring result should have length no greater than the minimum of - // (1) the input string length subtract the start position, and - // (2) the specified substring length. - return std::min(static_cast(type).getStringLength() - start_position_, - substring_length_); + inline static std::size_t ComputeMaximumSubstringLength( + const Type& type, + const std::size_t start_position, + const std::size_t substring_length) { + DCHECK(type.getTypeID() == kChar || type.getTypeID() == kVarChar); + + const std::size_t input_maximum_length = + type.getTypeID() == kChar + ? static_cast(type).getStringLength() + : static_cast(type).getStringLength(); + + // Substring result should have length no greater than the minimum of + // (1) the input string length subtract the start position, and + // (2) the specified substring length. + return std::min(input_maximum_length - start_position, substring_length); } - const std::size_t start_position_; - const std::size_t substring_length_; - private: DISALLOW_COPY_AND_ASSIGN(SubstringOperation); }; @@ -203,8 +177,6 @@ class SubstringUncheckedOperator : public 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 @@ -231,6 +203,100 @@ class SubstringUncheckedOperator : public UncheckedUnaryOperator { DISALLOW_COPY_AND_ASSIGN(SubstringUncheckedOperator); }; +template +inline void SubstringUncheckedOperator + ::computeSubstring(const char *input, + char *output) const { + std::size_t string_length = + (null_terminated ? strlen(input) : strnlen(input, maximum_input_length_)); + + if (start_position_ >= string_length) { + *output = '\0'; + return; + } + + const std::size_t actual_substring_length = + std::min(string_length - start_position_, substring_length_); + std::memcpy(output, input + start_position_, actual_substring_length); + + if (actual_substring_length < substring_length_) { + output[actual_substring_length] = '\0'; + } +} + +template +TypedValue SubstringUncheckedOperator + ::applyToTypedValue(const TypedValue& argument) const { + if (input_nullable && argument.isNull()) { + return TypedValue(result_type_.getTypeID()); + } + + char *output_ptr = static_cast(std::malloc(substring_length_)); + computeSubstring(static_cast(argument.getOutOfLineData()), + output_ptr); + + return TypedValue::CreateWithOwnedData(result_type_.getTypeID(), + output_ptr, + substring_length_); +} + +template +ColumnVector* SubstringUncheckedOperator + ::applyToColumnVector(const ColumnVector &argument) const { + return InvokeOnColumnVector( + argument, + [&](const auto &column_vector) -> ColumnVector* { // NOLINT(build/c++11) + NativeColumnVector *result = + new NativeColumnVector(result_type_, column_vector.size()); + + for (std::size_t cv_pos = 0; + cv_pos < column_vector.size(); + ++cv_pos) { + const char *input_ptr = static_cast( + column_vector.template getUntypedValue(cv_pos)); + + if (input_nullable && input_ptr == nullptr) { + result->appendNullValue(); + } else { + this->computeSubstring(input_ptr, + static_cast(result->getPtrForDirectWrite())); + } + } + return result; + }); +} + +#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION +template +ColumnVector* SubstringUncheckedOperator + ::applyToValueAccessor(ValueAccessor *accessor, + const attribute_id argument_attr_id) const { + return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter( + accessor, + [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11) + NativeColumnVector *result = + new NativeColumnVector(result_type_, accessor->getNumTuples()); + + accessor->beginIteration(); + while (accessor->next()) { + const char *input_ptr = static_cast( + accessor->template getUntypedValue(argument_attr_id)); + + if (input_nullable && (input_ptr == nullptr)) { + result->appendNullValue(); + } else { + this->computeSubstring(input_ptr, + static_cast(result->getPtrForDirectWrite())); + } + } + return result; + }); +} +#endif + } // namespace quickstep #endif /* QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_SUBSTRING_OPERATION_HPP_ */ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/UnaryOperation.cpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/UnaryOperation.cpp b/types/operations/unary_operations/UnaryOperation.cpp index af150b3..09b27d9 100644 --- a/types/operations/unary_operations/UnaryOperation.cpp +++ b/types/operations/unary_operations/UnaryOperation.cpp @@ -20,28 +20,8 @@ #include "types/operations/unary_operations/UnaryOperation.hpp" #include "types/operations/Operation.pb.h" -#include "types/operations/unary_operations/UnaryOperationID.hpp" #include "utility/Macros.hpp" namespace quickstep { -serialization::UnaryOperation UnaryOperation::getProto() const { - serialization::UnaryOperation proto; - switch (operation_id_) { - case UnaryOperationID::kNegate: - proto.set_operation_id(serialization::UnaryOperation::NEGATE); - break; - case UnaryOperationID::kCast: - FATAL_ERROR("Must use the overridden NumericCastOperation::getProto"); - case UnaryOperationID::kDateExtract: - FATAL_ERROR("Must use the overridden DateExtractOperation::getProto"); - case UnaryOperationID::kSubstring: - FATAL_ERROR("Must use the overridden SubstringOperation::getProto"); - default: - FATAL_ERROR("Unrecognized UnaryOperationID in UnaryOperation::getProto"); - } - - return proto; -} - } // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/UnaryOperation.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/UnaryOperation.hpp b/types/operations/unary_operations/UnaryOperation.hpp index 30a2961..70cb6f9 100644 --- a/types/operations/unary_operations/UnaryOperation.hpp +++ b/types/operations/unary_operations/UnaryOperation.hpp @@ -24,18 +24,10 @@ #include #include -#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN -#include -#include - -#include "storage/StorageBlockInfo.hpp" -#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN - #include "catalog/CatalogTypedefs.hpp" -#include "types/operations/Operation.hpp" -#include "types/operations/Operation.pb.h" #include "types/TypedValue.hpp" -#include "types/operations/unary_operations/UnaryOperationID.hpp" +#include "types/operations/Operation.hpp" +#include "types/operations/OperationSignature.hpp" #include "utility/Macros.hpp" namespace quickstep { @@ -48,6 +40,9 @@ class ValueAccessor; * @{ */ +class UnaryOperation; +typedef std::shared_ptr UnaryOperationPtr; + /** * @brief A unary operator which can be quickly applied to data items WITHOUT * checking their type. @@ -69,14 +64,6 @@ class UncheckedUnaryOperator { virtual TypedValue applyToTypedValue(const TypedValue &argument) const = 0; /** - * @brief Apply to a data item via a pointer without type-checking. - * - * @param argument The data item to apply to. - * @return The literal result of the operation. - **/ - virtual TypedValue applyToDataPtr(const void *argument) const = 0; - - /** * @brief Apply to a vector of values without type-checking. * * @param argument The argument ColumnVector to apply to. @@ -96,27 +83,6 @@ class UncheckedUnaryOperator { const attribute_id argument_attr_id) const = 0; #endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION -#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN - /** - * @brief Apply to an attribute of a list of joined tuples in a - * ValueAccessor. - * - * @param accessor The ValueAccessor to apply to. - * @param use_left_relation If true, this UnaryOperation's argument is - * assumed to be taken from the left relation in the pairs of - * joined_tuple_ids. If false, the right relation. - * @param argument_attr_id The attribute ID of the argument in accessor. - * @param joined_tuple_ids A series of pairs of tuple ids from the left and - * right relations in a join. - * @return A ColumnVector of literal results of the operation. - **/ - virtual ColumnVector* applyToValueAccessorForJoin( - ValueAccessor *accessor, - const bool use_left_relation, - const attribute_id argument_attr_id, - const std::vector> &joined_tuple_ids) const = 0; -#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN - protected: UncheckedUnaryOperator() { } @@ -134,30 +100,11 @@ class UncheckedUnaryOperator { class UnaryOperation : public Operation { public: /** - * @brief Generate a serialized Protocol Buffer representation of - * this UnaryOperation. - * - * @return The serialized Protocol Buffer representation of this UnaryOperation. - **/ - virtual serialization::UnaryOperation getProto() const; - - /** - * @brief Determine the ID of this UnaryOperation. - * - * @return The ID of this UnaryOperation. - **/ - inline UnaryOperationID getUnaryOperationID() const { - return operation_id_; - } - - /** * @brief Get a human-readable name for this UnaryOperation. * * @return A human-readable name for this UnaryOperation. **/ - virtual std::string getName() const { - return kUnaryOperationNames[static_cast(operation_id_)]; - } + virtual std::string getName() const = 0; /** * @brief Get a human-readable short name (e.g. "-") for this UnaryOperation. @@ -165,113 +112,32 @@ class UnaryOperation : public Operation { * @return A human-readable short name for this BinaryOperation. **/ virtual std::string getShortName() const { - return kUnaryOperationShortNames[static_cast(operation_id_)]; + return getName(); } - /** - * @brief Determine whether this UnaryOperation can apply to the specified - * Type. - * - * @param type The argument Type to check. - * @return Whether this UnaryOperation can apply to type. - **/ - virtual bool canApplyToType(const Type &type) const = 0; + virtual bool canApplyTo(const Type &argument_type, + const std::vector &static_arguments, + std::string *message) const = 0; - /** - * @brief Determine the Type of the result from applying this UnaryOperation - * to an argument of the specified Type. - * - * @param type The argument Type to check. - * @return The Type of the result from applying this UnaryOperation to type - * (NULL if not applicable). - **/ - virtual const Type* resultTypeForArgumentType(const Type &type) const = 0; - - /** - * @brief If this UnaryOperation always yields the same Type (or if the ONLY - * difference between 2 possible return Types is nullability), return - * that Type, otherwise return NULL. - * - * @return The nullable version of this UnaryOperation's fixed result Type, - * if applicable. - **/ - virtual const Type* fixedNullableResultType() const = 0; + virtual const Type* getResultType( + const Type &argument_type, + const std::vector &static_arguments) const = 0; - /** - * @brief Check if a particular Type might possibly be returned by this - * UnaryOperation, assuming an appropriate argument type. - * @note A nullable result type may be considered plausible even if a - * particular UnaryOperation never actually returns NULL values, so - * long as the non-nullable version of the type would otherwise be - * plausible. - * - * @param result_type Check whether this Type can possibly be returned by - * this UnaryOperation. - * @return true if result_type can be returned by this UnaryOperation, false - * otherwise. - **/ - virtual bool resultTypeIsPlausible(const Type &result_type) const = 0; + virtual UncheckedUnaryOperator* makeUncheckedUnaryOperator( + const Type &argument_type, + const std::vector &static_arguments) const = 0; - /** - * @brief Get a "hint" Type for the argument to this UnaryOperation based on - * a hint for this UnaryOperation's result type. If possible, returns - * a pointer to a Type that, when given to this UnaryOperation as an - * argument, yields values of the desired type (i.e. calling - * resultTypeForArgumentType() on the returned type should return the - * original type_hint). - * @note In some cases (e.g. NumericCastOperation) there may be multiple - * types that can be used as arguments to this UnaryOperation that will - * all yield the desired type_hint. In such cases, this method will - * pick one Type based on its own implementation-specific preference. - * - * @param type_hint A hint about what Type the result of this UnaryOperation - * should have. May be NULL to indicate no preference. - * @return A type hint for the argument to this UnaryOperation based on - * type_hint, or NULL if no suitable Type exists. - **/ - virtual const Type* pushDownTypeHint(const Type *type_hint) const = 0; - - /** - * @brief Apply this UnaryOperation to a TypedValue. - * @warning It is an error to call this method if this UnaryOperation can not - * be applied to argument_type. If in doubt, check canApplyToType() - * first. - * - * @param argument The TypedValue to apply to. - * @param argument_type The Type that argument belongs to. - * @return The literal result of the operation. - **/ - virtual TypedValue applyToChecked(const TypedValue &argument, - const Type &argument_type) const = 0; - - /** - * @brief Create an UncheckedUnaryOperator which can apply to items of the - * specified type. - * @warning The resulting UncheckedUnaryOperator performs no type-checking - * whatsoever. Nonetheless, it is useful in situations where many - * data items of the same, known type are to be operated on (for - * example, over many tuples in the same relation). - * - * @param type The Type of argument to apply to. - * @return An UncheckedUnaryOperator which applies this UnaryOperation to - * the specified Type. - * @exception OperationInapplicableToType This UnaryOperation is not - * applicable to type. - **/ - virtual UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const = 0; + bool canApplyTo(const Type &argument_type, + const std::vector &static_arguments) const { + std::string message; + return canApplyTo(argument_type, static_arguments, &message); + } protected: - explicit UnaryOperation(const UnaryOperationID operation_id) - : Operation(Operation::kUnaryOperation, - kUnaryOperationNames[ - static_cast::type>(operation_id)], - kUnaryOperationShortNames[ - static_cast::type>(operation_id)]), - operation_id_(operation_id) { + UnaryOperation() + : Operation(Operation::kUnaryOperation) { } - const UnaryOperationID operation_id_; - private: DISALLOW_COPY_AND_ASSIGN(UnaryOperation); }; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/UnaryOperationFactory.cpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/UnaryOperationFactory.cpp b/types/operations/unary_operations/UnaryOperationFactory.cpp deleted file mode 100644 index b306061..0000000 --- a/types/operations/unary_operations/UnaryOperationFactory.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - **/ - -#include "types/operations/unary_operations/UnaryOperationFactory.hpp" - -#include - -#include "types/TypeFactory.hpp" -#include "types/operations/Operation.pb.h" -#include "types/operations/unary_operations/ArithmeticUnaryOperations.hpp" -#include "types/operations/unary_operations/NumericCastOperation.hpp" -#include "types/operations/unary_operations/DateExtractOperation.hpp" -#include "types/operations/unary_operations/SubstringOperation.hpp" -#include "types/operations/unary_operations/UnaryOperationID.hpp" -#include "utility/Macros.hpp" - -#include "glog/logging.h" - -namespace quickstep { - -const UnaryOperation& UnaryOperationFactory::GetUnaryOperation(const UnaryOperationID id) { - switch (id) { - case UnaryOperationID::kNegate: - return NegateUnaryOperation::Instance(); - case UnaryOperationID::kCast: - FATAL_ERROR("Getting a CastOperation through GetUnaryOperation is not supported"); - case UnaryOperationID::kDateExtract: - FATAL_ERROR("Getting a DateExtractOperation through GetUnaryOperation is not supported"); - case UnaryOperationID::kSubstring: - FATAL_ERROR("Getting a SubstringOperation through GetUnaryOperation is not supported"); - default: - FATAL_ERROR("Unknown UnaryOperationID"); - } -} - -bool UnaryOperationFactory::ProtoIsValid(const serialization::UnaryOperation &proto) { - // Check that UnaryOperation is fully initialized. - if (!proto.IsInitialized()) { - return false; - } - - // Check that the operation_id is a valid UnaryOperation. - if (!proto.UnaryOperationID_IsValid(proto.operation_id())) { - return false; - } - - switch (proto.operation_id()) { - case serialization::UnaryOperation::NEGATE: - return true; - case serialization::UnaryOperation::CAST: - return proto.HasExtension(serialization::CastOperation::target_type) - && TypeFactory::ProtoIsValid(proto.GetExtension(serialization::CastOperation::target_type)); - case serialization::UnaryOperation::DATE_EXTRACT: - return proto.HasExtension(serialization::DateExtractOperation::unit) - && DateExtractOperation_Unit_IsValid(proto.GetExtension(serialization::DateExtractOperation::unit)); - case serialization::UnaryOperation::SUBSTRING: - return proto.HasExtension(serialization::SubstringOperation::start_position) - && proto.HasExtension(serialization::SubstringOperation::substring_length); - default: - return false; - } -} - -const UnaryOperation& UnaryOperationFactory::ReconstructFromProto( - const serialization::UnaryOperation &proto) { - DCHECK(ProtoIsValid(proto)) - << "Attempted to create UnaryOperation from an invalid proto description:\n" - << proto.DebugString(); - - switch (proto.operation_id()) { - case serialization::UnaryOperation::NEGATE: - return GetUnaryOperation(UnaryOperationID::kNegate); - case serialization::UnaryOperation::CAST: - return NumericCastOperation::Instance( - TypeFactory::ReconstructFromProto( - proto.GetExtension( - serialization::CastOperation::target_type))); - case serialization::UnaryOperation::DATE_EXTRACT: - switch (proto.GetExtension(serialization::DateExtractOperation::unit)) { - case serialization::DateExtractOperation::YEAR: - return DateExtractOperation::Instance(DateExtractUnit::kYear); - case serialization::DateExtractOperation::MONTH: - return DateExtractOperation::Instance(DateExtractUnit::kMonth); - case serialization::DateExtractOperation::DAY: - return DateExtractOperation::Instance(DateExtractUnit::kDay); - case serialization::DateExtractOperation::HOUR: - return DateExtractOperation::Instance(DateExtractUnit::kHour); - case serialization::DateExtractOperation::MINUTE: - return DateExtractOperation::Instance(DateExtractUnit::kMinute); - case serialization::DateExtractOperation::SECOND: - return DateExtractOperation::Instance(DateExtractUnit::kSecond); - default: - FATAL_ERROR("Unrecognized DateExtractOperation unit in UnaryOperation::ReconstructFromProto"); - } - case serialization::UnaryOperation::SUBSTRING: - return SubstringOperation::Instance( - proto.GetExtension(serialization::SubstringOperation::start_position), - proto.GetExtension(serialization::SubstringOperation::substring_length)); - default: - FATAL_ERROR("Unrecognized UnaryOperationID in UnaryOperation::ReconstructFromProto"); - } -} - -} // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/UnaryOperationFactory.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/UnaryOperationFactory.hpp b/types/operations/unary_operations/UnaryOperationFactory.hpp deleted file mode 100644 index 2ce83d4..0000000 --- a/types/operations/unary_operations/UnaryOperationFactory.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - **/ - -#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_FACTORY_HPP_ -#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_FACTORY_HPP_ - -#include "types/operations/unary_operations/UnaryOperationID.hpp" -#include "utility/Macros.hpp" - -namespace quickstep { - -class UnaryOperation; -namespace serialization { class UnaryOperation; } - -/** \addtogroup Types - * @{ - */ - -/** - * @brief All-static factory object that provides access to UnaryOperations. - **/ -class UnaryOperationFactory { - public: - /** - * @brief Convenience factory method to get a pointer to a UnaryOperation - * from that UnaryOperation's ID. - * - * @param id The ID of the desired UnaryOperation. - * @return The UnaryOperation corresponding to id. - **/ - static const UnaryOperation& GetUnaryOperation(const UnaryOperationID id); - - /** - * @brief Get a reference to a UnaryOperation from that UnaryOperation's - * serialized Protocol Buffer representation. - * - * @param proto A serialized Protocol Buffer representation of a UnaryOperation, - * originally generated by getProto(). - * @return The UnaryOperation described by proto. - **/ - static const UnaryOperation& ReconstructFromProto(const serialization::UnaryOperation &proto); - - /** - * @brief Check whether a serialization::UnaryOperation is fully-formed and - * all parts are valid. - * - * @param proto A serialized Protocol Buffer representation of a UnaryOperation, - * originally generated by getProto(). - * @return Whether proto is fully-formed and valid. - **/ - static bool ProtoIsValid(const serialization::UnaryOperation &proto); - - private: - UnaryOperationFactory(); - - DISALLOW_COPY_AND_ASSIGN(UnaryOperationFactory); -}; - -/** @} */ - -} // namespace quickstep - -#endif // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_FACTORY_HPP_ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/UnaryOperationID.cpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/UnaryOperationID.cpp b/types/operations/unary_operations/UnaryOperationID.cpp deleted file mode 100644 index b47a848..0000000 --- a/types/operations/unary_operations/UnaryOperationID.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - **/ - -#include "types/operations/unary_operations/UnaryOperationID.hpp" - -namespace quickstep { - -const char *kUnaryOperationNames[] = { - "Negate", "Cast", "DateExtract", "Substring" -}; - -const char *kUnaryOperationShortNames[] = { - "-", "Cast", "DateExtract", "Substring" -}; - -} // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/UnaryOperationID.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/UnaryOperationID.hpp b/types/operations/unary_operations/UnaryOperationID.hpp deleted file mode 100644 index fa50f50..0000000 --- a/types/operations/unary_operations/UnaryOperationID.hpp +++ /dev/null @@ -1,63 +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_ID_HPP_ -#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_ID_HPP_ - -#include - -namespace quickstep { - -/** \addtogroup Types - * @{ - */ - -/** - * @brief Concrete UnaryOperations. - **/ -enum class UnaryOperationID { - kNegate = 0, - kCast, - kDateExtract, - kSubstring, - kNumUnaryOperationIDs // Not a real UnaryOperationID, exists for counting purposes. -}; - -/** - * @brief Names of comparisons in the same order as UnaryOperationID. - * @note Defined out-of-line in UnaryOperation.cpp - **/ -extern const char *kUnaryOperationNames[ - static_cast::type>( - UnaryOperationID::kNumUnaryOperationIDs)]; - -/** - * @brief Short names (i.e. mathematical symbols) of comparisons in the same - * order as UnaryOperationID. - * @note Defined out-of-line in UnaryOperation.cpp - **/ -extern const char *kUnaryOperationShortNames[ - static_cast::type>( - UnaryOperationID::kNumUnaryOperationIDs)]; - -/** @} */ - -} // namespace quickstep - -#endif // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_ID_HPP_ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/operations/unary_operations/UnaryOperationWrapper.hpp ---------------------------------------------------------------------- diff --git a/types/operations/unary_operations/UnaryOperationWrapper.hpp b/types/operations/unary_operations/UnaryOperationWrapper.hpp new file mode 100644 index 0000000..59b2cf0 --- /dev/null +++ b/types/operations/unary_operations/UnaryOperationWrapper.hpp @@ -0,0 +1,250 @@ +/** + * 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 +#include +#include + +#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/OperationUtil.hpp" +#include "types/operations/unary_operations/UnaryOperation.hpp" +#include "utility/Macros.hpp" + +namespace quickstep { + +/** \addtogroup Types + * @{ + */ + +template +struct UnaryFunctor { + typedef ArgumentT ArgumentType; + typedef ResultT ResultType; + + static constexpr Operation + ::OperationSuperTypeID kOperationSuperTypeID = Operation::kUnaryOperation; +}; + +template +class UncheckedUnaryOperatorWrapperCodegen : public UncheckedUnaryOperator { + public: + template + UncheckedUnaryOperatorWrapperCodegen(const Type &argument_type, + const Type &result_type, + ConstructorArgs &&...args) + : functor_(std::forward(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; + ArgumentAccessorT accessor(static_cast(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::type; + using ArgumentGen = Codegen; + using ResultGen = Codegen; + + template + struct Implementation; + + const FunctorT functor_; + const Implementation impl_; + + DISALLOW_COPY_AND_ASSIGN(UncheckedUnaryOperatorWrapperCodegen); +}; + +template +template +struct UncheckedUnaryOperatorWrapperCodegen + ::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::ToNativeValueConst(argument), + result_type, + functor); + } + + template + 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::Dereference(arg_value), functor, result_cv); + } + } + return result_cv; + } + + const FunctorT &functor; + const Type &argument_type; + const Type &result_type; +}; + +template +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 getSignatures() const override { + return { + OperationSignature::Create(getName(), {ArgumentType::kStaticTypeID}, 0) + }; + } + + bool canApplyTo(const Type &argument_type, + const std::vector &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 &static_arguments) const override { + DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID); + DCHECK(static_arguments.empty()); + return getResultTypeImpl( + argument_type, static_arguments); + } + + UncheckedUnaryOperator* makeUncheckedUnaryOperator( + const Type &argument_type, + const std::vector &static_arguments) const override { + DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID); + DCHECK(static_arguments.empty()); + return makeUncheckedUnaryOperatorImpl< + std::is_default_constructible::value>( + argument_type, static_arguments); + } + + private: + using ArgumentType = typename FunctorT::ArgumentType; + using ResultType = typename FunctorT::ResultType; + + template + inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl( + const Type &argument_type, + const std::vector &static_arguments, + std::enable_if_t* = 0) const { + return new UncheckedUnaryOperatorWrapperCodegen( + argument_type, *getResultType(argument_type, static_arguments)); + } + + template + inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl( + const Type &argument_type, + const std::vector &static_arguments, + std::enable_if_t* = 0) const { + return new UncheckedUnaryOperatorWrapperCodegen( + argument_type, *getResultType(argument_type, static_arguments), + static_cast(argument_type)); + } + + template + inline const Type* getResultTypeImpl( + const Type &argument_type, + const std::vector &static_arguments, + std::enable_if_t* = 0) const { + return &TypeFactory::GetType(ResultType::kStaticTypeID, + argument_type.isNullable()); + } + + template + inline const Type* getResultTypeImpl( + const Type &argument_type, + const std::vector &static_arguments, + std::enable_if_t* = 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/da9baf7e/utility/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/utility/CMakeLists.txt b/utility/CMakeLists.txt index ca04462..56d80e3 100644 --- a/utility/CMakeLists.txt +++ b/utility/CMakeLists.txt @@ -159,6 +159,7 @@ QS_PROTOBUF_GENERATE_CPP(quickstep_utility_SortConfiguration_proto_srcs SortConfiguration.proto) add_subdirectory(lip_filter) +add_subdirectory(meta) # Declare micro-libs: add_library(quickstep_utility_Alignment ../empty_src.cpp Alignment.hpp) @@ -200,7 +201,6 @@ add_library(quickstep_utility_SortConfiguration_proto ${quickstep_utility_SortConfiguration_proto_hdrs}) add_library(quickstep_utility_SqlError SqlError.cpp SqlError.hpp) add_library(quickstep_utility_StringUtil StringUtil.cpp StringUtil.hpp) -add_library(quickstep_utility_TemplateUtil ../empty_src.cpp TemplateUtil.hpp) # Note that TextBasedTest.{hpp, cpp} are not in this static library. # Any tests that use them need to include them in the # executable. @@ -318,7 +318,6 @@ target_link_libraries(quickstep_utility_ShardedLockManager quickstep_utility_Macros) target_link_libraries(quickstep_utility_StringUtil glog) -target_link_libraries(quickstep_utility_TemplateUtil) target_link_libraries(quickstep_utility_TextBasedTestDriver glog gtest @@ -366,7 +365,6 @@ target_link_libraries(quickstep_utility quickstep_utility_SortConfiguration_proto quickstep_utility_SqlError quickstep_utility_StringUtil - quickstep_utility_TemplateUtil quickstep_utility_TextBasedTestDriver quickstep_utility_ThreadSafeQueue quickstep_utility_TreeStringSerializable @@ -478,14 +476,6 @@ target_link_libraries(TreeStringSerializable_unittest quickstep_utility_TreeStringSerializable) add_test(TreeStringSerializable_unittest TreeStringSerializable_unittest) -add_executable(TemplateUtil_unittest "${CMAKE_CURRENT_SOURCE_DIR}/tests/TemplateUtil_unittest.cpp") -target_link_libraries(TemplateUtil_unittest - gtest - gtest_main - quickstep_utility_Macros - quickstep_utility_TemplateUtil) -add_test(TemplateUtil_unittest TemplateUtil_unittest) - # Benchmarks: if (UNIX) add_executable(EqualsAnyConstant_benchmark http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/utility/StringUtil.cpp ---------------------------------------------------------------------- diff --git a/utility/StringUtil.cpp b/utility/StringUtil.cpp index 2745457..9fca695 100644 --- a/utility/StringUtil.cpp +++ b/utility/StringUtil.cpp @@ -52,6 +52,12 @@ std::string ToLower(const std::string& str) { return lower_str; } +std::string ToUpper(const std::string& str) { + std::string upper_str(str.size(), ' '); + std::transform(str.begin(), str.end(), upper_str.begin(), toupper); + return upper_str; +} + std::string EscapeSpecialChars(const std::string& text) { std::string new_text; for (const char& c : text) { http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/utility/StringUtil.hpp ---------------------------------------------------------------------- diff --git a/utility/StringUtil.hpp b/utility/StringUtil.hpp index abda8f3..e928225 100644 --- a/utility/StringUtil.hpp +++ b/utility/StringUtil.hpp @@ -35,11 +35,21 @@ namespace quickstep { * @brief Convert a string \p str to lower case. * * @param str The string to be converted. - * @return The converted string with all lower case characters bing converted to upper case characters. + * @return The converted string with all lower case characters being converted + * to upper case characters. */ extern std::string ToLower(const std::string &str); /** + * @brief Convert a string \p str to upper case. + * + * @param str The string to be converted. + * @return The converted string with all upper case characters being converted + * to lower case characters. + */ +extern std::string ToUpper(const std::string &str); + +/** * @brief Converts special characters to escape characters. * * @param text The string to be unescaped. http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/utility/TemplateUtil.hpp ---------------------------------------------------------------------- diff --git a/utility/TemplateUtil.hpp b/utility/TemplateUtil.hpp index dfae8e4..587336d 100644 --- a/utility/TemplateUtil.hpp +++ b/utility/TemplateUtil.hpp @@ -30,204 +30,6 @@ namespace quickstep { * @{ */ -namespace template_util_inner { - -/** - * @brief Represents a compile-time sequence of integers. - * - * Sequence is defined here for C++11 compatibility. For C++14 and above, - * std::integer_sequence can be used to achieve the same functionality. - * - * TODO(jianqiao): directly use std::integer_sequence if having C++14 support. - */ -template -struct Sequence {}; - -/** - * @brief The helper class for creating Sequence. MakeSequence::type is - * equivalent to Sequence<1,2,...,N>. - * - * MakeSequence is defined here for C++11 compatibility. For C++14 and above, - * std::make_index_sequence can be used to achieve the same functionality. - * - * TODO(jianqiao): directly use std::make_index_sequence if having C++14 support. - */ -template -struct MakeSequence : MakeSequence {}; - -template -struct MakeSequence<0, S...> { - typedef Sequence type; -}; - -/** - * @brief Final step of CreateBoolInstantiatedInstance. Now all bool_values are - * ready. Instantiate the template and create (i.e. new) an instance. - */ -template