mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
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
This commit is contained in:
@ -434,6 +434,38 @@ select x, not x as not_x, q2 from
|
||||
| | 4567890123456789
|
||||
(5 rows)
|
||||
|
||||
-- check qual push-down rules for a subquery with grouping sets
|
||||
explain (verbose, costs off)
|
||||
select * from (
|
||||
select 1 as x, q1, sum(q2)
|
||||
from int8_tbl i1
|
||||
group by grouping sets(1, 2)
|
||||
) ss
|
||||
where x = 1 and q1 = 123;
|
||||
QUERY PLAN
|
||||
--------------------------------------------
|
||||
Subquery Scan on ss
|
||||
Output: ss.x, ss.q1, ss.sum
|
||||
Filter: ((ss.x = 1) AND (ss.q1 = 123))
|
||||
-> GroupAggregate
|
||||
Output: (1), i1.q1, sum(i1.q2)
|
||||
Group Key: 1
|
||||
Sort Key: i1.q1
|
||||
Group Key: i1.q1
|
||||
-> Seq Scan on public.int8_tbl i1
|
||||
Output: 1, i1.q1, i1.q2
|
||||
(10 rows)
|
||||
|
||||
select * from (
|
||||
select 1 as x, q1, sum(q2)
|
||||
from int8_tbl i1
|
||||
group by grouping sets(1, 2)
|
||||
) ss
|
||||
where x = 1 and q1 = 123;
|
||||
x | q1 | sum
|
||||
---+----+-----
|
||||
(0 rows)
|
||||
|
||||
-- simple rescan tests
|
||||
select a, b, sum(v.x)
|
||||
from (values (1),(2)) v(x), gstest_data(v.x)
|
||||
|
@ -172,6 +172,22 @@ select x, not x as not_x, q2 from
|
||||
group by grouping sets(x, q2)
|
||||
order by x, q2;
|
||||
|
||||
-- check qual push-down rules for a subquery with grouping sets
|
||||
explain (verbose, costs off)
|
||||
select * from (
|
||||
select 1 as x, q1, sum(q2)
|
||||
from int8_tbl i1
|
||||
group by grouping sets(1, 2)
|
||||
) ss
|
||||
where x = 1 and q1 = 123;
|
||||
|
||||
select * from (
|
||||
select 1 as x, q1, sum(q2)
|
||||
from int8_tbl i1
|
||||
group by grouping sets(1, 2)
|
||||
) ss
|
||||
where x = 1 and q1 = 123;
|
||||
|
||||
-- simple rescan tests
|
||||
|
||||
select a, b, sum(v.x)
|
||||
|
Reference in New Issue
Block a user