Bug #121378 CASE WHEN TRUE changes the result of an identical WHERE predicate after SET NAMES binary
Submitted: 28 Sep 7:54 Modified: 1 Oct 5:02
Reporter: jinxin gui Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S2 (Serious)
Version:8.0.46, 8.4.11, 9.7.2, 26.07 OS:Linux
Assigned to: CPU Architecture:Any
Tags: BINARY, SET NAMES

[28 Sep 7:54] jinxin gui
Description:
With a `utf8mb4` table containing `London` and `Paris`, run `SET NAMES binary` and compare `WHERE city = 'London' AND city = 'london'` with `WHERE CASE WHEN xxx THEN city = 'London' AND city = 'london' ELSE city = 'London' AND city = 'london' END`. The first query returns 0 rows, but the second returns `London`. Both `CASE` branches contain the same predicate, so both queries should return 0 rows.

How to repeat:
Run the following statements in the same MySQL connection:

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (city CHAR(30)) CHARACTER SET=utf8mb4;
INSERT INTO t1 VALUES ('London'), ('Paris');
SET NAMES binary;

-- Actual: 0 rows.
SELECT DISTINCT *
FROM t1
WHERE city = 'London' AND city = 'london';

-- Actual: 1 row.
SELECT DISTINCT *
FROM t1
WHERE CASE
  WHEN (SELECT count(@@collation_connection)) THEN city = 'London' AND city = 'london'
  ELSE city = 'London' AND city = 'london'
END;

Expected result
Both queries should return 0 rows. The CASE expression uses the same predicate in both branches, so it should not change which rows satisfy WHERE. MySQL documents CASE WHEN as returning the selected branch’s result.

Actual result
The first query returns 0 rows; the second returns 1 row containing London. In the supplied mysql client output, that value appears as 0x4C6F6E646F6E. The mismatch reproduces only when SET NAMES binary is included;
[1 Oct 5:02] Chaithra Marsur Gopala Reddy
Hi jinxin gui,

Thank you for the test case. Verified as described.