Bug #81494 [Ver]: Stopped unbuffered query does not throw error
Edit report at https://bugs.php.net/bug.php?id=81494&edit=1
ID: 81494
Updated by: nikic@php.net
Reported by: madri2 at gmail dot com
Summary: Stopped unbuffered query does not throw error
Status: Verified
Type: Bug
Package: MySQLi related
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
After looking a bit closer, I believe the key problem here is that this is calling a method on
mysqli_result, while the error is reported on the connection (or stmt) and the result doesn't
have access to the connection.
So either we need to store the connection object in the mysqli result object, or we need to recover
it from the underlying driver -- mysqlnd has a conn field, which stores a reference to the
connection data, so we could use the low level API to access the error information.
Previous Comments:
------------------------------------------------------------------------
[2021-10-04 12:35:28] nikic@php.net
Oops, some autocomplete messed things up. I only wanted to change the status to Verified...
------------------------------------------------------------------------
[2021-10-04 12:17:36] madri2 at gmail dot com
<?php
error_reporting(E_ALL);
set_time_limit(0);
ini_set('memory_limit','2000M');
ini_set('display_errors', true);
$dbo = mysqli_connect('localhost', 'xxx', 'yyy', '');
$dbo2 = mysqli_connect('localhost', 'xxx', 'yyy', '');
mysqli_report(MYSQLI_REPORT_ALL & ~MYSQLI_REPORT_INDEX);
$req = $dbo->query("SELECT * FROM mustBeATableBigEnough", MYSQLI_USE_RESULT);
$numFound = 0;
while ($found = $req->fetch_assoc()) {
$numFound++;
$req2 = $dbo2->query("SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID =
'".$dbo->thread_id."'");
if ($found2 = $req2->fetch_assoc()) {
print_r($found2);
$dbo2->query("KILL ".$found2['ID']);
}
$req2->free();
}
$req->free();
echo 'numFound : '.$numFound."\n";
it outputs :
Array
(
[ID] => 2348965
[USER] => yyyyy
[HOST] => localhost
[DB] => zzzzzz
[COMMAND] => Query
[TIME] => 0
[STATE] => Sending data
[INFO] => SELECT * FROM xxxx
[TIME_MS] => 1.708
[STAGE] => 0
[MAX_STAGE] => 0
[PROGRESS] => 0.000
[MEMORY_USED] => 212672
[MAX_MEMORY_USED] => 212672
[EXAMINED_ROWS] => 0
[QUERY_ID] => 554751313
[INFO_BINARY] => SELECT * FROM xxxx
[TID] => 3625133
)
Warning: mysqli_result::fetch_assoc(): Error while reading a row in ....testBug.php on line 54
numFound : 52
the table contains millions of entries
------------------------------------------------------------------------
[2021-10-01 14:24:34] nikic@php.net
Please provide a full reproducer.
------------------------------------------------------------------------
[2021-10-01 14:22:06] madri2 at gmail dot com
Description:
------------
Do an unbuffered mysqli query and do a while to read all results,
kill the mysql request in mysql, then php will only trigger a warning when doing fetch_assoc
Warning: mysqli_result::fetch_assoc(): Error while reading a row
while ($found = $req->fetch_assoc()) {
}
will only stop the loop when the mysql query is killed, instead of throwing an error
I've tried to set mysqli_report(MYSQLI_REPORT_ALL & ~MYSQLI_REPORT_INDEX);
but this doesn't change anything
Expected result:
----------------
An exception thrown
Actual result:
--------------
Warning: mysqli_result::fetch_assoc(): Error while reading a row
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=81494&edit=1
Thread (9 messages)