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

Stored aggregate function in HAVING: ERROR 1054, or a wrong result when the column is also selected

    XMLWordPrintable

Details

    • Unexpected results

    Description

      A stored aggregate function (CREATE AGGREGATE FUNCTION) cannot be used directly in HAVING. Built-in aggregates like SUM work there.

      • If the column passed to the function is not in the select list: ERROR 1054 Unknown column 'v' in 'HAVING'.
      • If the column is also in the select list: no error, but a wrong result. The function fetches once per row of the group, but gets the value of the group's first row every time.

        CREATE TABLE t (g INT, v INT);
        INSERT INTO t VALUES (1, 10), (1, 20), (2, 5);
        DELIMITER //
        CREATE AGGREGATE FUNCTION my_sum(x INT) RETURNS INT
        BEGIN
          
        DECLARE s INT DEFAULT 0;
          
        DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN s;
          
        LOOP
            
        FETCH GROUP NEXT ROW;
            
        SET s = s + x;
          
        END LOOP;
        END //
        DELIMITER ;
        SELECT g, my_sum(v) FROM t GROUP BY g;                -- ok: 1 -> 30, 2 -> 5
        SELECT g FROM t GROUP BY g HAVING SUM(v) > 25;        -- ok: 1
        SELECT g FROM t GROUP BY g HAVING my_sum(v) > 25;     -- ERROR 1054 (42S22): Unknown column 'v' in 'HAVING'
        SELECT g, v FROM t GROUP BY g HAVING my_sum(v) > 25;  -- empty set, expected g = 1
        SELECT g, v FROM t GROUP BY g HAVING my_sum(v) = 20;  -- returns g = 1, so my_sum(v) is 10 + 10, not 10 + 20
        

        Expected: HAVING my_sum(v) > 25 returns g = 1, the same as HAVING SUM(v) > 25.
        What the function sees, using a copy of my_sum that appends each fetched x to a user variable @seen:

        in the select list:  10 20 = 30;  5 = 5;
        in HAVING:           10 10 = 20;  5 = 5;
        

        Also:

      • Same with a qualified column, HAVING my_sum(t.v) > 25, and without GROUP BY, SELECT 1 FROM t HAVING my_sum(v) > 10.
      • A column that is in GROUP BY works: HAVING my_sum(g) > 1.
      • ORDER BY my_sum(v) works.
        Workarounds: an alias (SELECT g, my_sum(v) AS s FROM t GROUP BY g HAVING s > 25) or a derived table.

      I searched Jira and found no existing issue. MDEV-14213 is about a plain stored function in HAVING, not an aggregate.

      Found while testing stored aggregates for a university project: https://github.com/ayoublabrinssi/Capstone-Starter-MariaDB-custom-aggregates

      Attachments

        Issue Links

          Activity

            People

              psergei Sergei Petrunia
              ayoub.brinssi Ayoub
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

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