This is an automated email from the ASF dual-hosted git repository.
ravindra 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 f8e2d6a ARROW-5872: [C++][Gandiva] Support mod(double, double)
function in Gandiva
f8e2d6a is described below
commit f8e2d6afd694f5d63ba061a8790ce717dd16e3e8
Author: Prudhvi Porandla <[email protected]>
AuthorDate: Wed Jul 10 15:32:44 2019 +0530
ARROW-5872: [C++][Gandiva] Support mod(double, double) function in Gandiva
Author: Prudhvi Porandla <[email protected]>
Closes #4820 from pprudhvi/mod-double and squashes the following commits:
332e47304 <Prudhvi Porandla> add mod(double, double) function
---
cpp/src/gandiva/function_registry_arithmetic.cc | 1 +
cpp/src/gandiva/precompiled/arithmetic_ops.cc | 10 +++++++++
cpp/src/gandiva/precompiled/arithmetic_ops_test.cc | 25 +++++++++++++++++++++-
cpp/src/gandiva/precompiled/types.h | 1 +
4 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/cpp/src/gandiva/function_registry_arithmetic.cc
b/cpp/src/gandiva/function_registry_arithmetic.cc
index f5d5ce7..e3fb447 100644
--- a/cpp/src/gandiva/function_registry_arithmetic.cc
+++ b/cpp/src/gandiva/function_registry_arithmetic.cc
@@ -66,6 +66,7 @@ std::vector<NativeFunction> GetArithmeticFunctionRegistry() {
BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(multiply, decimal128),
BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(divide, decimal128),
BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(mod, decimal128),
+ BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(mod, 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 9502640..76fa32b 100644
--- a/cpp/src/gandiva/precompiled/arithmetic_ops.cc
+++ b/cpp/src/gandiva/precompiled/arithmetic_ops.cc
@@ -17,6 +17,7 @@
extern "C" {
+#include <math.h>
#include "./types.h"
// Expand inner macro for all numeric types.
@@ -68,6 +69,15 @@ NUMERIC_TYPES(BINARY_SYMMETRIC, multiply, *)
MOD_OP(mod, int64, int32, int32)
MOD_OP(mod, int64, int64, int64)
+float64 mod_float64_float64(int64_t context, float64 x, float64 y) {
+ if (y == 0.0) {
+ char const* err_msg = "divide by zero error";
+ gdv_fn_context_set_error_msg(context, err_msg);
+ return 0.0;
+ }
+ return fmod(x, y);
+}
+
// Relational binary fns : left, right params are same, return is bool.
#define BINARY_RELATIONAL(NAME, TYPE, OP) \
FORCE_INLINE \
diff --git a/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc
b/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc
index e4f4ad8..a7b6269 100644
--- a/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc
+++ b/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc
@@ -33,7 +33,30 @@ TEST(TestArithmeticOps, TestIsDistinctFrom) {
EXPECT_EQ(is_not_distinct_from_int32_int32(1000, true, 1000, true), true);
}
-TEST(TestArithmeticOps, TestMod) { EXPECT_EQ(mod_int64_int32(10, 0), 10); }
+TEST(TestArithmeticOps, TestMod) {
+ gandiva::ExecutionContext context;
+ EXPECT_EQ(mod_int64_int32(10, 0), 10);
+
+ const double acceptable_abs_error = 0.00000000001; // 1e-10
+
+ EXPECT_DOUBLE_EQ(mod_float64_float64(reinterpret_cast<int64>(&context), 2.5,
0.0), 0.0);
+ EXPECT_TRUE(context.has_error());
+ EXPECT_EQ(context.get_error(), "divide by zero error");
+
+ context.Reset();
+ EXPECT_NEAR(mod_float64_float64(reinterpret_cast<int64>(&context), 2.5,
1.2), 0.1,
+ acceptable_abs_error);
+ EXPECT_FALSE(context.has_error());
+
+ context.Reset();
+ EXPECT_DOUBLE_EQ(mod_float64_float64(reinterpret_cast<int64>(&context), 2.5,
2.5), 0.0);
+ EXPECT_FALSE(context.has_error());
+
+ context.Reset();
+ EXPECT_NEAR(mod_float64_float64(reinterpret_cast<int64>(&context), 9.2,
3.7), 1.8,
+ acceptable_abs_error);
+ EXPECT_FALSE(context.has_error());
+}
TEST(TestArithmeticOps, TestDivide) {
gandiva::ExecutionContext context;
diff --git a/cpp/src/gandiva/precompiled/types.h
b/cpp/src/gandiva/precompiled/types.h
index 493a3ae..9dbf67e 100644
--- a/cpp/src/gandiva/precompiled/types.h
+++ b/cpp/src/gandiva/precompiled/types.h
@@ -121,6 +121,7 @@ double months_between_timestamp_timestamp(uint64, uint64);
int32 mem_compare(const char* left, int32 left_len, const char* right, int32
right_len);
int32 mod_int64_int32(int64 left, int32 right);
+float64 mod_float64_float64(int64 context, float64 left, float64 right);
int64 divide_int64_int64(int64 context, int64 in1, int64 in2);