mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-5.6'
* PHP-5.6: Update NEWS Fix another failing test Add NEWS Fix failing tests Patch for bug #67839 (mysqli does not handle 4-byte floats correctly)
This commit is contained in:
commit
603e3ddfc0
11 changed files with 187 additions and 20 deletions
|
@ -62,18 +62,18 @@ mysqli_close($link);
|
|||
--EXPECT--
|
||||
array(7) {
|
||||
[0]=>
|
||||
float(3.14159274101)
|
||||
float(3.141593)
|
||||
[1]=>
|
||||
float(-9.99999997475E-7)
|
||||
float(-1.0E-6)
|
||||
[2]=>
|
||||
float(0)
|
||||
[3]=>
|
||||
float(999999995904)
|
||||
float(1.0E+12)
|
||||
[4]=>
|
||||
float(0.564642488956)
|
||||
float(0.5646425)
|
||||
[5]=>
|
||||
float(1)
|
||||
[6]=>
|
||||
float(8.88888914608E+14)
|
||||
float(8.888889E+14)
|
||||
}
|
||||
done!
|
||||
done!
|
||||
|
|
|
@ -67,7 +67,7 @@ array(8) {
|
|||
[3]=>
|
||||
int(4999999)
|
||||
[4]=>
|
||||
float(2345.60009766)
|
||||
float(2345.6)
|
||||
[5]=>
|
||||
float(5678.89563)
|
||||
[6]=>
|
||||
|
@ -75,4 +75,4 @@ array(8) {
|
|||
[7]=>
|
||||
%unicode|string%(11) "mysql rulez"
|
||||
}
|
||||
done!
|
||||
done!
|
||||
|
|
|
@ -66,7 +66,7 @@ array(8) {
|
|||
[3]=>
|
||||
int(54)
|
||||
[4]=>
|
||||
float(2.59999990463)
|
||||
float(2.6)
|
||||
[5]=>
|
||||
float(58.89)
|
||||
[6]=>
|
||||
|
@ -74,4 +74,4 @@ array(8) {
|
|||
[7]=>
|
||||
%unicode|string%(3) "6.7"
|
||||
}
|
||||
done!
|
||||
done!
|
||||
|
|
58
ext/mysqli/tests/bug67839.phpt
Normal file
58
ext/mysqli/tests/bug67839.phpt
Normal file
|
@ -0,0 +1,58 @@
|
|||
--TEST--
|
||||
mysqli_float_handling - ensure 4 byte float is handled correctly
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifemb.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require('connect.inc');
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
|
||||
printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) {
|
||||
printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
die();
|
||||
}
|
||||
|
||||
if (!mysqli_query($link, "CREATE TABLE test(id INT PRIMARY KEY, fp4 FLOAT, fp8 DOUBLE) ENGINE = InnoDB")) {
|
||||
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
die();
|
||||
}
|
||||
|
||||
// Insert via string to make sure the real floating number gets to the DB
|
||||
if (!mysqli_query($link, "INSERT INTO test(id, fp4, fp8) VALUES (1, 9.9999, 9.9999)")) {
|
||||
printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
die();
|
||||
}
|
||||
|
||||
if (!($stmt = mysqli_prepare($link, "SELECT id, fp4, fp8 FROM test"))) {
|
||||
printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
die();
|
||||
}
|
||||
|
||||
if (!mysqli_stmt_execute($stmt)) {
|
||||
printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
if (!($result = mysqli_stmt_get_result($stmt))) {
|
||||
printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
die();
|
||||
}
|
||||
|
||||
$data = mysqli_fetch_assoc($result);
|
||||
print $data['id'] . ": " . $data['fp4'] . ": " . $data['fp8'] . "\n";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once("clean_table.inc");
|
||||
?>
|
||||
--EXPECTF--
|
||||
1: 9.9999: 9.9999
|
|
@ -42,10 +42,34 @@ require_once('skipifconnectfailure.inc');
|
|||
if (false !== ($tmp = @mysqli_change_user($link, $user, $passwd . '_unknown_really', $db)))
|
||||
printf("[009] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
// Reconnect because after 3 failed change_user attempts, the server blocks you off.
|
||||
if (!$link = my_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",
|
||||
printf("[009a] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
|
||||
if (!mysqli_query($link, 'SET @mysqli_change_user_test_var=1'))
|
||||
printf("[010] Failed to set test variable: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!$res = mysqli_query($link, 'SELECT @mysqli_change_user_test_var AS test_var'))
|
||||
printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
$tmp = mysqli_fetch_assoc($res);
|
||||
mysqli_free_result($res);
|
||||
if (1 != $tmp['test_var'])
|
||||
printf("[012] Cannot set test variable\n");
|
||||
|
||||
if (true !== ($tmp = mysqli_change_user($link, $user, $passwd, $db)))
|
||||
printf("[013] Expecting true, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!$res = mysqli_query($link, 'SELECT database() AS dbname, user() AS user'))
|
||||
printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
$tmp = mysqli_fetch_assoc($res);
|
||||
mysqli_free_result($res);
|
||||
|
||||
if (substr($tmp['user'], 0, strlen($user)) !== $user)
|
||||
printf("[015] Expecting user %s, got user() %s\n", $user, $tmp['user']);
|
||||
if ($tmp['dbname'] != $db)
|
||||
printf("[016] Expecting database %s, got database() %s\n", $db, $tmp['dbname']);
|
||||
|
||||
if (false !== ($tmp = @mysqli_change_user($link, $user, $passwd, $db . '_unknown_really')))
|
||||
printf("[011] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
|
@ -121,4 +145,4 @@ require_once('skipifconnectfailure.inc');
|
|||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
done!
|
||||
done!
|
||||
|
|
|
@ -48,6 +48,14 @@ if (mysqli_get_server_version($link) >= 50600)
|
|||
if (false !== ($tmp = mysqli_change_user($link, $user, $passwd, $db . '_unknown_really')))
|
||||
printf("[009] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
// Reconnect because Percona and MariaDB block any commands after 3 failed
|
||||
// change_user commands
|
||||
mysqli_close($link);
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
|
||||
printf("[020] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
}
|
||||
if (!mysqli_query($link, 'SET @mysqli_change_user_test_var=1'))
|
||||
printf("[010] Failed to set test variable: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
|
@ -116,4 +124,4 @@ if (mysqli_get_server_version($link) >= 50600)
|
|||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
done!
|
||||
done!
|
||||
|
|
|
@ -46,6 +46,11 @@ if (mysqli_get_server_version($link) >= 50600)
|
|||
if (false !== ($tmp = $mysqli->change_user($user, $passwd, $db . '_unknown_really')))
|
||||
printf("[008] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
// Reconnect because after 3 failed change_user attempts, the server blocks you off.
|
||||
if (!$mysqli = new my_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 (!$mysqli->query('SET @mysqli_change_user_test_var=1'))
|
||||
printf("[009] Failed to set test variable: [%d] %s\n", $mysqli->errno, $mysqli->error);
|
||||
|
||||
|
@ -84,4 +89,4 @@ if (mysqli_get_server_version($link) >= 50600)
|
|||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
done!
|
||||
done!
|
||||
|
|
|
@ -36,7 +36,7 @@ $port, $socket, mysqli_connect_errno(), mysqli_connect_error());
|
|||
mysqli_error($link));
|
||||
}
|
||||
|
||||
if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY
|
||||
if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(3), PRIMARY
|
||||
KEY(id)) ENGINE=' . $engine . " DEFAULT CHARSET=gbk")) {
|
||||
printf("Failed to create test table: [%d] %s\n", mysqli_errno($link),
|
||||
mysqli_error($link));
|
||||
|
|
|
@ -12,6 +12,11 @@ if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (!mysqli_query($link, 'SET SESSION sql_mode=\'\'')) {
|
||||
printf("Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!mysqli_query($link, 'CREATE TABLE test(id INT DEFAULT 0, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . $engine)) {
|
||||
printf("Failed to create test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
exit(1);
|
||||
|
@ -20,4 +25,4 @@ if (!mysqli_query($link, 'CREATE TABLE test(id INT DEFAULT 0, label CHAR(1), PRI
|
|||
if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f')")) {
|
||||
printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
}
|
||||
?>
|
||||
?>
|
||||
|
|
|
@ -49,3 +49,29 @@ fi
|
|||
if test "$PHP_MYSQLND" != "no" || test "$PHP_MYSQLND_ENABLED" = "yes" || test "$PHP_MYSQLI" != "no"; then
|
||||
PHP_ADD_BUILD_DIR([ext/mysqlnd], 1)
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Check if the compiler supports Decimal32/64/128 types from the IEEE-754 2008 version
|
||||
dnl References: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1657.pdf
|
||||
dnl http://speleotrove.com/decimal/
|
||||
dnl
|
||||
AC_CACHE_CHECK([whether whether compiler supports Decimal32/64/128 types], ac_cv_decimal_fp_supported,[
|
||||
AC_TRY_RUN( [
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
typedef float dec32 __attribute__((mode(SD)));
|
||||
dec32 k = 99.49f;
|
||||
double d2 = (double)k;
|
||||
return 0;
|
||||
}
|
||||
],[
|
||||
ac_cv_decimal_fp_supported=yes
|
||||
],[
|
||||
ac_cv_decimal_fp_supported=no
|
||||
],[
|
||||
ac_cv_decimal_fp_supported=no
|
||||
])])
|
||||
if test "$ac_cv_decimal_fp_supported" = "yes"; then
|
||||
AC_DEFINE(HAVE_DECIMAL_FP_SUPPORT, 1, [Define if the compiler supports Decimal32/64/128 types.])
|
||||
fi
|
||||
|
|
|
@ -174,12 +174,53 @@ ps_fetch_int64(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_l
|
|||
static void
|
||||
ps_fetch_float(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
|
||||
{
|
||||
float value;
|
||||
float fval;
|
||||
double dval;
|
||||
DBG_ENTER("ps_fetch_float");
|
||||
float4get(value, *row);
|
||||
ZVAL_DOUBLE(zv, value);
|
||||
float4get(fval, *row);
|
||||
(*row)+= 4;
|
||||
DBG_INF_FMT("value=%f", value);
|
||||
DBG_INF_FMT("value=%f", fval);
|
||||
|
||||
/*
|
||||
* The following is needed to correctly support 4-byte floats.
|
||||
* Otherwise, a value of 9.99 in a FLOAT column comes out of mysqli
|
||||
* as 9.9998998641968.
|
||||
*
|
||||
* For GCC, we use the built-in decimal support to "up-convert" a
|
||||
* 4-byte float to a 8-byte double.
|
||||
* When that is not available, we fall back to converting the float
|
||||
* to a string and then converting the string to a double. This mimics
|
||||
* what MySQL does.
|
||||
*/
|
||||
#ifdef HAVE_DECIMAL_FP_SUPPORT
|
||||
{
|
||||
typedef float dec32 __attribute__((mode(SD)));
|
||||
dec32 d32val = fval;
|
||||
|
||||
/* The following cast is guaranteed to do the right thing */
|
||||
dval = (double) d32val;
|
||||
}
|
||||
#else
|
||||
{
|
||||
char num_buf[2048]; /* Over allocated */
|
||||
char *s;
|
||||
|
||||
/* Convert to string. Ignoring localization, etc.
|
||||
* Following MySQL's rules. If precision is undefined (NOT_FIXED_DEC i.e. 31)
|
||||
* or larger than 31, the value is limited to 6 (FLT_DIG).
|
||||
*/
|
||||
s = php_gcvt(fval,
|
||||
field->decimals >= 31 ? 6 : field->decimals,
|
||||
'.',
|
||||
'e',
|
||||
num_buf);
|
||||
|
||||
/* And now convert back to double */
|
||||
dval = zend_strtod(s, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
ZVAL_DOUBLE(zv, dval);
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
/* }}} */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue