Details
-
Bug
-
Status: Confirmed (View Workflow)
-
Major
-
Resolution: Unresolved
-
11.4, 11.8, 12.3, 11.8.5
-
Ubuntu
Description
When a table has a VARCHAR column defined as PRIMARY KEY and a prefix
index on that same column with a short prefix length (e.g., 1
character), an equality lookup on the column may return 0 rows
instead of the correct 1 row. The bug is deterministic and reproduces
every time.
The key condition is that the optimizer chooses to use the prefix
index for the lookup, producing an EXPLAIN plan with type=const and
key=prefix_c0_117. Despite the EXPLAIN showing rows=2 with
Extra=Using where (indicating 2 candidate rows from the index that
need filtering), the WHERE filter incorrectly eliminates all rows and
returns an empty result set.
The same query using the PRIMARY KEY index (via IGNORE INDEX or
natural optimizer choice) correctly returns 1 row.
How to repeat
Run the following minimal SQL script:
DROP DATABASE IF EXISTS test_db5_minimal;
CREATE DATABASE test_db5_minimal;
USE test_db5_minimal;
CREATE TABLE t1(c0 VARCHAR(100), PRIMARY KEY(c0));
INSERT INTO t1 VALUES ('');
INSERT INTO t1 VALUES ('-1221357719');
INSERT INTO t1 VALUES ('o}_42''qT');
INSERT INTO t1 VALUES ('-1632889459');
INSERT INTO t1 VALUES ('JON');
– Create prefix index with length 1 on c0
CREATE INDEX prefix_c0_117 ON t1 (c0(1));
– BUG: This returns 0 rows (WRONG)
SELECT '=== FORCE INDEX (returns 0 rows - BUG) ===' AS test;
SELECT c0 FROM t1 FORCE INDEX(prefix_c0_117) WHERE c0 = '-1632889459' ORDER BY c0 LIMIT 100;
– Correct: This returns 1 row (CORRECT)
SELECT '=== IGNORE INDEX (returns 1 row - CORRECT) ===' AS test;
SELECT c0 FROM t1 IGNORE INDEX(prefix_c0_117) WHERE c0 = '-1632889459' ORDER BY c0 LIMIT 100;
– EXPLAIN plans for reference:
– FORCE INDEX: type=const, key=prefix_c0_117, key_len=6, rows=2, Extra=Using where
– IGNORE INDEX: type=const, key=PRIMARY, key_len=402, rows=1
Expected result: Both queries return 1 row with c0='-1632889459'.
Actual result: The FORCE INDEX query returns 0 rows.