Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-40046

Range optimizer's const-bound folding mishandles numeric-overflow string literals (e.g. `'-1e500'`) on a prefix(1) index, producing "Impossible WHERE" and returning 0 rows where 12 are correct.

    XMLWordPrintable

Details

    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:

      1. prefix index length = 1, AND
      2. 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

          Activity

            People

              raghunandan.bhat Raghunandan Bhat
              ZyanNo1 Zeyan Li
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.