From: Keyur Govande Date: Fri, 15 Aug 2014 23:13:36 +0000 (+0000) Subject: Merge branch 'PHP-5.4' into PHP-5.5 X-Git-Tag: php-5.5.17RC1~37 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7c4b5d91874ea0a69f5b65c05494056aaae81e71;p=php Merge branch 'PHP-5.4' into PHP-5.5 * PHP-5.4: Add NEWS Fix failing tests Patch for bug #67839 (mysqli does not handle 4-byte floats correctly) Conflicts: ext/mysqli/tests/table.inc --- 7c4b5d91874ea0a69f5b65c05494056aaae81e71 diff --cc ext/mysqli/tests/table.inc index cb089bb950,ec360c8f2c..e0d7a06c57 --- a/ext/mysqli/tests/table.inc +++ b/ext/mysqli/tests/table.inc @@@ -12,7 -12,12 +12,12 @@@ if (!mysqli_query($link, 'DROP TABLE I 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, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . $engine)) { +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); } diff --cc ext/mysqlnd/mysqlnd_ps_codec.c index d0e44fa275,3f7d31002f..fa4ed9da6f --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@@ -171,15 -190,58 +171,56 @@@ ps_fetch_int64(zval * zv, const MYSQLND /* {{{ ps_fetch_float */ -static -void ps_fetch_float(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +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; } /* }}} */