You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ap...@apache.org on 2022/02/08 12:34:56 UTC
[arrow] branch master updated: ARROW-14098: [C++] subtract(time, time) -> duration kernel
This is an automated email from the ASF dual-hosted git repository.
apitrou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/master by this push:
new 75bcece ARROW-14098: [C++] subtract(time, time) -> duration kernel
75bcece is described below
commit 75bcece383b583daeb6000a77819eee35c1a8f70
Author: Rok <ro...@mihevc.org>
AuthorDate: Tue Feb 8 13:33:01 2022 +0100
ARROW-14098: [C++] subtract(time, time) -> duration kernel
This is to resolve [ARROW-14098](https://issues.apache.org/jira/browse/ARROW-14098).
Closes #12105 from rok/ARROW-14098
Authored-by: Rok <ro...@mihevc.org>
Signed-off-by: Antoine Pitrou <an...@python.org>
---
cpp/src/arrow/compute/kernels/codegen_internal.cc | 9 ++++-
.../arrow/compute/kernels/codegen_internal_test.cc | 8 +++--
cpp/src/arrow/compute/kernels/scalar_arithmetic.cc | 30 +++++++++++++++++
.../arrow/compute/kernels/scalar_temporal_test.cc | 39 ++++++++++++++++++++++
4 files changed, 83 insertions(+), 3 deletions(-)
diff --git a/cpp/src/arrow/compute/kernels/codegen_internal.cc b/cpp/src/arrow/compute/kernels/codegen_internal.cc
index 1e06a36..26c12eb 100644
--- a/cpp/src/arrow/compute/kernels/codegen_internal.cc
+++ b/cpp/src/arrow/compute/kernels/codegen_internal.cc
@@ -120,7 +120,14 @@ void ReplaceTemporalTypes(const TimeUnit::type unit, std::vector<ValueDescr>* de
continue;
}
case Type::TIME32:
- case Type::TIME64:
+ case Type::TIME64: {
+ if (unit > TimeUnit::MILLI) {
+ it->type = time64(unit);
+ } else {
+ it->type = time32(unit);
+ }
+ continue;
+ }
case Type::DURATION: {
it->type = duration(unit);
continue;
diff --git a/cpp/src/arrow/compute/kernels/codegen_internal_test.cc b/cpp/src/arrow/compute/kernels/codegen_internal_test.cc
index 6b68632..c2e17e3 100644
--- a/cpp/src/arrow/compute/kernels/codegen_internal_test.cc
+++ b/cpp/src/arrow/compute/kernels/codegen_internal_test.cc
@@ -198,6 +198,10 @@ TEST(TestDispatchBest, CommonTemporalResolution) {
ASSERT_EQ(TimeUnit::MILLI, CommonTemporalResolution(args.data(), args.size()));
args = {timestamp(TimeUnit::SECOND, "UTC"), timestamp(TimeUnit::SECOND, tz)};
ASSERT_EQ(TimeUnit::SECOND, CommonTemporalResolution(args.data(), args.size()));
+ args = {time32(TimeUnit::MILLI), duration(TimeUnit::SECOND)};
+ ASSERT_EQ(TimeUnit::MILLI, CommonTemporalResolution(args.data(), args.size()));
+ args = {time64(TimeUnit::MICRO), duration(TimeUnit::NANO)};
+ ASSERT_EQ(TimeUnit::NANO, CommonTemporalResolution(args.data(), args.size()));
}
TEST(TestDispatchBest, ReplaceTemporalTypes) {
@@ -215,7 +219,7 @@ TEST(TestDispatchBest, ReplaceTemporalTypes) {
ty = CommonTemporalResolution(args.data(), args.size());
ReplaceTemporalTypes(ty, &args);
AssertTypeEqual(args[0].type, timestamp(TimeUnit::MILLI));
- AssertTypeEqual(args[1].type, duration(TimeUnit::MILLI));
+ AssertTypeEqual(args[1].type, time32(TimeUnit::MILLI));
args = {duration(TimeUnit::SECOND), date64()};
ty = CommonTemporalResolution(args.data(), args.size());
@@ -233,7 +237,7 @@ TEST(TestDispatchBest, ReplaceTemporalTypes) {
ty = CommonTemporalResolution(args.data(), args.size());
ReplaceTemporalTypes(ty, &args);
AssertTypeEqual(args[0].type, timestamp(TimeUnit::NANO, tz));
- AssertTypeEqual(args[1].type, duration(TimeUnit::NANO));
+ AssertTypeEqual(args[1].type, time64(TimeUnit::NANO));
args = {timestamp(TimeUnit::SECOND, tz), date64()};
ty = CommonTemporalResolution(args.data(), args.size());
diff --git a/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc b/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc
index b8dae54..dd04765 100644
--- a/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc
+++ b/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc
@@ -2481,6 +2481,20 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {
std::move(exec)));
}
+ // Add subtract(time32, time32) -> duration
+ for (auto unit : {TimeUnit::SECOND, TimeUnit::MILLI}) {
+ InputType in_type(match::Time32TypeUnit(unit));
+ auto exec = ScalarBinaryEqualTypes<Int64Type, Time32Type, Subtract>::Exec;
+ DCHECK_OK(subtract->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
+ }
+
+ // Add subtract(time64, time64) -> duration
+ for (auto unit : {TimeUnit::MICRO, TimeUnit::NANO}) {
+ InputType in_type(match::Time64TypeUnit(unit));
+ auto exec = ScalarBinaryEqualTypes<Int64Type, Time64Type, Subtract>::Exec;
+ DCHECK_OK(subtract->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
+ }
+
// Add subtract(date32, date32) -> duration(TimeUnit::SECOND)
InputType in_type_date_32(date32());
auto exec_date_32 = ScalarBinaryEqualTypes<Int64Type, Date32Type, SubtractDate32>::Exec;
@@ -2533,6 +2547,22 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {
duration(TimeUnit::MILLI),
std::move(exec_date_64_checked)));
+ // Add subtract_checked(time32, time32) -> duration
+ for (auto unit : {TimeUnit::SECOND, TimeUnit::MILLI}) {
+ InputType in_type(match::Time32TypeUnit(unit));
+ auto exec = ScalarBinaryEqualTypes<Int64Type, Time32Type, SubtractChecked>::Exec;
+ DCHECK_OK(
+ subtract_checked->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
+ }
+
+ // Add subtract_checked(time64, time64) -> duration
+ for (auto unit : {TimeUnit::MICRO, TimeUnit::NANO}) {
+ InputType in_type(match::Time64TypeUnit(unit));
+ auto exec = ScalarBinaryEqualTypes<Int64Type, Time64Type, SubtractChecked>::Exec;
+ DCHECK_OK(
+ subtract_checked->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
+ }
+
DCHECK_OK(registry->AddFunction(std::move(subtract_checked)));
// ----------------------------------------------------------------------
diff --git a/cpp/src/arrow/compute/kernels/scalar_temporal_test.cc b/cpp/src/arrow/compute/kernels/scalar_temporal_test.cc
index 67a5a8b..7b7a314 100644
--- a/cpp/src/arrow/compute/kernels/scalar_temporal_test.cc
+++ b/cpp/src/arrow/compute/kernels/scalar_temporal_test.cc
@@ -1117,6 +1117,45 @@ TEST_F(ScalarTemporalTest, TestTemporalSubtractTimestamp) {
}
}
+TEST_F(ScalarTemporalTest, TestTemporalSubtractTime) {
+ for (auto op : {"subtract", "subtract_checked"}) {
+ auto arr_s = ArrayFromJSON(time32(TimeUnit::SECOND), times_s);
+ auto arr_s2 = ArrayFromJSON(time32(TimeUnit::SECOND), times_s2);
+ auto arr_ms = ArrayFromJSON(time32(TimeUnit::MILLI), times_ms);
+ auto arr_ms2 = ArrayFromJSON(time32(TimeUnit::MILLI), times_ms2);
+ auto arr_us = ArrayFromJSON(time64(TimeUnit::MICRO), times_us);
+ auto arr_us2 = ArrayFromJSON(time64(TimeUnit::MICRO), times_us2);
+ auto arr_ns = ArrayFromJSON(time64(TimeUnit::NANO), times_ns);
+ auto arr_ns2 = ArrayFromJSON(time64(TimeUnit::NANO), times_ns2);
+
+ CheckScalarBinary(op, arr_s2, arr_s,
+ ArrayFromJSON(duration(TimeUnit::SECOND), seconds_between_time));
+ CheckScalarBinary(
+ op, arr_ms2, arr_ms,
+ ArrayFromJSON(duration(TimeUnit::MILLI), milliseconds_between_time));
+ CheckScalarBinary(
+ op, arr_us2, arr_us,
+ ArrayFromJSON(duration(TimeUnit::MICRO), microseconds_between_time));
+ CheckScalarBinary(op, arr_ns2, arr_ns,
+ ArrayFromJSON(duration(TimeUnit::NANO), nanoseconds_between_time));
+
+ CheckScalarBinary(op, arr_s, arr_s, ArrayFromJSON(duration(TimeUnit::SECOND), zeros));
+ CheckScalarBinary(op, arr_ms, arr_ms,
+ ArrayFromJSON(duration(TimeUnit::MILLI), zeros));
+ CheckScalarBinary(op, arr_us, arr_us,
+ ArrayFromJSON(duration(TimeUnit::MICRO), zeros));
+ CheckScalarBinary(op, arr_ns, arr_ns, ArrayFromJSON(duration(TimeUnit::NANO), zeros));
+
+ auto seconds_3 = ArrayFromJSON(time32(TimeUnit::SECOND), R"([3, null])");
+ auto milliseconds_2k = ArrayFromJSON(time32(TimeUnit::MILLI), R"([1999, null])");
+ auto milliseconds_1k = ArrayFromJSON(duration(TimeUnit::MILLI), R"([1001, null])");
+ auto microseconds_2M = ArrayFromJSON(time64(TimeUnit::MICRO), R"([1999999, null])");
+ auto microseconds_1M = ArrayFromJSON(duration(TimeUnit::MICRO), R"([1000001, null])");
+ CheckScalarBinary(op, seconds_3, milliseconds_2k, milliseconds_1k);
+ CheckScalarBinary(op, seconds_3, microseconds_2M, microseconds_1M);
+ }
+}
+
TEST_F(ScalarTemporalTest, TestTemporalDifferenceWeeks) {
auto raw_days = ArrayFromJSON(timestamp(TimeUnit::SECOND), R"([
"2021-08-09", "2021-08-10", "2021-08-11", "2021-08-12", "2021-08-13", "2021-08-14", "2021-08-15",