Bug #81567 [Opn->Ver]: Connection error status not immediately set for killed async query
Edit report at https://bugs.php.net/bug.php?id=81567&edit=1
ID: 81567
Updated by: nikic@php.net
Reported by: steven at movista dot com
Summary: Connection error status not immediately set for
killed async query
-Status: Open
+Status: Verified
Type: Bug
Package: MySQLi related
Operating System: Ubuntu 20.04.3 LTS
PHP Version: 7.4.25
Block user comment: N
Private report: N
New Comment:
Can reproduce this. I had to adjust the test case to use
$c->query('SET max_execution_time=1');
$c->query('SELECT SLEEP(10) UNION ALL SELECT 1', MYSQLI_ASYNC|MYSQLI_USE_RESULT);
because my MySQL version doesn't support max_statement_time, and seems to immediately return
from SLEEP without the UNION ALL.
Previous Comments:
------------------------------------------------------------------------
[2021-10-29 21:47:20] steven at movista dot com
Description:
------------
I'm running the Ubuntu php 7.4.25 distribution from http://ppa.launchpad.net/ondrej/php/ubuntu:
PHP 7.4.25 (cli) (built: Oct 22 2021 12:34:33) ( NTS )
I'm working with MariaDB (10.4.21-MariaDB-1:10.4.21+maria~focal-log) and Apache2
(2.4.41-4ubuntu3.8) with mod_php (7.4.25-1+ubuntu20.04.1+deb.sury.org+1). This also occurs via CLI
so I don't think Apache has anything to do with it.
I don't have any special configs for mysqlnd.
I'm running an async query that could be killed via MariaDB's max_statement_time and
MYSQLI_USE_RESULT.
When a query gets killed, then I call mysqli::poll(), then reap_async_query(), the connection handle
error status is not updated; errno is 0 and error is "".
For other queries with bad syntax or that reference non-existent columns/tables, the connection
handle error status is updated when reap_async_query() is called, but not when the query gets
killed.
The connection handle's error status is not updated until after I attempt a fetch on the
mysqli_stmt object I get back from reap_async_query(). I would expect that the connection handle
error status for a killed query would be set after reap_async_query(), but since I don't get it
until after attempting a fetch, this complicates my error handling.
For what it's worth, if I use MYSQLI_STORE_RESULT instead of MYSQLI_USE_RESULT, the connection
handle error status is set after reap_async_query(), but I prefer to use MYSQLI_USE_RESULT so I can
stream a result set directly to redis, a file, or whatever else so I don't have to keep the
entire result set in memory.
Test script:
---------------
<?php
$c = new mysqli(HOST,USER,PASSWORD,DATABASE);
$c->query('SET STATEMENT max_statement_time=1 FOR SELECT
SLEEP(10);',MYSQLI_ASYNC|MYSQLI_USE_RESULT);
$reads = $errors = $rejects = [$c];
mysqli::poll($reads,$errors,$rejects,2);
$c = $reads[0];
if($c->error) die("Error after poll! {$c->error}\n");
$rs = $c->reap_async_query();
if($c->error) die("Error after reaping query! {$c->error}\n");
$rs->fetch_row();
if($c->error) die("Error after fetching result set! {$c->error}\n");
Expected result:
----------------
What I expect to happen with my test script is that when it executes, there should be a short delay
and it should print "Error after reaping query! Query execution was interrupted
(max_statement_time exceeded)".
I expect that the connection handle error status should be set after reap_async_query(), so I can
check if the async query was successful or encountered some kind of error.
Actual result:
--------------
The script prints "Error after fetching result set! Query execution was interrupted
(max_statement_time exceeded)"
This indicates that the mysqli connection handle error status is not updated until after I've
called reap_async_query() and attempted any kind of fetch*().
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=81567&edit=1
Thread (4 messages)