Bug #66370 [Opn]: Errors in mysqli_store_result() do not set mysqli error/errno
Edit report at https://bugs.php.net/bug.php?id=66370&edit=1
ID: 66370
Updated by: nikic@php.net
Reported by: bugs dot php dot net at ss dot chernousov dot net
Summary: Errors in mysqli_store_result() do not set mysqli
error/errno
Status: Open
Type: Bug
Package: MySQLi related
Operating System: Gentoo Linux
PHP Version: 5.5.7
Block user comment: N
Private report: N
New Comment:
This issue should be fixed by a combination of:
https://github.com/php/php-src/commit/a66d73db4b2e2fcf03b9ecbbc196440eefeb6641
https://github.com/php/php-src/commit/24537a73c010d5ce56d83cae36c15b9c8d1a1a13
Previous Comments:
------------------------------------------------------------------------
[2017-10-24 14:59:27] bugs dot php dot net at ss dot chernousov dot net
(fixed summary title)
------------------------------------------------------------------------
[2016-08-04 11:31:14] 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.
------------------------------------------------------------------------
[2013-12-31 03:23:52] 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=
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=66370&edit=1
Thread (7 messages)