Skip to content

Commit

Permalink
Refresh upstream code copy with update_copied_funcs.pl
Browse files Browse the repository at this point in the history
This is required for the next release, to be in sync with the planner
code pg_hint_plan depends on.

Backpatch-through: 17
  • Loading branch information
michaelpq committed Aug 20, 2024
1 parent 3c0464f commit 6a1f91a
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 66 deletions.
121 changes: 75 additions & 46 deletions core.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
/*
* Except for the topmost scan/join rel, consider gathering
* partial paths. We'll do the same for the topmost scan/join rel
* once we know the final targetlist (see grouping_planner).
* once we know the final targetlist (see grouping_planner's and
* its call to apply_scanjoin_target_to_paths).
*/
if (!bms_equal(rel->relids, root->all_query_rels))
generate_useful_gather_paths(root, rel, false);
Expand All @@ -178,7 +179,7 @@ standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
set_cheapest(rel);

#ifdef OPTIMIZER_DEBUG
debug_print_rel(root, rel);
pprint(rel);
#endif
}
}
Expand Down Expand Up @@ -258,6 +259,8 @@ join_search_one_level(PlannerInfo *root, int level)
if (old_rel->joininfo != NIL || old_rel->has_eclass_joins ||
has_join_restriction(root, old_rel))
{
int first_rel;

/*
* There are join clauses or join order restrictions relevant to
* this rel, so consider joins between this rel and (only) those
Expand All @@ -271,24 +274,12 @@ join_search_one_level(PlannerInfo *root, int level)
* to each initial rel they don't already include but have a join
* clause or restriction with.
*/
List *other_rels_list;
ListCell *other_rels;

if (level == 2) /* consider remaining initial rels */
{
other_rels_list = joinrels[level - 1];
other_rels = lnext(other_rels_list, r);
}
else /* consider all initial rels */
{
other_rels_list = joinrels[1];
other_rels = list_head(other_rels_list);
}
first_rel = foreach_current_index(r) + 1;
else
first_rel = 0;

make_rels_by_clause_joins(root,
old_rel,
other_rels_list,
other_rels);
make_rels_by_clause_joins(root, old_rel, joinrels[1], first_rel);
}
else
{
Expand Down Expand Up @@ -332,8 +323,7 @@ join_search_one_level(PlannerInfo *root, int level)
foreach(r, joinrels[k])
{
RelOptInfo *old_rel = (RelOptInfo *) lfirst(r);
List *other_rels_list;
ListCell *other_rels;
int first_rel;
ListCell *r2;

/*
Expand All @@ -345,19 +335,12 @@ join_search_one_level(PlannerInfo *root, int level)
!has_join_restriction(root, old_rel))
continue;

if (k == other_level)
{
/* only consider remaining rels */
other_rels_list = joinrels[k];
other_rels = lnext(other_rels_list, r);
}
if (k == other_level) /* only consider remaining rels */
first_rel = foreach_current_index(r) + 1;
else
{
other_rels_list = joinrels[other_level];
other_rels = list_head(other_rels_list);
}
first_rel = 0;

for_each_cell(r2, other_rels_list, other_rels)
for_each_from(r2, joinrels[other_level], first_rel)
{
RelOptInfo *new_rel = (RelOptInfo *) lfirst(r2);

Expand Down Expand Up @@ -452,22 +435,21 @@ join_search_one_level(PlannerInfo *root, int level)
* automatically ensures that each new joinrel is only added to the list once.
*
* 'old_rel' is the relation entry for the relation to be joined
* 'other_rels_list': a list containing the other
* rels to be considered for joining
* 'other_rels': the first cell to be considered
* 'other_rels': a list containing the other rels to be considered for joining
* 'first_rel_idx': the first rel to be considered in 'other_rels'
*
* Currently, this is only used with initial rels in other_rels, but it
* will work for joining to joinrels too.
*/
static void
make_rels_by_clause_joins(PlannerInfo *root,
RelOptInfo *old_rel,
List *other_rels_list,
ListCell *other_rels)
List *other_rels,
int first_rel_idx)
{
ListCell *l;

for_each_cell(l, other_rels_list, other_rels)
for_each_from(l, other_rels, first_rel_idx)
{
RelOptInfo *other_rel = (RelOptInfo *) lfirst(l);

Expand Down Expand Up @@ -942,6 +924,9 @@ restriction_is_constant_false(List *restrictlist,
* Construct the SpecialJoinInfo for a child-join by translating
* SpecialJoinInfo for the join between parents. left_relids and right_relids
* are the relids of left and right side of the join respectively.
*
* If translations are added to or removed from this function, consider
* updating free_child_join_sjinfo() accordingly.
*/
static SpecialJoinInfo *
build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo,
Expand All @@ -953,6 +938,14 @@ build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo,
AppendRelInfo **right_appinfos;
int right_nappinfos;

/* Dummy SpecialJoinInfos can be created without any translation. */
if (parent_sjinfo->jointype == JOIN_INNER)
{
Assert(parent_sjinfo->ojrelid == 0);
init_dummy_sjinfo(sjinfo, left_relids, right_relids);
return sjinfo;
}

memcpy(sjinfo, parent_sjinfo, sizeof(SpecialJoinInfo));
left_appinfos = find_appinfos_by_relids(root, left_relids,
&left_nappinfos);
Expand Down Expand Up @@ -1260,7 +1253,6 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
SpecialJoinInfo *child_sjinfo;
List *child_restrictlist;
RelOptInfo *child_joinrel;
Relids child_joinrelids;
AppendRelInfo **appinfos;
int nappinfos;

Expand Down Expand Up @@ -1357,13 +1349,11 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
child_rel1->relids,
child_rel2->relids);

/* Build correct join relids for child join */
child_joinrelids = bms_union(child_rel1->relids, child_rel2->relids);
child_joinrelids = add_outer_joins_to_relids(root, child_joinrelids,
child_sjinfo, NULL);

/* Find the AppendRelInfo structures */
appinfos = find_appinfos_by_relids(root, child_joinrelids, &nappinfos);
appinfos = find_appinfos_by_relids(root,
bms_union(child_rel1->relids,
child_rel2->relids),
&nappinfos);

/*
* Construct restrictions applicable to the child join from those
Expand All @@ -1373,8 +1363,8 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
(List *) adjust_appendrel_attrs(root,
(Node *) parent_restrictlist,
nappinfos, appinfos);
pfree(appinfos);

/* Find or construct the child join's RelOptInfo */
child_joinrel = joinrel->part_rels[cnt_parts];
if (!child_joinrel)
{
Expand All @@ -1387,10 +1377,49 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
child_joinrel->relids);
}

Assert(bms_equal(child_joinrel->relids, child_joinrelids));
/* Assert we got the right one */
Assert(bms_equal(child_joinrel->relids,
adjust_child_relids(joinrel->relids,
nappinfos, appinfos)));

/* And make paths for the child join */
populate_joinrel_with_paths(root, child_rel1, child_rel2,
child_joinrel, child_sjinfo,
child_restrictlist);

pfree(appinfos);
free_child_join_sjinfo(child_sjinfo);
}
}


/*
* free_child_join_sjinfo
* Free memory consumed by a SpecialJoinInfo created by
* build_child_join_sjinfo()
*
* Only members that are translated copies of their counterpart in the parent
* SpecialJoinInfo are freed here.
*/
static void
free_child_join_sjinfo(SpecialJoinInfo *sjinfo)
{
/*
* Dummy SpecialJoinInfos of inner joins do not have any translated fields
* and hence no fields that to be freed.
*/
if (sjinfo->jointype != JOIN_INNER)
{
bms_free(sjinfo->min_lefthand);
bms_free(sjinfo->min_righthand);
bms_free(sjinfo->syn_lefthand);
bms_free(sjinfo->syn_righthand);

/*
* semi_rhs_exprs may in principle be freed, but a simple pfree() does
* not suffice, so we leave it alone.
*/
}

pfree(sjinfo);
}
18 changes: 1 addition & 17 deletions make_join_rel.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,23 +112,7 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
if (sjinfo == NULL)
{
sjinfo = &sjinfo_data;
sjinfo->type = T_SpecialJoinInfo;
sjinfo->min_lefthand = rel1->relids;
sjinfo->min_righthand = rel2->relids;
sjinfo->syn_lefthand = rel1->relids;
sjinfo->syn_righthand = rel2->relids;
sjinfo->jointype = JOIN_INNER;
sjinfo->ojrelid = 0;
sjinfo->commute_above_l = NULL;
sjinfo->commute_above_r = NULL;
sjinfo->commute_below_l = NULL;
sjinfo->commute_below_r = NULL;
/* we don't bother trying to make the remaining fields valid */
sjinfo->lhs_strict = false;
sjinfo->semi_can_btree = false;
sjinfo->semi_can_hash = false;
sjinfo->semi_operators = NIL;
sjinfo->semi_rhs_exprs = NIL;
init_dummy_sjinfo(sjinfo, rel1->relids, rel2->relids);
}

/*
Expand Down
5 changes: 3 additions & 2 deletions pg_hint_plan.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,14 +493,15 @@ void pg_hint_plan_set_rel_pathlist(PlannerInfo * root, RelOptInfo *rel,
static void create_plain_partial_paths(PlannerInfo *root,
RelOptInfo *rel);
static void make_rels_by_clause_joins(PlannerInfo *root, RelOptInfo *old_rel,
List *other_rels_list,
ListCell *other_rels);
List *other_rels,
int first_rel_idx);
static void make_rels_by_clauseless_joins(PlannerInfo *root,
RelOptInfo *old_rel,
List *other_rels);
static bool has_join_restriction(PlannerInfo *root, RelOptInfo *rel);
static void set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
RangeTblEntry *rte);
static void free_child_join_sjinfo(SpecialJoinInfo *sjinfo);
RelOptInfo *pg_hint_plan_make_join_rel(PlannerInfo *root, RelOptInfo *rel1,
RelOptInfo *rel2);

Expand Down
3 changes: 2 additions & 1 deletion update_copied_funcs.pl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
'build_child_join_sjinfo',
'get_matching_part_pairs',
'compute_partition_bounds',
'try_partitionwise_join'],
'try_partitionwise_join',
'free_child_join_sjinfo'],
head => core_c_head()},
'make_join_rel.c'
=> {protos => [],
Expand Down

0 comments on commit 6a1f91a

Please sign in to comment.