This is an automated email from the ASF dual-hosted git repository.

apitrou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 6f497ecc94 GH-38920: [C++][Gandiva] Refactor function holder to return 
arrow Result (#38873)
6f497ecc94 is described below

commit 6f497ecc942cb1b2b7b0cdded650006be8cf9896
Author: Yue <[email protected]>
AuthorDate: Wed Nov 29 17:44:28 2023 +0800

    GH-38920: [C++][Gandiva] Refactor function holder to return arrow Result 
(#38873)
    
    ### Rationale for this change
    * This PR tries to make Gandiva `FunctionHolder` classes to return 
`arrow::Result` instead of using output parameters, and this tries to address 
the follow up task mentioned in 
https://github.com/apache/arrow/pull/38632#discussion_r1388576545 and makes the 
code slightly simpler
    
    ### What changes are included in this PR?
    * A refactoring task to return `arrow::Result` in Gandiva FunctionHolder 
classes
    
    ### Are these changes tested?
    It should be covered by existing unit tests.
    
    ### Are there any user-facing changes?
    No
    * Closes: #38920
    
    Authored-by: Yue Ni <[email protected]>
    Signed-off-by: Antoine Pitrou <[email protected]>
---
 cpp/src/gandiva/function_holder_maker_registry.cc |   4 +-
 cpp/src/gandiva/interval_holder.cc                |  24 +--
 cpp/src/gandiva/interval_holder.h                 |  25 ++--
 cpp/src/gandiva/interval_holder_test.cc           |  44 ++----
 cpp/src/gandiva/random_generator_holder.cc        |  10 +-
 cpp/src/gandiva/random_generator_holder.h         |   3 +-
 cpp/src/gandiva/random_generator_holder_test.cc   |  39 ++---
 cpp/src/gandiva/regex_functions_holder.cc         |  61 ++++----
 cpp/src/gandiva/regex_functions_holder.h          |  22 ++-
 cpp/src/gandiva/regex_functions_holder_test.cc    | 170 +++++++---------------
 cpp/src/gandiva/to_date_holder.cc                 |  15 +-
 cpp/src/gandiva/to_date_holder.h                  |   6 +-
 cpp/src/gandiva/to_date_holder_test.cc            |  25 +---
 13 files changed, 151 insertions(+), 297 deletions(-)

diff --git a/cpp/src/gandiva/function_holder_maker_registry.cc 
b/cpp/src/gandiva/function_holder_maker_registry.cc
index bb93402475..37ca1fbf6c 100644
--- a/cpp/src/gandiva/function_holder_maker_registry.cc
+++ b/cpp/src/gandiva/function_holder_maker_registry.cc
@@ -41,9 +41,7 @@ arrow::Status FunctionHolderMakerRegistry::Register(const 
std::string& name,
 
 template <typename HolderType>
 static arrow::Result<FunctionHolderPtr> HolderMaker(const FunctionNode& node) {
-  std::shared_ptr<HolderType> derived_instance;
-  ARROW_RETURN_NOT_OK(HolderType::Make(node, &derived_instance));
-  return derived_instance;
+  return HolderType::Make(node);
 }
 
 arrow::Result<FunctionHolderPtr> FunctionHolderMakerRegistry::Make(
diff --git a/cpp/src/gandiva/interval_holder.cc 
b/cpp/src/gandiva/interval_holder.cc
index d63a11a10d..70f7792635 100644
--- a/cpp/src/gandiva/interval_holder.cc
+++ b/cpp/src/gandiva/interval_holder.cc
@@ -258,26 +258,26 @@ int64_t IntervalDaysHolder::operator()(ExecutionContext* 
ctx, const char* data,
   return 0;
 }
 
-Status IntervalDaysHolder::Make(const FunctionNode& node,
-                                std::shared_ptr<IntervalDaysHolder>* holder) {
+Result<std::shared_ptr<IntervalDaysHolder>> IntervalDaysHolder::Make(
+    const FunctionNode& node) {
   const std::string function_name("castINTERVALDAY");
-  return IntervalHolder<IntervalDaysHolder>::Make(node, holder, function_name);
+  return IntervalHolder<IntervalDaysHolder>::Make(node, function_name);
 }
 
-Status IntervalDaysHolder::Make(int32_t suppress_errors,
-                                std::shared_ptr<IntervalDaysHolder>* holder) {
-  return IntervalHolder<IntervalDaysHolder>::Make(suppress_errors, holder);
+Result<std::shared_ptr<IntervalDaysHolder>> IntervalDaysHolder::Make(
+    int32_t suppress_errors) {
+  return IntervalHolder<IntervalDaysHolder>::Make(suppress_errors);
 }
 
-Status IntervalYearsHolder::Make(const FunctionNode& node,
-                                 std::shared_ptr<IntervalYearsHolder>* holder) 
{
+Result<std::shared_ptr<IntervalYearsHolder>> IntervalYearsHolder::Make(
+    const FunctionNode& node) {
   const std::string function_name("castINTERVALYEAR");
-  return IntervalHolder<IntervalYearsHolder>::Make(node, holder, 
function_name);
+  return IntervalHolder<IntervalYearsHolder>::Make(node, function_name);
 }
 
-Status IntervalYearsHolder::Make(int32_t suppress_errors,
-                                 std::shared_ptr<IntervalYearsHolder>* holder) 
{
-  return IntervalHolder<IntervalYearsHolder>::Make(suppress_errors, holder);
+Result<std::shared_ptr<IntervalYearsHolder>> IntervalYearsHolder::Make(
+    int32_t suppress_errors) {
+  return IntervalHolder<IntervalYearsHolder>::Make(suppress_errors);
 }
 
 // The operator will cast a generic string defined by the user into an 
interval of months.
diff --git a/cpp/src/gandiva/interval_holder.h 
b/cpp/src/gandiva/interval_holder.h
index 38d8e9f86a..0a6a988025 100644
--- a/cpp/src/gandiva/interval_holder.h
+++ b/cpp/src/gandiva/interval_holder.h
@@ -39,8 +39,8 @@ class GANDIVA_EXPORT IntervalHolder : public FunctionHolder {
   ~IntervalHolder() override = default;
 
  protected:
-  static Status Make(const FunctionNode& node, std::shared_ptr<INTERVAL_TYPE>* 
holder,
-                     const std::string& function_name) {
+  static Result<std::shared_ptr<INTERVAL_TYPE>> Make(const FunctionNode& node,
+                                                     const std::string& 
function_name) {
     ARROW_RETURN_IF(node.children().size() != 1 && node.children().size() != 2,
                     Status::Invalid(function_name + " requires one or two 
parameters"));
 
@@ -63,14 +63,11 @@ class GANDIVA_EXPORT IntervalHolder : public FunctionHolder 
{
       suppress_errors = std::get<int>(literal_suppress_errors->holder());
     }
 
-    return Make(suppress_errors, holder);
+    return Make(suppress_errors);
   }
 
-  static Status Make(int32_t suppress_errors, std::shared_ptr<INTERVAL_TYPE>* 
holder) {
-    auto lholder = std::make_shared<INTERVAL_TYPE>(suppress_errors);
-
-    *holder = lholder;
-    return Status::OK();
+  static Result<std::shared_ptr<INTERVAL_TYPE>> Make(int32_t suppress_errors) {
+    return std::make_shared<INTERVAL_TYPE>(suppress_errors);
   }
 
   explicit IntervalHolder(int32_t supress_errors) : 
suppress_errors_(supress_errors) {}
@@ -94,11 +91,9 @@ class GANDIVA_EXPORT IntervalDaysHolder : public 
IntervalHolder<IntervalDaysHold
  public:
   ~IntervalDaysHolder() override = default;
 
-  static Status Make(const FunctionNode& node,
-                     std::shared_ptr<IntervalDaysHolder>* holder);
+  static Result<std::shared_ptr<IntervalDaysHolder>> Make(const FunctionNode& 
node);
 
-  static Status Make(int32_t suppress_errors,
-                     std::shared_ptr<IntervalDaysHolder>* holder);
+  static Result<std::shared_ptr<IntervalDaysHolder>> Make(int32_t 
suppress_errors);
 
   /// Cast a generic string to an interval
   int64_t operator()(ExecutionContext* ctx, const char* data, int32_t data_len,
@@ -131,11 +126,9 @@ class GANDIVA_EXPORT IntervalYearsHolder : public 
IntervalHolder<IntervalYearsHo
  public:
   ~IntervalYearsHolder() override = default;
 
-  static Status Make(const FunctionNode& node,
-                     std::shared_ptr<IntervalYearsHolder>* holder);
+  static Result<std::shared_ptr<IntervalYearsHolder>> Make(const FunctionNode& 
node);
 
-  static Status Make(int32_t suppress_errors,
-                     std::shared_ptr<IntervalYearsHolder>* holder);
+  static Result<std::shared_ptr<IntervalYearsHolder>> Make(int32_t 
suppress_errors);
 
   /// Cast a generic string to an interval
   int32_t operator()(ExecutionContext* ctx, const char* data, int32_t data_len,
diff --git a/cpp/src/gandiva/interval_holder_test.cc 
b/cpp/src/gandiva/interval_holder_test.cc
index fbfd6335f4..59a10cace8 100644
--- a/cpp/src/gandiva/interval_holder_test.cc
+++ b/cpp/src/gandiva/interval_holder_test.cc
@@ -20,8 +20,8 @@
 #include <gtest/gtest.h>
 
 #include <memory>
-#include <vector>
 
+#include "arrow/testing/gtest_util.h"
 #include "gandiva/execution_context.h"
 
 namespace gandiva {
@@ -32,14 +32,8 @@ class TestIntervalHolder : public ::testing::Test {
 };
 
 TEST_F(TestIntervalHolder, TestMatchAllPeriods) {
-  std::shared_ptr<IntervalDaysHolder> interval_days_holder;
-  std::shared_ptr<IntervalYearsHolder> interval_years_holder;
-
-  auto status = IntervalDaysHolder::Make(0, &interval_days_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
-
-  status = IntervalYearsHolder::Make(0, &interval_years_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto interval_days_holder, IntervalDaysHolder::Make(0));
+  EXPECT_OK_AND_ASSIGN(auto interval_years_holder, 
IntervalYearsHolder::Make(0));
 
   auto& cast_interval_day = *interval_days_holder;
   auto& cast_interval_year = *interval_years_holder;
@@ -289,14 +283,8 @@ TEST_F(TestIntervalHolder, TestMatchAllPeriods) {
 }
 
 TEST_F(TestIntervalHolder, TestMatchErrorsForCastIntervalDay) {
-  std::shared_ptr<IntervalDaysHolder> interval_days_holder;
-  std::shared_ptr<IntervalYearsHolder> interval_years_holder;
-
-  auto status = IntervalDaysHolder::Make(0, &interval_days_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
-
-  status = IntervalYearsHolder::Make(0, &interval_years_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto interval_days_holder, IntervalDaysHolder::Make(0));
+  EXPECT_OK_AND_ASSIGN(auto interval_years_holder, 
IntervalYearsHolder::Make(0));
 
   auto& cast_interval_day = *interval_days_holder;
   auto& cast_interval_year = *interval_years_holder;
@@ -440,12 +428,8 @@ TEST_F(TestIntervalHolder, 
TestMatchErrorsForCastIntervalDay) {
 }
 
 TEST_F(TestIntervalHolder, TestUsingWeekFormatterForCastIntervalDay) {
-  std::shared_ptr<IntervalDaysHolder> interval_holder;
-
-  auto status = IntervalDaysHolder::Make(0, &interval_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
-
-  auto& cast_interval_day = *interval_holder;
+  EXPECT_OK_AND_ASSIGN(auto interval_days_holder, IntervalDaysHolder::Make(0));
+  auto& cast_interval_day = *interval_days_holder;
 
   bool out_valid;
   std::string data("P1W");
@@ -465,12 +449,8 @@ TEST_F(TestIntervalHolder, 
TestUsingWeekFormatterForCastIntervalDay) {
 }
 
 TEST_F(TestIntervalHolder, TestUsingCompleteFormatterForCastIntervalDay) {
-  std::shared_ptr<IntervalDaysHolder> interval_holder;
-
-  auto status = IntervalDaysHolder::Make(0, &interval_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
-
-  auto& cast_interval_day = *interval_holder;
+  EXPECT_OK_AND_ASSIGN(auto interval_days_holder, IntervalDaysHolder::Make(0));
+  auto& cast_interval_day = *interval_days_holder;
 
   bool out_valid;
   std::string data("1742461111");
@@ -528,11 +508,7 @@ TEST_F(TestIntervalHolder, 
TestUsingCompleteFormatterForCastIntervalDay) {
 }
 
 TEST_F(TestIntervalHolder, TestUsingCompleteFormatterForCastIntervalYear) {
-  std::shared_ptr<IntervalYearsHolder> interval_years_holder;
-
-  auto status = IntervalYearsHolder::Make(0, &interval_years_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
-
+  EXPECT_OK_AND_ASSIGN(auto interval_years_holder, 
IntervalYearsHolder::Make(0));
   auto& cast_interval_years = *interval_years_holder;
 
   bool out_valid;
diff --git a/cpp/src/gandiva/random_generator_holder.cc 
b/cpp/src/gandiva/random_generator_holder.cc
index 3d395741d7..8f80c5826d 100644
--- a/cpp/src/gandiva/random_generator_holder.cc
+++ b/cpp/src/gandiva/random_generator_holder.cc
@@ -19,14 +19,13 @@
 #include "gandiva/node.h"
 
 namespace gandiva {
-Status RandomGeneratorHolder::Make(const FunctionNode& node,
-                                   std::shared_ptr<RandomGeneratorHolder>* 
holder) {
+Result<std::shared_ptr<RandomGeneratorHolder>> RandomGeneratorHolder::Make(
+    const FunctionNode& node) {
   ARROW_RETURN_IF(node.children().size() > 1,
                   Status::Invalid("'random' function requires at most one 
parameter"));
 
   if (node.children().size() == 0) {
-    *holder = std::shared_ptr<RandomGeneratorHolder>(new 
RandomGeneratorHolder());
-    return Status::OK();
+    return std::shared_ptr<RandomGeneratorHolder>(new RandomGeneratorHolder());
   }
 
   auto literal = dynamic_cast<LiteralNode*>(node.children().at(0).get());
@@ -38,8 +37,7 @@ Status RandomGeneratorHolder::Make(const FunctionNode& node,
       literal_type != arrow::Type::INT32,
       Status::Invalid("'random' function requires an int32 literal as 
parameter"));
 
-  *holder = std::shared_ptr<RandomGeneratorHolder>(new RandomGeneratorHolder(
+  return std::shared_ptr<RandomGeneratorHolder>(new RandomGeneratorHolder(
       literal->is_null() ? 0 : std::get<int32_t>(literal->holder())));
-  return Status::OK();
 }
 }  // namespace gandiva
diff --git a/cpp/src/gandiva/random_generator_holder.h 
b/cpp/src/gandiva/random_generator_holder.h
index 65b6607e87..ffab725aa7 100644
--- a/cpp/src/gandiva/random_generator_holder.h
+++ b/cpp/src/gandiva/random_generator_holder.h
@@ -34,8 +34,7 @@ class GANDIVA_EXPORT RandomGeneratorHolder : public 
FunctionHolder {
  public:
   ~RandomGeneratorHolder() override = default;
 
-  static Status Make(const FunctionNode& node,
-                     std::shared_ptr<RandomGeneratorHolder>* holder);
+  static Result<std::shared_ptr<RandomGeneratorHolder>> Make(const 
FunctionNode& node);
 
   double operator()() { return distribution_(generator_); }
 
diff --git a/cpp/src/gandiva/random_generator_holder_test.cc 
b/cpp/src/gandiva/random_generator_holder_test.cc
index 4b16c1b7d0..77b2750f2e 100644
--- a/cpp/src/gandiva/random_generator_holder_test.cc
+++ b/cpp/src/gandiva/random_generator_holder_test.cc
@@ -21,38 +21,35 @@
 
 #include <gtest/gtest.h>
 
+#include "arrow/testing/gtest_util.h"
+
 namespace gandiva {
 
 class TestRandGenHolder : public ::testing::Test {
  public:
-  FunctionNode BuildRandFunc() { return FunctionNode("random", {}, 
arrow::float64()); }
+  FunctionNode BuildRandFunc() { return {"random", {}, arrow::float64()}; }
 
   FunctionNode BuildRandWithSeedFunc(int32_t seed, bool seed_is_null) {
     auto seed_node =
         std::make_shared<LiteralNode>(arrow::int32(), LiteralHolder(seed), 
seed_is_null);
-    return FunctionNode("rand", {seed_node}, arrow::float64());
+    return {"rand", {seed_node}, arrow::float64()};
   }
 };
 
 TEST_F(TestRandGenHolder, NoSeed) {
-  std::shared_ptr<RandomGeneratorHolder> rand_gen_holder;
   FunctionNode rand_func = BuildRandFunc();
-  auto status = RandomGeneratorHolder::Make(rand_func, &rand_gen_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto rand_gen_holder, 
RandomGeneratorHolder::Make(rand_func));
 
   auto& random = *rand_gen_holder;
   EXPECT_NE(random(), random());
 }
 
 TEST_F(TestRandGenHolder, WithValidEqualSeeds) {
-  std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_1;
-  std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_2;
   FunctionNode rand_func_1 = BuildRandWithSeedFunc(12, false);
   FunctionNode rand_func_2 = BuildRandWithSeedFunc(12, false);
-  auto status = RandomGeneratorHolder::Make(rand_func_1, &rand_gen_holder_1);
-  EXPECT_EQ(status.ok(), true) << status.message();
-  status = RandomGeneratorHolder::Make(rand_func_2, &rand_gen_holder_2);
-  EXPECT_EQ(status.ok(), true) << status.message();
+
+  EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_1, 
RandomGeneratorHolder::Make(rand_func_1));
+  EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_2, 
RandomGeneratorHolder::Make(rand_func_2));
 
   auto& random_1 = *rand_gen_holder_1;
   auto& random_2 = *rand_gen_holder_2;
@@ -65,18 +62,12 @@ TEST_F(TestRandGenHolder, WithValidEqualSeeds) {
 }
 
 TEST_F(TestRandGenHolder, WithValidSeeds) {
-  std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_1;
-  std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_2;
-  std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_3;
   FunctionNode rand_func_1 = BuildRandWithSeedFunc(11, false);
   FunctionNode rand_func_2 = BuildRandWithSeedFunc(12, false);
   FunctionNode rand_func_3 = BuildRandWithSeedFunc(-12, false);
-  auto status = RandomGeneratorHolder::Make(rand_func_1, &rand_gen_holder_1);
-  EXPECT_EQ(status.ok(), true) << status.message();
-  status = RandomGeneratorHolder::Make(rand_func_2, &rand_gen_holder_2);
-  EXPECT_EQ(status.ok(), true) << status.message();
-  status = RandomGeneratorHolder::Make(rand_func_3, &rand_gen_holder_3);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_1, 
RandomGeneratorHolder::Make(rand_func_1));
+  EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_2, 
RandomGeneratorHolder::Make(rand_func_2));
+  EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_3, 
RandomGeneratorHolder::Make(rand_func_3));
 
   auto& random_1 = *rand_gen_holder_1;
   auto& random_2 = *rand_gen_holder_2;
@@ -86,14 +77,10 @@ TEST_F(TestRandGenHolder, WithValidSeeds) {
 }
 
 TEST_F(TestRandGenHolder, WithInValidSeed) {
-  std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_1;
-  std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_2;
   FunctionNode rand_func_1 = BuildRandWithSeedFunc(12, true);
   FunctionNode rand_func_2 = BuildRandWithSeedFunc(0, false);
-  auto status = RandomGeneratorHolder::Make(rand_func_1, &rand_gen_holder_1);
-  EXPECT_EQ(status.ok(), true) << status.message();
-  status = RandomGeneratorHolder::Make(rand_func_2, &rand_gen_holder_2);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_1, 
RandomGeneratorHolder::Make(rand_func_1));
+  EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_2, 
RandomGeneratorHolder::Make(rand_func_2));
 
   auto& random_1 = *rand_gen_holder_1;
   auto& random_2 = *rand_gen_holder_2;
diff --git a/cpp/src/gandiva/regex_functions_holder.cc 
b/cpp/src/gandiva/regex_functions_holder.cc
index 30d68cbc87..03a4af90d8 100644
--- a/cpp/src/gandiva/regex_functions_holder.cc
+++ b/cpp/src/gandiva/regex_functions_holder.cc
@@ -48,9 +48,9 @@ const FunctionNode LikeHolder::TryOptimize(const 
FunctionNode& node) {
     global_checked = true;
   }
 
-  std::shared_ptr<LikeHolder> holder;
-  auto status = Make(node, &holder);
-  if (status.ok()) {
+  auto maybe_holder = Make(node);
+  if (maybe_holder.ok()) {
+    auto holder = *maybe_holder;
     std::string& pattern = holder->pattern_;
     auto literal_type = node.children().at(1)->return_type();
 
@@ -83,7 +83,7 @@ const FunctionNode LikeHolder::TryOptimize(const 
FunctionNode& node) {
   return node;
 }
 
-Status LikeHolder::Make(const FunctionNode& node, std::shared_ptr<LikeHolder>* 
holder) {
+Result<std::shared_ptr<LikeHolder>> LikeHolder::Make(const FunctionNode& node) 
{
   ARROW_RETURN_IF(node.children().size() != 2 && node.children().size() != 3,
                   Status::Invalid("'like' function requires two or three 
parameters"));
 
@@ -102,10 +102,10 @@ Status LikeHolder::Make(const FunctionNode& node, 
std::shared_ptr<LikeHolder>* h
   if (node.descriptor()->name() == "ilike") {
     regex_op.set_case_sensitive(false);  // set case-insensitive for ilike 
function.
 
-    return Make(std::get<std::string>(literal->holder()), holder, regex_op);
+    return Make(std::get<std::string>(literal->holder()), regex_op);
   }
   if (node.children().size() == 2) {
-    return Make(std::get<std::string>(literal->holder()), holder);
+    return Make(std::get<std::string>(literal->holder()));
   } else {
     auto escape_char = dynamic_cast<LiteralNode*>(node.children().at(2).get());
     ARROW_RETURN_IF(
@@ -118,12 +118,11 @@ Status LikeHolder::Make(const FunctionNode& node, 
std::shared_ptr<LikeHolder>* h
         Status::Invalid(
             "'like' function requires a string literal as the third 
parameter"));
     return Make(std::get<std::string>(literal->holder()),
-                std::get<std::string>(escape_char->holder()), holder);
+                std::get<std::string>(escape_char->holder()));
   }
 }
 
-Status LikeHolder::Make(const std::string& sql_pattern,
-                        std::shared_ptr<LikeHolder>* holder) {
+Result<std::shared_ptr<LikeHolder>> LikeHolder::Make(const std::string& 
sql_pattern) {
   std::string pcre_pattern;
   ARROW_RETURN_NOT_OK(RegexUtil::SqlLikePatternToPcre(sql_pattern, 
pcre_pattern));
 
@@ -132,12 +131,11 @@ Status LikeHolder::Make(const std::string& sql_pattern,
                   Status::Invalid("Building RE2 pattern '", pcre_pattern,
                                   "' failed with: ", lholder->regex_.error()));
 
-  *holder = std::move(lholder);
-  return Status::OK();
+  return lholder;
 }
 
-Status LikeHolder::Make(const std::string& sql_pattern, const std::string& 
escape_char,
-                        std::shared_ptr<LikeHolder>* holder) {
+Result<std::shared_ptr<LikeHolder>> LikeHolder::Make(const std::string& 
sql_pattern,
+                                                     const std::string& 
escape_char) {
   ARROW_RETURN_IF(escape_char.length() > 1,
                   Status::Invalid("The length of escape char ", escape_char,
                                   " in 'like' function is greater than 1"));
@@ -154,28 +152,24 @@ Status LikeHolder::Make(const std::string& sql_pattern, 
const std::string& escap
                   Status::Invalid("Building RE2 pattern '", pcre_pattern,
                                   "' failed with: ", lholder->regex_.error()));
 
-  *holder = std::move(lholder);
-  return Status::OK();
+  return lholder;
 }
 
-Status LikeHolder::Make(const std::string& sql_pattern,
-                        std::shared_ptr<LikeHolder>* holder, RE2::Options 
regex_op) {
+Result<std::shared_ptr<LikeHolder>> LikeHolder::Make(const std::string& 
sql_pattern,
+                                                     RE2::Options regex_op) {
   std::string pcre_pattern;
   ARROW_RETURN_NOT_OK(RegexUtil::SqlLikePatternToPcre(sql_pattern, 
pcre_pattern));
 
-  std::shared_ptr<LikeHolder> lholder;
-  lholder = std::shared_ptr<LikeHolder>(new LikeHolder(pcre_pattern, 
regex_op));
+  auto lholder = std::shared_ptr<LikeHolder>(new LikeHolder(pcre_pattern, 
regex_op));
 
   ARROW_RETURN_IF(!lholder->regex_.ok(),
                   Status::Invalid("Building RE2 pattern '", pcre_pattern,
                                   "' failed with: ", lholder->regex_.error()));
 
-  *holder = std::move(lholder);
-  return Status::OK();
+  return lholder;
 }
 
-Status ReplaceHolder::Make(const FunctionNode& node,
-                           std::shared_ptr<ReplaceHolder>* holder) {
+Result<std::shared_ptr<ReplaceHolder>> ReplaceHolder::Make(const FunctionNode& 
node) {
   ARROW_RETURN_IF(node.children().size() != 3,
                   Status::Invalid("'replace' function requires three 
parameters"));
 
@@ -190,18 +184,17 @@ Status ReplaceHolder::Make(const FunctionNode& node,
       Status::Invalid(
           "'replace' function requires a string literal as the second 
parameter"));
 
-  return Make(std::get<std::string>(literal->holder()), holder);
+  return Make(std::get<std::string>(literal->holder()));
 }
 
-Status ReplaceHolder::Make(const std::string& sql_pattern,
-                           std::shared_ptr<ReplaceHolder>* holder) {
+Result<std::shared_ptr<ReplaceHolder>> ReplaceHolder::Make(
+    const std::string& sql_pattern) {
   auto lholder = std::shared_ptr<ReplaceHolder>(new 
ReplaceHolder(sql_pattern));
   ARROW_RETURN_IF(!lholder->regex_.ok(),
                   Status::Invalid("Building RE2 pattern '", sql_pattern,
                                   "' failed with: ", lholder->regex_.error()));
 
-  *holder = std::move(lholder);
-  return Status::OK();
+  return lholder;
 }
 
 void ReplaceHolder::return_error(ExecutionContext* context, std::string& data,
@@ -211,8 +204,7 @@ void ReplaceHolder::return_error(ExecutionContext* context, 
std::string& data,
   context->set_error_msg(err_msg.c_str());
 }
 
-Status ExtractHolder::Make(const FunctionNode& node,
-                           std::shared_ptr<ExtractHolder>* holder) {
+Result<std::shared_ptr<ExtractHolder>> ExtractHolder::Make(const FunctionNode& 
node) {
   ARROW_RETURN_IF(node.children().size() != 3,
                   Status::Invalid("'extract' function requires three 
parameters"));
 
@@ -221,18 +213,17 @@ Status ExtractHolder::Make(const FunctionNode& node,
       literal == nullptr || 
!IsArrowStringLiteral(literal->return_type()->id()),
       Status::Invalid("'extract' function requires a literal as the second 
parameter"));
 
-  return ExtractHolder::Make(std::get<std::string>(literal->holder()), holder);
+  return ExtractHolder::Make(std::get<std::string>(literal->holder()));
 }
 
-Status ExtractHolder::Make(const std::string& sql_pattern,
-                           std::shared_ptr<ExtractHolder>* holder) {
+Result<std::shared_ptr<ExtractHolder>> ExtractHolder::Make(
+    const std::string& sql_pattern) {
   auto lholder = std::shared_ptr<ExtractHolder>(new 
ExtractHolder(sql_pattern));
   ARROW_RETURN_IF(!lholder->regex_.ok(),
                   Status::Invalid("Building RE2 pattern '", sql_pattern,
                                   "' failed with: ", lholder->regex_.error()));
 
-  *holder = std::move(lholder);
-  return Status::OK();
+  return lholder;
 }
 
 const char* ExtractHolder::operator()(ExecutionContext* ctx, const char* 
user_input,
diff --git a/cpp/src/gandiva/regex_functions_holder.h 
b/cpp/src/gandiva/regex_functions_holder.h
index ecf4095f3d..36d942510b 100644
--- a/cpp/src/gandiva/regex_functions_holder.h
+++ b/cpp/src/gandiva/regex_functions_holder.h
@@ -35,15 +35,15 @@ class GANDIVA_EXPORT LikeHolder : public FunctionHolder {
  public:
   ~LikeHolder() override = default;
 
-  static Status Make(const FunctionNode& node, std::shared_ptr<LikeHolder>* 
holder);
+  static Result<std::shared_ptr<LikeHolder>> Make(const FunctionNode& node);
 
-  static Status Make(const std::string& sql_pattern, 
std::shared_ptr<LikeHolder>* holder);
+  static Result<std::shared_ptr<LikeHolder>> Make(const std::string& 
sql_pattern);
 
-  static Status Make(const std::string& sql_pattern, const std::string& 
escape_char,
-                     std::shared_ptr<LikeHolder>* holder);
+  static Result<std::shared_ptr<LikeHolder>> Make(const std::string& 
sql_pattern,
+                                                  const std::string& 
escape_char);
 
-  static Status Make(const std::string& sql_pattern, 
std::shared_ptr<LikeHolder>* holder,
-                     RE2::Options regex_op);
+  static Result<std::shared_ptr<LikeHolder>> Make(const std::string& 
sql_pattern,
+                                                  RE2::Options regex_op);
 
   // Try and optimise a function node with a "like" pattern.
   static const FunctionNode TryOptimize(const FunctionNode& node);
@@ -66,10 +66,9 @@ class GANDIVA_EXPORT ReplaceHolder : public FunctionHolder {
  public:
   ~ReplaceHolder() override = default;
 
-  static Status Make(const FunctionNode& node, std::shared_ptr<ReplaceHolder>* 
holder);
+  static Result<std::shared_ptr<ReplaceHolder>> Make(const FunctionNode& node);
 
-  static Status Make(const std::string& sql_pattern,
-                     std::shared_ptr<ReplaceHolder>* holder);
+  static Result<std::shared_ptr<ReplaceHolder>> Make(const std::string& 
sql_pattern);
 
   /// Return a new string with the pattern that matched the regex replaced for
   /// the replace_input parameter.
@@ -130,10 +129,9 @@ class GANDIVA_EXPORT ExtractHolder : public FunctionHolder 
{
  public:
   ~ExtractHolder() override = default;
 
-  static Status Make(const FunctionNode& node, std::shared_ptr<ExtractHolder>* 
holder);
+  static Result<std::shared_ptr<ExtractHolder>> Make(const FunctionNode& node);
 
-  static Status Make(const std::string& sql_pattern,
-                     std::shared_ptr<ExtractHolder>* holder);
+  static Result<std::shared_ptr<ExtractHolder>> Make(const std::string& 
sql_pattern);
 
   /// Extracts the matching text from a string using a regex
   const char* operator()(ExecutionContext* ctx, const char* user_input,
diff --git a/cpp/src/gandiva/regex_functions_holder_test.cc 
b/cpp/src/gandiva/regex_functions_holder_test.cc
index 930f3a7ade..534be5987a 100644
--- a/cpp/src/gandiva/regex_functions_holder_test.cc
+++ b/cpp/src/gandiva/regex_functions_holder_test.cc
@@ -19,7 +19,8 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <memory>
-#include <vector>
+
+#include "arrow/testing/gtest_util.h"
 #include "gandiva/regex_util.h"
 
 namespace gandiva {
@@ -31,7 +32,7 @@ class TestLikeHolder : public ::testing::Test {
     auto field = std::make_shared<FieldNode>(arrow::field("in", 
arrow::utf8()));
     auto pattern_node =
         std::make_shared<LiteralNode>(arrow::utf8(), LiteralHolder(pattern), 
false);
-    return FunctionNode("like", {field, pattern_node}, arrow::boolean());
+    return {"like", {field, pattern_node}, arrow::boolean()};
   }
 
   FunctionNode BuildLike(std::string pattern, char escape_char) {
@@ -40,16 +41,12 @@ class TestLikeHolder : public ::testing::Test {
         std::make_shared<LiteralNode>(arrow::utf8(), LiteralHolder(pattern), 
false);
     auto escape_char_node = std::make_shared<LiteralNode>(
         arrow::utf8(), LiteralHolder(std::string(1, escape_char)), false);
-    return FunctionNode("like", {field, pattern_node, escape_char_node},
-                        arrow::boolean());
+    return {"like", {field, pattern_node, escape_char_node}, arrow::boolean()};
   }
 };
 
 TEST_F(TestLikeHolder, TestMatchAny) {
-  std::shared_ptr<LikeHolder> like_holder;
-
-  auto status = LikeHolder::Make("ab%", &like_holder, regex_op);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make("ab%", 
regex_op));
 
   auto& like = *like_holder;
   EXPECT_TRUE(like("ab"));
@@ -61,10 +58,7 @@ TEST_F(TestLikeHolder, TestMatchAny) {
 }
 
 TEST_F(TestLikeHolder, TestMatchOne) {
-  std::shared_ptr<LikeHolder> like_holder;
-
-  auto status = LikeHolder::Make("ab_", &like_holder, regex_op);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make("ab_", 
regex_op));
 
   auto& like = *like_holder;
   EXPECT_TRUE(like("abc"));
@@ -76,10 +70,7 @@ TEST_F(TestLikeHolder, TestMatchOne) {
 }
 
 TEST_F(TestLikeHolder, TestPcreSpecial) {
-  std::shared_ptr<LikeHolder> like_holder;
-
-  auto status = LikeHolder::Make(".*ab_", &like_holder, regex_op);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make(".*ab_", 
regex_op));
 
   auto& like = *like_holder;
   EXPECT_TRUE(like(".*abc"));  // . and * aren't special in sql regex
@@ -88,34 +79,26 @@ TEST_F(TestLikeHolder, TestPcreSpecial) {
 
 TEST_F(TestLikeHolder, TestRegexEscape) {
   std::string res;
-  auto status = RegexUtil::SqlLikePatternToPcre("#%hello#_abc_def##", '#', 
res);
-  EXPECT_TRUE(status.ok()) << status.message();
+  ARROW_EXPECT_OK(RegexUtil::SqlLikePatternToPcre("#%hello#_abc_def##", '#', 
res));
 
   EXPECT_EQ(res, "%hello_abc.def#");
 }
 
 TEST_F(TestLikeHolder, TestDot) {
-  std::shared_ptr<LikeHolder> like_holder;
-
-  auto status = LikeHolder::Make("abc.", &like_holder, regex_op);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make("abc.", 
regex_op));
 
   auto& like = *like_holder;
   EXPECT_FALSE(like("abcd"));
 }
 
 TEST_F(TestLikeHolder, TestMatchSubString) {
-  std::shared_ptr<LikeHolder> like_holder;
-
-  auto status = LikeHolder::Make("%abc%", "\\", &like_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto like_holder, LikeHolder::Make("%abc%", "\\"));
 
   auto& like = *like_holder;
   EXPECT_TRUE(like("abc"));
   EXPECT_FALSE(like("xxabdc"));
 
-  status = LikeHolder::Make("%ab-.^$*+?()[]{}|—/c\\%%", "\\", &like_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(like_holder, 
LikeHolder::Make("%ab-.^$*+?()[]{}|—/c\\%%", "\\"));
 
   auto& like_reserved_char = *like_holder;
   EXPECT_TRUE(like_reserved_char("XXab-.^$*+?()[]{}|—/c%d"));
@@ -190,10 +173,7 @@ TEST_F(TestLikeHolder, TestOptimise) {
 }
 
 TEST_F(TestLikeHolder, TestMatchOneEscape) {
-  std::shared_ptr<LikeHolder> like_holder;
-
-  auto status = LikeHolder::Make("ab\\_", "\\", &like_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make("ab\\_", 
"\\"));
 
   auto& like = *like_holder;
 
@@ -207,10 +187,7 @@ TEST_F(TestLikeHolder, TestMatchOneEscape) {
 }
 
 TEST_F(TestLikeHolder, TestMatchManyEscape) {
-  std::shared_ptr<LikeHolder> like_holder;
-
-  auto status = LikeHolder::Make("ab\\%", "\\", &like_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make("ab\\%", 
"\\"));
 
   auto& like = *like_holder;
 
@@ -224,10 +201,7 @@ TEST_F(TestLikeHolder, TestMatchManyEscape) {
 }
 
 TEST_F(TestLikeHolder, TestMatchEscape) {
-  std::shared_ptr<LikeHolder> like_holder;
-
-  auto status = LikeHolder::Make("ab\\\\", "\\", &like_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make("ab\\\\", 
"\\"));
 
   auto& like = *like_holder;
 
@@ -237,10 +211,7 @@ TEST_F(TestLikeHolder, TestMatchEscape) {
 }
 
 TEST_F(TestLikeHolder, TestEmptyEscapeChar) {
-  std::shared_ptr<LikeHolder> like_holder;
-
-  auto status = LikeHolder::Make("ab\\_", "", &like_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make("ab\\_", ""));
 
   auto& like = *like_holder;
 
@@ -252,10 +223,7 @@ TEST_F(TestLikeHolder, TestEmptyEscapeChar) {
 }
 
 TEST_F(TestLikeHolder, TestMultipleEscapeChar) {
-  std::shared_ptr<LikeHolder> like_holder;
-
-  auto status = LikeHolder::Make("ab\\_", "\\\\", &like_holder);
-  EXPECT_EQ(status.ok(), false) << status.message();
+  ASSERT_RAISES(Invalid, LikeHolder::Make("ab\\_", "\\\\").status());
 }
 
 class TestILikeHolder : public ::testing::Test {
@@ -265,16 +233,14 @@ class TestILikeHolder : public ::testing::Test {
     auto field = std::make_shared<FieldNode>(arrow::field("in", 
arrow::utf8()));
     auto pattern_node =
         std::make_shared<LiteralNode>(arrow::utf8(), LiteralHolder(pattern), 
false);
-    return FunctionNode("ilike", {field, pattern_node}, arrow::boolean());
+    return {"ilike", {field, pattern_node}, arrow::boolean()};
   }
 };
 
 TEST_F(TestILikeHolder, TestMatchAny) {
-  std::shared_ptr<LikeHolder> like_holder;
-
   regex_op.set_case_sensitive(false);
-  auto status = LikeHolder::Make("ab%", &like_holder, regex_op);
-  EXPECT_EQ(status.ok(), true) << status.message();
+
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make("ab%", 
regex_op));
 
   auto& like = *like_holder;
   EXPECT_TRUE(like("ab"));
@@ -286,11 +252,8 @@ TEST_F(TestILikeHolder, TestMatchAny) {
 }
 
 TEST_F(TestILikeHolder, TestMatchOne) {
-  std::shared_ptr<LikeHolder> like_holder;
-
   regex_op.set_case_sensitive(false);
-  auto status = LikeHolder::Make("Ab_", &like_holder, regex_op);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make("Ab_", 
regex_op));
 
   auto& like = *like_holder;
   EXPECT_TRUE(like("abc"));
@@ -302,11 +265,8 @@ TEST_F(TestILikeHolder, TestMatchOne) {
 }
 
 TEST_F(TestILikeHolder, TestPcreSpecial) {
-  std::shared_ptr<LikeHolder> like_holder;
-
   regex_op.set_case_sensitive(false);
-  auto status = LikeHolder::Make(".*aB_", &like_holder, regex_op);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make(".*aB_", 
regex_op));
 
   auto& like = *like_holder;
   EXPECT_TRUE(like(".*Abc"));  // . and * aren't special in sql regex
@@ -314,11 +274,8 @@ TEST_F(TestILikeHolder, TestPcreSpecial) {
 }
 
 TEST_F(TestILikeHolder, TestDot) {
-  std::shared_ptr<LikeHolder> like_holder;
-
   regex_op.set_case_sensitive(false);
-  auto status = LikeHolder::Make("aBc.", &like_holder, regex_op);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const like_holder, LikeHolder::Make("aBc.", 
regex_op));
 
   auto& like = *like_holder;
   EXPECT_FALSE(like("abcd"));
@@ -330,10 +287,7 @@ class TestReplaceHolder : public ::testing::Test {
 };
 
 TEST_F(TestReplaceHolder, TestMultipleReplace) {
-  std::shared_ptr<ReplaceHolder> replace_holder;
-
-  auto status = ReplaceHolder::Make("ana", &replace_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const replace_holder, ReplaceHolder::Make("ana"));
 
   std::string input_string = "banana";
   std::string replace_string;
@@ -378,10 +332,7 @@ TEST_F(TestReplaceHolder, TestMultipleReplace) {
 }
 
 TEST_F(TestReplaceHolder, TestNoMatchPattern) {
-  std::shared_ptr<ReplaceHolder> replace_holder;
-
-  auto status = ReplaceHolder::Make("ana", &replace_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const replace_holder, ReplaceHolder::Make("ana"));
 
   std::string input_string = "apple";
   std::string replace_string;
@@ -398,10 +349,7 @@ TEST_F(TestReplaceHolder, TestNoMatchPattern) {
 }
 
 TEST_F(TestReplaceHolder, TestReplaceSameSize) {
-  std::shared_ptr<ReplaceHolder> replace_holder;
-
-  auto status = ReplaceHolder::Make("a", &replace_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const replace_holder, ReplaceHolder::Make("a"));
 
   std::string input_string = "ananindeua";
   std::string replace_string = "b";
@@ -418,11 +366,7 @@ TEST_F(TestReplaceHolder, TestReplaceSameSize) {
 }
 
 TEST_F(TestReplaceHolder, TestReplaceInvalidPattern) {
-  std::shared_ptr<ReplaceHolder> replace_holder;
-
-  auto status = ReplaceHolder::Make("+", &replace_holder);
-  EXPECT_EQ(status.ok(), false) << status.message();
-
+  ASSERT_RAISES(Invalid, ReplaceHolder::Make("+"));
   execution_context_.Reset();
 }
 
@@ -433,11 +377,8 @@ class TestExtractHolder : public ::testing::Test {
 };
 
 TEST_F(TestExtractHolder, TestSimpleExtract) {
-  std::shared_ptr<ExtractHolder> extract_holder;
-
   // Pattern to match of two group of letters
-  auto status = ExtractHolder::Make(R"((\w+) (\w+))", &extract_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto extract_holder, ExtractHolder::Make(R"((\w+) 
(\w+))"));
 
   std::string input_string = "John Doe";
   int32_t extract_index = 2;  // Retrieve the surname
@@ -469,8 +410,7 @@ TEST_F(TestExtractHolder, TestSimpleExtract) {
   EXPECT_EQ(out_length, 9);
   EXPECT_EQ(ret_as_str, "Paul Test");
 
-  status = ExtractHolder::Make(R"((\w+) (\w+) - (\d+))", &extract_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(extract_holder, ExtractHolder::Make(R"((\w+) (\w+) - 
(\d+))"));
 
   auto& extract2 = *extract_holder;
 
@@ -502,8 +442,7 @@ TEST_F(TestExtractHolder, TestSimpleExtract) {
   EXPECT_EQ(ret_as_str, "John Doe - 124");
 
   // Pattern to match only numbers
-  status = ExtractHolder::Make(R"(((\w+)))", &extract_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(extract_holder, ExtractHolder::Make(R"(((\w+)))"));
 
   auto& extract_numbers = *extract_holder;
 
@@ -569,11 +508,8 @@ TEST_F(TestExtractHolder, TestSimpleExtract) {
 }
 
 TEST_F(TestExtractHolder, TestNoMatches) {
-  std::shared_ptr<ExtractHolder> extract_holder;
-
   // Pattern to match of two group of letters
-  auto status = ExtractHolder::Make(R"((\w+) (\w+))", &extract_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto extract_holder, ExtractHolder::Make(R"((\w+) 
(\w+))"));
 
   std::string input_string = "John";
   int32_t extract_index = 2;  // The regex will not match with the input string
@@ -588,8 +524,7 @@ TEST_F(TestExtractHolder, TestNoMatches) {
   EXPECT_FALSE(execution_context_.has_error());
 
   // Pattern to match only numbers
-  status = ExtractHolder::Make(R"(\d+)", &extract_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(extract_holder, ExtractHolder::Make(R"(\d+)"));
 
   auto& extract_numbers = *extract_holder;
 
@@ -616,11 +551,8 @@ TEST_F(TestExtractHolder, TestNoMatches) {
 }
 
 TEST_F(TestExtractHolder, TestInvalidRange) {
-  std::shared_ptr<ExtractHolder> extract_holder;
-
   // Pattern to match of two group of letters
-  auto status = ExtractHolder::Make(R"((\w+) (\w+))", &extract_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto const extract_holder, ExtractHolder::Make(R"((\w+) 
(\w+))"));
 
   std::string input_string = "John Doe";
   int32_t extract_index = -1;
@@ -650,17 +582,11 @@ TEST_F(TestExtractHolder, TestInvalidRange) {
 }
 
 TEST_F(TestExtractHolder, TestExtractInvalidPattern) {
-  std::shared_ptr<ExtractHolder> extract_holder;
-
-  auto status = ExtractHolder::Make("+", &extract_holder);
-  EXPECT_EQ(status.ok(), false) << status.message();
-
+  ASSERT_RAISES(Invalid, ExtractHolder::Make("+"));
   execution_context_.Reset();
 }
 
 TEST_F(TestExtractHolder, TestErrorWhileBuildingHolder) {
-  std::shared_ptr<ExtractHolder> extract_holder;
-
   // Create function with incorrect number of params
   auto field = std::make_shared<FieldNode>(arrow::field("in", arrow::utf8()));
   auto pattern_node = std::make_shared<LiteralNode>(
@@ -668,10 +594,10 @@ TEST_F(TestExtractHolder, TestErrorWhileBuildingHolder) {
   auto function_node =
       FunctionNode("regexp_extract", {field, pattern_node}, arrow::utf8());
 
-  auto status = ExtractHolder::Make(function_node, &extract_holder);
-  EXPECT_EQ(status.ok(), false);
-  EXPECT_THAT(status.message(),
-              ::testing::HasSubstr("'extract' function requires three 
parameters"));
+  auto extract_holder = ExtractHolder::Make(function_node);
+  EXPECT_RAISES_WITH_MESSAGE_THAT(
+      Invalid, ::testing::HasSubstr("'extract' function requires three 
parameters"),
+      extract_holder.status());
 
   execution_context_.Reset();
 
@@ -682,11 +608,12 @@ TEST_F(TestExtractHolder, TestErrorWhileBuildingHolder) {
   function_node =
       FunctionNode("regexp_extract", {field, pattern_node, index_node}, 
arrow::utf8());
 
-  status = ExtractHolder::Make(function_node, &extract_holder);
-  EXPECT_EQ(status.ok(), false);
-  EXPECT_THAT(status.message(),
-              ::testing::HasSubstr(
-                  "'extract' function requires a literal as the second 
parameter"));
+  extract_holder = ExtractHolder::Make(function_node);
+  EXPECT_RAISES_WITH_MESSAGE_THAT(
+      Invalid,
+      ::testing::HasSubstr(
+          "'extract' function requires a literal as the second parameter"),
+      extract_holder.status());
 
   execution_context_.Reset();
 
@@ -698,11 +625,12 @@ TEST_F(TestExtractHolder, TestErrorWhileBuildingHolder) {
   function_node =
       FunctionNode("regexp_extract", {field, pattern_as_node, index_node}, 
arrow::utf8());
 
-  status = ExtractHolder::Make(function_node, &extract_holder);
-  EXPECT_EQ(status.ok(), false);
-  EXPECT_THAT(status.message(),
-              ::testing::HasSubstr(
-                  "'extract' function requires a literal as the second 
parameter"));
+  extract_holder = ExtractHolder::Make(function_node);
+  EXPECT_RAISES_WITH_MESSAGE_THAT(
+      Invalid,
+      ::testing::HasSubstr(
+          "'extract' function requires a literal as the second parameter"),
+      extract_holder.status());
 
   execution_context_.Reset();
 }
diff --git a/cpp/src/gandiva/to_date_holder.cc 
b/cpp/src/gandiva/to_date_holder.cc
index 27a16d1779..0778c39b4c 100644
--- a/cpp/src/gandiva/to_date_holder.cc
+++ b/cpp/src/gandiva/to_date_holder.cc
@@ -28,8 +28,7 @@
 
 namespace gandiva {
 
-Status ToDateHolder::Make(const FunctionNode& node,
-                          std::shared_ptr<ToDateHolder>* holder) {
+Result<std::shared_ptr<ToDateHolder>> ToDateHolder::Make(const FunctionNode& 
node) {
   if (node.children().size() != 2 && node.children().size() != 3) {
     return Status::Invalid("'to_date' function requires two or three 
parameters");
   }
@@ -66,17 +65,15 @@ Status ToDateHolder::Make(const FunctionNode& node,
     suppress_errors = std::get<int>(literal_suppress_errors->holder());
   }
 
-  return Make(pattern, suppress_errors, holder);
+  return Make(pattern, suppress_errors);
 }
 
-Status ToDateHolder::Make(const std::string& sql_pattern, int32_t 
suppress_errors,
-                          std::shared_ptr<ToDateHolder>* holder) {
+Result<std::shared_ptr<ToDateHolder>> ToDateHolder::Make(const std::string& 
sql_pattern,
+                                                         int32_t 
suppress_errors) {
   std::shared_ptr<std::string> transformed_pattern;
   ARROW_RETURN_NOT_OK(DateUtils::ToInternalFormat(sql_pattern, 
&transformed_pattern));
-  auto lholder = std::shared_ptr<ToDateHolder>(
-      new ToDateHolder(*(transformed_pattern.get()), suppress_errors));
-  *holder = lholder;
-  return Status::OK();
+  return std::shared_ptr<ToDateHolder>(
+      new ToDateHolder(*transformed_pattern, suppress_errors));
 }
 
 int64_t ToDateHolder::operator()(ExecutionContext* context, const char* data,
diff --git a/cpp/src/gandiva/to_date_holder.h b/cpp/src/gandiva/to_date_holder.h
index 1211b6a304..ac13f7a31b 100644
--- a/cpp/src/gandiva/to_date_holder.h
+++ b/cpp/src/gandiva/to_date_holder.h
@@ -35,10 +35,10 @@ class GANDIVA_EXPORT ToDateHolder : public FunctionHolder {
  public:
   ~ToDateHolder() override = default;
 
-  static Status Make(const FunctionNode& node, std::shared_ptr<ToDateHolder>* 
holder);
+  static Result<std::shared_ptr<ToDateHolder>> Make(const FunctionNode& node);
 
-  static Status Make(const std::string& sql_pattern, int32_t suppress_errors,
-                     std::shared_ptr<ToDateHolder>* holder);
+  static Result<std::shared_ptr<ToDateHolder>> Make(const std::string& 
sql_pattern,
+                                                    int32_t suppress_errors);
 
   /// Return true if the data matches the pattern.
   int64_t operator()(ExecutionContext* context, const char* data, int data_len,
diff --git a/cpp/src/gandiva/to_date_holder_test.cc 
b/cpp/src/gandiva/to_date_holder_test.cc
index 99036817d8..1e0f2e1578 100644
--- a/cpp/src/gandiva/to_date_holder_test.cc
+++ b/cpp/src/gandiva/to_date_holder_test.cc
@@ -16,7 +16,6 @@
 // under the License.
 
 #include <memory>
-#include <vector>
 
 #include "arrow/testing/gtest_util.h"
 
@@ -45,8 +44,7 @@ class TestToDateHolder : public ::testing::Test {
 };
 
 TEST_F(TestToDateHolder, TestSimpleDateTime) {
-  std::shared_ptr<ToDateHolder> to_date_holder;
-  ASSERT_OK(ToDateHolder::Make("YYYY-MM-DD HH:MI:SS", 1, &to_date_holder));
+  EXPECT_OK_AND_ASSIGN(auto to_date_holder, ToDateHolder::Make("YYYY-MM-DD 
HH:MI:SS", 1));
 
   auto& to_date = *to_date_holder;
   bool out_valid;
@@ -86,8 +84,7 @@ TEST_F(TestToDateHolder, TestSimpleDateTime) {
 }
 
 TEST_F(TestToDateHolder, TestSimpleDate) {
-  std::shared_ptr<ToDateHolder> to_date_holder;
-  ASSERT_OK(ToDateHolder::Make("YYYY-MM-DD", 1, &to_date_holder));
+  EXPECT_OK_AND_ASSIGN(auto to_date_holder, ToDateHolder::Make("YYYY-MM-DD", 
1));
 
   auto& to_date = *to_date_holder;
   bool out_valid;
@@ -119,10 +116,7 @@ TEST_F(TestToDateHolder, TestSimpleDate) {
 }
 
 TEST_F(TestToDateHolder, TestSimpleDateTimeError) {
-  std::shared_ptr<ToDateHolder> to_date_holder;
-
-  auto status = ToDateHolder::Make("YYYY-MM-DD HH:MI:SS", 0, &to_date_holder);
-  EXPECT_EQ(status.ok(), true) << status.message();
+  EXPECT_OK_AND_ASSIGN(auto to_date_holder, ToDateHolder::Make("YYYY-MM-DD 
HH:MI:SS", 0));
   auto& to_date = *to_date_holder;
   bool out_valid;
 
@@ -132,8 +126,7 @@ TEST_F(TestToDateHolder, TestSimpleDateTimeError) {
   EXPECT_EQ(0, millis_since_epoch);
   std::string expected_error =
       "Error parsing value 1986-01-40 01:01:01 +0800 for given format";
-  EXPECT_TRUE(execution_context_.get_error().find(expected_error) != 
std::string::npos)
-      << status.message();
+  EXPECT_TRUE(execution_context_.get_error().find(expected_error) != 
std::string::npos);
 
   // not valid should not return error
   execution_context_.Reset();
@@ -143,15 +136,12 @@ TEST_F(TestToDateHolder, TestSimpleDateTimeError) {
 }
 
 TEST_F(TestToDateHolder, TestSimpleDateTimeMakeError) {
-  std::shared_ptr<ToDateHolder> to_date_holder;
   // reject time stamps for now.
-  auto status = ToDateHolder::Make("YYYY-MM-DD HH:MI:SS tzo", 0, 
&to_date_holder);
-  EXPECT_EQ(status.IsInvalid(), true) << status.message();
+  ASSERT_RAISES(Invalid, ToDateHolder::Make("YYYY-MM-DD HH:MI:SS tzo", 
0).status());
 }
 
 TEST_F(TestToDateHolder, TestSimpleDateYearMonth) {
-  std::shared_ptr<ToDateHolder> to_date_holder;
-  ASSERT_OK(ToDateHolder::Make("YYYY-MM", 1, &to_date_holder));
+  EXPECT_OK_AND_ASSIGN(auto to_date_holder, ToDateHolder::Make("YYYY-MM", 1));
 
   auto& to_date = *to_date_holder;
   bool out_valid;
@@ -167,8 +157,7 @@ TEST_F(TestToDateHolder, TestSimpleDateYearMonth) {
 }
 
 TEST_F(TestToDateHolder, TestSimpleDateYear) {
-  std::shared_ptr<ToDateHolder> to_date_holder;
-  ASSERT_OK(ToDateHolder::Make("YYYY", 1, &to_date_holder));
+  EXPECT_OK_AND_ASSIGN(auto to_date_holder, ToDateHolder::Make("YYYY", 1));
 
   auto& to_date = *to_date_holder;
   bool out_valid;

Reply via email to