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

With (c0, vp_rowid) index ref access, string '0.45' is wrongly converted to integer key 0, causing multi-table reconstructed query to return c0=0 rows while single-table returns 0 rows.

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 12.3.2
    • None
    • Optimizer
    • Operating system:
      - Ubuntu 20.04.6 LTS (Focal Fossa)
      - Linux kernel: 5.4.0-204-generic
      - Architecture: x86_64
      Hardware:
      - CPU: 2 × Intel Xeon Gold 5218R @ 2.10 GHz
      - 40 physical cores / 80 logical CPUs

    Description

          1. Problem Description
            When the condition `'0.45' IN (c0)` uses the `(c0, vp_rowid)` index for `ref` access, MariaDB incorrectly converts the string value `'0.45'` to the integer index key `0`, thereby matching rows with `c0=0`. A full table scan returns 0 rows according to correct numeric comparison semantics. This produces inconsistent results between the single-table query and the multi-table LEFT JOIN derived-table reconstructed query.
          1. How to Reproduce
            Execute the following SQL:

      ```sql
      DROP DATABASE IF EXISTS repro_mariadb808_db12_min;
      CREATE DATABASE repro_mariadb808_db12_min;
      USE repro_mariadb808_db12_min;

      CREATE TABLE source_rows (
      vp_rowid BIGINT NOT NULL PRIMARY KEY,
      c0 TINYINT(1),
      c1 CHAR(1) NOT NULL,
      KEY idx_source (vp_rowid, c0)
      );

      CREATE TABLE left_rows (
      vp_rowid BIGINT NOT NULL PRIMARY KEY,
      c0 TINYINT(1),
      KEY idx_left (c0, vp_rowid)
      );

      CREATE TABLE right_rows (
      vp_rowid BIGINT NOT NULL PRIMARY KEY,
      c1 CHAR(1) NOT NULL
      );

      INSERT INTO source_rows VALUES
      (1, 0, 'a'),
      (2, 0, 'b'),
      (3, 1, 'c');

      INSERT INTO left_rows
      SELECT vp_rowid, c0 FROM source_rows;

      INSERT INTO right_rows
      SELECT vp_rowid, c1 FROM source_rows;

      – Original single-table query: actually returns 0 rows
      SELECT vp_rowid, c0
      FROM source_rows
      WHERE '0.45' IN (c0);

      – VP multi-table reconstructed query: incorrectly returns two rows with c0=0
      SELECT vp_rowid, c0
      FROM (
      SELECT l.vp_rowid, l.c0, r.c1
      FROM left_rows AS l
      LEFT JOIN right_rows AS r
      ON r.vp_rowid = l.vp_rowid
      ) AS reconstructed
      WHERE '0.45' IN (c0);
      ```

          1. Expected Behavior
            The single-table query and the multi-table reconstructed query should return identical results, i.e., 0 rows each.
          1. Actual Behavior
      • Single-table query: returns 0 rows (Empty set).
      • Multi-table reconstructed query: incorrectly returns two rows with `c0=0`.
          1. Additional Verification
            Disabling the problematic index:
            ```sql
            SELECT vp_rowid, c0
            FROM left_rows IGNORE INDEX (idx_left)
            WHERE '0.45' IN (c0);
            ```
            The result correctly returns 0 rows, and the execution plan becomes:
            ```
            table type key rows Extra
            left_rows ALL NULL 3 Using where; Using temporary
            ```

      Therefore, the problem is clear: when using the `(c0, vp_rowid)` index for `ref` access, MariaDB incorrectly converts the string value `'0.45'` to the integer index key `0`, thereby matching `c0=0`; a full table scan returns 0 rows according to correct numeric comparison semantics.

      Attachments

        Activity

          People

            Unassigned Unassigned
            Annie Annie liu
            Votes:
            0 Vote for this issue
            Watchers:
            1 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.