diff --git a/cpp/src/gandiva/function_registry_arithmetic.cc b/cpp/src/gandiva/function_registry_arithmetic.cc index 6a74a19e20c..74e528acecb 100644 --- a/cpp/src/gandiva/function_registry_arithmetic.cc +++ b/cpp/src/gandiva/function_registry_arithmetic.cc @@ -68,6 +68,10 @@ std::vector GetArithmeticFunctionRegistry() { BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(divide, {}, decimal128), BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(mod, {"modulo"}, decimal128), BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(mod, {"modulo"}, float64), + BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(div, {}, int32), + BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(div, {}, int64), + BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(div, {}, float32), + BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(div, {}, float64), // compare functions BINARY_RELATIONAL_SAFE_NULL_IF_NULL(equal, {}, decimal128), diff --git a/cpp/src/gandiva/precompiled/arithmetic_ops.cc b/cpp/src/gandiva/precompiled/arithmetic_ops.cc index 76fa32b5696..9334e08ccf6 100644 --- a/cpp/src/gandiva/precompiled/arithmetic_ops.cc +++ b/cpp/src/gandiva/precompiled/arithmetic_ops.cc @@ -180,4 +180,32 @@ NUMERIC_BOOL_DATE_FUNCTION(IS_NOT_DISTINCT_FROM) NUMERIC_FUNCTION(DIVIDE) +#define DIV(TYPE) \ + FORCE_INLINE \ + TYPE div_##TYPE##_##TYPE(int64 context, TYPE in1, TYPE in2) { \ + if (in2 == 0) { \ + char const* err_msg = "divide by zero error"; \ + gdv_fn_context_set_error_msg(context, err_msg); \ + return 0; \ + } \ + return static_cast(in1 / in2); \ + } + +DIV(int32) +DIV(int64) + +#define DIV_FLOAT(TYPE) \ + FORCE_INLINE \ + TYPE div_##TYPE##_##TYPE(int64 context, TYPE in1, TYPE in2) { \ + if (in2 == 0) { \ + char const* err_msg = "divide by zero error"; \ + gdv_fn_context_set_error_msg(context, err_msg); \ + return 0; \ + } \ + return static_cast(::trunc(in1 / in2)); \ + } + +DIV_FLOAT(float32) +DIV_FLOAT(float64) + } // extern "C" diff --git a/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc b/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc index a7b6269b2fd..0375783fffb 100644 --- a/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc +++ b/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc @@ -69,4 +69,32 @@ TEST(TestArithmeticOps, TestDivide) { EXPECT_EQ(context.has_error(), false); } +TEST(TestArithmeticOps, TestDiv) { + gandiva::ExecutionContext context; + EXPECT_EQ(div_int64_int64(reinterpret_cast(&context), 101, 0), 0); + EXPECT_EQ(context.has_error(), true); + EXPECT_EQ(context.get_error(), "divide by zero error"); + context.Reset(); + + EXPECT_EQ(div_int64_int64(reinterpret_cast(&context), 101, 111), 0); + EXPECT_EQ(context.has_error(), false); + context.Reset(); + + EXPECT_EQ(div_float64_float64(reinterpret_cast(&context), 1010.1010, 2.1), + 481.0); + EXPECT_EQ(context.has_error(), false); + context.Reset(); + + EXPECT_EQ(div_float64_float64(reinterpret_cast(&context), 1010.1010, 0.00000), + 0.0); + EXPECT_EQ(context.has_error(), true); + EXPECT_EQ(context.get_error(), "divide by zero error"); + context.Reset(); + + EXPECT_EQ(div_float32_float32(reinterpret_cast(&context), 1010.1010f, 2.1f), + 481.0f); + EXPECT_EQ(context.has_error(), false); + context.Reset(); +} + } // namespace gandiva diff --git a/cpp/src/gandiva/precompiled/types.h b/cpp/src/gandiva/precompiled/types.h index 9dbf67e160c..397cf99ddf5 100644 --- a/cpp/src/gandiva/precompiled/types.h +++ b/cpp/src/gandiva/precompiled/types.h @@ -125,6 +125,10 @@ float64 mod_float64_float64(int64 context, float64 left, float64 right); int64 divide_int64_int64(int64 context, int64 in1, int64 in2); +int64 div_int64_int64(int64 context, int64 in1, int64 in2); +float32 div_float32_float32(int64 context, float32 in1, float32 in2); +float64 div_float64_float64(int64 context, float64 in1, float64 in2); + float64 cbrt_int32(int32); float64 cbrt_int64(int64); float64 cbrt_float32(float32);