Fixed bug #79872 by improving error message

The actual behavior here is correct, but the previous error
message was misleading, as neither fetchAll() nor buffered queries
would help in this situation. Instead it is necessary to consume
all rowsets, which can be done by either unsetting the statement
or calling closeCursor().
This commit is contained in:
Nikita Popov 2020-12-10 11:46:29 +01:00
parent d63aedd173
commit 288581fade
3 changed files with 41 additions and 6 deletions

1
NEWS
View file

@ -51,6 +51,7 @@ PHP NEWS
query error). (Nikita)
. Fixed bug #76815 (PDOStatement cannot be GCed/closeCursor-ed when a
PROCEDURE resultset SIGNAL). (Nikita)
. Fixed bug #79872 (Can't execute query with pending result sets). (Nikita)
- Phar:
. Fixed bug #73809 (Phar Zip parse crash - mmap fail). (cmb)

View file

@ -73,12 +73,20 @@ int _pdo_mysql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int lin
if (einfo->errcode) {
if (einfo->errcode == 2014) {
einfo->errmsg = pestrdup(
"Cannot execute queries while other unbuffered queries are active. "
"Consider using PDOStatement::fetchAll(). Alternatively, if your code "
"is only ever going to run against mysql, you may enable query "
"buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.",
dbh->is_persistent);
if (mysql_more_results(H->server)) {
einfo->errmsg = pestrdup(
"Cannot execute queries while there are pending result sets. "
"Consider unsetting the previous PDOStatement or calling "
"PDOStatement::closeCursor()",
dbh->is_persistent);
} else {
einfo->errmsg = pestrdup(
"Cannot execute queries while other unbuffered queries are active. "
"Consider using PDOStatement::fetchAll(). Alternatively, if your code "
"is only ever going to run against mysql, you may enable query "
"buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.",
dbh->is_persistent);
}
} else if (einfo->errcode == 2057) {
einfo->errmsg = pestrdup(
"A stored procedure returning result sets of different size was called. "

View file

@ -0,0 +1,26 @@
--TEST--
Bug #79872: Can't execute query with pending result sets
--SKIPIF--
<?php
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc');
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
MySQLPDOTest::skip();
?>
--FILE--
<?php
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
$db = MySQLPDOTest::factory();
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare('SET @foo = 1; SET @bar = 2;');
$stmt->execute();
try {
var_dump($db->query('SELECT @foo')->fetchAll());
} catch (PDOException $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
SQLSTATE[HY000]: General error: 2014 Cannot execute queries while there are pending result sets. Consider unsetting the previous PDOStatement or calling PDOStatement::closeCursor()