From eefce01f8dd671702390e45b426f14a0779bbe25 Mon Sep 17 00:00:00 2001 From: Ulf Wendel Date: Wed, 10 Oct 2007 10:43:39 +0000 Subject: [PATCH] Adding new tests = making sure we're in sync with the 5_3 branch --- .../tests/mysqli_change_user_get_lock.phpt | 102 +++++++++ .../tests/mysqli_change_user_insert_id.phpt | 56 +++++ .../mysqli_change_user_locks_temporary.phpt | 103 +++++++++ ext/mysqli/tests/mysqli_change_user_oo.phpt | 2 +- ...ysqli_change_user_prepared_statements.phpt | 33 +++ .../tests/mysqli_change_user_rollback.phpt | 70 ++++++ .../tests/mysqli_change_user_set_names.phpt | 165 +++++++++++++ ext/mysqli/tests/mysqli_debug.phpt | 42 +++- ext/mysqli/tests/mysqli_debug_append.phpt | 79 +++++++ .../tests/mysqli_debug_control_string.phpt | 67 ++++++ ext/mysqli/tests/mysqli_debug_ini.phpt | 48 ++++ .../mysqli_debug_mysqlnd_control_string.phpt | 216 ++++++++++++++++++ .../tests/mysqli_debug_mysqlnd_only.phpt | 117 ++++++++++ ext/mysqli/tests/mysqli_fetch_field.phpt | 75 ++++++ .../tests/mysqli_fetch_field_flags.phpt | 172 ++++++++++++++ .../tests/mysqli_fetch_field_types.phpt | 119 ++++++++++ 16 files changed, 1459 insertions(+), 7 deletions(-) create mode 100644 ext/mysqli/tests/mysqli_change_user_get_lock.phpt create mode 100644 ext/mysqli/tests/mysqli_change_user_insert_id.phpt create mode 100644 ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt create mode 100644 ext/mysqli/tests/mysqli_change_user_prepared_statements.phpt create mode 100644 ext/mysqli/tests/mysqli_change_user_rollback.phpt create mode 100644 ext/mysqli/tests/mysqli_change_user_set_names.phpt create mode 100644 ext/mysqli/tests/mysqli_debug_append.phpt create mode 100644 ext/mysqli/tests/mysqli_debug_control_string.phpt create mode 100644 ext/mysqli/tests/mysqli_debug_ini.phpt create mode 100644 ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt create mode 100644 ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt create mode 100644 ext/mysqli/tests/mysqli_fetch_field_flags.phpt create mode 100644 ext/mysqli/tests/mysqli_fetch_field_types.phpt diff --git a/ext/mysqli/tests/mysqli_change_user_get_lock.phpt b/ext/mysqli/tests/mysqli_change_user_get_lock.phpt new file mode 100644 index 0000000000..437e39304f --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_get_lock.phpt @@ -0,0 +1,102 @@ +--TEST-- +mysqli_change_user() - GET_LOCK() +--SKIPIF-- + +--INI-- +max_execution_time=240 +--FILE-- + +--EXPECTF-- +Testing GET_LOCK()... +... lock 'phptest_%d' acquired by thread %d +... calling IS_USED_LOCK() on 'phptest_%d' using thread '%d' +... calling IS_FREE_LOCK() on 'phptest_%d' using thread '%d' +... calling IS_USED_LOCK() on 'phptest_%d' using new connection with thread '%d' +done! diff --git a/ext/mysqli/tests/mysqli_change_user_insert_id.phpt b/ext/mysqli/tests/mysqli_change_user_insert_id.phpt new file mode 100644 index 0000000000..243eab039f --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_insert_id.phpt @@ -0,0 +1,56 @@ +--TEST-- +mysqli_change_user() - LAST_INSERT_ID() +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt new file mode 100644 index 0000000000..43fa433d09 --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt @@ -0,0 +1,103 @@ +--TEST-- +mysqli_change_user() - table locks, GET_LOCK(), temporary tables +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_change_user_oo.phpt b/ext/mysqli/tests/mysqli_change_user_oo.phpt index 2bd73aca51..cb7bcf7e8f 100644 --- a/ext/mysqli/tests/mysqli_change_user_oo.phpt +++ b/ext/mysqli/tests/mysqli_change_user_oo.phpt @@ -8,7 +8,7 @@ require_once('skipifconnectfailure.inc'); require_once('table.inc'); if (!$IS_MYSQLND && (mysqli_get_server_version($link) < 50118 && mysqli_get_server_version($link) > 50100)) { - die("skip Your MySQL Server version has a known but that will cause a crash"); + die("skip Your MySQL Server version has a known bug that will cause a crash"); } ?> --FILE-- diff --git a/ext/mysqli/tests/mysqli_change_user_prepared_statements.phpt b/ext/mysqli/tests/mysqli_change_user_prepared_statements.phpt new file mode 100644 index 0000000000..ad3ed045cb --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_prepared_statements.phpt @@ -0,0 +1,33 @@ +--TEST-- +mysqli_change_user() - Prepared Statement +--SKIPIF-- + +--FILE-- +execute() && $stmt->bind_result($wrong) && $stmt->fetch()) { + printf("This is wrong, because after a mysqli_change_user() %s\n", $wrong); + } else { + if ($stmt->errno == 0) + printf("Error code 2013, 1243 or similar should have been set\n"); + } + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user_rollback.phpt b/ext/mysqli/tests/mysqli_change_user_rollback.phpt new file mode 100644 index 0000000000..ae1d91180e --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_rollback.phpt @@ -0,0 +1,70 @@ +--TEST-- +mysqli_change_user() - ROLLBACK +--SKIPIF-- + +--FILE-- + 0); + + if (!$res = mysqli_query($link, 'DELETE FROM test')) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS _num FROM test')) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if (0 != $row['_num']) + printf("[007] Rows should have been deleted in this transaction\n"); + + // DELETE should be rolled back + mysqli_change_user($link, $user, $passwd, $db); + + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS _num FROM test')) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['_num'] != $num) + printf("[010] Expecting %d rows in the table test, found %d rows\n", + $num, $row['_num']); + + mysqli_free_result($res); + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user_set_names.phpt b/ext/mysqli/tests/mysqli_change_user_set_names.phpt new file mode 100644 index 0000000000..1ac2d3d76b --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_set_names.phpt @@ -0,0 +1,165 @@ +--TEST-- +mysqli_change_user() - SET NAMES +--SKIPIF-- + +--FILE-- + $collation) { + + if (isset($not_changed['charset_client']) && + $charset != $not_changed['charset_client'] && + mysqli_query($link, sprintf('SET @@character_set_client = "%s"', $charset))) + unset($not_changed['charset_client']); + + if (isset($not_changed['charset_connection']) && + $charset != $not_changed['charset_connection'] && + mysqli_query($link, sprintf('SET @@character_connection = "%s"', $charset))) + unset($not_changed['charset_connection']); + + if (isset($not_changed['charset_results']) && + $charset != $not_changed['charset_results'] && + mysqli_query($link, sprintf('SET @@character_set_results = "%s"', $charset))) + unset($not_changed['charset_results']); + + if (isset($not_changed['collation_connection']) && + $collation != $not_changed['collation_connection'] && + mysqli_query($link, sprintf('SET @@collation_connection = "%s"', $collation))) + unset($not_changed['collation_connection']); + + if (isset($not_changed['collation_database']) && + $collation != $not_changed['collation_database'] && + mysqli_query($link, sprintf('SET @@collation_database = "%s"', $collation))) + unset($not_changed['collation_database']); + + if (isset($not_changed['collation_server']) && + $collation != $not_changed['collation_server'] && + mysqli_query($link, sprintf('SET @@collation_server = "%s"', $collation))) + unset($not_changed['collation_server']); + + if (empty($not_changed)) + break; + } + + if (!$res = mysqli_query($link, 'SELECT + @@character_set_client AS charset_client, + @@character_set_connection AS charset_connection, + @@character_set_results AS charset_results, + @@collation_connection AS collation_connection, + @@collation_database AS collation_database, + @@collation_server AS collation_server')) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$modified = mysqli_fetch_assoc($res)) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if ($modified == $defaults) + printf("[008] Not all settings have been changed\n"); + + // LAST_INSERT_ID should be reset + mysqli_change_user($link, $user, $passwd, $db); + + if (!$res = mysqli_query($link, 'SELECT + @@character_set_client AS charset_client, + @@character_set_connection AS charset_connection, + @@character_set_results AS charset_results, + @@collation_connection AS collation_connection, + @@collation_database AS collation_database, + @@collation_server AS collation_server')) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$new = mysqli_fetch_assoc($res)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if ($new == $modified) { + printf("[011] Charsets/collations have not been reset.\n"); + printf("Got:\n"); + var_dump($new); + printf("Expected:\n"); + var_dump($defaults); + } + + if (ini_get('unicode.semantics')) { + // charsets cannot take any other value but utf8 in unicode mode + $defaults['charset_client'] = 'utf8'; + $defaults['charset_connection'] = 'utf8'; + $defaults['charset_results'] = 'utf8'; + $defaults['collation_connection'] = 'utf8_general_ci'; + } + + if ($new != $defaults) { + printf("[012] Charsets/collations have not been reset to their defaults.\n"); + printf("Got:\n"); + var_dump($new); + printf("Expected:\n"); + var_dump($defaults); + } + + if (!is_object($charset = mysqli_get_charset($link))) + printf("[013] Expecting object/std_class, got %s/%s\n", gettype($charset), $charset); + + if ($charset->charset != $defaults['charset_connection']) + printf("[014] Expecting connection charset to be %s got %s\n", + $defaults['charset_connection'], + $charset->charset); + + if ($charset->collation != $defaults['collation_connection']) + printf("[015] Expecting collation to be %s got %s\n", + $defaults['collation_connection'], + $charset->collation); + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_debug.phpt b/ext/mysqli/tests/mysqli_debug.phpt index 88f7b9d970..6db6a45e44 100644 --- a/ext/mysqli/tests/mysqli_debug.phpt +++ b/ext/mysqli/tests/mysqli_debug.phpt @@ -10,19 +10,49 @@ if (!function_exists('mysqli_debug')) ?> --FILE-- --EXPECTF-- -done! \ No newline at end of file +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-- + +--FILE-- + +--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-- + +--FILE-- + +--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-- + +--INI-- +mysqlnd.debug="t:O,/tmp/mysqli_debug_phpt.trace" +--FILE-- + +--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-- + +--FILE-- +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-- + +--FILE-- + $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_fetch_field.phpt b/ext/mysqli/tests/mysqli_fetch_field.phpt index 03c709396b..9491191320 100644 --- a/ext/mysqli/tests/mysqli_fetch_field.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field.phpt @@ -21,6 +21,7 @@ require_once('skipifconnectfailure.inc'); 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)); } @@ -31,10 +32,28 @@ require_once('skipifconnectfailure.inc'); 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-- @@ -89,6 +108,34 @@ object(stdClass)#%d (11) { 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) { @@ -142,4 +189,32 @@ object(stdClass)#%d (11) { 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_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-- + +--FILE-- + '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_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-- + +--FILE-- +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 -- 2.40.0