Bug #95212 | MySQL timestamp arithmetics should not produce invalid values | ||
---|---|---|---|
Submitted: | 1 May 2019 13:12 | Modified: | 4 May 2019 20:53 |
Reporter: | Power Gamer | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: DML | Severity: | S4 (Feature request) |
Version: | 8.0.15 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[1 May 2019 13:12]
Power Gamer
[2 May 2019 13:53]
MySQL Verification Team
Hi Mr. Gamer, I have run your test case and I have got the following error message: ERROR 1292 (22007) at line 7: Incorrect datetime value: '2019-03-31 03:10:00' for column 'a' at row 1 That is how MySQL functions now. It is so by an intentional design. I guess that you would like a new feature that you would change this behaviour. In that case, please let us know exactly what would be the desired behaviour and I will verify your feature request.
[2 May 2019 15:24]
Power Gamer
The desired behavior (and I think it would be a better behavior than the current one) would be as follows. Regardless of what time zone is set through "SET time_zone=" the expressions involving +- INTERVAL should result in VALID (for selected time zone) values as long as the original values the expression operated on were valid (for selected time zone) and the resulting value is within the resulting data type range. The following examples will illustrate the rules: 1. SELECT TIMESTAMP '2019-01-33 00:00:00' + INTERVAL 1 DAY; Throw an error because the operand of expression is invalid (day 33) under current time zone (any time zone in this case) - current behavior. 2. SET time_zone="Europe/Kiev"; SELECT TIMESTAMP '2019-03-31 02:10:00' + INTERVAL 1 HOUR; The operand of expression ('2019-03-31 02:10:00') is valid under the currently set time zone. So, the result of the expression should also be valid under the current time zone - '2019-03-31 04:10:00'. Current behavior - INVALID date-time '2019-03-31 03:10:00' under the current time zone. 3. SET time_zone="Europe/Kiev"; SELECT TIMESTAMP '2019-01-01 00:00:00' + INTERVAL 9999 YEAR; The operand of expression ('2019-01-01 00:00:00') is valid under the currently set time zone. But the result of the expression would fall outside the supported date/time range (year is too big). Current behavior - result of the expression is NULL. Keep the current behavior or change to an error (changing to error would prevent inserting erroneous result into a table field accepting NULLs). 3. CREATE TABLE tbl3 (a DATETIME NOT NULL); SET time_zone="Europe/Kiev"; INSERT INTO tbl3(a) VALUES('2019-03-31 03:10:00'); SELECT a + INTERVAL 1 DAY FROM tbl3; The operand of expression (value of tbl3.a) is INVALID under currently selected timezone (time '2019-03-31 03:10:00' does not exist in Europe/Kiev), so the expression should result in an ERROR. Current behavior - '2019-04-01 03:10:00' (invalid timestamp + offset results in what kind of result ??). I think the current behavior of MySQL +- INTERVAL expressions can in short be surmised as: "Regardless of SET time_zone value treat all date-times as if UTC and perform additions and subtractions" (BTW, while being "intentional design" I have not seen it being mentioned anywhere in the documentation). It should be changed to "Honor the value of SET time_zone and treat all date-time values in that time zone when performing additions and subtractions". That new behavior can be implemented as "convert all date-times to UTC from currently set timezone, perform additions and subtractions and convert result back to currently set time zone". Here the report of another user who basically wanted the same feature in MySQL: https://bugs.mysql.com/bug.php?id=60550.
[3 May 2019 12:36]
MySQL Verification Team
Hello Mr. Power Gamer, Thank you for your clear definition in the change of behaviour. I agree with you that your suggested new behaviour is more appropriate then the current one. Verified as a feature request, since this represents a change of behaviour in the GA version.
[4 May 2019 20:53]
Power Gamer
Just wanted to note that in my previous comment my last statement is actually incorrect: ** That new behavior can be implemented as "convert all date-times to UTC from currently set timezone, perform additions and subtractions and convert result back to currently set time zone". ** The date-time arithmetic cannot be implemented that way because it will produce incorrect results if performed over the physical moment of time when DST change occurred. For example (arithmetic over a day when clock was moved forward): Europe/Kiev 2019-03-31 00:00:00 + 1 DAY should be Europe/Kiev 2019-04-01 00:00:00. If performed by first converting to UTC, adding a day and then converting back to Europe/Kiev the result would be different: Europe/Kiev 2019-03-31 00:00:00 -> UTC 2019-03-30 22:00:00 UTC 2019-03-30 22:00:00 +1 DAY = UTC 2019-03-31 22:00:00 UTC 2019-03-31 22:00:00 -> Europe/Kiev 2019-04-01 01:00:00 So to produce correct results the arithmetic will have to be implemented directly in the currently set time zone taking into account DST clock movements.
[6 May 2019 13:05]
MySQL Verification Team
Thanks also for the last comment, especially last paragraph.