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

Redundant DISTINCT in a UNION branch changes the returned floating-point value

    XMLWordPrintable

Details

    Description

      Description

      Adding DISTINCT to a branch of a UNION changes the client-visible value of a floating-point expression, even though the added DISTINCT is redundant because UNION already removes duplicate rows from the final result.

      In the example below, the second branch is empty, but its string expression still participates in the type resolution of the UNION. Without the branch-level DISTINCT, MariaDB returns the underlying floating-point value as 690.8200073242188. After adding DISTINCT, MariaDB appears to materialize and round the first branch according to the declared FLOAT(8,2) precision before performing the UNION, and returns 690.82 instead.

      The two queries are logically equivalent and return the same number of rows, but they expose different values to the client.

      Expected behaviour

      Both queries should return the same value. The redundant branch-level DISTINCT should only affect duplicate elimination and must not change the value or precision of f + d.

      Expected result for both queries:

      690.8200073242188
      

      Alternatively, returning 690.82 for both queries would also be internally consistent. The important requirement is that adding the redundant DISTINCT must not change the result.

      Actual behaviour

      The query without the redundant DISTINCT returns:

      690.8200073242188
      

      The logically equivalent query with DISTINCT returns:

      690.82
      

      The result is stable across repeated executions.

      How to repeat

      Execute the following complete SQL script:

      DROP DATABASE IF EXISTS rift_distinct_union_mre;
      CREATE DATABASE rift_distinct_union_mre;
      USE rift_distinct_union_mre;
       
      CREATE TABLE t (
          f FLOAT(8,2),
          d DECIMAL(10,2)
      );
       
      INSERT INTO t VALUES (690.82, 0);
       
      -- Original query.
      SELECT f + d AS v
      FROM t
      UNION
      SELECT 'x'
      WHERE FALSE;
       
      -- Logically equivalent query with a redundant DISTINCT.
      SELECT DISTINCT f + d AS v
      FROM t
      UNION
      SELECT 'x'
      WHERE FALSE;
      

      Observed output:

      v
      690.8200073242188
       
      v
      690.82
      

      Version

      SELECT VERISON();
      12.3.2-MariaDB-ubu2404
      

      Attachments

        Issue Links

          Activity

            People

              raghunandan.bhat Raghunandan Bhat
              chen7897 cl hl
              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.