mirror of
https://github.com/php/php-src.git
synced 2026-04-21 06:51:18 +02:00
Fixed bug #66878
Keep track of whether we have fully consumed all result sets, either using nextRowset() calls or closeCursor() and skip the attempt to consume remaining results sets during destruction in that case. Especiall if closeCursor() has been used, we really shouldn't have this sort of cross-statement inference.
This commit is contained in:
2
NEWS
2
NEWS
@@ -43,6 +43,8 @@ PHP NEWS
|
||||
statements). (Nikita)
|
||||
. Fixed bug #78152 (PDO::exec() - Bad error handling with multiple commands).
|
||||
(Nikita)
|
||||
. Fixed bug #66878 (Multiple rowsets not returned unless PDO statement object
|
||||
is unset()). (Nikita)
|
||||
|
||||
- Phar:
|
||||
. Fixed bug #73809 (Phar Zip parse crash - mmap fail). (cmb)
|
||||
|
||||
@@ -84,7 +84,7 @@ static int pdo_mysql_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!Z_ISUNDEF(stmt->database_object_handle)
|
||||
if (!S->done && !Z_ISUNDEF(stmt->database_object_handle)
|
||||
&& IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE(stmt->database_object_handle)])
|
||||
&& (!(OBJ_FLAGS(Z_OBJ(stmt->database_object_handle)) & IS_OBJ_FREE_CALLED))) {
|
||||
while (mysql_more_results(S->H->server)) {
|
||||
@@ -326,6 +326,7 @@ static int pdo_mysql_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
|
||||
PDO_DBG_ENTER("pdo_mysql_stmt_execute");
|
||||
PDO_DBG_INF_FMT("stmt=%p", S->stmt);
|
||||
|
||||
S->done = 0;
|
||||
if (S->stmt) {
|
||||
PDO_DBG_RETURN(pdo_mysql_stmt_execute_prepared(stmt));
|
||||
}
|
||||
@@ -365,6 +366,7 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt) /* {{{ */
|
||||
if (!H->emulate_prepare) {
|
||||
if (mysqlnd_stmt_next_result(S->stmt)) {
|
||||
pdo_mysql_error_stmt(stmt);
|
||||
S->done = 1;
|
||||
PDO_DBG_RETURN(0);
|
||||
}
|
||||
|
||||
@@ -374,6 +376,7 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt) /* {{{ */
|
||||
|
||||
if (mysql_next_result(H->server)) {
|
||||
pdo_mysql_error_stmt(stmt);
|
||||
S->done = 1;
|
||||
PDO_DBG_RETURN(0);
|
||||
} else {
|
||||
PDO_DBG_RETURN(pdo_mysql_fill_stmt_from_result(stmt));
|
||||
@@ -842,6 +845,8 @@ static int pdo_mysql_stmt_cursor_closer(pdo_stmt_t *stmt) /* {{{ */
|
||||
|
||||
PDO_DBG_ENTER("pdo_mysql_stmt_cursor_closer");
|
||||
PDO_DBG_INF_FMT("stmt=%p", S->stmt);
|
||||
|
||||
S->done = 1;
|
||||
if (S->result) {
|
||||
mysql_free_result(S->result);
|
||||
S->result = NULL;
|
||||
|
||||
@@ -142,6 +142,9 @@ typedef struct {
|
||||
zend_ulong *out_length;
|
||||
unsigned int params_given;
|
||||
unsigned max_length:1;
|
||||
/* Whether all result sets have been fully consumed.
|
||||
* If this flag is not set, they need to be consumed during destruction. */
|
||||
unsigned done:1;
|
||||
} pdo_mysql_stmt;
|
||||
|
||||
extern const pdo_driver_t pdo_mysql_driver;
|
||||
|
||||
36
ext/pdo_mysql/tests/bug66878.phpt
Normal file
36
ext/pdo_mysql/tests/bug66878.phpt
Normal file
@@ -0,0 +1,36 @@
|
||||
--TEST--
|
||||
Bug #66878: Multiple rowsets not returned unless PDO statement object is unset()
|
||||
--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');
|
||||
|
||||
$pdo = MySQLPDOTest::factory();
|
||||
|
||||
$sql = 'SELECT 123; SELECT 42; SELECT 999';
|
||||
|
||||
$stmt = $pdo->query($sql);
|
||||
var_dump($stmt->nextRowset());
|
||||
var_dump($stmt->nextRowset());
|
||||
var_dump($stmt->nextRowset());
|
||||
$stmt->closeCursor();
|
||||
|
||||
$stmt = $pdo->query($sql);
|
||||
var_dump($stmt->nextRowset());
|
||||
var_dump($stmt->nextRowset());
|
||||
var_dump($stmt->nextRowset());
|
||||
$stmt->closeCursor();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(false)
|
||||
Reference in New Issue
Block a user