You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ra...@apache.org on 2022/07/20 10:02:16 UTC

[arrow] branch master updated: ARROW-17140: [C++][GANDIVA] Adding Floor function (#13655)

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 b3098347af ARROW-17140: [C++][GANDIVA] Adding Floor function (#13655)
b3098347af is described below

commit b3098347af21751c9741b7829506d999ffefb847
Author: Sahaj Gupta <10...@users.noreply.github.com>
AuthorDate: Wed Jul 20 15:32:09 2022 +0530

    ARROW-17140: [C++][GANDIVA] Adding Floor function (#13655)
    
    Adding Floor Function.
    
    Authored-by: SG011 <sa...@dremio.com>
    Signed-off-by: Pindikura Ravindra <ra...@dremio.com>
---
 cpp/src/gandiva/function_registry_arithmetic.cc    |  3 ++
 cpp/src/gandiva/precompiled/arithmetic_ops.cc      |  9 ++++
 cpp/src/gandiva/precompiled/arithmetic_ops_test.cc | 20 +++++++
 cpp/src/gandiva/precompiled/types.h                |  2 +
 cpp/src/gandiva/tests/projector_test.cc            | 62 ++++++++++++++++++++++
 5 files changed, 96 insertions(+)

diff --git a/cpp/src/gandiva/function_registry_arithmetic.cc b/cpp/src/gandiva/function_registry_arithmetic.cc
index 245834f3c7..2eae9b5538 100644
--- a/cpp/src/gandiva/function_registry_arithmetic.cc
+++ b/cpp/src/gandiva/function_registry_arithmetic.cc
@@ -196,6 +196,9 @@ std::vector<NativeFunction> GetArithmeticFunctionRegistry() {
       // ceil functions
       UNARY_SAFE_NULL_IF_NULL(ceiling, {"ceil"}, float32, float32),
       UNARY_SAFE_NULL_IF_NULL(ceiling, {"ceil"}, float64, float64),
+      // floor functions
+      UNARY_SAFE_NULL_IF_NULL(floor, {}, float32, float32),
+      UNARY_SAFE_NULL_IF_NULL(floor, {}, float64, float64),
 
       // compare functions
       BINARY_RELATIONAL_BOOL_FN(equal, ({"eq", "same"})),
diff --git a/cpp/src/gandiva/precompiled/arithmetic_ops.cc b/cpp/src/gandiva/precompiled/arithmetic_ops.cc
index 51647cf0a1..309199c16d 100644
--- a/cpp/src/gandiva/precompiled/arithmetic_ops.cc
+++ b/cpp/src/gandiva/precompiled/arithmetic_ops.cc
@@ -499,6 +499,15 @@ CEILING(float64)
 
 #undef CEILING
 
+#define FLOOR(TYPE) \
+  FORCE_INLINE      \
+  gdv_##TYPE floor_##TYPE(gdv_##TYPE in1) { return static_cast<gdv_##TYPE>(floor(in1)); }
+
+FLOOR(float32)
+FLOOR(float64)
+
+#undef FLOOR
+
 #undef NUMERIC_FUNCTION
 #undef NUMERIC_TYPES
 
diff --git a/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc b/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc
index 6a7eb65207..b2dc805f2d 100644
--- a/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc
+++ b/cpp/src/gandiva/precompiled/arithmetic_ops_test.cc
@@ -633,4 +633,24 @@ TEST(TestArithmeticOps, TestCeilingFloatDouble) {
   EXPECT_EQ(ceiling_float64(-2147483647), -2147483647.0);
 }
 
+TEST(TestArithmeticOps, TestFloorFloatDouble) {
+  // ceiling from floats
+  EXPECT_EQ(floor_float32(6.6f), 6.0f);
+  EXPECT_EQ(floor_float32(-6.6f), -7.0f);
+  EXPECT_EQ(floor_float32(-6.3f), -7.0f);
+  EXPECT_EQ(floor_float32(0.0f), 0.0f);
+  EXPECT_EQ(floor_float32(-0), 0.0);
+
+  // ceiling from doubles
+  EXPECT_EQ(floor_float64(6.6), 6.0);
+  EXPECT_EQ(floor_float64(-6.6), -7.0);
+  EXPECT_EQ(floor_float64(-6.3), -7.0);
+  EXPECT_EQ(floor_float64(0.0), 0.0);
+  EXPECT_EQ(floor_float64(-0), 0.0);
+  EXPECT_EQ(floor_float64(999999.99999999999999999999999), 1000000.0);
+  EXPECT_EQ(floor_float64(-999999.99999999999999999999999), -1000000.0);
+  EXPECT_EQ(floor_float64(2147483647.7), 2147483647.0);
+  EXPECT_EQ(floor_float64(-2147483647), -2147483647.0);
+}
+
 }  // namespace gandiva
diff --git a/cpp/src/gandiva/precompiled/types.h b/cpp/src/gandiva/precompiled/types.h
index 26e0746397..a0a83f18dd 100644
--- a/cpp/src/gandiva/precompiled/types.h
+++ b/cpp/src/gandiva/precompiled/types.h
@@ -229,6 +229,8 @@ gdv_float32 sign_float32(gdv_float32 in);
 gdv_float64 sign_float64(gdv_float64 in);
 gdv_float32 ceiling_float32(gdv_float32 in);
 gdv_float64 ceiling_float64(gdv_float64 in);
+gdv_float32 floor_float32(gdv_float32 in);
+gdv_float64 floor_float64(gdv_float64 in);
 
 gdv_float32 round_float32(gdv_float32);
 gdv_float64 round_float64(gdv_float64);
diff --git a/cpp/src/gandiva/tests/projector_test.cc b/cpp/src/gandiva/tests/projector_test.cc
index 69a5ce7b2d..20b39bfe28 100644
--- a/cpp/src/gandiva/tests/projector_test.cc
+++ b/cpp/src/gandiva/tests/projector_test.cc
@@ -1779,6 +1779,68 @@ TEST_F(TestProjector, TestCeiling) {
   EXPECT_ARROW_ARRAY_EQUALS(out_float64, outputs2.at(0));
 }
 
+TEST_F(TestProjector, TestFloor) {
+  // input fields
+  auto field1 = field("f1", arrow::float32());
+  auto field2 = field("f2", arrow::float64());
+
+  // schema fields
+  auto schema1 = arrow::schema({field1});
+  auto schema2 = arrow::schema({field2});
+
+  // output fields
+  auto field3 = field("floor_float32", arrow::float32());
+  auto field4 = field("floor_float64", arrow::float64());
+
+  // Build expression
+  auto floor_float32 = TreeExprBuilder::MakeExpression("floor", {field1}, field3);
+  auto floor_float64 = TreeExprBuilder::MakeExpression("floor", {field2}, field4);
+
+  // Create a row-batch with some sample data
+  int num_records = 4;
+
+  std::shared_ptr<Projector> projector1;
+
+  auto status =
+      Projector::Make(schema1, {floor_float32}, TestConfiguration(), &projector1);
+  EXPECT_TRUE(status.ok()) << status.message();
+
+  // Create a row-batch with some sample data
+  auto array1 = MakeArrowArrayFloat32({1.1f, 2.2f, 3.3f, 4.4f}, {true, true, true, true});
+  auto in_batch1 = arrow::RecordBatch::Make(schema1, num_records, {array1});
+
+  auto out_float32 =
+      MakeArrowArrayFloat32({1.0f, 2.0f, 3.0f, 4.0f}, {true, true, true, true});
+
+  arrow::ArrayVector outputs1;
+
+  // Evaluate expression
+  status = projector1->Evaluate(*in_batch1, pool_, &outputs1);
+  EXPECT_TRUE(status.ok()) << status.message();
+
+  EXPECT_ARROW_ARRAY_EQUALS(out_float32, outputs1.at(0));
+
+  std::shared_ptr<Projector> projector2;
+
+  status = Projector::Make(schema2, {floor_float64}, TestConfiguration(), &projector2);
+  EXPECT_TRUE(status.ok()) << status.message();
+
+  // Create a row-batch with some sample data
+  auto array2 = MakeArrowArrayFloat64({1.1, 2.2, 3.3, 4.4}, {true, true, true, true});
+  auto in_batch2 = arrow::RecordBatch::Make(schema2, num_records, {array2});
+
+  auto out_float64 =
+      MakeArrowArrayFloat64({1.0, 2.0, 3.0, 4.0}, {true, true, true, true});
+
+  arrow::ArrayVector outputs2;
+
+  // Evaluate expression
+  status = projector2->Evaluate(*in_batch2, pool_, &outputs2);
+  EXPECT_TRUE(status.ok()) << status.message();
+
+  EXPECT_ARROW_ARRAY_EQUALS(out_float64, outputs2.at(0));
+}
+
 TEST_F(TestProjector, TestCastBitFunction) {
   auto field0 = field("f0", arrow::utf8());
   auto schema = arrow::schema({field0});