Skip to content

Commit 16f6644

Browse files
authored
apacheGH-33588: [Substrait] Add Substrait→Acero mapping for round operationMajor: (apache#33775)
Adds binary round kernel for float types. Provides fallback for binary round from int types to double. Does not provide fallback for binary round for decimal types. Minor: Fixes fallback behavior to only affect the first argument. Corrects fallback error message to display the original type instead of the fallback type when the underlying type cannot be found. Round benchmark changed to be driven like arithmetic benchamrk instead of the string benchmark. Trivial: Renames Arithmetic to Round to match the containing module. Removes some unreachable code. * Closes: apache#33588 Authored-by: David Sisson <EpsilonPrime@users.noreply.github.com> Signed-off-by: Weston Pace <weston.pace@gmail.com>
1 parent de6e537 commit 16f6644

7 files changed

Lines changed: 799 additions & 332 deletions

File tree

‎cpp/src/arrow/compute/api_scalar.cc‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,8 @@ static auto kReplaceSubstringOptionsType =
330330
static auto kRoundOptionsType = GetFunctionOptionsType<RoundOptions>(
331331
DataMember("ndigits", &RoundOptions::ndigits),
332332
DataMember("round_mode", &RoundOptions::round_mode));
333+
static auto kRoundBinaryOptionsType = GetFunctionOptionsType<RoundBinaryOptions>(
334+
DataMember("round_mode", &RoundBinaryOptions::round_mode));
333335
static auto kRoundTemporalOptionsType = GetFunctionOptionsType<RoundTemporalOptions>(
334336
DataMember("multiple", &RoundTemporalOptions::multiple),
335337
DataMember("unit", &RoundTemporalOptions::unit),
@@ -498,6 +500,22 @@ RoundOptions::RoundOptions(int64_t ndigits, RoundMode round_mode)
498500
}
499501
constexpr char RoundOptions::kTypeName[];
500502

503+
RoundBinaryOptions::RoundBinaryOptions(RoundMode round_mode)
504+
: FunctionOptions(internal::kRoundBinaryOptionsType), round_mode(round_mode) {
505+
static_assert(RoundMode::HALF_DOWN > RoundMode::DOWN &&
506+
RoundMode::HALF_DOWN > RoundMode::UP &&
507+
RoundMode::HALF_DOWN > RoundMode::TOWARDS_ZERO &&
508+
RoundMode::HALF_DOWN > RoundMode::TOWARDS_INFINITY &&
509+
RoundMode::HALF_DOWN < RoundMode::HALF_UP &&
510+
RoundMode::HALF_DOWN < RoundMode::HALF_TOWARDS_ZERO &&
511+
RoundMode::HALF_DOWN < RoundMode::HALF_TOWARDS_INFINITY &&
512+
RoundMode::HALF_DOWN < RoundMode::HALF_TO_EVEN &&
513+
RoundMode::HALF_DOWN < RoundMode::HALF_TO_ODD,
514+
"Invalid order of round modes. Modes prefixed with HALF need to be "
515+
"enumerated last with HALF_DOWN being the first among them.");
516+
}
517+
constexpr char RoundBinaryOptions::kTypeName[];
518+
501519
RoundTemporalOptions::RoundTemporalOptions(int multiple, CalendarUnit unit,
502520
bool week_starts_monday,
503521
bool ceil_is_strictly_greater,
@@ -683,6 +701,11 @@ Result<Datum> Round(const Datum& arg, RoundOptions options, ExecContext* ctx) {
683701
return CallFunction("round", {arg}, &options, ctx);
684702
}
685703

704+
Result<Datum> RoundBinary(const Datum& arg1, const Datum& arg2,
705+
RoundBinaryOptions options, ExecContext* ctx) {
706+
return CallFunction("round_binary", {arg1, arg2}, &options, ctx);
707+
}
708+
686709
Result<Datum> RoundToMultiple(const Datum& arg, RoundToMultipleOptions options,
687710
ExecContext* ctx) {
688711
return CallFunction("round_to_multiple", {arg}, &options, ctx);

‎cpp/src/arrow/compute/api_scalar.h‎

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ class ARROW_EXPORT RoundOptions : public FunctionOptions {
9191
RoundMode round_mode;
9292
};
9393

94+
class ARROW_EXPORT RoundBinaryOptions : public FunctionOptions {
95+
public:
96+
explicit RoundBinaryOptions(RoundMode round_mode = RoundMode::HALF_TO_EVEN);
97+
static constexpr char const kTypeName[] = "RoundBinaryOptions";
98+
static RoundBinaryOptions Defaults() { return RoundBinaryOptions(); }
99+
/// Rounding and tie-breaking mode
100+
RoundMode round_mode;
101+
};
102+
94103
enum class CalendarUnit : int8_t {
95104
NANOSECOND,
96105
MICROSECOND,
@@ -872,16 +881,34 @@ Result<Datum> Sign(const Datum& arg, ExecContext* ctx = NULLPTR);
872881

873882
/// \brief Round a value to a given precision.
874883
///
875-
/// If argument is null the result will be null.
884+
/// If arg is null the result will be null.
876885
///
877-
/// \param[in] arg the value rounded
886+
/// \param[in] arg the value to be rounded
878887
/// \param[in] options rounding options (rounding mode and number of digits), optional
879888
/// \param[in] ctx the function execution context, optional
880889
/// \return the element-wise rounded value
881890
ARROW_EXPORT
882891
Result<Datum> Round(const Datum& arg, RoundOptions options = RoundOptions::Defaults(),
883892
ExecContext* ctx = NULLPTR);
884893

894+
/// \brief Round a value to a given precision.
895+
///
896+
/// If arg1 is null the result will be null.
897+
/// If arg2 is null then the result will be null. If arg2 is negative, then the rounding
898+
/// place will be shifted to the left (thus -1 would correspond to rounding to the nearest
899+
/// ten). If positive, the rounding place will shift to the right (and +1 would
900+
/// correspond to rounding to the nearest tenth).
901+
///
902+
/// \param[in] arg1 the value to be rounded
903+
/// \param[in] arg2 the number of significant digits to round to
904+
/// \param[in] options rounding options, optional
905+
/// \param[in] ctx the function execution context, optional
906+
/// \return the element-wise rounded value
907+
ARROW_EXPORT
908+
Result<Datum> RoundBinary(const Datum& arg1, const Datum& arg2,
909+
RoundBinaryOptions options = RoundBinaryOptions::Defaults(),
910+
ExecContext* ctx = NULLPTR);
911+
885912
/// \brief Round a value to a given multiple.
886913
///
887914
/// If argument is null the result will be null.

0 commit comments

Comments
 (0)