diff options
| -rw-r--r-- | src/backend/optimizer/plan/subselect.c | 5 | ||||
| -rw-r--r-- | src/backend/optimizer/prep/prepjointree.c | 41 | 
2 files changed, 43 insertions, 3 deletions
| diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index cf503d51135..30386a38091 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -995,6 +995,11 @@ SS_process_ctes(PlannerInfo *root)   * (Notionally, we replace the SubLink with a constant TRUE, then elide the   * redundant constant from the qual.)   * + * On success, the caller is also responsible for recursively applying + * pull_up_sublinks processing to the rarg and quals of the returned JoinExpr. + * (On failure, there is no need to do anything, since pull_up_sublinks will + * be applied when we recursively plan the sub-select.) + *   * Side effects of a successful conversion include adding the SubLink's   * subselect to the query's rangetable, so that it can be referenced in   * the JoinExpr's rarg. diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 5a49768c6ce..93e9a947787 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -317,6 +317,7 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,  	{  		SubLink    *sublink = (SubLink *) node;  		JoinExpr   *j; +		Relids		child_rels;  		/* Is it a convertible ANY or EXISTS clause? */  		if (sublink->subLinkType == ANY_SUBLINK) @@ -325,7 +326,18 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,  											available_rels);  			if (j)  			{ -				/* Yes, insert the new join node into the join tree */ +				/* Yes; recursively process what we pulled up */ +				j->rarg = pull_up_sublinks_jointree_recurse(root, +															j->rarg, +															&child_rels); +				/* Pulled-up ANY/EXISTS quals can use those rels too */ +				child_rels = bms_add_members(child_rels, available_rels); +				/* ... and any inserted joins get stacked onto j->rarg */ +				j->quals = pull_up_sublinks_qual_recurse(root, +														 j->quals, +														 child_rels, +														 &j->rarg); +				/* Now insert the new join node into the join tree */  				j->larg = *jtlink;  				*jtlink = (Node *) j;  				/* and return NULL representing constant TRUE */ @@ -338,7 +350,18 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,  											   available_rels);  			if (j)  			{ -				/* Yes, insert the new join node into the join tree */ +				/* Yes; recursively process what we pulled up */ +				j->rarg = pull_up_sublinks_jointree_recurse(root, +															j->rarg, +															&child_rels); +				/* Pulled-up ANY/EXISTS quals can use those rels too */ +				child_rels = bms_add_members(child_rels, available_rels); +				/* ... and any inserted joins get stacked onto j->rarg */ +				j->quals = pull_up_sublinks_qual_recurse(root, +														 j->quals, +														 child_rels, +														 &j->rarg); +				/* Now insert the new join node into the join tree */  				j->larg = *jtlink;  				*jtlink = (Node *) j;  				/* and return NULL representing constant TRUE */ @@ -353,6 +376,7 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,  		/* If the immediate argument of NOT is EXISTS, try to convert */  		SubLink    *sublink = (SubLink *) get_notclausearg((Expr *) node);  		JoinExpr   *j; +		Relids		child_rels;  		if (sublink && IsA(sublink, SubLink))  		{ @@ -362,7 +386,18 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,  												   available_rels);  				if (j)  				{ -					/* Yes, insert the new join node into the join tree */ +					/* Yes; recursively process what we pulled up */ +					j->rarg = pull_up_sublinks_jointree_recurse(root, +																j->rarg, +																&child_rels); +					/* Pulled-up ANY/EXISTS quals can use those rels too */ +					child_rels = bms_add_members(child_rels, available_rels); +					/* ... and any inserted joins get stacked onto j->rarg */ +					j->quals = pull_up_sublinks_qual_recurse(root, +															 j->quals, +															 child_rels, +															 &j->rarg); +					/* Now insert the new join node into the join tree */  					j->larg = *jtlink;  					*jtlink = (Node *) j;  					/* and return NULL representing constant TRUE */ | 
