mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-11-21 03:13:05 +08:00
Do not translate dummy SpecialJoinInfos for child joins
This teaches build_child_join_sjinfo() to create the dummy SpecialJoinInfos (those created for inner joins) directly for a given child join, skipping the unnecessary overhead of translating the parent joinrel's SpecialJoinInfo. To that end, this commit moves the code to initialize the dummy SpecialJoinInfos to a new function named init_dummy_sjinfo() and changes the few existing sites that have this code and build_child_join_sjinfo() to call this new function. Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Reviewed-by: Richard Guo <guofenglinux@gmail.com> Reviewed-by: Amit Langote <amitlangote09@gmail.com> Reviewed-by: Andrey Lepikhov <a.lepikhov@postgrespro.ru> Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com> Discussion: https://postgr.es/m/CAExHW5tHqEf3ASVqvFFcghYGPfpy7o3xnvhHwBGbJFMRH8KjNw@mail.gmail.com
This commit is contained in:
parent
5278d0a2e8
commit
6190d828cd
@ -5050,23 +5050,7 @@ compute_semi_anti_join_factors(PlannerInfo *root,
|
|||||||
/*
|
/*
|
||||||
* Also get the normal inner-join selectivity of the join clauses.
|
* Also get the normal inner-join selectivity of the join clauses.
|
||||||
*/
|
*/
|
||||||
norm_sjinfo.type = T_SpecialJoinInfo;
|
init_dummy_sjinfo(&norm_sjinfo, outerrel->relids, innerrel->relids);
|
||||||
norm_sjinfo.min_lefthand = outerrel->relids;
|
|
||||||
norm_sjinfo.min_righthand = innerrel->relids;
|
|
||||||
norm_sjinfo.syn_lefthand = outerrel->relids;
|
|
||||||
norm_sjinfo.syn_righthand = innerrel->relids;
|
|
||||||
norm_sjinfo.jointype = JOIN_INNER;
|
|
||||||
norm_sjinfo.ojrelid = 0;
|
|
||||||
norm_sjinfo.commute_above_l = NULL;
|
|
||||||
norm_sjinfo.commute_above_r = NULL;
|
|
||||||
norm_sjinfo.commute_below_l = NULL;
|
|
||||||
norm_sjinfo.commute_below_r = NULL;
|
|
||||||
/* we don't bother trying to make the remaining fields valid */
|
|
||||||
norm_sjinfo.lhs_strict = false;
|
|
||||||
norm_sjinfo.semi_can_btree = false;
|
|
||||||
norm_sjinfo.semi_can_hash = false;
|
|
||||||
norm_sjinfo.semi_operators = NIL;
|
|
||||||
norm_sjinfo.semi_rhs_exprs = NIL;
|
|
||||||
|
|
||||||
nselec = clauselist_selectivity(root,
|
nselec = clauselist_selectivity(root,
|
||||||
joinquals,
|
joinquals,
|
||||||
@ -5219,23 +5203,8 @@ approx_tuple_count(PlannerInfo *root, JoinPath *path, List *quals)
|
|||||||
/*
|
/*
|
||||||
* Make up a SpecialJoinInfo for JOIN_INNER semantics.
|
* Make up a SpecialJoinInfo for JOIN_INNER semantics.
|
||||||
*/
|
*/
|
||||||
sjinfo.type = T_SpecialJoinInfo;
|
init_dummy_sjinfo(&sjinfo, path->outerjoinpath->parent->relids,
|
||||||
sjinfo.min_lefthand = path->outerjoinpath->parent->relids;
|
path->innerjoinpath->parent->relids);
|
||||||
sjinfo.min_righthand = path->innerjoinpath->parent->relids;
|
|
||||||
sjinfo.syn_lefthand = path->outerjoinpath->parent->relids;
|
|
||||||
sjinfo.syn_righthand = path->innerjoinpath->parent->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;
|
|
||||||
|
|
||||||
/* Get the approximate selectivity */
|
/* Get the approximate selectivity */
|
||||||
foreach(l, quals)
|
foreach(l, quals)
|
||||||
|
@ -654,6 +654,38 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_dummy_sjinfo
|
||||||
|
* Populate the given SpecialJoinInfo for a plain inner join between rel1
|
||||||
|
* and rel2
|
||||||
|
*
|
||||||
|
* Normally, an inner join does not have a SpecialJoinInfo node associated with
|
||||||
|
* it. But some functions involved in join planning require one containing at
|
||||||
|
* least the information of which relations are being joined. So we initialize
|
||||||
|
* that information here.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
init_dummy_sjinfo(SpecialJoinInfo *sjinfo, Relids left_relids,
|
||||||
|
Relids right_relids)
|
||||||
|
{
|
||||||
|
sjinfo->type = T_SpecialJoinInfo;
|
||||||
|
sjinfo->min_lefthand = left_relids;
|
||||||
|
sjinfo->min_righthand = right_relids;
|
||||||
|
sjinfo->syn_lefthand = left_relids;
|
||||||
|
sjinfo->syn_righthand = right_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;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* make_join_rel
|
* make_join_rel
|
||||||
@ -717,23 +749,7 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
|
|||||||
if (sjinfo == NULL)
|
if (sjinfo == NULL)
|
||||||
{
|
{
|
||||||
sjinfo = &sjinfo_data;
|
sjinfo = &sjinfo_data;
|
||||||
sjinfo->type = T_SpecialJoinInfo;
|
init_dummy_sjinfo(sjinfo, rel1->relids, rel2->relids);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1682,6 +1698,14 @@ build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo,
|
|||||||
AppendRelInfo **right_appinfos;
|
AppendRelInfo **right_appinfos;
|
||||||
int right_nappinfos;
|
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));
|
memcpy(sjinfo, parent_sjinfo, sizeof(SpecialJoinInfo));
|
||||||
left_appinfos = find_appinfos_by_relids(root, left_relids,
|
left_appinfos = find_appinfos_by_relids(root, left_relids,
|
||||||
&left_nappinfos);
|
&left_nappinfos);
|
||||||
|
@ -112,6 +112,8 @@ extern bool have_join_order_restriction(PlannerInfo *root,
|
|||||||
extern bool have_dangerous_phv(PlannerInfo *root,
|
extern bool have_dangerous_phv(PlannerInfo *root,
|
||||||
Relids outer_relids, Relids inner_params);
|
Relids outer_relids, Relids inner_params);
|
||||||
extern void mark_dummy_rel(RelOptInfo *rel);
|
extern void mark_dummy_rel(RelOptInfo *rel);
|
||||||
|
extern void init_dummy_sjinfo(SpecialJoinInfo *sjinfo, Relids left_relids,
|
||||||
|
Relids right_relids);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* equivclass.c
|
* equivclass.c
|
||||||
|
Loading…
Reference in New Issue
Block a user