Skip to content

Commit d572003

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 c8314d6 commit d572003

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
@@ -26,6 +26,7 @@
2626
#include "postgres.h"
2727

2828
#include "catalog/pg_type.h"
29+
#include "miscadmin.h"
2930
#include "nodes/makefuncs.h"
3031
#include "nodes/nodeFuncs.h"
3132
#include "optimizer/clauses.h"
@@ -230,6 +231,9 @@ static Node *
230231
pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
231232
Relids *relids)
232233
{
234+
/* Since this function recurses, it could be driven to stack overflow. */
235+
check_stack_depth();
236+
233237
if (jtnode == NULL)
234238
{
235239
*relids = NULL;
@@ -715,6 +719,11 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode,
715719
JoinExpr *lowest_nulling_outer_join,
716720
AppendRelInfo *containing_appendrel)
717721
{
722+
/* Since this function recurses, it could be driven to stack overflow. */
723+
check_stack_depth();
724+
/* Also, since it's a bit expensive, let's check for query cancel. */
725+
CHECK_FOR_INTERRUPTS();
726+
718727
Assert(jtnode != NULL);
719728
if (IsA(jtnode, RangeTblRef))
720729
{
@@ -1761,6 +1770,9 @@ is_simple_union_all(Query *subquery)
17611770
static bool
17621771
is_simple_union_all_recurse(Node *setOp, Query *setOpQuery, List *colTypes)
17631772
{
1773+
/* Since this function recurses, it could be driven to stack overflow. */
1774+
check_stack_depth();
1775+
17641776
if (IsA(setOp, RangeTblRef))
17651777
{
17661778
RangeTblRef *rtr = (RangeTblRef *) setOp;

0 commit comments

Comments
 (0)