Re: Optimizer Doesn't Push Down Where Expressions on Rollups - Mailing list pgsql-bugs

From Richard Guo
Subject Re: Optimizer Doesn't Push Down Where Expressions on Rollups
Date
Msg-id CAMbWs4-7HwzpS1WXmT11ZaY9Cfx-PXExZdzQ-vq+83xKNNQEvA@mail.gmail.com
Whole thread Raw
In response to Re: Optimizer Doesn't Push Down Where Expressions on Rollups  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Optimizer Doesn't Push Down Where Expressions on Rollups
Re: Optimizer Doesn't Push Down Where Expressions on Rollups
List pgsql-bugs
On Wed, Mar 11, 2020 at 10:06 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Richard Guo <guofenglinux@gmail.com> writes:
> In your case, the WHERE clauses would get pushed down into the subquery
> for both queries, with/without the ROLLUP. But since the subquery uses
> grouping/grouping sets, the WHERE clauses would be put in HAVING of the
> subquery.

Right, we do successfully push the clauses into HAVING of the subquery.

> Then when we plan for the subquery, we will decide whether a HAVING
> clause can be transfered into WHERE. Usually we do not do that if there
> are any nonempty grouping sets. Because if any referenced column isn't
> present in all the grouping sets, moving such a clause into WHERE would
> potentially change the results.

Yeah.  I think that it might be safe if the proposed clause can
be proven strict for (some subset of?) the grouping columns, because
that would eliminate the rollup grouping sets where those columns
come out NULL because they aren't being grouped on.  (This could then
also factor into throwing away those grouping sets, perhaps.)

This seems correct to me. If we can prove the HAVING clause is strict
for some grouping columns, then we can throw away the grouping sets that
do not contain these grouping columns, since their results would be
eliminated by this HAVING clause. After that we can move this HAVING
clause to WHERE. I'm thinking about this example:

select c1, c2, sum(c4) from t group by
    grouping sets ((c1, c2), (c2, c3), (c1, c4)) having c2 = 2;

select c1, c2, sum(c4) from t group by
    grouping sets ((c1, c2), (c2, c3)) having c2 = 2;

select c1, c2, sum(c4) from t where c2 = 2 group by
    grouping sets ((c1, c2), (c2, c3));


For non-strict HAVING clause, if its referenced columns are present in
all the grouping sets, I think we should also be able to move it to
WHERE.

Thanks
Richard 

pgsql-bugs by date:

Previous
From: Sergei Kornilov
Date:
Subject: Re: Streaming replication doesn't restart after timeout
Next
From: PG Bug reporting form
Date:
Subject: BUG #16299: pg_subscription_rel inconsistency post create database from template with disabled subscription