Skip to content

Commit e450621

Browse files
committed
Fixed bug #76815
When we receive an error while reading a result set, we should assume that no more result sets are available. libmysqlclient implements the same behavior.
1 parent 4922049 commit e450621

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ PHP NEWS
4040
queries"). (Nikita)
4141
. Fixed bug #71145 (Multiple statements in init command triggers unbuffered
4242
query error). (Nikita)
43+
. Fixed bug #76815 (PDOStatement cannot be GCed/closeCursor-ed when a
44+
PROCEDURE resultset SIGNAL). (Nikita)
4345

4446
- Phpdbg:
4547
. Fixed bug #76813 (Access violation near NULL on source operand). (cmb)

ext/mysqlnd/mysqlnd_result.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,6 +1359,13 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
13591359
UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, row_packet.server_status);
13601360
}
13611361

1362+
if (ret == FAIL) {
1363+
/* Error packets do not contain server status information. However, we know that after
1364+
* an error there will be no further result sets. */
1365+
UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status,
1366+
UPSERT_STATUS_GET_SERVER_STATUS(conn->upsert_status) & ~SERVER_MORE_RESULTS_EXISTS);
1367+
}
1368+
13621369
/* save some memory */
13631370
if (free_rows) {
13641371
/* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */

ext/pdo_mysql/tests/bug76815.phpt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug #76815: PDOStatement cannot be GCed/closeCursor-ed when a PROCEDURE resultset SIGNAL
3+
--SKIPIF--
4+
<?php
5+
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc');
6+
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
7+
MySQLPDOTest::skip();
8+
?>
9+
--FILE--
10+
<?php
11+
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
12+
13+
$pdo = MySQLPDOTest::factory();
14+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
15+
16+
$pdo->query('DROP FUNCTION IF EXISTS tst');
17+
$pdo->query('DROP PROCEDURE IF EXISTS tst2');
18+
$pdo->query('CREATE FUNCTION tst() RETURNS VARCHAR(5) DETERMINISTIC BEGIN RETURN \'x12345\'; END');
19+
$pdo->query('CREATE PROCEDURE tst2() BEGIN SELECT tst(); END');
20+
21+
$st = $pdo->prepare('CALL tst2()');
22+
try {
23+
$st->execute();
24+
} catch (PDOException $ex) {
25+
echo $ex->getMessage(), "\n";
26+
}
27+
unset($st);
28+
echo "Ok.\n";
29+
30+
?>
31+
--EXPECT--
32+
SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'tst()' at row 1
33+
Ok.

0 commit comments

Comments
 (0)