Bug #18712 | Truncation problem | ||
---|---|---|---|
Submitted: | 1 Apr 2006 22:29 | Modified: | 8 May 2006 18:54 |
Reporter: | Guillaume Girou | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Documentation | Severity: | S3 (Non-critical) |
Version: | 5.0.21-BK, 5.0.19 | OS: | Linux (Linux / Windows) |
Assigned to: | Paul DuBois | CPU Architecture: | Any |
[1 Apr 2006 22:29]
Guillaume Girou
[2 Apr 2006 3:14]
Peter Laursen
Same with MySQL 5.1.7! Also those: UPDATE t SET i = i - 11; UPDATE t SET i = i - 1111; result in '255'.
[2 Apr 2006 5:49]
Peter Laursen
And I can add: If i is an 'int' it returns 4294967295 -- an int is an int(10) by default If i is a 'bigint' it returns 18446744073709551615 -- a bigint is an int(20) by default
[2 Apr 2006 9:20]
Valeriy Kravchuk
Thank you for a problem report. Verified just as described with 5.0.21-BK on Linux: mysql> select version(); +-----------+ | version() | +-----------+ | 5.0.21 | +-----------+ 1 row in set (0.00 sec) mysql> CREATE TABLE t (i TINYINT UNSIGNED NOT NULL); Query OK, 0 rows affected (0.01 sec) mysql> INSERT t SET i = 0; Query OK, 1 row affected (0.00 sec) mysql> UPDATE t SET i = -1; Query OK, 0 rows affected, 1 warning (0.00 sec) Rows matched: 1 Changed: 0 Warnings: 1 mysql> show warnings; +---------+------+-----------------------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------------------+ | Warning | 1264 | Out of range value adjusted for column 'i' at row 1 | +---------+------+-----------------------------------------------------+ 1 row in set (0.00 sec) mysql> select * from t; +---+ | i | +---+ | 0 | +---+ 1 row in set (0.00 sec) mysql> UPDATE t SET i = i - 1; Query OK, 1 row affected, 1 warning (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 1 mysql> show warnings; +---------+------+-----------------------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------------------+ | Warning | 1264 | Out of range value adjusted for column 'i' at row 1 | +---------+------+-----------------------------------------------------+ 1 row in set (0.00 sec) mysql> select * from t; +-----+ | i | +-----+ | 255 | +-----+ 1 row in set (0.00 sec) mysql> show variables like 'sql%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | sql_mode | | | sql_notes | ON | | sql_warnings | ON | +---------------+-------+ 3 rows in set (0.00 sec) This inconsistent behaviour is a bug, because, according to the manual (http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html): "In non-strict mode, when an out-of-range value is assigned to an integer column, MySQL stores the value representing the corresponding endpoint of the column data type range. If you store 256 into a TINYINT or TINYINT UNSIGNED column, MySQL stores 127 or 255, respectively." SET i = -1 works as described above, while SET i = i - 1 - does not!
[4 May 2006 12:14]
Jani Tolonen
The problem here is that in this query: UPDATE t SET i = i - 1 the value i - 1 is evaluated first. Since field 'i' is unsigned, the value goes around already here. So it does not become -1, it becomes the other end of the unsigned value, e.g: select i-1 from t would result to 18446744073709551615. (or similar, upper end depending on the machine architecture) . For someone, this could be the desired behavior, so it cannot be fixed. Instead if one wants to have signed results instead of unsigned when one of the components has unsigned flag set, you can do this: UPDATE t SET i = CAST(i - 1 AS SIGNED) and it will result to 0.
[4 May 2006 13:36]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/5947
[5 May 2006 15:01]
Paul DuBois
The behavior demonstrated in the report should be described more clearly in the manual. I'm changing this to a documentation bug and assigning it to myself.
[8 May 2006 18:54]
Paul DuBois
Thank you for your bug report. This issue has been addressed in the documentation. The updated documentation will appear on our website shortly, and will be included in the next release of the relevant product(s). Additional info: The change in unsigned integer subtraction now is described in the "SQL changes" section of this page: http://dev.mysql.com/doc/refman/5.0/en/upgrading-from-4-1.html See also Bug#15472.