php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #66124 mysqli under mysqlnd loses precision when bind_param with 'i'
Submitted: 2013-11-20 09:05 UTC Modified: 2013-11-21 20:14 UTC
From: sskaje at gmail dot com Assigned: andrey (profile)
Status: Closed Package: MySQLi related
PHP Version: Irrelevant OS: CentOS/Ubuntu 64bit
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: sskaje at gmail dot com
New email:
PHP Version: OS:

 

 [2013-11-20 09:05 UTC] sskaje at gmail dot com
Description:
------------
in ext/mysqlnd/mysqlnd_ps_codec.c:
line 572->593, 632->648
bind_param() with 'i' is processed like
 1 copy to tmp_data
 2 call convert_to_double_ex

but the convert_to_double_ex makes the input 64-bit-numeric string losing it's precision.


This works fine with the libmysqlclient based build.



I tried changing the two convert_to_double_ex to convert_to_long_ex, works for this issue but not sure if it would take any side effect.



Test script:
---------------
<?php
/*
CREATE TABLE `ndtest` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

*/

$host = '172.16.3.53';
$user = 'sskaje';
$pass = 'sskaje';
$name = 'test';
$port = '3306';

$id = '1311200011005001566';

$mysqli = new mysqli($host, $user, $pass, $name, $port);

#delete data
$query = "DELETE FROM `ndtest`";
$mysqli->query($query);


$query = "INSERT INTO `ndtest` SET `id`=?";

$stmt = $mysqli->prepare($query);
$stmt->bind_param('i', $id);

echo "declare i\n";

$ret = $stmt->execute();

if($ret){
    echo "insert id:{$id}=>{$stmt->insert_id}\n";
}else{
    echo "insert failed.\n";
}


$query = "SELECT * FROM `ndtest`";
$result = $mysqli->query($query);

if($result){
    while ($row = $result->fetch_assoc()) {
        echo "fetch  id:{$row['id']}\n";
    }
}


echo "\n\n";

$query = "DELETE FROM `ndtest`";
$mysqli->query($query);


$query = "INSERT INTO `ndtest` SET `id`=?";

$stmt = $mysqli->prepare($query);
$stmt->bind_param('s', $id);

echo "declare s\n";

$ret = $stmt->execute();

if($ret){
    echo "insert id:{$id}\n";
}else{
    echo "insert failed.\n";
}



$query = "SELECT * FROM `ndtest`";
$result = $mysqli->query($query);

if($result){
    while ($row = $result->fetch_assoc()) {
        echo "fetch  id:{$row['id']}\n";
    }
}

Expected result:
----------------
[root@zhouyu php-5.5.5]# /usr/local/php/bin/php /root/ndtest.php
declare i
insert id:1311200011005001566=>1311200011005001566
fetch  id:1311200011005001566


declare s
insert id:1311200011005001566
fetch  id:1311200011005001566

Actual result:
--------------
[root@QA_Server81 ~]# /usr/local/php/bin/php /root/ndtest.php
declare i
insert id:1311200011005001566=>1311200011005001472
fetch  id:1311200011005001472


declare s
insert id:1311200011005001566
fetch  id:1311200011005001566

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-11-21 20:14 UTC] andrey@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: andrey
 [2013-11-21 20:14 UTC] andrey@php.net
Fixed in the next 5.4 version. SHould be 5.4.23
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 14:01:29 2024 UTC