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

Commit2f17b57

Browse files
committed
Improve performance of adjust_appendrel_attrs_multilevel.
The present implementations of adjust_appendrel_attrs_multilevel andits sibling adjust_child_relids_multilevel are very messy, becausethey work by reconstructing the relids of the child's immediateparent and then seeing if that's bms_equal to the relids of thetarget parent. Aside from being quite inefficient, this will notwork with planned future changes to make joinrels' relid setscontain outer-join relids in addition to baserels.The whole thing can be solved at a stroke by adding explicit parentand top_parent links to child RelOptInfos, and making these functionswork with RelOptInfo pointers instead of relids. Doing that issimpler for most callers, too.In my original version of this patch, I got rid ofRelOptInfo.top_parent_relids on the grounds that it was now redundant.However, that adds a lot of code churn in places that otherwise wouldnot need changing, and arguably the extra indirection needed to fetchtop_parent->relids in those places costs something. So this versionleaves that field in place.Discussion:https://postgr.es/m/553080.1657481916@sss.pgh.pa.us
1 parentec97db3 commit2f17b57

File tree

8 files changed

+83
-94
lines changed

8 files changed

+83
-94
lines changed

‎src/backend/optimizer/path/equivclass.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,8 +1760,8 @@ generate_join_implied_equalities_broken(PlannerInfo *root,
17601760
if (IS_OTHER_REL(inner_rel)&&result!=NIL)
17611761
result= (List*)adjust_appendrel_attrs_multilevel(root,
17621762
(Node*)result,
1763-
inner_rel->relids,
1764-
inner_rel->top_parent_relids);
1763+
inner_rel,
1764+
inner_rel->top_parent);
17651765

17661766
returnresult;
17671767
}
@@ -2626,8 +2626,8 @@ add_child_rel_equivalences(PlannerInfo *root,
26262626
child_expr= (Expr*)
26272627
adjust_appendrel_attrs_multilevel(root,
26282628
(Node*)cur_em->em_expr,
2629-
child_relids,
2630-
top_parent_relids);
2629+
child_rel,
2630+
child_rel->top_parent);
26312631
}
26322632

26332633
/*
@@ -2768,8 +2768,8 @@ add_child_join_rel_equivalences(PlannerInfo *root,
27682768
child_expr= (Expr*)
27692769
adjust_appendrel_attrs_multilevel(root,
27702770
(Node*)cur_em->em_expr,
2771-
child_relids,
2772-
top_parent_relids);
2771+
child_joinrel,
2772+
child_joinrel->top_parent);
27732773
}
27742774

27752775
/*
@@ -2791,8 +2791,8 @@ add_child_join_rel_equivalences(PlannerInfo *root,
27912791
new_nullable_relids=
27922792
adjust_child_relids_multilevel(root,
27932793
new_nullable_relids,
2794-
child_relids,
2795-
top_parent_relids);
2794+
child_joinrel,
2795+
child_joinrel->top_parent);
27962796

27972797
(void)add_eq_member(cur_ec,child_expr,
27982798
new_relids,new_nullable_relids,

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,8 +1793,8 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
17931793
withCheckOptions= (List*)
17941794
adjust_appendrel_attrs_multilevel(root,
17951795
(Node*)withCheckOptions,
1796-
this_result_rel->relids,
1797-
top_result_rel->relids);
1796+
this_result_rel,
1797+
top_result_rel);
17981798
withCheckOptionLists=lappend(withCheckOptionLists,
17991799
withCheckOptions);
18001800
}
@@ -1806,8 +1806,8 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
18061806
returningList= (List*)
18071807
adjust_appendrel_attrs_multilevel(root,
18081808
(Node*)returningList,
1809-
this_result_rel->relids,
1810-
top_result_rel->relids);
1809+
this_result_rel,
1810+
top_result_rel);
18111811
returningLists=lappend(returningLists,
18121812
returningList);
18131813
}
@@ -1828,13 +1828,13 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
18281828
leaf_action->qual=
18291829
adjust_appendrel_attrs_multilevel(root,
18301830
(Node*)action->qual,
1831-
this_result_rel->relids,
1832-
top_result_rel->relids);
1831+
this_result_rel,
1832+
top_result_rel);
18331833
leaf_action->targetList= (List*)
18341834
adjust_appendrel_attrs_multilevel(root,
18351835
(Node*)action->targetList,
1836-
this_result_rel->relids,
1837-
top_result_rel->relids);
1836+
this_result_rel,
1837+
top_result_rel);
18381838
if (leaf_action->commandType==CMD_UPDATE)
18391839
leaf_action->updateColnos=
18401840
adjust_inherited_attnums_multilevel(root,

‎src/backend/optimizer/util/appendinfo.c

Lines changed: 37 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -479,39 +479,34 @@ adjust_appendrel_attrs_mutator(Node *node,
479479

480480
/*
481481
* adjust_appendrel_attrs_multilevel
482-
* Apply Var translations froma toplevel appendrel parent down to a child.
482+
* Apply Var translations froman appendrel parent down to a child.
483483
*
484-
* In some cases we need to translate expressions referencing a parent relation
485-
* to reference an appendrel child that's multiple levels removed from it.
484+
* Replace Vars in the "node" expression that reference "parentrel" with
485+
* the appropriate Vars for "childrel". childrel can be more than one
486+
* inheritance level removed from parentrel.
486487
*/
487488
Node*
488489
adjust_appendrel_attrs_multilevel(PlannerInfo*root,Node*node,
489-
Relidschild_relids,
490-
Relidstop_parent_relids)
490+
RelOptInfo*childrel,
491+
RelOptInfo*parentrel)
491492
{
492493
AppendRelInfo**appinfos;
493-
Bitmapset*parent_relids=NULL;
494494
intnappinfos;
495-
intcnt;
496-
497-
Assert(bms_num_members(child_relids)==bms_num_members(top_parent_relids));
498-
499-
appinfos=find_appinfos_by_relids(root,child_relids,&nappinfos);
500495

501-
/*Construct relids set for theimmediate parentof given child. */
502-
for (cnt=0;cnt<nappinfos;cnt++)
496+
/*Recurse ifimmediate parentis not the top parent. */
497+
if (childrel->parent!=parentrel)
503498
{
504-
AppendRelInfo*appinfo=appinfos[cnt];
505-
506-
parent_relids=bms_add_member(parent_relids,appinfo->parent_relid);
499+
if (childrel->parent)
500+
node=adjust_appendrel_attrs_multilevel(root,node,
501+
childrel->parent,
502+
parentrel);
503+
else
504+
elog(ERROR,"childrel is not a child of parentrel");
507505
}
508506

509-
/* Recurse if immediate parent is not the top parent. */
510-
if (!bms_equal(parent_relids,top_parent_relids))
511-
node=adjust_appendrel_attrs_multilevel(root,node,parent_relids,
512-
top_parent_relids);
507+
/* Now translate for this child. */
508+
appinfos=find_appinfos_by_relids(root,childrel->relids,&nappinfos);
513509

514-
/* Now translate for this child */
515510
node=adjust_appendrel_attrs(root,node,nappinfos,appinfos);
516511

517512
pfree(appinfos);
@@ -554,56 +549,43 @@ adjust_child_relids(Relids relids, int nappinfos, AppendRelInfo **appinfos)
554549
}
555550

556551
/*
557-
* Replace any relid present in top_parent_relids with its child in
558-
* child_relids. Members of child_relids can be multiple levels below top
559-
* parent in the partition hierarchy.
552+
* Substitute child's relids for parent's relids in a Relid set.
553+
* The childrel can be multiple inheritance levels below the parent.
560554
*/
561555
Relids
562556
adjust_child_relids_multilevel(PlannerInfo*root,Relidsrelids,
563-
Relidschild_relids,Relidstop_parent_relids)
557+
RelOptInfo*childrel,
558+
RelOptInfo*parentrel)
564559
{
565560
AppendRelInfo**appinfos;
566561
intnappinfos;
567-
Relidsparent_relids=NULL;
568-
Relidsresult;
569-
Relidstmp_result=NULL;
570-
intcnt;
571562

572563
/*
573-
* If the given relids set doesn't contain any of thetopparent relids,
574-
*itwill remain unchanged.
564+
* If the given relids set doesn't contain any of the parent relids, it
565+
* will remain unchanged.
575566
*/
576-
if (!bms_overlap(relids,top_parent_relids))
567+
if (!bms_overlap(relids,parentrel->relids))
577568
returnrelids;
578569

579-
appinfos=find_appinfos_by_relids(root,child_relids,&nappinfos);
580-
581-
/* Construct relids set for the immediate parent of the given child. */
582-
for (cnt=0;cnt<nappinfos;cnt++)
583-
{
584-
AppendRelInfo*appinfo=appinfos[cnt];
585-
586-
parent_relids=bms_add_member(parent_relids,appinfo->parent_relid);
587-
}
588-
589570
/* Recurse if immediate parent is not the top parent. */
590-
if (!bms_equal(parent_relids,top_parent_relids))
571+
if (childrel->parent!=parentrel)
591572
{
592-
tmp_result=adjust_child_relids_multilevel(root,relids,
593-
parent_relids,
594-
top_parent_relids);
595-
relids=tmp_result;
573+
if (childrel->parent)
574+
relids=adjust_child_relids_multilevel(root,relids,
575+
childrel->parent,
576+
parentrel);
577+
else
578+
elog(ERROR,"childrel is not a child of parentrel");
596579
}
597580

598-
result=adjust_child_relids(relids,nappinfos,appinfos);
581+
/* Now translate for this child. */
582+
appinfos=find_appinfos_by_relids(root,childrel->relids,&nappinfos);
583+
584+
relids=adjust_child_relids(relids,nappinfos,appinfos);
599585

600-
/* Free memory consumed by any intermediate result. */
601-
if (tmp_result)
602-
bms_free(tmp_result);
603-
bms_free(parent_relids);
604586
pfree(appinfos);
605587

606-
returnresult;
588+
returnrelids;
607589
}
608590

609591
/*
@@ -694,8 +676,8 @@ get_translated_update_targetlist(PlannerInfo *root, Index relid,
694676
*processed_tlist= (List*)
695677
adjust_appendrel_attrs_multilevel(root,
696678
(Node*)root->processed_tlist,
697-
bms_make_singleton(relid),
698-
bms_make_singleton(root->parse->resultRelation));
679+
find_base_rel(root,relid),
680+
find_base_rel(root,root->parse->resultRelation));
699681
if (update_colnos)
700682
*update_colnos=
701683
adjust_inherited_attnums_multilevel(root,root->update_colnos,

‎src/backend/optimizer/util/pathnode.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4026,8 +4026,8 @@ reparameterize_path_by_child(PlannerInfo *root, Path *path,
40264026
#defineADJUST_CHILD_ATTRS(node) \
40274027
((node) = \
40284028
(List *) adjust_appendrel_attrs_multilevel(root, (Node *) (node), \
4029-
child_rel->relids, \
4030-
child_rel->top_parent_relids))
4029+
child_rel, \
4030+
child_rel->top_parent))
40314031

40324032
#defineREPARAMETERIZE_CHILD_PATH(path) \
40334033
do { \
@@ -4244,8 +4244,8 @@ do { \
42444244
old_ppi=new_path->param_info;
42454245
required_outer=
42464246
adjust_child_relids_multilevel(root,old_ppi->ppi_req_outer,
4247-
child_rel->relids,
4248-
child_rel->top_parent_relids);
4247+
child_rel,
4248+
child_rel->top_parent);
42494249

42504250
/* If we already have a PPI for this parameterization, just return it */
42514251
new_ppi=find_param_path_info(new_path->parent,required_outer);

‎src/backend/optimizer/util/relnode.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,10 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
265265
*/
266266
if (parent)
267267
{
268-
/*
269-
* Each direct or indirect child wants to know the relids of its
270-
* topmost parent.
271-
*/
272-
if (parent->top_parent_relids)
273-
rel->top_parent_relids=parent->top_parent_relids;
274-
else
275-
rel->top_parent_relids=bms_copy(parent->relids);
268+
/* We keep back-links to immediate parent and topmost parent. */
269+
rel->parent=parent;
270+
rel->top_parent=parent->top_parent ?parent->top_parent :parent;
271+
rel->top_parent_relids=rel->top_parent->relids;
276272

277273
/*
278274
* Also propagate lateral-reference information from appendrel parent
@@ -294,6 +290,8 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
294290
}
295291
else
296292
{
293+
rel->parent=NULL;
294+
rel->top_parent=NULL;
297295
rel->top_parent_relids=NULL;
298296
rel->direct_lateral_relids=NULL;
299297
rel->lateral_relids=NULL;
@@ -663,6 +661,8 @@ build_join_rel(PlannerInfo *root,
663661
joinrel->joininfo=NIL;
664662
joinrel->has_eclass_joins= false;
665663
joinrel->consider_partitionwise_join= false;/* might get changed later */
664+
joinrel->parent=NULL;
665+
joinrel->top_parent=NULL;
666666
joinrel->top_parent_relids=NULL;
667667
joinrel->part_scheme=NULL;
668668
joinrel->nparts=-1;
@@ -843,7 +843,9 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
843843
joinrel->joininfo=NIL;
844844
joinrel->has_eclass_joins= false;
845845
joinrel->consider_partitionwise_join= false;/* might get changed later */
846-
joinrel->top_parent_relids=NULL;
846+
joinrel->parent=parent_joinrel;
847+
joinrel->top_parent=parent_joinrel->top_parent ?parent_joinrel->top_parent :parent_joinrel;
848+
joinrel->top_parent_relids=joinrel->top_parent->relids;
847849
joinrel->part_scheme=NULL;
848850
joinrel->nparts=-1;
849851
joinrel->boundinfo=NULL;
@@ -855,9 +857,6 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
855857
joinrel->partexprs=NULL;
856858
joinrel->nullable_partexprs=NULL;
857859

858-
joinrel->top_parent_relids=bms_union(outer_rel->top_parent_relids,
859-
inner_rel->top_parent_relids);
860-
861860
/* Compute information relevant to foreign relations. */
862861
set_foreign_rel_properties(joinrel,outer_rel,inner_rel);
863862

‎src/backend/partitioning/partprune.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,8 +529,8 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
529529
partprunequal= (List*)
530530
adjust_appendrel_attrs_multilevel(root,
531531
(Node*)prunequal,
532-
subpart->relids,
533-
targetpart->relids);
532+
subpart,
533+
targetpart);
534534
}
535535

536536
/*

‎src/include/nodes/pathnodes.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,15 @@ typedef struct RelOptInfo
938938
*/
939939
/* consider partitionwise join paths? (if partitioned rel) */
940940
boolconsider_partitionwise_join;
941-
/* Relids of topmost parents (if "other" rel) */
941+
942+
/*
943+
* inheritance links, if this is an otherrel (otherwise NULL):
944+
*/
945+
/* Immediate parent relation (dumping it would be too verbose) */
946+
structRelOptInfo*parentpg_node_attr(read_write_ignore);
947+
/* Topmost parent relation (dumping it would be too verbose) */
948+
structRelOptInfo*top_parentpg_node_attr(read_write_ignore);
949+
/* Relids of topmost parent (redundant, but handy) */
942950
Relidstop_parent_relids;
943951

944952
/*

‎src/include/optimizer/appendinfo.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ extern AppendRelInfo *make_append_rel_info(Relation parentrel,
2323
externNode*adjust_appendrel_attrs(PlannerInfo*root,Node*node,
2424
intnappinfos,AppendRelInfo**appinfos);
2525
externNode*adjust_appendrel_attrs_multilevel(PlannerInfo*root,Node*node,
26-
Relidschild_relids,
27-
Relidstop_parent_relids);
26+
RelOptInfo*childrel,
27+
RelOptInfo*parentrel);
2828
externRelidsadjust_child_relids(Relidsrelids,intnappinfos,
2929
AppendRelInfo**appinfos);
3030
externRelidsadjust_child_relids_multilevel(PlannerInfo*root,Relidsrelids,
31-
Relidschild_relids,
32-
Relidstop_parent_relids);
31+
RelOptInfo*childrel,
32+
RelOptInfo*parentrel);
3333
externList*adjust_inherited_attnums(List*attnums,AppendRelInfo*context);
3434
externList*adjust_inherited_attnums_multilevel(PlannerInfo*root,
3535
List*attnums,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp