]> granicus.if.org Git - php/commitdiff
PDO MySQL: Make sure nextRowset() works with partially consumed result
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 9 Dec 2020 13:46:49 +0000 (14:46 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 9 Dec 2020 13:46:49 +0000 (14:46 +0100)
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.

ext/pdo_mysql/mysql_statement.c
ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt

index 7d0988b384395bea81abf5032fe6c64e2d1fe0ec..a8be36c426752abdde8c955d15e37ef2bad430a6 100644 (file)
@@ -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);
index 91a4615a52be0d8c4721107d03fe0e82855a04ba..b528f865abc2ae3b3dacd36a21488dcf997f4738 100644 (file)
@@ -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!