Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion cpp/src/arrow/compute/kernels/codegen_internal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions cpp/src/arrow/compute/kernels/codegen_internal_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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());
Expand All @@ -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());
Expand Down
30 changes: 30 additions & 0 deletions cpp/src/arrow/compute/kernels/scalar_arithmetic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)));

// ----------------------------------------------------------------------
Expand Down
39 changes: 39 additions & 0 deletions cpp/src/arrow/compute/kernels/scalar_temporal_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down