You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by GitBox <gi...@apache.org> on 2021/07/13 10:57:38 UTC

[GitHub] [arrow] augustoasilva opened a new pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

augustoasilva opened a new pull request #10711:
URL: https://github.com/apache/arrow/pull/10711


   Converts the number of seconds from unix epoch (1970-01-01 00:00:00 UTC) to a string representing the timestamp of that moment in the current system time zone in the format of "1970-01-01 00:00:00".


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva commented on pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva commented on pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#issuecomment-879806994


   @anthonylouisbsb could you review this PR?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva closed pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva closed pull request #10711:
URL: https://github.com/apache/arrow/pull/10711


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva commented on a change in pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva commented on a change in pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#discussion_r669991533



##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";

Review comment:
       Ok, I will take a look further within the already used libs on the project to process more patterns.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] github-actions[bot] commented on pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
github-actions[bot] commented on pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#issuecomment-878988685


   https://issues.apache.org/jira/browse/ARROW-13322


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva commented on a change in pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva commented on a change in pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#discussion_r669990651



##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));
+
+  if (!match) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern");
+    *out_len = 0;
+    return "";
+  }
+
+  // length from pattern
+  int res = 0;
+
+  switch (pattern_len) {
+    // yyyy
+    case 4:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64, year);
+      break;
+    // yyyy-MM
+    case 7:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64 "-%02" PRId64, year,
+                     month);
+      break;
+    // yyyy-MM-dd
+    case 10:

Review comment:
       No, I focused mainly on the first pattern.

##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));
+
+  if (!match) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern");
+    *out_len = 0;
+    return "";
+  }
+
+  // length from pattern
+  int res = 0;
+
+  switch (pattern_len) {
+    // yyyy
+    case 4:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64, year);
+      break;
+    // yyyy-MM
+    case 7:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64 "-%02" PRId64, year,
+                     month);
+      break;
+    // yyyy-MM-dd
+    case 10:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64, year, month, day);
+      break;
+    // yyyy-MM-dd hh
+    case 13:

Review comment:
       No, I focused mainly on the first pattern.

##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));
+
+  if (!match) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern");
+    *out_len = 0;
+    return "";
+  }
+
+  // length from pattern
+  int res = 0;
+
+  switch (pattern_len) {
+    // yyyy
+    case 4:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64, year);
+      break;
+    // yyyy-MM
+    case 7:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64 "-%02" PRId64, year,
+                     month);
+      break;
+    // yyyy-MM-dd
+    case 10:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64, year, month, day);
+      break;
+    // yyyy-MM-dd hh
+    case 13:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64, year, month,
+                     day, hour);
+      break;
+    // yyyy-MM-dd hh:mm
+    case 16:

Review comment:
       No, I focused mainly on the first pattern.

##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));
+
+  if (!match) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern");
+    *out_len = 0;
+    return "";
+  }
+
+  // length from pattern
+  int res = 0;
+
+  switch (pattern_len) {
+    // yyyy
+    case 4:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64, year);
+      break;
+    // yyyy-MM
+    case 7:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64 "-%02" PRId64, year,
+                     month);
+      break;
+    // yyyy-MM-dd
+    case 10:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64, year, month, day);
+      break;
+    // yyyy-MM-dd hh
+    case 13:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64, year, month,
+                     day, hour);
+      break;
+    // yyyy-MM-dd hh:mm
+    case 16:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64,
+                     year, month, day, hour, minute);
+      break;
+    // yyyy-MM-dd hh:mm:ss
+    case 19:

Review comment:
       No, I focused mainly on the first pattern.

##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));
+
+  if (!match) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern");
+    *out_len = 0;
+    return "";
+  }
+
+  // length from pattern
+  int res = 0;
+
+  switch (pattern_len) {
+    // yyyy
+    case 4:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64, year);
+      break;
+    // yyyy-MM
+    case 7:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64 "-%02" PRId64, year,
+                     month);
+      break;
+    // yyyy-MM-dd
+    case 10:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64, year, month, day);
+      break;
+    // yyyy-MM-dd hh
+    case 13:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64, year, month,
+                     day, hour);
+      break;
+    // yyyy-MM-dd hh:mm
+    case 16:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64,
+                     year, month, day, hour, minute);
+      break;
+    // yyyy-MM-dd hh:mm:ss
+    case 19:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+      break;
+    // yyyy-MM-dd hh:mm:ss.sss
+    case 23:

Review comment:
       No, I focused mainly on the first pattern.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva commented on a change in pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva commented on a change in pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#discussion_r669991187



##########
File path: cpp/src/gandiva/precompiled/time_test.cc
##########
@@ -839,4 +839,86 @@ TEST(TestTime, TestToTimeNumeric) {
   EXPECT_EQ(expected_output, to_time_float64(3601.500));
 }
 
-}  // namespace gandiva
+TEST(TestTime, TestFromUnixtimeWithoutPattern) {

Review comment:
       Ok, will do it.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva commented on a change in pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva commented on a change in pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#discussion_r669989632



##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}

Review comment:
       They are similar, but the from_unixtime does not has the seconds' fractions. Also, from_unixtime without the pattern the size is fixed. I think I could call the one that you have mentioned inside it to not duplicate the code.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] anthonylouisbsb commented on a change in pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
anthonylouisbsb commented on a change in pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#discussion_r671204429



##########
File path: cpp/src/gandiva/gdv_function_stubs.cc
##########
@@ -767,6 +769,113 @@ const char* gdv_fn_initcap_utf8(int64_t context, const char* data, int32_t data_
 }
 }
 
+GANDIVA_EXPORT
+const char* gdv_fn_from_unixtime_int64(int64_t context, gdv_timestamp in,
+                                       int32_t* out_len) {
+  const char* pattern = "yyyy-MM-dd hh:mm:ss";
+  const int length = strlen(pattern);
+  const char* ret =
+      gdv_fn_from_unixtime_int64_utf8(context, in, pattern, length, out_len);
+
+  return ret;
+}
+
+GANDIVA_EXPORT
+const char* gdv_fn_from_unixtime_int64_utf8(int64_t context, gdv_timestamp in,
+                                            const char* pattern, int32_t pattern_len,
+                                            int32_t* out_len) {
+  // Patter dictionary to translate a given pattern like yyyy-MM-dd to
+  // a pattern like %Y-%m-%d that the std::strftime can translate.
+  std::map<std::string, std::string> pattern_dict{
+      {"YYYY", "%Y"},  // converts 'YYYY' to full year, eg. 1970
+      {"YY", "%y"},    // converts 'YY' to final two-digits year, eg. 70
+      {"yyyy", "%Y"},  // converts 'YYYY' to full year, eg. 1970
+      {"yy", "%y"},    // converts 'YY' to final two-digits year, eg. 70
+      {"MM", "%m"},    // converts 'MM' to month digits, eg. 10
+      {"M", "%b"},     // converts 'M' to month abbreviation, eg. Oct
+      {"Mm", "%B"},    // converts 'Mm' to month abbreviation, eg. October
+      {"d", "%e"},  // converts 'd' to day of the month as a decimal number (range [1,31])
+      {"dd",
+       "%d"},  // converts 'dd' to day of the month as a decimal number (range [01,31])
+      {"h",
+       "%I"},  // converts 'h' hour as a decimal number, 12 hour clock (range [01-12])
+      {"hh",
+       "%H"},  // converts 'hh' to hour as a decimal number, 24 hour clock (range [00-23])
+      {"m", "%M"},   // converts 'm' to minute as a decimal number (range [00,59])
+      {"mm", "%M"},  // converts 'mm' minute as a decimal number (range [00,59])
+      {"s", "%S"},   // converts 's' to second as a decimal number (range [00,60])
+      {"ss", "%S"},  // converts 'ss' to second as a decimal number (range [00,60])
+  };
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context,
+                                 "Invalid pattern, it must have at least 1 char");
+    *out_len = 0;
+    return "";
+  }

Review comment:
       Is the pattern Literal? If it is Literal you can follow the example of the [TO_DATE](https://github.com/apache/arrow/blob/master/cpp/src/gandiva/to_date_holder.cc) function and move this process to a holder to avoid instantiate and convert this map for each value

##########
File path: cpp/src/gandiva/gdv_function_stubs.cc
##########
@@ -767,6 +769,113 @@ const char* gdv_fn_initcap_utf8(int64_t context, const char* data, int32_t data_
 }
 }
 
+GANDIVA_EXPORT
+const char* gdv_fn_from_unixtime_int64(int64_t context, gdv_timestamp in,
+                                       int32_t* out_len) {
+  const char* pattern = "yyyy-MM-dd hh:mm:ss";
+  const int length = strlen(pattern);

Review comment:
       I think you should insert the pattern length manually and change the name to `pattern_len`.
   
   I think magic numbers are bad when they are inserted without context, but in that case you know that number refers to the pattern above. It would avoid a call to the `strlen` function too. 

##########
File path: cpp/src/gandiva/tests/projector_test.cc
##########
@@ -1353,4 +1353,51 @@ TEST_F(TestProjector, TestBinRepresentation) {
   EXPECT_ARROW_ARRAY_EQUALS(exp, outputs.at(0));
 }
 
+TEST_F(TestProjector, TestFromUnixTime) {
+  // schema for input fields
+  auto field0 = field("f0", arrow::int64());
+  auto field1 = field("f1", arrow::utf8());
+  auto schema = arrow::schema({field0, field1});
+
+  // output fields
+  auto field_from_unixtime = field("from_unixtime", arrow::utf8());
+
+  // Build expression
+  auto from_unixtime_expr = TreeExprBuilder::MakeExpression(
+      "from_unixtime", {field0, field1}, field_from_unixtime);
+
+  std::shared_ptr<Projector> projector;
+  auto status =
+      Projector::Make(schema, {from_unixtime_expr}, TestConfiguration(), &projector);
+  EXPECT_TRUE(status.ok()) << status.message();
+
+  // Create a row-batch with some sample data
+  int64_t epoch_timestamp1 = 1107428640;  // 2005-02-03 11:04:00
+  int64_t epoch_timestamp2 = 1338975201;  // 2012-06-06 09:33:21
+  int64_t epoch_timestamp3 = 1543449599;  // 2018-11-28 23:59:59
+
+  std::string pattern1 = "yyyy-MM-dd hh:mm";
+  std::string pattern2 = "dd-M-yy";
+  std::string pattern3 = "hh:mm:ss dd-Mm-YYYY";
+
+  int num_records = 3;
+  auto array0 = MakeArrowArrayInt64(
+      {epoch_timestamp1, epoch_timestamp2, epoch_timestamp3}, {true, true, true});
+  auto array1 = MakeArrowArrayUtf8({pattern1, pattern2, pattern3}, {true, true, true});
+  // expected output
+  auto exp_from_unixtime = MakeArrowArrayUtf8(
+      {"2005-02-03 11:04", "06-Jun-12", "23:59:59 28-November-2018"}, {true, true, true});

Review comment:
       The date functions in the Gandiva usually consider the patterns as Literal(see the `TO_DATE` function). That one that you added has a different behavior?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva commented on a change in pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva commented on a change in pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#discussion_r671549496



##########
File path: cpp/src/gandiva/gdv_function_stubs.cc
##########
@@ -767,6 +769,113 @@ const char* gdv_fn_initcap_utf8(int64_t context, const char* data, int32_t data_
 }
 }
 
+GANDIVA_EXPORT
+const char* gdv_fn_from_unixtime_int64(int64_t context, gdv_timestamp in,
+                                       int32_t* out_len) {
+  const char* pattern = "yyyy-MM-dd hh:mm:ss";
+  const int length = strlen(pattern);

Review comment:
       It make senses, I will apply your suggestion.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva commented on pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva commented on pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#issuecomment-882961161


   Moving this PR to https://github.com/apache/arrow/pull/9877


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva closed pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva closed pull request #10711:
URL: https://github.com/apache/arrow/pull/10711


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] anthonylouisbsb commented on a change in pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
anthonylouisbsb commented on a change in pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#discussion_r669769114



##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));
+
+  if (!match) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern");
+    *out_len = 0;
+    return "";
+  }
+
+  // length from pattern
+  int res = 0;
+
+  switch (pattern_len) {
+    // yyyy
+    case 4:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64, year);
+      break;
+    // yyyy-MM
+    case 7:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64 "-%02" PRId64, year,
+                     month);
+      break;
+    // yyyy-MM-dd
+    case 10:

Review comment:
       What happens if the user defines a pattern like this: `dd-MM-yyyy`, the method will process it correctly?

##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";

Review comment:
       I think that regex does not cover all possible patterns that function can receive, like: `MM-yyyy-dd`.
   
   The [Hive](https://github.com/apache/hive/blob/a2d50efecdeb066b767ce0ae0850103d5ee35933/hplsql/src/main/java/org/apache/hive/hplsql/functions/FunctionDatetime.java#L173) code use an external library to process that result. I think you should do the same thing,
   
   [Strftime](https://www.cplusplus.com/reference/ctime/strftime/) is an example of a library that you can use to format the output of a time.

##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}

Review comment:
       This function you had created is very similar to [this other one](https://github.com/apache/arrow/blob/f1a7b0d765ad925cc764ebd3e512f02bcdedfd41/cpp/src/gandiva/precompiled/time.cc#L778). If they are equal, I think you do not need to repeat the code, just add an alias in the function registry for the existent function

##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));

Review comment:
       You should move this function to gdv_stubs and must use the RE2 library to process the regex

##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));
+
+  if (!match) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern");
+    *out_len = 0;
+    return "";
+  }
+
+  // length from pattern
+  int res = 0;
+
+  switch (pattern_len) {
+    // yyyy
+    case 4:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64, year);
+      break;
+    // yyyy-MM
+    case 7:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64 "-%02" PRId64, year,
+                     month);
+      break;
+    // yyyy-MM-dd
+    case 10:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64, year, month, day);
+      break;
+    // yyyy-MM-dd hh
+    case 13:

Review comment:
       The same case above, if the user define a different pattern with the same length: `dd-MM-yyyy hh`

##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));
+
+  if (!match) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern");
+    *out_len = 0;
+    return "";
+  }
+
+  // length from pattern
+  int res = 0;
+
+  switch (pattern_len) {
+    // yyyy
+    case 4:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64, year);
+      break;
+    // yyyy-MM
+    case 7:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64 "-%02" PRId64, year,
+                     month);
+      break;
+    // yyyy-MM-dd
+    case 10:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64, year, month, day);
+      break;
+    // yyyy-MM-dd hh
+    case 13:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64, year, month,
+                     day, hour);
+      break;
+    // yyyy-MM-dd hh:mm
+    case 16:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64,
+                     year, month, day, hour, minute);
+      break;
+    // yyyy-MM-dd hh:mm:ss
+    case 19:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+      break;
+    // yyyy-MM-dd hh:mm:ss.sss
+    case 23:

Review comment:
       Ditto

##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));
+
+  if (!match) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern");
+    *out_len = 0;
+    return "";
+  }
+
+  // length from pattern
+  int res = 0;
+
+  switch (pattern_len) {
+    // yyyy
+    case 4:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64, year);
+      break;
+    // yyyy-MM
+    case 7:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64 "-%02" PRId64, year,
+                     month);
+      break;
+    // yyyy-MM-dd
+    case 10:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64, year, month, day);
+      break;
+    // yyyy-MM-dd hh
+    case 13:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64, year, month,
+                     day, hour);
+      break;
+    // yyyy-MM-dd hh:mm
+    case 16:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64,
+                     year, month, day, hour, minute);
+      break;
+    // yyyy-MM-dd hh:mm:ss
+    case 19:

Review comment:
       Ditto

##########
File path: cpp/src/gandiva/precompiled/time_test.cc
##########
@@ -839,4 +839,86 @@ TEST(TestTime, TestToTimeNumeric) {
   EXPECT_EQ(expected_output, to_time_float64(3601.500));
 }
 
-}  // namespace gandiva
+TEST(TestTime, TestFromUnixtimeWithoutPattern) {

Review comment:
       Create some integrated tests for this function in Java or in the `tests` folder

##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));
+
+  if (!match) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern");
+    *out_len = 0;
+    return "";
+  }
+
+  // length from pattern
+  int res = 0;
+
+  switch (pattern_len) {
+    // yyyy
+    case 4:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64, year);
+      break;
+    // yyyy-MM
+    case 7:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64 "-%02" PRId64, year,
+                     month);
+      break;
+    // yyyy-MM-dd
+    case 10:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64, year, month, day);
+      break;
+    // yyyy-MM-dd hh
+    case 13:
+      res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64, year, month,
+                     day, hour);
+      break;
+    // yyyy-MM-dd hh:mm
+    case 16:

Review comment:
       Ditto




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva commented on a change in pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva commented on a change in pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#discussion_r669990651



##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));
+
+  if (!match) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern");
+    *out_len = 0;
+    return "";
+  }
+
+  // length from pattern
+  int res = 0;
+
+  switch (pattern_len) {
+    // yyyy
+    case 4:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64, year);
+      break;
+    // yyyy-MM
+    case 7:
+      res = snprintf(char_buffer, char_buffer_length, "%04" PRId64 "-%02" PRId64, year,
+                     month);
+      break;
+    // yyyy-MM-dd
+    case 10:

Review comment:
       Yes, the comment was misplaced.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva commented on pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva commented on pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#issuecomment-882961161


   Moving this PR to https://github.com/apache/arrow/pull/9877


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva commented on pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva commented on pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#issuecomment-882961161


   Moving this PR to https://github.com/apache/arrow/pull/9877


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva closed pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva closed pull request #10711:
URL: https://github.com/apache/arrow/pull/10711


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [arrow] augustoasilva commented on a change in pull request #10711: ARROW-13322: [C++][Gandiva] Add from_unixtime hive function to gandiva

Posted by GitBox <gi...@apache.org>.
augustoasilva commented on a change in pull request #10711:
URL: https://github.com/apache/arrow/pull/10711#discussion_r669990486



##########
File path: cpp/src/gandiva/precompiled/time.cc
##########
@@ -841,6 +843,161 @@ gdv_int64 castBIGINT_daytimeinterval(gdv_day_time_interval in) {
          extractDay_daytimeinterval(in) * MILLIS_IN_DAY;
 }
 
+FORCE_INLINE
+const char* from_unixtime_int64(gdv_int64 context, gdv_timestamp in, gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+
+  static const int kTimeStampStringLen = 19;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  // yyyy-MM-dd hh:mm:ss
+  int res = snprintf(char_buffer, char_buffer_length,
+                     "%04" PRId64 "-%02" PRId64 "-%02" PRId64 " %02" PRId64 ":%02" PRId64
+                     ":%02" PRId64,
+                     year, month, day, hour, minute, second);
+  if (res < 0) {
+    gdv_fn_context_set_error_msg(context, "Could not format the timestamp");
+    *out_len = 0;
+    return "";
+  }
+
+  *out_len = kTimeStampStringLen;
+
+  if (*out_len <= 0) {
+    if (*out_len < 0) {
+      gdv_fn_context_set_error_msg(context, "Length of output string cannot be negative");
+    }
+    *out_len = 0;
+    return "";
+  }
+
+  char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
+  if (ret == nullptr) {
+    gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
+    *out_len = 0;
+    return "";
+  }
+
+  memcpy(ret, char_buffer, *out_len);
+  return ret;
+}
+
+FORCE_INLINE
+const char* from_unixtime_int64_utf8(gdv_int64 context, gdv_timestamp in,
+                                     const char* pattern, gdv_int32 pattern_len,
+                                     gdv_int32* out_len) {
+  gdv_int64 year = extractYear_timestamp(in);
+  gdv_int64 month = extractMonth_timestamp(in);
+  gdv_int64 day = extractDay_timestamp(in);
+  gdv_int64 hour = extractHour_timestamp(in);
+  gdv_int64 minute = extractMinute_timestamp(in);
+  gdv_int64 second = extractSecond_timestamp(in);
+  gdv_int64 millis = in % MILLIS_IN_SEC;
+
+  if (pattern_len <= 0) {
+    gdv_fn_context_set_error_msg(context, "Invalid allowed pattern size");
+    *out_len = 0;
+    return "";
+  }
+
+  static const int kTimeStampStringLen = pattern_len;
+  const int char_buffer_length = kTimeStampStringLen + 1;  // snprintf adds \0
+  char char_buffer[char_buffer_length];
+
+  const char* regex_format =
+      "y{4}(-[M]{2})?+.*?(-[d]{2})?+.*?( [h]{2})?+.*?"
+      "(:[mm]{2})?+.*?(:[s]{2})?+.*?(.[s]{3})?+.*?";
+  bool match = std::regex_match(pattern, std::regex(regex_format));

Review comment:
       Ok, I will do it.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org