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

Materializing an empty `TIME` branch changes a `DATE` value in a mixed-type `UNION`

    XMLWordPrintable

Details

    Description

      MariaDB returns different values and result metadata for two relationally
      equivalent `UNION` queries. The query has three branches:

      1. An empty branch whose expression type is `TIME`.
      2. A branch returning one `DATE` value.
      3. An empty integer branch.

      When all expressions appear directly in the `UNION`, MariaDB returns the date as
      `2026-05-21`. When only the empty `TIME` branch is put behind a CTE, derived
      table, or temporary-table boundary, MariaDB returns
      `2026-05-21 00:00:00` instead.

      The empty branches return no rows in either query, but their expression types
      still participate in `UNION` type negotiation. Moving an empty branch across a
      relational boundary should not change the value produced by another branch.

      1. How to repeat

      No base tables or test data are required. Select an isolated database so that
      the temporary-table variant can also be executed:

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

      Run the direct query:

       
      ```sql
      (SELECT CAST('01:02:03' AS TIME) AS d WHERE FALSE)
      UNION
      (SELECT CAST('2026-05-21' AS DATE))
      UNION ALL
      SELECT 1 WHERE FALSE;
      ```
      
      

      Result:

       
      ```text
      2026-05-21
      ```
      
      

      Now place only the empty `TIME` branch in a CTE:

       
      ```sql
      WITH time_cut AS (
          SELECT CAST('01:02:03' AS TIME) AS d
          WHERE FALSE
      )
      (SELECT d FROM time_cut
       UNION
       SELECT CAST('2026-05-21' AS DATE))
      UNION ALL
      SELECT 1 WHERE FALSE;
      ```
      
      

      Result:

       
      ```text
      2026-05-21 00:00:00
      ```
      
      

      The derived-table form produces the same changed result:

       
      ```sql
      (SELECT d
       FROM (
           SELECT CAST('01:02:03' AS TIME) AS d
           WHERE FALSE
       ) AS time_cut
       UNION
       SELECT CAST('2026-05-21' AS DATE))
      UNION ALL
      SELECT 1 WHERE FALSE;
      ```
      
      

      The temporary-table form also produces the changed result:

       
      ```sql
      CREATE TEMPORARY TABLE time_cut AS
      SELECT CAST('01:02:03' AS TIME) AS d
      WHERE FALSE;
       
      (SELECT d FROM time_cut
       UNION
       SELECT CAST('2026-05-21' AS DATE))
      UNION ALL
      SELECT 1 WHERE FALSE;
      ```
      
      

      1. Metadata verification

      With PyMySQL, the direct and rewritten queries both expose a string result, but
      their declared maximum lengths differ:

       
      ```text
      Direct query:       MYSQL_TYPE_VAR_STRING, length 40
      CTE/derived query:  MYSQL_TYPE_VAR_STRING, length 76
      ```
      
      

      The length change corresponds to MariaDB formatting the `DATE` branch as a
      date-only string in the direct query and as a full `DATETIME` string after the
      boundary.

      1. Expected result

      All equivalent forms should return the same value and compatible metadata. The
      empty `TIME` branch contains no rows, and moving it into a CTE, derived table, or
      temporary table does not change the relational result.

      ```text
      2026-05-21
      ```
      
      

      1. Actual result

      The direct query returns:

       
      ```text
      2026-05-21
      ```
      
      

      The CTE, derived-table, and temporary-table forms return:

      ```text
      2026-05-21 00:00:00
      ```
      

      Attachments

        Activity

          People

            raghunandan.bhat Raghunandan Bhat
            chen7897 cl hl
            Votes:
            0 Vote for this issue
            Watchers:
            3 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.