Commit 5388fbae authored by Magne Mahre's avatar Magne Mahre

Bug #36466: Adding days to day_microsecond changes interpretation of microseco

      
When less than six places are given for microseconds, we zerofill from
the right (leftmost place is always 1/10s). We only did this when all
announced date/time fields were given; now we also format fractional
seconds when more significant fields are left out.


mysql-test/r/func_time.result:
  show that we treat fractions of seconds correctly (zerofill from
  right to six places) even if we left out fields on the left
mysql-test/t/func_time.test:
  show that we treat fractions of seconds correctly (zerofill from
  right to six places) even if we left out fields on the left
sql/item_timefunc.cc:
  format fractions of seconds even if announced
  more significant fields were left out
parent 0dae88ca
...@@ -1301,6 +1301,12 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SECOND; ...@@ -1301,6 +1301,12 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SECOND;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND; SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
select date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond);
date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond)
1000-01-02 03:02:01.050000
select date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond);
date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond)
1000-01-01 00:00:01.020000
End of 5.0 tests End of 5.0 tests
select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND); select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND);
date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND) date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND)
......
...@@ -819,6 +819,16 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SECOND; ...@@ -819,6 +819,16 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SECOND;
--error ER_PARSE_ERROR --error ER_PARSE_ERROR
SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND; SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
#
# Bug #36466:
# Adding days to day_microsecond changes interpretation of microseconds
#
# show that we treat fractions of seconds correctly (zerofill from right to
# six places) even if we left out fields on the left.
select date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond);
select date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond);
--echo End of 5.0 tests --echo End of 5.0 tests
# #
......
...@@ -865,6 +865,8 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, ...@@ -865,6 +865,8 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
{ {
const char *end=str+length; const char *end=str+length;
uint i; uint i;
long msec_length= 0;
while (str != end && !my_isdigit(cs,*str)) while (str != end && !my_isdigit(cs,*str))
str++; str++;
...@@ -874,12 +876,7 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, ...@@ -874,12 +876,7 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
const char *start= str; const char *start= str;
for (value=0; str != end && my_isdigit(cs,*str) ; str++) for (value=0; str != end && my_isdigit(cs,*str) ; str++)
value= value*LL(10) + (longlong) (*str - '0'); value= value*LL(10) + (longlong) (*str - '0');
if (transform_msec && i == count - 1) // microseconds always last msec_length= 6 - (str - start);
{
long msec_length= 6 - (uint) (str - start);
if (msec_length > 0)
value*= (long) log_10_int[msec_length];
}
values[i]= value; values[i]= value;
while (str != end && !my_isdigit(cs,*str)) while (str != end && !my_isdigit(cs,*str))
str++; str++;
...@@ -893,6 +890,10 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, ...@@ -893,6 +890,10 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
break; break;
} }
} }
if (transform_msec && msec_length > 0)
values[count - 1] *= (long) log_10_int[msec_length];
return (str != end); return (str != end);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment