From d12d36b1b06a7a8d6ffb872f54c5054327799416 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 27a16d1779960..621a450d3aef0 100644 --- a/cpp/src/gandiva/to_date_holder.cc +++ b/cpp/src/gandiva/to_date_holder.cc @@ -51,7 +51,7 @@ Status ToDateHolder::Make(const FunctionNode& node, 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 99036817d8e65..d60e440cd5c1e 100644 --- a/cpp/src/gandiva/to_date_holder_test.cc +++ b/cpp/src/gandiva/to_date_holder_test.cc @@ -30,14 +30,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: @@ -178,4 +182,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