Details
-
Bug
-
Status: Confirmed (View Workflow)
-
Major
-
Resolution: Unresolved
-
12.3, 11.8.8
-
Ubuntu24.04
Description
Description
When a TEXT-family column has a prefix index of length 1 and the query has a range predicate whose lower bound is a string literal that, when interpreted as a number, overflows DOUBLE (e.g. '-1e500'), the optimizer collapses the predicate to Impossible WHERE noticed after reading const tables during range-analysis on the prefix index. The query then returns 0 rows, even though string-comparison shows that 12 rows actually satisfy the predicate.
The WHERE clause is a string range: {{c0 >= '-1e500' AND c0 <= '᪾JwQ ['}}. With:
- IGNORE INDEX(prefix_idx) (full table scan): 12 rows ← correct
- ground truth via {{SUM(CASE WHEN c0 >= '-1e500' AND c0 <= '᪾JwQ [' THEN 1 ELSE 0 END)}}: 12 ← correct
- prefix(1) index (default plan): 0 rows ← BUG, EXPLAIN says "Impossible WHERE"
- prefix(2) index: 12 rows ← correct
- prefix(3) index: 12 rows ← correct
The bug is only triggered by the combination of:
- prefix index length = 1, AND
- the WHERE lower bound is a numeric-overflow string literal ('-1e500').
Either remove condition 1 (use full or longer-prefix index) or remove condition 2 (use a non-overflow numeric literal) and the bug disappears.
How to repeat
DROP DATABASE IF EXISTS bug_prefix_overflow; |
CREATE DATABASE bug_prefix_overflow; |
USE bug_prefix_overflow; |
|
|
CREATE TABLE t0(c0 MEDIUMTEXT); |
|
|
INSERT INTO t0(c0) VALUES ('0.5'),('123'),('abc'),('-2117222092'),('hello'),('Cv'); |
INSERT INTO t0(c0) VALUES ('*#'),('!b'),('0I'),('1*tE'),('4Ti}k'),('5(2*07'); |
INSERT INTO t0(c0) VALUES ('wp'),('x&'),('jx+'); |
|
|
CREATE INDEX prefix_idx ON t0(c0(1)); |
ANALYZE TABLE t0; |
|
|
-- Ground truth (string compare, no index): 12
|
SELECT SUM(CASE WHEN c0 >= '-1e500' AND c0 <= '᪾JwQ [' THEN 1 ELSE 0 END) AS truth FROM t0; |
|
|
-- BUG: returns 0
|
SELECT COUNT(*) FROM t0 WHERE c0 >= '-1e500' AND c0 <= '᪾JwQ ['; |
|
|
-- Correct: returns 12
|
SELECT COUNT(*) FROM t0 IGNORE INDEX(prefix_idx) WHERE c0 >= '-1e500' AND c0 <= '᪾JwQ ['; |
|
|
-- Diagnostic: prefix(2) is fine, prefix(3) is fine — only prefix(1) breaks.
|
DROP INDEX prefix_idx ON t0; |
CREATE INDEX prefix_idx2 ON t0(c0(2)); |
ANALYZE TABLE t0; |
SELECT COUNT(*) FROM t0 FORCE INDEX(prefix_idx2) WHERE c0 >= '-1e500' AND c0 <= '᪾JwQ ['; |
-- 12, correct |
Expected result
The default plan should also return 12. The optimizer must not infer "Impossible WHERE" from a prefix-index analysis when the predicate is a string range and the bound, while overflowing as a number, is a perfectly valid string boundary.
Actual result on 11.8.8-MariaDB
SHOW CREATE TABLE t0:
|
CREATE TABLE `t0` (
|
`c0` mediumtext DEFAULT NULL,
|
KEY `prefix_idx` (`c0`(1))
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
|
|
|
ground truth (CASE WHEN) : 12
|
default plan (uses prefix(1)) : 0 <-- WRONG
|
EXPLAIN default : Impossible WHERE noticed after reading const tables
|
IGNORE INDEX(prefix_idx) : 12
|
EXPLAIN IGNORE INDEX : type=ALL, rows=15
|
prefix_idx2 (length 2) FORCE : 12 <-- correct
|
Attachments
Issue Links
- relates to
-
MDEV-39843 prefix index causes incorrect range query result
-
- Confirmed
-