[wp-trac] [WordPress Trac] #36696: WP_Meta_Query can give wrong results when comparing large numbers
WordPress Trac
noreply at wordpress.org
Thu Apr 28 02:23:44 UTC 2016
#36696: WP_Meta_Query can give wrong results when comparing large numbers
--------------------------+-----------------------------
Reporter: gitlost | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Query | Version: 3.8.1
Severity: normal | Keywords:
Focuses: |
--------------------------+-----------------------------
This is a follow on from #27272.
Using quoted numbers can trigger MySQL to do floating-point type
conversion (last two points in the first bullet list in
http://dev.mysql.com/doc/refman/5.7/en/type-conversion.html):
> * If one of the arguments is a decimal value, comparison depends on the
other argument. The arguments are compared as decimal values if the other
argument is a decimal or integer value, or as floating-point values if the
other argument is a floating-point value.
> * In all other cases, the arguments are compared as floating-point
(real) numbers.
Currently number literals are quoted in `WP_Meta_Query`, whereas the
LONGTEXT `meta_value` column is cast to the passed-in meta `type`. Thus
when a number literal (quoted string) is compared to the `meta_value`
column (cast to SIGNED/UNSIGNED meta `type`), floating-point type
conversion is evoked. If the numbers involved are larger than the
floating-point precision (53 bits), then incorrect comparisons can occur.
You can see this happening in the `mysql` client by using the 54 bit
numbers 9007199254740992 (`0x20 0000 0000 0000`) and 9007199254740993
(`0x20 0000 0000 0001`):
{{{
select '9007199254740992'+0.0, '9007199254740993'+0.0,
'9007199254740992'+0.0 < '9007199254740993'+0.0;
}}}
which will return:
{{{
+------------------------+------------------------+-------------------------------------------------+
| '9007199254740992'+0.0 | '9007199254740993'+0.0 | '9007199254740992'+0.0
< '9007199254740993'+0.0 |
+------------------------+------------------------+-------------------------------------------------+
| 9.007199254740992e15 | 9.007199254740992e15 |
0 |
+------------------------+------------------------+-------------------------------------------------+
}}}
(Note the results are system dependent.)
A way around this is to not quote number literals, as in the proposed
patch, based on @wonderboymusic's
[https://core.trac.wordpress.org/ticket/27272#comment:5 "27272.2.diff"].
It's been switched (ahem) to an if-elseif-else statement to easily allow
cases like `DECIMAL(10,2)` etc to be added. (Note the patch attached here
also fixes a regression I introduced in previous proposed patches on the
#27272 ticket re casting on `LIKE`/`NOT LIKE`.)
This issue relates to #36652 (using the PHP type of the meta `value` to
determine cast), and the proposed patch should facilitate it.
This issue also relates to #36625 (don't bother `CHAR` casting
`meta_value` column), and the proposed patch shouldn't impact on a fix for
that.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/36696>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list