Bug #81567 [Opn->Ver]: Connection error status not immediately set for killed async query

From: Date: Thu, 04 Nov 2021 14:51:34 +0000
Subject: Bug #81567 [Opn->Ver]: Connection error status not immediately set for killed async query
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-237559@lists.php.net to get a copy of this message
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)

« previous php.bugs (#237559) next »