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

Commitbdd9a99

Browse files
committed
Propagate lateral-reference information to indirect descendant relations.
create_lateral_join_info() computes a bunch of information about lateralreferences between base relations, and then attempts to propagate thosemarkings to appendrel children of the original base relations. But theoriginal coding neglected the possibility of indirect descendants(grandchildren etc). During v11 development we noticed that this waswrong for partitioned-table cases, but failed to realize that it was justas wrong for any appendrel. While the case can't arise for appendrelsderived from traditional table inheritance (because we make a flatappendrel for that), nested appendrels can arise from nested UNION ALLsubqueries. Failure to mark the lower-level relations as having lateralreferences leads to confusion in add_paths_to_append_rel about whetherunparameterized paths can be built. It's not very clear whether thatleads to any user-visible misbehavior; the lack of field reports suggeststhat it may cause nothing worse than minor cost misestimation. Still,it's a bug, and it leads to failures of Asserts that I intend to addlater.To fix, we need to propagate information from all appendrel parents,not just those that are RELOPT_BASERELs. We can still do it in onepass, if we rely on the append_rel_list to be ordered with ancestorrelationships before descendant ones; add assertions checking that.While fixing this, we can make a small performance improvement bytraversing the append_rel_list just once instead of separately foreach appendrel parent relation.Noted while investigating bug #15613, though this patch does not fixthat (which is why I'm not committing the related Asserts yet).Discussion:https://postgr.es/m/3951.1549403812@sss.pgh.pa.us
1 parent592123e commitbdd9a99

File tree

1 file changed

+31
-40
lines changed

1 file changed

+31
-40
lines changed

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

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ void
419419
create_lateral_join_info(PlannerInfo*root)
420420
{
421421
boolfound_laterals= false;
422+
Relidsprev_parentsPG_USED_FOR_ASSERTS_ONLY=NULL;
422423
Indexrti;
423424
ListCell*lc;
424425

@@ -627,53 +628,43 @@ create_lateral_join_info(PlannerInfo *root)
627628
* every child anyway, and there's no value in forcing extra
628629
* reparameterize_path() calls. Similarly, a lateral reference to the
629630
* parent prevents use of otherwise-movable join rels for each child.
631+
*
632+
* It's possible for child rels to have their own children, in which case
633+
* the topmost parent's lateral info must be propagated all the way down.
634+
* This code handles that case correctly so long as append_rel_list has
635+
* entries for child relationships before grandchild relationships, which
636+
* is an okay assumption right now, but we'll need to be careful to
637+
* preserve it. The assertions below check for incorrect ordering.
630638
*/
631-
for (rti=1;rti<root->simple_rel_array_size;rti++)
639+
foreach(lc,root->append_rel_list)
632640
{
633-
RelOptInfo*brel=root->simple_rel_array[rti];
634-
RangeTblEntry*brte=root->simple_rte_array[rti];
635-
636-
/*
637-
* Skip empty slots. Also skip non-simple relations i.e. dead
638-
* relations.
639-
*/
640-
if (brel==NULL|| !IS_SIMPLE_REL(brel))
641-
continue;
641+
AppendRelInfo*appinfo= (AppendRelInfo*)lfirst(lc);
642+
RelOptInfo*parentrel=root->simple_rel_array[appinfo->parent_relid];
643+
RelOptInfo*childrel=root->simple_rel_array[appinfo->child_relid];
642644

643645
/*
644-
* In the case of table inheritance, the parent RTE is directly linked
645-
* to every child table via an AppendRelInfo. In the case of table
646-
* partitioning, the inheritance hierarchy is expanded one level at a
647-
* time rather than flattened. Therefore, an other member rel that is
648-
* a partitioned table may have children of its own, and must
649-
* therefore be marked with the appropriate lateral info so that those
650-
* children eventually get marked also.
646+
* If we're processing a subquery of a query with inherited target rel
647+
* (cf. inheritance_planner), append_rel_list may contain entries for
648+
* tables that are not part of the current subquery and hence have no
649+
* RelOptInfo. Ignore them. We can ignore dead rels, too.
651650
*/
652-
Assert(brte);
653-
if (brel->reloptkind==RELOPT_OTHER_MEMBER_REL&&
654-
(brte->rtekind!=RTE_RELATION||
655-
brte->relkind!=RELKIND_PARTITIONED_TABLE))
651+
if (parentrel==NULL|| !IS_SIMPLE_REL(parentrel))
656652
continue;
657653

658-
if (brte->inh)
659-
{
660-
foreach(lc,root->append_rel_list)
661-
{
662-
AppendRelInfo*appinfo= (AppendRelInfo*)lfirst(lc);
663-
RelOptInfo*childrel;
664-
665-
if (appinfo->parent_relid!=rti)
666-
continue;
667-
childrel=root->simple_rel_array[appinfo->child_relid];
668-
Assert(childrel->reloptkind==RELOPT_OTHER_MEMBER_REL);
669-
Assert(childrel->direct_lateral_relids==NULL);
670-
childrel->direct_lateral_relids=brel->direct_lateral_relids;
671-
Assert(childrel->lateral_relids==NULL);
672-
childrel->lateral_relids=brel->lateral_relids;
673-
Assert(childrel->lateral_referencers==NULL);
674-
childrel->lateral_referencers=brel->lateral_referencers;
675-
}
676-
}
654+
/* Verify that children are processed before grandchildren */
655+
#ifdefUSE_ASSERT_CHECKING
656+
prev_parents=bms_add_member(prev_parents,appinfo->parent_relid);
657+
Assert(!bms_is_member(appinfo->child_relid,prev_parents));
658+
#endif
659+
660+
/* OK, propagate info down */
661+
Assert(childrel->reloptkind==RELOPT_OTHER_MEMBER_REL);
662+
Assert(childrel->direct_lateral_relids==NULL);
663+
childrel->direct_lateral_relids=parentrel->direct_lateral_relids;
664+
Assert(childrel->lateral_relids==NULL);
665+
childrel->lateral_relids=parentrel->lateral_relids;
666+
Assert(childrel->lateral_referencers==NULL);
667+
childrel->lateral_referencers=parentrel->lateral_referencers;
677668
}
678669
}
679670

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp