ID: 35103 User updated by: php at pjberkel dot com Reported By: php at pjberkel dot com -Status: Feedback +Status: Open Bug Type: MySQLi related Operating System: * PHP Version: 5CVS-2005-11-04 (cvs) Assigned To: andrey New Comment:
I compiled the latest CVS snapshot from the 5.1 branch (php5-200511100130) and can confirm that the problem has been fixed for 32bit unsigned INT values. However, I also did some further testing using the unsigned BIGINT data type (which contain 64bit integer values) and discovered the same problem exists for unsigned values larger than the maximum signed 64bit value: (9223372036854775807 < int <= 18446744073709551615) (BTW I'm using http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html as a reference page for MySQL numerical types.) Changing the following two lines in the original reproduce code fragment: $mysqli->query("CREATE TABLE temp (id BIGINT UNSIGNED NOT NULL)"); $mysqli->query("INSERT INTO temp (id) VALUES (9223372036854775807),(9223372036854775808),(18446744073709551614),(18446744073709551615)"); Expected result: ---------------- string(19) "9223372036854775807" string(19) "9223372036854775808" string(20) "18446744073709551614" string(20) "18446744073709551615" Actual result: -------------- string(19) "9223372036854775807" string(20) "-9223372036854775808" int(-2) int(-1) I don't want to push the envelope too much on this as I guess it would be extremely rare for anyone to encounter this bug, but if there is a quick, easy solution then it's probably a good idea to fix the unsigned BIGINT problem too. Any plans to backport this to the 5.0.x branch? Thanks Previous Comments: ------------------------------------------------------------------------ [2005-11-09 14:44:17] [EMAIL PROTECTED] Hi, this has been addressed in the 5.1 branch. So far HEAD (6.0) is not patched, neither 5.0. Fixed is that a value from PS if the platform is 32bit and the type is int(11) unsigned and if the value is > MAX_INT a string will be returned. If the value <= MAX_INT an int will be returned. I know it's not nice to have different types but these are the limitations of PHP. In year or 2 most servers will run on 64bit :) Regarding the types returned. mysqli_query() always returns strings which is not that quite efficient in terms of memory consumption but the underlying libmysql functions return strings. It's matter of choice whether this can be optimized (by using more CPU cycles to reduce memory consumption). ------------------------------------------------------------------------ [2005-11-07 08:34:38] php at pjberkel dot com Thanks for the suggested workaround, while this does patch the problem it will be preferable to have a permanent fix as updating my entire codebase to deal with this problem will be quite time-consuming. Note that mysqli->query() / mysqli->fetch_row() does not appear to suffer from this bug, changing the prepared statement in the example to the following code: $result = $mysqli->query("SELECT id FROM temp"); while ($row = $result->fetch_row()) { var_dump($row[0]); } $result->close(); Shows that the values are correctly returned as variable type string (show by the results below): string(10) "2147483647" string(10) "2147483648" string(10) "2147483649" string(10) "3800001532" string(10) "3900002281" string(10) "4294967295" For the sake of consistency, it would be a good idea for both mysqli->query() and mysqli->prepare() to return the results using the same variable types. ------------------------------------------------------------------------ [2005-11-05 23:05:41] [EMAIL PROTECTED] How about using float type if the returned value is > MAX_INT? ------------------------------------------------------------------------ [2005-11-04 15:53:27] [EMAIL PROTECTED] if your code is aware that the variable is unsigned you can get the unsigned value by using sprintf() with %u as format specificator [EMAIL PROTECTED]:~/test> php -r '$a=-2; printf("%d %u\n", $a, $a);' -2 4294967294 However I think it is good idea to make that implicit so mysqli to return a string (on 32bit) and normal int (on 64bit). ------------------------------------------------------------------------ [2005-11-04 12:46:29] php at pjberkel dot com Compiling the current php5 STABLE CVS snapshot version under RHEL 4 yields the same incorrect results as before: using "var_dump" instead of "print" in the original example gives the results: int(2147483647) int(-2147483648) int(-2147483647) int(-494965764) int(-394965015) int(-1) ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/35103 -- Edit this bug report at http://bugs.php.net/?id=35103&edit=1