andrey                                   Mon, 05 Sep 2011 15:29:45 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=316188

Log:
Fix for Bug #55582 mysqli_num_rows() returns always 0 for unbuffered, when 
mysqlnd is used

Bug: https://bugs.php.net/55582 (Open) mysqli_num_rows() returns always 0 for 
unbuffered, when mysqlnd is used
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    U   php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_api.c
    U   php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_libmysql.h
    U   php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_mysqlnd.h
    A   php/php-src/branches/PHP_5_3/ext/mysqli/tests/bug55582.phpt
    U   php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_api.c
    U   php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_libmysql.h
    U   php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_mysqlnd.h
    U   php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_result_iterator.c
    A   php/php-src/branches/PHP_5_4/ext/mysqli/tests/bug55582.phpt
    U   php/php-src/branches/PHP_5_4/ext/mysqlnd/mysqlnd_result.c
    U   php/php-src/trunk/ext/mysqli/mysqli_api.c
    U   php/php-src/trunk/ext/mysqli/mysqli_libmysql.h
    U   php/php-src/trunk/ext/mysqli/mysqli_mysqlnd.h
    U   php/php-src/trunk/ext/mysqli/mysqli_result_iterator.c
    A   php/php-src/trunk/ext/mysqli/tests/bug55582.phpt
    U   php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/branches/PHP_5_3/NEWS	2011-09-05 15:29:45 UTC (rev 316188)
@@ -18,6 +18,10 @@
 - MySQL:
   . Fixed bug #55550 (mysql.trace_mode miscounts result sets). (Johannes)

+- MySQLi extension:
+  . Fixed bug #55582 (mysqli_num_rows() returns always 0 for unbuffered, when
+  mysqlnd is used). (Andrey)
+
 - mysqlnd
   . Fixed bug #55067 (MySQL doesn't support compression - wrong config option).
     (Andrey)

Modified: php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_api.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_api.c	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_api.c	2011-09-05 15:29:45 UTC (rev 316188)
@@ -1608,7 +1608,7 @@
 	}
 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);

-	if (mysqli_result_is_unbuffered(result)) {
+	if (mysqli_result_is_unbuffered_and_not_everything_is_fetched(result)) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
 		RETURN_LONG(0);
 	}

Modified: php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_libmysql.h
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_libmysql.h	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_libmysql.h	2011-09-05 15:29:45 UTC (rev 316188)
@@ -30,6 +30,7 @@
 #define MYSQLND_OPT_INT_AND_YEAR_AS_INT				201

 #define mysqli_result_is_unbuffered(r)		((r)->handle && (r)->handle->status == MYSQL_STATUS_USE_RESULT)
+#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r)		(((r)->handle && (r)->handle->status == MYSQL_STATUS_USE_RESULT) || ((r)->data == NULL))
 #define mysqli_server_status(c)				(c)->server_status
 #define mysqli_stmt_get_id(s)				((s)->stmt_id)
 #define mysqli_stmt_warning_count(s)		mysql_warning_count((s)->mysql)

Modified: php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_mysqlnd.h
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_mysqlnd.h	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_mysqlnd.h	2011-09-05 15:29:45 UTC (rev 316188)
@@ -31,6 +31,7 @@
 #define MYSQLI_CLOSE_DISCONNECTED              MYSQLND_CLOSE_DISCONNECTED

 #define mysqli_result_is_unbuffered(r)	((r)->unbuf)
+#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r)	((r)->unbuf && !(r)->unbuf->eof_reached)
 #define mysqli_server_status(c)			(c)->upsert_status.server_status
 #define mysqli_stmt_get_id(s)			((s)->data->stmt_id)
 #define mysqli_stmt_warning_count(s)	mysqlnd_stmt_warning_count((s))

Added: php/php-src/branches/PHP_5_3/ext/mysqli/tests/bug55582.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqli/tests/bug55582.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_3/ext/mysqli/tests/bug55582.phpt	2011-09-05 15:29:45 UTC (rev 316188)
@@ -0,0 +1,41 @@
+--TEST--
+Bug #55582 mysqli_num_rows() returns always 0 for unbuffered, when mysqlnd is used
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifconnectfailure.inc');
+require_once("connect.inc");
+?>
+--FILE--
+<?php
+	include "connect.inc";
+	if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) {
+		printf("[001] Cannot connect to the server");
+	}
+
+	var_dump($link->real_query("SELECT 1"));
+	$res = $link->use_result();
+	var_dump(mysqli_num_rows($res));
+	var_dump($res->fetch_assoc());
+	var_dump(mysqli_num_rows($res));
+	var_dump($res->fetch_assoc());
+	var_dump(mysqli_num_rows($res));
+
+	$link->close();
+	echo "done\n";
+?>
+--EXPECTF--
+bool(true)
+
+Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d
+int(0)
+array(1) {
+  [1]=>
+  string(1) "1"
+}
+
+Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d
+int(0)
+NULL
+int(1)
+done
\ No newline at end of file

Modified: php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_api.c
===================================================================
--- php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_api.c	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_api.c	2011-09-05 15:29:45 UTC (rev 316188)
@@ -1612,7 +1612,7 @@
 	}
 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);

-	if (mysqli_result_is_unbuffered(result)) {
+	if (mysqli_result_is_unbuffered_and_not_everything_is_fetched(result)) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
 		RETURN_LONG(0);
 	}

Modified: php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_libmysql.h
===================================================================
--- php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_libmysql.h	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_libmysql.h	2011-09-05 15:29:45 UTC (rev 316188)
@@ -30,6 +30,7 @@

 /* r->data should be always NULL, at least in recent libmysql versions, the status changes once data is read*/
 #define mysqli_result_is_unbuffered(r)		(((r)->handle && (r)->handle->status == MYSQL_STATUS_USE_RESULT) || ((r)->data == NULL))
+#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r)		(((r)->handle && (r)->handle->status == MYSQL_STATUS_USE_RESULT) || ((r)->data == NULL))
 #define mysqli_server_status(c)				(c)->server_status
 #define mysqli_stmt_get_id(s)				((s)->stmt_id)
 #define mysqli_stmt_warning_count(s)		mysql_warning_count((s)->mysql)

Modified: php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_mysqlnd.h
===================================================================
--- php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_mysqlnd.h	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_mysqlnd.h	2011-09-05 15:29:45 UTC (rev 316188)
@@ -31,6 +31,7 @@
 #define MYSQLI_CLOSE_DISCONNECTED              MYSQLND_CLOSE_DISCONNECTED

 #define mysqli_result_is_unbuffered(r)	((r)->unbuf)
+#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r)	((r)->unbuf && !(r)->unbuf->eof_reached)
 #define mysqli_server_status(c)			(c)->upsert_status.server_status
 #define mysqli_stmt_get_id(s)			((s)->data->stmt_id)
 #define mysqli_stmt_warning_count(s)	mysqlnd_stmt_warning_count((s))

Modified: php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_result_iterator.c
===================================================================
--- php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_result_iterator.c	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/branches/PHP_5_4/ext/mysqli/mysqli_result_iterator.c	2011-09-05 15:29:45 UTC (rev 316188)
@@ -133,7 +133,7 @@

 	if (mysqli_result_is_unbuffered(result)) {
 #if MYSQLI_USE_MYSQLND
-		if (result->unbuf && result->unbuf->eof_reached) {
+		if (result->unbuf->eof_reached) {
 #else
 		if (result->eof) {
 #endif

Added: php/php-src/branches/PHP_5_4/ext/mysqli/tests/bug55582.phpt
===================================================================
--- php/php-src/branches/PHP_5_4/ext/mysqli/tests/bug55582.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_4/ext/mysqli/tests/bug55582.phpt	2011-09-05 15:29:45 UTC (rev 316188)
@@ -0,0 +1,41 @@
+--TEST--
+Bug #55582 mysqli_num_rows() returns always 0 for unbuffered, when mysqlnd is used
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifconnectfailure.inc');
+require_once("connect.inc");
+?>
+--FILE--
+<?php
+	include "connect.inc";
+	if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) {
+		printf("[001] Cannot connect to the server");
+	}
+
+	var_dump($link->real_query("SELECT 1"));
+	$res = $link->use_result();
+	var_dump(mysqli_num_rows($res));
+	var_dump($res->fetch_assoc());
+	var_dump(mysqli_num_rows($res));
+	var_dump($res->fetch_assoc());
+	var_dump(mysqli_num_rows($res));
+
+	$link->close();
+	echo "done\n";
+?>
+--EXPECTF--
+bool(true)
+
+Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d
+int(0)
+array(1) {
+  [1]=>
+  string(1) "1"
+}
+
+Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d
+int(0)
+NULL
+int(1)
+done
\ No newline at end of file

Modified: php/php-src/branches/PHP_5_4/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/branches/PHP_5_4/ext/mysqlnd/mysqlnd_result.c	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/branches/PHP_5_4/ext/mysqlnd/mysqlnd_result.c	2011-09-05 15:29:45 UTC (rev 316188)
@@ -601,19 +601,18 @@
 static unsigned long *
 mysqlnd_fetch_lengths_unbuffered(MYSQLND_RES * const result TSRMLS_DC)
 {
-	return result->lengths;
+	/* simulate output of libmysql */
+	return (!result->unbuf || result->unbuf->last_row_data || result->unbuf->eof_reached)? result->lengths:NULL;
 }
 /* }}} */


-#if !defined(MYSQLND_USE_OPTIMISATIONS) || MYSQLND_USE_OPTIMISATIONS == 0
 /* {{{ mysqlnd_res::fetch_lengths */
 PHPAPI unsigned long * _mysqlnd_fetch_lengths(MYSQLND_RES * const result TSRMLS_DC)
 {
 	return result->m.fetch_lengths? result->m.fetch_lengths(result TSRMLS_CC) : NULL;
 }
 /* }}} */
-#endif


 /* {{{ mysqlnd_fetch_row_unbuffered_c */

Modified: php/php-src/trunk/ext/mysqli/mysqli_api.c
===================================================================
--- php/php-src/trunk/ext/mysqli/mysqli_api.c	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/trunk/ext/mysqli/mysqli_api.c	2011-09-05 15:29:45 UTC (rev 316188)
@@ -1612,7 +1612,7 @@
 	}
 	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);

-	if (mysqli_result_is_unbuffered(result)) {
+	if (mysqli_result_is_unbuffered_and_not_everything_is_fetched(result)) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
 		RETURN_LONG(0);
 	}

Modified: php/php-src/trunk/ext/mysqli/mysqli_libmysql.h
===================================================================
--- php/php-src/trunk/ext/mysqli/mysqli_libmysql.h	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/trunk/ext/mysqli/mysqli_libmysql.h	2011-09-05 15:29:45 UTC (rev 316188)
@@ -30,6 +30,7 @@

 /* r->data should be always NULL, at least in recent libmysql versions, the status changes once data is read*/
 #define mysqli_result_is_unbuffered(r)		(((r)->handle && (r)->handle->status == MYSQL_STATUS_USE_RESULT) || ((r)->data == NULL))
+#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r)		(((r)->handle && (r)->handle->status == MYSQL_STATUS_USE_RESULT) || ((r)->data == NULL))
 #define mysqli_server_status(c)				(c)->server_status
 #define mysqli_stmt_get_id(s)				((s)->stmt_id)
 #define mysqli_stmt_warning_count(s)		mysql_warning_count((s)->mysql)

Modified: php/php-src/trunk/ext/mysqli/mysqli_mysqlnd.h
===================================================================
--- php/php-src/trunk/ext/mysqli/mysqli_mysqlnd.h	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/trunk/ext/mysqli/mysqli_mysqlnd.h	2011-09-05 15:29:45 UTC (rev 316188)
@@ -31,6 +31,7 @@
 #define MYSQLI_CLOSE_DISCONNECTED              MYSQLND_CLOSE_DISCONNECTED

 #define mysqli_result_is_unbuffered(r)	((r)->unbuf)
+#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r)	((r)->unbuf && !(r)->unbuf->eof_reached)
 #define mysqli_server_status(c)			(c)->upsert_status.server_status
 #define mysqli_stmt_get_id(s)			((s)->data->stmt_id)
 #define mysqli_stmt_warning_count(s)	mysqlnd_stmt_warning_count((s))

Modified: php/php-src/trunk/ext/mysqli/mysqli_result_iterator.c
===================================================================
--- php/php-src/trunk/ext/mysqli/mysqli_result_iterator.c	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/trunk/ext/mysqli/mysqli_result_iterator.c	2011-09-05 15:29:45 UTC (rev 316188)
@@ -133,7 +133,7 @@

 	if (mysqli_result_is_unbuffered(result)) {
 #if MYSQLI_USE_MYSQLND
-		if (result->unbuf && result->unbuf->eof_reached) {
+		if (result->unbuf->eof_reached) {
 #else
 		if (result->eof) {
 #endif

Added: php/php-src/trunk/ext/mysqli/tests/bug55582.phpt
===================================================================
--- php/php-src/trunk/ext/mysqli/tests/bug55582.phpt	                        (rev 0)
+++ php/php-src/trunk/ext/mysqli/tests/bug55582.phpt	2011-09-05 15:29:45 UTC (rev 316188)
@@ -0,0 +1,41 @@
+--TEST--
+Bug #55582 mysqli_num_rows() returns always 0 for unbuffered, when mysqlnd is used
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifconnectfailure.inc');
+require_once("connect.inc");
+?>
+--FILE--
+<?php
+	include "connect.inc";
+	if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) {
+		printf("[001] Cannot connect to the server");
+	}
+
+	var_dump($link->real_query("SELECT 1"));
+	$res = $link->use_result();
+	var_dump(mysqli_num_rows($res));
+	var_dump($res->fetch_assoc());
+	var_dump(mysqli_num_rows($res));
+	var_dump($res->fetch_assoc());
+	var_dump(mysqli_num_rows($res));
+
+	$link->close();
+	echo "done\n";
+?>
+--EXPECTF--
+bool(true)
+
+Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d
+int(0)
+array(1) {
+  [1]=>
+  string(1) "1"
+}
+
+Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d
+int(0)
+NULL
+int(1)
+done
\ No newline at end of file

Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c	2011-09-05 15:11:48 UTC (rev 316187)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c	2011-09-05 15:29:45 UTC (rev 316188)
@@ -601,19 +601,18 @@
 static unsigned long *
 mysqlnd_fetch_lengths_unbuffered(MYSQLND_RES * const result TSRMLS_DC)
 {
-	return result->lengths;
+	/* simulate output of libmysql */
+	return (!result->unbuf || result->unbuf->last_row_data || result->unbuf->eof_reached)? result->lengths:NULL;
 }
 /* }}} */


-#if !defined(MYSQLND_USE_OPTIMISATIONS) || MYSQLND_USE_OPTIMISATIONS == 0
 /* {{{ mysqlnd_res::fetch_lengths */
 PHPAPI unsigned long * _mysqlnd_fetch_lengths(MYSQLND_RES * const result TSRMLS_DC)
 {
 	return result->m.fetch_lengths? result->m.fetch_lengths(result TSRMLS_CC) : NULL;
 }
 /* }}} */
-#endif


 /* {{{ mysqlnd_fetch_row_unbuffered_c */
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to