Bug #52155 | Match of varchar column to a numeric zero returns all rows | ||
---|---|---|---|
Submitted: | 17 Mar 2010 18:51 | Modified: | 1 Sep 2011 18:24 |
Reporter: | Charles Ayres | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: Parser | Severity: | S2 (Serious) |
Version: | 5.0.20a | OS: | Linux |
Assigned to: | CPU Architecture: | Any | |
Tags: | "type conversion" |
[17 Mar 2010 18:51]
Charles Ayres
[18 Mar 2010 4:28]
Valeriy Kravchuk
Sorry, but this is known and documented feature of MySQL. When you compare numbers to strings, they are compared as float numbers. Any string that does NOT start with a digit is implicitly converted to number 0. Hence the results you get. Please, always compare numbers to numbers and strings to strings if you want to prevent undesired results. Read http://dev.mysql.com/doc/refman/5.0/en/type-conversion.html for the details.
[18 Mar 2010 16:00]
Charles Ayres
Many thanks for the resolution. You're right, it's documented, although it still seems to me a rather non-intuitive and even dangerous way of handling it.
[1 Sep 2011 17:37]
Tim Furry
It may not be a bug, but Charle's assessment as a dangerous way to handle it is spot on. I'm pretty sure other RDBMS attempt to convert the 0 to a string '0' and then search the table for a match, rather than trying to convert the table strings to a float. I was bit with this when an external system submitted a 0 instead of a string and the lookup succeeded when it should have failed.
[1 Sep 2011 18:24]
Charles Ayres
Thanks Tim - seems to me there are 3 preferable ways this could be handled: a) as you suggest, convert the comparison expression to the type of the column (if possible - else return an error); b) Convert the column values to the type of the comparison expression, but return an error and rollback the transaction at the first unsuccessful conversion attempt, as does Oracle: SQL> select empno, ename from emp where ename = 0; ERROR at line 1: ORA-01722: invalid number c) Convert the column values to the type of the comparison expression as it does now, but treat unsuccessful conversions as nulls rather than zeros. That way you shouldn't get a match where you really don't want one. Thanks, Charles
[1 Sep 2011 18:58]
Tim Furry
I'd vote for 'a' as the most intuitive (my expectation), with any of them being far superior to the current MySQL implementation. It seems like 'a' would be faster as well, with only a single conversion required. I was rather incredulous when my test returned all the rows of the table, once I figured out what was happening...seems like a double conversion (both values to a third type) is asking for trouble. That being said, I just confirmed that MSSQL 2008R2 tries to convert the column value to the literal (as in 'b', like your Oracle example): select * from db.dbo.testtable where value = 0; Conversion failed when converting the nvarchar value 'red' to data type int. The more I think about that, the less intuitive I find it. Tim