Skip to content

Commit 5beb788

Browse files
committed
Add some recursion and looping defenses in prepjointree.c.
Andrey Lepikhov demonstrated a case where we spend an unreasonable amount of time in pull_up_subqueries(). Not only is that recursing with no explicit check for stack overrun, but the code seems not interruptable by control-C. Let's stick a CHECK_FOR_INTERRUPTS there, along with sprinkling some stack depth checks. An actual fix for the excessive time consumption seems a bit risky to back-patch; but this isn't, so let's do so. Discussion: https://postgr.es/m/703c09a2-08f3-d2ec-b33d-dbecd62428b8@postgrespro.ru
1 parent 73bb72f commit 5beb788

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

src/backend/optimizer/prep/prepjointree.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "catalog/pg_type.h"
2929
#include "funcapi.h"
30+
#include "miscadmin.h"
3031
#include "nodes/makefuncs.h"
3132
#include "nodes/multibitmapset.h"
3233
#include "nodes/nodeFuncs.h"
@@ -308,6 +309,9 @@ static Node *
308309
pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
309310
Relids *relids)
310311
{
312+
/* Since this function recurses, it could be driven to stack overflow. */
313+
check_stack_depth();
314+
311315
if (jtnode == NULL)
312316
{
313317
*relids = NULL;
@@ -805,6 +809,11 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode,
805809
JoinExpr *lowest_nulling_outer_join,
806810
AppendRelInfo *containing_appendrel)
807811
{
812+
/* Since this function recurses, it could be driven to stack overflow. */
813+
check_stack_depth();
814+
/* Also, since it's a bit expensive, let's check for query cancel. */
815+
CHECK_FOR_INTERRUPTS();
816+
808817
Assert(jtnode != NULL);
809818
if (IsA(jtnode, RangeTblRef))
810819
{
@@ -1937,6 +1946,9 @@ is_simple_union_all(Query *subquery)
19371946
static bool
19381947
is_simple_union_all_recurse(Node *setOp, Query *setOpQuery, List *colTypes)
19391948
{
1949+
/* Since this function recurses, it could be driven to stack overflow. */
1950+
check_stack_depth();
1951+
19401952
if (IsA(setOp, RangeTblRef))
19411953
{
19421954
RangeTblRef *rtr = (RangeTblRef *) setOp;

0 commit comments

Comments
 (0)