You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by hb...@apache.org on 2016/08/31 16:35:12 UTC
incubator-quickstep git commit: Separate code paths for Datetime and
Date in Extract
Repository: incubator-quickstep
Updated Branches:
refs/heads/datetype-fix 4913b7f67 -> 483901f4f
Separate code paths for Datetime and Date in Extract
Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/483901f4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/483901f4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/483901f4
Branch: refs/heads/datetype-fix
Commit: 483901f4fb7ad4753e91f331da3b15a3fc59e47c
Parents: 4913b7f
Author: Harshad Deshmukh <hb...@apache.org>
Authored: Wed Aug 31 11:34:27 2016 -0500
Committer: Harshad Deshmukh <hb...@apache.org>
Committed: Wed Aug 31 11:34:27 2016 -0500
----------------------------------------------------------------------
query_optimizer/tests/resolver/Select.test | 37 +--
types/DateOperatorOverloads.hpp | 9 -
types/DatetimeLit.hpp | 8 +
.../operations/unary_operations/CMakeLists.txt | 3 +-
.../unary_operations/DateExtractOperation.cpp | 248 ++++++++++++++++---
.../unary_operations/DateExtractOperation.hpp | 52 +++-
.../tests/DateExtractOperation_unittest.cpp | 24 +-
7 files changed, 302 insertions(+), 79 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/483901f4/query_optimizer/tests/resolver/Select.test
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/resolver/Select.test b/query_optimizer/tests/resolver/Select.test
index 41fbbcb..facb3a1 100644
--- a/query_optimizer/tests/resolver/Select.test
+++ b/query_optimizer/tests/resolver/Select.test
@@ -2151,7 +2151,7 @@ name
select datetime '1998-12-12' + interval '5 day',
date '1998-12-12' - interval '5 month',
interval '5 year' + date '1998-12-12',
- date '1998-12-12' - date '1998-12-11',
+ datetime '1998-12-12' - datetime '1998-12-11',
interval '10 day' + interval '11 day',
interval '30 month' + interval '1 year',
interval '30 month' - interval '1 year'
@@ -2172,18 +2172,16 @@ TopLevelPlan
| | +-Add
| | +-Literal[value=1998-12-12T00:00:00,type=Datetime]
| | +-Literal[value=5 days 00:00:00,type=DatetimeInterval]
-| +-Alias[id=7,name=,
-| | alias=(Date('1998-12-12')-YearMonthInterval('5 month')),relation=,
-| | type=Date]
+| +-Alias[id=7,name=,alias=(Date('1998-12-12')-YearMonthInterval('5 month')),
+| | relation=,type=Date]
| | +-Subtract
| | +-Literal[value=1998-12-12,type=Date]
| | +-Literal[value=5 mons,type=YearMonthInterval]
-| +-Alias[id=8,name=,
-| | alias=(YearMonthInterval('5 year')+Datetime('1998-12-12')),relation=,
-| | type=Datetime]
+| +-Alias[id=8,name=,alias=(YearMonthInterval('5 year')+Date('1998-12-12')),
+| | relation=,type=Date]
| | +-Add
| | +-Literal[value=5 years,type=YearMonthInterval]
-| | +-Literal[value=1998-12-12T00:00:00,type=Datetime]
+| | +-Literal[value=1998-12-12,type=Date]
| +-Alias[id=9,name=,alias=(Datetime('1998-12-12')-Datetime('1998-12-11')),
| | relation=,type=DatetimeInterval]
| | +-Subtract
@@ -2212,11 +2210,9 @@ TopLevelPlan
| alias=(Datetime('1998-12-12')+DatetimeInterval('5 day')),relation=,
| type=Datetime]
+-AttributeReference[id=7,name=,
- | alias=(Datetime('1998-12-12')-YearMonthInterval('5 month')),relation=,
- | type=Datetime]
+ | alias=(Date('1998-12-12')-YearMonthInterval('5 month')),relation=,type=Date]
+-AttributeReference[id=8,name=,
- | alias=(YearMonthInterval('5 year')+Datetime('1998-12-12')),relation=,
- | type=Datetime]
+ | alias=(YearMonthInterval('5 year')+Date('1998-12-12')),relation=,type=Date]
+-AttributeReference[id=9,name=,
| alias=(Datetime('1998-12-12')-Datetime('1998-12-11')),relation=,
| type=DatetimeInterval]
@@ -2270,9 +2266,9 @@ TopLevelPlan
relation=,type=YearMonthInterval]
==
-SELECT EXTRACT(YEAR FROM DATE '2016-01-02 10:20:30') * 10000 +
- EXTRACT(MONTH FROM DATE '2016-01-02 10:20:30') * 100 +
- EXTRACT(DAY FROM DATE '2016-01-02 10:20:30') AS date_digits
+SELECT EXTRACT(YEAR FROM DATETIME '2016-01-02 10:20:30') * 10000 +
+ EXTRACT(MONTH FROM DATETIME '2016-01-02 10:20:30') * 100 +
+ EXTRACT(DAY FROM DATETIME '2016-01-02 10:20:30') AS date_digits
FROM generate_series(1, 1);
--
TopLevelPlan
@@ -2501,11 +2497,20 @@ ERROR: Can not apply binary operation "Add" to arguments of types DatetimeInterv
select 5 / (date '1999-10-12' + yearmonth interval '10 year')
from test
--
-ERROR: Can not apply binary operation "Divide" to arguments of types Int and Datetime (1 : 10)
+ERROR: Can not apply binary operation "Divide" to arguments of types Int and Date (1 : 10)
select 5 / (date '1999-10-12' + yearmont...
^
==
+select 5 / (datetime '1999-10-12' + yearmonth interval '10 year')
+from test
+--
+ERROR: Can not apply binary operation "Divide" to arguments of types Int and Datetime (1 : 10)
+select 5 / (datetime '1999-10-12' + yearmont...
+ ^
+==
+
+
# CASE expressions.
SELECT CASE int_col%2
WHEN 1 THEN 'odd'
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/483901f4/types/DateOperatorOverloads.hpp
----------------------------------------------------------------------
diff --git a/types/DateOperatorOverloads.hpp b/types/DateOperatorOverloads.hpp
index 05b5b85..b04f44e 100644
--- a/types/DateOperatorOverloads.hpp
+++ b/types/DateOperatorOverloads.hpp
@@ -38,7 +38,6 @@ namespace quickstep {
// Month arithmetic clamps to the actual last day of a given month.
inline int ClampDayOfMonth(const int year, const int month, const int day) {
- std::cout << "ClampDayOfMonth : year = " << year << " month = " << month << " day = " << day << "\n";
DCHECK_LT(day, 32);
switch (month) {
case 2: {
@@ -46,10 +45,6 @@ inline int ClampDayOfMonth(const int year, const int month, const int day) {
(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
? 29
: 28;
- const int return_val = (day > days_in_february) ? days_in_february : day;
- std::cout << "year " << year << " month: " << month
- << " days in february: " << days_in_february
- << " return: " << return_val << "\n";
return (day > days_in_february) ? days_in_february : day;
}
case 4:
@@ -138,8 +133,6 @@ inline DateLit operator+(const DateLit &lhs, const YearMonthIntervalLit &rhs) {
const std::uint8_t result_day = static_cast<std::uint8_t>(
ClampDayOfMonth(result_year, result_month, lhs.day));
- std::cout << "Result day: " << unsigned(result_day) << "\n";
-
return DateLit::Create(result_year, result_month, result_day);
}
@@ -205,8 +198,6 @@ inline DateLit operator-(const DateLit &lhs, const YearMonthIntervalLit &rhs) {
const std::uint8_t result_day = static_cast<std::uint8_t>(
ClampDayOfMonth(result_year, result_month, lhs.day));
- std::cout << "Result day: " << unsigned(result_day) << "\n";
-
return DateLit::Create(result_year, result_month, result_day);
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/483901f4/types/DatetimeLit.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeLit.hpp b/types/DatetimeLit.hpp
index 580a0ed..58c852f 100644
--- a/types/DatetimeLit.hpp
+++ b/types/DatetimeLit.hpp
@@ -91,6 +91,14 @@ struct DateLit {
inline bool operator!=(const DateLit& rhs) const {
return !(*this == rhs);
}
+
+ inline std::int32_t yearField() const {
+ return year;
+ }
+
+ inline std::int32_t monthField() const {
+ return static_cast<std::int32_t>(month);
+ }
};
/**
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/483901f4/types/operations/unary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt
index d612464..8aee499 100644
--- a/types/operations/unary_operations/CMakeLists.txt
+++ b/types/operations/unary_operations/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Licensed to the Apache Software Foundation (ASF) under one
+# Licensed to the Agache 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
@@ -60,6 +60,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOper
quickstep_storage_ValueAccessor
quickstep_storage_ValueAccessorUtil
quickstep_types_DatetimeLit
+ quickstep_types_IntType
quickstep_types_LongType
quickstep_types_Type
quickstep_types_TypeFactory
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/483901f4/types/operations/unary_operations/DateExtractOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.cpp b/types/operations/unary_operations/DateExtractOperation.cpp
index a86afc4..325adb0 100644
--- a/types/operations/unary_operations/DateExtractOperation.cpp
+++ b/types/operations/unary_operations/DateExtractOperation.cpp
@@ -23,6 +23,7 @@
#include <cstdint>
#include <memory>
#include <string>
+#include <type_traits>
#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
#include <utility>
@@ -35,6 +36,7 @@
#include "storage/ValueAccessor.hpp"
#include "storage/ValueAccessorUtil.hpp"
#include "types/DatetimeLit.hpp"
+#include "types/IntType.hpp"
#include "types/LongType.hpp"
#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
@@ -46,12 +48,13 @@
#include "glog/logging.h"
+using std::int32_t;
using std::int64_t;
namespace quickstep {
template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToTypedValue(
+TypedValue DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToTypedValue(
const TypedValue &argument) const {
if (argument_nullable && argument.isNull()) {
return TypedValue(kLong);
@@ -61,7 +64,17 @@ TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToTypedVa
}
template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr(const void *argument) const {
+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);
}
@@ -70,7 +83,16 @@ TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr
}
template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToColumnVector(
+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.
@@ -96,9 +118,36 @@ ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToColu
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* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessor(
+ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessor(
ValueAccessor *accessor,
const attribute_id argument_attr_id) const {
return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
@@ -121,11 +170,36 @@ ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValu
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* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessorForJoin(
+ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessorForJoin(
ValueAccessor *accessor,
const bool use_left_relation,
const attribute_id argument_attr_id,
@@ -151,10 +225,38 @@ ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValu
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 DatetimeLit *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 DateExtractUncheckedOperator<unit, argument_nullable>::dateExtract(const DatetimeLit &argument) const {
+inline int64_t DatetimeExtractUncheckedOperator<unit, argument_nullable>::dateExtract(const DatetimeLit &argument) const {
switch (unit) {
case DateExtractUnit::kYear:
return argument.yearField();
@@ -169,6 +271,18 @@ inline int64_t DateExtractUncheckedOperator<unit, argument_nullable>::dateExtrac
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.");
}
}
@@ -265,22 +379,35 @@ std::string DateExtractOperation::getName() const {
}
const Type* DateExtractOperation::pushDownTypeHint(const Type *type_hint) const {
- /*if (type_hint == nullptr) {
+ if (type_hint == nullptr) {
return nullptr;
}
if (type_hint->getTypeID() == kLong) {
- return &TypeFactory::GetType(kDatetime, type_hint->isNullable());
+ switch (unit_) {
+ case DateExtractUnit::kYear: // Fall through.
+ 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.
+ case DateExtractUnit::kMinute:
+ case DateExtractUnit::kSecond:
+ return &TypeFactory::GetType(kDatetime, type_hint->isNullable());
+ default:
+ return nullptr;
+ }
} else {
return nullptr;
- }*/
- return nullptr;
+ }
}
TypedValue DateExtractOperation::applyToChecked(const TypedValue &argument,
const Type &argument_type) const {
- if ((argument.getTypeID() != TypeID::kDatetime)
- || (argument_type.getTypeID() != TypeID::kDatetime)) {
+ 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()]
@@ -289,14 +416,34 @@ TypedValue DateExtractOperation::applyToChecked(const TypedValue &argument,
}
if (argument.isNull()) {
- return TypedValue(kLong);
+ 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:
- return TypedValue(argument.getLiteral<DatetimeLit>().yearField());
- case DateExtractUnit::kMonth:
- return TypedValue(argument.getLiteral<DatetimeLit>().monthField());
+ 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:
@@ -313,45 +460,80 @@ TypedValue DateExtractOperation::applyToChecked(const TypedValue &argument,
UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperatorForTypeHelper(const Type &type) const {
switch (unit_) {
- case DateExtractUnit::kYear:
- if (type.isNullable()) {
- return new DateExtractUncheckedOperator<DateExtractUnit::kYear, true>();
+ 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 {
- return new DateExtractUncheckedOperator<DateExtractUnit::kYear, false>();
+ 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.isNullable()) {
- return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, true>();
+ }
+ 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 {
- return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, false>();
+ // 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 DateExtractUncheckedOperator<DateExtractUnit::kDay, true>();
+ return new DatetimeExtractUncheckedOperator<DateExtractUnit::kDay, true>();
} else {
- return new DateExtractUncheckedOperator<DateExtractUnit::kDay, false>();
+ return new DatetimeExtractUncheckedOperator<DateExtractUnit::kDay, false>();
}
case DateExtractUnit::kHour:
if (type.isNullable()) {
- return new DateExtractUncheckedOperator<DateExtractUnit::kHour, true>();
+ return new DatetimeExtractUncheckedOperator<DateExtractUnit::kHour, true>();
} else {
- return new DateExtractUncheckedOperator<DateExtractUnit::kHour, false>();
+ return new DatetimeExtractUncheckedOperator<DateExtractUnit::kHour, false>();
}
case DateExtractUnit::kMinute:
if (type.isNullable()) {
- return new DateExtractUncheckedOperator<DateExtractUnit::kMinute, true>();
+ return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMinute, true>();
} else {
- return new DateExtractUncheckedOperator<DateExtractUnit::kMinute, false>();
+ return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMinute, false>();
}
case DateExtractUnit::kSecond:
if (type.isNullable()) {
- return new DateExtractUncheckedOperator<DateExtractUnit::kSecond, true>();
+ return new DatetimeExtractUncheckedOperator<DateExtractUnit::kSecond, true>();
} else {
- return new DateExtractUncheckedOperator<DateExtractUnit::kSecond, false>();
+ 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());
+ }
+ } else {
+ return nullptr;
+ }
+}
+
} // namespace quickstep
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/483901f4/types/operations/unary_operations/DateExtractOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.hpp b/types/operations/unary_operations/DateExtractOperation.hpp
index fd12bed..f8c091b 100644
--- a/types/operations/unary_operations/DateExtractOperation.hpp
+++ b/types/operations/unary_operations/DateExtractOperation.hpp
@@ -61,6 +61,40 @@ enum class DateExtractUnit {
};
/**
+ * @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>
@@ -89,7 +123,7 @@ class DateExtractUncheckedOperator : public UncheckedUnaryOperator {
#endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
private:
- inline std::int64_t dateExtract(const DatetimeLit &argument) const;
+ inline std::int32_t dateExtract(const DateLit &argument) const;
DISALLOW_COPY_AND_ASSIGN(DateExtractUncheckedOperator);
};
@@ -114,23 +148,17 @@ class DateExtractOperation : public UnaryOperation {
std::string getName() const override;
bool canApplyToType(const Type &type) const override {
- return type.getTypeID() == TypeID::kDatetime;
+ return type.getTypeID() == TypeID::kDatetime || type.getTypeID() == kDate;
}
- const Type* resultTypeForArgumentType(const Type &type) const override {
- if (canApplyToType(type)) {
- return &LongType::Instance(type.isNullable());
- } else {
- return nullptr;
- }
- }
+ const Type* resultTypeForArgumentType(const Type &type) const override;
const Type* fixedNullableResultType() const override {
- return &LongType::InstanceNullable();
+ return nullptr;
}
bool resultTypeIsPlausible(const Type &result_type) const override {
- return (result_type.getTypeID() == kLong);
+ return result_type.getTypeID() == kLong || result_type.getTypeID() == kInt;
}
const Type* pushDownTypeHint(const Type *type_hint) const override;
@@ -139,7 +167,7 @@ class DateExtractOperation : public UnaryOperation {
const Type &argument_type) const override;
UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const override {
- DCHECK_EQ(TypeID::kDatetime, type.getTypeID());
+ DCHECK(canApplyToType(type));
return makeUncheckedUnaryOperatorForTypeHelper(type);
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/483901f4/types/operations/unary_operations/tests/DateExtractOperation_unittest.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/tests/DateExtractOperation_unittest.cpp b/types/operations/unary_operations/tests/DateExtractOperation_unittest.cpp
index ec14408..6cff66c 100644
--- a/types/operations/unary_operations/tests/DateExtractOperation_unittest.cpp
+++ b/types/operations/unary_operations/tests/DateExtractOperation_unittest.cpp
@@ -77,19 +77,22 @@ class DateExtractOperationTest : public ::testing::Test {
static void CheckFixedNullableResultTypeForField(const DateExtractUnit field) {
const Type *fixed_result_type
= DateExtractOperation::Instance(field).fixedNullableResultType();
- ASSERT_NE(fixed_result_type, nullptr);
- EXPECT_TRUE(TypeFactory::GetType(kLong, true).equals(*fixed_result_type));
+ ASSERT_EQ(fixed_result_type, nullptr);
}
static void CheckResultTypeIsPlausibleForField(const DateExtractUnit field) {
- // Only Long is plausible.
+ // Long and Int are plausible.
EXPECT_TRUE(DateExtractOperation::Instance(field).resultTypeIsPlausible(
TypeFactory::GetType(kLong, false)));
EXPECT_TRUE(DateExtractOperation::Instance(field).resultTypeIsPlausible(
TypeFactory::GetType(kLong, true)));
+ EXPECT_TRUE(DateExtractOperation::Instance(field).resultTypeIsPlausible(
+ TypeFactory::GetType(kInt, false)));
+ EXPECT_TRUE(DateExtractOperation::Instance(field).resultTypeIsPlausible(
+ TypeFactory::GetType(kInt, true)));
for (const TypeID type_id
- : {kInt, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval}) {
+ : {kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval}) {
EXPECT_FALSE(DateExtractOperation::Instance(field).resultTypeIsPlausible(
TypeFactory::GetType(type_id, false)));
EXPECT_FALSE(DateExtractOperation::Instance(field).resultTypeIsPlausible(
@@ -109,12 +112,17 @@ class DateExtractOperationTest : public ::testing::Test {
static void CheckPushDownTypeHintForField(const DateExtractUnit field) {
const UnaryOperation &op = DateExtractOperation::Instance(field);
- // If hint is Long, then the argument is a Datetime with the same
- // nullability.
const Type *argument_hint
= op.pushDownTypeHint(&TypeFactory::GetType(kLong, true));
- ASSERT_NE(argument_hint, nullptr);
- EXPECT_TRUE(TypeFactory::GetType(kDatetime, true).equals(*argument_hint));
+ if ((field == DateExtractUnit::kMonth) || (field == DateExtractUnit::kYear)) {
+ // If field is either Year or Month, the argument is NULL.
+ ASSERT_EQ(argument_hint, nullptr);
+ } else {
+ // Otherwise, if hint is Long, then the argument is a Datetime with the
+ // same nullability.
+ ASSERT_NE(argument_hint, nullptr);
+ EXPECT_TRUE(TypeFactory::GetType(kDatetime, true).equals(*argument_hint));
+ }
argument_hint = op.pushDownTypeHint(&TypeFactory::GetType(kLong, false));
ASSERT_NE(argument_hint, nullptr);