summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Wendel <uw@php.net>2007-07-23 12:24:02 +0000
committerUlf Wendel <uw@php.net>2007-07-23 12:24:02 +0000
commitff87d3ec5b2ccc1555d669cbe5f5a90ba5885068 (patch)
treec03b91a1182ab50066fc1ebfc1d69bce4b820ee8
parent8e85715547978fb7bed32d95e907e7bfd1f0d794 (diff)
downloadphp-git-ff87d3ec5b2ccc1555d669cbe5f5a90ba5885068.tar.gz
Adding tests for a few new functions that come with mysqlnd:
mysqli_stmt_get_result() - create mysqli_result set from stmt mysqli_get_cache_stats() - mysqlnd internal status/stats mysqli_get_client_stats() - mysqlnd internal status/stats/
-rw-r--r--ext/mysqli/tests/mysqli_get_cache_stats.phpt127
-rw-r--r--ext/mysqli/tests/mysqli_get_cache_stats_free_buffered.phpt92
-rw-r--r--ext/mysqli/tests/mysqli_get_client_stats.phpt644
-rw-r--r--ext/mysqli/tests/mysqli_stmt_get_result.phpt208
-rw-r--r--ext/mysqli/tests/mysqli_stmt_get_result2.phpt187
-rw-r--r--ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt128
-rw-r--r--ext/mysqli/tests/mysqli_stmt_get_result_field_count.phpt46
-rw-r--r--ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt259
-rw-r--r--ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt236
-rw-r--r--ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt125
10 files changed, 2052 insertions, 0 deletions
diff --git a/ext/mysqli/tests/mysqli_get_cache_stats.phpt b/ext/mysqli/tests/mysqli_get_cache_stats.phpt
new file mode 100644
index 0000000000..c2fb0d51e4
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_get_cache_stats.phpt
@@ -0,0 +1,127 @@
+--TEST--
+mysqli_get_cache_stats()
+--SKIPIF--
+<?PHP
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+if (!function_exists('mysqli_get_cache_stats')) {
+ die("skip only available with mysqlnd");
+}
+if (ini_get("unicode.semantics")) {
+ die("skip: zval cache works now only in non-unicode mode");
+}
+?>
+--FILE--
+<?php
+ $tmp = $link = null;
+ if (!is_null($tmp = @mysqli_get_cache_stats($link)))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ include "connect.inc";
+
+ if (!is_array($info = mysqli_get_cache_stats()) || empty($info))
+ printf("[002] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info);
+
+ var_dump($info);
+
+ if ($info['size'] !== $info['free_items'])
+ printf("[003] Unused cache should have size (%d) == free_items (%d)\n",
+ $info['size'], $info['free_items']);
+
+ require_once('table.inc');
+
+ if (!is_array($new_info = mysqli_get_cache_stats()) || empty($new_info))
+ printf("[004] Expecting array/any_non_empty, got %s/%s\n", gettype($new_info), $new_info);
+
+ if ($info['size'] !== $new_info['size'])
+ printf("[005] Cache size should not have changes! Expecting int/%d, got %s/%d\n",
+ $info['size'], gettype($new_info['size']), $new_info['size']);
+
+ if (count($info) != count($new_info)) {
+ printf("[006] Both arrays should have the same number of entries\n");
+ var_dump($info);
+ var_dump($new_info);
+ }
+
+ if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id"))
+ printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (!is_object($res = mysqli_use_result($link)))
+ printf("[008] Expecting object, got %s/%s. [%d] %s\n",
+ gettype($res), $res, mysqli_errno($link), mysqli_error($link));
+
+ if (!$row = mysqli_fetch_assoc($res))
+ printf("[009] There should be at least one row in the test table for this test, [%d] %s\n",
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_cache_stats()) || empty($new_info))
+ printf("[010] Expecting array/any_non_empty, got %s/%s\n", gettype($new_info), $new_info);
+
+ if ($new_info['get_hits'] <= $info['get_hits'])
+ printf("[011] get_hits should have increased, %d (new) <= %d (old)!\n",
+ $new_info['get_hits'], $info['get_hits']);
+
+ if (!$row = mysqli_fetch_assoc($res))
+ printf("[012] There should be two rows in the test table for this test, [%d] %s\n",
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_cache_stats()) || empty($new_info))
+ printf("[013] Expecting array/any_non_empty, got %s/%s\n", gettype($new_info), $new_info);
+
+ if ($new_info['put_misses'] <= $info['put_misses'])
+ printf("[014] put_misses should have increased, %d (new) <= %d (old)!\n",
+ $new_info['put_misses'], $info['put_misses']);
+
+ if ($new_info['references'] < $info['references'] + 2)
+ printf("[015] reference counter should have increased, %d (new) < %d + 2 (old)!\n",
+ $new_info['references'], $info['references']);
+
+ unset($row);
+ mysqli_free_result($res);
+
+ if (!is_array($info = mysqli_get_cache_stats()) || empty($info))
+ printf("[016] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info);
+
+ if ($info['free_items'] <= $new_info['free_items'])
+ printf("[017] Looks like cached entries never get free'd.\n");
+
+ mysqli_close($link);
+
+ print "done!";
+?>
+--EXPECTF--
+array(7) {
+ ["put_hits"]=>
+ int(0)
+ ["put_misses"]=>
+ int(0)
+ ["get_hits"]=>
+ int(0)
+ ["get_misses"]=>
+ int(0)
+ ["size"]=>
+ int(%d)
+ ["free_items"]=>
+ int(%d)
+ ["references"]=>
+ int(%d)
+}
+done!
+--UEXPECTF--
+array(7) {
+ [u"put_hits"]=>
+ int(0)
+ [u"put_misses"]=>
+ int(0)
+ [u"get_hits"]=>
+ int(0)
+ [u"get_misses"]=>
+ int(0)
+ [u"size"]=>
+ int(%d)
+ [u"free_items"]=>
+ int(%d)
+ [u"references"]=>
+ int(%d)
+}
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_get_cache_stats_free_buffered.phpt b/ext/mysqli/tests/mysqli_get_cache_stats_free_buffered.phpt
new file mode 100644
index 0000000000..33ab38ee53
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_get_cache_stats_free_buffered.phpt
@@ -0,0 +1,92 @@
+--TEST--
+mysqli_get_cache_stats() - freeing for buffered result sets
+--SKIPIF--
+<?PHP
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+if (!function_exists('mysqli_get_cache_stats')) {
+ die("skip only available with mysqlnd");
+}
+if (ini_get("unicode.semantics")) {
+ die("skip: zval cache works now only in non-unicode mode");
+}
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ require_once('table.inc');
+
+ if (!is_array($info = mysqli_get_cache_stats()) || empty($info))
+ printf("[001] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info);
+
+ if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id"))
+ printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ $rows = array();
+ while ($rows[] = mysqli_fetch_assoc($res))
+ ;
+ mysqli_free_result($res);
+
+ if (!is_array($new_info = mysqli_get_cache_stats()) || empty($new_info))
+ printf("[003] Expecting array/any_non_empty, got %s/%s\n", gettype($new_info), $new_info);
+
+ if ($new_info['free_items'] >= $info['free_items']) {
+ printf("[004] mysqli_free_result() should not yet have free slots again, because \$rows still exists\n");
+ var_dump($info);
+ var_dump($new_info);
+ }
+
+ /* nothing should change because GC will happen some time after free_result */
+ unset($rows);
+
+ if (!is_array($new_info = mysqli_get_cache_stats()) || empty($new_info))
+ printf("[005] Expecting array/any_non_empty, got %s/%s\n", gettype($new_info), $new_info);
+
+ if (defined("WE_HAVE_GARBAGE_COLLECTOR_TO_FREE_AFTER_ON_UNSET_AFTER_FREE_RESULT")) {
+ /*
+ For now we can't reclaim the slots after the free_result is called.
+ unset() should happen before free_result().
+ */
+ if ($new_info['free_items'] < $info['free_items']) {
+ printf("[006] \$rows has been unset, free item count should be back to the original value\n");
+ var_dump($info);
+ var_dump($new_info);
+ }
+ } else {
+ /* We have to reset $info */
+ $info = mysqli_get_cache_stats();
+ }
+
+ if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id"))
+ printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ $rows = array();
+ while ($rows[] = mysqli_fetch_assoc($res))
+ ;
+ unset($rows);
+ mysqli_free_result($res);
+
+ if (!is_array($new_info = mysqli_get_cache_stats()) || empty($new_info))
+ printf("[008] Expecting array/any_non_empty, got %s/%s\n", gettype($new_info), $new_info);
+
+ if ($new_info['free_items'] < $info['free_items']) {
+ printf("[009] \$rows has been unset, mysqli_free_result() has been called, free item count should be back to the original value\n");
+ var_dump($info);
+ var_dump($new_info);
+ }
+
+ mysqli_close($link);
+
+ if (!is_array($new_info = mysqli_get_cache_stats()) || empty($new_info))
+ printf("[010] Expecting array/any_non_empty, got %s/%s\n", gettype($new_info), $new_info);
+
+ if ($new_info['free_items'] < $info['free_items']) {
+ printf("[011] connection has been closed, free item count should be back to the original value\n");
+ var_dump($info);
+ var_dump($new_info);
+ }
+
+ print "done!";
+?>
+--EXPECTF--
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_get_client_stats.phpt b/ext/mysqli/tests/mysqli_get_client_stats.phpt
new file mode 100644
index 0000000000..3bcc57a122
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_get_client_stats.phpt
@@ -0,0 +1,644 @@
+--TEST--
+mysqli_get_client_stats()
+--SKIPIF--
+<?PHP
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+if (!function_exists('mysqli_get_client_stats')) {
+ die("skip only available with mysqlnd");
+}
+?>
+--FILE--
+<?php
+ /*
+ TODO
+ no_index_used - difficult to simulate because server/engine dependent
+ bad_index_used - difficult to simulate because server/engine dependent
+ flushed_normal_sets
+ flushed_ps_sets
+ explicit_close
+ implicit_close
+ disconnect_close
+ in_middle_of_command_close
+ explicit_free_result
+ implicit_free_result
+ explicit_stmt_close
+ implicit_stmt_close
+ */
+
+ function mysqli_get_client_stats_assert_eq($field, $current, $expected, &$test_counter, $desc = "") {
+
+ $test_counter++;
+ if (is_array($current) && is_array($expected)) {
+ if ($current[$field] !== $expected[$field]) {
+ printf("[%03d] %s Expecting %s = %s/%s, got %s/%s\n",
+ $test_counter, $desc,
+ $field, $expected[$field], gettype($expected[$field]),
+ $current[$field], gettype($current[$field]));
+ }
+ } else if (is_array($current)) {
+ if ($current[$field] !== $expected) {
+ printf("[%03d] %s Expecting %s = %s/%s, got %s/%s\n",
+ $test_counter, $desc,
+ $field, $expected, gettype($expected),
+ $current[$field], gettype($current[$field]));
+ }
+ } else {
+ if ($current !== $expected) {
+ printf("[%03d] %s Expecting %s = %s/%s, got %s/%s\n",
+ $test_counter, $desc,
+ $field, $expected, gettype($expected),
+ $current, gettype($current));
+ }
+ }
+
+ }
+
+ function mysqli_get_client_stats_assert_gt($field, $current, $expected, &$test_counter, $desc = "") {
+
+ $test_counter++;
+ if (is_array($current) && is_array($expected)) {
+ if ($current[$field] <= $expected[$field]) {
+ printf("[%03d] %s Expecting %s = %s/%s, got %s/%s\n",
+ $test_counter, $desc,
+ $field, $expected[$field], gettype($expected[$field]),
+ $current[$field], gettype($current[$field]));
+ }
+ } else {
+ if ($current <= $expected) {
+ printf("[%03d] %s Expecting %s = %s/%s, got %s/%s\n",
+ $test_counter, $desc, $field,
+ $expected, gettype($expected),
+ $current, gettype($current));
+ }
+ }
+
+ }
+
+
+ $tmp = $link = null;
+ if (!is_null($tmp = @mysqli_get_client_stats($link)))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ include "connect.inc";
+
+ if (!is_array($info = mysqli_get_client_stats()) || empty($info))
+ printf("[002] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info);
+
+ var_dump($info);
+
+ if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
+ printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+ exit(1);
+ }
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[004] Expecting array/any_non_empty, got %s/%s\n", gettype($new_info), $new_info);
+
+ if (count($info) != count($new_info)) {
+ printf("[005] Expecting the same number of entries in the arrays\n");
+ var_dump($info);
+ var_dump($new_info);
+ }
+
+ $test_counter = 6;
+ mysqli_get_client_stats_assert_gt('bytes_sent', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_gt('bytes_received', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_gt('packets_sent', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_gt('packets_received', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_gt('protocol_overhead_in', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_gt('protocol_overhead_out', $new_info, $info, $test_counter);
+
+ // we assume the above as tested and in the following we check only those
+ mysqli_get_client_stats_assert_eq('result_set_queries', $new_info, $info, $test_counter);
+
+ /* we need to skip this test in unicode - we send set names utf8 during mysql_connect */
+ if (!ini_get("unicode.semantics"))
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_eq('buffered_sets', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_eq('unbuffered_sets', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_eq('ps_buffered_sets', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_eq('ps_unbuffered_sets', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_eq('rows_fetched_from_server', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_eq('rows_fetched_from_client', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_eq('rows_skipped', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_eq('copy_on_write_saved', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_eq('copy_on_write_performed', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_eq('command_buffer_too_small', $new_info, $info, $test_counter);
+ // This is not a mistake that I use string(1) "1" here! Andrey did not go for int to avoid any
+ // issues for very large numbers and 32 vs. 64bit systems
+ mysqli_get_client_stats_assert_eq('connect_success', $new_info, "1", $test_counter);
+ mysqli_get_client_stats_assert_eq('connect_failure', $new_info, $info, $test_counter);
+ mysqli_get_client_stats_assert_eq('connection_reused', $new_info, $info, $test_counter);
+
+ require('table.inc');
+ if (!is_array($info = mysqli_get_client_stats()) || empty($info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($info), $info);
+
+ //
+ // result_set_queries statistics
+ //
+
+ if (!$res = mysqli_query($link, "SELECT id, label FROM test"))
+ printf("[%03d] SELECT failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ $rows = 0;
+ while ($row = mysqli_fetch_assoc($res))
+ $rows++;
+
+ if (0 == $rows)
+ printf("[%03d] Expecting at least one result, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ mysqli_free_result($res);
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+
+ mysqli_get_client_stats_assert_eq('result_set_queries', $new_info, (string)($info['result_set_queries'] + 1), $test_counter);
+ $info = $new_info;
+
+ //
+ // non_result_set_queries - DDL
+ //
+
+ // CREATE TABLE, DROP TABLE
+ if (!mysqli_query($link, "DROP TABLE IF EXISTS non_result_set_queries_test"))
+ printf("[%03d] DROP TABLE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!mysqli_query($link, "CREATE TABLE non_result_set_queries_test(id INT) ENGINE = " . $engine)) {
+ printf("[%03d] CREATE TABLE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+ } else {
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 2), $test_counter, 'CREATE/DROP TABLE');
+ }
+ $info = $new_info;
+
+ // ALERT TABLE
+ if (!mysqli_query($link, "ALTER TABLE non_result_set_queries_test ADD label CHAR(1)")) {
+ printf("[%03d] ALTER TABLE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+ } else {
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'ALTER TABLE');
+ }
+ $info = $new_info;
+
+ // CREATE INDEX, DROP INDEX
+ if (!mysqli_query($link, "CREATE INDEX idx_1 ON non_result_set_queries_test(id)")) {
+ printf("[%03d] CREATE INDEX failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+ } else {
+
+ if (!mysqli_query($link, "DROP INDEX idx_1 ON non_result_set_queries_test"))
+ printf("[%03d] DROP INDEX failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 2), $test_counter, 'DROP INDEX');
+ }
+ $info = $new_info;
+
+ // RENAME TABLE
+ if (!mysqli_query($link, "DROP TABLE IF EXISTS client_stats_test"))
+ printf("[%03d] Cleanup, DROP TABLE client_stats_test failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ $info = $new_info;
+
+ if (!mysqli_query($link, "RENAME TABLE non_result_set_queries_test TO client_stats_test")) {
+ printf("[%03d] RENAME TABLE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ } else {
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'RENAME TABLE');
+
+ }
+ $info = $new_info;
+
+ if (!mysqli_query($link, "DROP TABLE IF EXISTS non_result_set_queries_test"))
+ printf("[%03d] Cleanup, DROP TABLE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!mysqli_query($link, "DROP TABLE IF EXISTS client_stats_test"))
+ printf("[%03d] Cleanup, DROP TABLE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ // Let's see if we have privileges for CREATE DATABASE
+ mysqli_query($link, "DROP DATABASE IF EXISTS mysqli_get_client_stats");
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ $info = $new_info;
+
+
+ // CREATE, ALTER, RENAME, DROP DATABASE
+ if (mysqli_query($link, "CREATE DATABASE mysqli_get_client_stats")) {
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE DATABASE');
+ $info = $new_info;
+
+ if (!mysqli_query($link, "ALTER DATABASE DEFAULT CHARACTER SET latin1"))
+ printf("[%03d] ALTER DATABASE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE DATABASE');
+ $info = $new_info;
+
+ if (mysqli_get_server_version($link) > 51700) {
+ if (!mysqli_query($link, "RENAME DATABASE mysqli_get_client_stats TO mysqli_get_client_stats_"))
+ printf("[%03d] RENAME DATABASE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE DATABASE');
+ $info = $new_info;
+ } else {
+ if (!mysqli_query($link, "CREATE DATABASE mysqli_get_client_stats_"))
+ printf("[%03d] CREATE DATABASE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ $info = $new_info;
+ }
+
+ if (!mysqli_query($link, "DROP DATABASE mysqli_get_client_stats_"))
+ printf("[%03d] DROP DATABASE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DROP DATABASE');
+ $info = $new_info;
+ }
+
+ // CREATE SERVER, ALTER SERVER, DROP SERVER
+ // We don't really try to use federated, we just want to see if the syntax works
+ mysqli_query($link, "DROP SERVER IF EXISTS myself");
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ $info = $new_info;
+
+ $sql = sprintf("CREATE SERVER myself FOREIGN DATA WRAPPER mysql OPTIONS (user '%s', password '%s', database '%s')",
+ $user, $passwd, $db);
+ if (mysqli_query($link, $sql)) {
+ // server knows about it
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE SERVER');
+ $info = $new_info;
+
+ if (!mysqli_query($link, sprintf("ALTER SERVER myself OPTIONS(user '%s_')", $user)))
+ printf("[%03d] ALTER SERVER failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'ALTER SERVER');
+ $info = $new_info;
+
+ if (!mysqli_query($link, "DROP SERVER myself"))
+ printf("[%03d] DROP SERVER failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DROP SERVER');
+ $info = $new_info;
+ }
+
+ /*
+ We don't test the NDB ones.
+ 13.1. Data Definition Statements
+ 13.1.3. ALTER LOGFILE GROUP Syntax
+ 13.1.4. ALTER TABLESPACE Syntax
+ 13.1.9. CREATE LOGFILE GROUP Syntax
+ 13.1.10. CREATE TABLESPACE Syntax
+ 13.1.15. DROP LOGFILE GROUP Syntax
+ 13.1.16. DROP TABLESPACE Syntax
+ */
+
+ //
+ // DML
+ //
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ $info = $new_info;
+
+ if (!mysqli_query($link, "INSERT INTO test(id) VALUES (100)"))
+ printf("[%03d] INSERT failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'INSERT');
+ $info = $new_info;
+
+ if (!mysqli_query($link, "UPDATE test SET label ='z' WHERE id = 100"))
+ printf("[%03d] UPDATE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'UPDATE');
+ $info = $new_info;
+
+ if (!mysqli_query($link, "REPLACE INTO test(id, label) VALUES (100, 'b')"))
+ printf("[%03d] INSERT failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'REPLACE');
+ $info = $new_info;
+
+ // NOTE: this will NOT update dbl_ddls counter
+ if (!$res = mysqli_query($link, "SELECT id, label FROM test WHERE id = 100"))
+ printf("[%03d] SELECT@dml failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+ mysqli_free_result($res);
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, $info, $test_counter, 'SELECT@dml');
+ $info = $new_info;
+
+ if (!mysqli_query($link, "DELETE FROM test WHERE id = 100"))
+ printf("[%03d] DELETE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DELETE');
+ $info = $new_info;
+
+ if (!$res = mysqli_query($link, "TRUNCATE TABLE test"))
+ printf("[%03d] TRUNCATE failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'TRUNCATE');
+ $info = $new_info;
+
+ $file = tempnam(sys_get_temp_dir(), 'mysqli_test');
+ if ($fp = fopen($file, 'w')) {
+ @fwrite($fp, '1;"a"');
+ fclose($fp);
+ chmod($file, 0644);
+ $sql = sprintf('LOAD DATA LOCAL INFILE "%s" INTO TABLE test', mysqli_real_escape_string($link, $file));
+ if (mysqli_query($link, $sql)) {
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'LOAD DATA LOCAL');
+ $info = $new_info;
+ }
+ unlink($file);
+ }
+
+ /*
+ We skip those:
+ 13.2. Data Manipulation Statements
+ 13.2.2. DO Syntax
+ 13.2.3. HANDLER Syntax
+ 13.2.5. LOAD DATA INFILE Syntax
+ */
+ mysqli_query($link, "DELETE FROM test");
+ if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (1, 'a'), (2, 'b')"))
+ printf("[%03d] Cannot insert new records, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id"))
+ printf("[%03d] Cannot SELECT with mysqli_real_query(), [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_object($res = mysqli_use_result($link)))
+ printf("[%03d] mysqli_use_result() failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ while ($row = mysqli_fetch_assoc($res))
+ ;
+ mysqli_free_result($res);
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('unbuffered_sets', $new_info, (string)($info['unbuffered_sets'] + 1), $test_counter, 'mysqli_use_result()');
+ $info = $new_info;
+
+ if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id"))
+ printf("[%03d] Cannot SELECT with mysqli_real_query() II, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ if (!is_object($res = mysqli_store_result($link)))
+ printf("[%03d] mysqli_use_result() failed, [%d] %s\n", ++$test_counter,
+ mysqli_errno($link), mysqli_error($link));
+
+ while ($row = mysqli_fetch_assoc($res))
+ ;
+ mysqli_free_result($res);
+ if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
+ printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
+ ++$test_counter, gettype($new_info), $new_info);
+ mysqli_get_client_stats_assert_eq('buffered_sets', $new_info, (string)($info['buffered_sets'] + 1), $test_counter, 'mysqli_use_result()');
+ $info = $new_info;
+
+
+ /*
+ no_index_used
+ bad_index_used
+ flushed_normal_sets
+ flushed_ps_sets
+ explicit_close
+ implicit_close
+ disconnect_close
+ in_middle_of_command_close
+ explicit_free_result
+ implicit_free_result
+ explicit_stmt_close
+ implicit_stmt_close
+ */
+
+ print "done!";
+?>
+--EXPECTF--
+array(33) {
+ ["bytes_sent"]=>
+ string(1) "0"
+ ["bytes_received"]=>
+ string(1) "0"
+ ["packets_sent"]=>
+ string(1) "0"
+ ["packets_received"]=>
+ string(1) "0"
+ ["protocol_overhead_in"]=>
+ string(1) "0"
+ ["protocol_overhead_out"]=>
+ string(1) "0"
+ ["result_set_queries"]=>
+ string(1) "0"
+ ["non_result_set_queries"]=>
+ string(1) "0"
+ ["no_index_used"]=>
+ string(1) "0"
+ ["bad_index_used"]=>
+ string(1) "0"
+ ["buffered_sets"]=>
+ string(1) "0"
+ ["unbuffered_sets"]=>
+ string(1) "0"
+ ["ps_buffered_sets"]=>
+ string(1) "0"
+ ["ps_unbuffered_sets"]=>
+ string(1) "0"
+ ["flushed_normal_sets"]=>
+ string(1) "0"
+ ["flushed_ps_sets"]=>
+ string(1) "0"
+ ["rows_fetched_from_server"]=>
+ string(1) "0"
+ ["rows_fetched_from_client"]=>
+ string(1) "0"
+ ["rows_skipped"]=>
+ string(1) "0"
+ ["copy_on_write_saved"]=>
+ string(1) "0"
+ ["copy_on_write_performed"]=>
+ string(1) "0"
+ ["command_buffer_too_small"]=>
+ string(1) "0"
+ ["connect_success"]=>
+ string(1) "0"
+ ["connect_failure"]=>
+ string(1) "0"
+ ["connection_reused"]=>
+ string(1) "0"
+ ["explicit_close"]=>
+ string(1) "0"
+ ["implicit_close"]=>
+ string(1) "0"
+ ["disconnect_close"]=>
+ string(1) "0"
+ ["in_middle_of_command_close"]=>
+ string(1) "0"
+ ["explicit_free_result"]=>
+ string(1) "0"
+ ["implicit_free_result"]=>
+ string(1) "0"
+ ["explicit_stmt_close"]=>
+ string(1) "0"
+ ["implicit_stmt_close"]=>
+ string(1) "0"
+}
+done!
+--UEXPECTF--
+array(33) {
+ [u"bytes_sent"]=>
+ unicode(1) "0"
+ [u"bytes_received"]=>
+ unicode(1) "0"
+ [u"packets_sent"]=>
+ unicode(1) "0"
+ [u"packets_received"]=>
+ unicode(1) "0"
+ [u"protocol_overhead_in"]=>
+ unicode(1) "0"
+ [u"protocol_overhead_out"]=>
+ unicode(1) "0"
+ [u"result_set_queries"]=>
+ unicode(1) "0"
+ [u"non_result_set_queries"]=>
+ unicode(1) "0"
+ [u"no_index_used"]=>
+ unicode(1) "0"
+ [u"bad_index_used"]=>
+ unicode(1) "0"
+ [u"buffered_sets"]=>
+ unicode(1) "0"
+ [u"unbuffered_sets"]=>
+ unicode(1) "0"
+ [u"ps_buffered_sets"]=>
+ unicode(1) "0"
+ [u"ps_unbuffered_sets"]=>
+ unicode(1) "0"
+ [u"flushed_normal_sets"]=>
+ unicode(1) "0"
+ [u"flushed_ps_sets"]=>
+ unicode(1) "0"
+ [u"rows_fetched_from_server"]=>
+ unicode(1) "0"
+ [u"rows_fetched_from_client"]=>
+ unicode(1) "0"
+ [u"rows_skipped"]=>
+ unicode(1) "0"
+ [u"copy_on_write_saved"]=>
+ unicode(1) "0"
+ [u"copy_on_write_performed"]=>
+ unicode(1) "0"
+ [u"command_buffer_too_small"]=>
+ unicode(1) "0"
+ [u"connect_success"]=>
+ unicode(1) "0"
+ [u"connect_failure"]=>
+ unicode(1) "0"
+ [u"connection_reused"]=>
+ unicode(1) "0"
+ [u"explicit_close"]=>
+ unicode(1) "0"
+ [u"implicit_close"]=>
+ unicode(1) "0"
+ [u"disconnect_close"]=>
+ unicode(1) "0"
+ [u"in_middle_of_command_close"]=>
+ unicode(1) "0"
+ [u"explicit_free_result"]=>
+ unicode(1) "0"
+ [u"implicit_free_result"]=>
+ unicode(1) "0"
+ [u"explicit_stmt_close"]=>
+ unicode(1) "0"
+ [u"implicit_stmt_close"]=>
+ unicode(1) "0"
+}
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_stmt_get_result.phpt b/ext/mysqli/tests/mysqli_stmt_get_result.phpt
new file mode 100644
index 0000000000..089628df78
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_stmt_get_result.phpt
@@ -0,0 +1,208 @@
+--TEST--
+mysqli_stmt_get_result()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+
+if (!function_exists('mysqli_stmt_get_result'))
+ die('skip mysqli_stmt_get_result not available');
+?>
+--FILE--
+<?php
+ /*
+ NOTE: no datatype tests here! This is done by
+ mysqli_stmt_bind_result.phpt already. Restrict
+ this test case to the basics.
+ */
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_stmt_get_result()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_stmt_get_result($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+
+ if (!$stmt = mysqli_stmt_init($link))
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ // stmt object status test
+ if (NULL !== ($tmp = mysqli_stmt_fetch($stmt)))
+ printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2"))
+ printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ // FIXME - different versions return different values ?!
+ if ((NULL !== ($tmp = mysqli_stmt_get_result($stmt))) && (false !== $tmp))
+ printf("[006] Expecting NULL or boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ if (!mysqli_stmt_execute($stmt))
+ printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!mysqli_stmt_store_result($stmt))
+ printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (is_object($tmp = mysqli_stmt_store_result($stmt)))
+ printf("[009] non-object, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ mysqli_stmt_close($stmt);
+
+ if (!$stmt = mysqli_stmt_init($link))
+ printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ // stmt object status test
+ if (NULL !== ($tmp = mysqli_stmt_fetch($stmt)))
+ printf("[011] Expecting NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2"))
+ printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ // FIXME - different versions return different values ?!
+ if ((NULL !== ($tmp = mysqli_stmt_get_result($stmt))) && (false !== $tmp))
+ printf("[013] Expecting NULL or boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ if (!mysqli_stmt_execute($stmt))
+ printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!is_object($tmp = mysqli_stmt_get_result($stmt)))
+ printf("[016] NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ mysqli_free_result($tmp);
+ mysqli_stmt_close($stmt);
+
+ if (!$stmt = mysqli_stmt_init($link))
+ printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ // stmt object status test
+ if (NULL !== ($tmp = mysqli_stmt_get_result($stmt)))
+ printf("[018] Expecting NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2"))
+ printf("[019] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (false !== ($tmp = mysqli_stmt_get_result($stmt)))
+ printf("[020] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ if (!mysqli_stmt_execute($stmt))
+ printf("[023] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!is_object($tmp = mysqli_stmt_get_result($stmt)))
+ printf("[024] Expecting object, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ if (false !== ($tmp = mysqli_stmt_fetch($stmt)))
+ printf("[025] false, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) {
+ printf("[026] [%d] [%s]\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ printf("[027] [%d] [%s]\n", mysqli_errno($link), mysqli_error($link));
+ printf("[028] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+ }
+
+ if (false !== ($tmp = mysqli_stmt_fetch($stmt)))
+ printf("[029] false, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ mysqli_stmt_close($stmt);
+
+ if (!$stmt = mysqli_stmt_init($link))
+ printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2"))
+ printf("[033] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!mysqli_stmt_execute($stmt))
+ printf("[034] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ $id = NULL;
+ $label = NULL;
+ if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label)))
+ printf("[035] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ if (!is_object($tmp = $result = mysqli_stmt_get_result($stmt)))
+ printf("[036] Expecting array, got %s/%s, [%d] %s\n",
+ gettype($tmp), var_export($tmp, 1),
+ mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (false !== ($tmp = mysqli_stmt_fetch($stmt)))
+ printf("[037] Expecting boolean/false, got %s/%s, [%d] %s\n",
+ gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ printf("[038] [%d] [%s]\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ printf("[039] [%d] [%s]\n", mysqli_errno($link), mysqli_error($link));
+ while ($row = mysqli_fetch_assoc($result)) {
+ var_dump($row);
+ }
+ mysqli_free_result($result);
+
+ if (!mysqli_kill($link, mysqli_thread_id($link)))
+ printf("[040] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (false !== ($tmp = mysqli_stmt_get_result($stmt)))
+ printf("[041] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ mysqli_stmt_close($stmt);
+
+ if (NULL !== ($tmp = mysqli_stmt_fetch($stmt)))
+ printf("[042] Expecting NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
+
+ mysqli_close($link);
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt
+ in %s on line %d
+
+Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt
+ in %s on line %d
+
+Warning: mysqli_stmt_get_result(): invalid object or resource mysqli_stmt
+ in %s on line %d
+[038] [2014] [Commands out of sync; you can't run this command now]
+[039] [0] []
+array(2) {
+ ["id"]=>
+ int(1)
+ ["label"]=>
+ %s(1) "a"
+}
+array(2) {
+ ["id"]=>
+ int(2)
+ ["label"]=>
+ %s(1) "b"
+}
+
+Warning: mysqli_stmt_fetch(): Couldn't fetch mysqli_stmt in %s on line %d
+done!
+--UEXPECTF--
+Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt
+ in %s on line %d
+
+Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt
+ in %s on line %d
+
+Warning: mysqli_stmt_get_result(): invalid object or resource mysqli_stmt
+ in %s on line %d
+[038] [2014] [Commands out of sync; you can't run this command now]
+[039] [0] []
+array(2) {
+ [%s"id"]=>
+ int(1)
+ [%s"label"]=>
+ %s(1) "a"
+}
+array(2) {
+ [%s"id"]=>
+ int(2)
+ [%s"label"]=>
+ %s(1) "b"
+}
+
+Warning: mysqli_stmt_fetch(): Couldn't fetch mysqli_stmt in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_stmt_get_result2.phpt b/ext/mysqli/tests/mysqli_stmt_get_result2.phpt
new file mode 100644
index 0000000000..9128390573
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_stmt_get_result2.phpt
@@ -0,0 +1,187 @@
+--TEST--
+mysqli_stmt_get_result()
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+<?php require_once('skipifemb.inc'); ?>
+<?php if (!function_exists('mysqli_stmt_get_result')) die('skip mysqli_stmt_get_result not available')?>
+--FILE--
+<?php
+ /*
+ NOTE: no datatype tests here! This is done by
+ mysqli_stmt_bind_result.phpt already. Restrict
+ this test case to the basics.
+ */
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_stmt_get_result()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_stmt_get_result($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+
+ if (!$stmt = mysqli_stmt_init($link))
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (!is_null($tmp = @mysqli_stmt_get_result($stmt, "foo")))
+ printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 1"))
+ printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!mysqli_stmt_execute($stmt))
+ printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) {
+ printf("[007] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+ while ($row = mysqli_fetch_assoc($res))
+ var_dump($row);
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+
+ if (false !== ($res = mysqli_stmt_get_result($stmt))) {
+ printf("[008] boolean/false got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ mysqli_stmt_execute($stmt);
+ if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) {
+ printf("[009] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+ while ($row = mysqli_fetch_assoc($res))
+ var_dump($row);
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+
+ mysqli_stmt_close($stmt);
+
+ if (!($stmt = mysqli_stmt_init($link)) ||
+ !mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2") ||
+ !mysqli_stmt_execute($stmt))
+ printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ $id = $label = null;
+ if (!mysqli_stmt_bind_result($stmt, $id, $label))
+ printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!mysqli_stmt_fetch($stmt))
+ printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (false !== ($res = mysqli_stmt_get_result($stmt))) {
+ printf("[013] boolean/false got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ mysqli_stmt_close($stmt);
+
+ if (!($stmt = mysqli_stmt_init($link)) ||
+ !mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2") ||
+ !mysqli_stmt_execute($stmt))
+ printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) {
+ printf("[015] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ $id = $label = null;
+ if (!mysqli_stmt_bind_result($stmt, $id, $label))
+ printf("[016] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!mysqli_stmt_fetch($stmt))
+ printf("[017] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ mysqli_stmt_close($stmt);
+
+ if (!($stmt = mysqli_stmt_init($link)) ||
+ !mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2") ||
+ !mysqli_stmt_execute($stmt))
+ printf("[018] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) {
+ printf("[019] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ $id = $label = null;
+ if (!mysqli_stmt_bind_result($stmt, $id, $label))
+ printf("[020] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ $row = mysqli_fetch_assoc($res);
+ if (NULL !== $id || NULL !== $label)
+ printf("[021] Bound variables should not have been set\n");
+ mysqli_free_result($res);
+
+ mysqli_stmt_close($stmt);
+
+ if (!($stmt = mysqli_stmt_init($link)) ||
+ !mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2") ||
+ !mysqli_stmt_execute($stmt))
+ printf("[022] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) {
+ printf("[023] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+ if (!in_array($res->type, array(MYSQLI_STORE_RESULT, MYSQLI_USE_RESULT))) {
+ printf("[024] Unknown result set type %s\n", $res->type);
+ }
+ if ($res->type !== MYSQLI_STORE_RESULT)
+ printf("[025] Expecting int/%d got %s/%s", MYSQLI_STORE_RESULT, gettype($res->type), $res->type);
+
+ mysqli_free_result($res);
+ mysqli_stmt_close($stmt);
+ mysqli_close($link);
+
+ if (NULL !== ($res = mysqli_stmt_get_result($stmt))) {
+ printf("[022] Expecting NULL got %s/%s\n",
+ gettype($res), $res);
+ }
+
+ print "done!";
+?>
+--EXPECTF--
+array(2) {
+ ["id"]=>
+ int(1)
+ ["label"]=>
+ string(1) "a"
+}
+NULL
+array(2) {
+ ["id"]=>
+ int(1)
+ ["label"]=>
+ string(1) "a"
+}
+NULL
+[017] [2014] Commands out of sync; you can't run this command now
+
+Warning: mysqli_stmt_get_result(): Couldn't fetch mysqli_stmt in %s on line %d
+done!
+--UEXPECTF--
+array(2) {
+ [u"id"]=>
+ int(1)
+ [u"label"]=>
+ unicode(1) "a"
+}
+NULL
+array(2) {
+ [u"id"]=>
+ int(1)
+ [u"label"]=>
+ unicode(1) "a"
+}
+NULL
+[017] [2014] Commands out of sync; you can't run this command now
+
+Warning: mysqli_stmt_get_result(): Couldn't fetch mysqli_stmt in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt
new file mode 100644
index 0000000000..5f3b552569
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt
@@ -0,0 +1,128 @@
+--TEST--
+Fetching BIT column values using the PS API
+--SKIPIF--
+<?php
+ require_once('skipif.inc');
+ require_once('skipifemb.inc');
+
+ if (!function_exists('mysqli_stmt_get_result'))
+ die("skip mysqli_stmt_get_result() not available");
+
+ require_once('connect.inc');
+ require_once('table.inc');
+ if (mysqli_get_server_version($link) < 50003)
+ // b'001' syntax not supported before 5.0.3
+ die("skip Syntax used for test not supported with MySQL Server before 5.0.3");
+ if (!$IS_MYSQLND && (mysqli_get_client_version() < 50003))
+ // better don't trust libmysql before 5.0.3
+ die("skip Syntax used for test not supported with MySQL Server before 5.0.3");
+?>
+--FILE--
+<?php
+ require('connect.inc');
+
+ function dec32bin($dec, $bits) {
+
+ $maxval = pow(2, $bits);
+ $bin = '';
+ for ($bitval = $maxval; $bitval >= 1; $bitval = $bitval / 2) {
+ if (($dec / $bitval) >= 1) {
+ $bin .= '1';
+ $dec -= $bitval;
+ } else {
+ $bin .= '0';
+ }
+ }
+ return $bin;
+ }
+
+ if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+
+ for ($bits = 1; $bits <= 46; $bits++) {
+ if (1 == $bits)
+ $max_value = 1;
+ else
+ $max_value = pow(2, $bits) - 1;
+
+ if (!mysqli_query($link, "DROP TABLE IF EXISTS test") ||
+ !mysqli_query($link, $sql = sprintf('CREATE TABLE test(id BIGINT UNSIGNED, bit_value BIT(%d) NOT NULL, bit_null BIT(%d) DEFAULT NULL) ENGINE="%s"', $bits, $bits, $engine)))
+ printf("[002 - %d] [%d] %s\n",$bits, mysqli_errno($link), mysqli_error($link));
+
+ if (!$stmt = mysqli_stmt_init($link))
+ printf("[003 - %d] [%d] %s\n", $bits, mysqli_errno($link), mysqli_error($link));
+
+ $tests = 0;
+ $rand_max = mt_getrandmax();
+ while ($tests < 10) {
+
+ $tests++;
+ if (1 == $tests)
+ $value = 0;
+ else if (2 == $tests)
+ $value = $max_value;
+ else {
+ if ($max_value > $rand_max) {
+ $max_loops = floor($max_value/$rand_max);
+ $num_loops = mt_rand(1, $max_loops);
+ $value = 0;
+ for ($i = 0; $i < $num_loops; $i++)
+ $value += mt_rand(0, $rand_max);
+ } else {
+ $value = mt_rand(0, $max_value);
+ }
+ }
+
+ $bin = ($bits < 32) ? decbin($value) : dec32bin($value, $bits);
+ $sql = sprintf("INSERT INTO test(id, bit_value) VALUES (%s, b'%s')", $value, $bin);
+ for ($i = 0; ($i < strlen($bin)) && ($bin[$i] == '0'); $i++)
+ ;
+ $bin2 = substr($bin, $i, strlen($bin));
+
+ if (!mysqli_stmt_prepare($stmt, $sql) ||
+ !mysqli_stmt_execute($stmt))
+ printf("[004 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ $sql = sprintf("SELECT bin(bit_value) AS _bin, id, bit_value, bit_null FROM test WHERE id = %s", $value);
+ if (!mysqli_stmt_prepare($stmt, $sql) ||
+ !mysqli_stmt_execute($stmt))
+ printf("[005 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!$res = mysqli_stmt_get_result($stmt))
+ printf("[006 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!$row = mysqli_fetch_assoc($res))
+ printf("[007 - %d] [%d] %s\n", $bits, mysqli_errno($link), mysqli_error($link));
+ mysqli_free_result($res);
+
+ if (($value != $row['id']) || (($bin != $row['_bin']) && ($bin2 != $row['_bin']))) {
+ debug_zval_dump($row);
+ printf("[008 - %d] Insert of %s in BIT(%d) column might have failed. id = %s, bin = %s (%s/%s)\n",
+ $bits, $value, $bits, $row['id'], $row['_bin'], $bin, $bin2);
+ break;
+ }
+ if ($value != $row['bit_value']) {
+ debug_zval_dump($row);
+ printf("%10s %64s\n%10s %64s\n", '_bin', $row['_bin'], 'insert', $bin);
+ printf("[009 - %d] Expecting %s got %s\n", $bits, $value, $row['bit_value']);
+ break;
+ }
+
+ if (null !== $row['bit_null']) {
+ debug_zval_dump($row);
+ printf("[010 - %d] Expecting null got %s/%s\n", $bits, gettype($row['bit_value']), $row['bit_value']);
+ break;
+ }
+
+ }
+
+ mysqli_stmt_close($stmt);
+
+ }
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_field_count.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_field_count.phpt
new file mode 100644
index 0000000000..0b0b2d7265
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_stmt_get_result_field_count.phpt
@@ -0,0 +1,46 @@
+--TEST--
+mysqli_stmt_get_result() - meta data, field_count()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+
+if (!function_exists('mysqli_stmt_get_result'))
+ die('skip mysqli_stmt_get_result not available')
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ require('table.inc');
+
+ if (!$stmt = mysqli_stmt_init($link))
+ printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 3"))
+ printf("[002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!mysqli_stmt_execute($stmt))
+ printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) {
+ printf("[004] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ if (!is_object($res_meta = mysqli_stmt_result_metadata($stmt)) ||
+ 'mysqli_result' != get_class($res_meta)) {
+ printf("[005] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ printf("%s %s\n",
+ $res_meta->field_count,
+ $res->field_count);
+
+ mysqli_stmt_close($stmt);
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+2 2
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt
new file mode 100644
index 0000000000..132450e989
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt
@@ -0,0 +1,259 @@
+--TEST--
+mysqli_stmt_get_result() - meta data
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+
+if (!function_exists('mysqli_stmt_get_result'))
+ die('skip mysqli_stmt_get_result not available');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ require('table.inc');
+
+ if (!$stmt = mysqli_stmt_init($link))
+ printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 3"))
+ printf("[002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!mysqli_stmt_execute($stmt))
+ printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) {
+ printf("[004] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ if (!is_object($res_meta = mysqli_stmt_result_metadata($stmt)) ||
+ 'mysqli_result' != get_class($res_meta)) {
+ printf("[005] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ var_dump(mysqli_fetch_assoc($res));
+ var_dump(mysqli_fetch_assoc($res_meta));
+
+ mysqli_free_result($res);
+ mysqli_free_result($res_meta);
+ mysqli_stmt_close($stmt);
+
+ // !mysqli_stmt_prepare($stmt, "SELECT id, label, id + 1 as _id, concat(label, '_') _label FROM test as _test ORDER BY id ASC LIMIT 3") ||
+ if (!($stmt = mysqli_stmt_init($link)) ||
+ !mysqli_stmt_prepare($stmt, "SELECT id , label, id + 1 AS _id, label AS _label, null AS _null, CONCAT(label, '_') _label_concat FROM test _test ORDER BY id ASC LIMIT 3") ||
+ !mysqli_stmt_execute($stmt))
+ printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) {
+ printf("[007] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ if (!is_object($res_meta = mysqli_stmt_result_metadata($stmt)) ||
+ 'mysqli_result' != get_class($res_meta)) {
+ printf("[008] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ if (($tmp1 = mysqli_num_fields($res)) !== ($tmp2 = mysqli_num_fields($res_meta))) {
+ printf("[009] %s/%s !== %s/%s\n", gettype($tmp1), $tmp1, gettype($tmp2), $tmp2);
+ }
+
+ /*
+ if (($tmp1 = mysqli_field_count($link)) !== ($tmp2 = $res->field_count()))
+ printf("[010] %s/%s !== %s/%s\n", gettype($tmp1), $tmp1, gettype($tmp2), $tmp2);
+
+ if (($tmp1 = $res_meta->field_count()) !== $tmp2)
+ printf("[011] %s/%s !== %s/%s\n", gettype($tmp1), $tmp1, gettype($tmp2), $tmp2);
+ */
+
+ if (($tmp1 = mysqli_field_tell($res)) !== ($tmp2 = $res_meta->current_field))
+ printf("[012] %s/%s !== %s/%s\n", gettype($tmp1), $tmp1, gettype($tmp2), $tmp2);
+
+ if (0 !== $tmp1)
+ printf("[013] Expecting int/0 got %s/%s\n", gettype($tmp1), $tmp1);
+
+ $fields = array();
+ while ($info = $res->fetch_field())
+ $fields['res'][] = $info;
+ var_dump($info);
+ while ($info = $res_meta->fetch_field())
+ $fields['meta'][] = $info;
+ var_dump($info);
+ $fields['all_res'] = $res->fetch_fields();
+ $fields['all_meta'] = $res_meta->fetch_fields();
+
+ if (count($fields['res']) != count($fields['meta'])) {
+ printf("[014] stmt_get_result indicates %d fields, stmt_result_metadata indicates %d fields\n",
+ count($fields['res']),
+ count($fields['meta']));
+ }
+
+ foreach ($fields['res'] as $k => $info) {
+ printf("%s\n", $info->name);
+ if ($info->name !== $fields['meta'][$k]->name)
+ printf("[015 - %d] Expecting name %s/%s got %s/%s\n",
+ $k, gettype($info->name), $info->name, gettype($fields['meta'][$k]->name), $fields['meta'][$k]->name);
+
+ if ($info->orgname !== $fields['meta'][$k]->orgname)
+ printf("[016 - %d] Expecting orgname %s/%s got %s/%s\n",
+ $k, gettype($info->orgname), $info->orgname, gettype($fields['meta'][$k]->orgname), $fields['meta'][$k]->orgname);
+
+ if ($info->table !== $fields['meta'][$k]->table)
+ printf("[017 - %d] Expecting table %s/%s got %s/%s\n",
+ $k, gettype($info->table), $info->table, gettype($fields['meta'][$k]->table), $fields['meta'][$k]->table);
+
+ if ($info->orgtable !== $fields['meta'][$k]->orgtable)
+ printf("[018 - %d] Expecting orgtable %s/%s got %s/%s\n",
+ $k, gettype($info->orgtable), $info->orgtable, gettype($fields['meta'][$k]->orgtable), $fields['meta'][$k]->orgtable);
+
+ if ($info->def !== $fields['meta'][$k]->def)
+ printf("[019 - %d] Expecting def %s/%s got %s/%s\n",
+ $k, gettype($info->def), $info->def, gettype($fields['meta'][$k]->def), $fields['meta'][$k]->def);
+/*
+ if ($info->max_length !== $fields['meta'][$k]->max_length)
+ printf("[020 - %d] Expecting max_length %s/%s got %s/%s\n",
+ $k, gettype($info->max_length), $info->max_length, gettype($fields['meta'][$k]->max_length), $fields['meta'][$k]->max_length);
+*/
+ if ($info->length !== $fields['meta'][$k]->length)
+ printf("[021 - %d] Expecting length %s/%s got %s/%s\n",
+ $k, gettype($info->length), $info->length, gettype($fields['meta'][$k]->length), $fields['meta'][$k]->length);
+
+ if ($info->charsetnr !== $fields['meta'][$k]->charsetnr)
+ printf("[022 - %d] Expecting charsetnr %s/%s got %s/%s\n",
+ $k, gettype($info->charsetnr), $info->charsetnr, gettype($fields['meta'][$k]->charsetnr), $fields['meta'][$k]->charsetnr);
+
+ if ($info->flags !== $fields['meta'][$k]->flags)
+ printf("[023 - %d] Expecting flags %s/%s got %s/%s\n",
+ $k, gettype($info->flags), $info->flags, gettype($fields['meta'][$k]->flags), $fields['meta'][$k]->flags);
+
+ if ($info->type !== $fields['meta'][$k]->type)
+ printf("[024 - %d] Expecting type %s/%s got %s/%s\n",
+ $k, gettype($info->type), $info->type, gettype($fields['meta'][$k]->type), $fields['meta'][$k]->type);
+
+ if ($info->decimals !== $fields['meta'][$k]->decimals)
+ printf("[025 - %d] Expecting decimals %s/%s got %s/%s\n",
+ $k, getdecimals($info->decimals), $info->decimals, getdecimals($fields['meta'][$k]->decimals), $fields['meta'][$k]->decimals);
+
+ /* Make them equal for the check */
+ $tmp = $fields['all_res'][$k]->max_length;
+ $fields['all_res'][$k]->max_length = $fields['all_meta'][$k]->max_length;
+
+ if ($fields['all_res'][$k] != $fields['all_meta'][$k]) {
+ printf("[026 - %d] fetch_fields() seems to have returned different data, dumping\n", $k);
+ var_dump($fields['all_res'][$k]);
+ var_dump($fields['all_meta'][$k]);
+ }
+ $fields['all_res'][$k]->max_length = $tmp;
+ }
+
+ $num = count($fields['res']);
+ for ($i = 0; $i < 100; $i++) {
+ $pos = mt_rand(-1, $num + 1);
+ if ($pos >= 0 && $pos < $num) {
+ if (true !== mysqli_field_seek($res, $pos))
+ printf("[027] field_seek(res) failed\n");
+ if (true !== $res_meta->field_seek($pos))
+ printf("[028] field_seek(res__meta) failed\n");
+
+ $tmp1 = $res->fetch_field();
+ $tmp2 = mysqli_fetch_field($res_meta);
+ $tmp2->max_length = $tmp1->max_length;
+ if ($tmp1 != $tmp2) {
+ printf("[029] Field info differs, dumping data\n");
+ var_dump($tmp1);
+ var_dump($tmp2);
+ }
+
+ if ($tmp1 != $fields['res'][$pos]) {
+ printf("[030] Field info differs, dumping data\n");
+ var_dump($tmp1);
+ var_dump($fields['res'][$pos]);
+ }
+
+ $pos++;
+ if ($pos !== ($tmp = mysqli_field_tell($res)))
+ printf("[031] Expecting %s/%s got %s/%s\n",
+ gettype($pos), $pos, gettype($tmp), $tmp);
+
+ if ($pos !== ($tmp = mysqli_field_tell($res_meta)))
+ printf("[032] Expecting %s/%s got %s/%s\n",
+ gettype($pos), $pos, gettype($tmp), $tmp);
+ } else {
+
+ if (false !== @mysqli_field_seek($res, $pos))
+ printf("[033] field_seek(%d) did not fail\n", $pos);
+ if (false !== @mysqli_field_seek($res_meta, $pos))
+ printf("[034] field_seek(%d) did not fail\n", $pos);
+ }
+ }
+
+ $res->free_result();
+ mysqli_free_result($res_meta);
+
+ var_dump(mysqli_fetch_field($res));
+
+ mysqli_stmt_close($stmt);
+
+ var_dump(mysqli_fetch_field($res));
+
+ mysqli_close($link);
+
+ var_dump(mysqli_fetch_field($res));
+
+ print "done!";
+?>
+--EXPECTF--
+array(2) {
+ ["id"]=>
+ int(1)
+ ["label"]=>
+ string(1) "a"
+}
+NULL
+bool(false)
+bool(false)
+id
+label
+_id
+_label
+_null
+_label_concat
+
+Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+
+Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+
+Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+done!
+--UEXPECTF--
+array(2) {
+ [u"id"]=>
+ int(1)
+ [u"label"]=>
+ unicode(1) "a"
+}
+NULL
+bool(false)
+bool(false)
+id
+label
+_id
+_label
+_null
+_label_concat
+
+Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+
+Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+
+Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt
new file mode 100644
index 0000000000..61a0608a9e
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt
@@ -0,0 +1,236 @@
+--TEST--
+mysqli_stmt_get_result() - meta data, field info
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+
+if (!function_exists('mysqli_stmt_get_result'))
+ die('skip mysqli_stmt_get_result not available');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ require('table.inc');
+
+ if (!($stmt = mysqli_stmt_init($link)) ||
+ !mysqli_stmt_prepare($stmt, "SELECT id, label, id + 1 as _id, concat(label, '_') ___label FROM test ORDER BY id ASC LIMIT 3") ||
+ !mysqli_stmt_execute($stmt))
+ printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) {
+ printf("[007] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ if (!is_object($res_meta = mysqli_stmt_result_metadata($stmt)) ||
+ 'mysqli_result' != get_class($res_meta)) {
+ printf("[008] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ $fields = array();
+ while ($info = $res->fetch_field()) {
+ var_dump($info);
+ }
+
+ mysqli_stmt_close($stmt);
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+object(stdClass)#%d (11) {
+ ["name"]=>
+ string(2) "id"
+ ["orgname"]=>
+ string(2) "id"
+ ["table"]=>
+ string(4) "test"
+ ["orgtable"]=>
+ string(4) "test"
+ ["def"]=>
+ string(0) ""
+ ["max_length"]=>
+ int(0)
+ ["length"]=>
+ int(11)
+ ["charsetnr"]=>
+ int(63)
+ ["flags"]=>
+ int(49155)
+ ["type"]=>
+ int(3)
+ ["decimals"]=>
+ int(0)
+}
+object(stdClass)#%d (11) {
+ ["name"]=>
+ string(5) "label"
+ ["orgname"]=>
+ string(5) "label"
+ ["table"]=>
+ string(4) "test"
+ ["orgtable"]=>
+ string(4) "test"
+ ["def"]=>
+ string(0) ""
+ ["max_length"]=>
+ int(1)
+ ["length"]=>
+ int(1)
+ ["charsetnr"]=>
+ int(8)
+ ["flags"]=>
+ int(0)
+ ["type"]=>
+ int(254)
+ ["decimals"]=>
+ int(0)
+}
+object(stdClass)#%d (11) {
+ ["name"]=>
+ string(3) "_id"
+ ["orgname"]=>
+ string(0) ""
+ ["table"]=>
+ string(0) ""
+ ["orgtable"]=>
+ string(0) ""
+ ["def"]=>
+ string(0) ""
+ ["max_length"]=>
+ int(0)
+ ["length"]=>
+ int(17)
+ ["charsetnr"]=>
+ int(63)
+ ["flags"]=>
+ int(32897)
+ ["type"]=>
+ int(8)
+ ["decimals"]=>
+ int(0)
+}
+object(stdClass)#%d (11) {
+ ["name"]=>
+ string(8) "___label"
+ ["orgname"]=>
+ string(0) ""
+ ["table"]=>
+ string(0) ""
+ ["orgtable"]=>
+ string(0) ""
+ ["def"]=>
+ string(0) ""
+ ["max_length"]=>
+ int(2)
+ ["length"]=>
+ int(2)
+ ["charsetnr"]=>
+ int(8)
+ ["flags"]=>
+ int(0)
+ ["type"]=>
+ int(253)
+ ["decimals"]=>
+ int(31)
+}
+done!
+--UEXPECTF--
+object(stdClass)#%d (11) {
+ [u"name"]=>
+ unicode(2) "id"
+ [u"orgname"]=>
+ unicode(2) "id"
+ [u"table"]=>
+ unicode(4) "test"
+ [u"orgtable"]=>
+ unicode(4) "test"
+ [u"def"]=>
+ unicode(0) ""
+ [u"max_length"]=>
+ int(0)
+ [u"length"]=>
+ int(11)
+ [u"charsetnr"]=>
+ int(63)
+ [u"flags"]=>
+ int(49155)
+ [u"type"]=>
+ int(3)
+ [u"decimals"]=>
+ int(0)
+}
+object(stdClass)#%d (11) {
+ [u"name"]=>
+ unicode(5) "label"
+ [u"orgname"]=>
+ unicode(5) "label"
+ [u"table"]=>
+ unicode(4) "test"
+ [u"orgtable"]=>
+ unicode(4) "test"
+ [u"def"]=>
+ unicode(0) ""
+ [u"max_length"]=>
+ int(1)
+ [u"length"]=>
+ int(3)
+ [u"charsetnr"]=>
+ int(33)
+ [u"flags"]=>
+ int(0)
+ [u"type"]=>
+ int(254)
+ [u"decimals"]=>
+ int(0)
+}
+object(stdClass)#%d (11) {
+ [u"name"]=>
+ unicode(3) "_id"
+ [u"orgname"]=>
+ unicode(0) ""
+ [u"table"]=>
+ unicode(0) ""
+ [u"orgtable"]=>
+ unicode(0) ""
+ [u"def"]=>
+ unicode(0) ""
+ [u"max_length"]=>
+ int(0)
+ [u"length"]=>
+ int(17)
+ [u"charsetnr"]=>
+ int(63)
+ [u"flags"]=>
+ int(32897)
+ [u"type"]=>
+ int(8)
+ [u"decimals"]=>
+ int(0)
+}
+object(stdClass)#%d (11) {
+ [u"name"]=>
+ unicode(8) "___label"
+ [u"orgname"]=>
+ unicode(0) ""
+ [u"table"]=>
+ unicode(0) ""
+ [u"orgtable"]=>
+ unicode(0) ""
+ [u"def"]=>
+ unicode(0) ""
+ [u"max_length"]=>
+ int(2)
+ [u"length"]=>
+ int(6)
+ [u"charsetnr"]=>
+ int(33)
+ [u"flags"]=>
+ int(0)
+ [u"type"]=>
+ int(253)
+ [u"decimals"]=>
+ int(31)
+}
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt
new file mode 100644
index 0000000000..345506cf5b
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt
@@ -0,0 +1,125 @@
+--TEST--
+mysqli_stmt_get_result() - seeking
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+
+if (!function_exists('mysqli_stmt_get_result'))
+ die('skip mysqli_stmt_get_result not available');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ require('table.inc');
+
+ if (!$stmt = mysqli_stmt_init($link))
+ printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 3"))
+ printf("[002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!mysqli_stmt_execute($stmt))
+ printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) {
+ printf("[004] Expecting object/mysqli_result got %s/%s, [%d] %s\n",
+ gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+
+ if (3 !== $res->num_rows)
+ printf("[005] Expecting 3 rows, got %s/%s rows\n", gettype($res->num_rows), $res->num_rows);
+
+ if (2 !== $res->field_count)
+ printf("[006] Expecting 2 fields, got %s/%s rows\n", gettype($res->field_count), $res->field_count);
+
+ if (0 !== $res->current_field)
+ printf("[006] Expecting offset 0, got %s/%s rows\n", gettype($res->current_field), $res->current_field);
+
+ for ($i = 2; $i > 0; $i--) {
+ if (!$res->data_seek($i))
+ printf("[007] Cannot seek to position %d, [%d] %s\n",
+ $i, mysqli_stmt_errno($stmt), $stmt->error);
+ $row = $res->fetch_array(MYSQLI_BOTH);
+ if (($row[0] !== $row['id']) || ($row[0] !== $i + 1)) {
+ printf("[008] Record looks wrong, dumping data\n");
+ var_dump($row);
+ } else {
+ unset($row[0]);
+ unset($row['id']);
+ }
+ if ($row[1] !== $row['label']) {
+ printf("[009] Record looks wrong, dumping data\n");
+ var_dump($row);
+ } else {
+ unset($row[1]);
+ unset($row['label']);
+ }
+ if (!empty($row)) {
+ printf("[010] Not empty, dumping unexpected data\n");
+ var_dump($row);
+ }
+ }
+
+ if (false !== ($tmp = $res->data_seek(-1)))
+ printf("[011] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp);
+
+ if (false !== ($tmp = $res->data_seek($res->num_rows + 1)))
+ printf("[012] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp);
+
+ if (false !== ($tmp = $res->data_seek(PHP_INT_MAX + 1)))
+ printf("[013] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp);
+
+ for ($i = 0; $i < 100; $i++) {
+ /* intentionally out of range! */
+ $pos = mt_rand(-1, 4);
+ $tmp = mysqli_data_seek($res, $pos);
+ if (($pos >= 0 && $pos < 3)) {
+ if (true !== $tmp)
+ printf("[015] Expecting boolan/true got %s/%s\n", gettype($tmp), $tmp);
+ $row = $res->fetch_array(MYSQLI_NUM);
+ if ($row[0] !== $pos + 1)
+ printf("[016] Expecting id = %d for pos %d got %s/%s\n",
+ $pos + 1, $pos, gettype($row[0]), $row[0]);
+ } else {
+ if (false !== $tmp)
+ printf("[014] Expecting boolan/false got %s/%s\n", gettype($tmp), $tmp);
+ }
+ }
+
+ mysqli_stmt_close($stmt);
+
+ if (true !== ($tmp = mysqli_data_seek($res, 0)))
+ printf("[015] Expecting boolan/true got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_array($row = $res->fetch_array(MYSQLI_NUM)))
+ printf("[016] Expecting array got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_free_result($res);
+
+ if (NULL !== ($tmp = mysqli_data_seek($res, 0)))
+ printf("[017] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
+
+ if (NULL !== ($row = $res->fetch_array(MYSQLI_NUM)))
+ printf("[018] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_close($link);
+
+ if (NULL !== ($tmp = mysqli_data_seek($res, 0)))
+ printf("[019] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
+
+ if (NULL !== ($row = $res->fetch_array(MYSQLI_NUM)))
+ printf("[020] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
+
+ print "done!";
+?>
+--EXPECTF--
+
+Warning: mysqli_data_seek(): Couldn't fetch mysqli_result in %s on line %d
+
+Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d
+
+Warning: mysqli_data_seek(): Couldn't fetch mysqli_result in %s on line %d
+
+Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d
+done! \ No newline at end of file