Avoid pushing quals down into sub-queries that have grouping sets.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 22 Aug 2020 18:46:40 +0000 (14:46 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 22 Aug 2020 18:46:40 +0000 (14:46 -0400)
commit6fa403e61241bea60db83ce13ebcea7d6dda3024
treefe3b2584ef8c9c2c378fbde1ed3ff1dfad969daa
parentaa5b5c1740e870b45742c44602c40fe67f23a9a9
Avoid pushing quals down into sub-queries that have grouping sets.

The trouble with doing this is that an apparently-constant subquery
output column isn't really constant if it is a grouping column that
appears in only some of the grouping sets.  A qual using such a
column would be subject to incorrect const-folding after push-down,
as seen in bug #16585 from Paul Sivash.

To fix, just disable qual pushdown altogether if the sub-query has
nonempty groupingSets.  While we could imagine far less restrictive
solutions, there is not much point in working harder right now,
because subquery_planner() won't move HAVING clauses to WHERE within
such a subquery.  If the qual stays in HAVING it's not going to be
a lot more useful than if we'd kept it at the outer level.

Having said that, this restriction could be removed if we used a
parsetree representation that distinguished such outputs from actual
constants, which is something I hope to do in future.  Hence, make
the patch a minimal addition rather than integrating it more tightly
(e.g. by renumbering the existing items in subquery_is_pushdown_safe's
comment).

Back-patch to 9.5 where grouping sets were introduced.

Discussion: https://postgr.es/m/16585-9d8c340d23ade8c1@postgresql.org
src/backend/optimizer/path/allpaths.c
src/test/regress/expected/groupingsets.out
src/test/regress/sql/groupingsets.sql