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

`BIT` result type changes after a materialization rewrite under `DISTINCT`

    XMLWordPrintable

Details

    • Not for Release Notes

    Description

      MariaDB changes the result type of a selected `BIT(8)` column when the query is
      rewritten by placing the source relation behind a `FROM` subquery and the outer
      query applies `DISTINCT`.

      The direct query exposes the column as the MariaDB protocol type `BIT` and a
      binary-capable client receives byte strings. The equivalent query produced by
      the VECT materialization operator (`from_subquery` placement) exposes the same
      values as protocol type `LONG`, so clients receive integers instead.

      The bit patterns are unchanged. This is a result metadata and client-visible
      type change caused by MariaDB's handling of a mergeable materialization
      boundary. The SQL is valid and the two queries are relationally equivalent.

      1. Expected result

      The direct and materialized queries should preserve both the `BIT(8)` result
      type and the byte-string representation. Introducing an equivalent relational
      materialization boundary should not change the selected column's protocol
      metadata or client-visible type.

      1. Actual result

      MariaDB 12.3.2 changes the materialized query's result type from `BIT` to
      `LONG`. The bit patterns remain numerically equivalent, but applications,
      ORMs, serializers, and result comparators receive integers instead of byte
      strings.

      How to repeat'

       
       
      ```sql
      DROP DATABASE IF EXISTS mariadb_bit_distinct_materialization_test;
      CREATE DATABASE mariadb_bit_distinct_materialization_test;
      USE mariadb_bit_distinct_materialization_test;
       
      CREATE TABLE bit_source (
          id INT PRIMARY KEY,
          b BIT(8)
      );
       
      INSERT INTO bit_source VALUES
          (1, b'11001100'),
          (2, b'11010011'),
          (3, b'10111111'),
          (4, b'00110110');
      ```
      
      

      Run the original query:

       
      ```sql
      SELECT DISTINCT b
      FROM bit_source;
      ```
      
      

      On MariaDB, the first column has protocol type `BIT` (`MYSQL_TYPE_BIT`, code
      16), and a binary-capable client receives:

       
      ```text
      b'\xcc'
      b'\xd3'
      b'\xbf'
      b'6'
      ```
      
      

      Now apply the VECT materialization operator by cutting the source relation into
      a `FROM` subquery:

       
      ```sql
      SELECT DISTINCT input.b
      FROM (
          SELECT b
          FROM bit_source
      ) AS input;
      ```
      
      

      On MariaDB, the first column now has protocol type `LONG`
      (`MYSQL_TYPE_LONG`, code 3), and the same values are returned as:

       
      ```text
      204
      211
      191
      54
      ```
      
      

      The equivalent CTE placement has the same result-type change:

       
      ```sql
      WITH input AS (
          SELECT b
          FROM bit_source
      )
      SELECT DISTINCT input.b
      FROM input;
      ```
      
      

      Forcing the derived table not to merge avoids this particular result-type
      change on the tested MariaDB version:

       
      ```sql
      SELECT /*+ NO_MERGE(input) */ DISTINCT input.b
      FROM (
          SELECT b
          FROM bit_source
      ) AS input;
      ```
      

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              chen7897 cl hl
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

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