From d66780d90c6faf7bf051cbf12b4b68dff098bd54 Mon Sep 17 00:00:00 2001 From: Yue Date: Thu, 30 Nov 2023 03:55:14 +0800 Subject: [PATCH] GH-38879: [C++][Gandiva] Fix Gandiva to_date function's validation for supress errors parameter (#38987) ### Rationale for this change * This PR fixes the `to_date_utf8_utf8_int32` gandiva function to avoid crash for invalid input ### What changes are included in this PR? * A bug fix for to_date_utf8_utf8_int32 parameter validation ### Are these changes tested? Yes, new tests are added to verify non literal input won't crash the to_date_utf8_utf8_int32 function ### Are there any user-facing changes? No * Closes: #38879 Authored-by: Yue Ni Signed-off-by: Sutou Kouhei --- cpp/src/gandiva/to_date_holder.cc | 2 +- cpp/src/gandiva/to_date_holder_test.cc | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/cpp/src/gandiva/to_date_holder.cc b/cpp/src/gandiva/to_date_holder.cc index 0778c39b4c2e4..76f16f0cb1b74 100644 --- a/cpp/src/gandiva/to_date_holder.cc +++ b/cpp/src/gandiva/to_date_holder.cc @@ -50,7 +50,7 @@ Result> ToDateHolder::Make(const FunctionNode& nod if (node.children().size() == 3) { auto literal_suppress_errors = dynamic_cast(node.children().at(2).get()); - if (literal_pattern == nullptr) { + if (literal_suppress_errors == nullptr) { return Status::Invalid( "The (optional) third parameter to 'to_date' function needs to an integer " "literal to indicate whether to suppress the error"); diff --git a/cpp/src/gandiva/to_date_holder_test.cc b/cpp/src/gandiva/to_date_holder_test.cc index 1e0f2e1578fb1..1612d9b4f440e 100644 --- a/cpp/src/gandiva/to_date_holder_test.cc +++ b/cpp/src/gandiva/to_date_holder_test.cc @@ -29,14 +29,18 @@ namespace gandiva { class TestToDateHolder : public ::testing::Test { public: - FunctionNode BuildToDate(std::string pattern) { + FunctionNode BuildToDate(std::string pattern, + std::shared_ptr suppress_error_node = nullptr) { auto field = std::make_shared(arrow::field("in", arrow::utf8())); auto pattern_node = std::make_shared(arrow::utf8(), LiteralHolder(pattern), false); - auto suppress_error_node = - std::make_shared(arrow::int32(), LiteralHolder(0), false); - return FunctionNode("to_date_utf8_utf8_int32", - {field, pattern_node, suppress_error_node}, arrow::int64()); + if (suppress_error_node == nullptr) { + suppress_error_node = + std::make_shared(arrow::int32(), LiteralHolder(0), false); + } + return {"to_date_utf8_utf8_int32", + {field, pattern_node, std::move(suppress_error_node)}, + arrow::int64()}; } protected: @@ -167,4 +171,14 @@ TEST_F(TestToDateHolder, TestSimpleDateYear) { EXPECT_EQ(millis_since_epoch, 915148800000); } +TEST_F(TestToDateHolder, TestMakeFromFunctionNode) { + auto to_date_func = BuildToDate("YYYY"); + EXPECT_OK_AND_ASSIGN(auto to_date_holder, ToDateHolder::Make(to_date_func)); +} + +TEST_F(TestToDateHolder, TestMakeFromInvalidSurpressParamFunctionNode) { + auto non_literal_param = std::make_shared(arrow::field("in", arrow::utf8())); + auto to_date_func = BuildToDate("YYYY", std::move(non_literal_param)); + ASSERT_RAISES(Invalid, ToDateHolder::Make(to_date_func).status()); +} } // namespace gandiva