php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #66370 Errors in mysqli_store_result() do not set mysqli error/errno
Submitted: 2013-12-31 03:23 UTC Modified: 2020-10-29 10:01 UTC
Votes:10
Avg. Score:4.4 ± 0.7
Reproduced:8 of 8 (100.0%)
Same Version:1 (12.5%)
Same OS:3 (37.5%)
From: bugs dot php dot net at ss dot chernousov dot net Assigned: nikic (profile)
Status: Closed Package: MySQLi related
PHP Version: 5.5.7 OS: Gentoo Linux
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: bugs dot php dot net at ss dot chernousov dot net
New email:
PHP Version: OS:

 

 [2013-12-31 03:23 UTC] bugs dot php dot net at ss dot chernousov dot net
Description:
------------
(This is related to mysqlnd in general, not only to mysqli).

When connection gets broken while store_result()/query() is transferring data, "Empty row packet body" warning is generated, but errno/error are not set. Any following mysql-network-related function generates 2006/"MySQL server has gone away" and correctly sets errno/error. Expected behaviour: store_result()/query() to set errno/error immediately after an error happened.


More digging details below.

store_result() generates one Warning ("Empty row packet body"), but query() generates two:

Warning: Empty row packet body in 1.php on line 5
Warning: mysqli::query(): (00000/0):  in 1.php on line 5

And neither of them sets errno/error.

I added CONN_SET_STATE(conn, CONN_QUIT_SENT) and SET_CLIENT_ERROR(*conn->error_info, ...) to php_mysqlnd_read_row_ex() in mysqlnd_wireprotocol.c (similarly to PACKET_READ_HEADER_AND_BODY macro), and found another problem: errors from mysqlnd_wireprotocol.c are set to *conn->error_info, but store_result_fetch_data() in mysqlnd_result.c expects errors in row_packet->error_info. It seems that errors generated in mysqlnd_wireprotocol.c are never actually used in mysqlnd_result.c. Furthermore, connection state set in mysqlnd_wireprotocol.c is always overwritten in mysqlnd_result.c with either CONN_NEXT_RESULT_PENDING or CONN_READY.

I ended up with the following patch to at least set correct errno/error on store_result()/query(), so the script can get aware about lost connections timely. However this patch is definitely not a complete solution, it doesn't fix neither double warning nor connection state (and it looks like it's not the only place where warnings are raised but errno/error are not set).

Test script:
---------------
<?php

// connect to a remote server, slow connection is preferrable (so you'll have more time to kill the connection)
// while script is performing $mysqli->query(), kill the connection using mysql "kill" command (killall -9 mysqld would work too :))

$mysqli = new mysqli('remote-host', 'user', 'password');
$mysqli->query('set global max_allowed_packet=' . 60e6); // 60M
// echo "Do this in mysql shell: kill {$mysqli->threadid}\n";
$mysqli->query('select repeat("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", 500000)'); // ~50M packet
echo "errno={$mysqli->errno}, error={$mysqli->error}\n";

Expected result:
----------------
Warning: mysqli::query(): (HY000/2006): MySQL server has gone away in 1.php on line 9
errno=2006, error=MySQL server has gone away

Actual result:
--------------
Warning: Empty row packet body in 1.php on line 9
Warning: mysqli::query(): (00000/0):  in 1.php on line 9
errno=0, error=

Patches

mysqlnd-errno-error-fix.patch (last revision 2013-12-31 03:24 UTC by bugs dot php dot net at ss dot chernousov dot net)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-02-17 11:47 UTC] andrey@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: andrey
 [2016-08-04 11:31 UTC] sergey at dotsgo dot com
Just stuck with the same issue while dealing with a mysql server on another continent and transferring large amounts of data on an unreliable connection.
 [2017-10-24 07:21 UTC] kalle@php.net
-Status: Assigned +Status: Open -Assigned To: andrey +Assigned To:
 [2017-10-24 14:59 UTC] bugs dot php dot net at ss dot chernousov dot net
-Summary: Errors in mysqli_store_result() don't not set mysqli error/errno +Summary: Errors in mysqli_store_result() do not set mysqli error/errno
 [2017-10-24 14:59 UTC] bugs dot php dot net at ss dot chernousov dot net
(fixed summary title)
 [2020-10-29 10:01 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 19 16:01:28 2024 UTC