PHP bug 67130: nextRowset should work with unfetched rows
authorPeter LeBrun <plebrun@wayfair.com>
Fri, 1 Jul 2016 19:44:06 +0000 (15:44 -0400)
committerAdam Baratz <adambaratz@php.net>
Wed, 21 Sep 2016 18:27:23 +0000 (14:27 -0400)
ext/pdo_dblib/dblib_stmt.c
ext/pdo_dblib/tests/bug_67130.phpt [new file with mode: 0644]

index 1c0577e6116f0d53b6e7a9b2e6aafea3a0c703e5..a230db2984378ec7efe90f5f17727dff098359fd 100644 (file)
@@ -119,7 +119,7 @@ static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt)
        return 1;
 }
 
-static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt)
+static int pdo_dblib_stmt_next_rowset_no_cancel(pdo_stmt_t *stmt)
 {
        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
        pdo_dblib_db_handle *H = S->H;
@@ -142,6 +142,27 @@ static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt)
        return 1;
 }
 
+static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt)
+{
+       pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+       pdo_dblib_db_handle *H = S->H;
+       RETCODE ret = SUCCESS;
+
+       /* Ideally use dbcanquery here, but there is a bug in FreeTDS's implementation of dbcanquery
+        * It has been resolved but is currently only available in nightly builds
+        */
+       while (NO_MORE_ROWS != ret) {
+               ret = dbnextrow(H->link);
+
+               if (FAIL == ret) {
+                       pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_DBLIB: dbnextrow() returned FAIL");
+                       return 0;
+               }
+       }
+
+       return pdo_dblib_stmt_next_rowset_no_cancel(stmt);
+}
+
 static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt)
 {
        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
@@ -160,7 +181,7 @@ static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt)
                return 0;
        }
 
-       ret = pdo_dblib_stmt_next_rowset(stmt);
+       ret = pdo_dblib_stmt_next_rowset_no_cancel(stmt);
 
        stmt->row_count = DBCOUNT(H->link);
        stmt->column_count = dbnumcols(H->link);
diff --git a/ext/pdo_dblib/tests/bug_67130.phpt b/ext/pdo_dblib/tests/bug_67130.phpt
new file mode 100644 (file)
index 0000000..4cfb66f
--- /dev/null
@@ -0,0 +1,36 @@
+--TEST--
+PDO_DBLIB: \PDOStatement::nextRowset() should succeed when all rows in current rowset haven't been fetched
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+
+$stmt = $db->query('SELECT 1; SELECT 2; SELECT 3;');
+var_dump($stmt->fetch());
+var_dump($stmt->fetch());
+var_dump($stmt->nextRowset());
+var_dump($stmt->nextRowset());
+var_dump($stmt->fetch());
+var_dump($stmt->nextRowset());
+?>
+--EXPECT--
+array(2) {
+  ["computed"]=>
+  int(1)
+  [0]=>
+  int(1)
+}
+bool(false)
+bool(true)
+bool(true)
+array(2) {
+  ["computed"]=>
+  int(3)
+  [0]=>
+  int(3)
+}
+bool(false)