Bug #15472 | Decrementing UNSIGNED column produces wrong result | ||
---|---|---|---|
Submitted: | 5 Dec 2005 1:18 | Modified: | 8 May 2006 18:54 |
Reporter: | Paul DuBois | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Documentation | Severity: | S3 (Non-critical) |
Version: | 5.0, 5.1 | OS: | Linux (Linux, Windows) |
Assigned to: | Paul DuBois | CPU Architecture: | Any |
[5 Dec 2005 1:18]
Paul DuBois
[5 Dec 2005 9:18]
Valeriy Kravchuk
Thank you for a bug report. Verified just as described on 5.0.17-BK (ChangeSet@1.1973, 2005-12-03 20:52:34+01:00): mysql> drop table if exists t; Query OK, 0 rows affected (0,01 sec) mysql> create table t (i int unsigned); Query OK, 0 rows affected (0,00 sec) mysql> insert into t set i = 0; Query OK, 1 row affected (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 | +------------+ | 4294967295 | +------------+ 1 row in set (0,00 sec) In strict mode (default on Windows) the same 1264 is produced, but as an error.
[11 Apr 2006 15:01]
Georgi Kodinov
This behaviour is because of an addition of a flag in the function Field_long::store(). This flag is controled by the NO_UNSIGNED_SUBTRACTION sql_mode flag. When off (by default) the statement behaves as described in that bug for 5.0 (sets the field to ~0). When you turn it on the 4.1 behaviour is back. Do we want that flag on by default or do we want this particular place to disregard the flag ?
[11 Apr 2006 20:01]
Trudy Pelzer
This has been determined to be correct behaviour; the MySQL Reference Manual states that the result of an arithmetic operation where one operand is unsigned is also unsigned. In earlier releases, MySQL was not able to consistently track whether a value was unsigned, everywhere in the server. This was corrected, causing the discrepancy shown.
[5 May 2006 15:04]
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#18712.
[24 Jan 2012 10:42]
iago tomas
Just for anyone that might be hitting similar problem, in our case we werent' able to turn on the NO_UNSIGNED_SUBTRACTION flag easily . Instead we fond that casting the unsigned field in the update to a signed field did the trick. As an example: DROP TABLE IF EXISTS `new_table`; CREATE TABLE `new_table` ( `prova` int(10) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; insert into new_table (prova) VALUES(0); update new_table set prova=IF((CAST(prova AS SIGNED)-1)>0,(CAST(prova AS SIGNED)-1),0); /* Works*/ select * from new_table; update new_table set prova=IF((prova-1)>0,(prova-1),0); /* doesnt' work*/ select * from new_table;