diff --git a/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc b/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc index 249c5ad92f4..29133a576d0 100644 --- a/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc +++ b/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc @@ -2660,6 +2660,13 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) { std::move(exec))); } + // Add subtract(duration, duration) -> duration + for (auto unit : TimeUnit::values()) { + InputType in_type(match::DurationTypeUnit(unit)); + auto exec = ArithmeticExecFromOp(Type::DURATION); + DCHECK_OK(subtract->AddKernel({in_type, in_type}, duration(unit), std::move(exec))); + } + // Add subtract(time32, time32) -> duration for (auto unit : {TimeUnit::SECOND, TimeUnit::MILLI}) { InputType in_type(match::Time32TypeUnit(unit)); @@ -2714,6 +2721,15 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) { OutputType(FirstType), std::move(exec))); } + // Add subtract_checked(duration, duration) -> duration + for (auto unit : TimeUnit::values()) { + InputType in_type(match::DurationTypeUnit(unit)); + auto exec = + ArithmeticExecFromOp(Type::DURATION); + DCHECK_OK( + subtract_checked->AddKernel({in_type, in_type}, duration(unit), std::move(exec))); + } + // Add subtract_checked(date32, date32) -> duration(TimeUnit::SECOND) auto exec_date_32_checked = ScalarBinaryEqualTypes::Exec; diff --git a/cpp/src/arrow/compute/kernels/scalar_temporal_test.cc b/cpp/src/arrow/compute/kernels/scalar_temporal_test.cc index 7efb9ce88bb..560699c09ed 100644 --- a/cpp/src/arrow/compute/kernels/scalar_temporal_test.cc +++ b/cpp/src/arrow/compute/kernels/scalar_temporal_test.cc @@ -1429,6 +1429,32 @@ TEST_F(ScalarTemporalTest, TestTemporalSubtractTimeAndDuration) { } } +TEST_F(ScalarTemporalTest, TestTemporalSubtractDuration) { + for (auto op : {"subtract", "subtract_checked"}) { + for (auto u : TimeUnit::values()) { + auto unit = duration(u); + CheckScalarBinary(op, ArrayFromJSON(unit, times_s2), ArrayFromJSON(unit, times_s), + ArrayFromJSON(unit, seconds_between_time)); + } + + auto seconds_3 = ArrayFromJSON(duration(TimeUnit::SECOND), R"([3, null])"); + auto milliseconds_2k = ArrayFromJSON(duration(TimeUnit::MILLI), R"([2000, null])"); + auto milliseconds_1k = ArrayFromJSON(duration(TimeUnit::MILLI), R"([1000, null])"); + CheckScalarBinary(op, seconds_3, milliseconds_2k, milliseconds_1k); + } + + for (auto unit : TimeUnit::values()) { + auto duration_ty = duration(unit); + auto arr1 = ArrayFromJSON(duration_ty, R"([-9223372036854775808, null])"); + auto arr2 = ArrayFromJSON(duration_ty, R"([1, null])"); + auto arr3 = ArrayFromJSON(duration_ty, R"([9223372036854775807, null])"); + + CheckScalarBinary("subtract", arr1, arr2, arr3); + EXPECT_RAISES_WITH_MESSAGE_THAT(Invalid, ::testing::HasSubstr("overflow"), + CallFunction("subtract_checked", {arr1, arr2})); + } +} + 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", diff --git a/docs/source/cpp/compute.rst b/docs/source/cpp/compute.rst index 72b19bb4979..97f5f8c12e4 100644 --- a/docs/source/cpp/compute.rst +++ b/docs/source/cpp/compute.rst @@ -423,39 +423,39 @@ floating-point arguments will cast all arguments to floating-point, while mixed decimal and integer arguments will cast all arguments to decimals. Mixed time resolution temporal inputs will be cast to finest input resolution. -+------------------+--------+----------------------------+----------------------------+-------+ -| Function name | Arity | Input types | Output type | Notes | -+==================+========+============================+============================+=======+ -| abs | Unary | Numeric | Numeric | | -+------------------+--------+----------------------------+----------------------------+-------+ -| abs_checked | Unary | Numeric | Numeric | | -+------------------+--------+----------------------------+----------------------------+-------+ -| add | Binary | Numeric/Temporal | Numeric/Temporal | \(1) | -+------------------+--------+----------------------------+----------------------------+-------+ -| add_checked | Binary | Numeric/Temporal | Numeric/Temporal | \(1) | -+------------------+--------+----------------------------+----------------------------+-------+ -| divide | Binary | Numeric | Numeric | \(1) | -+------------------+--------+----------------------------+----------------------------+-------+ -| divide_checked | Binary | Numeric | Numeric | \(1) | -+------------------+--------+----------------------------+----------------------------+-------+ -| multiply | Binary | Numeric | Numeric | \(1) | -+------------------+--------+----------------------------+----------------------------+-------+ -| multiply_checked | Binary | Numeric | Numeric | \(1) | -+------------------+--------+----------------------------+----------------------------+-------+ -| negate | Unary | Numeric | Numeric | | -+------------------+--------+----------------------------+----------------------------+-------+ -| negate_checked | Unary | Signed Numeric | Signed Numeric | | -+------------------+--------+----------------------------+----------------------------+-------+ -| power | Binary | Numeric | Numeric | | -+------------------+--------+----------------------------+----------------------------+-------+ -| power_checked | Binary | Numeric | Numeric | | -+------------------+--------+----------------------------+----------------------------+-------+ -| sign | Unary | Numeric | Int8/Float32/Float64 | \(2) | -+------------------+--------+----------------------------+----------------------------+-------+ -| subtract | Binary | Numeric/Temporal | Numeric/Temporal | \(1) | -+------------------+--------+----------------------------+----------------------------+-------+ -| subtract_checked | Binary | Numeric/Temporal | Numeric/Temporal | \(1) | -+------------------+--------+----------------------------+----------------------------+-------+ ++------------------+--------+------------------+----------------------+-------+ +| Function name | Arity | Input types | Output type | Notes | ++==================+========+==================+======================+=======+ +| abs | Unary | Numeric | Numeric | | ++------------------+--------+------------------+----------------------+-------+ +| abs_checked | Unary | Numeric | Numeric | | ++------------------+--------+------------------+----------------------+-------+ +| add | Binary | Numeric/Temporal | Numeric/Temporal | \(1) | ++------------------+--------+------------------+----------------------+-------+ +| add_checked | Binary | Numeric/Temporal | Numeric/Temporal | \(1) | ++------------------+--------+------------------+----------------------+-------+ +| divide | Binary | Numeric | Numeric | \(1) | ++------------------+--------+------------------+----------------------+-------+ +| divide_checked | Binary | Numeric | Numeric | \(1) | ++------------------+--------+------------------+----------------------+-------+ +| multiply | Binary | Numeric | Numeric | \(1) | ++------------------+--------+------------------+----------------------+-------+ +| multiply_checked | Binary | Numeric | Numeric | \(1) | ++------------------+--------+------------------+----------------------+-------+ +| negate | Unary | Numeric | Numeric | | ++------------------+--------+------------------+----------------------+-------+ +| negate_checked | Unary | Signed Numeric | Signed Numeric | | ++------------------+--------+------------------+----------------------+-------+ +| power | Binary | Numeric | Numeric | | ++------------------+--------+------------------+----------------------+-------+ +| power_checked | Binary | Numeric | Numeric | | ++------------------+--------+------------------+----------------------+-------+ +| sign | Unary | Numeric | Int8/Float32/Float64 | \(2) | ++------------------+--------+------------------+----------------------+-------+ +| subtract | Binary | Numeric/Temporal | Numeric/Temporal | \(1) | ++------------------+--------+------------------+----------------------+-------+ +| subtract_checked | Binary | Numeric/Temporal | Numeric/Temporal | \(1) | ++------------------+--------+------------------+----------------------+-------+ * \(1) Precision and scale of computed DECIMAL results