Skip to content

Commit fb9e56e

Browse files
committed
Suppress subquery pullup/pushdown when a subquery contains volatile
functions in its targetlist, to avoid introducing multiple evaluations of volatile functions that textually appear only once. This is a slightly tighter version of Jaime Casanova's recent patch.
1 parent 9bf760f commit fb9e56e

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

src/backend/optimizer/path/allpaths.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.151 2006/08/10 02:36:28 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.152 2006/08/19 02:48:53 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -871,6 +871,10 @@ compare_tlist_datatypes(List *tlist, List *colTypes,
871871
* 5. We must not push down any quals that refer to subselect outputs that
872872
* return sets, else we'd introduce functions-returning-sets into the
873873
* subquery's WHERE/HAVING quals.
874+
*
875+
* 6. We must not push down any quals that refer to subselect outputs that
876+
* contain volatile functions, for fear of introducing strange results due
877+
* to multiple evaluation of a volatile function.
874878
*/
875879
static bool
876880
qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
@@ -940,6 +944,13 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
940944
safe = false;
941945
break;
942946
}
947+
948+
/* Refuse volatile functions (point 6) */
949+
if (contain_volatile_functions((Node *) tle->expr))
950+
{
951+
safe = false;
952+
break;
953+
}
943954
}
944955

945956
list_free(vars);

src/backend/optimizer/prep/prepjointree.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.42 2006/08/12 20:05:55 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.43 2006/08/19 02:48:53 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -656,6 +656,15 @@ is_simple_subquery(Query *subquery)
656656
if (expression_returns_set((Node *) subquery->targetList))
657657
return false;
658658

659+
/*
660+
* Don't pull up a subquery that has any volatile functions in its
661+
* targetlist. Otherwise we might introduce multiple evaluations of
662+
* these functions, if they get copied to multiple places in the upper
663+
* query, leading to surprising results.
664+
*/
665+
if (contain_volatile_functions((Node *) subquery->targetList))
666+
return false;
667+
659668
/*
660669
* Hack: don't try to pull up a subquery with an empty jointree.
661670
* query_planner() will correctly generate a Result plan for a jointree

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy