You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by ji...@apache.org on 2017/03/09 21:32:28 UTC
[49/55] [abbrv] incubator-quickstep git commit: Initial commit
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/6941f903/types/operations/unary_operations/DateExtractOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.cpp b/types/operations/unary_operations/DateExtractOperation.cpp
index c99e403..c09b400 100644
--- a/types/operations/unary_operations/DateExtractOperation.cpp
+++ b/types/operations/unary_operations/DateExtractOperation.cpp
@@ -21,521 +21,136 @@
#include <cstddef>
#include <cstdint>
-#include <memory>
+#include <map>
#include <string>
#include <type_traits>
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-#include <utility>
#include <vector>
-#include "storage/StorageBlockInfo.hpp"
-#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-#include "catalog/CatalogTypedefs.hpp"
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
+#include "types/DateType.hpp"
#include "types/DatetimeLit.hpp"
-#include "types/IntType.hpp"
-#include "types/LongType.hpp"
+#include "types/DatetimeType.hpp"
#include "types/Type.hpp"
-#include "types/TypeFactory.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-#include "types/operations/Operation.pb.h"
-#include "utility/Macros.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
#include "glog/logging.h"
-using std::int32_t;
-using std::int64_t;
-
namespace quickstep {
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToTypedValue(
- const TypedValue &argument) const {
- if (argument_nullable && argument.isNull()) {
- return TypedValue(kLong);
- }
-
- return TypedValue(dateExtract(argument.getLiteral<DatetimeLit>()));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToTypedValue(
- const TypedValue &argument) const {
- if (argument_nullable && argument.isNull()) {
- return TypedValue(kInt);
- }
-
- return TypedValue(dateExtract(argument.getLiteral<DateLit>()));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr(const void *argument) const {
- if (argument_nullable && argument == nullptr) {
- return TypedValue(kLong);
- }
-
- return TypedValue(dateExtract(*static_cast<const DatetimeLit*>(argument)));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr(const void *argument) const {
- if (argument_nullable && argument == nullptr) {
- return TypedValue(kInt);
- }
-
- return TypedValue(dateExtract(*static_cast<const DateLit*>(argument)));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToColumnVector(
- const ColumnVector &argument) const {
- // Datetime are usable with NativeColumnVector, so 'argument' should always
- // be native.
- DCHECK(argument.isNative());
-
- const NativeColumnVector &native_argument = static_cast<const NativeColumnVector&>(argument);
- std::unique_ptr<NativeColumnVector> result(
- new NativeColumnVector(LongType::Instance(argument_nullable), native_argument.size()));
-
- for (std::size_t pos = 0;
- pos < native_argument.size();
- ++pos) {
- const DatetimeLit *datetime_arg =
- static_cast<const DatetimeLit*>(native_argument.getUntypedValue<argument_nullable>(pos));
- if (argument_nullable && (datetime_arg == nullptr)) {
- result->appendNullValue();
- } else {
- *static_cast<int64_t*>(result->getPtrForDirectWrite())
- = dateExtract(*datetime_arg);
- }
- }
-
- return result.release();
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToColumnVector(
- const ColumnVector &argument) const {
- // Date is usable with NativeColumnVector, so 'argument' should always
- // be native.
- DCHECK(argument.isNative());
-
- const NativeColumnVector &native_argument = static_cast<const NativeColumnVector&>(argument);
- std::unique_ptr<NativeColumnVector> result(
- new NativeColumnVector(IntType::Instance(argument_nullable), native_argument.size()));
-
- for (std::size_t pos = 0;
- pos < native_argument.size();
- ++pos) {
- const DateLit *date_arg =
- static_cast<const DateLit*>(native_argument.getUntypedValue<argument_nullable>(pos));
- if (argument_nullable && (date_arg == nullptr)) {
- result->appendNullValue();
- } else {
- *static_cast<int32_t*>(result->getPtrForDirectWrite())
- = dateExtract(*date_arg);
- }
- }
-
- return result.release();
-}
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessor(
- ValueAccessor *accessor,
- const attribute_id argument_attr_id) const {
- return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
- accessor,
- [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11)
- std::unique_ptr<NativeColumnVector> result(
- new NativeColumnVector(LongType::Instance(argument_nullable), accessor->getNumTuples()));
- accessor->beginIteration();
- while (accessor->next()) {
- const DatetimeLit *datetime_arg =
- static_cast<const DatetimeLit*>(
- accessor->template getUntypedValue<argument_nullable>(argument_attr_id));
- if (argument_nullable && (datetime_arg == nullptr)) {
- result->appendNullValue();
- } else {
- *static_cast<int64_t*>(result->getPtrForDirectWrite())
- = this->dateExtract(*datetime_arg);
- }
- }
- return result.release();
- });
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessor(
- ValueAccessor *accessor,
- const attribute_id argument_attr_id) const {
- return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
- accessor,
- [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11)
- std::unique_ptr<NativeColumnVector> result(
- new NativeColumnVector(IntType::Instance(argument_nullable), accessor->getNumTuples()));
- accessor->beginIteration();
- while (accessor->next()) {
- const DateLit *date_arg =
- static_cast<const DateLit*>(
- accessor->template getUntypedValue<argument_nullable>(argument_attr_id));
- if (argument_nullable && (date_arg == nullptr)) {
- result->appendNullValue();
- } else {
- *static_cast<int32_t*>(result->getPtrForDirectWrite())
- = this->dateExtract(*date_arg);
- }
- }
- return result.release();
- });
-}
-#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessorForJoin(
- ValueAccessor *accessor,
- const bool use_left_relation,
- const attribute_id argument_attr_id,
- const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const {
- std::unique_ptr<NativeColumnVector> result(
- new NativeColumnVector(LongType::Instance(argument_nullable), joined_tuple_ids.size()));
- return InvokeOnValueAccessorNotAdapter(
- accessor,
- [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11)
- for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
- const DatetimeLit *datetime_arg =
- static_cast<const DatetimeLit*>(
- accessor->template getUntypedValueAtAbsolutePosition<argument_nullable>(
- argument_attr_id,
- use_left_relation ? joined_pair.first : joined_pair.second));
- if (argument_nullable && (datetime_arg == nullptr)) {
- result->appendNullValue();
- } else {
- *static_cast<int64_t*>(result->getPtrForDirectWrite())
- = this->dateExtract(*datetime_arg);
- }
- }
- return result.release();
- });
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessorForJoin(
- ValueAccessor *accessor,
- const bool use_left_relation,
- const attribute_id argument_attr_id,
- const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const {
- std::unique_ptr<NativeColumnVector> result(
- new NativeColumnVector(IntType::Instance(argument_nullable), joined_tuple_ids.size()));
- return InvokeOnValueAccessorNotAdapter(
- accessor,
- [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11)
- for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
- const DateLit *date_arg =
- static_cast<const DateLit*>(
- accessor->template getUntypedValueAtAbsolutePosition<argument_nullable>(
- argument_attr_id,
- use_left_relation ? joined_pair.first : joined_pair.second));
- if (argument_nullable && (date_arg == nullptr)) {
- result->appendNullValue();
- } else {
- *static_cast<int32_t*>(result->getPtrForDirectWrite())
- = this->dateExtract(*date_arg);
- }
- }
- return result.release();
- });
-}
-#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-template <DateExtractUnit unit, bool argument_nullable>
-inline int64_t
-DatetimeExtractUncheckedOperator<unit, argument_nullable>::dateExtract(
- const DatetimeLit &argument) const {
- switch (unit) {
- case DateExtractUnit::kYear:
- return argument.yearField();
- case DateExtractUnit::kMonth:
- return argument.monthField();
- case DateExtractUnit::kDay:
- return argument.dayField();
- case DateExtractUnit::kHour:
- return argument.hourField();
- case DateExtractUnit::kMinute:
- return argument.minuteField();
- case DateExtractUnit::kSecond:
- return argument.secondField();
- default:
- FATAL_ERROR("Unsupported DateExtractUnit in DatetimeExtractUncheckedOperator::dateExtract.");
- }
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-inline int32_t DateExtractUncheckedOperator<unit, argument_nullable>::dateExtract(const DateLit &argument) const {
- switch (unit) {
- case DateExtractUnit::kYear:
- return argument.yearField();
- case DateExtractUnit::kMonth:
- return argument.monthField();
- default:
- FATAL_ERROR("Unsupported DateExtractUnit in DateExtractUncheckedOperator::dateExtract.");
- }
-}
-
-const DateExtractOperation& DateExtractOperation::Instance(const DateExtractUnit unit) {
- switch (unit) {
- case DateExtractUnit::kYear: {
- static DateExtractOperation instance(DateExtractUnit::kYear);
- return instance;
- }
- case DateExtractUnit::kMonth: {
- static DateExtractOperation instance(DateExtractUnit::kMonth);
- return instance;
- }
- case DateExtractUnit::kDay: {
- static DateExtractOperation instance(DateExtractUnit::kDay);
- return instance;
- }
- case DateExtractUnit::kHour: {
- static DateExtractOperation instance(DateExtractUnit::kHour);
- return instance;
- }
- case DateExtractUnit::kMinute: {
- static DateExtractOperation instance(DateExtractUnit::kMinute);
- return instance;
- }
- case DateExtractUnit::kSecond: {
- static DateExtractOperation instance(DateExtractUnit::kSecond);
- return instance;
- }
- default: {
- FATAL_ERROR("Unsupported DateExtractUnit in DateExtractOperation::Instance.");
+struct DateExtractFunctor
+ : public UnaryFunctor<DateType, IntType> {
+ template <typename DateExtractUnitT>
+ inline int apply(const DateLit &argument) const {
+ switch (DateExtractUnitT::value) {
+ case DateExtractUnit::kYear:
+ return argument.yearField();
+ case DateExtractUnit::kMonth:
+ return argument.monthField();
+ case DateExtractUnit::kDay:
+ return argument.dayField();
+ default:
+ DLOG(FATAL) << "Unsupported DateExtractUnit in DateExtractFunctor::apply";
}
}
-}
-
-serialization::UnaryOperation DateExtractOperation::getProto() const {
- serialization::UnaryOperation proto;
- proto.set_operation_id(serialization::UnaryOperation::DATE_EXTRACT);
-
- switch (unit_) {
- case DateExtractUnit::kYear:
- proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::YEAR);
- break;
- case DateExtractUnit::kMonth:
- proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::MONTH);
- break;
- case DateExtractUnit::kDay:
- proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::DAY);
- break;
- case DateExtractUnit::kHour:
- proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::HOUR);
- break;
- case DateExtractUnit::kMinute:
- proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::MINUTE);
- break;
- case DateExtractUnit::kSecond:
- proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::SECOND);
- break;
- default:
- FATAL_ERROR("Unsupported DateExtractUnit in DateExtractOperation::getProto.");
- }
-
- return proto;
-}
-
-std::string DateExtractOperation::getName() const {
- std::string name(kUnaryOperationNames[static_cast<std::size_t>(operation_id_)]);
- name.push_back('(');
- switch (unit_) {
- case DateExtractUnit::kYear:
- name.append("YEAR)");
- break;
- case DateExtractUnit::kMonth:
- name.append("MONTH)");
- break;
- case DateExtractUnit::kDay:
- name.append("DAY)");
- break;
- case DateExtractUnit::kHour:
- name.append("HOUR)");
- break;
- case DateExtractUnit::kMinute:
- name.append("MINUTE)");
- break;
- case DateExtractUnit::kSecond:
- name.append("SECOND)");
- break;
- default:
- name.append("UNKNOWN)");
- break;
- }
- return name;
-}
-
-const Type* DateExtractOperation::pushDownTypeHint(const Type *type_hint) const {
- if (type_hint == nullptr) {
- return nullptr;
- }
+};
- if (type_hint->getTypeID() == kLong) {
- switch (unit_) {
- case DateExtractUnit::kYear: // Fall through.
+struct DatetimeExtractFunctor
+ : public UnaryFunctor<DatetimeType, IntType> {
+ template <typename DateExtractUnitT>
+ inline std::int64_t apply(const DatetimeLit &argument) const {
+ switch (DateExtractUnitT::value) {
+ case DateExtractUnit::kYear:
+ return argument.yearField();
case DateExtractUnit::kMonth:
- // There are two possibilities for the return type, based on whether we
- // have Datetime or Date as the underlying date implementation.
- return nullptr;
- case DateExtractUnit::kDay: // Fall through.
+ return argument.monthField();
+ case DateExtractUnit::kDay:
+ return argument.dayField();
case DateExtractUnit::kHour:
+ return argument.hourField();
case DateExtractUnit::kMinute:
+ return argument.minuteField();
case DateExtractUnit::kSecond:
- return &TypeFactory::GetType(kDatetime, type_hint->isNullable());
+ return argument.secondField();
default:
- return nullptr;
+ DLOG(FATAL) << "Unsupported DateExtractUnit in DatetimeExtractFunctor::apply";
+ }
+ }
+};
+
+const std::map<std::string, DateExtractUnit> DateExtractOperation::kNameToUnitMap = {
+ { "year", DateExtractUnit::kYear },
+ { "month", DateExtractUnit::kMonth },
+ { "day", DateExtractUnit::kDay },
+ { "hour", DateExtractUnit::kHour },
+ { "minute", DateExtractUnit::kMinute },
+ { "second", DateExtractUnit::kSecond }
+};
+
+UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperator(
+ const Type &type,
+ const std::vector<TypedValue> &static_arguments) const {
+ DCHECK_EQ(1u, static_arguments.size());
+ DateExtractUnit unit = parseUnit(static_arguments.front());
+ const Type *result_type = getResultType(type, static_arguments);
+
+ if (type.getTypeID() == kDate) {
+ switch (unit) {
+ case DateExtractUnit::kYear:
+ return new UncheckedUnaryOperatorWrapperCodegen<
+ DateExtractFunctor,
+ std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>(
+ type, *result_type);
+ case DateExtractUnit::kMonth:
+ return new UncheckedUnaryOperatorWrapperCodegen<
+ DateExtractFunctor,
+ std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>(
+ type, *result_type);
+ case DateExtractUnit::kDay:
+ return new UncheckedUnaryOperatorWrapperCodegen<
+ DateExtractFunctor,
+ std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>(
+ type, *result_type);
+ default:
+ LOG(FATAL) << "Unsupported DateExtractUnit for DateType in "
+ << "DateExtractOperation::makeUncheckedUnaryOperator";
}
} else {
- return nullptr;
- }
-}
-
-TypedValue DateExtractOperation::applyToChecked(const TypedValue &argument,
- const Type &argument_type) const {
- if (((argument.getTypeID() != TypeID::kDatetime) ||
- (argument_type.getTypeID() != TypeID::kDatetime)) &&
- ((argument.getTypeID() != TypeID::kDate) ||
- (argument_type.getTypeID() != TypeID::kDate))) {
- LOG(FATAL) << "UnaryOperation " << getName() << " is only applicable to Type "
- << kTypeNames[TypeID::kDatetime] << ", but applyToChecked() was "
- << "called with 'argument' of Type " << kTypeNames[argument.getTypeID()]
- << " and explicit 'argument_type' parameter of "
- << argument_type.getName();
- }
-
- if (argument.isNull()) {
- if (argument.getTypeID() == TypeID::kDatetime) {
- return TypedValue(kLong);
- } else {
- // argument type is kDate.
- DCHECK_EQ(TypeID::kDate, argument.getTypeID());
- return TypedValue(kInt);
- }
- }
-
- switch (unit_) {
- case DateExtractUnit::kYear: {
- if (argument.getTypeID() == TypeID::kDatetime) {
- return TypedValue(argument.getLiteral<DatetimeLit>().yearField());
- } else {
- // argument type is kDate.
- DCHECK_EQ(TypeID::kDate, argument.getTypeID());
- return TypedValue(argument.getLiteral<DateLit>().yearField());
- }
- }
- case DateExtractUnit::kMonth: {
- if (argument.getTypeID() == TypeID::kDatetime) {
- return TypedValue(argument.getLiteral<DatetimeLit>().monthField());
- } else {
- // argument type is kDate.
- DCHECK_EQ(TypeID::kDate, argument.getTypeID());
- return TypedValue(argument.getLiteral<DateLit>().monthField());
- }
- }
- case DateExtractUnit::kDay:
- return TypedValue(argument.getLiteral<DatetimeLit>().dayField());
- case DateExtractUnit::kHour:
- return TypedValue(argument.getLiteral<DatetimeLit>().hourField());
- case DateExtractUnit::kMinute:
- return TypedValue(argument.getLiteral<DatetimeLit>().minuteField());
- case DateExtractUnit::kSecond:
- return TypedValue(argument.getLiteral<DatetimeLit>().secondField());
- default: {
- LOG(FATAL) << "Unsupported DateExtractUnit in DateExtractOperation::applyToChecked().";
- }
- }
-}
-
-UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperatorForTypeHelper(const Type &type) const {
- switch (unit_) {
- case DateExtractUnit::kYear: {
- if (type.getTypeID() == TypeID::kDatetime) {
- if (type.isNullable()) {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kYear, true>();
- } else {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kYear, false>();
- }
- } else {
- DCHECK_EQ(TypeID::kDate, type.getTypeID());
- // type is kDate.
- if (type.isNullable()) {
- return new DateExtractUncheckedOperator<DateExtractUnit::kYear, true>();
- } else {
- return new DateExtractUncheckedOperator<DateExtractUnit::kYear, false>();
- }
- }
- }
- case DateExtractUnit::kMonth: {
- if (type.getTypeID() == TypeID::kDatetime) {
- if (type.isNullable()) {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMonth, true>();
- } else {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMonth, false>();
- }
- } else {
- // type is kDate.
- DCHECK_EQ(TypeID::kDate, type.getTypeID());
- if (type.isNullable()) {
- return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, true>();
- } else {
- return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, false>();
- }
- }
- }
- case DateExtractUnit::kDay:
- if (type.isNullable()) {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kDay, true>();
- } else {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kDay, false>();
- }
- case DateExtractUnit::kHour:
- if (type.isNullable()) {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kHour, true>();
- } else {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kHour, false>();
- }
- case DateExtractUnit::kMinute:
- if (type.isNullable()) {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMinute, true>();
- } else {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMinute, false>();
- }
- case DateExtractUnit::kSecond:
- if (type.isNullable()) {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kSecond, true>();
- } else {
- return new DatetimeExtractUncheckedOperator<DateExtractUnit::kSecond, false>();
- }
- default:
- FATAL_ERROR("Unsupported DateExtractUnit in DateExtractOperation::makeUncheckedUnaryOperatorForTypeHelper.");
- }
-}
-
-const Type* DateExtractOperation::resultTypeForArgumentType(const Type &type) const {
- if (canApplyToType(type)) {
- if (type.getTypeID() == kDatetime) {
- return &LongType::Instance(type.isNullable());
- } else {
- DCHECK_EQ(kDate, type.getTypeID());
- return &IntType::Instance(type.isNullable());
+ switch (unit) {
+ case DateExtractUnit::kYear:
+ return new UncheckedUnaryOperatorWrapperCodegen<
+ DatetimeExtractFunctor,
+ std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>(
+ type, *result_type);
+ case DateExtractUnit::kMonth:
+ return new UncheckedUnaryOperatorWrapperCodegen<
+ DatetimeExtractFunctor,
+ std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>(
+ type, *result_type);
+ case DateExtractUnit::kDay:
+ return new UncheckedUnaryOperatorWrapperCodegen<
+ DatetimeExtractFunctor,
+ std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>(
+ type, *result_type);
+ case DateExtractUnit::kHour:
+ return new UncheckedUnaryOperatorWrapperCodegen<
+ DatetimeExtractFunctor,
+ std::integral_constant<DateExtractUnit, DateExtractUnit::kHour>>(
+ type, *result_type);
+ case DateExtractUnit::kMinute:
+ return new UncheckedUnaryOperatorWrapperCodegen<
+ DatetimeExtractFunctor,
+ std::integral_constant<DateExtractUnit, DateExtractUnit::kMinute>>(
+ type, *result_type);
+ case DateExtractUnit::kSecond:
+ return new UncheckedUnaryOperatorWrapperCodegen<
+ DatetimeExtractFunctor,
+ std::integral_constant<DateExtractUnit, DateExtractUnit::kSecond>>(
+ type, *result_type);
+ default:
+ LOG(FATAL) << "Unsupported DateExtractUnit for DatetimeType in "
+ << "DateExtractOperation::makeUncheckedUnaryOperator";
}
- } else {
- return nullptr;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/6941f903/types/operations/unary_operations/DateExtractOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.hpp b/types/operations/unary_operations/DateExtractOperation.hpp
index f8c091b..00948a4 100644
--- a/types/operations/unary_operations/DateExtractOperation.hpp
+++ b/types/operations/unary_operations/DateExtractOperation.hpp
@@ -31,101 +31,26 @@
#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
#include "catalog/CatalogTypedefs.hpp"
+#include "types/IntType.hpp"
#include "types/LongType.hpp"
#include "types/Type.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
#include "types/operations/Operation.pb.h"
#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
#include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
namespace quickstep {
-class ColumnVector;
-class ValueAccessor;
-
-struct DatetimeLit;
-
-/** \addtogroup Types
- * @{
- */
-
enum class DateExtractUnit {
kYear = 0,
kMonth,
kDay,
kHour,
kMinute,
- kSecond
-};
-
-/**
- * @brief UncheckedUnaryOperator for Datetime Extract.
- */
-template <DateExtractUnit unit, bool argument_nullable>
-class DatetimeExtractUncheckedOperator : public UncheckedUnaryOperator {
- public:
- DatetimeExtractUncheckedOperator()
- : UncheckedUnaryOperator() {}
-
- TypedValue applyToTypedValue(const TypedValue &argument) const override;
-
- TypedValue applyToDataPtr(const void *argument) const override;
-
- ColumnVector* applyToColumnVector(const ColumnVector &argument) const override;
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
- ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
- const attribute_id argument_attr_id) const override;
-#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
- ColumnVector* applyToValueAccessorForJoin(
- ValueAccessor *accessor,
- const bool use_left_relation,
- const attribute_id argument_attr_id,
- const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override;
-#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
- private:
- inline std::int64_t dateExtract(const DatetimeLit &argument) const;
-
- DISALLOW_COPY_AND_ASSIGN(DatetimeExtractUncheckedOperator);
-};
-
-/**
- * @brief UncheckedUnaryOperator for Date Extract.
- */
-template <DateExtractUnit unit, bool argument_nullable>
-class DateExtractUncheckedOperator : public UncheckedUnaryOperator {
- public:
- DateExtractUncheckedOperator()
- : UncheckedUnaryOperator() {}
-
- TypedValue applyToTypedValue(const TypedValue &argument) const override;
-
- TypedValue applyToDataPtr(const void *argument) const override;
-
- ColumnVector* applyToColumnVector(const ColumnVector &argument) const override;
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
- ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
- const attribute_id argument_attr_id) const override;
-#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
- ColumnVector* applyToValueAccessorForJoin(
- ValueAccessor *accessor,
- const bool use_left_relation,
- const attribute_id argument_attr_id,
- const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override;
-#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
- private:
- inline std::int32_t dateExtract(const DateLit &argument) const;
-
- DISALLOW_COPY_AND_ASSIGN(DateExtractUncheckedOperator);
+ kSecond,
+ kInvalid
};
/**
@@ -133,55 +58,67 @@ class DateExtractUncheckedOperator : public UncheckedUnaryOperator {
*/
class DateExtractOperation : public UnaryOperation {
public:
- /**
- * @brief Get a reference to the singleton instance of this Operation for a
- * particular DateExtractUnit.
- *
- * @param unit The date unit to extract.
- * @return A reference to the singleton instance of this Operation for the
- * specified DateExtractUnit.
- **/
- static const DateExtractOperation& Instance(const DateExtractUnit unit);
-
- serialization::UnaryOperation getProto() const override;
-
- std::string getName() const override;
-
- bool canApplyToType(const Type &type) const override {
- return type.getTypeID() == TypeID::kDatetime || type.getTypeID() == kDate;
- }
-
- const Type* resultTypeForArgumentType(const Type &type) const override;
+ DateExtractOperation() {}
- const Type* fixedNullableResultType() const override {
- return nullptr;
+ std::string getName() const override {
+ return "DateExtract";
}
- bool resultTypeIsPlausible(const Type &result_type) const override {
- return result_type.getTypeID() == kLong || result_type.getTypeID() == kInt;
+ std::string getShortName() const override {
+ return "DateExtract";
}
- const Type* pushDownTypeHint(const Type *type_hint) const override;
-
- TypedValue applyToChecked(const TypedValue &argument,
- const Type &argument_type) const override;
+ std::vector<OperationSignaturePtr> getSignatures() const override {
+ const std::vector<TypeID> target_type_carrier = { kVarChar };
+ return {
+ OperationSignature::Create(getName(), {kDate}, target_type_carrier),
+ OperationSignature::Create(getName(), {kDatetime}, target_type_carrier)
+ };
+ }
- UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const override {
- DCHECK(canApplyToType(type));
+ bool canApplyTo(const Type &type,
+ const std::vector<TypedValue> &static_arguments,
+ std::string *message) const override {
+ DCHECK_EQ(1u, static_arguments.size());
+ if (parseUnit(static_arguments.front()) == DateExtractUnit::kInvalid) {
+ *message = "Invalid extraction unit for DateExtract";
+ return false;
+ }
+ return true;
+ }
- return makeUncheckedUnaryOperatorForTypeHelper(type);
+ const Type* getResultType(
+ const Type &type,
+ const std::vector<TypedValue> &static_arguments) const override {
+ DCHECK(UnaryOperation::canApplyTo(type, static_arguments));
+ if (type.getTypeID() == kDatetime) {
+ return &LongType::Instance(type.isNullable());
+ } else {
+ DCHECK_EQ(kDate, type.getTypeID());
+ return &IntType::Instance(type.isNullable());
+ }
}
- private:
- explicit DateExtractOperation(const DateExtractUnit unit)
- : UnaryOperation(UnaryOperationID::kDateExtract),
- unit_(unit) {}
+ UncheckedUnaryOperator* makeUncheckedUnaryOperator(
+ const Type &type,
+ const std::vector<TypedValue> &static_arguments) const override;
- UncheckedUnaryOperator* makeUncheckedUnaryOperatorForTypeHelper(const Type &type) const;
+ private:
+ static DateExtractUnit parseUnit(const TypedValue &unit_arg) {
+ DCHECK(unit_arg.getTypeID() == kVarChar);
+ const std::string unit_str =
+ ToLower(std::string(static_cast<const char*>(unit_arg.getOutOfLineData())));
+
+ auto it = kNameToUnitMap.find(unit_str);
+ if (it != kNameToUnitMap.end()) {
+ return it->second;
+ } else {
+ return DateExtractUnit::kInvalid;
+ }
+ }
- const DateExtractUnit unit_;
+ static const std::map<std::string, DateExtractUnit> kNameToUnitMap;
- private:
DISALLOW_COPY_AND_ASSIGN(DateExtractOperation);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/6941f903/types/operations/unary_operations/NumericCastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/NumericCastOperation.hpp b/types/operations/unary_operations/NumericCastOperation.hpp
deleted file mode 100644
index 1c5e3d4..0000000
--- a/types/operations/unary_operations/NumericCastOperation.hpp
+++ /dev/null
@@ -1,313 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_
-
-#include <cstddef>
-#include <string>
-#include <utility>
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-#include <vector>
-#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-#include "catalog/CatalogTypedefs.hpp"
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
-#include "types/DoubleType.hpp"
-#include "types/FloatType.hpp"
-#include "types/IntType.hpp"
-#include "types/LongType.hpp"
-#include "types/Type.hpp"
-#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-#include "types/operations/Operation.pb.h"
-#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
-#include "utility/Macros.hpp"
-#include "utility/PtrMap.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-/** \addtogroup Types
- * @{
- */
-
-// TODO(quickstep-team): Support CAST on Datetime, YearMonthInterval, DatetimeInterval, VarChar, Char.
-// Currently we only need cast operations on numeric values.
-
-/**
- * @brief UncheckedUnaryOperator for CAST.
- */
-template <class SourceType, bool source_nullability, class TargetType, bool target_nullability>
-class UncheckedNumericCastOperator : public UncheckedUnaryOperator {
- public:
- UncheckedNumericCastOperator()
- : UncheckedUnaryOperator(),
- target_type_(TargetType::Instance(target_nullability)) {
- }
-
- TypedValue applyToTypedValue(const TypedValue &argument) const override {
- if (source_nullability && argument.isNull()) {
- return TypedValue(TargetType::kStaticTypeID);
- }
-
- return TypedValue(static_cast<typename TargetType::cpptype>(
- argument.getLiteral<typename SourceType::cpptype>()));
- }
-
- TypedValue applyToDataPtr(const void *argument) const override {
- if (source_nullability && argument == nullptr) {
- return TypedValue(TargetType::kStaticTypeID);
- }
-
- return TypedValue(
- static_cast<const typename TargetType::cpptype>(
- *static_cast<const typename SourceType::cpptype*>(argument)));
- }
-
- ColumnVector* applyToColumnVector(const ColumnVector &argument) const override {
- DCHECK(NativeColumnVector::UsableForType(target_type_));
- DCHECK(argument.isNative());
- const NativeColumnVector &native_argument = static_cast<const NativeColumnVector&>(argument);
- NativeColumnVector *result = new NativeColumnVector(
- target_type_,
- native_argument.size());
- for (std::size_t pos = 0;
- pos < native_argument.size();
- ++pos) {
- const typename SourceType::cpptype *scalar_arg
- = static_cast<const typename SourceType::cpptype*>(
- native_argument.getUntypedValue<source_nullability>(pos));
- if (source_nullability && (scalar_arg == nullptr)) {
- result->appendNullValue();
- } else {
- *static_cast<typename TargetType::cpptype*>(result->getPtrForDirectWrite())
- = static_cast<typename TargetType::cpptype>(*scalar_arg);
- }
- }
- return result;
- }
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
- ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
- const attribute_id argument_attr_id) const override {
- DCHECK(NativeColumnVector::UsableForType(target_type_));
- return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
- accessor,
- [&](auto *accessor) -> ColumnVector* { // NOLINT(build/c++11)
- NativeColumnVector *result = new NativeColumnVector(
- target_type_,
- accessor->getNumTuples());
- accessor->beginIteration();
- while (accessor->next()) {
- const typename SourceType::cpptype *scalar_arg
- = static_cast<const typename SourceType::cpptype*>(
- accessor->template getUntypedValue<source_nullability>(argument_attr_id));
- if (source_nullability && (scalar_arg == nullptr)) {
- result->appendNullValue();
- } else {
- *static_cast<typename TargetType::cpptype*>(result->getPtrForDirectWrite())
- = static_cast<typename TargetType::cpptype>(*scalar_arg);
- }
- }
- return result;
- });
- }
-#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
- ColumnVector* applyToValueAccessorForJoin(
- ValueAccessor *accessor,
- const bool use_left_relation,
- const attribute_id argument_attr_id,
- const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override {
- DCHECK(NativeColumnVector::UsableForType(target_type_));
- NativeColumnVector *result = new NativeColumnVector(target_type_,
- joined_tuple_ids.size());
- InvokeOnValueAccessorNotAdapter(
- accessor,
- [&](auto *accessor) -> void { // NOLINT(build/c++11)
- for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
- const typename SourceType::cpptype *scalar_arg
- = static_cast<const typename SourceType::cpptype*>(
- accessor->template getUntypedValueAtAbsolutePosition<source_nullability>(
- argument_attr_id,
- use_left_relation ? joined_pair.first : joined_pair.second));
- if (source_nullability && (scalar_arg == nullptr)) {
- result->appendNullValue();
- } else {
- *static_cast<typename TargetType::cpptype*>(result->getPtrForDirectWrite())
- = static_cast<typename TargetType::cpptype>(*scalar_arg);
- }
- }
- });
- return result;
- }
-#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
- private:
- const Type &target_type_;
-
- DISALLOW_COPY_AND_ASSIGN(UncheckedNumericCastOperator);
-};
-
-/**
- * @brief UnaryOperation for CAST.
- */
-class NumericCastOperation : public UnaryOperation {
- public:
- serialization::UnaryOperation getProto() const override {
- serialization::UnaryOperation proto;
- proto.set_operation_id(serialization::UnaryOperation::CAST);
- proto.MutableExtension(serialization::CastOperation::target_type)
- ->CopyFrom(getTargetType().getProto());
-
- return proto;
- }
-
- /**
- * @brief Get a reference to the singleton instance of this Operation.
- *
- * @param target_type The target type to coerce input values to.
- * @return A reference to the singleton instance of this Operation.
- **/
- static const NumericCastOperation& Instance(const Type &target_type) {
- static PtrMap<const Type*, NumericCastOperation> instance_map;
- PtrMap<const Type*, NumericCastOperation>::iterator instance_map_it =
- instance_map.find(&target_type);
- if (instance_map_it == instance_map.end()) {
- instance_map_it = instance_map.insert(&target_type,
- new NumericCastOperation(target_type)).first;
- }
- return *(instance_map_it->second);
- }
-
- /**
- * @return The target type for coercion.
- */
- const Type& getTargetType() const {
- return target_type_;
- }
-
- std::string getName() const override {
- return std::string(kUnaryOperationNames[static_cast<std::size_t>(operation_id_)])
- .append("(")
- .append(target_type_.getName())
- .append(")");
- }
-
- bool canApplyToType(const Type &type) const override {
- return target_type_.isCoercibleFrom(type);
- }
-
- const Type* resultTypeForArgumentType(const Type &type) const override {
- if (canApplyToType(type)) {
- return &target_type_;
- } else {
- return nullptr;
- }
- }
-
- const Type* fixedNullableResultType() const override {
- return &target_type_.getNullableVersion();
- }
-
- bool resultTypeIsPlausible(const Type &result_type) const override {
- return result_type.equals(target_type_)
- || result_type.equals(target_type_.getNullableVersion());
- }
-
- const Type* pushDownTypeHint(const Type *type_hint) const override {
- return &target_type_;
- }
-
- TypedValue applyToChecked(const TypedValue &argument,
- const Type &argument_type) const override {
- return target_type_.coerceValue(argument, argument_type);
- }
-
- UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const override {
- switch (type.getTypeID()) {
- case kInt:
- return makeUncheckedUnaryOperatorHelperForSourceNullability<IntType>(type);
- case kLong:
- return makeUncheckedUnaryOperatorHelperForSourceNullability<LongType>(type);
- case kFloat:
- return makeUncheckedUnaryOperatorHelperForSourceNullability<FloatType>(type);
- case kDouble:
- return makeUncheckedUnaryOperatorHelperForSourceNullability<DoubleType>(type);
- default:
- FATAL_ERROR("Unhandled type " << kTypeNames[type.getTypeID()]);
- }
- }
-
- private:
- explicit NumericCastOperation(const Type &target_type)
- : UnaryOperation(UnaryOperationID::kCast),
- target_type_(target_type) {}
-
- template <class SourceType>
- UncheckedUnaryOperator* makeUncheckedUnaryOperatorHelperForSourceNullability(const Type &type) const {
- if (type.isNullable()) {
- return makeUncheckedUnaryOperatorHelperForTargetType<SourceType, true>();
- } else {
- return makeUncheckedUnaryOperatorHelperForTargetType<SourceType, false>();
- }
- }
-
- template <class SourceType, bool source_nullability>
- UncheckedUnaryOperator* makeUncheckedUnaryOperatorHelperForTargetType() const {
- switch (target_type_.getTypeID()) {
- case kInt:
- return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, IntType>();
- case kLong:
- return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, LongType>();
- case kFloat:
- return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, FloatType>();
- case kDouble:
- return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, DoubleType>();
- default:
- FATAL_ERROR("Unhandled type " << kTypeNames[target_type_.getTypeID()]);
- }
- }
-
- template <class SourceType, bool source_nullability, class TargetType>
- UncheckedUnaryOperator* makeUncheckedUnaryOperatorHelperForTargetNullability() const {
- if (target_type_.isNullable()) {
- return new UncheckedNumericCastOperator<SourceType, source_nullability, TargetType, true>();
- } else {
- return new UncheckedNumericCastOperator<SourceType, source_nullability, TargetType, false>();
- }
- }
-
- const Type& target_type_;
-
- DISALLOW_COPY_AND_ASSIGN(NumericCastOperation);
-};
-
-/** @} */
-
-} // namespace quickstep
-
-#endif // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/6941f903/types/operations/unary_operations/SubstringOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/SubstringOperation.cpp b/types/operations/unary_operations/SubstringOperation.cpp
index 84f1c8d..408ea2d 100644
--- a/types/operations/unary_operations/SubstringOperation.cpp
+++ b/types/operations/unary_operations/SubstringOperation.cpp
@@ -40,30 +40,27 @@
namespace quickstep {
-serialization::UnaryOperation SubstringOperation::getProto() const {
- serialization::UnaryOperation proto;
- proto.set_operation_id(serialization::UnaryOperation::SUBSTRING);
- proto.SetExtension(serialization::SubstringOperation::start_position,
- start_position_);
- proto.SetExtension(serialization::SubstringOperation::substring_length,
- substring_length_);
- return proto;
-}
+UncheckedUnaryOperator* SubstringOperation::makeUncheckedUnaryOperator(
+ const Type &type,
+ const std::vector<TypedValue> &static_arguments) const {
+ DCHECK(UnaryOperation::canApplyTo(type, static_arguments));
-UncheckedUnaryOperator* SubstringOperation::makeUncheckedUnaryOperatorForType(
- const Type &type) const {
- DCHECK(type.getSuperTypeID() == Type::kAsciiString);
+ std::size_t start_position;
+ std::size_t substring_length;
+ ExtractStaticArguments(static_arguments, &start_position, &substring_length);
const std::size_t input_maximum_length =
- static_cast<const AsciiStringSuperType&>(type).getStringLength();
+ type.getTypeID() == kChar
+ ? static_cast<const CharType&>(type).getStringLength()
+ : static_cast<const VarCharType&>(type).getStringLength();
const bool input_null_terminated = (type.getTypeID() == TypeID::kVarChar);
- const Type *result_type = resultTypeForArgumentType(type);
+ const Type *result_type = getResultType(type, static_arguments);
DCHECK(result_type != nullptr);
return CreateBoolInstantiatedInstance<SubstringUncheckedOperator, UncheckedUnaryOperator>(
- std::forward_as_tuple(start_position_,
- computeMaximumSubstringLength(type),
+ std::forward_as_tuple(start_position,
+ ComputeMaximumSubstringLength(type, start_position, substring_length),
input_maximum_length,
*result_type),
input_null_terminated, type.isNullable());
@@ -108,23 +105,6 @@ TypedValue SubstringUncheckedOperator<null_terminated,
}
template <bool null_terminated, bool input_nullable>
-TypedValue SubstringUncheckedOperator<null_terminated,
- input_nullable>
- ::applyToDataPtr(const void *argument) const {
- if (input_nullable && argument == nullptr) {
- return TypedValue(result_type_.getTypeID());
- }
-
- char *output_ptr = static_cast<char*>(std::malloc(substring_length_));
- computeSubstring(static_cast<const char*>(argument),
- output_ptr);
-
- return TypedValue::CreateWithOwnedData(result_type_.getTypeID(),
- output_ptr,
- substring_length_);
-}
-
-template <bool null_terminated, bool input_nullable>
ColumnVector* SubstringUncheckedOperator<null_terminated,
input_nullable>
::applyToColumnVector(const ColumnVector &argument) const {
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/6941f903/types/operations/unary_operations/SubstringOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/SubstringOperation.hpp b/types/operations/unary_operations/SubstringOperation.hpp
index 66f311f..fd5868f 100644
--- a/types/operations/unary_operations/SubstringOperation.hpp
+++ b/types/operations/unary_operations/SubstringOperation.hpp
@@ -22,23 +22,27 @@
#include <algorithm>
#include <cstddef>
+#include <cstdint>
#include <cstdlib>
#include <cstring>
+#include <limits>
#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>
#include "catalog/CatalogTypedefs.hpp"
+#include "types/CharType.hpp"
#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
+#include "types/VarCharType.hpp"
#include "types/operations/Operation.pb.h"
#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
#include "utility/HashPair.hpp"
#include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
#include "glog/logging.h"
@@ -53,116 +57,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<std::size_t>::CombineHashes(pair.first, pair.second);
- };
- static std::unordered_map<std::pair<std::size_t, std::size_t>,
- std::unique_ptr<const SubstringOperation>,
- decltype(hash)> instance_map(10, hash);
-
- const std::pair<std::size_t, std::size_t> 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<const SubstringOperation>(instance));
- return *instance;
- }
+ SubstringOperation() {}
+
+ std::string getName() const override {
+ return "Substring";
}
- serialization::UnaryOperation getProto() const override;
+ std::string getShortName() const override {
+ return "Substring";
+ }
- bool canApplyToType(const Type &type) const override {
- return (type.getSuperTypeID() == Type::kAsciiString);
+ std::vector<OperationSignaturePtr> getSignatures() const override {
+ return {
+ OperationSignature::Create(getName(), {kChar}, {kLong, kLong}),
+ OperationSignature::Create(getName(), {kVarChar}, {kLong, kLong})
+ };
}
- 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());
+ bool canApplyTo(const Type &type,
+ const std::vector<TypedValue> &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);
+
+ if (static_arguments[0].getLiteral<std::int64_t>() <= 0) {
+ *message = "The start position must be greater than 0";
+ return false;
}
- return nullptr;
- }
- const Type* fixedNullableResultType() const override {
- // Result type is not fixed (i.e. can have various lengths).
- return nullptr;
- }
+ if (static_arguments.size() == 2) {
+ DCHECK(static_arguments[1].getTypeID() == kLong);
+ if (static_arguments[1].getLiteral<std::int64_t>() <= 0) {
+ *message = "The substring length must be greater than 0";
+ return false;
+ }
+ }
- bool resultTypeIsPlausible(const Type &result_type) const override {
- // Result can be coerced to Char or VarChar.
- return (result_type.getSuperTypeID() == Type::kAsciiString);
+ return true;
}
- const Type* pushDownTypeHint(const Type *type_hint) const override {
- // Input can only be a string, but we don't know the length.
- return nullptr;
- }
+ const Type* getResultType(
+ const Type &type,
+ const std::vector<TypedValue> &static_arguments) const override {
+ DCHECK(UnaryOperation::canApplyTo(type, static_arguments));
- TypedValue applyToChecked(const TypedValue &argument,
- const Type &argument_type) const override {
- DCHECK(canApplyToType(argument_type));
-
- const Type *result_type = resultTypeForArgumentType(argument_type);
- DCHECK(result_type != nullptr);
-
- 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<char*>(std::malloc(result_length));
- const char *input_ptr = static_cast<const char*>(argument.getOutOfLineData());
-
- 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<TypedValue> &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<TypedValue> &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<std::size_t>(static_arguments[0].getLiteral<std::int64_t>() - 1);
+
+ DCHECK(static_arguments.size() < 2u || static_arguments[1].getTypeID() == kLong);
+ *substring_length =
+ static_arguments.size() < 2u
+ ? std::numeric_limits<std::size_t>::max()
+ : static_cast<std::size_t>(static_arguments[1].getLiteral<std::int64_t>());
}
/**
@@ -171,19 +140,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<const AsciiStringSuperType&>(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<const CharType&>(type).getStringLength()
+ : static_cast<const VarCharType&>(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 +176,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
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/6941f903/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/6941f903/types/operations/unary_operations/UnaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperation.hpp b/types/operations/unary_operations/UnaryOperation.hpp
index 30a2961..68dc993 100644
--- a/types/operations/unary_operations/UnaryOperation.hpp
+++ b/types/operations/unary_operations/UnaryOperation.hpp
@@ -24,18 +24,10 @@
#include <string>
#include <type_traits>
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-#include <utility>
-#include <vector>
-
-#include "storage/StorageBlockInfo.hpp"
-#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
#include "catalog/CatalogTypedefs.hpp"
-#include "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<const UnaryOperation> 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<std::pair<tuple_id, tuple_id>> &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<std::size_t>(operation_id_)];
- }
+ virtual std::string getName() const = 0;
/**
* @brief Get a human-readable short name (e.g. "-") for this UnaryOperation.
@@ -165,113 +112,35 @@ class UnaryOperation : public Operation {
* @return A human-readable short name for this BinaryOperation.
**/
virtual std::string getShortName() const {
- return kUnaryOperationShortNames[static_cast<std::size_t>(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 std::vector<OperationSignaturePtr> getSignatures() 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;
+ virtual bool canApplyTo(const Type &argument_type,
+ const std::vector<TypedValue> &static_arguments,
+ std::string *message) 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<TypedValue> &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<TypedValue> &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<TypedValue> &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<typename std::underlying_type<UnaryOperationID>::type>(operation_id)],
- kUnaryOperationShortNames[
- static_cast<typename std::underlying_type<UnaryOperationID>::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/6941f903/types/operations/unary_operations/UnaryOperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationFactory.cpp b/types/operations/unary_operations/UnaryOperationFactory.cpp
index b306061..cebf9e2 100644
--- a/types/operations/unary_operations/UnaryOperationFactory.cpp
+++ b/types/operations/unary_operations/UnaryOperationFactory.cpp
@@ -21,100 +21,54 @@
#include <string>
-#include "types/TypeFactory.hpp"
-#include "types/operations/Operation.pb.h"
+#include "types/operations/OperationSignature.hpp"
#include "types/operations/unary_operations/ArithmeticUnaryOperations.hpp"
-#include "types/operations/unary_operations/NumericCastOperation.hpp"
+#include "types/operations/unary_operations/CMathUnaryOperations.hpp"
+#include "types/operations/unary_operations/CastOperation.hpp"
#include "types/operations/unary_operations/DateExtractOperation.hpp"
#include "types/operations/unary_operations/SubstringOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
+#include "utility/StringUtil.hpp"
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");
- }
+UnaryOperationFactory::UnaryOperationFactory() {
+ registerUnaryOperation(UnaryOperationPtr(new CastOperation()));
+ registerUnaryOperation(UnaryOperationPtr(new DateExtractOperation()));
+ registerUnaryOperation(UnaryOperationPtr(new SubstringOperation()));
+
+ registerUnaryOperationPack<CMathUnaryFunctorPack>();
+ registerUnaryOperationPack<ArithmeticUnaryFunctorPack>();
}
-bool UnaryOperationFactory::ProtoIsValid(const serialization::UnaryOperation &proto) {
- // Check that UnaryOperation is fully initialized.
- if (!proto.IsInitialized()) {
- return false;
- }
+void UnaryOperationFactory::registerUnaryOperation(
+ const UnaryOperationPtr &operation) {
+ for (const OperationSignaturePtr op_sig : operation->getSignatures()) {
+ const OperationSignaturePtr normalized_op_sig =
+ OperationSignature::Create(ToLower(op_sig->getName()),
+ op_sig->getArgumentTypeIDs(),
+ op_sig->getNumStaticArguments());
- // Check that the operation_id is a valid UnaryOperation.
- if (!proto.UnaryOperationID_IsValid(proto.operation_id())) {
- return false;
- }
+ // TODO: print error message for collision
+ unary_operations_.emplace(normalized_op_sig, operation);
- 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 auto name_arity_pair = std::make_pair(normalized_op_sig->getName(),
+ normalized_op_sig->getArity());
+ name_arity_index_[name_arity_pair].emplace(normalized_op_sig);
}
}
-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");
+template <typename UnaryOperationPackT>
+void UnaryOperationFactory::registerUnaryOperationPack() {
+ for (const UnaryOperationPtr &operation : UnaryOperationPackT::GenerateAll()) {
+ registerUnaryOperation(operation);
}
}
+const UnaryOperationFactory& UnaryOperationFactory::Instance() {
+ static UnaryOperationFactory instance;
+ return instance;
+}
+
} // namespace quickstep
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/6941f903/types/operations/unary_operations/UnaryOperationFactory.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationFactory.hpp b/types/operations/unary_operations/UnaryOperationFactory.hpp
index 2ce83d4..c586b62 100644
--- a/types/operations/unary_operations/UnaryOperationFactory.hpp
+++ b/types/operations/unary_operations/UnaryOperationFactory.hpp
@@ -20,13 +20,18 @@
#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 <set>
+#include <unordered_map>
+#include <utility>
+
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "utility/HashPair.hpp"
#include "utility/Macros.hpp"
-namespace quickstep {
+#include "glog/logging.h"
-class UnaryOperation;
-namespace serialization { class UnaryOperation; }
+namespace quickstep {
/** \addtogroup Types
* @{
@@ -37,38 +42,51 @@ namespace serialization { class UnaryOperation; }
**/
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);
+ static const UnaryOperationFactory& Instance();
+
+ inline bool hasUnaryOperation(
+ const OperationSignaturePtr &op_signature) const {
+ return unary_operations_.find(op_signature) != unary_operations_.end();
+ }
+
+ inline bool hasUnaryOperation(const std::string &name,
+ const std::size_t arity) const {
+ const auto it = name_arity_index_.find(std::make_pair(name, arity));
+ return it != name_arity_index_.end();
+ }
+
+ inline const UnaryOperationPtr getUnaryOperation(
+ const OperationSignaturePtr &op_signature) const {
+ DCHECK(hasUnaryOperation(op_signature));
+ return unary_operations_.at(op_signature);
+ }
+
+ inline const std::set<OperationSignaturePtr,
+ OperationSignatureNumStaticArgumentsGreater>&
+ getUnaryOperations(const std::string &name,
+ const std::size_t arity) const {
+ DCHECK(hasUnaryOperation(name, arity));
+ return name_arity_index_.at(std::make_pair(name, arity));
+ }
private:
UnaryOperationFactory();
+ void registerUnaryOperation(const UnaryOperationPtr &operation);
+
+ template <typename UnaryOperationPackT>
+ void registerUnaryOperationPack();
+
+ std::unordered_map<OperationSignaturePtr,
+ UnaryOperationPtr,
+ OperationSignatureHash,
+ OperationSignatureEqual> unary_operations_;
+
+ std::unordered_map<
+ std::pair<std::string, std::size_t>,
+ std::set<OperationSignaturePtr,
+ OperationSignatureNumStaticArgumentsGreater>> name_arity_index_;
+
DISALLOW_COPY_AND_ASSIGN(UnaryOperationFactory);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/6941f903/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/6941f903/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 <type_traits>
-
-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<typename std::underlying_type<UnaryOperationID>::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<typename std::underlying_type<UnaryOperationID>::type>(
- UnaryOperationID::kNumUnaryOperationIDs)];
-
-/** @} */
-
-} // namespace quickstep
-
-#endif // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_ID_HPP_