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

GROUP BY merges distinct DECIMAL values after generated-column substitution

    XMLWordPrintable

Details

    Description

      The indexed GROUP BY a returns one (11.11, 2) group, although the stored values of a are 11.11 and 22.22. Disabling the generated-column index returns two count-1 groups. This was reproduced with MariaDB 12.3.3 on Linux/amd64.

      Run:

      CREATE DATABASE decimal_groups;
      USE decimal_groups;
      CREATE TABLE amounts (a DECIMAL(4,2), b DECIMAL(5,4) AS (a), KEY by_generated_value(b)) ENGINE=InnoDB;
      INSERT IGNORE INTO amounts(a) VALUES (11.11),(22.22);
      SHOW WARNINGS;
      SELECT 'base_rows' AS section;
      SELECT a,b FROM amounts ORDER BY a+0;
      SELECT 'indexed_groups' AS section;
      SELECT a,COUNT(*) AS n FROM amounts GROUP BY a;
      SELECT 'unindexed_groups' AS section;
      SELECT a,COUNT(*) AS n FROM amounts IGNORE INDEX(by_generated_value) GROUP BY a;
      EXPLAIN EXTENDED SELECT a,COUNT(*) AS n FROM amounts GROUP BY a;
      SHOW WARNINGS;
      DROP DATABASE decimal_groups;
      SELECT COUNT(*) AS remaining_schemas FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='decimal_groups';

      The relevant output is:

      Level  Code  Message
      Warning  1264  Out of range value for column 'b' at row 1
      Warning  1264  Out of range value for column 'b' at row 2
      section
      base_rows
      a      b
      11.11  9.9999
      22.22  9.9999
      section
      indexed_groups
      a      n
      11.11  2
      section
      unindexed_groups
      a      n
      11.11  1
      22.22  1

      The warnings and saturation of generated column b are expected under INSERT IGNORE, but base column a retains two distinct values. Grouping by a must therefore return (11.11, 1) and (22.22, 1) regardless of whether the generated-column index is available.

      EXPLAIN EXTENDED reports the rewritten query as:

      select `decimal_groups`.`amounts`.`a` AS `a`,count(0) AS `n` from `decimal_groups`.`amounts` group by `decimal_groups`.`amounts`.`b`

      This shows that MariaDB substitutes the generated column and groups by b, which cannot preserve the distinction between the two stored a values. The source evidence indicates that the decimal compatibility check compares total precision and scale without preserving integer-digit capacity; this appears to permit the lossy substitution.

      This occurs when grouping DECIMAL values whose indexed generated column has greater total precision and scale but less integer capacity.

      Attachments

        Issue Links

          Activity

            People

              ycp Yuchen Pei
              Wren Qin
              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 - 1d
                  1d
                  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.