Skip to content

Commit 6f497ec

Browse files
authored
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 #38632 (comment) 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 <niyue.com@gmail.com> Signed-off-by: Antoine Pitrou <antoine@python.org>
1 parent c441862 commit 6f497ec

13 files changed

Lines changed: 151 additions & 297 deletions

cpp/src/gandiva/function_holder_maker_registry.cc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ arrow::Status FunctionHolderMakerRegistry::Register(const std::string& name,
4141

4242
template <typename HolderType>
4343
static arrow::Result<FunctionHolderPtr> HolderMaker(const FunctionNode& node) {
44-
std::shared_ptr<HolderType> derived_instance;
45-
ARROW_RETURN_NOT_OK(HolderType::Make(node, &derived_instance));
46-
return derived_instance;
44+
return HolderType::Make(node);
4745
}
4846

4947
arrow::Result<FunctionHolderPtr> FunctionHolderMakerRegistry::Make(

cpp/src/gandiva/interval_holder.cc

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -258,26 +258,26 @@ int64_t IntervalDaysHolder::operator()(ExecutionContext* ctx, const char* data,
258258
return 0;
259259
}
260260

261-
Status IntervalDaysHolder::Make(const FunctionNode& node,
262-
std::shared_ptr<IntervalDaysHolder>* holder) {
261+
Result<std::shared_ptr<IntervalDaysHolder>> IntervalDaysHolder::Make(
262+
const FunctionNode& node) {
263263
const std::string function_name("castINTERVALDAY");
264-
return IntervalHolder<IntervalDaysHolder>::Make(node, holder, function_name);
264+
return IntervalHolder<IntervalDaysHolder>::Make(node, function_name);
265265
}
266266

267-
Status IntervalDaysHolder::Make(int32_t suppress_errors,
268-
std::shared_ptr<IntervalDaysHolder>* holder) {
269-
return IntervalHolder<IntervalDaysHolder>::Make(suppress_errors, holder);
267+
Result<std::shared_ptr<IntervalDaysHolder>> IntervalDaysHolder::Make(
268+
int32_t suppress_errors) {
269+
return IntervalHolder<IntervalDaysHolder>::Make(suppress_errors);
270270
}
271271

272-
Status IntervalYearsHolder::Make(const FunctionNode& node,
273-
std::shared_ptr<IntervalYearsHolder>* holder) {
272+
Result<std::shared_ptr<IntervalYearsHolder>> IntervalYearsHolder::Make(
273+
const FunctionNode& node) {
274274
const std::string function_name("castINTERVALYEAR");
275-
return IntervalHolder<IntervalYearsHolder>::Make(node, holder, function_name);
275+
return IntervalHolder<IntervalYearsHolder>::Make(node, function_name);
276276
}
277277

278-
Status IntervalYearsHolder::Make(int32_t suppress_errors,
279-
std::shared_ptr<IntervalYearsHolder>* holder) {
280-
return IntervalHolder<IntervalYearsHolder>::Make(suppress_errors, holder);
278+
Result<std::shared_ptr<IntervalYearsHolder>> IntervalYearsHolder::Make(
279+
int32_t suppress_errors) {
280+
return IntervalHolder<IntervalYearsHolder>::Make(suppress_errors);
281281
}
282282

283283
// The operator will cast a generic string defined by the user into an interval of months.

cpp/src/gandiva/interval_holder.h

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ class GANDIVA_EXPORT IntervalHolder : public FunctionHolder {
3939
~IntervalHolder() override = default;
4040

4141
protected:
42-
static Status Make(const FunctionNode& node, std::shared_ptr<INTERVAL_TYPE>* holder,
43-
const std::string& function_name) {
42+
static Result<std::shared_ptr<INTERVAL_TYPE>> Make(const FunctionNode& node,
43+
const std::string& function_name) {
4444
ARROW_RETURN_IF(node.children().size() != 1 && node.children().size() != 2,
4545
Status::Invalid(function_name + " requires one or two parameters"));
4646

@@ -63,14 +63,11 @@ class GANDIVA_EXPORT IntervalHolder : public FunctionHolder {
6363
suppress_errors = std::get<int>(literal_suppress_errors->holder());
6464
}
6565

66-
return Make(suppress_errors, holder);
66+
return Make(suppress_errors);
6767
}
6868

69-
static Status Make(int32_t suppress_errors, std::shared_ptr<INTERVAL_TYPE>* holder) {
70-
auto lholder = std::make_shared<INTERVAL_TYPE>(suppress_errors);
71-
72-
*holder = lholder;
73-
return Status::OK();
69+
static Result<std::shared_ptr<INTERVAL_TYPE>> Make(int32_t suppress_errors) {
70+
return std::make_shared<INTERVAL_TYPE>(suppress_errors);
7471
}
7572

7673
explicit IntervalHolder(int32_t supress_errors) : suppress_errors_(supress_errors) {}
@@ -94,11 +91,9 @@ class GANDIVA_EXPORT IntervalDaysHolder : public IntervalHolder<IntervalDaysHold
9491
public:
9592
~IntervalDaysHolder() override = default;
9693

97-
static Status Make(const FunctionNode& node,
98-
std::shared_ptr<IntervalDaysHolder>* holder);
94+
static Result<std::shared_ptr<IntervalDaysHolder>> Make(const FunctionNode& node);
9995

100-
static Status Make(int32_t suppress_errors,
101-
std::shared_ptr<IntervalDaysHolder>* holder);
96+
static Result<std::shared_ptr<IntervalDaysHolder>> Make(int32_t suppress_errors);
10297

10398
/// Cast a generic string to an interval
10499
int64_t operator()(ExecutionContext* ctx, const char* data, int32_t data_len,
@@ -131,11 +126,9 @@ class GANDIVA_EXPORT IntervalYearsHolder : public IntervalHolder<IntervalYearsHo
131126
public:
132127
~IntervalYearsHolder() override = default;
133128

134-
static Status Make(const FunctionNode& node,
135-
std::shared_ptr<IntervalYearsHolder>* holder);
129+
static Result<std::shared_ptr<IntervalYearsHolder>> Make(const FunctionNode& node);
136130

137-
static Status Make(int32_t suppress_errors,
138-
std::shared_ptr<IntervalYearsHolder>* holder);
131+
static Result<std::shared_ptr<IntervalYearsHolder>> Make(int32_t suppress_errors);
139132

140133
/// Cast a generic string to an interval
141134
int32_t operator()(ExecutionContext* ctx, const char* data, int32_t data_len,

cpp/src/gandiva/interval_holder_test.cc

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
#include <gtest/gtest.h>
2121

2222
#include <memory>
23-
#include <vector>
2423

24+
#include "arrow/testing/gtest_util.h"
2525
#include "gandiva/execution_context.h"
2626

2727
namespace gandiva {
@@ -32,14 +32,8 @@ class TestIntervalHolder : public ::testing::Test {
3232
};
3333

3434
TEST_F(TestIntervalHolder, TestMatchAllPeriods) {
35-
std::shared_ptr<IntervalDaysHolder> interval_days_holder;
36-
std::shared_ptr<IntervalYearsHolder> interval_years_holder;
37-
38-
auto status = IntervalDaysHolder::Make(0, &interval_days_holder);
39-
EXPECT_EQ(status.ok(), true) << status.message();
40-
41-
status = IntervalYearsHolder::Make(0, &interval_years_holder);
42-
EXPECT_EQ(status.ok(), true) << status.message();
35+
EXPECT_OK_AND_ASSIGN(auto interval_days_holder, IntervalDaysHolder::Make(0));
36+
EXPECT_OK_AND_ASSIGN(auto interval_years_holder, IntervalYearsHolder::Make(0));
4337

4438
auto& cast_interval_day = *interval_days_holder;
4539
auto& cast_interval_year = *interval_years_holder;
@@ -289,14 +283,8 @@ TEST_F(TestIntervalHolder, TestMatchAllPeriods) {
289283
}
290284

291285
TEST_F(TestIntervalHolder, TestMatchErrorsForCastIntervalDay) {
292-
std::shared_ptr<IntervalDaysHolder> interval_days_holder;
293-
std::shared_ptr<IntervalYearsHolder> interval_years_holder;
294-
295-
auto status = IntervalDaysHolder::Make(0, &interval_days_holder);
296-
EXPECT_EQ(status.ok(), true) << status.message();
297-
298-
status = IntervalYearsHolder::Make(0, &interval_years_holder);
299-
EXPECT_EQ(status.ok(), true) << status.message();
286+
EXPECT_OK_AND_ASSIGN(auto interval_days_holder, IntervalDaysHolder::Make(0));
287+
EXPECT_OK_AND_ASSIGN(auto interval_years_holder, IntervalYearsHolder::Make(0));
300288

301289
auto& cast_interval_day = *interval_days_holder;
302290
auto& cast_interval_year = *interval_years_holder;
@@ -440,12 +428,8 @@ TEST_F(TestIntervalHolder, TestMatchErrorsForCastIntervalDay) {
440428
}
441429

442430
TEST_F(TestIntervalHolder, TestUsingWeekFormatterForCastIntervalDay) {
443-
std::shared_ptr<IntervalDaysHolder> interval_holder;
444-
445-
auto status = IntervalDaysHolder::Make(0, &interval_holder);
446-
EXPECT_EQ(status.ok(), true) << status.message();
447-
448-
auto& cast_interval_day = *interval_holder;
431+
EXPECT_OK_AND_ASSIGN(auto interval_days_holder, IntervalDaysHolder::Make(0));
432+
auto& cast_interval_day = *interval_days_holder;
449433

450434
bool out_valid;
451435
std::string data("P1W");
@@ -465,12 +449,8 @@ TEST_F(TestIntervalHolder, TestUsingWeekFormatterForCastIntervalDay) {
465449
}
466450

467451
TEST_F(TestIntervalHolder, TestUsingCompleteFormatterForCastIntervalDay) {
468-
std::shared_ptr<IntervalDaysHolder> interval_holder;
469-
470-
auto status = IntervalDaysHolder::Make(0, &interval_holder);
471-
EXPECT_EQ(status.ok(), true) << status.message();
472-
473-
auto& cast_interval_day = *interval_holder;
452+
EXPECT_OK_AND_ASSIGN(auto interval_days_holder, IntervalDaysHolder::Make(0));
453+
auto& cast_interval_day = *interval_days_holder;
474454

475455
bool out_valid;
476456
std::string data("1742461111");
@@ -528,11 +508,7 @@ TEST_F(TestIntervalHolder, TestUsingCompleteFormatterForCastIntervalDay) {
528508
}
529509

530510
TEST_F(TestIntervalHolder, TestUsingCompleteFormatterForCastIntervalYear) {
531-
std::shared_ptr<IntervalYearsHolder> interval_years_holder;
532-
533-
auto status = IntervalYearsHolder::Make(0, &interval_years_holder);
534-
EXPECT_EQ(status.ok(), true) << status.message();
535-
511+
EXPECT_OK_AND_ASSIGN(auto interval_years_holder, IntervalYearsHolder::Make(0));
536512
auto& cast_interval_years = *interval_years_holder;
537513

538514
bool out_valid;

cpp/src/gandiva/random_generator_holder.cc

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,13 @@
1919
#include "gandiva/node.h"
2020

2121
namespace gandiva {
22-
Status RandomGeneratorHolder::Make(const FunctionNode& node,
23-
std::shared_ptr<RandomGeneratorHolder>* holder) {
22+
Result<std::shared_ptr<RandomGeneratorHolder>> RandomGeneratorHolder::Make(
23+
const FunctionNode& node) {
2424
ARROW_RETURN_IF(node.children().size() > 1,
2525
Status::Invalid("'random' function requires at most one parameter"));
2626

2727
if (node.children().size() == 0) {
28-
*holder = std::shared_ptr<RandomGeneratorHolder>(new RandomGeneratorHolder());
29-
return Status::OK();
28+
return std::shared_ptr<RandomGeneratorHolder>(new RandomGeneratorHolder());
3029
}
3130

3231
auto literal = dynamic_cast<LiteralNode*>(node.children().at(0).get());
@@ -38,8 +37,7 @@ Status RandomGeneratorHolder::Make(const FunctionNode& node,
3837
literal_type != arrow::Type::INT32,
3938
Status::Invalid("'random' function requires an int32 literal as parameter"));
4039

41-
*holder = std::shared_ptr<RandomGeneratorHolder>(new RandomGeneratorHolder(
40+
return std::shared_ptr<RandomGeneratorHolder>(new RandomGeneratorHolder(
4241
literal->is_null() ? 0 : std::get<int32_t>(literal->holder())));
43-
return Status::OK();
4442
}
4543
} // namespace gandiva

cpp/src/gandiva/random_generator_holder.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ class GANDIVA_EXPORT RandomGeneratorHolder : public FunctionHolder {
3434
public:
3535
~RandomGeneratorHolder() override = default;
3636

37-
static Status Make(const FunctionNode& node,
38-
std::shared_ptr<RandomGeneratorHolder>* holder);
37+
static Result<std::shared_ptr<RandomGeneratorHolder>> Make(const FunctionNode& node);
3938

4039
double operator()() { return distribution_(generator_); }
4140

cpp/src/gandiva/random_generator_holder_test.cc

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,38 +21,35 @@
2121

2222
#include <gtest/gtest.h>
2323

24+
#include "arrow/testing/gtest_util.h"
25+
2426
namespace gandiva {
2527

2628
class TestRandGenHolder : public ::testing::Test {
2729
public:
28-
FunctionNode BuildRandFunc() { return FunctionNode("random", {}, arrow::float64()); }
30+
FunctionNode BuildRandFunc() { return {"random", {}, arrow::float64()}; }
2931

3032
FunctionNode BuildRandWithSeedFunc(int32_t seed, bool seed_is_null) {
3133
auto seed_node =
3234
std::make_shared<LiteralNode>(arrow::int32(), LiteralHolder(seed), seed_is_null);
33-
return FunctionNode("rand", {seed_node}, arrow::float64());
35+
return {"rand", {seed_node}, arrow::float64()};
3436
}
3537
};
3638

3739
TEST_F(TestRandGenHolder, NoSeed) {
38-
std::shared_ptr<RandomGeneratorHolder> rand_gen_holder;
3940
FunctionNode rand_func = BuildRandFunc();
40-
auto status = RandomGeneratorHolder::Make(rand_func, &rand_gen_holder);
41-
EXPECT_EQ(status.ok(), true) << status.message();
41+
EXPECT_OK_AND_ASSIGN(auto rand_gen_holder, RandomGeneratorHolder::Make(rand_func));
4242

4343
auto& random = *rand_gen_holder;
4444
EXPECT_NE(random(), random());
4545
}
4646

4747
TEST_F(TestRandGenHolder, WithValidEqualSeeds) {
48-
std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_1;
49-
std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_2;
5048
FunctionNode rand_func_1 = BuildRandWithSeedFunc(12, false);
5149
FunctionNode rand_func_2 = BuildRandWithSeedFunc(12, false);
52-
auto status = RandomGeneratorHolder::Make(rand_func_1, &rand_gen_holder_1);
53-
EXPECT_EQ(status.ok(), true) << status.message();
54-
status = RandomGeneratorHolder::Make(rand_func_2, &rand_gen_holder_2);
55-
EXPECT_EQ(status.ok(), true) << status.message();
50+
51+
EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_1, RandomGeneratorHolder::Make(rand_func_1));
52+
EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_2, RandomGeneratorHolder::Make(rand_func_2));
5653

5754
auto& random_1 = *rand_gen_holder_1;
5855
auto& random_2 = *rand_gen_holder_2;
@@ -65,18 +62,12 @@ TEST_F(TestRandGenHolder, WithValidEqualSeeds) {
6562
}
6663

6764
TEST_F(TestRandGenHolder, WithValidSeeds) {
68-
std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_1;
69-
std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_2;
70-
std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_3;
7165
FunctionNode rand_func_1 = BuildRandWithSeedFunc(11, false);
7266
FunctionNode rand_func_2 = BuildRandWithSeedFunc(12, false);
7367
FunctionNode rand_func_3 = BuildRandWithSeedFunc(-12, false);
74-
auto status = RandomGeneratorHolder::Make(rand_func_1, &rand_gen_holder_1);
75-
EXPECT_EQ(status.ok(), true) << status.message();
76-
status = RandomGeneratorHolder::Make(rand_func_2, &rand_gen_holder_2);
77-
EXPECT_EQ(status.ok(), true) << status.message();
78-
status = RandomGeneratorHolder::Make(rand_func_3, &rand_gen_holder_3);
79-
EXPECT_EQ(status.ok(), true) << status.message();
68+
EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_1, RandomGeneratorHolder::Make(rand_func_1));
69+
EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_2, RandomGeneratorHolder::Make(rand_func_2));
70+
EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_3, RandomGeneratorHolder::Make(rand_func_3));
8071

8172
auto& random_1 = *rand_gen_holder_1;
8273
auto& random_2 = *rand_gen_holder_2;
@@ -86,14 +77,10 @@ TEST_F(TestRandGenHolder, WithValidSeeds) {
8677
}
8778

8879
TEST_F(TestRandGenHolder, WithInValidSeed) {
89-
std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_1;
90-
std::shared_ptr<RandomGeneratorHolder> rand_gen_holder_2;
9180
FunctionNode rand_func_1 = BuildRandWithSeedFunc(12, true);
9281
FunctionNode rand_func_2 = BuildRandWithSeedFunc(0, false);
93-
auto status = RandomGeneratorHolder::Make(rand_func_1, &rand_gen_holder_1);
94-
EXPECT_EQ(status.ok(), true) << status.message();
95-
status = RandomGeneratorHolder::Make(rand_func_2, &rand_gen_holder_2);
96-
EXPECT_EQ(status.ok(), true) << status.message();
82+
EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_1, RandomGeneratorHolder::Make(rand_func_1));
83+
EXPECT_OK_AND_ASSIGN(auto rand_gen_holder_2, RandomGeneratorHolder::Make(rand_func_2));
9784

9885
auto& random_1 = *rand_gen_holder_1;
9986
auto& random_2 = *rand_gen_holder_2;

0 commit comments

Comments
 (0)