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);
 

Reply via email to