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

In multi-table join/derived table scenarios, the return type length of `TRIM(ORD(c0))` is incorrectly deduced, causing the trailing character of the result string to be truncated (`14857150` becomes `1485715`).

    XMLWordPrintable

Details

    • Bug
    • Status: Confirmed (View Workflow)
    • Major
    • Resolution: Unresolved
    • 10.11, 11.4, 11.8, 12.3, 13.0, 13.0.1
    • 10.11, 11.4, 11.8, 12.3, 13.0
    • Character Sets, Optimizer

    Description

          1. Problem Description
            When a query involves multi-table joins, derived tables, temporary tables, and sorting, the result of `TRIM(ORD(c0))` is truncated to an incorrect maximum length during materialization/sorting. In a single-table query, constant folding via the primary key evaluates the expression early and produces the correct result. In a multi-table query, the expression is evaluated at runtime, and the optimizer deduces its return type length as `VARCHAR(7)` or similar, while the actual generated string length is 8, resulting in the trailing `'0'` being truncated.
          1. How to Reproduce
            Execute the following SQL:

      ```sql
      DROP DATABASE IF EXISTS repro_mariadb806_db1_min6;
      CREATE DATABASE repro_mariadb806_db1_min6
      CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci;
      USE repro_mariadb806_db1_min6;

      CREATE TABLE t4 (
      c0 VARCHAR(100) NOT NULL,
      PRIMARY KEY (c0)
      ) ENGINE=InnoDB
      DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci;

      INSERT INTO t4 VALUES ('⳾v*');

      CREATE TABLE vp_mariadb_database1_937_source LIKE t4;
      ALTER TABLE vp_mariadb_database1_937_source
      ADD COLUMN vp_rowid BIGINT NOT NULL FIRST;
      ALTER TABLE vp_mariadb_database1_937_source ENGINE=InnoDB;

      INSERT INTO vp_mariadb_database1_937_source (vp_rowid, c0)
      SELECT ROW_NUMBER() OVER (ORDER BY c0), c0
      FROM t4;

      CREATE TABLE vp_mariadb_database1_937_left (
      vp_rowid BIGINT NOT NULL,
      c0 VARCHAR(100)
      CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci
      ) ENGINE=InnoDB;

      CREATE TABLE vp_mariadb_database1_937_right (
      vp_rowid BIGINT NOT NULL
      ) ENGINE=InnoDB;

      INSERT INTO vp_mariadb_database1_937_left
      SELECT vp_rowid, c0 FROM vp_mariadb_database1_937_source;

      INSERT INTO vp_mariadb_database1_937_right
      SELECT vp_rowid FROM vp_mariadb_database1_937_source;

      SET NAMES utf8mb4 COLLATE utf8mb4_uca1400_ai_ci;

      – Single-table query
      SELECT *
      FROM (
      SELECT TRIM(ORD(c0)) AS vp_ast_col_0,
      -1914373596 AS vp_ast_col_1,
      c0 AS vp_ast_col_2,
      c0 AS vp_ast_col_3,
      '' AS vp_ast_col_4
      FROM vp_mariadb_database1_937_source
      ) q
      WHERE q.vp_ast_col_2 = '⳾v*'
      ORDER BY 1, 2, 3, 4, 5;

      – Multi-table rewritten query
      SELECT *
      FROM (
      SELECT TRIM(ORD(c0)) AS vp_ast_col_0,
      -1914373596 AS vp_ast_col_1,
      c0 AS vp_ast_col_2,
      c0 AS vp_ast_col_3,
      '' AS vp_ast_col_4
      FROM (
      SELECT l.vp_rowid, l.c0
      FROM vp_mariadb_database1_937_left l
      JOIN (
      SELECT vp_rowid, CONCAT('vp:', vp_rowid) AS payload
      FROM vp_mariadb_database1_937_right
      ) p ON p.payload = CONCAT('vp:', l.vp_rowid)
      JOIN vp_mariadb_database1_937_right r
      ON r.vp_rowid = p.vp_rowid
      ) vp_rel
      ) q
      WHERE q.vp_ast_col_2 = '⳾v*'
      ORDER BY 1, 2, 3, 4, 5;
      ```

          1. Expected Behavior
            Both queries should return identical results, with `vp_ast_col_0` equal to `14857150`.
      Query Type vp_ast_col_0 vp_ast_col_1 vp_ast_col_2 vp_ast_col_3 vp_ast_col_4
      ------------------ -------------- -------------- -------------- -------------- --------------
      Single-table 14857150 -1914373596 ⳾v* ⳾v*  
      Multi-table 14857150 -1914373596 ⳾v* ⳾v*  
          1. Actual Behavior
            In the multi-table query, `vp_ast_col_0` loses the trailing `'0'`.
      Query Type vp_ast_col_0 vp_ast_col_1 vp_ast_col_2 vp_ast_col_3 vp_ast_col_4
      ------------------ -------------- -------------- -------------- -------------- --------------
      Single-table 14857150 -1914373596 ⳾v* ⳾v*  
      Multi-table 1485715 -1914373596 ⳾v* ⳾v*  
          1. Execution Plan Comparison
            *Single-table query execution plan:*
            ```
            1 | SIMPLE | vp_mariadb_database1_937_source
            const PRIMARY PRIMARY 402 const 1

            ```
            Because `c0` is the primary key, `WHERE c0 = '⳾v*'` directly hits the primary key. The optimizer treats the entire row as a constant, and the outer `TRIM(ORD(c0))` is evaluated via constant folding, yielding the correct result `14857150`.

      *Multi-table query execution plan:*
      ```
      1 | SIMPLE | l

      ALL NULL NULL NULL NULL 1
      Using where; Using temporary; Using filesort

      1 | SIMPLE | vp_mariadb_database1_937_right

      ALL NULL NULL NULL NULL 1
      Using where; Using join buffer (flat, BNL join)

      1 | SIMPLE | r

      hash_ALL NULL #hash#$hj 8
      ...vp_mariadb_database1_937_right.vp_rowid 1
      Using where; Using join buffer (flat, BNLH join)
      ```
      Here the primary key constant path is not possible. The derived table `vp_rel` is materialized or merged, `TRIM(ORD(c0))` is evaluated at runtime, and the result passes through temporary/filesort. The final output changes from `14857150` to `1485715`, dropping one `'0'`.

      Attachments

        Activity

          People

            raghunandan.bhat Raghunandan Bhat
            Annie Annie liu
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Time Tracking

                Estimated:
                Original Estimate - 0d
                0d
                Remaining:
                Remaining Estimate - 2d
                2d
                Logged:
                Time Spent - Not Specified
                Not Specified

                Git Integration

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