Details
-
Bug
-
Status: Confirmed (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 12.3.2
Description
Summary
Wrong result: LOCATE/INSTR return 0 for strings that compare equal under utf8mb4_*_ci (e.g. ắ vs a)
Description
Under utf8mb4_unicode_ci (and similar), 'ắ' = 'a' is true, but:
LOCATE('ắ', 'a') -- 0 (wrong; expect 1) |
LOCATE('a', 'ắ') -- 0 (wrong; expect 1) |
INSTR('a', 'ắ') -- 0 (wrong; expect 1) |
INSTR('ắ', 'a') -- 0 (wrong; expect 1) |
LOCATE('ắ', 'aa') -- 0 (wrong; expect 1) |
MySQL 9.7.1 returns 1 for these LOCATE/INSTR shapes under utf8mb4_unicode_ci.
This is not the same early-return as FIND_IN_SET's buffer->length() < find->length() gate (LOCATE('ắ','aa') still fails though the haystack is longer in bytes). Item_func_locate::val_int() uses cmp_collation.collation->instr(...), which appears not to treat these as matches.
How to repeat
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; |
|
|
SELECT 'ắ' = 'a' AS eq; -- 1 |
SELECT LOCATE('ắ', 'a') AS l1; -- Actual: 0; Expected: 1 |
SELECT LOCATE('a', 'ắ') AS l2; -- Actual: 0; Expected: 1 |
SELECT INSTR('a', 'ắ') AS i1; -- Actual: 0; Expected: 1 |
SELECT INSTR('ắ', 'a') AS i2; -- Actual: 0; Expected: 1 |
SELECT LOCATE('ắ', 'aa') AS l3; -- Actual: 0; Expected: 1 |
|
|
-- Control: FIND_IN_SET when list is long enough in bytes still finds a match
|
SELECT FIND_IN_SET('ắ', 'a,b') AS fis; -- 1 |
Observed on: 12.3.2-MariaDB
Oracle: MySQL 9.7.1 → all LOCATE/INSTR above return 1.
Actual result
All listed LOCATE/INSTR calls return 0.
Expected result
Return 1 (match at first character), consistent with = under the same collation.
Attachments
Issue Links
- relates to
-
MDEV-40865 FIND_IN_SET returns 0 when needle is longer in bytes than haystack token but equal under collation
-
- Confirmed
-