summaryrefslogtreecommitdiff
path: root/sql/item_timefunc.cc
diff options
context:
space:
mode:
authorunknown <dlenev@brandersnatch.localdomain>2004-12-22 18:58:25 +0300
committerunknown <dlenev@brandersnatch.localdomain>2004-12-22 18:58:25 +0300
commit0ed3eb41a0db444896a5dd26e814b8f0f630957b (patch)
treed57706867d87609f0c34d809f0d981f8eedf267c /sql/item_timefunc.cc
parentcb6007ceb61a3733af011b1f0ff96e3951155f5b (diff)
downloadmariadb-git-0ed3eb41a0db444896a5dd26e814b8f0f630957b.tar.gz
Fix for bug #7458 "Microseconds are gobbled from the string result of
STR_TO_DATE() function if there is another format specifier after %f in format string". Also small cleanup of STR_TO_DATE() implementation. (After review version.) mysql-test/r/date_formats.result: Added test for small bug in STR_TO_DATE() implementation which caused microseconds to be gobbled from string result of this function, if there was another specifier after %f in format string. mysql-test/t/date_formats.test: Added test for small bug in STR_TO_DATE() implementation which caused microseconds to be gobbled from string result of this function, if there was another specifier after %f in format string. sql/item_timefunc.cc: Small cleanup of str_to_date() implementation. Renamed check_result_type() to less ambigous get_date_time_result_type() and made it static. Also added handling of %X,%x,%V,%v to this function. Fixed small bug in it which caused microseconds to be gobbled if there was some other specifiers after %f. Cleaned up comments a bit.
Diffstat (limited to 'sql/item_timefunc.cc')
-rw-r--r--sql/item_timefunc.cc60
1 files changed, 39 insertions, 21 deletions
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 354c8b5c50c..84a9e01ed2a 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -149,6 +149,9 @@ static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
conversion specifiers that can be used in such sub-patterns is limited.
Also most of checks are skipped in this case.
+ If one adds new format specifiers to this function he should also
+ consider adding them to get_date_time_result_type() function.
+
RETURN
0 ok
1 error
@@ -2595,25 +2598,31 @@ void Item_func_get_format::print(String *str)
/*
- check_result_type(s, l) returns DATE/TIME type
- according to format string
-
- s: DATE/TIME format string
- l: length of s
- Result: date_time_format_types value:
- DATE_TIME_MICROSECOND, DATE_TIME,
- TIME_MICROSECOND, TIME_ONLY
-
- We don't process day format's characters('D', 'd', 'e')
- because day may be a member of all date/time types.
- If only day format's character and no time part present
- the result type is MYSQL_TYPE_DATE
+ Get type of datetime value (DATE/TIME/...) which will be produced
+ according to format string.
+
+ SYNOPSIS
+ get_date_time_result_type()
+ format - format string
+ length - length of format string
+
+ NOTE
+ We don't process day format's characters('D', 'd', 'e') because day
+ may be a member of all date/time types.
+
+ Format specifiers supported by this function should be in sync with
+ specifiers supported by extract_date_time() function.
+
+ RETURN VALUE
+ One of date_time_format_types values:
+ DATE_TIME_MICROSECOND, DATE_TIME, DATE_ONLY, TIME_MICROSECOND, TIME_ONLY
*/
-date_time_format_types check_result_type(const char *format, uint length)
+static date_time_format_types
+get_date_time_result_type(const char *format, uint length)
{
const char *time_part_frms= "HISThiklrs";
- const char *date_part_frms= "MUYWabcjmuyw";
+ const char *date_part_frms= "MVUXYWabcjmvuxyw";
bool date_part_used= 0, time_part_used= 0, frac_second_used= 0;
const char *val= format;
@@ -2624,22 +2633,30 @@ date_time_format_types check_result_type(const char *format, uint length)
if (*val == '%' && val+1 != end)
{
val++;
- if ((frac_second_used= (*val == 'f')) ||
- (!time_part_used && strchr(time_part_frms, *val)))
+ if (*val == 'f')
+ frac_second_used= time_part_used= 1;
+ else if (!time_part_used && strchr(time_part_frms, *val))
time_part_used= 1;
else if (!date_part_used && strchr(date_part_frms, *val))
date_part_used= 1;
- if (time_part_used && date_part_used && frac_second_used)
+ if (date_part_used && frac_second_used)
+ {
+ /*
+ frac_second_used implies time_part_used, and thus we already
+ have all types of date-time components and can end our search.
+ */
return DATE_TIME_MICROSECOND;
+ }
}
}
+ /* We don't have all three types of date-time components */
+ if (frac_second_used)
+ return TIME_MICROSECOND;
if (time_part_used)
{
if (date_part_used)
return DATE_TIME;
- if (frac_second_used)
- return TIME_MICROSECOND;
return TIME_ONLY;
}
return DATE_ONLY;
@@ -2670,7 +2687,8 @@ void Item_func_str_to_date::fix_length_and_dec()
if ((const_item= args[1]->const_item()))
{
format= args[1]->val_str(&format_str);
- cached_format_type= check_result_type(format->ptr(), format->length());
+ cached_format_type= get_date_time_result_type(format->ptr(),
+ format->length());
switch (cached_format_type) {
case DATE_ONLY:
cached_timestamp_type= MYSQL_TIMESTAMP_DATE;