summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-12-10 11:46:29 +0100
committerNikita Popov <nikita.ppv@gmail.com>2020-12-10 11:46:29 +0100
commit288581fadef58363dac4fc72ded0fae830bf603c (patch)
tree22652c599af378afafcac907d4b140a9faa92cbf
parentd63aedd173fbb8b3399cff4b991f8a343dd0f331 (diff)
downloadphp-git-288581fadef58363dac4fc72ded0fae830bf603c.tar.gz
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().
-rw-r--r--NEWS1
-rw-r--r--ext/pdo_mysql/mysql_driver.c20
-rw-r--r--ext/pdo_mysql/tests/bug79872.phpt26
3 files changed, 41 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 5178fb162f..0a91136d76 100644
--- a/NEWS
+++ b/NEWS
@@ -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)
diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c
index 764c453438..90bc7792d5 100644
--- a/ext/pdo_mysql/mysql_driver.c
+++ b/ext/pdo_mysql/mysql_driver.c
@@ -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. "
diff --git a/ext/pdo_mysql/tests/bug79872.phpt b/ext/pdo_mysql/tests/bug79872.phpt
new file mode 100644
index 0000000000..0d1ecaf2d3
--- /dev/null
+++ b/ext/pdo_mysql/tests/bug79872.phpt
@@ -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()