Skip to content

Commit 1a3daa5

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 b87037b commit 1a3daa5

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"
@@ -315,6 +316,9 @@ static Node *
315316
pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
316317
Relids *relids)
317318
{
319+
/* Since this function recurses, it could be driven to stack overflow. */
320+
check_stack_depth();
321+
318322
if (jtnode == NULL)
319323
{
320324
*relids = NULL;
@@ -812,6 +816,11 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode,
812816
JoinExpr *lowest_nulling_outer_join,
813817
AppendRelInfo *containing_appendrel)
814818
{
819+
/* Since this function recurses, it could be driven to stack overflow. */
820+
check_stack_depth();
821+
/* Also, since it's a bit expensive, let's check for query cancel. */
822+
CHECK_FOR_INTERRUPTS();
823+
815824
Assert(jtnode != NULL);
816825
if (IsA(jtnode, RangeTblRef))
817826
{
@@ -1941,6 +1950,9 @@ is_simple_union_all(Query *subquery)
19411950
static bool
19421951
is_simple_union_all_recurse(Node *setOp, Query *setOpQuery, List *colTypes)
19431952
{
1953+
/* Since this function recurses, it could be driven to stack overflow. */
1954+
check_stack_depth();
1955+
19441956
if (IsA(setOp, RangeTblRef))
19451957
{
19461958
RangeTblRef *rtr = (RangeTblRef *) setOp;

0 commit comments

Comments
 (0)