summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Wendel <uw@php.net>2007-10-10 10:14:38 +0000
committerUlf Wendel <uw@php.net>2007-10-10 10:14:38 +0000
commitec08f105b92ddfc7591caac7fc100f038fc9a141 (patch)
tree48a00c2774b1757b7f9ed0dbf415f2bb8f3feec8
parent97c82d363fb7e6c0c2a855c13d6fc35e696bb5d8 (diff)
downloadphp-git-ec08f105b92ddfc7591caac7fc100f038fc9a141.tar.gz
Adding new tests mysqli_d*.phpt mysqli_e*.phpt mysqli_f*.phpt
-rw-r--r--ext/mysqli/tests/mysqli_data_seek.phpt70
-rw-r--r--ext/mysqli/tests/mysqli_data_seek_oo.phpt79
-rw-r--r--ext/mysqli/tests/mysqli_debug.phpt58
-rw-r--r--ext/mysqli/tests/mysqli_debug_append.phpt79
-rw-r--r--ext/mysqli/tests/mysqli_debug_control_string.phpt67
-rw-r--r--ext/mysqli/tests/mysqli_debug_ini.phpt48
-rw-r--r--ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt216
-rw-r--r--ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt117
-rw-r--r--ext/mysqli/tests/mysqli_disable_reads_from_master.phpt43
-rw-r--r--ext/mysqli/tests/mysqli_disable_rpl_parse.phpt41
-rw-r--r--ext/mysqli/tests/mysqli_driver.phpt115
-rw-r--r--ext/mysqli/tests/mysqli_driver_unclonable.phpt13
-rw-r--r--ext/mysqli/tests/mysqli_dump_debug_info.phpt44
-rw-r--r--ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt38
-rw-r--r--ext/mysqli/tests/mysqli_embedded_connect.phpt32
-rw-r--r--ext/mysqli/tests/mysqli_enable_reads_from_master.phpt43
-rw-r--r--ext/mysqli/tests/mysqli_enable_rpl_parse.phpt41
-rw-r--r--ext/mysqli/tests/mysqli_errno.phpt52
-rw-r--r--ext/mysqli/tests/mysqli_errno_oo.phpt49
-rw-r--r--ext/mysqli/tests/mysqli_error.phpt49
-rw-r--r--ext/mysqli/tests/mysqli_error_oo.phpt46
-rw-r--r--ext/mysqli/tests/mysqli_error_unicode.phpt57
-rw-r--r--ext/mysqli/tests/mysqli_explain_metadata.phpt155
-rw-r--r--ext/mysqli/tests/mysqli_fetch_all.phpt561
-rw-r--r--ext/mysqli/tests/mysqli_fetch_all_oo.phpt564
-rw-r--r--ext/mysqli/tests/mysqli_fetch_array.phpt454
-rw-r--r--ext/mysqli/tests/mysqli_fetch_array_assoc.phpt62
-rw-r--r--ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt112
-rw-r--r--ext/mysqli/tests/mysqli_fetch_array_oo.phpt435
-rw-r--r--ext/mysqli/tests/mysqli_fetch_assoc.phpt161
-rw-r--r--ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt113
-rw-r--r--ext/mysqli/tests/mysqli_fetch_assoc_no_alias.phpt201
-rw-r--r--ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt249
-rw-r--r--ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt108
-rw-r--r--ext/mysqli/tests/mysqli_fetch_field.phpt220
-rw-r--r--ext/mysqli/tests/mysqli_fetch_field_direct.phpt108
-rw-r--r--ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt117
-rw-r--r--ext/mysqli/tests/mysqli_fetch_field_flags.phpt172
-rw-r--r--ext/mysqli/tests/mysqli_fetch_field_oo.phpt151
-rw-r--r--ext/mysqli/tests/mysqli_fetch_field_types.phpt119
-rw-r--r--ext/mysqli/tests/mysqli_fetch_fields.phpt143
-rw-r--r--ext/mysqli/tests/mysqli_fetch_lengths.phpt51
-rw-r--r--ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt43
-rw-r--r--ext/mysqli/tests/mysqli_fetch_object.phpt153
-rw-r--r--ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt76
-rw-r--r--ext/mysqli/tests/mysqli_fetch_object_no_object.phpt24
-rw-r--r--ext/mysqli/tests/mysqli_fetch_object_oo.phpt126
-rw-r--r--ext/mysqli/tests/mysqli_fetch_row.phpt71
-rw-r--r--ext/mysqli/tests/mysqli_field_count.phpt59
-rw-r--r--ext/mysqli/tests/mysqli_field_seek.phpt331
-rw-r--r--ext/mysqli/tests/mysqli_field_tell.phpt148
-rw-r--r--ext/mysqli/tests/mysqli_fork.phpt264
-rw-r--r--ext/mysqli/tests/mysqli_free_result.phpt75
53 files changed, 7023 insertions, 0 deletions
diff --git a/ext/mysqli/tests/mysqli_data_seek.phpt b/ext/mysqli/tests/mysqli_data_seek.phpt
new file mode 100644
index 0000000000..d25347ade0
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_data_seek.phpt
@@ -0,0 +1,70 @@
+--TEST--
+mysqli_data_seek()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (NULL !== ($tmp = @mysqli_data_seek()))
+ printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (NULL !== ($tmp = @mysqli_data_seek($link)))
+ printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (NULL !== ($tmp = @mysqli_data_seek($link, $link)))
+ printf("[003] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, 'SELECT * FROM test ORDER BY id LIMIT 4', MYSQLI_STORE_RESULT))
+ printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (true !== ($tmp = mysqli_data_seek($res, 3)))
+ printf("[005] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
+
+ $row = mysqli_fetch_assoc($res);
+ if (4 != $row['id'])
+ printf("[006] Expecting record 4/d, got record %s/%s\n", $row['id'], $row['label']);
+
+ if (true !== ($tmp = mysqli_data_seek($res, 0)))
+ printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
+
+ $row = mysqli_fetch_assoc($res);
+ if (1 != $row['id'])
+ printf("[008] Expecting record 1/a, got record %s/%s\n", $row['id'], $row['label']);
+
+ if (false !== ($tmp = mysqli_data_seek($res, 4)))
+ printf("[009] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (false !== ($tmp = mysqli_data_seek($res, -1)))
+ printf("[010] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, 'SELECT * FROM test ORDER BY id', MYSQLI_USE_RESULT))
+ printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (false !== ($tmp = mysqli_data_seek($res, 3)))
+ printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_free_result($res);
+
+ if (NULL !== ($tmp = mysqli_data_seek($res, 1)))
+ printf("[013] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_close($link);
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d
+
+Warning: mysqli_data_seek(): Couldn't fetch mysqli_result in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_data_seek_oo.phpt b/ext/mysqli/tests/mysqli_data_seek_oo.phpt
new file mode 100644
index 0000000000..40fabe1ce9
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_data_seek_oo.phpt
@@ -0,0 +1,79 @@
+--TEST--
+mysqli_result->data_seek()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ require('table.inc');
+
+ if (!$mysqli = new mysqli($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);
+
+ $res = new mysqli_result($mysqli);
+ if (NULL !== ($tmp = @$res->data_seek(0)))
+ printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!$res = $mysqli->query('SELECT * FROM test ORDER BY id LIMIT 4', MYSQLI_STORE_RESULT))
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (NULL !== ($tmp = @$res->data_seek()))
+ printf("[004] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (NULL !== ($tmp = @$res->data_seek($link)))
+ printf("[005] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (NULL !== ($tmp = @$res->data_seek($link, $link)))
+ printf("[006] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (true !== ($tmp = $res->data_seek(3)))
+ printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
+
+ $row = $res->fetch_assoc();
+ if (4 != $row['id'])
+ printf("[008] Expecting record 4/d, got record %s/%s\n", $row['id'], $row['label']);
+
+ if (true !== ($tmp = $res->data_seek(0)))
+ printf("[009] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
+
+ $row = $res->fetch_assoc();
+ if (1 != $row['id'])
+ printf("[010] Expecting record 1/a, got record %s/%s\n", $row['id'], $row['label']);
+
+ if (false !== ($tmp = $res->data_seek(4)))
+ printf("[011] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (false !== ($tmp = $res->data_seek(-1)))
+ printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
+
+ $res->free_result();
+
+ if (!$res = $mysqli->query('SELECT * FROM test ORDER BY id', MYSQLI_USE_RESULT))
+ printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (false !== ($tmp = $res->data_seek(3)))
+ printf("[014] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
+
+ $res->free_result();
+
+ if (NULL !== ($tmp = $res->data_seek(1)))
+ printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ $mysqli->close();
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_result::data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d
+
+Warning: mysqli_result::data_seek(): Couldn't fetch mysqli_result in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_debug.phpt b/ext/mysqli/tests/mysqli_debug.phpt
new file mode 100644
index 0000000000..6db6a45e44
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_debug.phpt
@@ -0,0 +1,58 @@
+--TEST--
+mysqli_debug()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+
+if (!function_exists('mysqli_debug'))
+ die("skip: mysqli_debug() not available");
+?>
+--FILE--
+<?php
+ require_once('connect.inc');;
+
+ if (NULL !== ($tmp = @mysqli_debug()))
+ printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ // NOTE: documentation is not clear on this: function always return NULL or TRUE
+ if (true !== ($tmp = mysqli_debug(sprintf('d:t:O,%s/mysqli_debug_phpt.trace', sys_get_temp_dir()))))
+ printf("[002] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
+
+ if ($IS_MYSQLND) {
+ // let's make this mysqlnd only - for libmysql we need debug installation
+
+ // table.inc will create a database connection and run some SQL queries, therefore
+ // the debug file should have entries
+ require_once('table.inc');
+
+ clearstatcache();
+ $trace_file = sprintf('%s/mysqli_debug_phpt.trace', sys_get_temp_dir());
+ if (!file_exists($trace_file))
+ printf("[003] Trace file '%s' has not been created\n", $trace_file);
+ if (filesize($trace_file) < 50)
+ printf("[004] Trace file '%s' is very small. filesize() reports only %d bytes. Please check.\n",
+ $trace_file,
+ filesize($trace_file));
+
+ // will mysqli_debug() mind if the trace file gets removed?
+ unlink($trace_file);
+ clearstatcache();
+
+ if (!$res = mysqli_query($link, 'SELECT * FROM test'))
+ printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ else
+ mysqli_free_result($res);
+
+ mysqli_close($link);
+
+ clearstatcache();
+ if (!file_exists($trace_file))
+ printf("[006] Trace file '%s' does not exist\n", $trace_file);
+ unlink($trace_file);
+ }
+
+ print "done!";
+?>
+--EXPECTF--
+done%s \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_debug_append.phpt b/ext/mysqli/tests/mysqli_debug_append.phpt
new file mode 100644
index 0000000000..90f6d6faac
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_debug_append.phpt
@@ -0,0 +1,79 @@
+--TEST--
+mysqli_debug() - append to trace file
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+
+if (!function_exists('mysqli_debug'))
+ die("skip: mysqli_debug() not available");
+?>
+--FILE--
+<?php
+ require_once('connect.inc');;
+
+ if (true !== ($tmp = mysqli_debug(sprintf('d:t:O,%s/mysqli_debug_phpt.trace', sys_get_temp_dir()))))
+ printf("[001] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
+
+ // table.inc will create a database connection and run some SQL queries, therefore
+ // the debug file should have entries
+ require_once('table.inc');
+
+ clearstatcache();
+ $trace_file = sprintf('%s/mysqli_debug_phpt.trace', sys_get_temp_dir());
+ if (!file_exists($trace_file))
+ printf("[002] Trace file '%s' has not been created\n", $trace_file);
+ if (filesize($trace_file) < 50)
+ printf("[003] Trace file '%s' is very small. filesize() reports only %d bytes. Please check.\n",
+ $trace_file,
+ filesize($trace_file));
+
+ // will mysqli_debug() mind if the trace file gets removed?
+ unlink($trace_file);
+ clearstatcache();
+
+ if (!$fp = fopen($trace_file, 'w')) {
+ printf("[004] Cannot create trace file to test append mode\n");
+ } else {
+
+ if (!fwrite($fp, (binary) 'mysqli_debug.phpt test line'))
+ printf("[005] Cannot write to trace file.\n");
+ fclose($fp);
+
+ if (true !== ($tmp = mysqli_debug(sprintf('d:a,%s', $trace_file))))
+ printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!$res = mysqli_query($link, 'SELECT * FROM test'))
+ printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ else
+ mysqli_free_result($res);
+
+ $trace = file_get_contents($trace_file);
+ if (!strstr($trace, 'mysqli_debug.phpt test line'))
+ printf("[008] Cannot find original file content any more. Seems that the trace file got overwritten and not appended. Please check.");
+
+ if (true !== ($tmp = mysqli_debug(sprintf('d:A,%s', $trace_file))))
+ printf("[009] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!$res = mysqli_query($link, 'SELECT * FROM test'))
+ printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ else
+ mysqli_free_result($res);
+
+ if (!strstr(file_get_contents($trace_file), $trace))
+ printf("[011] Cannot find original file content any more. Seems that the trace file got overwritten and not appended. Please check.");
+ }
+
+ // what will happen if we create new trace entries...?
+ unlink($trace_file);
+ clearstatcache();
+ if (file_exists($trace_file))
+ printf("[012] Could not remove trace file '%s'.\n", $trace_file);
+
+ mysqli_close($link);
+ print "done";
+ if ($IS_MYSQLND)
+ print "libmysql/DBUG package prints some debug info here."
+?>
+--EXPECTF--
+done%s
diff --git a/ext/mysqli/tests/mysqli_debug_control_string.phpt b/ext/mysqli/tests/mysqli_debug_control_string.phpt
new file mode 100644
index 0000000000..4b869dc14f
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_debug_control_string.phpt
@@ -0,0 +1,67 @@
+--TEST--
+mysqli_debug() - invalid debug control strings
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+
+if (!function_exists('mysqli_debug'))
+ die("skip: mysqli_debug() not available");
+?>
+--FILE--
+<?php
+ require_once('connect.inc');
+ require_once('table.inc');
+
+ function try_control_string($link, $control_string, $trace_file, $offset) {
+
+ if (true !== ($tmp = mysqli_debug($control_string))) {
+ printf("[%03d][control string '%s'] Expecting boolean/true, got %s/%s.\n",
+ $offset + 1,
+ $control_string,
+ gettype($tmp),
+ $tmp);
+ return false;
+ }
+
+ if (!$res = mysqli_query($link, 'SELECT * FROM test')) {
+ printf("[%03d][control string '%s'] [%d] %s.\n",
+ $offset + 2,
+ $control_string,
+ mysqli_errno($link),
+ mysqli_error($link));
+ return false;
+ }
+
+ clearstatcache();
+ if (!file_exists($trace_file)) {
+ printf("[%03d][control string '%s'] Trace file has not been written.\n",
+ $offset + 3,
+ $control_string,
+ gettype($tmp),
+ $tmp);
+ return false;
+ }
+
+ unlink($trace_file);
+ }
+
+ $trace_file = sprintf('%s%s%s', sys_get_temp_dir(), DIRECTORY_SEPARATOR, 'mysqli_debug_phpt.trace');
+ try_control_string($link, 't:,,:o,' . $trace_file, $trace_file, 10);
+ try_control_string($link, ':' . chr(0) . 'A,' . $trace_file, $trace_file, 20);
+ try_control_string($link, 't:o,' . $trace_file . ':abc', $trace_file, 30);
+ try_control_string($link, 't:o,' . $trace_file . ':ABC,123:b', $trace_file, 40);
+ try_control_string($link, 't:ABC,123:b;:o,' . $trace_file, $trace_file, 50);
+ try_control_string($link, 't:A;BC,123:b;:o,' . $trace_file, $trace_file, 60);
+ try_control_string($link, 't:p:o,' . $trace_file, $trace_file, 70);
+ try_control_string($link, 't:p,1,,2:o,' . $trace_file, $trace_file, 80);
+ try_control_string($link, 't:z,1,,2:o,' . $trace_file, $trace_file, 90);#
+
+ mysqli_close($link);
+ print "done";
+ if ($IS_MYSQLND)
+ print "libmysql/DBUG package prints some debug info here."
+?>
+--EXPECTF--
+[023][control string '%s'] Trace file has not been written.
+done%s \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_debug_ini.phpt b/ext/mysqli/tests/mysqli_debug_ini.phpt
new file mode 100644
index 0000000000..2d1bb08a8e
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_debug_ini.phpt
@@ -0,0 +1,48 @@
+--TEST--
+mysqli_debug() - enabling trace with ini setting
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+
+if (!function_exists('mysqli_debug'))
+ die("skip mysqli_debug() not available");
+
+require_once('connect.inc');
+if (!$IS_MYSQLND || ($MYSQLND_VERSION < 940))
+ die("skip needs mysqlnd version/revision 940+");
+
+if (!$fp = @fopen('/tmp/mysqli_debug_phpt.trace', 'w'))
+ die("skip PHP cannot create a file in /tmp/mysqli_debug_phpt");
+else
+ fclose($fp);
+?>
+--INI--
+mysqlnd.debug="t:O,/tmp/mysqli_debug_phpt.trace"
+--FILE--
+<?php
+ require_once('connect.inc');
+ require_once('table.inc');
+
+ var_dump(ini_get('mysqlnd.debug'));
+
+ $trace_file = '/tmp/mysqli_debug_phpt.trace';
+ clearstatcache();
+ if (!file_exists($trace_file))
+ printf("[003] Trace file '%s' has not been created\n", $trace_file);
+ if (filesize($trace_file) < 50)
+ printf("[004] Trace file '%s' is very small. filesize() reports only %d bytes. Please check.\n",
+ $trace_file,
+ filesize($trace_file));
+
+ mysqli_close($link);
+ unlink($trace_file);
+
+ print "done!";
+?>
+--EXPECTF--
+string(32) "t:O,/tmp/mysqli_debug_phpt.trace"
+done!
+--UEXPECTF--
+unicode(32) "t:O,/tmp/mysqli_debug_phpt.trace"
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt
new file mode 100644
index 0000000000..06feebf6a1
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt
@@ -0,0 +1,216 @@
+--TEST--
+mysqli_debug() - all control string options supported by both mysqlnd and libmysql except oOaA
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+
+if (!function_exists('mysqli_debug'))
+ die("skip: mysqli_debug() not available");
+?>
+--FILE--
+<?php
+ require_once('connect.inc');;
+ require_once('table.inc');
+
+ function try_control_string($link, $control_string, $trace_file, $offset) {
+
+ @unlink($trace_file);
+ if (true !== ($tmp = @mysqli_debug($control_string))) {
+ printf("[%03d][control string '%s'] Expecting boolean/true, got %s/%s.\n",
+ $offset + 1,
+ $control_string,
+ gettype($tmp),
+ $tmp);
+ return false;
+ }
+
+ if (!$res = mysqli_query($link, 'SELECT * FROM test')) {
+ printf("[%03d][control string '%s'] [%d] %s.\n",
+ $offset + 2,
+ $control_string,
+ mysqli_errno($link),
+ mysqli_error($link));
+ return false;
+ }
+ while ($row = mysqli_fetch_assoc($res))
+ ;
+ mysqli_free_result($res);
+
+ clearstatcache();
+ if (!file_exists($trace_file)) {
+ printf("[%03d][control string '%s'] Trace file has not been written.\n",
+ $offset + 3,
+ $control_string,
+ gettype($tmp),
+ $tmp);
+ return false;
+ }
+
+ return trim(substr(file_get_contents($trace_file), 0, 100024));
+ }
+
+ $trace_file = sprintf('%s%s%s', sys_get_temp_dir(), DIRECTORY_SEPARATOR, 'mysqli_debug_phpt.trace');
+
+ $trace = try_control_string($link, 't:O,' . $trace_file, $trace_file, 10);
+ if (!strstr($trace, 'SELECT * FROM test') && !strstr($trace, 'mysql_real_query'))
+ printf("[015] SELECT query cannot be found in trace. Trace contents seems wrong.\n");
+
+ // T - gettimeofday() system call, system dependent format
+ // 16:57:03.350734 >mysql_real_query
+ $trace = try_control_string($link, 't:O,' . $trace_file . ':T', $trace_file, 20);
+ if (!preg_match('@^[012]{0,1}[0-9]{1}:[0-5]{0,1}[0-9]{1}:[0-5]{0,1}[0-9]{1}@ismU', $trace))
+ printf("[025] Timestamp not found. One reason could be that the test is borked and does not recognize the format of the gettimeofday() system call. Check manually (and fix the test, if needed :-)). First characters from trace are '%s'\n", substr($trace, 0, 80));
+
+ // i - add PID of the current process
+ // currently PHP is not multi-threaded, so it should be save to test for the PID of this PHP process
+ if (false === ($pid = getmypid()))
+ $pid = "[\d]+";
+
+ $trace = try_control_string($link, 't:O,' . $trace_file . ':i', $trace_file, 30);
+ if (!preg_match("@^" . $pid . "*@ismU", $trace))
+ printf("[035] Process ID has not been found, first characters from trace are '%s'\n", substr($trace, 0, 80));
+
+ // L - line numbers
+ $trace = try_control_string($link, 't:O,' . $trace_file . ':L', $trace_file, 40);
+ if (!preg_match("@^[\d]+@ismU", $trace))
+ printf("[045] Line numbers have not been found, first characters from trace are '%s'\n", substr($trace, 0, 80));
+
+ // F - file name
+ $trace = try_control_string($link, 't:O,' . $trace_file . ':F', $trace_file, 50);
+ // hopefully we'll never see a file name that's not covered by this regular expression...
+ if (!preg_match("@^\s*[/\w\\\\d\.\-]+\.[ch]@ismU", $trace))
+ printf("[055] File names seem to be missing, first characters from trace are '%s'\n", substr($trace, 0, 80));
+
+ // -n - print function nesting depth
+ $trace = try_control_string($link, 't:O,' . $trace_file . ':n', $trace_file, 60);
+ if (!preg_match("@^\d+:@ismU", $trace))
+ printf("[065] Nesting level seem to be missing, first characters from trace are '%s'\n", substr($trace, 0, 80));
+
+ // -t,[N] - maximum nesting level
+ $trace = try_control_string($link, 't,1:n:O,' . $trace_file, $trace_file, 70);
+ $lines = explode("\n", $trace);
+ foreach ($lines as $k => $line) {
+ $line = trim($line);
+ if (!preg_match("@^(\d+):+@ismU", $line, $matches)) {
+ printf("[075] Nesting level seem to be missing, first characters from trace are '%s'\n", substr($line, 0, 80));
+ } else {
+ if (!isset($matches[1]) || ((int)$matches[1] > 1)) {
+ printf("[076] Nesting level seem to be %d, should not be higher than 1, first characters from trace are '%s'\n",
+ $matches[1],
+ substr($line, 0, 80));
+ }
+ }
+ }
+
+ // omitting t
+ $trace = try_control_string($link, 'n:O,' . $trace_file, $trace_file, 80);
+ $lines = explode("\n", $trace);
+ foreach ($lines as $k => $line) {
+ $line = trim($line);
+ if (preg_match("@^[|\s]*>[\w]+@ism", $line, $matches)) {
+ printf("[085] Looks like a function call, but there should be none in the trace file, first characters from trace are '%s'\n",
+ substr($line, 0, 80));
+ }
+ }
+
+ // -f[,functions] - Limit debugger list to specified functions. Empty list -> all functions
+ $lines_all_funcs = explode("\n", try_control_string($link, 't:O,' . $trace_file, $trace_file, 90));
+ $functions_all_funcs = array();
+ foreach ($lines_all_funcs as $k => $line) {
+ $line = trim($line);
+ if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) {
+ $functions_all_funcs[$matches[1]] = $matches[1];
+ }
+ }
+
+ $lines_trace = explode("\n", try_control_string($link, 't:f:O,' . $trace_file, $trace_file, 100));
+ $functions_trace = array();
+ foreach ($lines_trace as $k => $line) {
+ $line = trim($line);
+ if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) {
+ $functions_trace[$matches[1]] = $matches[1];
+ }
+ }
+
+ $tmp = array_diff($functions_all_funcs, $functions_trace);
+ if (!empty($tmp)) {
+ printf("[105] Looks like not all functions are listed in the trace. Check manually, dumping diff.");
+ var_dump($tmp);
+ }
+
+ // get two or three function names to play with...
+ $test_functions = array('simple' => array(), 'doubledot' => array());
+
+ foreach ($functions_all_funcs as $func) {
+ if (count($test_functions['simple']) < 2 && !strstr($func, '::'))
+ $test_functions['simple'][$func] = $func;
+ else if (count($test_functions['doubledot']) < 2 && strstr($func, '::'))
+ $test_functions['doubledot'][$func] = $func;
+ }
+
+ $control_string = '';
+ if ($func = reset($test_functions['simple']))
+ $control_string .= sprintf('%s,', $func);
+ if ($func = reset($test_functions['doubledot']))
+ $control_string .= sprintf('%s,', $func);
+ if ($func = next($test_functions['simple']))
+ $control_string .= sprintf('%s,', $func);
+ if ($func = next($test_functions['doubledot']))
+ $control_string .= sprintf('%s,', $func);
+ $control_string = sprintf('t:f,%s:O,%s', $control_string, $trace_file);
+
+ $lines_trace = explode("\n", try_control_string($link, $control_string, $trace_file, 110));
+ $functions_trace = array();
+ foreach ($lines_trace as $k => $line) {
+ $line = trim($line);
+ if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) {
+ $functions_trace[$matches[1]] = $matches[1];
+ }
+ }
+
+ foreach ($test_functions['simple'] as $func)
+ if (isset($functions_trace[$func])) {
+ unset($functions_trace[$func]);
+ unset($test_functions['simple'][$func]);
+ }
+
+ foreach ($test_functions['doubledot'] as $func)
+ if (isset($functions_trace[$func])) {
+ unset($functions_trace[$func]);
+ unset($test_functions['doubledot'][$func]);
+ }
+
+ if (!empty($functions_trace)) {
+ printf("[115] Dumping list of unexpected functions which should have not been shown when using control string '%s'.\n",
+ $control_string);
+ var_dump($functions_trace);
+ }
+ $tmp = array_merge($test_functions['doubledot'], $test_functions['simple']);
+ if (!empty($tmp)) {
+ printf("[116] Dumping list of functions which should have been shown when using control string '%s'.\n",
+ $control_string);
+ var_dump($tmp);
+ }
+
+ if ($IS_MYSQLND) {
+ // mysqlnd only option
+ // m - trace memory allocations
+ $trace = try_control_string($link, 't:O,' . $trace_file . ':m', $trace_file, 120);
+ if (!preg_match("@^[|\s]*>\_mysqlnd_pefree@ismU", $trace, $matches) &&
+ !preg_match("@^[|\s]*>\_mysqlnd_pemalloc@ismU", $trace, $matches)) {
+ printf("[125] Memory dump does neither contain _mysqlnd_pefree nor _mysqlnd_pemalloc calls - check manually.\n");
+ var_dump($trace);
+ }
+
+ }
+
+ mysqli_close($link);
+ print "done";
+ if ($IS_MYSQLND)
+ print "libmysql/DBUG package prints some debug info here.";
+ @unlink($trace_file);
+?>
+--EXPECTF--
+[083][control string 'n:O,/tmp/mysqli_debug_phpt.trace'] Trace file has not been written.
+done%s
diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt
new file mode 100644
index 0000000000..b8066bea18
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt
@@ -0,0 +1,117 @@
+--TEST--
+mysqli_debug() - mysqlnd only control strings
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('connect.inc');
+
+if (!function_exists('mysqli_debug'))
+ die("skip mysqli_debug() not available");
+
+if (!$IS_MYSQLND)
+ die("skip mysqlnd only test");
+?>
+--FILE--
+<?php
+ require_once('connect.inc');;
+ require_once('table.inc');
+
+ function try_control_string($link, $control_string, $trace_file, $offset) {
+
+ @unlink($trace_file);
+ if (true !== ($tmp = @mysqli_debug($control_string))) {
+ printf("[%03d][control string '%s'] Expecting boolean/true, got %s/%s.\n",
+ $offset + 1,
+ $control_string,
+ gettype($tmp),
+ $tmp);
+ return false;
+ }
+
+ if (!$res = mysqli_query($link, 'SELECT * FROM test')) {
+ printf("[%03d][control string '%s'] [%d] %s.\n",
+ $offset + 2,
+ $control_string,
+ mysqli_errno($link),
+ mysqli_error($link));
+ return false;
+ }
+ while ($row = mysqli_fetch_assoc($res))
+ ;
+ mysqli_free_result($res);
+
+ clearstatcache();
+ if (!file_exists($trace_file)) {
+ printf("[%03d][control string '%s'] Trace file has not been written.\n",
+ $offset + 3,
+ $control_string,
+ gettype($tmp),
+ $tmp);
+ return false;
+ }
+
+ return trim(substr(file_get_contents($trace_file), 0, 100024));
+ }
+
+ $memory_funcs = array(
+ '_mysqlnd_ecalloc',
+ '_mysqlnd_emalloc',
+ '_mysqlnd_palloc_free_thd_cache_reference',
+ '_mysqlnd_pecalloc',
+ '_mysqlnd_pefree',
+ '_mysqlnd_pemalloc',
+ '_mysqlnd_perealloc',
+ );
+ $trace_file = sprintf('%s%s%s', sys_get_temp_dir(), DIRECTORY_SEPARATOR, 'mysqli_debug_phpt.trace');
+
+ $trace = try_control_string($link, 't:m:O,' . $trace_file, $trace_file, 10);
+ if (!strstr($trace, 'SELECT * FROM test') && !strstr($trace, 'mysql_real_query'))
+ printf("[015] SELECT query cannot be found in trace. Trace contents seems wrong.\n");
+
+ $lines_trace = explode("\n", $trace);
+ $functions_trace = array();
+ foreach ($lines_trace as $k => $line) {
+ $line = trim($line);
+ if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) {
+ $functions_trace[$matches[1]] = $matches[1];
+ }
+ }
+
+ $found = 0;
+ foreach ($memory_funcs as $k => $name)
+ if (isset($functions_trace[$name]))
+ $found++;
+
+ if ($found < (count($memory_funcs) - 2))
+ printf("[016] Only %d memory functions have been found, expecting at least %d.\n",
+ $found, count($memory_funcs) - 2);
+
+ $trace = try_control_string($link, 't:O,' . $trace_file, $trace_file, 20);
+ if (!strstr($trace, 'SELECT * FROM test') && !strstr($trace, 'mysql_real_query'))
+ printf("[025] SELECT query cannot be found in trace. Trace contents seems wrong.\n");
+
+ $lines_trace = explode("\n", $trace);
+ $functions_trace = array();
+ foreach ($lines_trace as $k => $line) {
+ $line = trim($line);
+ if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) {
+ $functions_trace[$matches[1]] = $matches[1];
+ }
+ }
+
+ $found = 0;
+ foreach ($memory_funcs as $k => $name)
+ if (isset($functions_trace[$name]))
+ $found++;
+
+ if ($found > 2)
+ printf("[026] More than %d memory functions have been recorded, that's strange.\n",
+ $found);
+
+ mysqli_close($link);
+ @unlink($trace_file);
+ print "done!";
+?>
+--EXPECTF--
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt b/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt
new file mode 100644
index 0000000000..80a37f8f93
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt
@@ -0,0 +1,43 @@
+--TEST--
+mysqli_disable_reads_from_master()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+if (!function_exists('mysqli_disable_reads_from_master')) {
+ die("skip mysqli_disable_reads_from_master() not available");
+}
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (NULL !== ($tmp = @mysqli_disable_reads_from_master()))
+ printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (NULL !== ($tmp = @mysqli_disable_reads_from_master($link)))
+ printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ 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);
+ }
+
+ if (!is_bool($tmp = mysqli_disable_reads_from_master($link)))
+ printf("[004] Expecting boolean/[true|false] value, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_close($link);
+
+ if (NULL !== ($tmp = mysqli_disable_reads_from_master($link)))
+ printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_disable_reads_from_master(): Couldn't fetch mysqli in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_disable_rpl_parse.phpt b/ext/mysqli/tests/mysqli_disable_rpl_parse.phpt
new file mode 100644
index 0000000000..2e66a7c121
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_disable_rpl_parse.phpt
@@ -0,0 +1,41 @@
+--TEST--
+mysqli_disable_rpl_parse()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+if (!function_exists('mysqli_disable_rpl_parse'))
+ die("skip mysqli_disable_rpl_parse() not available");
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (NULL !== ($tmp = @mysqli_disable_rpl_parse()))
+ printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (NULL !== ($tmp = @mysqli_disable_rpl_parse($link)))
+ printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ 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);
+ }
+
+ if (!is_bool($tmp = mysqli_disable_rpl_parse($link)))
+ printf("[004] Expecting boolean/[true|false] value, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_close($link);
+
+ if (NULL !== ($tmp = mysqli_disable_rpl_parse($link)))
+ printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_disable_rpl_parse(): Couldn't fetch mysqli in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_driver.phpt b/ext/mysqli/tests/mysqli_driver.phpt
new file mode 100644
index 0000000000..765fee527c
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_driver.phpt
@@ -0,0 +1,115 @@
+--TEST--
+mysqli_driver class
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ include "table.inc";
+
+ if (!is_object($driver = new mysqli_driver()))
+ printf("[001] Failed to create mysqli_driver object\n");
+
+ $client_info = mysqli_get_client_info();
+ if (($tmp = $driver->client_info) !== $client_info)
+ printf("[002] Expecting %s/%s, got %s/%s\n",
+ gettype($client_info), $client_info,
+ gettype($tmp), $tmp);
+
+ $client_version = mysqli_get_client_version();
+ if (($tmp = $driver->client_version) !== $client_version)
+ printf("[003] Expecting %s/%s, got %s/%s\n",
+ gettype($client_version), $client_version,
+ gettype($tmp), $tmp);
+
+ if (!is_int($tmp = $driver->driver_version) || (0 == $tmp))
+ printf("[004] Expecting int/any, got %s/%s\n",
+ gettype($tmp), $tmp);
+
+
+ $all_modes = array(MYSQLI_REPORT_INDEX, MYSQLI_REPORT_ERROR, MYSQLI_REPORT_STRICT,
+ MYSQLI_REPORT_ALL, MYSQLI_REPORT_OFF);
+ $report_mode = $driver->report_mode;
+ if (!is_int($report_mode))
+ printf("[005] Expecting int/any, got %s/%s\n",
+ gettype($report_mode), $report_mode);
+
+ if (!in_array($report_mode, $all_modes))
+ printf("[006] Illegal report mode returned? Got %s, expected %s\n",
+ $report_mode, implode(', ', $all_modes));
+
+ $driver->report_mode = MYSQLI_REPORT_STRICT;
+ $ok = false;
+ try {
+
+ if ($link = mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket))
+ printf("[007] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n",
+ $host, $user . 'unknown_really', $db, $port, $socket);
+ mysqli_close($link);
+
+ } catch (mysqli_sql_exception $e) {
+ $ok = true;
+ if ('' == $e->getMessage())
+ printf("[008] getMessage() has returned an emptry string.\n");
+ if ('' == $e->getCode())
+ printf("[009] getCode() has returned an empty string.\n");
+ if ('' == $e->getFile())
+ printf("[010] getFile() has returned an empty string.\n");
+ if ('' == $e->getLine())
+ printf("[011] getLine() has returned an empty string.\n");
+ $tmp = $e->getTrace();
+ if (empty($tmp))
+ printf("[012] getTrace() has returned an empty array.\n");
+ if ('' == $e->getTraceAsString())
+ printf("[013] getTraceAsString() has returned an empty string.\n");
+ if ('' == $e->__toString())
+ printf("[014] __toString() has returned an empty string.\n");
+
+ }
+ if (!$ok)
+ printf("[015] Error reporting mode has not been switched to exceptions and or no exception thrown\n");
+
+
+ $driver->report_mode = MYSQLI_REPORT_OFF;
+ if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ printf("[016] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
+ mysqli_query($link, "NO_SQL");
+ mysqli_close($link);
+
+ $driver->report_mode = MYSQLI_REPORT_ERROR;
+
+ if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ printf("[017] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
+ mysqli_query($link, "NO_SQL");
+ mysqli_close($link);
+
+ if (MYSQLI_REPORT_ERROR !== $driver->report_mode)
+ printf("[018] Error mode should be different\n");
+
+ /* TODO - more report testing should go in here, but it's not really documented what behaviour is expected */
+
+ $driver->report_mode = $report_mode;
+
+ $reconnect = $driver->reconnect;
+ if (!is_bool($reconnect))
+ printf("[019] Expecting boolean/any, got %s/%s\n",
+ gettype($reconnect), $reconnect);
+
+ /* pointless, but I need more documentation */
+ $driver->reconnect = true;
+ $driver->reconnect = false;
+ $driver->reconnect = $reconnect;
+
+ if (!is_bool($embedded = $driver->embedded))
+ printf("[020] Expecting boolean/any, got %s/%s\n",
+ gettype($embedded), $embedded);
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NO_SQL' at line 1 in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_driver_unclonable.phpt b/ext/mysqli/tests/mysqli_driver_unclonable.phpt
new file mode 100644
index 0000000000..0e2438eef9
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_driver_unclonable.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Trying to clone mysqli_driver object
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+<?php require_once('skipifemb.inc'); ?>
+--FILE--
+<?php
+ $driver = new mysqli_driver;
+ $driver_clone = clone $driver;
+ print "done!";
+?>
+--EXPECTF--
+Fatal error: Trying to clone an uncloneable object of class mysqli_driver in %s on line %d \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_dump_debug_info.phpt b/ext/mysqli/tests/mysqli_dump_debug_info.phpt
new file mode 100644
index 0000000000..d93738edc8
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_dump_debug_info.phpt
@@ -0,0 +1,44 @@
+--TEST--
+mysqli_dump_debug_info()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (NULL !== ($tmp = @mysqli_dump_debug_info()))
+ printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (NULL !== ($tmp = @mysqli_dump_debug_info($link)))
+ printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ 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_bool($tmp = mysqli_dump_debug_info($link)))
+ printf("[004] Expecting boolean/[true|false] value, got %s/%s, [%d] %s\n",
+ gettype($tmp), $tmp,
+ mysqli_errno($link), mysqli_error($link));
+
+ mysqli_close($link);
+
+ if (NULL !== ($tmp = mysqli_dump_debug_info($link)))
+ printf("[005] Expecting NULL, got %s/%s\n",
+ gettype($tmp), $tmp,
+ mysqli_errno($link), mysqli_error($link));
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_dump_debug_info(): Couldn't fetch mysqli in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt b/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt
new file mode 100644
index 0000000000..1d334f95df
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt
@@ -0,0 +1,38 @@
+--TEST--
+mysqli_dump_debug_info()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!$mysqli = new mysqli($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);
+
+ if (NULL !== ($tmp = @$mysqli->dump_debug_info($link)))
+ printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_bool($tmp = $mysqli->dump_debug_info()))
+ printf("[003] Expecting boolean/[true|false] value, got %s/%s, [%d] %s\n",
+ gettype($tmp), $tmp,
+ $mysqli->errno, $mysqli->error);
+
+ $mysqli->close();
+
+ if (NULL !== ($tmp = $mysqli->dump_debug_info()))
+ printf("[004] Expecting NULL, got %s/%s, [%d] %s\n",
+ gettype($tmp), $tmp,
+ $mysqli->errno, $mysqli->error);
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli::dump_debug_info(): Couldn't fetch mysqli in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_embedded_connect.phpt b/ext/mysqli/tests/mysqli_embedded_connect.phpt
new file mode 100644
index 0000000000..5ee5fa76a1
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_embedded_connect.phpt
@@ -0,0 +1,32 @@
+--TEST--
+mysqli_embedded_connect()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifnotemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ $tmp = NULL;
+ $link = NULL;
+
+ if (NULL !== ($tmp = @mysqli_embedded_connect()))
+ printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!$link = mysqli_embedded_connect($db)) {
+ printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+ }
+
+ if (!is_bool($tmp = mysqli_embedded_connect($db . '_unknown')))
+ printf("[003] Expecting boolean/[true|false] value, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_close($link);
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_embedded_connect() expects parameter 1 to be mysqli, null given in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt b/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt
new file mode 100644
index 0000000000..2228f3d6c5
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt
@@ -0,0 +1,43 @@
+--TEST--
+mysqli_enable_reads_from_master()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+if (!function_exists('mysqli_enable_reads_from_master')) {
+ die("skip function mysqli_enable_reads_from_master() not available\n");
+}
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (NULL !== ($tmp = @mysqli_enable_reads_from_master()))
+ printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (NULL !== ($tmp = @mysqli_enable_reads_from_master($link)))
+ printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ 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);
+ }
+
+ if (!is_bool($tmp = mysqli_enable_reads_from_master($link)))
+ printf("[004] Expecting boolean/[true|false] value, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_close($link);
+
+ if (NULL !== ($tmp = mysqli_enable_reads_from_master($link)))
+ printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_enable_reads_from_master(): Couldn't fetch mysqli in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_enable_rpl_parse.phpt b/ext/mysqli/tests/mysqli_enable_rpl_parse.phpt
new file mode 100644
index 0000000000..b2664d93f0
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_enable_rpl_parse.phpt
@@ -0,0 +1,41 @@
+--TEST--
+mysqli_enable_rpl_parse()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+if (!function_exists('mysqli_enable_rpl_parse'))
+ die("skip mysqli_enable_rpl_parse() not available");
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (NULL !== ($tmp = @mysqli_enable_rpl_parse()))
+ printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (NULL !== ($tmp = @mysqli_enable_rpl_parse($link)))
+ printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ 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);
+ }
+
+ if (!is_bool($tmp = mysqli_enable_rpl_parse($link)))
+ printf("[004] Expecting boolean/[true|false] value, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_close($link);
+
+ if (NULL !== ($tmp = mysqli_enable_rpl_parse($link)))
+ printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_enable_rpl_parse(): Couldn't fetch mysqli in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_errno.phpt b/ext/mysqli/tests/mysqli_errno.phpt
new file mode 100644
index 0000000000..c57b037262
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_errno.phpt
@@ -0,0 +1,52 @@
+--TEST--
+mysqli_errno()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_errno()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_errno($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ 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);
+}
+
+ var_dump(mysqli_errno($link));
+
+ if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) {
+ printf("[004] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ mysqli_query($link, 'SELECT * FROM test');
+ var_dump(mysqli_errno($link));
+
+ @mysqli_query($link, 'No SQL');
+ if (($tmp = mysqli_errno($link)) == 0)
+ printf("[005] Expecting int/any non zero got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_close($link);
+
+ var_dump(mysqli_errno($link));
+
+ print "done!";
+?>
+--EXPECTF--
+int(0)
+int(%d)
+
+Warning: mysqli_errno(): Couldn't fetch mysqli in %s on line %d
+NULL
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_errno_oo.phpt b/ext/mysqli/tests/mysqli_errno_oo.phpt
new file mode 100644
index 0000000000..09f7d6ed32
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_errno_oo.phpt
@@ -0,0 +1,49 @@
+--TEST--
+$mysqli->errno
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ $mysqli = new mysqli();
+ if (!is_null($tmp = @$mysqli->errno))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket))
+ printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+
+ var_dump($mysqli->errno);
+
+ if (!$mysqli->query('DROP TABLE IF EXISTS test')) {
+ printf("[003] Failed to drop old test table: [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ $mysqli->query('SELECT * FROM test');
+ var_dump($mysqli->errno);
+
+ @$mysqli->query('No SQL');
+ if (($tmp = $mysqli->errno) === 0)
+ printf("[004] Expecting int/any non zero got %s/%s\n", gettype($tmp), $tmp);
+
+ $mysqli->close();
+
+ var_dump($mysqli->errno);
+
+ print "done!";
+?>
+--EXPECTF--
+int(0)
+int(%d)
+
+Warning: main(): Couldn't fetch mysqli in %s on line %d
+NULL
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_error.phpt b/ext/mysqli/tests/mysqli_error.phpt
new file mode 100644
index 0000000000..8a2a749a60
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_error.phpt
@@ -0,0 +1,49 @@
+--TEST--
+mysqli_error()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_error()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_error($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ 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);
+ }
+
+ $tmp = mysqli_error($link);
+ if (!is_string($tmp) || ('' !== $tmp))
+ printf("[004] Expecting string/empty, got %s/%s. [%d] %s\n", gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link));
+
+ if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) {
+ printf("[005] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ mysqli_query($link, 'SELECT * FROM test');
+ $tmp = mysqli_error($link);
+ if (!is_string($tmp) || !preg_match("/Table '\w*\.test' doesn't exist/su", $tmp))
+ printf("[006] Expecting string/[Table... doesn't exit], got %s/%s. [%d] %s\n", gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link));
+
+ mysqli_close($link);
+
+ var_dump(mysqli_error($link));
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_error(): Couldn't fetch mysqli in %s on line %d
+NULL
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_error_oo.phpt b/ext/mysqli/tests/mysqli_error_oo.phpt
new file mode 100644
index 0000000000..456f8f9a35
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_error_oo.phpt
@@ -0,0 +1,46 @@
+--TEST--
+$mysqli->error
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ $mysqli = new mysqli();
+ if (!is_null($tmp = @$mysqli->error))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket))
+ printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+
+ $tmp = $mysqli->error;
+ if (!is_string($tmp) || ('' !== $tmp))
+ printf("[003] Expecting string/empty, got %s/%s. [%d] %s\n", gettype($tmp), $tmp, $mysqli->errno, $mysqli->error);
+
+ if (!$mysqli->query('DROP TABLE IF EXISTS test')) {
+ printf("[004] Failed to drop old test table: [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ $mysqli->query('SELECT * FROM test');
+ $tmp = $mysqli->error;
+ if (!is_string($tmp) || !preg_match("/Table '\w*\.test' doesn't exist/su", $tmp))
+ printf("[006] Expecting string/[Table... doesn't exit], got %s/%s. [%d] %s\n", gettype($tmp), $tmp, $mysqli->errno, $mysqli->error);
+
+ $mysqli->close();
+
+ var_dump($mysqli->error);
+
+ print "done!";
+?>
+--EXPECTF--
+Warning: main(): Couldn't fetch mysqli in %s on line %d
+NULL
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_error_unicode.phpt b/ext/mysqli/tests/mysqli_error_unicode.phpt
new file mode 100644
index 0000000000..b622f2897e
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_error_unicode.phpt
@@ -0,0 +1,57 @@
+--TEST--
+mysqli_error()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_error()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_error($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ 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);
+ }
+
+ if (!ini_get("unicode.semantics")) {
+ mysqli_query($link, "set names utf8");
+ }
+
+ $tmp = mysqli_error($link);
+ if (!is_string($tmp) || ('' !== $tmp))
+ printf("[004] Expecting string/empty, got %s/%s. [%d] %s\n", gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link));
+
+
+ mysqli_query($link, 'SELECT * FROM няма_такава_таблица');
+ $tmp = mysqli_error($link);
+ var_dump(str_replace($db.".", "", $tmp));
+
+ mysqli_close($link);
+
+ var_dump(mysqli_error($link));
+
+ print "done!";
+?>
+--EXPECTF--
+string(58) "Table 'няма_такава_таблица' doesn't exist"
+
+Warning: mysqli_error(): Couldn't fetch mysqli in %s on line %d
+NULL
+done!
+--UEXPECTF--
+unicode(41) "Table 'няма_такава_таблица' doesn't exist"
+
+Warning: mysqli_error(): Couldn't fetch mysqli in %s on line %d
+NULL
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_explain_metadata.phpt b/ext/mysqli/tests/mysqli_explain_metadata.phpt
new file mode 100644
index 0000000000..a8cc59d7cf
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_explain_metadata.phpt
@@ -0,0 +1,155 @@
+--TEST--
+EXPLAIN - metadata
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ require_once('connect.inc');
+ require_once('table.inc');
+
+ if (!$res = mysqli_query($link, 'EXPLAIN SELECT t1.*, t2.* FROM test AS t1, test AS t2'))
+ printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ $num_rows = 0;
+ $num_fields = 0;
+ $field_names = array();
+ if (!$row = mysqli_fetch_assoc($res)) {
+ printf("[002] Expecting result but got no data [%d] %s\n",
+ mysqli_errno($link), mysqli_error($link));
+ } else {
+ $num_rows++;
+ $num_fields = count($row);
+ foreach ($row as $name => $value)
+ $field_names[$name] = gettype($value);
+ }
+
+ while ($row = mysqli_fetch_assoc($res))
+ $num_rows++;
+
+ if (($tmp = mysqli_num_rows($res)) !== $num_rows) {
+ printf("[003] Expecting int/%d got %s/%s\n",
+ $num_rows, gettype($tmp), $tmp);
+ }
+ if (($tmp = mysqli_field_count($link)) !== $num_fields) {
+ printf("[004] Expecting int/%d got %s/%s\n",
+ $num_fields, gettype($tmp), $tmp);
+ }
+ $fields = mysqli_fetch_fields($res);
+ if (($tmp = count($fields)) !== $num_fields) {
+ printf("[005] Expecting int/%d got %s/%s\n",
+ $num_fields, gettype($tmp), $tmp);
+ }
+
+ foreach ($fields as $k => $field) {
+ $field->max_length = 0;// change it or we will get diff error
+ if (isset($field_names[$field->name])) {
+ unset($field_names[$field->name]);
+ } else {
+ printf("[006] Unexpected field '%s', dumping info\n");
+ var_dump($field);
+ }
+ }
+ if (!empty($field_names)) {
+ printf("[007] Field descriptions missing for the following columns\n");
+ var_dump($field_names);
+ }
+
+ mysqli_free_result($res);
+
+ $stmt = mysqli_stmt_init($link);
+ /* Depending on your version, the MySQL server migit not support this */
+ if ($stmt->prepare('EXPLAIN SELECT t1.*, t2.* FROM test AS t1, test AS t2') && $stmt->execute()) {
+ if (!mysqli_stmt_store_result($stmt))
+ printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (!$res_meta = mysqli_stmt_result_metadata($stmt))
+ printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+
+ if (($tmp = mysqli_stmt_num_rows($stmt)) !== $num_rows) {
+ printf("[010] Expecting int/%d got %s/%s\n",
+ $num_rows, gettype($tmp), $tmp);
+ }
+ if (($tmp = mysqli_stmt_field_count($stmt)) !== $num_fields) {
+ printf("[011] Expecting int/%d got %s/%s\n",
+ $num_fields, gettype($tmp), $tmp);
+ }
+ if (($tmp = mysqli_field_count($link)) !== $num_fields) {
+ printf("[013] Expecting int/%d got %s/%s\n",
+ $num_fields, gettype($tmp), $tmp);
+ }
+ if (($tmp = $res_meta->field_count) !== $num_fields) {
+ printf("[014] Expecting int/%d got %s/%s\n",
+ $num_fields, gettype($tmp), $tmp);
+ }
+ $fields_res_meta = mysqli_fetch_fields($res_meta);
+ if (($tmp = count($fields_res_meta)) !== $num_fields)
+ printf("[015] Expecting int/%d got %s/%s\n",
+ $num_fields, gettype($tmp), $tmp);
+
+ if ($fields_res_meta != $fields) {
+ printf("[016] Prepared Statement metadata differs from normal metadata, dumping\n");
+ var_dump($fields_res_meta);
+ var_dump($fields);
+ }
+
+ if (function_exists('mysqli_stmt_get_result') &&
+ $stmt->prepare('EXPLAIN SELECT t1.*, t2.* FROM test AS t1, test AS t2') &&
+ $stmt->execute()) {
+ if (!$res_stmt = mysqli_stmt_get_result($stmt)) {
+ printf("[017] Cannot fetch result from PS [%d] %s\n",
+ mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
+ }
+ if (($tmp = mysqli_num_rows($res_stmt)) !== $num_rows) {
+ printf("[018] Expecting int/%d got %s/%s\n",
+ $num_rows, gettype($tmp), $tmp);
+ }
+ if ((mysqli_stmt_num_rows($stmt)) !== 0) {
+ printf("[019] Expecting int/0 got %s/%s\n", gettype($tmp), $tmp);
+ }
+ if (($tmp = mysqli_stmt_field_count($stmt)) !== $num_fields) {
+ printf("[020] Expecting int/%d got %s/%s\n",
+ $num_fields, gettype($tmp), $tmp);
+
+ }
+ if (($tmp = $res_stmt->field_count) !== $num_fields) {
+ printf("[021] Expecting int/%d got %s/%s\n",
+ $num_fields, gettype($tmp), $tmp);
+ }
+
+ $fields_stmt = mysqli_fetch_fields($res_stmt);
+ if (($tmp = count($fields_stmt)) !== $num_fields) {
+ printf("[022] Expecting int/%d got %s/%s\n",
+ $num_fields, gettype($tmp), $tmp);
+ }
+ reset($fields);
+ foreach ($fields_stmt as $fields_stmt_val) {
+ list(,$fields_val) = each($fields);
+ unset($fields_stmt_val->max_length);
+ unset($fields_val->max_length);
+ if ($fields_stmt_val != $fields_val) {
+ printf("[023] PS mysqli_stmt_get_result() metadata seems wrong, dumping\n");
+ var_dump($fields_stmt_val);
+ var_dump($fields_val);
+ }
+ }
+/*
+ if ($fields_stmt != $fields) {
+ printf("[023] PS mysqli_stmt_get_result() metadata seems wrong, dumping\n");
+ var_dump($fields_stmt);
+ var_dump($fields);
+ }
+*/
+ mysqli_free_result($res_stmt);
+ }
+ }
+ mysqli_stmt_close($stmt);
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+done!
diff --git a/ext/mysqli/tests/mysqli_fetch_all.phpt b/ext/mysqli/tests/mysqli_fetch_all.phpt
new file mode 100644
index 0000000000..f93d204a67
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_all.phpt
@@ -0,0 +1,561 @@
+--TEST--
+mysqli_fetch_all()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+if (!function_exists('mysqli_fetch_all'))
+ die("skip: function only available with mysqlnd");
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_fetch_all()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_fetch_all($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 2")) {
+ printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ print "[005]\n";
+ var_dump(mysqli_fetch_all($res));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 2")) {
+ printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ print "[007]\n";
+ var_dump(mysqli_fetch_all($res, MYSQLI_NUM));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 2")) {
+ printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ print "[008]\n";
+ var_dump(mysqli_fetch_all($res, MYSQLI_BOTH));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 2")) {
+ printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ print "[010]\n";
+ var_dump(mysqli_fetch_all($res, MYSQLI_ASSOC));
+
+ print "[011]\n";
+ var_dump(mysqli_fetch_all($res));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 2")) {
+ printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ print "[013]\n";
+ var_dump(mysqli_fetch_all($res, MYSQLI_ASSOC));
+
+ print "[016]\n";
+ var_dump(mysqli_fetch_all($res));
+
+ if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) {
+ printf("[010] Cannot run query, [%d] %s\n", mysqli_errno($link), $mysqli_error($link));
+ }
+ print "[017]\n";
+ var_dump(mysqli_fetch_all($res, MYSQLI_BOTH));
+
+ mysqli_free_result($res);
+ if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS C")) {
+ printf("[018] Cannot run query, [%d] %s\n",
+ mysqli_errno($link), $mysqli_error($link));
+ exit(1);
+ }
+
+ do {
+ $illegal_mode = mt_rand(-10000, 10000);
+ } while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH)));
+ // NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes.
+ $tmp = mysqli_fetch_all($res, $illegal_mode);
+ if (false !== $tmp)
+ printf("[019] Expecting boolean/false although, got %s/%s. [%d] %s\n",
+ gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link));
+
+ mysqli_free_result($res);
+
+ function func_mysqli_fetch_all($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL) {
+
+ if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) {
+ printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+ if (!mysqli_query($link, $sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) {
+ print $sql;
+ // don't bail, engine might not support the datatype
+ return false;
+ }
+
+ if (is_null($php_value) && !mysqli_query($link, $sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+ if (!is_null($php_value)) {
+ if (is_int($sql_value) && !mysqli_query($link, sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link));
+ return false;
+ } else if (!is_int($sql_value) && !mysqli_query($link, sprintf("INSERT INTO test(id, label) VALUES (1, '%s')", $sql_value))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+ }
+
+ if (!$res = mysqli_query($link, "SELECT id, label FROM test")) {
+ printf("[%04d] [%d] %s\n", $offset + 2, mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+ if (!$tmp = mysqli_fetch_all($res, MYSQLI_BOTH)) {
+ printf("[%04d] [%d] %s\n", $offset + 3, mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+ $row = $tmp[0];
+
+ $fields = mysqli_fetch_fields($res);
+
+ if (!(gettype($php_value)=="unicode" && ($fields[1]->flags & 128))) {
+
+ if ($regexp_comparison) {
+ if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) {
+ printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4,
+ gettype($php_value), $php_value, $regexp_comparison,
+ gettype($row[1]), $row[1],
+ gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+ } else {
+ if (($row['label'] !== $php_value) || ($row[1] != $php_value)) {
+ printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4,
+ gettype($php_value), $php_value,
+ gettype($row[1]), $row[1],
+ gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ function func_mysqli_fetch_array_make_string($len) {
+
+ $ret = '';
+ for ($i = 0; $i < $len; $i++)
+ $ret .= chr(mt_rand(65, 90));
+
+ return $ret;
+ }
+
+ func_mysqli_fetch_all($link, $engine, "TINYINT", -11, "-11", 20);
+ func_mysqli_fetch_all($link, $engine, "TINYINT", NULL, NULL, 30);
+ func_mysqli_fetch_all($link, $engine, "TINYINT UNSIGNED", 1, "1", 40);
+ func_mysqli_fetch_all($link, $engine, "TINYINT UNSIGNED", NULL, NULL, 50);
+
+ func_mysqli_fetch_all($link, $engine, "BOOL", 1, "1", 60);
+ func_mysqli_fetch_all($link, $engine, "BOOL", NULL, NULL, 70);
+ func_mysqli_fetch_all($link, $engine, "BOOLEAN", 0, "0", 80);
+ func_mysqli_fetch_all($link, $engine, "BOOLEAN", NULL, NULL, 90);
+
+ func_mysqli_fetch_all($link, $engine, "SMALLINT", -32768, "-32768", 100);
+ func_mysqli_fetch_all($link, $engine, "SMALLINT", 32767, "32767", 110);
+ func_mysqli_fetch_all($link, $engine, "SMALLINT", NULL, NULL, 120);
+ func_mysqli_fetch_all($link, $engine, "SMALLINT UNSIGNED", 65535, "65535", 130);
+ func_mysqli_fetch_all($link, $engine, "SMALLINT UNSIGNED", NULL, NULL, 140);
+
+ func_mysqli_fetch_all($link, $engine, "MEDIUMINT", -8388608, "-8388608", 150);
+ func_mysqli_fetch_all($link, $engine, "MEDIUMINT", 8388607, "8388607", 160);
+ func_mysqli_fetch_all($link, $engine, "MEDIUMINT", NULL, NULL, 170);
+ func_mysqli_fetch_all($link, $engine, "MEDIUMINT UNSIGNED", 16777215, "16777215", 180);
+ func_mysqli_fetch_all($link, $engine, "MEDIUMINT UNSIGNED", NULL, NULL, 190);
+
+ func_mysqli_fetch_all($link, $engine, "INTEGER", -2147483648, "-2147483648", 200);
+ func_mysqli_fetch_all($link, $engine, "INTEGER", 2147483647, "2147483647", 210);
+ func_mysqli_fetch_all($link, $engine, "INTEGER", NULL, NULL, 220);
+ func_mysqli_fetch_all($link, $engine, "INTEGER UNSIGNED", 4294967295, "4294967295", 230);
+ func_mysqli_fetch_all($link, $engine, "INTEGER UNSIGNED", NULL, NULL, 240);
+
+ func_mysqli_fetch_all($link, $engine, "BIGINT", -9223372036854775808, "-9223372036854775808", 250);
+ func_mysqli_fetch_all($link, $engine, "BIGINT", NULL, NULL, 260);
+ func_mysqli_fetch_all($link, $engine, "BIGINT UNSIGNED", 18446744073709551615, "18446744073709551615", 270);
+ func_mysqli_fetch_all($link, $engine, "BIGINT UNSIGNED", NULL, NULL, 280);
+
+ func_mysqli_fetch_all($link, $engine, "FLOAT", -9223372036854775808 - 1.1, "-9.22337e+18", 290, "/-9\.22337e\+[0]?18/iu");
+ func_mysqli_fetch_all($link, $engine, "FLOAT", NULL, NULL, 300);
+ func_mysqli_fetch_all($link, $engine, "FLOAT UNSIGNED", 18446744073709551615 + 1.1, "1.84467e+19", 310, "/1\.84467e\+[0]?19/iu");
+ func_mysqli_fetch_all($link, $engine, "FLOAT UNSIGNED ", NULL, NULL, 320);
+
+ func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2)", -99999999.99, "-99999999.99", 330);
+ func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2)", NULL, NULL, 340);
+ func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2) UNSIGNED", 99999999.99, "99999999.99", 350);
+ func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2) UNSIGNED", NULL, NULL, 360);
+
+ func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", -99999999.99, "-99999999.99", 370);
+ func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", NULL, NULL, 380);
+ func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", 99999999.99, "99999999.99", 390);
+ func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", NULL, NULL, 400);
+
+ // don't care about date() strict TZ warnings...
+ func_mysqli_fetch_all($link, $engine, "DATE", @date('Y-m-d'), @date('Y-m-d'), 410);
+ func_mysqli_fetch_all($link, $engine, "DATE NOT NULL", @date('Y-m-d'), @date('Y-m-d'), 420);
+ func_mysqli_fetch_all($link, $engine, "DATE", NULL, NULL, 430);
+
+ func_mysqli_fetch_all($link, $engine, "DATETIME", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 440);
+ func_mysqli_fetch_all($link, $engine, "DATETIME NOT NULL", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 450);
+ func_mysqli_fetch_all($link, $engine, "DATETIME", NULL, NULL, 460);
+
+ func_mysqli_fetch_all($link, $engine, "TIMESTAMP", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 470);
+
+ func_mysqli_fetch_all($link, $engine, "TIME", @date('H:i:s'), @date('H:i:s'), 480);
+ func_mysqli_fetch_all($link, $engine, "TIME NOT NULL", @date('H:i:s'), @date('H:i:s'), 490);
+ func_mysqli_fetch_all($link, $engine, "TIME", NULL, NULL, 500);
+
+ func_mysqli_fetch_all($link, $engine, "YEAR", @date('Y'), @date('Y'), 510);
+ func_mysqli_fetch_all($link, $engine, "YEAR NOT NULL", @date('Y'), @date('Y'), 520);
+ func_mysqli_fetch_all($link, $engine, "YEAR", NULL, NULL, 530);
+
+ $string255 = func_mysqli_fetch_array_make_string(255);
+ func_mysqli_fetch_all($link, $engine, "CHAR(1)", "a", "a", 540);
+ func_mysqli_fetch_all($link, $engine, "CHAR(255)", $string255, $string255, 550);
+ func_mysqli_fetch_all($link, $engine, "CHAR(1) NOT NULL", "a", "a", 560);
+ func_mysqli_fetch_all($link, $engine, "CHAR(1)", NULL, NULL, 570);
+
+ $string65k = func_mysqli_fetch_array_make_string(65535);
+ func_mysqli_fetch_all($link, $engine, "VARCHAR(1)", "a", "a", 580);
+ func_mysqli_fetch_all($link, $engine, "VARCHAR(255)", $string255, $string255, 590);
+ func_mysqli_fetch_all($link, $engine, "VARCHAR(65635)", $string65k, $string65k, 600);
+ func_mysqli_fetch_all($link, $engine, "VARCHAR(1) NOT NULL", "a", "a", 610);
+ func_mysqli_fetch_all($link, $engine, "VARCHAR(1)", NULL, NULL, 620);
+
+ func_mysqli_fetch_all($link, $engine, "BINARY(1)", "a", "a", 630);
+ func_mysqli_fetch_all($link, $engine, "BINARY(2)", chr(0) . "a", chr(0) . "a", 640);
+ func_mysqli_fetch_all($link, $engine, "BINARY(1) NOT NULL", "b", "b", 650);
+ func_mysqli_fetch_all($link, $engine, "BINARY(1)", NULL, NULL, 660);
+
+ func_mysqli_fetch_all($link, $engine, "VARBINARY(1)", "a", "a", 670);
+ func_mysqli_fetch_all($link, $engine, "VARBINARY(2)", chr(0) . "a", chr(0) . "a", 680);
+ func_mysqli_fetch_all($link, $engine, "VARBINARY(1) NOT NULL", "b", "b", 690);
+ func_mysqli_fetch_all($link, $engine, "VARBINARY(1)", NULL, NULL, 700);
+
+ func_mysqli_fetch_all($link, $engine, "TINYBLOB", "a", "a", 710);
+ func_mysqli_fetch_all($link, $engine, "TINYBLOB", chr(0) . "a", chr(0) . "a", 720);
+ func_mysqli_fetch_all($link, $engine, "TINYBLOB NOT NULL", "b", "b", 730);
+ func_mysqli_fetch_all($link, $engine, "TINYBLOB", NULL, NULL, 740);
+
+ func_mysqli_fetch_all($link, $engine, "TINYTEXT", "a", "a", 750);
+ func_mysqli_fetch_all($link, $engine, "TINYTEXT NOT NULL", "a", "a", 760);
+ func_mysqli_fetch_all($link, $engine, "TINYTEXT", NULL, NULL, 770);
+
+ func_mysqli_fetch_all($link, $engine, "BLOB", "a", "a", 780);
+ func_mysqli_fetch_all($link, $engine, "BLOB", chr(0) . "a", chr(0) . "a", 780);
+ func_mysqli_fetch_all($link, $engine, "BLOB", NULL, NULL, 790);
+
+ func_mysqli_fetch_all($link, $engine, "TEXT", "a", "a", 800);
+ func_mysqli_fetch_all($link, $engine, "TEXT", chr(0) . "a", chr(0) . "a", 810);
+ func_mysqli_fetch_all($link, $engine, "TEXT", NULL, NULL, 820);
+
+ func_mysqli_fetch_all($link, $engine, "MEDIUMBLOB", "a", "a", 830);
+ func_mysqli_fetch_all($link, $engine, "MEDIUMBLOB", chr(0) . "a", chr(0) . "a", 840);
+ func_mysqli_fetch_all($link, $engine, "MEDIUMBLOB", NULL, NULL, 850);
+
+ func_mysqli_fetch_all($link, $engine, "MEDIUMTEXT", "a", "a", 860);
+ func_mysqli_fetch_all($link, $engine, "MEDIUMTEXT", chr(0) . "a", chr(0) . "a", 870);
+ func_mysqli_fetch_all($link, $engine, "MEDIUMTEXT", NULL, NULL, 880);
+
+ func_mysqli_fetch_all($link, $engine, "LONGBLOB", "a", "a", 890);
+ func_mysqli_fetch_all($link, $engine, "LONGTEXT", chr(0) . "a", chr(0) . "a", 900);
+ func_mysqli_fetch_all($link, $engine, "LONGBLOB", NULL, NULL, 910);
+
+ func_mysqli_fetch_all($link, $engine, "ENUM('a', 'b')", "a", "a", 920);
+ func_mysqli_fetch_all($link, $engine, "ENUM('a', 'b')", NULL, NULL, 930);
+
+ func_mysqli_fetch_all($link, $engine, "SET('a', 'b')", "a", "a", 940);
+ func_mysqli_fetch_all($link, $engine, "SET('a', 'b')", NULL, NULL, 950);
+
+ mysqli_close($link);
+
+ if (null !== ($tmp = mysqli_fetch_array($res, MYSQLI_ASSOC)))
+ printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ print "done!";
+?>
+--EXPECTF--
+[005]
+array(2) {
+ [0]=>
+ array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ string(1) "2"
+ [1]=>
+ string(1) "b"
+ }
+}
+[007]
+array(2) {
+ [0]=>
+ array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ string(1) "2"
+ [1]=>
+ string(1) "b"
+ }
+}
+[008]
+array(2) {
+ [0]=>
+ array(4) {
+ [0]=>
+ string(1) "1"
+ ["id"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "a"
+ ["label"]=>
+ string(1) "a"
+ }
+ [1]=>
+ array(4) {
+ [0]=>
+ string(1) "2"
+ ["id"]=>
+ string(1) "2"
+ [1]=>
+ string(1) "b"
+ ["label"]=>
+ string(1) "b"
+ }
+}
+[010]
+array(2) {
+ [0]=>
+ array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["label"]=>
+ string(1) "a"
+ }
+ [1]=>
+ array(2) {
+ ["id"]=>
+ string(1) "2"
+ ["label"]=>
+ string(1) "b"
+ }
+}
+[011]
+NULL
+[013]
+array(2) {
+ [0]=>
+ array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["label"]=>
+ string(1) "a"
+ }
+ [1]=>
+ array(2) {
+ ["id"]=>
+ string(1) "2"
+ ["label"]=>
+ string(1) "b"
+ }
+}
+[016]
+NULL
+[017]
+array(1) {
+ [0]=>
+ array(11) {
+ [0]=>
+ string(1) "1"
+ ["a"]=>
+ string(1) "2"
+ [1]=>
+ string(1) "2"
+ [2]=>
+ string(1) "3"
+ ["c"]=>
+ string(1) "3"
+ [3]=>
+ string(1) "4"
+ ["C"]=>
+ string(1) "4"
+ [4]=>
+ NULL
+ ["d"]=>
+ NULL
+ [5]=>
+ string(1) "1"
+ ["e"]=>
+ string(1) "1"
+ }
+}
+
+Warning: mysqli_fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH in %s on line %d
+
+Warning: mysqli_fetch_array(): Couldn't fetch mysqli_result in %s on line %d
+done!
+--UEXPECTF--
+[005]
+array(2) {
+ [0]=>
+ array(2) {
+ [0]=>
+ unicode(1) "1"
+ [1]=>
+ unicode(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "b"
+ }
+}
+[007]
+array(2) {
+ [0]=>
+ array(2) {
+ [0]=>
+ unicode(1) "1"
+ [1]=>
+ unicode(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "b"
+ }
+}
+[008]
+array(2) {
+ [0]=>
+ array(4) {
+ [0]=>
+ unicode(1) "1"
+ [u"id"]=>
+ unicode(1) "1"
+ [1]=>
+ unicode(1) "a"
+ [u"label"]=>
+ unicode(1) "a"
+ }
+ [1]=>
+ array(4) {
+ [0]=>
+ unicode(1) "2"
+ [u"id"]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "b"
+ [u"label"]=>
+ unicode(1) "b"
+ }
+}
+[010]
+array(2) {
+ [0]=>
+ array(2) {
+ [u"id"]=>
+ unicode(1) "1"
+ [u"label"]=>
+ unicode(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [u"id"]=>
+ unicode(1) "2"
+ [u"label"]=>
+ unicode(1) "b"
+ }
+}
+[011]
+NULL
+[013]
+array(2) {
+ [0]=>
+ array(2) {
+ [u"id"]=>
+ unicode(1) "1"
+ [u"label"]=>
+ unicode(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [u"id"]=>
+ unicode(1) "2"
+ [u"label"]=>
+ unicode(1) "b"
+ }
+}
+[016]
+NULL
+[017]
+array(1) {
+ [0]=>
+ array(11) {
+ [0]=>
+ unicode(1) "1"
+ [u"a"]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "2"
+ [2]=>
+ unicode(1) "3"
+ [u"c"]=>
+ unicode(1) "3"
+ [3]=>
+ unicode(1) "4"
+ [u"C"]=>
+ unicode(1) "4"
+ [4]=>
+ NULL
+ [u"d"]=>
+ NULL
+ [5]=>
+ unicode(1) "1"
+ [u"e"]=>
+ unicode(1) "1"
+ }
+}
+
+Warning: mysqli_fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH in %s on line %d
+
+Warning: mysqli_fetch_array(): Couldn't fetch mysqli_result in %s on line %d
+done!
diff --git a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt
new file mode 100644
index 0000000000..fcbc52e782
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt
@@ -0,0 +1,564 @@
+--TEST--
+$mysqli->fetch_all() (introduced with mysqlnd)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+if (!function_exists('mysqli_fetch_all'))
+ die("skip: function only available with mysqlnd");
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ $mysqli = new mysqli();
+
+ if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket))
+ printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+
+ require('table.inc');
+ if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 2")) {
+ printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ print "[005]\n";
+ var_dump($res->fetch_all());
+ $res->free_result();
+
+ if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 2")) {
+ printf("[006] [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ print "[007]\n";
+ var_dump($res->fetch_all(MYSQLI_NUM));
+ $res->free_result();
+
+ if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 2")) {
+ printf("[008] [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ print "[008]\n";
+ var_dump($res->fetch_all(MYSQLI_BOTH));
+ $res->free_result();
+
+ if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 2")) {
+ printf("[009] [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ print "[010]\n";
+ var_dump($res->fetch_all(MYSQLI_ASSOC));
+
+ print "[011]\n";
+ var_dump($res->fetch_array());
+ $res->free_result();
+
+ if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 2")) {
+ printf("[012] [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ print "[013]\n";
+ var_dump($res->fetch_all(MYSQLI_ASSOC));
+
+ print "[016]\n";
+ var_dump($res->fetch_array());
+
+ if (!$res = $mysqli->query("SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) {
+ printf("[010] Cannot run query, [%d] %s\n", $mysqli->errno, $$mysqli->error);
+ }
+ print "[017]\n";
+ var_dump($res->fetch_all(MYSQLI_BOTH));
+
+ $res->free_result();
+ if (!$res = $mysqli->query("SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS C")) {
+ printf("[018] Cannot run query, [%d] %s\n",
+ $mysqli->errno, $$mysqli->error);
+ exit(1);
+ }
+
+ do {
+ $illegal_mode = mt_rand(-10000, 10000);
+ } while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH)));
+ // NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes.
+ $tmp = $res->fetch_all($illegal_mode);
+ if (false !== $tmp)
+ printf("[019] Expecting boolean/false although, got %s/%s. [%d] %s\n",
+ gettype($tmp), $tmp, $mysqli->errno, $mysqli->error);
+
+ $res->free_result();
+
+ function func_mysqli_fetch_all_oo($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL) {
+
+ if (!$link->query("DROP TABLE IF EXISTS test")) {
+ printf("[%04d] [%d] %s\n", $offset, $link->errno, $link->error);
+ return false;
+ }
+
+ if (!$link->query($sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) {
+ print $sql;
+ // don't bail, engine might not support the datatype
+ return false;
+ }
+
+ if (is_null($php_value) && !$link->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, $link->errno, $link->error);
+ return false;
+ }
+
+ if (!is_null($php_value)) {
+ if (is_int($sql_value) && !$link->query(sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, $link->errno, $link->error);
+ return false;
+ } else if (!is_int($sql_value) && !$link->query(sprintf("INSERT INTO test(id, label) VALUES (1, '%s')", $sql_value))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, $link->errno, $link->error);
+ return false;
+ }
+ }
+
+ if (!$res = $link->query("SELECT id, label FROM test")) {
+ printf("[%04d] [%d] %s\n", $offset + 2, $link->errno, $link->error);
+ return false;
+ }
+
+ if (!$tmp = $res->fetch_all(MYSQLI_BOTH)) {
+ printf("[%04d] [%d] %s\n", $offset + 3, $link->errno, $link->error);
+ return false;
+ }
+ $row = $tmp[0];
+
+ $fields = mysqli_fetch_fields($res);
+
+ if (!(gettype($php_value)=="unicode" && ($fields[1]->flags & 128))) {
+ if ($regexp_comparison) {
+ if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) {
+ printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4,
+ gettype($php_value), $php_value, $regexp_comparison,
+ gettype($row[1]), $row[1],
+ gettype($row['label']), $row['label'], $link->errno, $link->error);
+ return false;
+ }
+ } else {
+ if (($row['label'] !== $php_value) || ($row[1] != $php_value)) {
+ printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4,
+ gettype($php_value), $php_value,
+ gettype($row[1]), $row[1],
+ gettype($row['label']), $row['label'], $link->errno, $link->error);
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ function func_mysqli_fetch_array_oo_make_string($len) {
+
+ $ret = '';
+ for ($i = 0; $i < $len; $i++)
+ $ret .= chr(mt_rand(65, 90));
+
+ return $ret;
+ }
+
+ func_mysqli_fetch_all_oo($link, $engine, "TINYINT", -11, "-11", 20);
+ func_mysqli_fetch_all_oo($link, $engine, "TINYINT", NULL, NULL, 30);
+ func_mysqli_fetch_all_oo($link, $engine, "TINYINT UNSIGNED", 1, "1", 40);
+ func_mysqli_fetch_all_oo($link, $engine, "TINYINT UNSIGNED", NULL, NULL, 50);
+
+ func_mysqli_fetch_all_oo($link, $engine, "BOOL", 1, "1", 60);
+ func_mysqli_fetch_all_oo($link, $engine, "BOOL", NULL, NULL, 70);
+ func_mysqli_fetch_all_oo($link, $engine, "BOOLEAN", 0, "0", 80);
+ func_mysqli_fetch_all_oo($link, $engine, "BOOLEAN", NULL, NULL, 90);
+
+ func_mysqli_fetch_all_oo($link, $engine, "SMALLINT", -32768, "-32768", 100);
+ func_mysqli_fetch_all_oo($link, $engine, "SMALLINT", 32767, "32767", 110);
+ func_mysqli_fetch_all_oo($link, $engine, "SMALLINT", NULL, NULL, 120);
+ func_mysqli_fetch_all_oo($link, $engine, "SMALLINT UNSIGNED", 65535, "65535", 130);
+ func_mysqli_fetch_all_oo($link, $engine, "SMALLINT UNSIGNED", NULL, NULL, 140);
+
+ func_mysqli_fetch_all_oo($link, $engine, "MEDIUMINT", -8388608, "-8388608", 150);
+ func_mysqli_fetch_all_oo($link, $engine, "MEDIUMINT", 8388607, "8388607", 160);
+ func_mysqli_fetch_all_oo($link, $engine, "MEDIUMINT", NULL, NULL, 170);
+ func_mysqli_fetch_all_oo($link, $engine, "MEDIUMINT UNSIGNED", 16777215, "16777215", 180);
+ func_mysqli_fetch_all_oo($link, $engine, "MEDIUMINT UNSIGNED", NULL, NULL, 190);
+
+ func_mysqli_fetch_all_oo($link, $engine, "INTEGER", -2147483648, "-2147483648", 200);
+ func_mysqli_fetch_all_oo($link, $engine, "INTEGER", 2147483647, "2147483647", 210);
+ func_mysqli_fetch_all_oo($link, $engine, "INTEGER", NULL, NULL, 220);
+ func_mysqli_fetch_all_oo($link, $engine, "INTEGER UNSIGNED", 4294967295, "4294967295", 230);
+ func_mysqli_fetch_all_oo($link, $engine, "INTEGER UNSIGNED", NULL, NULL, 240);
+
+ func_mysqli_fetch_all_oo($link, $engine, "BIGINT", -9223372036854775808, "-9223372036854775808", 250);
+ func_mysqli_fetch_all_oo($link, $engine, "BIGINT", NULL, NULL, 260);
+ func_mysqli_fetch_all_oo($link, $engine, "BIGINT UNSIGNED", 18446744073709551615, "18446744073709551615", 270);
+ func_mysqli_fetch_all_oo($link, $engine, "BIGINT UNSIGNED", NULL, NULL, 280);
+
+ func_mysqli_fetch_all_oo($link, $engine, "FLOAT", -9223372036854775808 - 1.1, "-9.22337e+18", 290, "/-9\.22337e\+[0]?18/iu");
+ func_mysqli_fetch_all_oo($link, $engine, "FLOAT", NULL, NULL, 300);
+ func_mysqli_fetch_all_oo($link, $engine, "FLOAT UNSIGNED", 18446744073709551615 + 1.1, "1.84467e+19", 310, "/1\.84467e\+[0]?19/iu");
+ func_mysqli_fetch_all_oo($link, $engine, "FLOAT UNSIGNED ", NULL, NULL, 320);
+
+ func_mysqli_fetch_all_oo($link, $engine, "DOUBLE(10,2)", -99999999.99, "-99999999.99", 330);
+ func_mysqli_fetch_all_oo($link, $engine, "DOUBLE(10,2)", NULL, NULL, 340);
+ func_mysqli_fetch_all_oo($link, $engine, "DOUBLE(10,2) UNSIGNED", 99999999.99, "99999999.99", 350);
+ func_mysqli_fetch_all_oo($link, $engine, "DOUBLE(10,2) UNSIGNED", NULL, NULL, 360);
+
+ func_mysqli_fetch_all_oo($link, $engine, "DECIMAL(10,2)", -99999999.99, "-99999999.99", 370);
+ func_mysqli_fetch_all_oo($link, $engine, "DECIMAL(10,2)", NULL, NULL, 380);
+ func_mysqli_fetch_all_oo($link, $engine, "DECIMAL(10,2)", 99999999.99, "99999999.99", 390);
+ func_mysqli_fetch_all_oo($link, $engine, "DECIMAL(10,2)", NULL, NULL, 400);
+
+ // don't care about date() strict TZ warnings...
+ $date = @date('Y-m-d');
+ func_mysqli_fetch_all_oo($link, $engine, "DATE", $date, $date, 410);
+ func_mysqli_fetch_all_oo($link, $engine, "DATE NOT NULL", $date, $date, 420);
+ func_mysqli_fetch_all_oo($link, $engine, "DATE", NULL, NULL, 430);
+
+ $datetime = @date('Y-m-d H:i:s');
+ func_mysqli_fetch_all_oo($link, $engine, "DATETIME", $datetime, $datetime, 440);
+ func_mysqli_fetch_all_oo($link, $engine, "DATETIME NOT NULL", $datetime, $datetime, 450);
+ func_mysqli_fetch_all_oo($link, $engine, "DATETIME", NULL, NULL, 460);
+
+ func_mysqli_fetch_all_oo($link, $engine, "TIMESTAMP", $datetime, $datetime, 470);
+
+ $time = @date('H:i:s');
+ func_mysqli_fetch_all_oo($link, $engine, "TIME", $time, $time, 480);
+ func_mysqli_fetch_all_oo($link, $engine, "TIME NOT NULL", $time, $time, 490);
+ func_mysqli_fetch_all_oo($link, $engine, "TIME", NULL, NULL, 500);
+
+ func_mysqli_fetch_all_oo($link, $engine, "YEAR", @date('Y'), @date('Y'), 510);
+ func_mysqli_fetch_all_oo($link, $engine, "YEAR NOT NULL", @date('Y'), @date('Y'), 520);
+ func_mysqli_fetch_all_oo($link, $engine, "YEAR", NULL, NULL, 530);
+
+ $string255 = func_mysqli_fetch_array_oo_make_string(255);
+ func_mysqli_fetch_all_oo($link, $engine, "CHAR(1)", "a", "a", 540);
+ func_mysqli_fetch_all_oo($link, $engine, "CHAR(255)", $string255, $string255, 550);
+ func_mysqli_fetch_all_oo($link, $engine, "CHAR(1) NOT NULL", "a", "a", 560);
+ func_mysqli_fetch_all_oo($link, $engine, "CHAR(1)", NULL, NULL, 570);
+
+ $string65k = func_mysqli_fetch_array_oo_make_string(65535);
+ func_mysqli_fetch_all_oo($link, $engine, "VARCHAR(1)", "a", "a", 580);
+ func_mysqli_fetch_all_oo($link, $engine, "VARCHAR(255)", $string255, $string255, 590);
+ func_mysqli_fetch_all_oo($link, $engine, "VARCHAR(65635)", $string65k, $string65k, 600);
+ func_mysqli_fetch_all_oo($link, $engine, "VARCHAR(1) NOT NULL", "a", "a", 610);
+ func_mysqli_fetch_all_oo($link, $engine, "VARCHAR(1)", NULL, NULL, 620);
+
+ func_mysqli_fetch_all_oo($link, $engine, "BINARY(1)", "a", "a", 630);
+ func_mysqli_fetch_all_oo($link, $engine, "BINARY(2)", chr(0) . "a", chr(0) . "a", 640);
+ func_mysqli_fetch_all_oo($link, $engine, "BINARY(1) NOT NULL", "b", "b", 650);
+ func_mysqli_fetch_all_oo($link, $engine, "BINARY(1)", NULL, NULL, 660);
+
+ func_mysqli_fetch_all_oo($link, $engine, "VARBINARY(1)", "a", "a", 670);
+ func_mysqli_fetch_all_oo($link, $engine, "VARBINARY(2)", chr(0) . "a", chr(0) . "a", 680);
+ func_mysqli_fetch_all_oo($link, $engine, "VARBINARY(1) NOT NULL", "b", "b", 690);
+ func_mysqli_fetch_all_oo($link, $engine, "VARBINARY(1)", NULL, NULL, 700);
+
+ func_mysqli_fetch_all_oo($link, $engine, "TINYBLOB", "a", "a", 710);
+ func_mysqli_fetch_all_oo($link, $engine, "TINYBLOB", chr(0) . "a", chr(0) . "a", 720);
+ func_mysqli_fetch_all_oo($link, $engine, "TINYBLOB NOT NULL", "b", "b", 730);
+ func_mysqli_fetch_all_oo($link, $engine, "TINYBLOB", NULL, NULL, 740);
+
+ func_mysqli_fetch_all_oo($link, $engine, "TINYTEXT", "a", "a", 750);
+ func_mysqli_fetch_all_oo($link, $engine, "TINYTEXT NOT NULL", "a", "a", 760);
+ func_mysqli_fetch_all_oo($link, $engine, "TINYTEXT", NULL, NULL, 770);
+
+ func_mysqli_fetch_all_oo($link, $engine, "BLOB", "a", "a", 780);
+ func_mysqli_fetch_all_oo($link, $engine, "BLOB", chr(0) . "a", chr(0) . "a", 780);
+ func_mysqli_fetch_all_oo($link, $engine, "BLOB", NULL, NULL, 790);
+
+ func_mysqli_fetch_all_oo($link, $engine, "TEXT", "a", "a", 800);
+ func_mysqli_fetch_all_oo($link, $engine, "TEXT", chr(0) . "a", chr(0) . "a", 810);
+ func_mysqli_fetch_all_oo($link, $engine, "TEXT", NULL, NULL, 820);
+
+ func_mysqli_fetch_all_oo($link, $engine, "MEDIUMBLOB", "a", "a", 830);
+ func_mysqli_fetch_all_oo($link, $engine, "MEDIUMBLOB", chr(0) . "a", chr(0) . "a", 840);
+ func_mysqli_fetch_all_oo($link, $engine, "MEDIUMBLOB", NULL, NULL, 850);
+
+ func_mysqli_fetch_all_oo($link, $engine, "MEDIUMTEXT", "a", "a", 860);
+ func_mysqli_fetch_all_oo($link, $engine, "MEDIUMTEXT", chr(0) . "a", chr(0) . "a", 870);
+ func_mysqli_fetch_all_oo($link, $engine, "MEDIUMTEXT", NULL, NULL, 880);
+
+ func_mysqli_fetch_all_oo($link, $engine, "LONGBLOB", "a", "a", 890);
+ func_mysqli_fetch_all_oo($link, $engine, "LONGTEXT", chr(0) . "a", chr(0) . "a", 900);
+ func_mysqli_fetch_all_oo($link, $engine, "LONGBLOB", NULL, NULL, 910);
+
+ func_mysqli_fetch_all_oo($link, $engine, "ENUM('a', 'b')", "a", "a", 920);
+ func_mysqli_fetch_all_oo($link, $engine, "ENUM('a', 'b')", NULL, NULL, 930);
+
+ func_mysqli_fetch_all_oo($link, $engine, "SET('a', 'b')", "a", "a", 940);
+ func_mysqli_fetch_all_oo($link, $engine, "SET('a', 'b')", NULL, NULL, 950);
+
+ mysqli_close($link);
+
+ if (null !== ($tmp = $res->fetch_array(MYSQLI_ASSOC)))
+ printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ print "done!";
+?>
+--EXPECTF--
+[005]
+array(2) {
+ [0]=>
+ array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ string(1) "2"
+ [1]=>
+ string(1) "b"
+ }
+}
+[007]
+array(2) {
+ [0]=>
+ array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ string(1) "2"
+ [1]=>
+ string(1) "b"
+ }
+}
+[008]
+array(2) {
+ [0]=>
+ array(4) {
+ [0]=>
+ string(1) "1"
+ ["id"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "a"
+ ["label"]=>
+ string(1) "a"
+ }
+ [1]=>
+ array(4) {
+ [0]=>
+ string(1) "2"
+ ["id"]=>
+ string(1) "2"
+ [1]=>
+ string(1) "b"
+ ["label"]=>
+ string(1) "b"
+ }
+}
+[010]
+array(2) {
+ [0]=>
+ array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["label"]=>
+ string(1) "a"
+ }
+ [1]=>
+ array(2) {
+ ["id"]=>
+ string(1) "2"
+ ["label"]=>
+ string(1) "b"
+ }
+}
+[011]
+NULL
+[013]
+array(2) {
+ [0]=>
+ array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["label"]=>
+ string(1) "a"
+ }
+ [1]=>
+ array(2) {
+ ["id"]=>
+ string(1) "2"
+ ["label"]=>
+ string(1) "b"
+ }
+}
+[016]
+NULL
+[017]
+array(1) {
+ [0]=>
+ array(11) {
+ [0]=>
+ string(1) "1"
+ ["a"]=>
+ string(1) "2"
+ [1]=>
+ string(1) "2"
+ [2]=>
+ string(1) "3"
+ ["c"]=>
+ string(1) "3"
+ [3]=>
+ string(1) "4"
+ ["C"]=>
+ string(1) "4"
+ [4]=>
+ NULL
+ ["d"]=>
+ NULL
+ [5]=>
+ string(1) "1"
+ ["e"]=>
+ string(1) "1"
+ }
+}
+
+Warning: mysqli_result::fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH in %s on line %d
+
+Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d
+done!
+--UEXPECTF--
+[005]
+array(2) {
+ [0]=>
+ array(2) {
+ [0]=>
+ unicode(1) "1"
+ [1]=>
+ unicode(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "b"
+ }
+}
+[007]
+array(2) {
+ [0]=>
+ array(2) {
+ [0]=>
+ unicode(1) "1"
+ [1]=>
+ unicode(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "b"
+ }
+}
+[008]
+array(2) {
+ [0]=>
+ array(4) {
+ [0]=>
+ unicode(1) "1"
+ [u"id"]=>
+ unicode(1) "1"
+ [1]=>
+ unicode(1) "a"
+ [u"label"]=>
+ unicode(1) "a"
+ }
+ [1]=>
+ array(4) {
+ [0]=>
+ unicode(1) "2"
+ [u"id"]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "b"
+ [u"label"]=>
+ unicode(1) "b"
+ }
+}
+[010]
+array(2) {
+ [0]=>
+ array(2) {
+ [u"id"]=>
+ unicode(1) "1"
+ [u"label"]=>
+ unicode(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [u"id"]=>
+ unicode(1) "2"
+ [u"label"]=>
+ unicode(1) "b"
+ }
+}
+[011]
+NULL
+[013]
+array(2) {
+ [0]=>
+ array(2) {
+ [u"id"]=>
+ unicode(1) "1"
+ [u"label"]=>
+ unicode(1) "a"
+ }
+ [1]=>
+ array(2) {
+ [u"id"]=>
+ unicode(1) "2"
+ [u"label"]=>
+ unicode(1) "b"
+ }
+}
+[016]
+NULL
+[017]
+array(1) {
+ [0]=>
+ array(11) {
+ [0]=>
+ unicode(1) "1"
+ [u"a"]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "2"
+ [2]=>
+ unicode(1) "3"
+ [u"c"]=>
+ unicode(1) "3"
+ [3]=>
+ unicode(1) "4"
+ [u"C"]=>
+ unicode(1) "4"
+ [4]=>
+ NULL
+ [u"d"]=>
+ NULL
+ [5]=>
+ unicode(1) "1"
+ [u"e"]=>
+ unicode(1) "1"
+ }
+}
+
+Warning: mysqli_result::fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH 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
diff --git a/ext/mysqli/tests/mysqli_fetch_array.phpt b/ext/mysqli/tests/mysqli_fetch_array.phpt
new file mode 100644
index 0000000000..798d75096a
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_array.phpt
@@ -0,0 +1,454 @@
+--TEST--
+mysqli_fetch_array() - all datatypes but BIT
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_fetch_array()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_fetch_array($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 5")) {
+ printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ print "[005]\n";
+ var_dump(mysqli_fetch_array($res));
+
+ print "[006]\n";
+ var_dump(mysqli_fetch_array($res, MYSQLI_NUM));
+
+ print "[007]\n";
+ var_dump(mysqli_fetch_array($res, MYSQLI_BOTH));
+
+ print "[008]\n";
+ var_dump(mysqli_fetch_array($res, MYSQLI_ASSOC));
+
+ print "[009]\n";
+ var_dump(mysqli_fetch_array($res));
+
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) {
+ printf("[010] Cannot run query, [%d] %s\n", mysqli_errno($link), $mysqli_error($link));
+ }
+ print "[011]\n";
+ var_dump(mysqli_fetch_array($res, MYSQLI_BOTH));
+
+ mysqli_free_result($res);
+ if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS C")) {
+ printf("[012] Cannot run query, [%d] %s\n",
+ mysqli_errno($link), $mysqli_error($link));
+ exit(1);
+ }
+
+ do {
+ $illegal_mode = mt_rand(-10000, 10000);
+ } while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH)));
+ // NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes.
+ $tmp = mysqli_fetch_array($res, $illegal_mode);
+ if (false !== $tmp)
+ printf("[013] Expecting boolean/false although, got %s/%s. [%d] %s\n",
+ gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link));
+
+ $tmp = mysqli_fetch_array($res, $illegal_mode);
+ if (false !== $tmp)
+ printf("[014] Expecting boolean/false, got %s/%s. [%d] %s\n",
+ gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link));
+
+ mysqli_free_result($res);
+
+ function func_mysqli_fetch_array($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL, $binary_type = false) {
+
+ if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) {
+ printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+ if (!mysqli_query($link, $sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) {
+ print $sql;
+ // don't bail, engine might not support the datatype
+ return false;
+ }
+
+ if (is_null($php_value) && !mysqli_query($link, $sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+ if (!is_null($php_value)) {
+ if (is_int($sql_value) && !mysqli_query($link, sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link));
+ return false;
+ } else if (!is_int($sql_value) && !mysqli_query($link, sprintf("INSERT INTO test(id, label) VALUES (1, '%s')", $sql_value))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+ }
+
+ if (!$res = mysqli_query($link, "SELECT id, label FROM test")) {
+ printf("[%04d] [%d] %s\n", $offset + 2, mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+ if (!$row = mysqli_fetch_array($res, MYSQLI_BOTH)) {
+ printf("[%04d] [%d] %s\n", $offset + 3, mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+
+
+ if ($regexp_comparison) {
+ if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) {
+ printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4,
+ gettype($php_value), $php_value, $regexp_comparison,
+ gettype($row[1]), $row[1],
+ gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+ } else if ((gettype($php_value) == 'unicode') && $binary_type) {
+ // Unicode is on and we are told that the MySQL column type is a binary type.
+ // Don't expect a unicode value from the database, you'll get binary string
+ if (($row['label'] != $php_value) || ($row[1] != $php_value)) {
+ printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 5,
+ gettype($php_value), $php_value,
+ gettype($row[1]), $row[1],
+ gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+ if (gettype($row['label']) == 'unicode') {
+ var_dump(mysqli_fetch_field_direct($res, 1), $row['label']);
+ printf("[%04d] SQL Type: '%s', binary columns are supposed to return binary string and not unicode\n",
+ $offset + 6, $sql_type);
+ return false;
+ }
+ } else {
+ if (($row['label'] !== $php_value) || ($row[1] != $php_value)) {
+ printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 7,
+ gettype($php_value), $php_value,
+ gettype($row[1]), $row[1],
+ gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function func_mysqli_fetch_array_make_string($len) {
+
+ $ret = '';
+ for ($i = 0; $i < $len; $i++)
+ $ret .= chr(mt_rand(65, 90));
+
+ return $ret;
+ }
+
+ func_mysqli_fetch_array($link, $engine, "TINYINT", -11, "-11", 20);
+ func_mysqli_fetch_array($link, $engine, "TINYINT", NULL, NULL, 30);
+ func_mysqli_fetch_array($link, $engine, "TINYINT UNSIGNED", 1, "1", 40);
+ func_mysqli_fetch_array($link, $engine, "TINYINT UNSIGNED", NULL, NULL, 50);
+
+ func_mysqli_fetch_array($link, $engine, "BOOL", 1, "1", 60);
+ func_mysqli_fetch_array($link, $engine, "BOOL", NULL, NULL, 70);
+ func_mysqli_fetch_array($link, $engine, "BOOLEAN", 0, "0", 80);
+ func_mysqli_fetch_array($link, $engine, "BOOLEAN", NULL, NULL, 90);
+
+ func_mysqli_fetch_array($link, $engine, "SMALLINT", -32768, "-32768", 100);
+ func_mysqli_fetch_array($link, $engine, "SMALLINT", 32767, "32767", 110);
+ func_mysqli_fetch_array($link, $engine, "SMALLINT", NULL, NULL, 120);
+ func_mysqli_fetch_array($link, $engine, "SMALLINT UNSIGNED", 65535, "65535", 130);
+ func_mysqli_fetch_array($link, $engine, "SMALLINT UNSIGNED", NULL, NULL, 140);
+
+ func_mysqli_fetch_array($link, $engine, "MEDIUMINT", -8388608, "-8388608", 150);
+ func_mysqli_fetch_array($link, $engine, "MEDIUMINT", 8388607, "8388607", 160);
+ func_mysqli_fetch_array($link, $engine, "MEDIUMINT", NULL, NULL, 170);
+ func_mysqli_fetch_array($link, $engine, "MEDIUMINT UNSIGNED", 16777215, "16777215", 180);
+ func_mysqli_fetch_array($link, $engine, "MEDIUMINT UNSIGNED", NULL, NULL, 190);
+
+ func_mysqli_fetch_array($link, $engine, "INTEGER", -2147483648, "-2147483648", 200);
+ func_mysqli_fetch_array($link, $engine, "INTEGER", 2147483647, "2147483647", 210);
+ func_mysqli_fetch_array($link, $engine, "INTEGER", NULL, NULL, 220);
+ func_mysqli_fetch_array($link, $engine, "INTEGER UNSIGNED", 4294967295, "4294967295", 230);
+ func_mysqli_fetch_array($link, $engine, "INTEGER UNSIGNED", NULL, NULL, 240);
+
+ if ($IS_MYSQLND ||
+ ((mysqli_get_server_version($link) >= 51000) &&
+ (mysqli_get_client_version($link) >= 51000))) {
+ func_mysqli_fetch_array($link, $engine, "BIGINT", -9223372036854775808, "-9223372036854775808", 250);
+ func_mysqli_fetch_array($link, $engine, "BIGINT", NULL, NULL, 260);
+ func_mysqli_fetch_array($link, $engine, "BIGINT UNSIGNED", 18446744073709551615, "18446744073709551615", 260);
+ func_mysqli_fetch_array($link, $engine, "BIGINT UNSIGNED", NULL, NULL, 280);
+ }
+
+ func_mysqli_fetch_array($link, $engine, "FLOAT", -9223372036854775808 - 1.1, "-9.22337e+18", 290, "/-9\.22337e\+[0]?18/iu");
+ func_mysqli_fetch_array($link, $engine, "FLOAT", NULL, NULL, 300);
+ func_mysqli_fetch_array($link, $engine, "FLOAT UNSIGNED", 18446744073709551615 + 1.1, "1.84467e+19", 310, "/1\.84467e\+[0]?19/iu");
+ func_mysqli_fetch_array($link, $engine, "FLOAT UNSIGNED ", NULL, NULL, 320);
+
+ func_mysqli_fetch_array($link, $engine, "DOUBLE(10,2)", -99999999.99, "-99999999.99", 330);
+ func_mysqli_fetch_array($link, $engine, "DOUBLE(10,2)", NULL, NULL, 340);
+ func_mysqli_fetch_array($link, $engine, "DOUBLE(10,2) UNSIGNED", 99999999.99, "99999999.99", 350);
+ func_mysqli_fetch_array($link, $engine, "DOUBLE(10,2) UNSIGNED", NULL, NULL, 360);
+
+ func_mysqli_fetch_array($link, $engine, "DECIMAL(10,2)", -99999999.99, "-99999999.99", 370);
+ func_mysqli_fetch_array($link, $engine, "DECIMAL(10,2)", NULL, NULL, 380);
+ func_mysqli_fetch_array($link, $engine, "DECIMAL(10,2)", 99999999.99, "99999999.99", 390);
+ func_mysqli_fetch_array($link, $engine, "DECIMAL(10,2)", NULL, NULL, 400);
+
+ // don't care about date() strict TZ warnings...
+ $date = @date('Y-m-d');
+ func_mysqli_fetch_array($link, $engine, "DATE",$date, $date, 410);
+ func_mysqli_fetch_array($link, $engine, "DATE NOT NULL",$date, $date, 420);
+ func_mysqli_fetch_array($link, $engine, "DATE", NULL, NULL, 430);
+
+ $date = @date('Y-m-d H:i:s');
+ func_mysqli_fetch_array($link, $engine, "DATETIME", $date, $date, 440);
+ func_mysqli_fetch_array($link, $engine, "DATETIME NOT NULL", $date, $date, 450);
+ func_mysqli_fetch_array($link, $engine, "DATETIME", NULL, NULL, 460);
+ func_mysqli_fetch_array($link, $engine, "TIMESTAMP", $date, $date, 470);
+
+ $date = @date('H:i:s');
+ func_mysqli_fetch_array($link, $engine, "TIME", $date, $date, 480);
+ func_mysqli_fetch_array($link, $engine, "TIME NOT NULL", $date, $date, 490);
+ func_mysqli_fetch_array($link, $engine, "TIME", NULL, NULL, 500);
+
+ func_mysqli_fetch_array($link, $engine, "YEAR", @date('Y'), @date('Y'), 510);
+ func_mysqli_fetch_array($link, $engine, "YEAR NOT NULL", @date('Y'), @date('Y'), 520);
+ func_mysqli_fetch_array($link, $engine, "YEAR", NULL, NULL, 530);
+
+ $string255 = func_mysqli_fetch_array_make_string(255);
+ func_mysqli_fetch_array($link, $engine, "CHAR(1)", "a", "a", 540);
+ func_mysqli_fetch_array($link, $engine, "CHAR(255)", $string255, $string255, 550);
+ func_mysqli_fetch_array($link, $engine, "CHAR(1) NOT NULL", "a", "a", 560);
+ func_mysqli_fetch_array($link, $engine, "CHAR(1)", NULL, NULL, 570);
+
+ $string65k = func_mysqli_fetch_array_make_string(65535);
+ func_mysqli_fetch_array($link, $engine, "VARCHAR(1)", "a", "a", 580);
+ func_mysqli_fetch_array($link, $engine, "VARCHAR(255)", $string255, $string255, 590);
+ func_mysqli_fetch_array($link, $engine, "VARCHAR(65635)", $string65k, $string65k, 600);
+ func_mysqli_fetch_array($link, $engine, "VARCHAR(1) NOT NULL", "a", "a", 610);
+ func_mysqli_fetch_array($link, $engine, "VARCHAR(1)", NULL, NULL, 620);
+
+ func_mysqli_fetch_array($link, $engine, "BINARY(1)", "a", "a", 630, null, true);
+ func_mysqli_fetch_array($link, $engine, "BINARY(2)", chr(0) . "a", chr(0) . "a", 640, null, true);
+ func_mysqli_fetch_array($link, $engine, "BINARY(1) NOT NULL", "b", "b", 650, null, true);
+ func_mysqli_fetch_array($link, $engine, "BINARY(1)", NULL, NULL, 660, null, true);
+
+ func_mysqli_fetch_array($link, $engine, "VARBINARY(1)", "a", "a", 670, null, true);
+ func_mysqli_fetch_array($link, $engine, "VARBINARY(2)", chr(0) . "a", chr(0) . "a", 680, null, true);
+ func_mysqli_fetch_array($link, $engine, "VARBINARY(1) NOT NULL", "b", "b", 690, null, true);
+ func_mysqli_fetch_array($link, $engine, "VARBINARY(1)", NULL, NULL, 700, null, true);
+
+ func_mysqli_fetch_array($link, $engine, "TINYBLOB", "a", "a", 710, null, true);
+ func_mysqli_fetch_array($link, $engine, "TINYBLOB", chr(0) . "a", chr(0) . "a", 720, null, true);
+ func_mysqli_fetch_array($link, $engine, "TINYBLOB NOT NULL", "b", "b", 730, null, true);
+ func_mysqli_fetch_array($link, $engine, "TINYBLOB", NULL, NULL, 740, null, true);
+
+ func_mysqli_fetch_array($link, $engine, "TINYTEXT", "a", "a", 750);
+ func_mysqli_fetch_array($link, $engine, "TINYTEXT NOT NULL", "a", "a", 760);
+ func_mysqli_fetch_array($link, $engine, "TINYTEXT", NULL, NULL, 770);
+
+ func_mysqli_fetch_array($link, $engine, "BLOB", "a", "a", 780, null, true);
+ func_mysqli_fetch_array($link, $engine, "BLOB", chr(0) . "a", chr(0) . "a", 780, null, true);
+ func_mysqli_fetch_array($link, $engine, "BLOB", NULL, NULL, 790, null, true);
+
+ func_mysqli_fetch_array($link, $engine, "TEXT", "a", "a", 800);
+ func_mysqli_fetch_array($link, $engine, "TEXT", chr(0) . "a", chr(0) . "a", 810);
+ func_mysqli_fetch_array($link, $engine, "TEXT", NULL, NULL, 820);
+
+ func_mysqli_fetch_array($link, $engine, "MEDIUMBLOB", "a", "a", 830, null, true);
+ func_mysqli_fetch_array($link, $engine, "MEDIUMBLOB", chr(0) . "a", chr(0) . "a", 840, null, true);
+ func_mysqli_fetch_array($link, $engine, "MEDIUMBLOB", NULL, NULL, 850, null, true);
+
+ func_mysqli_fetch_array($link, $engine, "MEDIUMTEXT", "a", "a", 860);
+ func_mysqli_fetch_array($link, $engine, "MEDIUMTEXT", chr(0) . "a", chr(0) . "a", 870);
+ func_mysqli_fetch_array($link, $engine, "MEDIUMTEXT", NULL, NULL, 880);
+
+ func_mysqli_fetch_array($link, $engine, "LONGBLOB", "a", "a", 890, null, true);
+ func_mysqli_fetch_array($link, $engine, "LONGTEXT", chr(0) . "a", chr(0) . "a", 900);
+ func_mysqli_fetch_array($link, $engine, "LONGBLOB", NULL, NULL, 910, null, true);
+
+ func_mysqli_fetch_array($link, $engine, "ENUM('a', 'b')", "a", "a", 920);
+ func_mysqli_fetch_array($link, $engine, "ENUM('a', 'b')", NULL, NULL, 930);
+
+ func_mysqli_fetch_array($link, $engine, "SET('a', 'b')", "a", "a", 940);
+ func_mysqli_fetch_array($link, $engine, "SET('a', 'b')", NULL, NULL, 950);
+
+ mysqli_close($link);
+
+ if (null !== ($tmp = mysqli_fetch_array($res, MYSQLI_ASSOC)))
+ printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ print "done!";
+?>
+--EXPECTF--
+[005]
+array(4) {
+ [0]=>
+ string(1) "1"
+ ["id"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "a"
+ ["label"]=>
+ string(1) "a"
+}
+[006]
+array(2) {
+ [0]=>
+ string(1) "2"
+ [1]=>
+ string(1) "b"
+}
+[007]
+array(4) {
+ [0]=>
+ string(1) "3"
+ ["id"]=>
+ string(1) "3"
+ [1]=>
+ string(1) "c"
+ ["label"]=>
+ string(1) "c"
+}
+[008]
+array(2) {
+ ["id"]=>
+ string(1) "4"
+ ["label"]=>
+ string(1) "d"
+}
+[009]
+array(4) {
+ [0]=>
+ string(1) "5"
+ ["id"]=>
+ string(1) "5"
+ [1]=>
+ string(1) "e"
+ ["label"]=>
+ string(1) "e"
+}
+[011]
+array(11) {
+ [0]=>
+ string(1) "1"
+ ["a"]=>
+ string(1) "2"
+ [1]=>
+ string(1) "2"
+ [2]=>
+ string(1) "3"
+ ["c"]=>
+ string(1) "3"
+ [3]=>
+ string(1) "4"
+ ["C"]=>
+ string(1) "4"
+ [4]=>
+ NULL
+ ["d"]=>
+ NULL
+ [5]=>
+ string(1) "1"
+ ["e"]=>
+ string(1) "1"
+}
+
+Warning: mysqli_fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d
+
+Warning: mysqli_fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d
+
+Warning: mysqli_fetch_array(): Couldn't fetch mysqli_result in %s on line %d
+done!
+--UEXPECTF--
+[005]
+array(4) {
+ [0]=>
+ unicode(1) "1"
+ [u"id"]=>
+ unicode(1) "1"
+ [1]=>
+ unicode(1) "a"
+ [u"label"]=>
+ unicode(1) "a"
+}
+[006]
+array(2) {
+ [0]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "b"
+}
+[007]
+array(4) {
+ [0]=>
+ unicode(1) "3"
+ [u"id"]=>
+ unicode(1) "3"
+ [1]=>
+ unicode(1) "c"
+ [u"label"]=>
+ unicode(1) "c"
+}
+[008]
+array(2) {
+ [u"id"]=>
+ unicode(1) "4"
+ [u"label"]=>
+ unicode(1) "d"
+}
+[009]
+array(4) {
+ [0]=>
+ unicode(1) "5"
+ [u"id"]=>
+ unicode(1) "5"
+ [1]=>
+ unicode(1) "e"
+ [u"label"]=>
+ unicode(1) "e"
+}
+[011]
+array(11) {
+ [0]=>
+ unicode(1) "1"
+ [u"a"]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "2"
+ [2]=>
+ unicode(1) "3"
+ [u"c"]=>
+ unicode(1) "3"
+ [3]=>
+ unicode(1) "4"
+ [u"C"]=>
+ unicode(1) "4"
+ [4]=>
+ NULL
+ [u"d"]=>
+ NULL
+ [5]=>
+ unicode(1) "1"
+ [u"e"]=>
+ unicode(1) "1"
+}
+
+Warning: mysqli_fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d
+
+Warning: mysqli_fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d
+
+Warning: mysqli_fetch_array(): Couldn't fetch mysqli_result in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_array_assoc.phpt b/ext/mysqli/tests/mysqli_fetch_array_assoc.phpt
new file mode 100644
index 0000000000..ac638848ac
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_array_assoc.phpt
@@ -0,0 +1,62 @@
+--TEST--
+mysqli_fetch_array()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ require('table.inc');
+
+ if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 5")) {
+ printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[002]\n";
+ var_dump(mysqli_fetch_array($res, MYSQLI_ASSOC));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 5")) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[004]\n";
+ var_dump(mysqli_fetch_array($res, MYSQLI_ASSOC));
+ mysqli_free_result($res);
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+[002]
+array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["label"]=>
+ string(1) "a"
+}
+[004]
+array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["label"]=>
+ string(1) "a"
+}
+done!
+--UEXPECTF--
+[002]
+array(2) {
+ [u"id"]=>
+ unicode(1) "1"
+ [u"label"]=>
+ unicode(1) "a"
+}
+[004]
+array(2) {
+ [u"id"]=>
+ unicode(1) "1"
+ [u"label"]=>
+ unicode(1) "a"
+}
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt b/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt
new file mode 100644
index 0000000000..6c8e58a88a
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt
@@ -0,0 +1,112 @@
+--TEST--
+mysqli_fetch_array()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ require("table.inc");
+
+ // do as much as we can do in 5 seconds
+ $start = microtime(true);
+ for ($id = 100, $start = microtime(true); (microtime(true) - $start) < 5; $id++) {
+ if (!mysqli_query($link, $sql = sprintf("INSERT INTO test(id, label) VALUES (%d, '%s')",
+ $id, mysqli_real_escape_string($link, chr(65 + ($id % 26)))))) {
+ printf("[001] %s failed: [%d] %s\n", $sql, mysqli_errno($link), mysqli_error($link));
+ break;
+ }
+ }
+
+ if (!$res = mysqli_query($link, 'SELECT id, label FROM test')) {
+ printf("[002] SELECT failed: [%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+ }
+
+ while ($row = mysqli_fetch_array($res)) {
+ // overwrite results and check if the cache magic works
+ $row['label'] = NULL;
+ }
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, 'SELECT id, label FROM test')) {
+ printf("[003] SELECT failed: [%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+ }
+
+ $i = 0;
+ $results = array();
+ while ($row = mysqli_fetch_array($res, MYSQLI_BOTH)) {
+
+ // create copies and destroy later
+ $results[$i++] = &$row;
+ if ($i % 999) {
+ $results = array();
+ }
+
+ if ($row[0] < 0 || $row[0] > $id) {
+ printf("[004] Unexpected result row[0] = '%s' (range 0...%d), [%d] %s\n",
+ $row[0], $id, mysqli_errno($link), mysqli_error($link));
+ break;
+ }
+ if ($row[0] !== $row['id']) {
+ printf("[005] Unexpected result row[0] = '%s', row[id] = '%s', [%d] %s\n",
+ $row[0], $row[id], mysqli_errno($link), mysqli_error($link));
+ break;
+ }
+
+ $len = strlen($row[1]);
+ if (!is_string($row[1]) || $len == 0 || $len > 1) {
+ printf("[006] Unexpected result row[1] = '%s', [%d] %s\n",
+ $row[1], mysqli_errno($link), mysqli_error($link));
+ break;
+ }
+ if ($row[1] !== $row['label']) {
+ printf("[007] Unexpected result row[1] = '%s', row[label] = '%s', [%d] %s\n",
+ $row[1], $row['label'], mysqli_errno($link), mysqli_error($link));
+ break;
+ }
+
+ }
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, 'SELECT id, label FROM test')) {
+ printf("[008] SELECT failed: [%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+ }
+
+ while ($row = mysqli_fetch_array($res, MYSQLI_ASSOC)) {
+ // overwrite results and check if the cache magic works
+ $row['label'] = NULL;
+ }
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, 'SELECT count(*) AS num FROM test')) {
+ printf("[009] SELECT failed: [%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+ }
+ $row = mysqli_fetch_assoc($res);
+ $num = $row['num'];
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, 'SELECT id, label FROM test')) {
+ printf("[010] SELECT failed: [%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+ }
+
+ $i = 0;
+ while ($row = mysqli_fetch_array($res, MYSQLI_NUM)) {
+ // overwrite results and check if the cache magic works
+ $row[0] = NULL;
+ $i++;
+ }
+ mysqli_free_result($res);
+
+ if ($i != $num)
+ printf("[011] Expecting %d results, got %d results, [%d] %s\n",
+ $num, $i, mysqli_errno($link), mysqli_error($link));
+
+ mysqli_close($link);
+
+ print "done!";
+?>
+--EXPECTF--
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt
new file mode 100644
index 0000000000..a13b131e5f
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt
@@ -0,0 +1,435 @@
+--TEST--
+mysqli->fetch_array()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ require('table.inc');
+ if (!$mysqli = new mysqli($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);
+
+ if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 5")) {
+ printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ print "[005]\n";
+ var_dump($res->fetch_array());
+
+ print "[006]\n";
+ var_dump($res->fetch_array(MYSQLI_NUM));
+
+ print "[007]\n";
+ var_dump($res->fetch_array(MYSQLI_BOTH));
+
+ print "[008]\n";
+ var_dump($res->fetch_array(MYSQLI_ASSOC));
+
+ print "[009]\n";
+ var_dump($res->fetch_array());
+
+ $res->free_result();
+
+ if (!$res = $mysqli->query("SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) {
+ printf("[010] Cannot run query, [%d] %s\n", $mysqli->errno, $$mysqli->error);
+ }
+ print "[011]\n";
+ var_dump($res->fetch_array(MYSQLI_BOTH));
+
+ $res->free_result();
+ if (!$res = $mysqli->query("SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS C")) {
+ printf("[012] Cannot run query, [%d] %s\n",
+ $mysqli->errno, $$mysqli->error);
+ exit(1);
+ }
+
+ do {
+ $illegal_mode = mt_rand(-10000, 10000);
+ } while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH)));
+ // NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes.
+ $tmp = $res->fetch_array($illegal_mode);
+ if (false !== $tmp)
+ printf("[013] Expecting boolean/false although, got %s/%s. [%d] %s\n",
+ gettype($tmp), $tmp, $mysqli->errno, $mysqli->error);
+
+ $tmp = $res->fetch_array($illegal_mode);
+ if (false !== $tmp)
+ printf("[014] Expecting boolean/false, got %s/%s. [%d] %s\n",
+ gettype($tmp), $tmp, $mysqli->errno, $mysqli->error);
+
+ $res->free_result();
+
+ function func_mysqli_fetch_array($mysqli, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL) {
+
+ if (!$mysqli->query("DROP TABLE IF EXISTS test")) {
+ printf("[%04d] [%d] %s\n", $offset, $mysqli->errno, $mysqli->error);
+ return false;
+ }
+
+ if (!$mysqli->query($sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) {
+ print $sql;
+ // don't bail, engine might not support the datatype
+ return false;
+ }
+
+ if (is_null($php_value) && !$mysqli->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, $mysqli->errno, $mysqli->error);
+ return false;
+ }
+
+ if (!is_null($php_value)) {
+ if (is_int($sql_value) && !$mysqli->query(sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, $mysqli->errno, $mysqli->error);
+ return false;
+ } else if (!is_int($sql_value) && !$mysqli->query(sprintf("INSERT INTO test(id, label) VALUES (1, '%s')", $sql_value))) {
+ printf("[%04d] [%d] %s\n", $offset + 1, $mysqli->errno, $mysqli->error);
+ return false;
+ }
+ }
+
+ if (!$res = $mysqli->query("SELECT id, label FROM test")) {
+ printf("[%04d] [%d] %s\n", $offset + 2, $mysqli->errno, $mysqli->error);
+ return false;
+ }
+
+ if (!$row = $res->fetch_array(MYSQLI_BOTH)) {
+ printf("[%04d] [%d] %s\n", $offset + 3, $mysqli->errno, $mysqli->error);
+ return false;
+ }
+ $fields = mysqli_fetch_fields($res);
+
+ if (!(gettype($php_value)=="unicode" && ($fields[1]->flags & 128))) {
+ if ($regexp_comparison) {
+ if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) {
+ printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4,
+ gettype($php_value), $php_value, $regexp_comparison,
+ gettype($row[1]), $row[1],
+ gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error);
+ return false;
+ }
+ } else {
+ if (($row['label'] !== $php_value) || ($row[1] != $php_value)) {
+ printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4,
+ gettype($php_value), $php_value,
+ gettype($row[1]), $row[1],
+ gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ function func_mysqli_fetch_array_make_string($len) {
+
+ $ret = '';
+ for ($i = 0; $i < $len; $i++)
+ $ret .= chr(mt_rand(65, 90));
+
+ return $ret;
+ }
+
+ func_mysqli_fetch_array($mysqli, $engine, "TINYINT", -11, "-11", 20);
+ func_mysqli_fetch_array($mysqli, $engine, "TINYINT", NULL, NULL, 30);
+ func_mysqli_fetch_array($mysqli, $engine, "TINYINT UNSIGNED", 1, "1", 40);
+ func_mysqli_fetch_array($mysqli, $engine, "TINYINT UNSIGNED", NULL, NULL, 50);
+
+ func_mysqli_fetch_array($mysqli, $engine, "BOOL", 1, "1", 60);
+ func_mysqli_fetch_array($mysqli, $engine, "BOOL", NULL, NULL, 70);
+ func_mysqli_fetch_array($mysqli, $engine, "BOOLEAN", 0, "0", 80);
+ func_mysqli_fetch_array($mysqli, $engine, "BOOLEAN", NULL, NULL, 90);
+
+ func_mysqli_fetch_array($mysqli, $engine, "SMALLINT", -32768, "-32768", 100);
+ func_mysqli_fetch_array($mysqli, $engine, "SMALLINT", 32767, "32767", 110);
+ func_mysqli_fetch_array($mysqli, $engine, "SMALLINT", NULL, NULL, 120);
+ func_mysqli_fetch_array($mysqli, $engine, "SMALLINT UNSIGNED", 65535, "65535", 130);
+ func_mysqli_fetch_array($mysqli, $engine, "SMALLINT UNSIGNED", NULL, NULL, 140);
+
+ func_mysqli_fetch_array($mysqli, $engine, "MEDIUMINT", -8388608, "-8388608", 150);
+ func_mysqli_fetch_array($mysqli, $engine, "MEDIUMINT", 8388607, "8388607", 160);
+ func_mysqli_fetch_array($mysqli, $engine, "MEDIUMINT", NULL, NULL, 170);
+ func_mysqli_fetch_array($mysqli, $engine, "MEDIUMINT UNSIGNED", 16777215, "16777215", 180);
+ func_mysqli_fetch_array($mysqli, $engine, "MEDIUMINT UNSIGNED", NULL, NULL, 190);
+
+ func_mysqli_fetch_array($mysqli, $engine, "INTEGER", -2147483648, "-2147483648", 200);
+ func_mysqli_fetch_array($mysqli, $engine, "INTEGER", 2147483647, "2147483647", 210);
+ func_mysqli_fetch_array($mysqli, $engine, "INTEGER", NULL, NULL, 220);
+ func_mysqli_fetch_array($mysqli, $engine, "INTEGER UNSIGNED", 4294967295, "4294967295", 230);
+ func_mysqli_fetch_array($mysqli, $engine, "INTEGER UNSIGNED", NULL, NULL, 240);
+
+ if ($IS_MYSQLND ||
+ ((mysqli_get_server_version($link) >= 51000) &&
+ (mysqli_get_client_version($link) >= 51000))) {
+ func_mysqli_fetch_array($mysqli, $engine, "BIGINT", -9223372036854775808, "-9223372036854775808", 250);
+ func_mysqli_fetch_array($mysqli, $engine, "BIGINT", NULL, NULL, 260);
+ func_mysqli_fetch_array($mysqli, $engine, "BIGINT UNSIGNED", 18446744073709551615, "18446744073709551615", 270);
+ func_mysqli_fetch_array($mysqli, $engine, "BIGINT UNSIGNED", NULL, NULL, 280);
+ }
+
+ func_mysqli_fetch_array($mysqli, $engine, "FLOAT", -9223372036854775808 - 1.1, "-9.22337e+18", 290, "/-9\.22337e\+[0]?18/iu");
+ func_mysqli_fetch_array($mysqli, $engine, "FLOAT", NULL, NULL, 300);
+ func_mysqli_fetch_array($mysqli, $engine, "FLOAT UNSIGNED", 18446744073709551615 + 1.1, "1.84467e+19", 310, "/1\.84467e\+[0]?19/iu");
+ func_mysqli_fetch_array($mysqli, $engine, "FLOAT UNSIGNED ", NULL, NULL, 320);
+
+ func_mysqli_fetch_array($mysqli, $engine, "DOUBLE(10,2)", -99999999.99, "-99999999.99", 330);
+ func_mysqli_fetch_array($mysqli, $engine, "DOUBLE(10,2)", NULL, NULL, 340);
+ func_mysqli_fetch_array($mysqli, $engine, "DOUBLE(10,2) UNSIGNED", 99999999.99, "99999999.99", 350);
+ func_mysqli_fetch_array($mysqli, $engine, "DOUBLE(10,2) UNSIGNED", NULL, NULL, 360);
+ func_mysqli_fetch_array($mysqli, $engine, "DECIMAL(10,2)", -99999999.99, "-99999999.99", 370);
+ func_mysqli_fetch_array($mysqli, $engine, "DECIMAL(10,2)", NULL, NULL, 380);
+ func_mysqli_fetch_array($mysqli, $engine, "DECIMAL(10,2)", 99999999.99, "99999999.99", 390);
+ func_mysqli_fetch_array($mysqli, $engine, "DECIMAL(10,2)", NULL, NULL, 400);
+
+ // don't care about date() strict TZ warnings...
+ $date = @date('Y-m-d');
+ func_mysqli_fetch_array($mysqli, $engine, "DATE",$date, $date, 410);
+ func_mysqli_fetch_array($mysqli, $engine, "DATE NOT NULL",$date, $date, 420);
+ func_mysqli_fetch_array($mysqli, $engine, "DATE", NULL, NULL, 430);
+
+ $date = @date('Y-m-d H:i:s');
+ func_mysqli_fetch_array($mysqli, $engine, "DATETIME", $date, $date, 440);
+ func_mysqli_fetch_array($mysqli, $engine, "DATETIME NOT NULL", $date, $date, 450);
+ func_mysqli_fetch_array($mysqli, $engine, "DATETIME", NULL, NULL, 460);
+ func_mysqli_fetch_array($mysqli, $engine, "TIMESTAMP", $date, $date, 470);
+ $date = @date('H:i:s');
+ func_mysqli_fetch_array($mysqli, $engine, "TIME", $date, $date, 480);
+ func_mysqli_fetch_array($mysqli, $engine, "TIME NOT NULL", $date, $date, 490);
+ func_mysqli_fetch_array($mysqli, $engine, "TIME", NULL, NULL, 500);
+ func_mysqli_fetch_array($mysqli, $engine, "YEAR", @date('Y'), @date('Y'), 510);
+ func_mysqli_fetch_array($mysqli, $engine, "YEAR NOT NULL", @date('Y'), @date('Y'), 520);
+ func_mysqli_fetch_array($mysqli, $engine, "YEAR", NULL, NULL, 530);
+
+ $string255 = func_mysqli_fetch_array_make_string(255);
+ func_mysqli_fetch_array($mysqli, $engine, "CHAR(1)", "a", "a", 540);
+ func_mysqli_fetch_array($mysqli, $engine, "CHAR(255)", $string255, $string255, 550);
+ func_mysqli_fetch_array($mysqli, $engine, "CHAR(1) NOT NULL", "a", "a", 560);
+ func_mysqli_fetch_array($mysqli, $engine, "CHAR(1)", NULL, NULL, 570);
+
+ $string65k = func_mysqli_fetch_array_make_string(65535);
+ func_mysqli_fetch_array($mysqli, $engine, "VARCHAR(1)", "a", "a", 580);
+ func_mysqli_fetch_array($mysqli, $engine, "VARCHAR(255)", $string255, $string255, 590);
+ func_mysqli_fetch_array($mysqli, $engine, "VARCHAR(65635)", $string65k, $string65k, 600);
+ func_mysqli_fetch_array($mysqli, $engine, "VARCHAR(1) NOT NULL", "a", "a", 610);
+ func_mysqli_fetch_array($mysqli, $engine, "VARCHAR(1)", NULL, NULL, 620);
+
+ func_mysqli_fetch_array($mysqli, $engine, "BINARY(1)", "a", "a", 630);
+ func_mysqli_fetch_array($mysqli, $engine, "BINARY(2)", chr(0) . "a", chr(0) . "a", 640);
+ func_mysqli_fetch_array($mysqli, $engine, "BINARY(1) NOT NULL", "b", "b", 650);
+ func_mysqli_fetch_array($mysqli, $engine, "BINARY(1)", NULL, NULL, 660);
+
+ func_mysqli_fetch_array($mysqli, $engine, "VARBINARY(1)", "a", "a", 670);
+ func_mysqli_fetch_array($mysqli, $engine, "VARBINARY(2)", chr(0) . "a", chr(0) . "a", 680);
+ func_mysqli_fetch_array($mysqli, $engine, "VARBINARY(1) NOT NULL", "b", "b", 690);
+ func_mysqli_fetch_array($mysqli, $engine, "VARBINARY(1)", NULL, NULL, 700);
+
+ func_mysqli_fetch_array($mysqli, $engine, "TINYBLOB", "a", "a", 710);
+ func_mysqli_fetch_array($mysqli, $engine, "TINYBLOB", chr(0) . "a", chr(0) . "a", 720);
+ func_mysqli_fetch_array($mysqli, $engine, "TINYBLOB NOT NULL", "b", "b", 730);
+ func_mysqli_fetch_array($mysqli, $engine, "TINYBLOB", NULL, NULL, 740);
+
+ func_mysqli_fetch_array($mysqli, $engine, "TINYTEXT", "a", "a", 750);
+ func_mysqli_fetch_array($mysqli, $engine, "TINYTEXT NOT NULL", "a", "a", 760);
+ func_mysqli_fetch_array($mysqli, $engine, "TINYTEXT", NULL, NULL, 770);
+
+ func_mysqli_fetch_array($mysqli, $engine, "BLOB", "a", "a", 780);
+ func_mysqli_fetch_array($mysqli, $engine, "BLOB", chr(0) . "a", chr(0) . "a", 780);
+ func_mysqli_fetch_array($mysqli, $engine, "BLOB", NULL, NULL, 790);
+
+ func_mysqli_fetch_array($mysqli, $engine, "TEXT", "a", "a", 800);
+ func_mysqli_fetch_array($mysqli, $engine, "TEXT", chr(0) . "a", chr(0) . "a", 810);
+ func_mysqli_fetch_array($mysqli, $engine, "TEXT", NULL, NULL, 820);
+
+ func_mysqli_fetch_array($mysqli, $engine, "MEDIUMBLOB", "a", "a", 830);
+ func_mysqli_fetch_array($mysqli, $engine, "MEDIUMBLOB", chr(0) . "a", chr(0) . "a", 840);
+ func_mysqli_fetch_array($mysqli, $engine, "MEDIUMBLOB", NULL, NULL, 850);
+
+ func_mysqli_fetch_array($mysqli, $engine, "MEDIUMTEXT", "a", "a", 860);
+ func_mysqli_fetch_array($mysqli, $engine, "MEDIUMTEXT", chr(0) . "a", chr(0) . "a", 870);
+ func_mysqli_fetch_array($mysqli, $engine, "MEDIUMTEXT", NULL, NULL, 880);
+
+ func_mysqli_fetch_array($mysqli, $engine, "LONGBLOB", "a", "a", 890);
+ func_mysqli_fetch_array($mysqli, $engine, "LONGTEXT", chr(0) . "a", chr(0) . "a", 900);
+ func_mysqli_fetch_array($mysqli, $engine, "LONGBLOB", NULL, NULL, 910);
+
+ func_mysqli_fetch_array($mysqli, $engine, "ENUM('a', 'b')", "a", "a", 920);
+ func_mysqli_fetch_array($mysqli, $engine, "ENUM('a', 'b')", NULL, NULL, 930);
+
+ func_mysqli_fetch_array($mysqli, $engine, "SET('a', 'b')", "a", "a", 940);
+ func_mysqli_fetch_array($mysqli, $engine, "SET('a', 'b')", NULL, NULL, 950);
+
+ $mysqli->close();
+
+ if (null !== ($tmp = $res->fetch_array(MYSQLI_ASSOC)))
+ printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ print "done!";
+?>
+--EXPECTF--
+[005]
+array(4) {
+ [0]=>
+ string(1) "1"
+ ["id"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "a"
+ ["label"]=>
+ string(1) "a"
+}
+[006]
+array(2) {
+ [0]=>
+ string(1) "2"
+ [1]=>
+ string(1) "b"
+}
+[007]
+array(4) {
+ [0]=>
+ string(1) "3"
+ ["id"]=>
+ string(1) "3"
+ [1]=>
+ string(1) "c"
+ ["label"]=>
+ string(1) "c"
+}
+[008]
+array(2) {
+ ["id"]=>
+ string(1) "4"
+ ["label"]=>
+ string(1) "d"
+}
+[009]
+array(4) {
+ [0]=>
+ string(1) "5"
+ ["id"]=>
+ string(1) "5"
+ [1]=>
+ string(1) "e"
+ ["label"]=>
+ string(1) "e"
+}
+[011]
+array(11) {
+ [0]=>
+ string(1) "1"
+ ["a"]=>
+ string(1) "2"
+ [1]=>
+ string(1) "2"
+ [2]=>
+ string(1) "3"
+ ["c"]=>
+ string(1) "3"
+ [3]=>
+ string(1) "4"
+ ["C"]=>
+ string(1) "4"
+ [4]=>
+ NULL
+ ["d"]=>
+ NULL
+ [5]=>
+ string(1) "1"
+ ["e"]=>
+ string(1) "1"
+}
+
+Warning: mysqli_result::fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d
+
+Warning: mysqli_result::fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d
+
+Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d
+done!
+--UEXPECTF--
+[005]
+array(4) {
+ [0]=>
+ unicode(1) "1"
+ [u"id"]=>
+ unicode(1) "1"
+ [1]=>
+ unicode(1) "a"
+ [u"label"]=>
+ unicode(1) "a"
+}
+[006]
+array(2) {
+ [0]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "b"
+}
+[007]
+array(4) {
+ [0]=>
+ unicode(1) "3"
+ [u"id"]=>
+ unicode(1) "3"
+ [1]=>
+ unicode(1) "c"
+ [u"label"]=>
+ unicode(1) "c"
+}
+[008]
+array(2) {
+ [u"id"]=>
+ unicode(1) "4"
+ [u"label"]=>
+ unicode(1) "d"
+}
+[009]
+array(4) {
+ [0]=>
+ unicode(1) "5"
+ [u"id"]=>
+ unicode(1) "5"
+ [1]=>
+ unicode(1) "e"
+ [u"label"]=>
+ unicode(1) "e"
+}
+[011]
+array(11) {
+ [0]=>
+ unicode(1) "1"
+ [u"a"]=>
+ unicode(1) "2"
+ [1]=>
+ unicode(1) "2"
+ [2]=>
+ unicode(1) "3"
+ [u"c"]=>
+ unicode(1) "3"
+ [3]=>
+ unicode(1) "4"
+ [u"C"]=>
+ unicode(1) "4"
+ [4]=>
+ NULL
+ [u"d"]=>
+ NULL
+ [5]=>
+ unicode(1) "1"
+ [u"e"]=>
+ unicode(1) "1"
+}
+
+Warning: mysqli_result::fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d
+
+Warning: mysqli_result::fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH 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
diff --git a/ext/mysqli/tests/mysqli_fetch_assoc.phpt b/ext/mysqli/tests/mysqli_fetch_assoc.phpt
new file mode 100644
index 0000000000..00ca325f4f
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_assoc.phpt
@@ -0,0 +1,161 @@
+--TEST--
+mysqli_fetch_assoc()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test
+
+ if (!is_null($tmp = @mysqli_fetch_assoc()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_fetch_assoc($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1")) {
+ printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ print "[005]\n";
+ var_dump(mysqli_fetch_assoc($res));
+
+ print "[006]\n";
+ var_dump(mysqli_fetch_assoc($res));
+
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT
+ 1 AS a,
+ 2 AS a,
+ 3 AS c,
+ 4 AS C,
+ NULL AS d,
+ true AS e,
+ 5 AS '-1',
+ 6 AS '-10',
+ 7 AS '-100',
+ 8 AS '-1000',
+ 9 AS '10000',
+ 'a' AS '100000',
+ 'b' AS '1000000',
+ 'c' AS '9',
+ 'd' AS '9',
+ 'e' AS '01',
+ 'f' AS '-02'
+ ")) {
+ printf("[007] Cannot run query, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[008]\n";
+ var_dump(mysqli_fetch_assoc($res));
+
+ mysqli_free_result($res);
+
+ if (NULL !== ($tmp = mysqli_fetch_assoc($res)))
+ printf("[008] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_close($link);
+
+ print "done!";
+?>
+--EXPECTF--
+[005]
+array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["label"]=>
+ string(1) "a"
+}
+[006]
+NULL
+[008]
+array(15) {
+ ["a"]=>
+ string(1) "2"
+ ["c"]=>
+ string(1) "3"
+ ["C"]=>
+ string(1) "4"
+ ["d"]=>
+ NULL
+ ["e"]=>
+ string(1) "1"
+ [-1]=>
+ string(1) "5"
+ [-10]=>
+ string(1) "6"
+ [-100]=>
+ string(1) "7"
+ [-1000]=>
+ string(1) "8"
+ [10000]=>
+ string(1) "9"
+ [100000]=>
+ string(1) "a"
+ [1000000]=>
+ string(1) "b"
+ [9]=>
+ string(1) "d"
+ ["01"]=>
+ string(1) "e"
+ ["-02"]=>
+ string(1) "f"
+}
+
+Warning: mysqli_fetch_assoc(): Couldn't fetch mysqli_result in %s on line %d
+done!
+--UEXPECTF--
+[005]
+array(2) {
+ [u"id"]=>
+ unicode(1) "1"
+ [u"label"]=>
+ unicode(1) "a"
+}
+[006]
+NULL
+[008]
+array(15) {
+ [u"a"]=>
+ unicode(1) "2"
+ [u"c"]=>
+ unicode(1) "3"
+ [u"C"]=>
+ unicode(1) "4"
+ [u"d"]=>
+ NULL
+ [u"e"]=>
+ unicode(1) "1"
+ [-1]=>
+ unicode(1) "5"
+ [-10]=>
+ unicode(1) "6"
+ [-100]=>
+ unicode(1) "7"
+ [-1000]=>
+ unicode(1) "8"
+ [10000]=>
+ unicode(1) "9"
+ [100000]=>
+ unicode(1) "a"
+ [1000000]=>
+ unicode(1) "b"
+ [9]=>
+ unicode(1) "d"
+ [u"01"]=>
+ unicode(1) "e"
+ [u"-02"]=>
+ unicode(1) "f"
+}
+
+Warning: mysqli_fetch_assoc(): Couldn't fetch mysqli_result in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt
new file mode 100644
index 0000000000..dc01154daa
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt
@@ -0,0 +1,113 @@
+--TEST--
+mysqli_fetch_assoc() - BIT
+--SKIPIF--
+<?php
+ require_once('skipif.inc');
+ require_once('skipifemb.inc');
+ require_once('skipifconnectfailure.inc');
+
+ 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;
+ $tests = 0;
+ if (!mysqli_query($link, "DROP TABLE IF EXISTS test") ||
+ !mysqli_query($link, $sql = sprintf('CREATE TABLE test(id BIGINT, 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));
+
+ $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_query($link, $sql))
+ printf("[003 - %d] [%d] %s\n", $bits, mysqli_errno($link), mysqli_error($link));
+
+ $sql = sprintf("SELECT id, BIN(bit_value) AS _bin, bit_value + 0 AS _bit_value0, bit_value, bit_null FROM test WHERE id = %s", $value);
+ if (!$res = mysqli_query($link, $sql))
+ printf("[004 - %d] [%d] %s\n", $bits, mysqli_errno($link), mysqli_error($link));
+
+ if (!$row = mysqli_fetch_assoc($res))
+ printf("[005 - %d] [%d] %s\n", $bits, mysqli_errno($link), mysqli_error($link));
+
+ if (($value != $row['id']) || (($bin != $row['_bin']) && ($bin2 != $row['_bin']))) {
+ debug_zval_dump($row);
+ printf("[006 - %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("[007 - %d] Expecting %s got %s\n", $bits, $value, $row['bit_value']);
+ break;
+ }
+
+ if (null !== $row['bit_null']) {
+ debug_zval_dump($row);
+ printf("[008 - %d] Expecting null got %s/%s\n", $bits, gettype($row['bit_value']), $row['bit_value']);
+ break;
+ }
+ }
+ }
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+done!
diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias.phpt
new file mode 100644
index 0000000000..6050d5253f
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias.phpt
@@ -0,0 +1,201 @@
+--TEST--
+mysqli_fetch_assoc()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ require('table.inc');
+
+ if (!$res = mysqli_query($link, "SELECT 1, 2")) {
+ printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[002]\n";
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT 1 AS a, 2")) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[004]\n";
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT 1 AS a, 2, 2 as '2'")) {
+ printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[006]\n";
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 as '2', 2")) {
+ printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[008]\n";
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+
+ /* Now do it with unbuffered queries */
+ if (!$res = mysqli_real_query($link, "SELECT 1, 2")) {
+ printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ if (!$res = mysqli_use_result($link)) {
+ printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[011]\n";
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_real_query($link, "SELECT 1 AS a, 2")) {
+ printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ if (!$res = mysqli_use_result($link)) {
+ printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[014]\n";
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_real_query($link, "SELECT 1 AS a, 2, 2 as '2'")) {
+ printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ if (!$res = mysqli_use_result($link)) {
+ printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[017]\n";
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_real_query($link, "SELECT 1 AS a, 2 as '2', 2")) {
+ printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ if (!$res = mysqli_use_result($link)) {
+ printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[017]\n";
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+ mysqli_close($link);
+
+ print "done!";
+?>
+--EXPECTF--
+[002]
+array(2) {
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "2"
+}
+[004]
+array(2) {
+ ["a"]=>
+ string(1) "1"
+ [2]=>
+ string(1) "2"
+}
+[006]
+array(2) {
+ ["a"]=>
+ string(1) "1"
+ [2]=>
+ string(1) "2"
+}
+[008]
+array(2) {
+ ["a"]=>
+ string(1) "1"
+ [2]=>
+ string(1) "2"
+}
+[011]
+array(2) {
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "2"
+}
+[014]
+array(2) {
+ ["a"]=>
+ %s(1) "1"
+ [2]=>
+ %s(1) "2"
+}
+[017]
+array(2) {
+ ["a"]=>
+ string(1) "1"
+ [2]=>
+ string(1) "2"
+}
+[017]
+array(2) {
+ ["a"]=>
+ string(1) "1"
+ [2]=>
+ string(1) "2"
+}
+done!
+--UEXPECTF--
+[002]
+array(2) {
+ [1]=>
+ unicode(1) "1"
+ [2]=>
+ unicode(1) "2"
+}
+[004]
+array(2) {
+ [u"a"]=>
+ unicode(1) "1"
+ [2]=>
+ unicode(1) "2"
+}
+[006]
+array(2) {
+ [u"a"]=>
+ unicode(1) "1"
+ [2]=>
+ unicode(1) "2"
+}
+[008]
+array(2) {
+ [u"a"]=>
+ unicode(1) "1"
+ [2]=>
+ unicode(1) "2"
+}
+[011]
+array(2) {
+ [1]=>
+ unicode(1) "1"
+ [2]=>
+ unicode(1) "2"
+}
+[014]
+array(2) {
+ [u"a"]=>
+ unicode(1) "1"
+ [2]=>
+ unicode(1) "2"
+}
+[017]
+array(2) {
+ [u"a"]=>
+ unicode(1) "1"
+ [2]=>
+ unicode(1) "2"
+}
+[017]
+array(2) {
+ [u"a"]=>
+ unicode(1) "1"
+ [2]=>
+ unicode(1) "2"
+}
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt
new file mode 100644
index 0000000000..5706f6b020
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt
@@ -0,0 +1,249 @@
+--TEST--
+mysqli_fetch_assoc() - utf8
+--SKIPIF--
+<?php
+ require_once('skipif.inc');
+ require_once('skipifemb.inc');
+ require_once('skipifconnectfailure.inc');
+ require('connect.inc');
+
+ if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ die("skip Cannot connect to server to check charsets");
+
+ if (!$res = mysqli_query($link, "SHOW CHARACTER SET LIKE 'UTF8'"))
+ die("skip Cannot run SHOW CHARACTER SET to check charsets");
+
+ if (!$tmp = mysqli_fetch_assoc($res))
+ die("skip Looks like UTF8 is not available on the server");
+
+ if (strtolower($tmp['Charset']) !== 'utf8')
+ die("skip Not sure if UTF8 is available, cancelling the test");
+
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SHOW CHARACTER SET LIKE 'UCS2'"))
+ die("skip Cannot run SHOW CHARACTER SET to check charsets");
+
+ if (!$tmp = mysqli_fetch_assoc($res))
+ die("skip Looks like UCS2 is not available on the server");
+
+ if (strtolower($tmp['Charset']) !== 'ucs2')
+ die("skip Not sure if UCS2 is available, cancelling the test");
+
+ mysqli_free_result($res);
+ mysqli_close($link);
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ require('table.inc');
+
+ /* some cyrillic (utf8) comes here */
+ if (!$res = mysqli_query($link, "SET NAMES UTF8")) {
+ printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ if (!$res = mysqli_query($link, "SELECT 1 AS 'Андрей Христов', 2 AS 'Улф Вендел', 3 AS 'Георг Рихтер'")) {
+ printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[003]\n";
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "CREATE TABLE автори_на_mysqlnd (id integer not null auto_increment primary key, име varchar(20) character set ucs2, фамилия varchar(20) character set utf8)")) {
+ printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ if (!$res = mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилия) VALUES ('Андрей', 'Христов'), ('Георг', 'Рихтер'), ('Улф','Вендел')")) {
+ printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ if (!$res = mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилия) VALUES ('Andrey', 'Hristov'), ('Georg', 'Richter'), ('Ulf','Wendel')")) {
+ printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ if (!$res = mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилия) VALUES ('安德烈', 'Hristov'), ('格奥尔', 'Richter'), ('乌尔夫','Wendel')")) {
+ printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ if (!$res = mysqli_query($link, "SELECT id, име, фамилия FROM автори_на_mysqlnd ORDER BY фамилия, име")) {
+ printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "[009]\n";
+ while ($row = mysqli_fetch_assoc($res)) {
+ var_dump($row);
+ }
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "DROP TABLE автори_на_mysqlnd")) {
+ printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+[003]
+array(3) {
+ ["Андрей Христов"]=>
+ string(1) "1"
+ ["Улф Вендел"]=>
+ string(1) "2"
+ ["Георг Рихтер"]=>
+ string(1) "3"
+}
+[009]
+array(3) {
+ ["id"]=>
+ string(1) "4"
+ ["име"]=>
+ string(6) "Andrey"
+ ["фамилия"]=>
+ string(7) "Hristov"
+}
+array(3) {
+ ["id"]=>
+ string(1) "7"
+ ["име"]=>
+ string(9) "安德烈"
+ ["фамилия"]=>
+ string(7) "Hristov"
+}
+array(3) {
+ ["id"]=>
+ string(1) "5"
+ ["име"]=>
+ string(5) "Georg"
+ ["фамилия"]=>
+ string(7) "Richter"
+}
+array(3) {
+ ["id"]=>
+ string(1) "8"
+ ["име"]=>
+ string(9) "格奥尔"
+ ["фамилия"]=>
+ string(7) "Richter"
+}
+array(3) {
+ ["id"]=>
+ string(1) "6"
+ ["име"]=>
+ string(3) "Ulf"
+ ["фамилия"]=>
+ string(6) "Wendel"
+}
+array(3) {
+ ["id"]=>
+ string(1) "9"
+ ["име"]=>
+ string(9) "乌尔夫"
+ ["фамилия"]=>
+ string(6) "Wendel"
+}
+array(3) {
+ ["id"]=>
+ string(1) "3"
+ ["име"]=>
+ string(6) "Улф"
+ ["фамилия"]=>
+ string(12) "Вендел"
+}
+array(3) {
+ ["id"]=>
+ string(1) "2"
+ ["име"]=>
+ string(10) "Георг"
+ ["фамилия"]=>
+ string(12) "Рихтер"
+}
+array(3) {
+ ["id"]=>
+ string(1) "1"
+ ["име"]=>
+ string(12) "Андрей"
+ ["фамилия"]=>
+ string(14) "Христов"
+}
+done!
+--UEXPECTF--
+[003]
+array(3) {
+ [u"Андрей Христов"]=>
+ unicode(1) "1"
+ [u"Улф Вендел"]=>
+ unicode(1) "2"
+ [u"Георг Рихтер"]=>
+ unicode(1) "3"
+}
+[009]
+array(3) {
+ [u"id"]=>
+ unicode(1) "4"
+ [u"име"]=>
+ unicode(6) "Andrey"
+ [u"фамилия"]=>
+ unicode(7) "Hristov"
+}
+array(3) {
+ [u"id"]=>
+ unicode(1) "7"
+ [u"име"]=>
+ unicode(3) "安德烈"
+ [u"фамилия"]=>
+ unicode(7) "Hristov"
+}
+array(3) {
+ [u"id"]=>
+ unicode(1) "5"
+ [u"име"]=>
+ unicode(5) "Georg"
+ [u"фамилия"]=>
+ unicode(7) "Richter"
+}
+array(3) {
+ [u"id"]=>
+ unicode(1) "8"
+ [u"име"]=>
+ unicode(3) "格奥尔"
+ [u"фамилия"]=>
+ unicode(7) "Richter"
+}
+array(3) {
+ [u"id"]=>
+ unicode(1) "6"
+ [u"име"]=>
+ unicode(3) "Ulf"
+ [u"фамилия"]=>
+ unicode(6) "Wendel"
+}
+array(3) {
+ [u"id"]=>
+ unicode(1) "9"
+ [u"име"]=>
+ unicode(3) "乌尔夫"
+ [u"фамилия"]=>
+ unicode(6) "Wendel"
+}
+array(3) {
+ [u"id"]=>
+ unicode(1) "3"
+ [u"име"]=>
+ unicode(3) "Улф"
+ [u"фамилия"]=>
+ unicode(6) "Вендел"
+}
+array(3) {
+ [u"id"]=>
+ unicode(1) "2"
+ [u"име"]=>
+ unicode(5) "Георг"
+ [u"фамилия"]=>
+ unicode(6) "Рихтер"
+}
+array(3) {
+ [u"id"]=>
+ unicode(1) "1"
+ [u"име"]=>
+ unicode(6) "Андрей"
+ [u"фамилия"]=>
+ unicode(7) "Христов"
+}
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt
new file mode 100644
index 0000000000..1751848378
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt
@@ -0,0 +1,108 @@
+--TEST--
+mysqli_fetch_assoc()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test
+ $mysqli = new mysqli();
+ $res = @new mysqli_result($mysqli);
+ if (!is_null($tmp = @$res->fetch_assoc()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket))
+ printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+
+ if (!is_null($tmp = @$res->fetch_assoc($link)))
+ printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!$res = $mysqli->query("SELECT id, label FROM test ORDER BY id LIMIT 1")) {
+ printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ print "[005]\n";
+ var_dump($res->fetch_assoc());
+
+ print "[006]\n";
+ var_dump($res->fetch_assoc());
+
+ $res->free_result();
+
+ if (!$res = $mysqli->query("SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) {
+ printf("[007] Cannot run query, [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+ print "[008]\n";
+ var_dump($res->fetch_assoc());
+
+ $res->free_result();
+
+ if (NULL !== ($tmp = $res->fetch_assoc()))
+ printf("[008] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_close($link);
+
+ print "done!";
+?>
+--EXPECTF--
+[005]
+array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["label"]=>
+ string(1) "a"
+}
+[006]
+NULL
+[008]
+array(5) {
+ ["a"]=>
+ string(1) "2"
+ ["c"]=>
+ string(1) "3"
+ ["C"]=>
+ string(1) "4"
+ ["d"]=>
+ NULL
+ ["e"]=>
+ string(1) "1"
+}
+
+Warning: mysqli_result::fetch_assoc(): Couldn't fetch mysqli_result in %s on line %d
+done!
+--UEXPECTF--
+[005]
+array(2) {
+ [u"id"]=>
+ unicode(1) "1"
+ [u"label"]=>
+ unicode(1) "a"
+}
+[006]
+NULL
+[008]
+array(5) {
+ [u"a"]=>
+ unicode(1) "2"
+ [u"c"]=>
+ unicode(1) "3"
+ [u"C"]=>
+ unicode(1) "4"
+ [u"d"]=>
+ NULL
+ [u"e"]=>
+ unicode(1) "1"
+}
+
+Warning: mysqli_result::fetch_assoc(): Couldn't fetch mysqli_result in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_field.phpt b/ext/mysqli/tests/mysqli_fetch_field.phpt
new file mode 100644
index 0000000000..9491191320
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_field.phpt
@@ -0,0 +1,220 @@
+--TEST--
+mysqli_fetch_field()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test
+ if (!is_null($tmp = @mysqli_fetch_field()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_fetch_field($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+
+ if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ while ($tmp = mysqli_fetch_field($res))
+ var_dump($tmp);
+ var_dump($tmp);
+
+ mysqli_free_result($res);
+
+ // Read http://bugs.php.net/bug.php?id=42344 on defaults!
+ if (NULL !== ($tmp = mysqli_fetch_field($res)))
+ printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!mysqli_query($link, "DROP TABLE IF EXISTS test"))
+ printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (!mysqli_query($link, "CREATE TABLE test(id INT NOT NULL DEFAULT 1)"))
+ printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (!mysqli_query($link, "INSERT INTO test(id) VALUES (2)"))
+ printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ if (!$res = mysqli_query($link, "SELECT id as _default_test FROM test")) {
+ printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ var_dump(mysqli_fetch_assoc($res));
+ var_dump(mysqli_fetch_field($res));
+ mysqli_free_result($res);
+
+ 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(1)
+ ["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)
+}
+bool(false)
+
+Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d
+array(1) {
+ ["_default_test"]=>
+ string(1) "2"
+}
+object(stdClass)#%d (11) {
+ ["name"]=>
+ string(13) "_default_test"
+ ["orgname"]=>
+ string(2) "id"
+ ["table"]=>
+ string(4) "test"
+ ["orgtable"]=>
+ string(4) "test"
+ ["def"]=>
+ string(0) ""
+ ["max_length"]=>
+ int(1)
+ ["length"]=>
+ int(11)
+ ["charsetnr"]=>
+ int(63)
+ ["flags"]=>
+ int(32769)
+ ["type"]=>
+ int(3)
+ ["decimals"]=>
+ int(0)
+}
+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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [u"flags"]=>
+ int(0)
+ [u"type"]=>
+ int(254)
+ [u"decimals"]=>
+ int(0)
+}
+bool(false)
+
+Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d
+array(1) {
+ [u"_default_test"]=>
+ unicode(1) "2"
+}
+object(stdClass)#%d (11) {
+ [u"name"]=>
+ unicode(13) "_default_test"
+ [u"orgname"]=>
+ unicode(2) "id"
+ [u"table"]=>
+ unicode(4) "test"
+ [u"orgtable"]=>
+ unicode(4) "test"
+ [u"def"]=>
+ unicode(0) ""
+ [u"max_length"]=>
+ int(1)
+ [u"length"]=>
+ int(11)
+ [u"charsetnr"]=>
+ int(63)
+ [u"flags"]=>
+ int(32769)
+ [u"type"]=>
+ int(3)
+ [u"decimals"]=>
+ int(0)
+}
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_field_direct.phpt b/ext/mysqli/tests/mysqli_fetch_field_direct.phpt
new file mode 100644
index 0000000000..a11e0f6bea
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_field_direct.phpt
@@ -0,0 +1,108 @@
+--TEST--
+mysqli_fetch_field_direct()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_fetch_field_direct()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_fetch_field_direct($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_fetch_field_direct($link, $link)))
+ printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+
+ if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) {
+ printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ var_dump(mysqli_fetch_field_direct($res, -1));
+ var_dump(mysqli_fetch_field_direct($res, 0));
+ var_dump(mysqli_fetch_field_direct($res, 2));
+
+ mysqli_free_result($res);
+
+ if (NULL !== ($tmp = mysqli_fetch_field_direct($res, 0)))
+ printf("Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_fetch_field_direct(): Field offset is invalid for resultset in %s on line %d
+bool(false)
+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(%d)
+ ["length"]=>
+ int(%d)
+ ["charsetnr"]=>
+ int(%d)
+ ["flags"]=>
+ int(%d)
+ ["type"]=>
+ int(%d)
+ ["decimals"]=>
+ int(%d)
+}
+
+Warning: mysqli_fetch_field_direct(): Field offset is invalid for resultset in %s on line %d
+bool(false)
+
+Warning: mysqli_fetch_field_direct(): Couldn't fetch mysqli_result in %s on line %d
+done!
+--UEXPECTF--
+Warning: mysqli_fetch_field_direct(): Field offset is invalid for resultset in %s on line %d
+bool(false)
+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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [u"flags"]=>
+ int(%d)
+ [u"type"]=>
+ int(%d)
+ [u"decimals"]=>
+ int(%d)
+}
+
+Warning: mysqli_fetch_field_direct(): Field offset is invalid for resultset in %s on line %d
+bool(false)
+
+Warning: mysqli_fetch_field_direct(): Couldn't fetch mysqli_result in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt
new file mode 100644
index 0000000000..42f8156af2
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt
@@ -0,0 +1,117 @@
+--TEST--
+$res->fetch_field_direct(s)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ $mysqli = new mysqli();
+ $res = @new mysqli_result($mysqli);
+ if (!is_null($tmp = @$res->fetch_field_direct()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+
+ if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket))
+ printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+
+ if (!$res = $mysqli->query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ if (!is_null($tmp = @$res->fetch_field_direct()))
+ printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @$res->fetch_field_direct($link)))
+ printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @$res->fetch_field_direct($link, $link)))
+ printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ var_dump($res->fetch_field_direct(-1));
+ var_dump($res->fetch_field_direct(0));
+ var_dump($res->fetch_field_direct(2));
+
+ $res->free_result();
+
+ if (NULL !== ($tmp = $res->fetch_field_direct(0)))
+ printf("[007] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ $mysqli->close();
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_result::fetch_field_direct(): Field offset is invalid for resultset in %s on line %d
+bool(false)
+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(%d)
+ ["length"]=>
+ int(11)
+ ["charsetnr"]=>
+ int(%d)
+ ["flags"]=>
+ int(%d)
+ ["type"]=>
+ int(%d)
+ ["decimals"]=>
+ int(%d)
+}
+
+Warning: mysqli_result::fetch_field_direct(): Field offset is invalid for resultset in %s on line %d
+bool(false)
+
+Warning: mysqli_result::fetch_field_direct(): Couldn't fetch mysqli_result in %s on line %d
+done!
+--UEXPECTF--
+Warning: mysqli_result::fetch_field_direct(): Field offset is invalid for resultset in %s on line %d
+bool(false)
+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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [u"flags"]=>
+ int(%d)
+ [u"type"]=>
+ int(%d)
+ [u"decimals"]=>
+ int(%d)
+}
+
+Warning: mysqli_result::fetch_field_direct(): Field offset is invalid for resultset in %s on line %d
+bool(false)
+
+Warning: mysqli_result::fetch_field_direct(): Couldn't fetch mysqli_result in %s on line %d
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt
new file mode 100644
index 0000000000..ebaab10cff
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt
@@ -0,0 +1,172 @@
+--TEST--
+mysqli_fetch_field() - flags/field->flags
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $flags = array(
+ MYSQLI_NOT_NULL_FLAG => 'NOT_NULL',
+ MYSQLI_PRI_KEY_FLAG => 'PRI_KEY',
+ MYSQLI_UNIQUE_KEY_FLAG => 'UNIQUE_KEY',
+ MYSQLI_MULTIPLE_KEY_FLAG => 'MULTIPLE_KEY',
+ MYSQLI_BLOB_FLAG => 'BLOB',
+ MYSQLI_UNSIGNED_FLAG => 'UNSIGNED',
+ MYSQLI_ZEROFILL_FLAG => 'ZEROFILL',
+ MYSQLI_AUTO_INCREMENT_FLAG => 'AUTO_INCREMENT',
+ MYSQLI_TIMESTAMP_FLAG => 'TIMESTAMP',
+ MYSQLI_SET_FLAG => 'SET',
+ MYSQLI_NUM_FLAG => 'NUM',
+ MYSQLI_PART_KEY_FLAG => 'PART_KEY',
+ MYSQLI_GROUP_FLAG => 'MYSQLI_GROUP_FLAG'
+ // MYSQLI_NO_DEFAULT_VALUE_FLAG
+ // MYSQLI_BINARY_FLAG
+ // MYSQLI_ENUM_FLAG
+ // MYSQLI_BINCMP_FLAG
+ );
+ krsort($flags);
+
+ $columns = array(
+ 'INT DEFAULT NULL' => 'NUM',
+ 'INT NOT NULL' => 'NOT_NULL NO_DEFAULT_VALUE NUM',
+ 'INT NOT NULL DEFAULT 1' => 'NOT_NULL NUM',
+ 'INT UNSIGNED DEFAULT NULL' => 'UNSIGNED NUM',
+ 'INT UNSIGNED NOT NULL' => 'NOT_NULL UNSIGNED NO_DEFAULT_VALUE NUM',
+ 'INT UNSIGNED NOT NULL DEFAULT 1' => 'NOT_NULL UNSIGNED NULL',
+ 'INT UNSIGNED ZEROFILL DEFAULT NULL' => 'UNSIGNED ZEROFILL NUM',
+ 'INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY' => 'NOT_NULL PRI_KEY UNSIGNED AUTO_INCREMENT NUM PART_KEY',
+ 'CHAR(1) DEFAULT NULL' => '',
+ 'CHAR(1) NOT NULL' => 'NOT_NULL NO_DEFAULT_VALUE',
+ 'TIMESTAMP NOT NULL' => 'NOT_NULL UNSIGNED ZEROFILL BINARY TIMESTAMP',
+ 'VARBINARY(127) DEFAULT NULL' => 'NOT_NULL BINARY',
+ 'BLOB' => 'BLOB BINARY',
+ 'TINYBLOB' => 'BLOB BINARY',
+ 'MEDIUMBLOB' => 'BLOB BINARY',
+ 'LONGBLOB' => 'BLOB BINARY',
+ 'TEXT' => 'BLOB',
+ 'TINYTEXT' => 'BLOB',
+ 'MEDIUMTEXT' => 'BLOB',
+ 'LONGTEXT' => 'BLOB',
+ 'SET("one", "two")' => 'SET',
+ 'SET("one", "two") NOT NULL' => 'NOT_NULL SET NO_DEFAULT_VALUE',
+ 'SET("one", "two") NOT NULL DEFAULT "one"' => 'NOT_NULL SET',
+ 'ENUM("one", "two")' => 'ENUM',
+ 'ENUM("one", "two") NOT NULL' => 'NOT_NULL ENUM NO_DEFAULT_VALUE',
+ 'ENUM("one", "two") NOT NULL DEFAULT "one"' => 'NOT_NULL ENUM',
+ 'TINYINT UNIQUE' => 'UNIQUE_KEY NUM PART_KEY',
+ 'SMALLINT UNIQUE' => 'UNIQUE_KEY NUM PART_KEY',
+ 'MEDIUMINT UNIQUE DEFAULT 1' => 'UNIQUE_KEY NUM PART_KEY',
+ 'BIGINT UNSIGNED UNIQUE DEFAULT 100' => 'UNIQUE_KEY UNSIGNED NUM PART_KEY',
+ 'BIT' => 'UNSIGNED',
+ 'VARCHAR(2) NOT NULL PRIMARY KEY' => 'NOT_NULL PRI_KEY NO_DEFAULT_VALUE PART_KEY'
+ );
+
+ function checkFlags($reported_flags, $expected_flags, $flags) {
+
+ $found_flags = $unexpected_flags = '';
+ foreach ($flags as $code => $name) {
+ if ($code >= $reported_flags) {
+ $reported_flags -= $code;
+ $found_flags .= $name . ' ';
+ if (stristr($expected_flags, $name)) {
+ $expected_flags = trim(str_ireplace($name, '', $expected_flags));
+ } else {
+ $unexpected_flags .= $name . ' ';
+ }
+ }
+ }
+
+ return array($expected_flags, $unexpected_flags, $found_flags);
+ }
+
+ if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
+
+ foreach ($columns as $column_def => $expected_flags) {
+ if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) {
+ printf("[002] %s [%d] %s\n", $column_def,
+ mysqli_errno($link), mysqli_error($link));
+ continue;
+ }
+
+ $create = sprintf('CREATE TABLE test(id INT, col1 %s)', $column_def);
+ if (!mysqli_query($link, $create)) {
+ // Server might not support it - skip
+ continue;
+ }
+
+ if (!$res = mysqli_query($link, 'SELECT * FROM test')) {
+ printf("[003] Can't select from table, %s [%d] %s\n", $column_def,
+ mysqli_errno($link), mysqli_error($link));
+ continue;
+ }
+
+ $field = mysqli_fetch_field_direct($res, 1);
+ if (!is_object($field)) {
+ printf("[004] Fetching the meta data failed, %s [%d] %s\n", $column_def,
+ mysqli_errno($link), mysqli_error($link));
+ continue;
+ }
+ if ($field->name != 'col1') {
+ printf("[005] Field information seems wrong, %s [%d] %s\n", $column_def,
+ mysqli_errno($link), mysqli_error($link));
+ continue;
+ }
+
+ list($missing_flags, $unexpected_flags, $flags_found) = checkFlags($field->flags, $expected_flags, $flags);
+ if ($unexpected_flags)
+ printf("[006] Found unexpected flags '%s' for %s, found '%s'\n",
+ $unexpected_flags, $column_def, $flags_found);
+ if ($missing_flags)
+ printf("[007] The flags '%s' have not been reported for %s, found '%s'\n",
+ $missing_flags, $column_def, $flags_found);
+
+ mysqli_free_result($res);
+ }
+
+ if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) {
+ printf("[008] %s [%d] %s\n", $column_def,
+ mysqli_errno($link), mysqli_error($link));
+ continue;
+ }
+
+ $column_def = array('col1 CHAR(1)', 'col2 CHAR(2)','INDEX idx_col1_col2(col1, col2)');
+ $expected_flags = array('col1' => 'MULTIPLE_KEY PART_KEY', 'col2' => 'PART_KEY');
+ $create = 'CREATE TABLE test(id INT, ';
+ foreach ($column_def as $k => $v) {
+ $create .= sprintf('%s, ', $v);
+ }
+ $create = sprintf('%s)', substr($create, 0, -2));
+
+ if (mysqli_query($link, $create)) {
+ if (!$res = mysqli_query($link, 'SELECT * FROM test')) {
+ printf("[009] Cannot run SELECT, [%d] %s\n",
+ mysqli_errno($link), mysqli_error($link));
+ }
+ // id column - skip it
+ $field = mysqli_fetch_field($res);
+ while ($field = mysqli_fetch_field($res)) {
+ if (!isset($expected_flags[$field->name])) {
+ printf("[010] Found unexpected field '%s'\n", $field->name);
+ continue;
+ }
+ list($missing_flags, $unexpected_flags, $flags_found) = checkFlags($field->flags, $expected_flags[$field->name], $flags);
+ if ($unexpected_flags)
+ printf("[011] Found unexpected flags '%s' for %s, found '%s'\n",
+ $unexpected_flags, $field->name, $flags_found);
+ if ($missing_flags)
+ printf("[012] The flags '%s' have not been reported for %s, found '%s'\n",
+ $missing_flags, $field->name, $flags_found);
+ }
+ }
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt
new file mode 100644
index 0000000000..fcc326f5f3
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt
@@ -0,0 +1,151 @@
+--TEST--
+mysqli_fetch_field()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test
+ $mysqli = new mysqli();
+ $res = @new mysqli_result($mysqli);
+ if (!is_null($tmp = @$res->fetch_field()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket))
+ printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+
+ if (!$res = $mysqli->query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) {
+ printf("[003] [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ if (!is_null($tmp = @$res->fetch_field($link)))
+ printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ while ($tmp = $res->fetch_field())
+ var_dump($tmp);
+ var_dump($tmp);
+
+ $res->free_result();
+
+ if (NULL !== ($tmp = $res->fetch_field()))
+ printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ $mysqli->close();
+ 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(1)
+ ["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)
+}
+bool(false)
+
+Warning: mysqli_result::fetch_field(): Couldn't fetch mysqli_result in %s on line %d
+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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [u"flags"]=>
+ int(%d)
+ [u"type"]=>
+ int(%d)
+ [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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [u"flags"]=>
+ int(%d)
+ [u"type"]=>
+ int(%d)
+ [u"decimals"]=>
+ int(0)
+}
+bool(false)
+
+Warning: mysqli_result::fetch_field(): Couldn't fetch mysqli_result in %s on line %d
+done!
diff --git a/ext/mysqli/tests/mysqli_fetch_field_types.phpt b/ext/mysqli/tests/mysqli_fetch_field_types.phpt
new file mode 100644
index 0000000000..84038c4c8d
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_field_types.phpt
@@ -0,0 +1,119 @@
+--TEST--
+mysqli_fetch_field() - data types/field->type
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ require('table.inc');
+
+ function mysqli_field_datatypes($link, $sql_type, $php_value, $php_type, $datatypes) {
+ if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) {
+ printf("[001] %s, [%d] %s\n", $sql_type,
+ mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+ $sql = sprintf("CREATE TABLE test(id %s)", $sql_type);
+ if (!mysqli_query($link, $sql)) {
+ printf("[002] %s, [%d] %s\n", $sql_type,
+ mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+ $sql = sprintf("INSERT INTO test(id) VALUES ('%s')", $php_value);
+ if (!mysqli_query($link, $sql)) {
+ printf("[003] %s, [%d] %s\n", $sql_type,
+ mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+ if (!$res = mysqli_query($link, 'SELECT id FROM test')) {
+ printf("[004] %s, [%d] %s\n", $sql_type,
+ mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+ if (!is_object($field = mysqli_fetch_field($res))) {
+ printf("[004] %s, expecting object got %s, [%d] %s\n", $sql_type,
+ gettype($field),
+ mysqli_errno($link), mysqli_error($link));
+ return false;
+ }
+
+ if ($field->type != $php_type) {
+ $code_name = 'unknown';
+ foreach ($datatypes as $k => $v) {
+ if ($k == $field->type) {
+ $code_name = (is_array($v)) ? $v[0] : $v;
+ break;
+ }
+ }
+ printf("[006] Expecting %d for %s got code %d for %s\n",
+ $php_type, $sql_type, $field->type, $code_name);
+ return false;
+ }
+
+ return true;
+ }
+
+ $datatypes = array(
+ MYSQLI_TYPE_TINY => array('TINYINT', 5),
+ MYSQLI_TYPE_SHORT => array('SMALLINT', 10),
+ MYSQLI_TYPE_LONG => 'MYSQLI_TYPE_LONG - TODO add testing',
+ MYSQLI_TYPE_FLOAT => array('FLOAT', '1.3'),
+ MYSQLI_TYPE_DOUBLE => array('DOUBLE', '1.4'),
+ MYSQLI_TYPE_TIMESTAMP => array('TIMESTAMP', '2007-08-20 18:34:00'),
+ MYSQLI_TYPE_LONGLONG => array('BIGINT', 100),
+ MYSQLI_TYPE_INT24 => array('MEDIUMINT', 10),
+ MYSQLI_TYPE_DATE => array('DATE', '2007-08-20'),
+ MYSQLI_TYPE_TIME => array('TIME', '18:41:38'),
+ MYSQLI_TYPE_DATETIME => array('DATETIME', '2007-08-20 18:42:01'),
+ MYSQLI_TYPE_YEAR => array('YEAR', '2007'),
+ MYSQLI_TYPE_ENUM => array('ENUM("everything", "is", "just", "wonderful")', 'is'),
+ // MYSQLI_TYPE_SET => array('SET("I", "smash", "the")', 'I,smash,the'), - string
+ // MYSQLI_TYPE_TINY_BLOB => array("TINYBLOB", "I got a tiny blog"), - blob
+ // MYSQLI_TYPE_MEDIUM_BLOB => array("MEDIUMBLOB", "No blob for masses"), - blob
+ // MYSQLI_TYPE_LONG_BLOB => array("LONGBLOB", "Small is beautiful?"), - blob
+ MYSQLI_TYPE_BLOB => array("LONGBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'),
+ MYSQLI_TYPE_BLOB => array("MEDIUMBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'),
+ MYSQLI_TYPE_BLOB => array("TINYBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'),
+ MYSQLI_TYPE_BLOB => array("BLOB", 'silly'),
+ MYSQLI_TYPE_VAR_STRING => array("VARCHAR(32768)", 'varchar'),
+ MYSQLI_TYPE_STRING => 'MYSQLI_TYPE_STRING - TODO add testing',
+ MYSQLI_TYPE_STRING => array('CHAR(1)', 'a'),
+ MYSQLI_TYPE_STRING => array('SET("I", "smash", "the")', 'Will be converted to string although it is a SET...'),
+ MYSQLI_TYPE_NULL => 'MYSQLI_TYPE_NULL - TODO add testing',
+ MYSQLI_TYPE_NEWDATE => 'MYSQLI_TYPE_NEWDATE - TODO add testing',
+ MYSQLI_TYPE_INTERVAL => 'MYSQLI_TYPE_INTERVAL - TODO add testing',
+ MYSQLI_TYPE_GEOMETRY => 'MYSQLI_TYPE_GEOMETRY - TODO add testing',
+ );
+
+ if ($IS_MYSQLND) {
+ $version = 50007 + 1;
+ } else {
+ $version = mysqli_get_client_version();
+ }
+
+ if ($version > 50002) {
+ $datatypes[MYSQLI_TYPE_NEWDECIMAL] = array('DECIMAL', '1.1');
+ $datatypes[MYSQLI_TYPE_BIT] = array('BIT', 0);
+ } else {
+ $datatypes[MYSQLI_TYPE_DECIMAL] = array('DECIMAL', '1.1');
+ }
+
+ foreach ($datatypes as $php_type => $datatype) {
+ if (is_array($datatype))
+ mysqli_field_datatypes($link, $datatype[0], $datatype[1], $php_type, $datatypes);
+ }
+
+ mysqli_close($link);
+
+ print "done!";
+?>
+--EXPECTF--
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_fields.phpt b/ext/mysqli/tests/mysqli_fetch_fields.phpt
new file mode 100644
index 0000000000..3ddf854e1b
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_fields.phpt
@@ -0,0 +1,143 @@
+--TEST--
+mysqli_fetch_fields()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test
+ if (!is_null($tmp = @mysqli_fetch_fields()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_fetch_fields($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ $fields = mysqli_fetch_fields($res);
+ foreach ($fields as $k => $field)
+ var_dump($field);
+
+ mysqli_free_result($res);
+
+ if (NULL !== ($tmp = mysqli_fetch_fields($res)))
+ printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ 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(1)
+ ["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)
+}
+
+Warning: mysqli_fetch_fields(): Couldn't fetch mysqli_result in %s on line %d
+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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [u"flags"]=>
+ int(%d)
+ [u"type"]=>
+ int(%d)
+ [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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [u"flags"]=>
+ int(0)
+ [u"type"]=>
+ int(%d)
+ [u"decimals"]=>
+ int(0)
+}
+
+Warning: mysqli_fetch_fields(): Couldn't fetch mysqli_result in %s on line %d
+done!
diff --git a/ext/mysqli/tests/mysqli_fetch_lengths.phpt b/ext/mysqli/tests/mysqli_fetch_lengths.phpt
new file mode 100644
index 0000000000..054bfcb29f
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_lengths.phpt
@@ -0,0 +1,51 @@
+--TEST--
+mysqli_fetch_lengths()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket))
+ printf("[001] Cannot connect\n");
+
+ if (!is_null($tmp = @mysqli_fetch_lengths()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_fetch_lengths($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1")) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ var_dump(mysqli_fetch_lengths($res));
+ while ($row = mysqli_fetch_assoc($res))
+ var_dump(mysqli_fetch_lengths($res));
+ var_dump(mysqli_fetch_lengths($res));
+
+ mysqli_free_result($res);
+
+ var_dump(mysqli_fetch_lengths($res));
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+bool(false)
+array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+}
+bool(false)
+
+Warning: mysqli_fetch_lengths(): 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_fetch_lengths_oo.phpt b/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt
new file mode 100644
index 0000000000..77797d4514
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt
@@ -0,0 +1,43 @@
+--TEST--
+mysqli_result->lengths
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket))
+ printf("[001] Cannot connect\n");
+
+ require('table.inc');
+ if (!$res = $mysqli->query("SELECT id, label FROM test ORDER BY id LIMIT 1")) {
+ printf("[002] [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ var_dump($res->lengths);
+ while ($row = $res->fetch_assoc())
+ var_dump($res->lengths);
+ var_dump($res->lengths);
+
+ $res->free_result();
+ var_dump($res->lengths);
+ $mysqli->close();
+ print "done!";
+?>
+--EXPECTF--
+NULL
+array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+}
+NULL
+
+Warning: main(): 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_fetch_object.phpt b/ext/mysqli/tests/mysqli_fetch_object.phpt
new file mode 100644
index 0000000000..39cfd0518f
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_object.phpt
@@ -0,0 +1,153 @@
+--TEST--
+mysqli_fetch_object()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include_once("connect.inc");
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_fetch_object()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_fetch_object($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5")) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ $obj = mysqli_fetch_object($res);
+ if (($obj->ID !== "1") || ($obj->label !== "a") || (get_class($obj) != 'stdClass')) {
+ printf("[004] Object seems wrong. [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ var_dump($obj);
+ }
+
+ class mysqli_fetch_object_test {
+
+ public $a = null;
+ public $b = null;
+
+ public function toString() {
+ var_dump($this);
+ }
+ }
+
+ $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_test');
+ if (($obj->ID !== "2") || ($obj->label !== "b") || ($obj->a !== NULL) || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_test')) {
+ printf("[005] Object seems wrong. [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ var_dump($obj);
+ }
+
+
+
+ class mysqli_fetch_object_construct extends mysqli_fetch_object_test {
+
+ public function __construct($a, $b) {
+ $this->a = $a;
+ $this->b = $b;
+ }
+
+ }
+
+ $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_construct', null);
+
+ if (($obj->ID !== "3") || ($obj->label !== "c") || ($obj->a !== NULL) || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_construct')) {
+ printf("[006] Object seems wrong. [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ var_dump($obj);
+ }
+
+ $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_construct', array('a'));
+ if (($obj->ID !== "4") || ($obj->label !== "d") || ($obj->a !== 'a') || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_construct')) {
+ printf("[007] Object seems wrong. [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ var_dump($obj);
+ }
+
+ $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_construct', array('a', 'b'));
+ if (($obj->ID !== "5") || ($obj->label !== "e") || ($obj->a !== 'a') || ($obj->b !== 'b') || (get_class($obj) != 'mysqli_fetch_object_construct')) {
+ printf("[008] Object seems wrong. [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ var_dump($obj);
+ }
+
+ var_dump(mysqli_fetch_object($res, 'mysqli_fetch_object_construct', array('a', 'b', 'c')));
+ var_dump(mysqli_fetch_object($res));
+
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST")) {
+ printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ mysqli_free_result($res);
+ var_dump(mysqli_fetch_object($res));
+
+ if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5"))
+ printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ /*
+ TODO
+ I'm using the procedural interface, this should not throw an exception.
+ Also, I did not ask to get exceptions using the mysqli_options()
+ */
+ try {
+ if (false !== ($obj = mysqli_fetch_object($res, 'mysqli_fetch_object_construct', 'a')))
+ printf("[011] Should have failed\n");
+ } catch (Exception $e) {
+ printf("%s\n", $e->getMessage());
+ }
+
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5"))
+ printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ class mysqli_fetch_object_private_constructor extends mysqli_fetch_object_test {
+
+ private function __construct($a, $b) {
+ $this->a = $a;
+ $this->b = $b;
+ }
+ }
+ /*
+ TODO
+ I think we should bail out here. The following line will give a Fatal error: Call to private ... from invalid context
+ var_dump($obj = new mysqli_fetch_object_private_constructor(1, 2));
+ This does not fail.
+ */
+ $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_private_constructor', array('a', 'b'));
+ mysqli_free_result($res);
+
+ // Fatal error, script execution will end
+ var_dump(mysqli_fetch_object($res, 'this_class_does_not_exist'));
+
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+Warning: Missing argument 1 for mysqli_fetch_object_construct::__construct() in %s on line %d
+
+Warning: Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d
+
+Notice: Undefined variable: a in %s on line %d
+
+Notice: Undefined variable: b in %s on line %d
+
+Warning: Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d
+
+Notice: Undefined variable: b in %s on line %d
+NULL
+NULL
+
+Warning: mysqli_fetch_object(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+Parameter ctor_params must be an array
+
+Fatal error: Class 'this_class_does_not_exist' not found in %s on line %d \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt b/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt
new file mode 100644
index 0000000000..9c87aabf18
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt
@@ -0,0 +1,76 @@
+--TEST--
+mysqli_fetch_object() - calling constructor on class wo constructor
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5")) {
+ printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ class mysqli_fetch_object_test {
+
+ public $a = null;
+ public $b = null;
+
+ public function toString() {
+ var_dump($this);
+ }
+ }
+
+ printf("No exception with PHP:\n");
+ var_dump($obj = new mysqli_fetch_object_test(1, 2));
+
+ printf("\nException with mysqli. Note that at all other places we throws errors but no exceptions unless the error mode has been changed:\n");
+ try {
+ var_dump($obj = mysqli_fetch_object($res, 'mysqli_fetch_object_test', array(1, 2)));
+ } catch (Exception $e) {
+ printf("Exception: %s\n", $e->getMessage());
+ }
+
+ printf("\nFatal error with PHP (but no exception!):\n");
+ var_dump($obj->mysqli_fetch_object_test(1, 2));
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+No exception with PHP:
+object(mysqli_fetch_object_test)#%d (%d) {
+ ["a"]=>
+ NULL
+ ["b"]=>
+ NULL
+}
+
+Exception with mysqli. Note that at all other places we throws errors but no exceptions unless the error mode has been changed:
+Exception: Class mysqli_fetch_object_test does not have a constructor hence you cannot use ctor_params
+
+Fatal error with PHP (but no exception!):
+
+Fatal error: Call to undefined method mysqli_fetch_object_test::mysqli_fetch_object_test() in %s on line %d
+--UEXPECTF--
+No exception with PHP:
+object(mysqli_fetch_object_test)#%d (%d) {
+ [%s"a"]=>
+ NULL
+ [%s"b"]=>
+ NULL
+}
+
+Exception with mysqli. Note that at all other places we throws errors but no exceptions unless the error mode has been changed:
+Exception: Class mysqli_fetch_object_test does not have a constructor hence you cannot use ctor_params
+
+Fatal error with PHP (but no exception!):
+
+Fatal error: Call to undefined method mysqli_fetch_object_test::mysqli_fetch_object_test() in %s on line %d \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_object_no_object.phpt b/ext/mysqli/tests/mysqli_fetch_object_no_object.phpt
new file mode 100644
index 0000000000..a9173d093e
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_object_no_object.phpt
@@ -0,0 +1,24 @@
+--TEST--
+mysqli_fetch_object()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5")) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ $obj = mysqli_fetch_object($res);
+ var_dump(gettype($obj));
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+%s(6) "object"
+done!
diff --git a/ext/mysqli/tests/mysqli_fetch_object_oo.phpt b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt
new file mode 100644
index 0000000000..fe3434cf63
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt
@@ -0,0 +1,126 @@
+--TEST--
+mysqli_fetch_object()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ $mysqli = new mysqli();
+ $res = @new mysqli_result($mysqli);
+ if (!is_null($tmp = @$res->fetch_object()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket))
+ printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+
+ if (!$res = $mysqli->query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5")) {
+ printf("[003] [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ if (!is_null($tmp = @$res->fetch_object($link)))
+ printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @$res->fetch_object($link, $link)))
+ printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @$res->fetch_object($link, $link, $link)))
+ printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ $obj = mysqli_fetch_object($res);
+ if (($obj->ID !== "1") || ($obj->label !== "a") || (get_class($obj) != 'stdClass')) {
+ printf("[007] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error);
+ var_dump($obj);
+ }
+
+ class mysqli_fetch_object_test {
+
+ public $a = null;
+ public $b = null;
+
+ public function toString() {
+ var_dump($this);
+ }
+ }
+
+ $obj = $res->fetch_object('mysqli_fetch_object_test');
+ if (($obj->ID !== "2") || ($obj->label !== "b") || ($obj->a !== NULL) || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_test')) {
+ printf("[008] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error);
+ var_dump($obj);
+ }
+
+ class mysqli_fetch_object_construct extends mysqli_fetch_object_test {
+
+ public function __construct($a, $b) {
+ $this->a = $a;
+ $this->b = $b;
+ }
+
+ }
+
+ $obj = $res->fetch_object('mysqli_fetch_object_construct', null);
+
+ if (($obj->ID !== "3") || ($obj->label !== "c") || ($obj->a !== NULL) || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_construct')) {
+ printf("[009] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error);
+ var_dump($obj);
+ }
+
+ $obj = $res->fetch_object('mysqli_fetch_object_construct', array('a'));
+ if (($obj->ID !== "4") || ($obj->label !== "d") || ($obj->a !== 'a') || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_construct')) {
+ printf("[010] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error);
+ var_dump($obj);
+ }
+
+ $obj = $res->fetch_object('mysqli_fetch_object_construct', array('a', 'b'));
+ if (($obj->ID !== "5") || ($obj->label !== "e") || ($obj->a !== 'a') || ($obj->b !== 'b') || (get_class($obj) != 'mysqli_fetch_object_construct')) {
+ printf("[011] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error);
+ var_dump($obj);
+ }
+
+ var_dump($res->fetch_object('mysqli_fetch_object_construct', array('a', 'b', 'c')));
+ var_dump(mysqli_fetch_object($res));
+
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST")) {
+ printf("[012] [%d] %s\n", $mysqli->errno, $mysqli->error);
+ }
+
+ mysqli_free_result($res);
+
+ var_dump(mysqli_fetch_object($res));
+
+ // Fatal error, script execution will end
+ var_dump($res->fetch_object('this_class_does_not_exist'));
+
+ $mysqli->close();
+ print "done!";
+?>
+--EXPECTF--
+Warning: Missing argument 1 for mysqli_fetch_object_construct::__construct() in %s on line %d
+
+Warning: Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d
+
+Notice: Undefined variable: a in %s on line %d
+
+Notice: Undefined variable: b in %s on line %d
+
+Warning: Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d
+
+Notice: Undefined variable: b in %s on line %d
+NULL
+NULL
+
+Warning: mysqli_fetch_object(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+
+Fatal error: Class 'this_class_does_not_exist' not found in %s on line %d \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_fetch_row.phpt b/ext/mysqli/tests/mysqli_fetch_row.phpt
new file mode 100644
index 0000000000..22ec282eb1
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fetch_row.phpt
@@ -0,0 +1,71 @@
+--TEST--
+mysqli_fetch_row()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_fetch_row()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_fetch_row($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT id, label, id AS _id FROM test ORDER BY id LIMIT 1")) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ print "[004]\n";
+ var_dump(mysqli_fetch_row($res));
+
+ print "[005]\n";
+ var_dump(mysqli_fetch_row($res));
+
+ mysqli_free_result($res);
+
+ var_dump(mysqli_fetch_row($res));
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+[004]
+array(3) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "a"
+ [2]=>
+ string(1) "1"
+}
+[005]
+NULL
+
+Warning: mysqli_fetch_row(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+done!
+--UEXPECTF--
+[004]
+array(3) {
+ [0]=>
+ unicode(1) "1"
+ [1]=>
+ unicode(1) "a"
+ [2]=>
+ unicode(1) "1"
+}
+[005]
+NULL
+
+Warning: mysqli_fetch_row(): 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_field_count.phpt b/ext/mysqli/tests/mysqli_field_count.phpt
new file mode 100644
index 0000000000..8d1e8da5ea
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_field_count.phpt
@@ -0,0 +1,59 @@
+--TEST--
+mysqli_field_count()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_field_count()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_field_count($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+
+ var_dump(mysqli_field_count($link));
+
+ if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 1")) {
+ printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ var_dump(mysqli_field_count($link));
+
+ mysqli_free_result($res);
+
+ if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'x')"))
+ printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ var_dump($link->field_count);
+ var_dump(mysqli_field_count($link));
+
+ if (!$res = mysqli_query($link, 'SELECT NULL as _null, "" AS "", "three" AS "drei"'))
+ printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ var_dump(mysqli_field_count($link));
+ mysqli_free_result($res);
+
+ mysqli_close($link);
+
+ var_dump(mysqli_field_count($link));
+
+ print "done!";
+?>
+--EXPECTF--
+int(0)
+int(2)
+int(0)
+int(0)
+int(3)
+
+Warning: mysqli_field_count(): Couldn't fetch mysqli in %s on line %d
+NULL
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_field_seek.phpt b/ext/mysqli/tests/mysqli_field_seek.phpt
new file mode 100644
index 0000000000..c3065dd494
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_field_seek.phpt
@@ -0,0 +1,331 @@
+--TEST--
+mysqli_field_seek()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ function mysqli_field_seek_flags($flags) {
+
+ $ret = '';
+
+ if ($flags & MYSQLI_NOT_NULL_FLAG)
+ $ret .= 'MYSQLI_NOT_NULL_FLAG ';
+
+ if ($flags & MYSQLI_PRI_KEY_FLAG)
+ $ret .= 'MYSQLI_PRI_KEY_FLAG ';
+
+ if ($flags & MYSQLI_UNIQUE_KEY_FLAG)
+ $ret .= 'MYSQLI_UNIQUE_KEY_FLAG ';
+
+ if ($flags & MYSQLI_MULTIPLE_KEY_FLAG)
+ $ret .= 'MYSQLI_MULTIPLE_KEY_FLAG ';
+
+ if ($flags & MYSQLI_BLOB_FLAG)
+ $ret .= 'MYSQLI_BLOB_FLAG ';
+
+ if ($flags & MYSQLI_UNSIGNED_FLAG)
+ $ret .= 'MYSQLI_UNSIGNED_FLAG ';
+
+ if ($flags & MYSQLI_ZEROFILL_FLAG)
+ $ret .= 'MYSQLI_ZEROFILL_FLAG ';
+
+ if ($flags & MYSQLI_AUTO_INCREMENT_FLAG)
+ $ret .= 'MYSQLI_AUTO_INCREMENT_FLAG ';
+
+ if ($flags & MYSQLI_TIMESTAMP_FLAG)
+ $ret .= 'MYSQLI_TIMESTAMP_FLAG ';
+
+ if ($flags & MYSQLI_SET_FLAG)
+ $ret .= 'MYSQLI_SET_FLAG ';
+
+ if ($flags & MYSQLI_NUM_FLAG)
+ $ret .= 'MYSQLI_NUM_FLAG ';
+
+ if ($flags & MYSQLI_PART_KEY_FLAG)
+ $ret .= 'MYSQLI_PART_KEY_FLAG ';
+
+ if ($flags & MYSQLI_GROUP_FLAG)
+ $ret .= 'MYSQLI_GROUP_FLAG ';
+
+ return $ret;
+ }
+
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_field_seek()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_field_seek($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1", MYSQLI_USE_RESULT)) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ var_dump(mysqli_field_seek($res, -1));
+ var_dump(mysqli_fetch_field($res));
+ var_dump(mysqli_field_seek($res, 0));
+ var_dump(mysqli_fetch_field($res));
+ var_dump(mysqli_field_seek($res, 1));
+ var_dump(mysqli_fetch_field($res));
+ var_dump(mysqli_field_tell($res));
+ var_dump(mysqli_field_seek($res, 2));
+ var_dump(mysqli_fetch_field($res));
+ var_dump(mysqli_field_seek($res, PHP_INT_MAX + 1));
+
+ if (!is_null($tmp = @mysqli_field_seek($res, 0, "too many")))
+ printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ mysqli_free_result($res);
+
+ if (!$res = mysqli_query($link, "SELECT NULL as _null", MYSQLI_STORE_RESULT)) {
+ printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ var_dump(mysqli_field_seek($res, 0));
+ var_dump(mysqli_fetch_field($res));
+
+ mysqli_free_result($res);
+
+ var_dump(mysqli_field_seek($res, 0));
+
+
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
+bool(false)
+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)
+}
+bool(true)
+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)
+}
+bool(true)
+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(0)
+ ["length"]=>
+ int(1)
+ ["charsetnr"]=>
+ int(8)
+ ["flags"]=>
+ int(0)
+ ["type"]=>
+ int(254)
+ ["decimals"]=>
+ int(0)
+}
+int(2)
+
+Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
+bool(false)
+bool(false)
+
+Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
+bool(false)
+bool(true)
+object(stdClass)#3 (11) {
+ ["name"]=>
+ string(5) "_null"
+ ["orgname"]=>
+ string(0) ""
+ ["table"]=>
+ string(0) ""
+ ["orgtable"]=>
+ string(0) ""
+ ["def"]=>
+ string(0) ""
+ ["max_length"]=>
+ int(0)
+ ["length"]=>
+ int(0)
+ ["charsetnr"]=>
+ int(63)
+ ["flags"]=>
+ int(32896)
+ ["type"]=>
+ int(6)
+ ["decimals"]=>
+ int(0)
+}
+
+Warning: mysqli_field_seek(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+done!
+--UEXPECTF--
+Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
+bool(false)
+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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [u"flags"]=>
+ int(%d)
+ [u"type"]=>
+ int(%d)
+ [u"decimals"]=>
+ int(0)
+}
+bool(true)
+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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [u"flags"]=>
+ int(%d)
+ [u"type"]=>
+ int(%d)
+ [u"decimals"]=>
+ int(0)
+}
+bool(true)
+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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [u"flags"]=>
+ int(%d)
+ [u"type"]=>
+ int(%d)
+ [u"decimals"]=>
+ int(0)
+}
+int(2)
+
+Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
+bool(false)
+bool(false)
+
+Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
+bool(false)
+bool(true)
+object(stdClass)#3 (11) {
+ [u"name"]=>
+ unicode(5) "_null"
+ [u"orgname"]=>
+ unicode(0) ""
+ [u"table"]=>
+ unicode(0) ""
+ [u"orgtable"]=>
+ unicode(0) ""
+ [u"def"]=>
+ unicode(0) ""
+ [u"max_length"]=>
+ int(0)
+ [u"length"]=>
+ int(0)
+ [u"charsetnr"]=>
+ int(63)
+ [u"flags"]=>
+ int(32896)
+ [u"type"]=>
+ int(6)
+ [u"decimals"]=>
+ int(0)
+}
+
+Warning: mysqli_field_seek(): 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_field_tell.phpt b/ext/mysqli/tests/mysqli_field_tell.phpt
new file mode 100644
index 0000000000..fae8bc4d7f
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_field_tell.phpt
@@ -0,0 +1,148 @@
+--TEST--
+mysqli_field_tell()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_field_tell()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_field_tell($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT id FROM test ORDER BY id LIMIT 1", MYSQLI_USE_RESULT)) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ var_dump(mysqli_field_tell($res));
+ var_dump(mysqli_field_seek(1));
+ var_dump(mysqli_field_tell($res));
+ var_dump(mysqli_fetch_field($res));
+ var_dump(mysqli_fetch_field($res));
+ var_dump(mysqli_field_tell($res));
+
+ if (!is_null($tmp = @mysqli_field_tell($res, 'too many arguments')))
+ printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+
+ var_dump(mysqli_field_seek($res, 2));
+ var_dump(mysqli_field_tell($res));
+
+ var_dump(mysqli_field_seek($res, -1));
+ var_dump(mysqli_field_tell($res));
+
+ var_dump(mysqli_field_seek($res, 0));
+ var_dump(mysqli_field_tell($res));
+
+
+
+ mysqli_free_result($res);
+
+ var_dump(mysqli_field_tell($res));
+
+ mysqli_close($link);
+
+ print "done!";
+?>
+--EXPECTF--
+int(0)
+
+Warning: mysqli_field_seek() expects exactly 2 parameters, 1 given in %s on line %d
+NULL
+int(0)
+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)
+}
+bool(false)
+int(1)
+
+Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
+bool(false)
+int(1)
+
+Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
+bool(false)
+int(1)
+bool(true)
+int(0)
+
+Warning: mysqli_field_tell(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+done!
+--UEXPECTF--
+int(0)
+
+Warning: mysqli_field_seek() expects exactly 2 parameters, 1 given in %s on line %d
+NULL
+int(0)
+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(%d)
+ [u"length"]=>
+ int(%d)
+ [u"charsetnr"]=>
+ int(%d)
+ [u"flags"]=>
+ int(%d)
+ [u"type"]=>
+ int(%d)
+ [u"decimals"]=>
+ int(0)
+}
+bool(false)
+int(1)
+
+Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
+bool(false)
+int(1)
+
+Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
+bool(false)
+int(1)
+bool(true)
+int(0)
+
+Warning: mysqli_field_tell(): 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_fork.phpt b/ext/mysqli/tests/mysqli_fork.phpt
new file mode 100644
index 0000000000..bede1b40b4
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_fork.phpt
@@ -0,0 +1,264 @@
+--TEST--
+Forking a child and using the same connection.
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+if (!function_exists('pcntl_fork'))
+ die("skip Process Control Functions not available");
+
+if (!function_exists('posix_getpid'))
+ die("skip POSIX functions not available");
+
+require_once('connect.inc');
+if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
+ die(sprintf("skip Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket));
+}
+
+if (!$res = mysqli_query($link, "SHOW VARIABLES LIKE 'have_innodb'")) {
+ die(sprintf("skip Cannot fetch have_innodb variable\n"));
+}
+
+$row = mysqli_fetch_row($res);
+mysqli_free_result($res);
+mysqli_close($link);
+
+if ($row[1] == "DISABLED" || $row[1] == "NO") {
+ die(sprintf ("skip Innodb support is not installed or enabled."));
+}
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+ require_once("table.inc");
+
+ $res = mysqli_query($link, "SELECT 'dumped by the parent' AS message");
+ $pid = pcntl_fork();
+ switch ($pid) {
+ case -1:
+ printf("[001] Cannot fork child");
+ break;
+
+ case 0:
+ /* child */
+ exit(0);
+ break;
+
+ default:
+ /* parent */
+ $status = null;
+ $wait_id = pcntl_waitpid($pid, $status);
+ if (pcntl_wifexited($status) && (0 != ($tmp = pcntl_wexitstatus($status)))) {
+ printf("Exit code: %s\n", (pcntl_wifexited($status)) ? pcntl_wexitstatus($status) : 'n/a');
+ printf("Signal: %s\n", (pcntl_wifsignaled($status)) ? pcntl_wtermsig($status) : 'n/a');
+ printf("Stopped: %d\n", (pcntl_wifstopped($status)) ? pcntl_wstopsig($status) : 'n/a');
+ }
+ var_dump(mysqli_fetch_assoc($res));
+ mysqli_free_result($res);
+ break;
+ }
+
+ if (@mysqli_query($link, "SELECT id FROM test WHERE id = 1"))
+ printf("[003] Expecting error and closed connection, child exit should have closed connection\n");
+ else if ((($errno = mysqli_errno($link)) == 0) || ('' == ($error = mysqli_error($link))))
+ printf("[004] Expecting error string and error code from MySQL, got errno = %s/%s, error = %s/%s\n",
+ gettype($errno), $errno, gettype($error), $error);
+
+ mysqli_close($link);
+ if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ printf("[005] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+
+ /* non trivial tests require a message list for parent-child communication */
+ if (!mysqli_query($link, "DROP TABLE IF EXISTS messages"))
+ printf("[006] [%d] %s\n", mysqli_error($link), mysqli_errno($link));
+
+ if (!mysqli_query($link, "CREATE TABLE messages(
+ msg_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ msg_time TIMESTAMP,
+ pid INT NOT NULL,
+ sender ENUM('child', 'parent') NOT NULL,
+ msg TEXT) ENGINE = InnoDB"))
+ printf("[007] [%d] %s\n", mysqli_error($link), mysqli_errno($link));
+
+ mysqli_autocommit($link, false);
+ if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 3", MYSQLI_USE_RESULT))
+ printf("[008] [%d] %s\n", mysqli_error($link), mysqli_errno($link));
+
+ $pid = pcntl_fork();
+
+ switch ($pid) {
+ case -1:
+ printf("[009] Cannot fork child");
+ break;
+
+ case 0:
+ /* child */
+ if (!($plink = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) || !mysqli_autocommit($plink, true))
+ exit(mysqli_errno($plink));
+
+ $sql = sprintf("INSERT INTO messages(pid, sender, msg) VALUES (%d, 'child', '%%s')", posix_getpid());
+ if (!mysqli_query($plink, sprintf($sql, 'start')))
+ exit(mysqli_errno($plink));
+
+ $parent_sql = sprintf("SELECT msg_id, msg_time, msg FROM messages WHERE pid = %d AND sender = 'parent' ORDER BY msg_id DESC LIMIT 1", posix_getppid());
+ $msg_id = 0;
+ while ($row = mysqli_fetch_assoc($res)) {
+ /* send row to parent */
+ ob_start();
+ var_dump($row);
+ $tmp = ob_get_contents();
+ ob_end_clean();
+ if (!mysqli_query($plink, sprintf($sql, $tmp)))
+ exit(mysqli_errno($plink));
+
+ /* let the parent reply... */
+ $start = time();
+ do {
+ usleep(100);
+ if (!$pres = mysqli_query($plink, $parent_sql))
+ continue;
+ $tmp = mysqli_fetch_assoc($pres);
+ mysqli_free_result($pres);
+ if ($tmp['msg_id'] == $msg_id)
+ /* no new message */
+ continue;
+ if ($tmp['msg'] == 'stop')
+ break 2;
+ $msg_id = $tmp['msg_id'];
+ break;
+ } while ((time() - $start) < 5);
+
+ }
+
+ if (!mysqli_query($plink, sprintf($sql, 'stop')) || !mysqli_commit($link))
+ exit(mysqli_errno($plink));
+ exit(0);
+ break;
+
+ default:
+ /* parent */
+ if (!$plink = mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ printf("[010] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+
+ $status = null;
+ $start = time();
+ $sql = sprintf("SELECT msg_id, msg_time, msg FROM messages WHERE pid = %d AND sender = 'child' ORDER BY msg_id DESC LIMIT 1", $pid);
+ $parent_sql = sprintf("INSERT INTO messages (pid, sender, msg) VALUES (%d, 'parent', '%%s')", posix_getpid());
+ $last_msg_id = 0;
+ $num_rows = 0;
+ do {
+ $wait_id = pcntl_waitpid($pid, $status, WNOHANG);
+ if ($pres = mysqli_query($plink, $sql)) {
+ $row = mysqli_fetch_assoc($pres);
+ if ($row['msg_id'] != $last_msg_id) {
+ $last_msg_id = $row['msg_id'];
+ switch ($row['msg']) {
+ case 'start':
+ break;
+ case 'stop':
+ break 2;
+ default:
+ /* client has started fetching rows */
+ $client_row = $row['msg'];
+
+ $num_rows++;
+ if ($num_rows > 3) {
+ printf("[011] Child has fetched more than three rows!\n");
+ var_dump($client_row);
+ if (!mysqli_query($plink, sprintf($parent_sql, 'stop'))) {
+ printf("[012] Parent cannot inform child\n", mysqli_errno($plink), mysqli_error($plink));
+ }
+ break 2;
+ }
+
+ if (!$parent_row = mysqli_fetch_assoc($res)) {
+ printf("[013] Parent cannot fetch row %d\n", $num_rows, mysqli_errno($link), mysqli_error($link));
+ if (!mysqli_query($plink, sprintf($parent_sql, 'stop'))) {
+ printf("[014] Parent cannot inform child\n", mysqli_errno($plink), mysqli_error($plink));
+ }
+ break 2;
+ }
+
+ ob_start();
+ var_dump($parent_row);
+ $parent_row = ob_get_contents();
+ ob_end_clean();
+
+ if ($parent_row != $client_row) {
+ printf("[015] Child indicates different results than parent.\n");
+ var_dump($child_row);
+ var_dump($parent_row);
+ if (!mysqli_query($plink, sprintf($parent_sql, 'stop'))) {
+ printf("[016] Parent cannot inform child\n", mysqli_errno($plink), mysqli_error($plink));
+ }
+ break 2;
+ }
+
+ if (!mysqli_query($plink, sprintf($parent_sql, 'continue'))) {
+ printf("[017] Parent cannot inform child to continue.\n", mysqli_errno($plink), mysqli_error($plink));
+ }
+ break;
+ }
+ }
+ mysqli_free_result($pres);
+ }
+ usleep(100);
+ } while (((time() - $start) < 5) && ($num_rows < 3));
+ mysqli_close($plink);
+ $wait_id = pcntl_waitpid($pid, $status);
+ if (pcntl_wifexited($status) && (0 != ($tmp = pcntl_wexitstatus($status)))) {
+ printf("Exit code: %s\n", (pcntl_wifexited($status)) ? pcntl_wexitstatus($status) : 'n/a');
+ printf("Signal: %s\n", (pcntl_wifsignaled($status)) ? pcntl_wtermsig($status) : 'n/a');
+ printf("Stopped: %d\n", (pcntl_wifstopped($status)) ? pcntl_wstopsig($status) : 'n/a');
+ }
+ break;
+ }
+ mysqli_free_result($res);
+ mysqli_close($link);
+
+ if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ printf("[018] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+
+ if (!$res = mysqli_query($link, "SELECT sender, msg FROM messages ORDER BY msg_id ASC"))
+ printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+
+ while ($row = mysqli_fetch_assoc($res))
+ printf("%10s %s\n", $row['sender'], substr($row['msg'], 0, 5));
+ mysqli_free_result($res);
+
+ print "done!";
+?>
+--EXPECTF--
+array(1) {
+ ["message"]=>
+ string(20) "dumped by the parent"
+}
+ child start
+ child array
+ parent conti
+ child array
+ parent conti
+ child array
+ parent conti
+ child stop
+done!
+--UEXPECTF--
+array(1) {
+ [u"message"]=>
+ unicode(20) "dumped by the parent"
+}
+ child start
+ child array
+ parent conti
+ child array
+ parent conti
+ child array
+ parent conti
+ child stop
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_free_result.phpt b/ext/mysqli/tests/mysqli_free_result.phpt
new file mode 100644
index 0000000000..32f57078df
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_free_result.phpt
@@ -0,0 +1,75 @@
+--TEST--
+mysqli_free_result()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ include "connect.inc";
+
+ $db = 'test';
+ $tmp = NULL;
+ $link = NULL;
+
+ if (!is_null($tmp = @mysqli_free_result()))
+ printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ if (!is_null($tmp = @mysqli_free_result($link)))
+ printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
+
+ require('table.inc');
+ if (!$res = mysqli_query($link, "SELECT id FROM test ORDER BY id LIMIT 1")) {
+ printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+
+ print "a\n";
+ var_dump(mysqli_free_result($res));
+ print "b\n";
+ var_dump(mysqli_free_result($res));
+
+ if (!$res = mysqli_query($link, "SELECT id FROM test ORDER BY id LIMIT 1")) {
+ printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "c\n";
+ var_dump($res = mysqli_store_result($link));
+ var_dump(mysqli_error($link));
+ print "[005]\n";
+ var_dump(mysqli_free_result($res));
+
+ if (!$res = mysqli_query($link, "SELECT id FROM test ORDER BY id LIMIT 1")) {
+ printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ print "d\n";
+ var_dump($res = mysqli_use_result($link));
+ var_dump(mysqli_error($link));
+ print "[007]\n";
+ var_dump(mysqli_free_result($res));
+
+ mysqli_close($link);
+ print "done!";
+?>
+--EXPECTF--
+a
+NULL
+b
+
+Warning: mysqli_free_result(): Couldn't fetch mysqli_result in %s on line %d
+NULL
+c
+bool(false)
+%s(0) ""
+[005]
+
+Warning: mysqli_free_result() expects parameter 1 to be mysqli_result, boolean given in %s on line %d
+NULL
+d
+bool(false)
+%s(0) ""
+[007]
+
+Warning: mysqli_free_result() expects parameter 1 to be mysqli_result, boolean given in %s on line %d
+NULL
+done! \ No newline at end of file