Skip to content

Prefix Index Scan Returns Wrong Results for Unicode String Range Comparison #295

Description

@ZyanNo1

1. Minimal reproduce step

DROP DATABASE IF EXISTS bug_repro;
CREATE DATABASE bug_repro;
USE bug_repro;
CREATE TABLE t (c2 VARCHAR(32) CHARACTER SET utf8mb4) ENGINE=InnoDB;
INSERT INTO t VALUES ('#а|'), ('ׄׄ׉');
CREATE INDEX pfx ON t (c2(1));
ANALYZE TABLE t;

-- [CORRECT] Full table scan (IGNORE INDEX)
SELECT '[CORRECT] IGNORE INDEX' AS plan, COUNT(*) FROM t IGNORE INDEX(pfx)
 WHERE c2 > '#а|';

-- [BUG] Prefix index scan (FORCE INDEX)
SELECT '[BUG]    FORCE INDEX' AS plan, COUNT(*) FROM t FORCE INDEX(pfx)
 WHERE c2 > '#а|';

2. What did you expect to see?

Both queries should return 1. The value 'ׄׄ׉' (starts with Hebrew character U+05C4, UTF-8: 0xD7 0x93) compares greater than '#а|' (starts with ASCII '#', UTF-8: 0x23) in both byte order and Unicode code point order. The prefix index on c2(1) stores the first character which is sufficient to determine 'ׄ' > '#':

plan                    COUNT(*)
[CORRECT] IGNORE INDEX  1
[BUG]    FORCE INDEX    1

3. What did you see instead

The FORCE INDEX query returns 0 — the prefix index scan incorrectly excludes the Hebrew row 'ׄׄ׉':

plan                    COUNT(*)
[CORRECT] IGNORE INDEX  1
[BUG]    FORCE INDEX    0

Root cause: When evaluating the range condition c2 > '#а|' via a prefix index on c2(1), the index scan path incorrectly determines that the Hebrew character 'ׄ' (U+05C4) does NOT compare greater than '#' (U+0023), even though it does. The prefix index should be able to use just the first character for this comparison, but the comparison logic for multi-byte UTF-8 characters in the prefix index scan path is flawed.

4. What is your PolarDB-X version?

VERSION(): 5.6.29-PXC-5.4.19-20250825

Docker image: polardbx/polardb-x:v2.4.2_5.4.19

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions