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

yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new abd2eb4fa1 [Bug](date function) Fix bug for date format %T (#11729)
abd2eb4fa1 is described below

commit abd2eb4fa148a3c88d9a78b29a2289d161c73b67
Author: Gabriel <gabrielleeb...@gmail.com>
AuthorDate: Fri Aug 12 19:29:58 2022 +0800

    [Bug](date function) Fix bug for date format %T (#11729)
    
    * [Bug](date function) Fix bug for date format %T
---
 be/src/vec/runtime/vdatetime_value.cpp             | 99 ++++++++++++++--------
 be/src/vec/runtime/vdatetime_value.h               | 20 +++--
 .../datetime_functions/test_date_function.out      |  3 +
 .../datetime_functions/test_date_function.groovy   |  1 +
 4 files changed, 81 insertions(+), 42 deletions(-)

diff --git a/be/src/vec/runtime/vdatetime_value.cpp 
b/be/src/vec/runtime/vdatetime_value.cpp
index 315851c454..04dd72b8d4 100644
--- a/be/src/vec/runtime/vdatetime_value.cpp
+++ b/be/src/vec/runtime/vdatetime_value.cpp
@@ -48,7 +48,11 @@ uint8_t mysql_week_mode(uint32_t mode) {
 bool VecDateTimeValue::check_range(uint32_t year, uint32_t month, uint32_t 
day, uint32_t hour,
                                    uint32_t minute, uint32_t second, uint16_t 
type) {
     bool time = hour > (type == TIME_TIME ? TIME_MAX_HOUR : 23) || minute > 59 
|| second > 59;
-    return time || check_date(year, month, day);
+    if (type == TIME_TIME) {
+        return time;
+    } else {
+        return time || check_date(year, month, day);
+    }
 }
 
 bool VecDateTimeValue::check_date(uint32_t year, uint32_t month, uint32_t day) 
{
@@ -1316,22 +1320,32 @@ bool VecDateTimeValue::from_date_format_str(const char* 
format, int format_len,
                 val = tmp;
                 date_part_used = true;
                 break;
-            case 'r':
-                if (!from_date_format_str("%I:%i:%S %p", 11, val, val_end - 
val, &tmp)) {
+            case 'r': {
+                VecDateTimeValue tmp_val;
+                if (!tmp_val.from_date_format_str("%I:%i:%S %p", 11, val, 
val_end - val, &tmp)) {
                     return false;
                 }
+                this->_hour = tmp_val._hour;
+                this->_minute = tmp_val._minute;
+                this->_second = tmp_val._second;
                 val = tmp;
                 time_part_used = true;
                 already_set_time_part = true;
                 break;
-            case 'T':
-                if (!from_date_format_str("%H:%i:%S", 8, val, val_end - val, 
&tmp)) {
+            }
+            case 'T': {
+                VecDateTimeValue tmp_val;
+                if (!tmp_val.from_date_format_str("%H:%i:%S", 8, val, val_end 
- val, &tmp)) {
                     return false;
                 }
+                this->_hour = tmp_val._hour;
+                this->_minute = tmp_val._minute;
+                this->_second = tmp_val._second;
                 time_part_used = true;
                 already_set_time_part = true;
                 val = tmp;
                 break;
+            }
             case '.':
                 while (val < val_end && ispunct(*val)) {
                     val++;
@@ -1679,13 +1693,19 @@ std::size_t hash_value(VecDateTimeValue const& value) {
 
 template <typename T>
 bool DateV2Value<T>::is_invalid(uint32_t year, uint32_t month, uint32_t day, 
uint8_t hour,
-                                uint8_t minute, uint8_t second, uint32_t 
microsecond) {
+                                uint8_t minute, uint8_t second, uint32_t 
microsecond,
+                                bool only_time_part) {
     if (hour > 24 || minute >= 60 || second >= 60 || microsecond > 999999) {
         return true;
     }
+    if (only_time_part) {
+        return false;
+    }
+    if (year < MIN_YEAR || year > MAX_YEAR) {
+        return true;
+    }
     if (month == 2 && day == 29 && doris::is_leap(year)) return false;
-    if (year < MIN_YEAR || year > MAX_YEAR || month == 0 || month > 12 ||
-        day > s_days_in_month[month] || day == 0) {
+    if (month == 0 || month > 12 || day > s_days_in_month[month] || day == 0) {
         return true;
     }
     return false;
@@ -2061,22 +2081,41 @@ bool DateV2Value<T>::from_date_format_str(const char* 
format, int format_len, co
                 val = tmp;
                 date_part_used = true;
                 break;
-            case 'r':
-                if (!from_date_format_str("%I:%i:%S %p", 11, val, val_end - 
val, &tmp)) {
+            case 'r': {
+                if constexpr (is_datetime) {
+                    DateV2Value<DateTimeV2ValueType> tmp_val;
+                    if (!tmp_val.from_date_format_str("%I:%i:%S %p", 11, val, 
val_end - val,
+                                                      &tmp)) {
+                        return false;
+                    }
+                    this->date_v2_value_.hour_ = tmp_val.hour();
+                    this->date_v2_value_.minute_ = tmp_val.minute();
+                    this->date_v2_value_.second_ = tmp_val.second();
+                    val = tmp;
+                    time_part_used = true;
+                    already_set_time_part = true;
+                    break;
+                } else {
                     return false;
                 }
-                val = tmp;
-                time_part_used = true;
-                already_set_time_part = true;
-                break;
-            case 'T':
-                if (!from_date_format_str("%H:%i:%S", 8, val, val_end - val, 
&tmp)) {
+            }
+            case 'T': {
+                if constexpr (is_datetime) {
+                    DateV2Value<DateTimeV2ValueType> tmp_val;
+                    if (!tmp_val.from_date_format_str("%H:%i:%S", 8, val, 
val_end - val, &tmp)) {
+                        return false;
+                    }
+                    this->date_v2_value_.hour_ = tmp_val.hour();
+                    this->date_v2_value_.minute_ = tmp_val.minute();
+                    this->date_v2_value_.second_ = tmp_val.second();
+                    time_part_used = true;
+                    already_set_time_part = true;
+                    val = tmp;
+                    break;
+                } else {
                     return false;
                 }
-                time_part_used = true;
-                already_set_time_part = true;
-                val = tmp;
-                break;
+            }
             case '.':
                 while (val < val_end && ispunct(*val)) {
                     val++;
@@ -2156,20 +2195,9 @@ bool DateV2Value<T>::from_date_format_str(const char* 
format, int format_len, co
             LOG(WARNING) << "Microsecond is not allowed for date type!";
             return false;
         }
-        if (!date_part_used) {
-            LOG(WARNING) << "Time type is not supported yet!";
-            return false;
-        }
-    } else {
-        if (date_part_used) {
-            if (time_part_used) {
-                if constexpr (!is_datetime) {
-                    LOG(WARNING) << "Time part is not allowed for date type!";
-                    return false;
-                }
-            }
-        } else {
-            LOG(WARNING) << "Time type is not supported yet!";
+    } else if (time_part_used) {
+        if constexpr (!is_datetime) {
+            LOG(WARNING) << "Time part is not allowed for date type!";
             return false;
         }
     }
@@ -2228,7 +2256,8 @@ bool DateV2Value<T>::from_date_format_str(const char* 
format, int format_len, co
         }
     }
     if constexpr (is_datetime) {
-        return check_range_and_set_time(year, month, day, hour, minute, 
second, microsecond);
+        return check_range_and_set_time(year, month, day, hour, minute, 
second, microsecond,
+                                        time_part_used && !date_part_used);
     } else {
         return check_range_and_set_time(year, month, day, 0, 0, 0, 0);
     }
diff --git a/be/src/vec/runtime/vdatetime_value.h 
b/be/src/vec/runtime/vdatetime_value.h
index 1a384e20aa..0ac9ccf074 100644
--- a/be/src/vec/runtime/vdatetime_value.h
+++ b/be/src/vec/runtime/vdatetime_value.h
@@ -815,14 +815,20 @@ public:
 
     // Return true if range or date is invalid
     static bool is_invalid(uint32_t year, uint32_t month, uint32_t day, 
uint8_t hour,
-                           uint8_t minute, uint8_t second, uint32_t 
microsecond);
+                           uint8_t minute, uint8_t second, uint32_t 
microsecond,
+                           bool only_time_part = false);
 
     bool check_range_and_set_time(uint16_t year, uint8_t month, uint8_t day, 
uint8_t hour,
-                                  uint8_t minute, uint8_t second, uint32_t 
microsecond) {
-        if (is_invalid(year, month, day, hour, minute, second, microsecond)) {
+                                  uint8_t minute, uint8_t second, uint32_t 
microsecond,
+                                  bool only_time_part = false) {
+        if (is_invalid(year, month, day, hour, minute, second, microsecond, 
only_time_part)) {
             return false;
         }
-        set_time(year, month, day, hour, minute, second, microsecond);
+        if (only_time_part) {
+            set_time(0, 0, 0, hour, minute, second, microsecond);
+        } else {
+            set_time(year, month, day, hour, minute, second, microsecond);
+        }
         return true;
     };
 
@@ -1134,6 +1140,9 @@ public:
         }
     };
 
+    bool from_date_format_str(const char* format, int format_len, const char* 
value, int value_len,
+                              const char** sub_val_end);
+
 private:
     static uint8_t calc_week(const uint32_t& day_nr, const uint16_t& year, 
const uint8_t& month,
                              const uint8_t& day, uint8_t mode, uint16_t* 
to_year,
@@ -1145,9 +1154,6 @@ private:
     // Helper to set max, min, zero
     void set_zero();
 
-    bool from_date_format_str(const char* format, int format_len, const char* 
value, int value_len,
-                              const char** sub_val_end);
-
     union {
         T date_v2_value_;
         underlying_value int_val_;
diff --git 
a/regression-test/data/query/sql_functions/datetime_functions/test_date_function.out
 
b/regression-test/data/query/sql_functions/datetime_functions/test_date_function.out
index ee492a41b2..902bfc5147 100644
--- 
a/regression-test/data/query/sql_functions/datetime_functions/test_date_function.out
+++ 
b/regression-test/data/query/sql_functions/datetime_functions/test_date_function.out
@@ -353,3 +353,6 @@ true
 -- !sql --
 \N
 
+-- !sql --
+2022-07-12T20:00:45
+
diff --git 
a/regression-test/suites/query/sql_functions/datetime_functions/test_date_function.groovy
 
b/regression-test/suites/query/sql_functions/datetime_functions/test_date_function.groovy
index 6f915f44a1..b5387f8205 100644
--- 
a/regression-test/suites/query/sql_functions/datetime_functions/test_date_function.groovy
+++ 
b/regression-test/suites/query/sql_functions/datetime_functions/test_date_function.groovy
@@ -293,4 +293,5 @@ suite("test_date_function", "query") {
 
     qt_sql """ select date_format('2022-08-04', '%X %V %w'); """
     qt_sql """ select STR_TO_DATE('Tue Jul 12 20:00:45 CST 2022', '%a %b %e 
%H:%i:%s %Y'); """
+    qt_sql """ select STR_TO_DATE('Tue Jul 12 20:00:45 CST 2022', '%a %b %e %T 
CST %Y'); """
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to