bug: having clause evaluated before group by - Mailing list pgsql-hackers

From Jacob Brazeal
Subject bug: having clause evaluated before group by
Date
Msg-id CA+COZaA0tnyza0pHx6-UEdM5dcLGP4RJJ0KOHFq+wVQCY2Jyiw@mail.gmail.com
Whole thread
Responses Re: bug: having clause evaluated before group by
List pgsql-hackers

Hi all,

A HAVING clause can be evaluated before GROUP BY when it contains an expression that distinguishes equal numeric values, producing a result that is not possible under the query's semantics.

For example, on current master:

CREATE TABLE t (c numeric);
INSERT INTO t VALUES (0), (0), (0), (0.0), (0.0);

SELECT c, count(*) FROM t GROUP BY c; c | count
---+------- 0 |     5

SELECT c, count(*) FROM t  GROUP BY c  HAVING scale(c) = 1;  c  | count
-----+------- 0.0 |     2

All five input values are equal according to numeric equality, so they form one group. Therefore the second query can return either no rows or one row with a count of 5, depending on the value used to represent the group. A count of 2 is impossible; it implies three scale-0 rows have been filtered before grouping.

The planner has two optimizations that can move a qualification across a grouping boundary:

  • transferring a HAVING clause to WHERE before aggregation; and
  • pushing an outer restriction into a subquery past DISTINCT, DISTINCT ON, window partitioning, or set-operation grouping.

Commit 44fb59fc605 added expression_has_grouping_conflict() to prevent such movement when the expression can distinguish values that the grouping operation considers equal.

The check appears to be incomplete. For a grouping-column reference that is not a direct operand of the grouping equality, such as scale(c), grouping_conflict_walker() rejects the expression for a nondeterministic collation, but not for a type whose equality does not imply image equality.

That matters for numeric, where 0 and 0.0 compare equal but have different scales. It also appears relevant to other non-equalimage cases such as record_image_ops and float positive/negative zero.

I reproduced this on master at 1c9c3589042.

pgsql-hackers by date:

Previous
From: Haibo Yan
Date:
Subject: Re: Fix race in background worker termination for database
Next
From: Tom Lane
Date:
Subject: Re: bug: having clause evaluated before group by