Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit65a7cd0

Browse files
committed
Fix pull_up_sublinks' failure to handle nested pull-up opportunities.
After finding an EXISTS or ANY sub-select that can be converted to asemi-join or anti-join, we should recurse into the body of the sub-select.This allows cases such as EXISTS-within-EXISTS to be optimized properly.The original coding would leave the lower sub-select as a SubLink, whichis no better and often worse than what we can do with a join. Per examplefrom Wayne Conrad.Back-patch to 8.4. There is a related issue in older versions' handlingof pull_up_IN_clauses, but they're lame enough anyway about the whole areathat it seems not worth the extra work to try to fix.
1 parente79518e commit65a7cd0

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

‎src/backend/optimizer/plan/subselect.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,11 @@ SS_process_ctes(PlannerInfo *root)
995995
* (Notionally, we replace the SubLink with a constant TRUE, then elide the
996996
* redundant constant from the qual.)
997997
*
998+
* On success, the caller is also responsible for recursively applying
999+
* pull_up_sublinks processing to the rarg and quals of the returned JoinExpr.
1000+
* (On failure, there is no need to do anything, since pull_up_sublinks will
1001+
* be applied when we recursively plan the sub-select.)
1002+
*
9981003
* Side effects of a successful conversion include adding the SubLink's
9991004
* subselect to the query's rangetable, so that it can be referenced in
10001005
* the JoinExpr's rarg.

‎src/backend/optimizer/prep/prepjointree.c

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
317317
{
318318
SubLink*sublink= (SubLink*)node;
319319
JoinExpr*j;
320+
Relidschild_rels;
320321

321322
/* Is it a convertible ANY or EXISTS clause? */
322323
if (sublink->subLinkType==ANY_SUBLINK)
@@ -325,7 +326,18 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
325326
available_rels);
326327
if (j)
327328
{
328-
/* Yes, insert the new join node into the join tree */
329+
/* Yes; recursively process what we pulled up */
330+
j->rarg=pull_up_sublinks_jointree_recurse(root,
331+
j->rarg,
332+
&child_rels);
333+
/* Pulled-up ANY/EXISTS quals can use those rels too */
334+
child_rels=bms_add_members(child_rels,available_rels);
335+
/* ... and any inserted joins get stacked onto j->rarg */
336+
j->quals=pull_up_sublinks_qual_recurse(root,
337+
j->quals,
338+
child_rels,
339+
&j->rarg);
340+
/* Now insert the new join node into the join tree */
329341
j->larg=*jtlink;
330342
*jtlink= (Node*)j;
331343
/* and return NULL representing constant TRUE */
@@ -338,7 +350,18 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
338350
available_rels);
339351
if (j)
340352
{
341-
/* Yes, insert the new join node into the join tree */
353+
/* Yes; recursively process what we pulled up */
354+
j->rarg=pull_up_sublinks_jointree_recurse(root,
355+
j->rarg,
356+
&child_rels);
357+
/* Pulled-up ANY/EXISTS quals can use those rels too */
358+
child_rels=bms_add_members(child_rels,available_rels);
359+
/* ... and any inserted joins get stacked onto j->rarg */
360+
j->quals=pull_up_sublinks_qual_recurse(root,
361+
j->quals,
362+
child_rels,
363+
&j->rarg);
364+
/* Now insert the new join node into the join tree */
342365
j->larg=*jtlink;
343366
*jtlink= (Node*)j;
344367
/* and return NULL representing constant TRUE */
@@ -353,6 +376,7 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
353376
/* If the immediate argument of NOT is EXISTS, try to convert */
354377
SubLink*sublink= (SubLink*)get_notclausearg((Expr*)node);
355378
JoinExpr*j;
379+
Relidschild_rels;
356380

357381
if (sublink&&IsA(sublink,SubLink))
358382
{
@@ -362,7 +386,18 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
362386
available_rels);
363387
if (j)
364388
{
365-
/* Yes, insert the new join node into the join tree */
389+
/* Yes; recursively process what we pulled up */
390+
j->rarg=pull_up_sublinks_jointree_recurse(root,
391+
j->rarg,
392+
&child_rels);
393+
/* Pulled-up ANY/EXISTS quals can use those rels too */
394+
child_rels=bms_add_members(child_rels,available_rels);
395+
/* ... and any inserted joins get stacked onto j->rarg */
396+
j->quals=pull_up_sublinks_qual_recurse(root,
397+
j->quals,
398+
child_rels,
399+
&j->rarg);
400+
/* Now insert the new join node into the join tree */
366401
j->larg=*jtlink;
367402
*jtlink= (Node*)j;
368403
/* and return NULL representing constant TRUE */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp