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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]