You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ko...@apache.org on 2023/09/08 03:47:49 UTC

[arrow] branch main updated: GH-37608: [C++][Gandiva] TO_DATE function supports YYYY-MM and YYYY (#37609)

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

kou 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 a8a604cfc5 GH-37608: [C++][Gandiva] TO_DATE function supports YYYY-MM and YYYY (#37609)
a8a604cfc5 is described below

commit a8a604cfc5bc8d05ca3b1ef1388e6efd8ba6e5cd
Author: DenisTarasyuk <13...@users.noreply.github.com>
AuthorDate: Fri Sep 8 06:47:43 2023 +0300

    GH-37608: [C++][Gandiva] TO_DATE function supports YYYY-MM and YYYY (#37609)
    
    Added fix for case when pattern does not contain day part
    
    ### Rationale for this change
    
    TO_DATE Gandiva function returns wrong result if used with pattern 'YYYY-MM' or 'YYYY'.
    
    ### What changes are included in this PR?
    
    Add a fix for case when tm_mday is zero to set it to 1
    
    ### Are these changes tested?
    
    Added tests that cover described cases
    
    ### Are there any user-facing changes?
    
    No
    
    * Closes: #37608
    
    Authored-by: DenisTarasyuk <13...@users.noreply.github.com>
    Signed-off-by: Sutou Kouhei <ko...@clear-code.com>
---
 cpp/src/arrow/util/value_parsing.h     |  2 +-
 cpp/src/gandiva/to_date_holder_test.cc | 29 +++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/cpp/src/arrow/util/value_parsing.h b/cpp/src/arrow/util/value_parsing.h
index 5193f0af75..d4bbf20665 100644
--- a/cpp/src/arrow/util/value_parsing.h
+++ b/cpp/src/arrow/util/value_parsing.h
@@ -801,7 +801,7 @@ static inline bool ParseTimestampStrptime(const char* buf, size_t length,
   // ignore the time part
   arrow_vendored::date::sys_seconds secs =
       arrow_vendored::date::sys_days(arrow_vendored::date::year(result.tm_year + 1900) /
-                                     (result.tm_mon + 1) / result.tm_mday);
+                                     (result.tm_mon + 1) / std::max(result.tm_mday, 1));
   if (!ignore_time_in_day) {
     secs += (std::chrono::hours(result.tm_hour) + std::chrono::minutes(result.tm_min) +
              std::chrono::seconds(result.tm_sec));
diff --git a/cpp/src/gandiva/to_date_holder_test.cc b/cpp/src/gandiva/to_date_holder_test.cc
index a420774bfc..99036817d8 100644
--- a/cpp/src/gandiva/to_date_holder_test.cc
+++ b/cpp/src/gandiva/to_date_holder_test.cc
@@ -149,4 +149,33 @@ TEST_F(TestToDateHolder, TestSimpleDateTimeMakeError) {
   EXPECT_EQ(status.IsInvalid(), true) << status.message();
 }
 
+TEST_F(TestToDateHolder, TestSimpleDateYearMonth) {
+  std::shared_ptr<ToDateHolder> to_date_holder;
+  ASSERT_OK(ToDateHolder::Make("YYYY-MM", 1, &to_date_holder));
+
+  auto& to_date = *to_date_holder;
+  bool out_valid;
+  std::string s("2012-12");
+  int64_t millis_since_epoch =
+      to_date(&execution_context_, s.data(), (int)s.length(), true, &out_valid);
+  EXPECT_EQ(millis_since_epoch, 1354320000000);
+
+  s = std::string("2012-01");
+  millis_since_epoch =
+      to_date(&execution_context_, s.data(), (int)s.length(), true, &out_valid);
+  EXPECT_EQ(millis_since_epoch, 1325376000000);
+}
+
+TEST_F(TestToDateHolder, TestSimpleDateYear) {
+  std::shared_ptr<ToDateHolder> to_date_holder;
+  ASSERT_OK(ToDateHolder::Make("YYYY", 1, &to_date_holder));
+
+  auto& to_date = *to_date_holder;
+  bool out_valid;
+  std::string s("1999");
+  int64_t millis_since_epoch =
+      to_date(&execution_context_, s.data(), (int)s.length(), true, &out_valid);
+  EXPECT_EQ(millis_since_epoch, 915148800000);
+}
+
 }  // namespace gandiva