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

Commitc44c47a

Browse files
committed
Some preliminary refactoring towards partitionwise join.
Partitionwise join proposes add a concept of child join relations,which will have the same relationship with join relations as "othermember" relations do with base relations. These relations will needsome but not all of the handling that we currently have for joinrelations, and some but not all of the handling that we currently havefor appendrels, since they are a mix of the two. Refactor a littlebit so that the necessary bits of logic are exposed as separatefunctions.Ashutosh Bapat, reviewed and tested by Rajkumar Raghuwanshi andby me.Discussion:http://postgr.es/m/CAFjFpRfqotRR6cM3sooBHMHEVdkFfAZ6PyYg4GRZsoMuW08HjQ@mail.gmail.com
1 parent60f826c commitc44c47a

File tree

3 files changed

+149
-73
lines changed

3 files changed

+149
-73
lines changed

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

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ static void subquery_push_qual(Query *subquery,
129129
staticvoidrecurse_push_qual(Node*setOp,Query*topquery,
130130
RangeTblEntry*rte,Indexrti,Node*qual);
131131
staticvoidremove_unused_subquery_outputs(Query*subquery,RelOptInfo*rel);
132+
staticvoidadd_paths_to_append_rel(PlannerInfo*root,RelOptInfo*rel,
133+
List*live_childrels);
132134

133135

134136
/*
@@ -1182,27 +1184,18 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
11821184
{
11831185
intparentRTindex=rti;
11841186
List*live_childrels=NIL;
1185-
List*subpaths=NIL;
1186-
boolsubpaths_valid= true;
1187-
List*partial_subpaths=NIL;
1188-
boolpartial_subpaths_valid= true;
1189-
List*all_child_pathkeys=NIL;
1190-
List*all_child_outers=NIL;
11911187
ListCell*l;
11921188

11931189
/*
11941190
* Generate access paths for each member relation, and remember the
1195-
* cheapest path for each one. Also, identify all pathkeys (orderings)
1196-
* and parameterizations (required_outer sets) available for the member
1197-
* relations.
1191+
* non-dummy children.
11981192
*/
11991193
foreach(l,root->append_rel_list)
12001194
{
12011195
AppendRelInfo*appinfo= (AppendRelInfo*)lfirst(l);
12021196
intchildRTindex;
12031197
RangeTblEntry*childRTE;
12041198
RelOptInfo*childrel;
1205-
ListCell*lcp;
12061199

12071200
/* append_rel_list contains all append rels; ignore others */
12081201
if (appinfo->parent_relid!=parentRTindex)
@@ -1237,6 +1230,45 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
12371230
* Child is live, so add it to the live_childrels list for use below.
12381231
*/
12391232
live_childrels=lappend(live_childrels,childrel);
1233+
}
1234+
1235+
/* Add paths to the "append" relation. */
1236+
add_paths_to_append_rel(root,rel,live_childrels);
1237+
}
1238+
1239+
1240+
/*
1241+
* add_paths_to_append_rel
1242+
*Generate paths for given "append" relation given the set of non-dummy
1243+
*child rels.
1244+
*
1245+
* The function collects all parameterizations and orderings supported by the
1246+
* non-dummy children. For every such parameterization or ordering, it creates
1247+
* an append path collecting one path from each non-dummy child with given
1248+
* parameterization or ordering. Similarly it collects partial paths from
1249+
* non-dummy children to create partial append paths.
1250+
*/
1251+
staticvoid
1252+
add_paths_to_append_rel(PlannerInfo*root,RelOptInfo*rel,
1253+
List*live_childrels)
1254+
{
1255+
List*subpaths=NIL;
1256+
boolsubpaths_valid= true;
1257+
List*partial_subpaths=NIL;
1258+
boolpartial_subpaths_valid= true;
1259+
List*all_child_pathkeys=NIL;
1260+
List*all_child_outers=NIL;
1261+
ListCell*l;
1262+
1263+
/*
1264+
* For every non-dummy child, remember the cheapest path. Also, identify
1265+
* all pathkeys (orderings) and parameterizations (required_outer sets)
1266+
* available for the non-dummy member relations.
1267+
*/
1268+
foreach(l,live_childrels)
1269+
{
1270+
RelOptInfo*childrel=lfirst(l);
1271+
ListCell*lcp;
12401272

12411273
/*
12421274
* If child has an unparameterized cheapest-total path, add that to

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

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ static bool is_dummy_rel(RelOptInfo *rel);
3232
staticvoidmark_dummy_rel(RelOptInfo*rel);
3333
staticboolrestriction_is_constant_false(List*restrictlist,
3434
boolonly_pushed_down);
35+
staticvoidpopulate_joinrel_with_paths(PlannerInfo*root,RelOptInfo*rel1,
36+
RelOptInfo*rel2,RelOptInfo*joinrel,
37+
SpecialJoinInfo*sjinfo,List*restrictlist);
3538

3639

3740
/*
@@ -724,6 +727,27 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
724727
returnjoinrel;
725728
}
726729

730+
/* Add paths to the join relation. */
731+
populate_joinrel_with_paths(root,rel1,rel2,joinrel,sjinfo,
732+
restrictlist);
733+
734+
bms_free(joinrelids);
735+
736+
returnjoinrel;
737+
}
738+
739+
/*
740+
* populate_joinrel_with_paths
741+
* Add paths to the given joinrel for given pair of joining relations. The
742+
* SpecialJoinInfo provides details about the join and the restrictlist
743+
* contains the join clauses and the other clauses applicable for given pair
744+
* of the joining relations.
745+
*/
746+
staticvoid
747+
populate_joinrel_with_paths(PlannerInfo*root,RelOptInfo*rel1,
748+
RelOptInfo*rel2,RelOptInfo*joinrel,
749+
SpecialJoinInfo*sjinfo,List*restrictlist)
750+
{
727751
/*
728752
* Consider paths using each rel as both outer and inner. Depending on
729753
* the join type, a provably empty outer or inner rel might mean the join
@@ -868,10 +892,6 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
868892
elog(ERROR,"unrecognized join type: %d", (int)sjinfo->jointype);
869893
break;
870894
}
871-
872-
bms_free(joinrelids);
873-
874-
returnjoinrel;
875895
}
876896

877897

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

Lines changed: 83 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ static List *subbuild_joinrel_restrictlist(RelOptInfo *joinrel,
4949
staticList*subbuild_joinrel_joinlist(RelOptInfo*joinrel,
5050
List*joininfo_list,
5151
List*new_joininfo);
52+
staticvoidset_foreign_rel_properties(RelOptInfo*joinrel,
53+
RelOptInfo*outer_rel,RelOptInfo*inner_rel);
54+
staticvoidadd_join_rel(PlannerInfo*root,RelOptInfo*joinrel);
5255

5356

5457
/*
@@ -327,6 +330,82 @@ find_join_rel(PlannerInfo *root, Relids relids)
327330
returnNULL;
328331
}
329332

333+
/*
334+
* set_foreign_rel_properties
335+
*Set up foreign-join fields if outer and inner relation are foreign
336+
*tables (or joins) belonging to the same server and assigned to the same
337+
*user to check access permissions as.
338+
*
339+
* In addition to an exact match of userid, we allow the case where one side
340+
* has zero userid (implying current user) and the other side has explicit
341+
* userid that happens to equal the current user; but in that case, pushdown of
342+
* the join is only valid for the current user. The useridiscurrent field
343+
* records whether we had to make such an assumption for this join or any
344+
* sub-join.
345+
*
346+
* Otherwise these fields are left invalid, so GetForeignJoinPaths will not be
347+
* called for the join relation.
348+
*
349+
*/
350+
staticvoid
351+
set_foreign_rel_properties(RelOptInfo*joinrel,RelOptInfo*outer_rel,
352+
RelOptInfo*inner_rel)
353+
{
354+
if (OidIsValid(outer_rel->serverid)&&
355+
inner_rel->serverid==outer_rel->serverid)
356+
{
357+
if (inner_rel->userid==outer_rel->userid)
358+
{
359+
joinrel->serverid=outer_rel->serverid;
360+
joinrel->userid=outer_rel->userid;
361+
joinrel->useridiscurrent=outer_rel->useridiscurrent||inner_rel->useridiscurrent;
362+
joinrel->fdwroutine=outer_rel->fdwroutine;
363+
}
364+
elseif (!OidIsValid(inner_rel->userid)&&
365+
outer_rel->userid==GetUserId())
366+
{
367+
joinrel->serverid=outer_rel->serverid;
368+
joinrel->userid=outer_rel->userid;
369+
joinrel->useridiscurrent= true;
370+
joinrel->fdwroutine=outer_rel->fdwroutine;
371+
}
372+
elseif (!OidIsValid(outer_rel->userid)&&
373+
inner_rel->userid==GetUserId())
374+
{
375+
joinrel->serverid=outer_rel->serverid;
376+
joinrel->userid=inner_rel->userid;
377+
joinrel->useridiscurrent= true;
378+
joinrel->fdwroutine=outer_rel->fdwroutine;
379+
}
380+
}
381+
}
382+
383+
/*
384+
* add_join_rel
385+
*Add given join relation to the list of join relations in the given
386+
*PlannerInfo. Also add it to the auxiliary hashtable if there is one.
387+
*/
388+
staticvoid
389+
add_join_rel(PlannerInfo*root,RelOptInfo*joinrel)
390+
{
391+
/* GEQO requires us to append the new joinrel to the end of the list! */
392+
root->join_rel_list=lappend(root->join_rel_list,joinrel);
393+
394+
/* store it into the auxiliary hashtable if there is one. */
395+
if (root->join_rel_hash)
396+
{
397+
JoinHashEntry*hentry;
398+
boolfound;
399+
400+
hentry= (JoinHashEntry*)hash_search(root->join_rel_hash,
401+
&(joinrel->relids),
402+
HASH_ENTER,
403+
&found);
404+
Assert(!found);
405+
hentry->join_rel=joinrel;
406+
}
407+
}
408+
330409
/*
331410
* build_join_rel
332411
* Returns relation entry corresponding to the union of two given rels,
@@ -425,46 +504,8 @@ build_join_rel(PlannerInfo *root,
425504
joinrel->joininfo=NIL;
426505
joinrel->has_eclass_joins= false;
427506

428-
/*
429-
* Set up foreign-join fields if outer and inner relation are foreign
430-
* tables (or joins) belonging to the same server and assigned to the same
431-
* user to check access permissions as. In addition to an exact match of
432-
* userid, we allow the case where one side has zero userid (implying
433-
* current user) and the other side has explicit userid that happens to
434-
* equal the current user; but in that case, pushdown of the join is only
435-
* valid for the current user. The useridiscurrent field records whether
436-
* we had to make such an assumption for this join or any sub-join.
437-
*
438-
* Otherwise these fields are left invalid, so GetForeignJoinPaths will
439-
* not be called for the join relation.
440-
*/
441-
if (OidIsValid(outer_rel->serverid)&&
442-
inner_rel->serverid==outer_rel->serverid)
443-
{
444-
if (inner_rel->userid==outer_rel->userid)
445-
{
446-
joinrel->serverid=outer_rel->serverid;
447-
joinrel->userid=outer_rel->userid;
448-
joinrel->useridiscurrent=outer_rel->useridiscurrent||inner_rel->useridiscurrent;
449-
joinrel->fdwroutine=outer_rel->fdwroutine;
450-
}
451-
elseif (!OidIsValid(inner_rel->userid)&&
452-
outer_rel->userid==GetUserId())
453-
{
454-
joinrel->serverid=outer_rel->serverid;
455-
joinrel->userid=outer_rel->userid;
456-
joinrel->useridiscurrent= true;
457-
joinrel->fdwroutine=outer_rel->fdwroutine;
458-
}
459-
elseif (!OidIsValid(outer_rel->userid)&&
460-
inner_rel->userid==GetUserId())
461-
{
462-
joinrel->serverid=outer_rel->serverid;
463-
joinrel->userid=inner_rel->userid;
464-
joinrel->useridiscurrent= true;
465-
joinrel->fdwroutine=outer_rel->fdwroutine;
466-
}
467-
}
507+
/* Compute information relevant to the foreign relations. */
508+
set_foreign_rel_properties(joinrel,outer_rel,inner_rel);
468509

469510
/*
470511
* Create a new tlist containing just the vars that need to be output from
@@ -532,25 +573,8 @@ build_join_rel(PlannerInfo *root,
532573
is_parallel_safe(root, (Node*)joinrel->reltarget->exprs))
533574
joinrel->consider_parallel= true;
534575

535-
/*
536-
* Add the joinrel to the query's joinrel list, and store it into the
537-
* auxiliary hashtable if there is one. NB: GEQO requires us to append
538-
* the new joinrel to the end of the list!
539-
*/
540-
root->join_rel_list=lappend(root->join_rel_list,joinrel);
541-
542-
if (root->join_rel_hash)
543-
{
544-
JoinHashEntry*hentry;
545-
boolfound;
546-
547-
hentry= (JoinHashEntry*)hash_search(root->join_rel_hash,
548-
&(joinrel->relids),
549-
HASH_ENTER,
550-
&found);
551-
Assert(!found);
552-
hentry->join_rel=joinrel;
553-
}
576+
/* Add the joinrel to the PlannerInfo. */
577+
add_join_rel(root,joinrel);
554578

555579
/*
556580
* Also, if dynamic-programming join search is active, add the new joinrel

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp