Bug #120090 Incorrect result with OUTER JOIN and CASE expression with string literal in join condition
Submitted: 18 Mar 4:40 Modified: 18 Mar 8:13
Reporter: Weipeng Wang Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S3 (Non-critical)
Version: OS:Linux
Assigned to: CPU Architecture:x86

[18 Mar 4:40] Weipeng Wang
Description:
A query involving an OUTER JOIN may produce incorrect results when the join condition uses an expression of the form `= CASE ...` with a string constant, and the joined column has a KEY constraint.

When the query is partitioned using complementary predicates (`IS NULL` and `IS NOT NULL`) and combined with `UNION ALL`, the result differs from the original query.

In particular, rows containing larger floating-point values (beyond the effective precision range) do not appear in the partitioned query result, while they are present in the original query

How to repeat:
CREATE TABLE t0(c0 FLOAT);
CREATE TABLE t1(c0 FLOAT KEY);
 
INSERT INTO t0 VALUES (0), (0.148433678), (527808465);
INSERT INTO t1 VALUES (0), (0.148433678), (527808465);

(SELECT ta0.c0 AS ref0, ta1.c0 AS ref1 FROM t1 AS ta1 LEFT JOIN t0 AS ta0 ON ta1.c0 = (CASE WHEN 0 THEN 'x' ELSE ta0.c0 END) WHERE ta0.c0 IS NULL)
UNION ALL
(SELECT ta0.c0, ta1.c0 FROM t1 AS ta1 LEFT JOIN t0 AS ta0 ON ta1.c0 = (CASE WHEN 0 THEN 'x' ELSE ta0.c0 END) WHERE ta0.c0 IS NOT NULL);
/* returns 1 row: (0, 0) */

SELECT ta0.c0 AS ref0, ta1.c0 AS ref1 FROM t1 AS ta1 LEFT JOIN t0 AS ta0 ON ta1.c0 = (CASE WHEN 0 THEN 'x' ELSE ta0.c0 END);
/* returns 3 rows: (0, 0) (0.148434, 0.148434) (527808000, 527808000) */
[18 Mar 8:13] Roy Lyseng
Thank you for the bug report.
However, this is not a bug.
FLOAT operations are imprecise and cannot always be trusted in equality comparisons.