Bug #6147 | Traditional: Assigning a string to a numeric column has unexpected results | ||
---|---|---|---|
Submitted: | 18 Oct 2004 20:03 | Modified: | 4 Oct 2006 1:30 |
Reporter: | Trudy Pelzer | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: General | Severity: | S3 (Non-critical) |
Version: | 5.0.2-alpha-debug | OS: | Linux (SuSE 9.1) |
Assigned to: | Alexander Barkov | CPU Architecture: | Any |
[18 Oct 2004 20:03]
Trudy Pelzer
[19 Oct 2004 0:41]
MySQL Verification Team
Verified on latest Bk source.
[6 Apr 2005 23:02]
Trudy Pelzer
More information on this issue. The problem appears to be connected to how MySQL does rounding on INSERT. The rounding should be based on the data type of the target, and is being done correctly unless (a) the source is a string that is being converted to a number and (b) the target is an integer: mysql> create table t (i int, f float, d0 decimal, d1 decimal(3,1)); Query OK, 0 rows affected (0.01 sec) mysql> insert into t values (2.44,2.44,2.44,2.44); Query OK, 1 row affected, 2 warnings (0.01 sec) mysql> insert into t values (2.55,2.55,2.55,2.55); Query OK, 1 row affected, 2 warnings (0.00 sec) mysql> insert into t values (2.66,2.66,2.66,2.66); Query OK, 1 row affected, 2 warnings (0.00 sec) mysql> select * from t; +------+------+------+------+ | i | f | d0 | d1 | +------+------+------+------+ | 2 | 2.44 | 2 | 2.4 | | 3 | 2.55 | 3 | 2.6 | | 3 | 2.66 | 3 | 2.7 | +------+------+------+------+ 3 rows in set (0.00 sec) --As expected; exact numeric source gets rounded based on data type of target (round half-up for i, d0, d1; no rounding for float) mysql> insert into t values ('2.44','2.44','2.44','2.44'); Query OK, 1 row affected, 3 warnings (0.00 sec) mysql> insert into t values ('2.55','2.55','2.55','2.55'); Query OK, 1 row affected, 3 warnings (0.00 sec) mysql> insert into t values ('2.66','2.66','2.66','2.66'); Query OK, 1 row affected, 3 warnings (0.00 sec) mysql> select * from t; +------+------+------+------+ | i | f | d0 | d1 | +------+------+------+------+ | 2 | 2.44 | 2 | 2.4 | | 3 | 2.55 | 3 | 2.6 | | 3 | 2.66 | 3 | 2.7 | | 2 | 2.44 | 2 | 2.4 | | 2 | 2.55 | 3 | 2.6 | | 2 | 2.66 | 3 | 2.7 | +------+------+------+------+ 6 rows in set (0.00 sec) -- Not as expected; approximate numeric source should get rounded based on data type of target. Float decimal, and decimal(3,1) columns are treated correctly; integer column is treated incorrectly, it should result in 2,3,3. Conclusion: bug in INSERT for integers when source is approximate numeric *if* source is approximate numeric because it's a string mysql> insert into t values (2.44e0,2.44e0,2.44e0,2.44e0); Query OK, 1 row affected, 2 warnings (0.00 sec) mysql> insert into t values (2.55e0,2.55e0,2.55e0,2.55e0); Query OK, 1 row affected, 2 warnings (0.00 sec) mysql> insert into t values (2.66e0,2.66e0,2.66e0,2.66e0); Query OK, 1 row affected, 2 warnings (0.00 sec) mysql> select * from t; +------+------+------+------+ | i | f | d0 | d1 | +------+------+------+------+ | 2 | 2.44 | 2 | 2.4 | | 3 | 2.55 | 3 | 2.6 | | 3 | 2.66 | 3 | 2.7 | | 2 | 2.44 | 2 | 2.4 | | 2 | 2.55 | 3 | 2.6 | | 2 | 2.66 | 3 | 2.7 | | 2 | 2.44 | 2 | 2.4 | | 3 | 2.55 | 3 | 2.6 | | 3 | 2.66 | 3 | 2.7 | +------+------+------+------+ 9 rows in set (0.00 sec) -- As expected; approximate numeric source being rounded based on data type of target. Note that when the approximate numeric source is a numeric literal rather than a string, the rounding into an integer target is correct. mysql> insert into t values ('2.44e0','2.44e0','2.44e0','2.44e0'); Query OK, 1 row affected, 3 warnings (0.00 sec) mysql> insert into t values ('2.55e0','2.55e0','2.55e0','2.55e0'); Query OK, 1 row affected, 3 warnings (0.00 sec) mysql> insert into t values ('2.66e0','2.66e0','2.66e0','2.66e0'); Query OK, 1 row affected, 3 warnings (0.00 sec) mysql> select * from t; +------+------+------+------+ | i | f | d0 | d1 | +------+------+------+------+ | 2 | 2.44 | 2 | 2.4 | | 3 | 2.55 | 3 | 2.6 | | 3 | 2.66 | 3 | 2.7 | | 2 | 2.44 | 2 | 2.4 | | 2 | 2.55 | 3 | 2.6 | | 2 | 2.66 | 3 | 2.7 | | 2 | 2.44 | 2 | 2.4 | | 3 | 2.55 | 3 | 2.6 | | 3 | 2.66 | 3 | 2.7 | | 2 | 2.44 | 2 | 2.4 | | 2 | 2.55 | 3 | 2.6 | | 2 | 2.66 | 3 | 2.7 | +------+------+------+------+ 12 rows in set (0.00 sec) -- Not as expected; again, approximate numeric source into integer target should be rounded based on data type of target (correct result is 2,3,3), all other targets show correct result. Note again the fact that it's because the source is a string that the integer problem occurs.
[10 Apr 2005 17:57]
Paul DuBois
Additional information regarding incorrect assignment of numeric values specified as strings when inserted into integer columns. I believe the results can be explained as follows: If MySQL is inserting into an INT column, and the source is a string, MySQL tries to convert it to a number but stops at the decimal point. (Probably this is more general, like "stops at first non-digit" but it does appear to stop at the decimal point.) Test script: drop table if exists t; create table t (i int, d decimal); insert into t values(2.55,2.55); insert into t values(2.55e0,2.55e0); insert into t values(2.55e1,2.55e1); insert into t values('2.55','2.55'); insert into t values('2.55e0','2.55e0'); insert into t values('2.55e1','2.55e1'); insert into t values('2.55e2','2.55e2'); select * from t; The last few rows insert strings, so they require string-to-number conversion. If that conversion is always really to double, the results for both columns should, I believe, be the same. But here's the result: +------+------+ | i | d | +------+------+ | 3 | 3 | | 3 | 3 | | 26 | 26 | | 2 | 3 | | 2 | 3 | | 2 | 26 | | 2 | 255 | +------+------+ Note the INT column results. It appears that when the target column is an integer, the string-to-number conversion is not "to double" but "until the first non-digit" or something. The conversion appears to stop at the decimal point because it entirely ignores the exponent. The problem is demonstrated most clearly by the values expressed as strings are numbers in scientific notation. But the conversion problem is more general in that, for values with any fractional part, the fractional part will be truncated, not rounded.
[29 Jan 2006 22:30]
Alexej Kubarev
I can verify this in 5.0.18 on several different platforms Several scripts stoped working after migration from 4.1 to 5.0. It seems to me that this bug will actually stop migration of many hosts to the new version. For instance a very popular Invision Power Board script(latest version) will not even install properly on 5.0.18 because of this problem. Assigning an empty string to an int column is the problem: example query is: INSERT INTO column (id, something) VALUES ('','some data') where id is an int. Beats me why does this happend but i know for sure that the problem is fixed as soon as i change type of the "id" column to something like varchar
[18 Mar 2006 11:33]
Jim Winstead
discussed briefly with monty, and he has suggested making the string-to-integer conversion routines (like strntoll10, or something like that) handle doing the rounding, rather than any sort of string->decimal->integer conversion.
[5 Jun 2006 12:12]
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/7268
[20 Jul 2006 8:42]
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/9366
[2 Oct 2006 9:19]
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/12925 ChangeSet@1.2286, 2006-10-02 14:17:41+05:00, bar@mysql.com +1 -0 bug#6147 - fixing ndb test results (forgot to include into the main commit)
[2 Oct 2006 9:20]
Alexander Barkov
Pushed into 5.0-rpl, currently marked as 5.0.26
[3 Oct 2006 20:03]
Chad MILLER
Available in 5.0.26.
[3 Oct 2006 20:11]
Chad MILLER
Available in 5.1.12-beta.
[4 Oct 2006 1:30]
Paul DuBois
Noted in 5.0.26, 5.1.12 changelogs. With TRADITIONAL SQL mode, assignment of out-of-bound values and rounding of assigned values was done correctly, but assignment of the same numbers represented as strings sometimes was handled differently.