Bug #92474 | STR_TO_DATE truncates bad microseconds unexpectedly | ||
---|---|---|---|
Submitted: | 18 Sep 2018 9:54 | Modified: | 19 Sep 2018 5:37 |
Reporter: | Alexander Barkov | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: Data Types | Severity: | S3 (Non-critical) |
Version: | 5.7, 5.7.23, 8.0.12 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[18 Sep 2018 9:54]
Alexander Barkov
[18 Sep 2018 10:23]
MySQL Verification Team
Hello Alexander, Thank you for the report and test case. regards, Umesh
[18 Sep 2018 12:10]
Roy Lyseng
Hi Alexander, a fractional decimal value can never be out of range. In this case there is excess precision that should be rounded or truncated to a microsecond value according to the SQL mode time_truncate_fractional.
[18 Sep 2018 12:17]
Alexander Barkov
The manual says that %f stands for Microseconds (000000..999999). It does not say it stands for the arbitrary length fractional part.
[18 Sep 2018 13:19]
Roy Lyseng
Strictly the manual is correct, as the format specifier indicates a microsecond value in the formatted value. It does not say explicitly what to do if the input value has more than 6 fractional digits, however it does follow the general pattern of truncation and rounding. We can be more explicit about it in the documentation, though.
[19 Sep 2018 5:33]
Alexander Barkov
Roy, SELECT STR_TO_DATE('2017-12-31 23:59:59 and 10 microseconds', '%Y-%m-%d %H:%i:%s and %f microseconds') AS c; +----------------------------+ | c | +----------------------------+ | 2017-12-31 23:59:59.100000 | +----------------------------+ A microsecond value of 10 would generate fractional part .000010 (instead of .100000). So %f is not "microseconds" in STR_TO_DATE(). It's a fractioal part with an arbitrary length. Btw, is there a way to scan microseconds, so "10" in the format string gives ".000010"?
[19 Sep 2018 5:37]
Alexander Barkov
Hi Roy, In case if %f is a fractional part with an arbitrary length (which would be nice to say explicitly in the manual), should not this expression honor sql_mode: STR_TO_DATE('2017-12-31 23:59:59.99999999', '%Y-%m-%d %H:%i:%s.%f') and return '2018-01-01 00:00:00.000000' instead of '2017-12-31 23:59:59.999999' like it does in all other cases of string-to-datetime conversion?
[19 Sep 2018 7:11]
Roy Lyseng
So %f is not "microseconds" in STR_TO_DATE(). It's a fractional part with an arbitrary length. Correct. Btw, is there a way to scan microseconds, so "10" in the format string gives ".000010"? Not that I am aware of. In case if %f is a fractional part with an arbitrary length (which would be nice to say explicitly in the manual), should not this expression honor sql_mode: STR_TO_DATE('2017-12-31 23:59:59.99999999', '%Y-%m-%d %H:%i:%s.%f') and return '2018-01-01 00:00:00.000000' instead of '2017-12-31 23:59:59.999999' like it does in all other cases of string-to-datetime conversion? I agree that the fraction should be rounded or truncated according to current SQL mode. In this case, the fraction should be rounded to 1.000000 seconds and used to increment the seconds value (etc).