[enhance](function) support two special format for str_to_date (#29823)

This commit is contained in:
zclllyybb
2024-01-11 13:59:41 +08:00
committed by yiguolei
parent eed72a101e
commit 4d97f8ea75
6 changed files with 77 additions and 20 deletions

View File

@ -30,6 +30,7 @@
#include <chrono> // IWYU pragma: keep
// IWYU pragma: no_include <bits/std_abs.h>
#include <cmath>
#include <cstring>
#include <exception>
#include <string>
#include <string_view>
@ -1588,11 +1589,24 @@ bool VecDateTimeValue::from_date_format_str(const char* format, int format_len,
// so we only need to set date part
// 3. if both are true, means all part of date_time be set, no need check_range_and_set_time
bool already_set_date_part = yearday > 0 || (week_num >= 0 && weekday > 0);
if (already_set_date_part && already_set_time_part) return true;
if (already_set_date_part)
if (already_set_date_part && already_set_time_part) {
return true;
}
// for two special date cases, complete default month/day
if (!time_part_used && year > 0) {
if (std::string_view {format, end} == "%Y") {
month = day = 1;
} else if (std::string_view {format, end} == "%Y-%m") {
day = 1;
}
}
if (already_set_date_part) {
return check_range_and_set_time(_year, _month, _day, hour, minute, second, _type);
if (already_set_time_part)
}
if (already_set_time_part) {
return check_range_and_set_time(year, month, day, _hour, _minute, _second, _type);
}
return check_range_and_set_time(year, month, day, hour, minute, second, _type);
}
@ -2578,6 +2592,16 @@ bool DateV2Value<T>::from_date_format_str(const char* format, int format_len, co
date_v2_value_.day_, 0, 0, 0, 0);
}
}
// for two special date cases, complete default month/day
if (!time_part_used && year > 0) {
if (std::string_view {format, end} == "%Y") {
month = day = 1;
} else if (std::string_view {format, end} == "%Y-%m") {
day = 1;
}
}
if (already_set_time_part) {
if constexpr (is_datetime) {
return check_range_and_set_time(year, month, day, date_v2_value_.hour_,

View File

@ -33,7 +33,7 @@ under the License.
Convert STR to DATE type by format specified, if the conversion result does not return NULL. Note that the 'format' parameter specifies the format of the first parameter.
The `format` supported is consistent with [date_format](date_format.md)
All formats in [date_format](./date-format) are supported. In addition, support auto completing the remainder of date part for '%Y' and '%Y-%m'.
### example
@ -65,7 +65,13 @@ mysql> select str_to_date("2020-09-01", "%Y-%m-%d %H:%i:%s");
+------------------------------------------------+
| 2020-09-01 00:00:00 |
+------------------------------------------------+
1 row in set (0.01 sec)
mysql> select str_to_date('2023','%Y');
+---------------------------+
| str_to_date('2023', '%Y') |
+---------------------------+
| 2023-01-01 |
+---------------------------+
```
### keywords

View File

@ -32,7 +32,7 @@ under the License.
通过format指定的方式将str转化为DATE类型,如果转化结果不对返回NULL。注意format指定的是第一个参数的格式。
支持的format格式与[date_format](date_format.md)一致
支持[date_format](./date-format)中的所有 format 格式,此外对于 '%Y' 和 '%Y-%m',支持补齐日期剩余部分。
### example
@ -64,7 +64,13 @@ mysql> select str_to_date("2020-09-01", "%Y-%m-%d %H:%i:%s");
+------------------------------------------------+
| 2020-09-01 00:00:00 |
+------------------------------------------------+
1 row in set (0.01 sec)
mysql> select str_to_date('2023','%Y');
+---------------------------+
| str_to_date('2023', '%Y') |
+---------------------------+
| 2023-01-01 |
+---------------------------+
```
### keywords

View File

@ -1536,6 +1536,14 @@ public class DateLiteral extends LiteralExpr {
getDateFromDaynr(days);
}
if (!timePartUsed && year > 0) {
if (format.equals("%Y")) {
month = day = 1;
} else if (format.equals("%Y-%m")) {
day = 1;
}
}
// Compute timestamp type
// TODO(Gabriel): we still use old version datetime/date and change this to new version when
// we think it's stable enough

View File

@ -13,6 +13,15 @@
-- !select4 --
2020-12-03T11:45:14
-- !add_1 --
2023-01-01
-- !add_2 --
2023-12-01
-- !add_3 --
2023-01-01
-- !select5 --
2019-12-01 yyyy-MM-dd 2019-12-01T00:00
20201203 yyyyMMdd 2020-12-03T00:00
@ -27,3 +36,12 @@
-- !select8 --
2020-12-03T11:45:14
-- !add_4 --
2023-01-01
-- !add_5 --
2023-12-01
-- !add_6 --
2023-01-01

View File

@ -36,43 +36,38 @@ suite("test_str_to_date") {
sql """ INSERT INTO test_str_to_date_db VALUES(2,'20201203', 'yyyyMMdd');"""
sql """ INSERT INTO test_str_to_date_db VALUES(3,'2020-12-03 11:45:14', 'yyyy-MM-dd HH:mm:ss');"""
sql """ set enable_nereids_planner=true , enable_fallback_to_original_planner=false;"""
sql """ set enable_nereids_planner=true , enable_fallback_to_original_planner=false;"""
qt_select1 """
select s1,s2,STR_TO_DATE(s1,s2) from test_str_to_date_db order by id;
"""
qt_select2 """
SELECT STR_TO_DATE('2019-12-01', 'yyyy-MM-dd');
"""
qt_select3 """
SELECT STR_TO_DATE('20201203', 'yyyyMMdd');
"""
qt_select4 """
SELECT STR_TO_DATE('2020-12-03 11:45:14', 'yyyy-MM-dd HH:mm:ss');
"""
qt_add_1 " select STR_TO_DATE('2023', '%Y') "
qt_add_2 " select STR_TO_DATE('2023-12', '%Y-%m') "
qt_add_3 " select STR_TO_DATE('2023-12', '%Y')"
sql """ set enable_nereids_planner=false;"""
sql """ set enable_nereids_planner=false;"""
qt_select5 """
select s1,s2,STR_TO_DATE(s1,s2) from test_str_to_date_db order by id;
"""
qt_select6 """
SELECT STR_TO_DATE('2019-12-01', 'yyyy-MM-dd');
"""
qt_select7 """
SELECT STR_TO_DATE('20201203', 'yyyyMMdd');
"""
qt_select8 """
SELECT STR_TO_DATE('2020-12-03 11:45:14', 'yyyy-MM-dd HH:mm:ss');
"""
qt_add_4 " select STR_TO_DATE('2023', '%Y') "
qt_add_5 " select STR_TO_DATE('2023-12', '%Y-%m') "
qt_add_6 " select STR_TO_DATE('2023-12', '%Y')"
}