Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/optimizer/path/costsize.c37
-rw-r--r--src/backend/optimizer/path/joinrels.c58
2 files changed, 44 insertions, 51 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 3c14c605a07..ee23ed7835d 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -5050,23 +5050,7 @@ compute_semi_anti_join_factors(PlannerInfo *root,
/*
* Also get the normal inner-join selectivity of the join clauses.
*/
- norm_sjinfo.type = T_SpecialJoinInfo;
- 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;
+ init_dummy_sjinfo(&norm_sjinfo, outerrel->relids, innerrel->relids);
nselec = clauselist_selectivity(root,
joinquals,
@@ -5219,23 +5203,8 @@ approx_tuple_count(PlannerInfo *root, JoinPath *path, List *quals)
/*
* Make up a SpecialJoinInfo for JOIN_INNER semantics.
*/
- sjinfo.type = T_SpecialJoinInfo;
- sjinfo.min_lefthand = path->outerjoinpath->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;
+ init_dummy_sjinfo(&sjinfo, path->outerjoinpath->parent->relids,
+ path->innerjoinpath->parent->relids);
/* Get the approximate selectivity */
foreach(l, quals)
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index c59aff28226..17ef825a345 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -654,6 +654,38 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
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
@@ -717,23 +749,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);
}
/*
@@ -1682,6 +1698,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);