summaryrefslogtreecommitdiff
path: root/ext/mysqlnd
diff options
context:
space:
mode:
authorKeyur Govande <keyur@php.net>2015-01-06 06:33:38 +0000
committerKeyur Govande <keyur@php.net>2015-01-26 21:20:29 +0000
commitb34f8ef599ffd6111db68930cf015ce18d501f07 (patch)
tree0743ab1e8ce5c9f6bf1641a2399417c699b659bb /ext/mysqlnd
parent49cc1d4e84d65ea7dd728467f30f341c170a2524 (diff)
downloadphp-git-b34f8ef599ffd6111db68930cf015ce18d501f07.tar.gz
Fix for bugs #68114 (Build fails on OS X due to undefined symbols)
and #68657 (Reading 4 byte floats with Mysqli and libmysqlclient has rounding errors). The patch removes support for Decimal floating point numbers and now defaults to using similar logic as what libmysqlclient does: convert a 4 byte floating point number into a string, and then the string into a double. The quirks of MySQL are maintained as seen in Field_Float::val_str()
Diffstat (limited to 'ext/mysqlnd')
-rw-r--r--ext/mysqlnd/config9.m431
-rw-r--r--ext/mysqlnd/mysqlnd_ps_codec.c53
2 files changed, 5 insertions, 79 deletions
diff --git a/ext/mysqlnd/config9.m4 b/ext/mysqlnd/config9.m4
index 8f749cf273..0e08b977af 100644
--- a/ext/mysqlnd/config9.m4
+++ b/ext/mysqlnd/config9.m4
@@ -49,34 +49,3 @@ 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>
-#include <string.h>
-
-int main(int argc, char **argv) {
- typedef float dec32 __attribute__((mode(SD)));
- dec32 k = 99.49f;
- double d2 = (double)k;
- const char *check_str = "99.49";
- char print_str[32];
-
- snprintf(print_str, 32, "%f", d2);
- return memcmp(print_str, check_str, 5);
-}
-],[
- 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
diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c
index b2dd22ba8a..d2e5763210 100644
--- a/ext/mysqlnd/mysqlnd_ps_codec.c
+++ b/ext/mysqlnd/mysqlnd_ps_codec.c
@@ -24,6 +24,7 @@
#include "mysqlnd_wireprotocol.h"
#include "mysqlnd_priv.h"
#include "mysqlnd_debug.h"
+#include "ext/standard/float_to_double.h"
#define MYSQLND_SILENT
@@ -181,56 +182,12 @@ ps_fetch_float(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_l
(*row)+= 4;
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)));
- /* volatile so the compiler will not optimize away the conversion */
- volatile dec32 d32val = fval;
-
- /* The following cast is guaranteed to do the right thing */
- dval = (double) d32val;
- }
-#elif defined(PHP_WIN32)
- {
- /* float datatype on Winows is already 4 byte but has a precision of 7 digits */
- char num_buf[2048];
- (void)_gcvt_s(num_buf, 2048, fval, field->decimals >= 31 ? 7 : field->decimals);
- dval = zend_strtod(num_buf, NULL);
- }
-#else
- {
- char num_buf[2048]; /* Over allocated */
- char *s;
-
-#ifndef FLT_DIG
-# define FLT_DIG 6
-#endif
- /* 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 ? FLT_DIG : field->decimals,
- '.',
- 'e',
- num_buf);
-
- /* And now convert back to double */
- dval = zend_strtod(s, NULL);
- }
+#ifndef NOT_FIXED_DEC
+# define NOT_FIXED_DEC 31
#endif
+ dval = float_to_double(fval, (field->decimals >= NOT_FIXED_DEC) ? -1 : field->decimals);
+
ZVAL_DOUBLE(zv, dval);
DBG_VOID_RETURN;
}