From: Nikita Popov Date: Wed, 9 Dec 2020 13:46:49 +0000 (+0100) Subject: PDO MySQL: Make sure nextRowset() works with partially consumed result X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=186b76636830a00e2533c7b0aaff4b02d9489376;p=php PDO MySQL: Make sure nextRowset() works with partially consumed result This was already working in all cases apart from native prepared statements with unbuffered queries. In that case invoking stmt_free_result() addresses the issue. --- diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c index 7d0988b384..a8be36c426 100644 --- a/ext/pdo_mysql/mysql_statement.c +++ b/ext/pdo_mysql/mysql_statement.c @@ -349,6 +349,15 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt) /* {{{ */ PDO_DBG_ENTER("pdo_mysql_stmt_next_rowset"); PDO_DBG_INF_FMT("stmt=%p", S->stmt); + /* ensure that we free any previous unfetched results */ + if (S->stmt) { + mysql_stmt_free_result(S->stmt); + } + if (S->result) { + mysql_free_result(S->result); + S->result = NULL; + } + #ifdef PDO_USE_MYSQLND if (!H->emulate_prepare) { if (!mysqlnd_stmt_more_results(S->stmt)) { @@ -359,11 +368,6 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt) /* {{{ */ PDO_DBG_RETURN(0); } - /* TODO - this code is stolen from execute() - see above */ - if (S->result) { - mysql_free_result(S->result); - S->result = NULL; - } { /* for SHOW/DESCRIBE and others the column/field count is not available before execute */ int i; @@ -394,17 +398,6 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt) /* {{{ */ } #endif -/* ensure that we free any previous unfetched results */ -#ifndef PDO_USE_MYSQLND - if (S->stmt) { - mysql_stmt_free_result(S->stmt); - } -#endif - if (S->result) { - mysql_free_result(S->result); - S->result = NULL; - } - if (!mysql_more_results(H->server)) { /* No more results */ PDO_DBG_RETURN(0); diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt index 91a4615a52..b528f865ab 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt @@ -57,6 +57,11 @@ if (!MySQLPDOTest::isPDOMySQLnd()) } while ($stmt->nextRowSet()); var_dump($stmt->nextRowSet()); + echo "Skip fetchAll(): "; + unset($stmt); + $stmt = $db->query('CALL p()'); + var_dump($stmt->nextRowSet()); + $stmt->closeCursor(); } try { @@ -160,6 +165,7 @@ array(3) { array(0) { } bool(false) +Skip fetchAll(): bool(true) array(1) { [0]=> array(1) { @@ -211,6 +217,7 @@ array(3) { array(0) { } bool(false) +Skip fetchAll(): bool(true) Native PS... array(1) { [0]=> @@ -263,6 +270,7 @@ array(3) { array(0) { } bool(false) +Skip fetchAll(): bool(true) array(1) { [0]=> array(1) { @@ -314,4 +322,5 @@ array(3) { array(0) { } bool(false) +Skip fetchAll(): bool(true) done!