Commit 11470352 authored by Tom Lane's avatar Tom Lane

Disallow pushing volatile qual expressions down into DISTINCT subqueries.

A WHERE clause applied to the output of a subquery with DISTINCT should
theoretically be applied only once per distinct row; but if we push it
into the subquery then it will be evaluated at each row before duplicate
elimination occurs.  If the qual is volatile this can give rise to
observably wrong results, so don't do that.

While at it, refactor a little bit to allow subquery_is_pushdown_safe
to report more than one kind of restrictive condition without indefinitely
expanding its argument list.

Although this is a bug fix, it seems unwise to back-patch it into released
branches, since it might de-optimize plans for queries that aren't giving
any trouble in practice.  So apply to 9.4 but not further back.
parent f71136ee
This diff is collapsed.
...@@ -739,3 +739,32 @@ select * from int4_tbl where ...@@ -739,3 +739,32 @@ select * from int4_tbl where
0 0
(1 row) (1 row)
--
-- Check that volatile quals aren't pushed down past a DISTINCT:
-- nextval() should not be called more than the nominal number of times
--
create temp sequence ts1;
select * from
(select distinct ten from tenk1) ss
where ten < 10 + nextval('ts1')
order by 1;
ten
-----
0
1
2
3
4
5
6
7
8
9
(10 rows)
select nextval('ts1');
nextval
---------
11
(1 row)
...@@ -422,3 +422,16 @@ select * from int4_tbl where ...@@ -422,3 +422,16 @@ select * from int4_tbl where
select * from int4_tbl where select * from int4_tbl where
(case when f1 in (select unique1 from tenk1 a) then f1 else null end) in (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in
(select ten from tenk1 b); (select ten from tenk1 b);
--
-- Check that volatile quals aren't pushed down past a DISTINCT:
-- nextval() should not be called more than the nominal number of times
--
create temp sequence ts1;
select * from
(select distinct ten from tenk1) ss
where ten < 10 + nextval('ts1')
order by 1;
select nextval('ts1');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment