Skip to content

Commit 97431d6

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 f489b48 commit 97431d6

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/nodeFuncs.h"
3233
#include "optimizer/clauses.h"
@@ -235,6 +236,9 @@ static Node *
235236
pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
236237
Relids *relids)
237238
{
239+
/* Since this function recurses, it could be driven to stack overflow. */
240+
check_stack_depth();
241+
238242
if (jtnode == NULL)
239243
{
240244
*relids = NULL;
@@ -732,6 +736,11 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode,
732736
JoinExpr *lowest_nulling_outer_join,
733737
AppendRelInfo *containing_appendrel)
734738
{
739+
/* Since this function recurses, it could be driven to stack overflow. */
740+
check_stack_depth();
741+
/* Also, since it's a bit expensive, let's check for query cancel. */
742+
CHECK_FOR_INTERRUPTS();
743+
735744
Assert(jtnode != NULL);
736745
if (IsA(jtnode, RangeTblRef))
737746
{
@@ -1854,6 +1863,9 @@ is_simple_union_all(Query *subquery)
18541863
static bool
18551864
is_simple_union_all_recurse(Node *setOp, Query *setOpQuery, List *colTypes)
18561865
{
1866+
/* Since this function recurses, it could be driven to stack overflow. */
1867+
check_stack_depth();
1868+
18571869
if (IsA(setOp, RangeTblRef))
18581870
{
18591871
RangeTblRef *rtr = (RangeTblRef *) setOp;

0 commit comments

Comments
 (0)