@@ -42,7 +42,7 @@ static List *select_mergejoin_clauses(PlannerInfo *root,
42
42
RelOptInfo *innerrel,
43
43
List *restrictlist,
44
44
JoinType jointype,
45
- bool *have_nonmergeable_clause );
45
+ bool *mergejoin_allowed );
46
46
47
47
48
48
/*
@@ -78,7 +78,7 @@ add_paths_to_joinrel(PlannerInfo *root,
78
78
List *restrictlist)
79
79
{
80
80
List *mergeclause_list = NIL;
81
- bool have_nonmergeable_clause = false ;
81
+ bool mergejoin_allowed = true ;
82
82
83
83
/*
84
84
* Find potential mergejoin clauses. We can skip this if we are not
@@ -93,13 +93,13 @@ add_paths_to_joinrel(PlannerInfo *root,
93
93
innerrel,
94
94
restrictlist,
95
95
jointype,
96
- &have_nonmergeable_clause );
96
+ &mergejoin_allowed );
97
97
98
98
/*
99
99
* 1. Consider mergejoin paths where both relations must be explicitly
100
100
* sorted. Skip this if we can't mergejoin.
101
101
*/
102
- if (!have_nonmergeable_clause )
102
+ if (mergejoin_allowed )
103
103
sort_inner_and_outer(root, joinrel, outerrel, innerrel,
104
104
restrictlist, mergeclause_list, jointype, sjinfo);
105
105
@@ -108,9 +108,9 @@ add_paths_to_joinrel(PlannerInfo *root,
108
108
* sorted. This includes both nestloops and mergejoins where the outer
109
109
* path is already ordered. Again, skip this if we can't mergejoin.
110
110
* (That's okay because we know that nestloop can't handle right/full
111
- * joins at all, so it wouldn't work in those cases either.)
111
+ * joins at all, so it wouldn't work in the prohibited cases either.)
112
112
*/
113
- if (!have_nonmergeable_clause )
113
+ if (mergejoin_allowed )
114
114
match_unsorted_outer(root, joinrel, outerrel, innerrel,
115
115
restrictlist, mergeclause_list, jointype, sjinfo);
116
116
@@ -127,7 +127,7 @@ add_paths_to_joinrel(PlannerInfo *root,
127
127
* those made by match_unsorted_outer when add_paths_to_joinrel() is
128
128
* invoked with the two rels given in the other order.
129
129
*/
130
- if (!have_nonmergeable_clause )
130
+ if (mergejoin_allowed )
131
131
match_unsorted_inner(root, joinrel, outerrel, innerrel,
132
132
restrictlist, mergeclause_list, jointype, sjinfo);
133
133
#endif
@@ -927,10 +927,14 @@ best_appendrel_indexscan(PlannerInfo *root, RelOptInfo *rel,
927
927
* Select mergejoin clauses that are usable for a particular join.
928
928
* Returns a list of RestrictInfo nodes for those clauses.
929
929
*
930
- * *have_nonmergeable_clause is set TRUE if this is a right/full join and
931
- * there are nonmergejoinable join clauses. The executor's mergejoin
932
- * machinery cannot handle such cases, so we have to avoid generating a
933
- * mergejoin plan.
930
+ * *mergejoin_allowed is normally set to TRUE, but it is set to FALSE if
931
+ * this is a right/full join and there are nonmergejoinable join clauses.
932
+ * The executor's mergejoin machinery cannot handle such cases, so we have
933
+ * to avoid generating a mergejoin plan. (Note that this flag does NOT
934
+ * consider whether there are actually any mergejoinable clauses. This is
935
+ * correct because in some cases we need to build a clauseless mergejoin.
936
+ * Simply returning NIL is therefore not enough to distinguish safe from
937
+ * unsafe cases.)
934
938
*
935
939
* We also mark each selected RestrictInfo to show which side is currently
936
940
* being considered as outer. These are transient markings that are only
@@ -947,22 +951,21 @@ select_mergejoin_clauses(PlannerInfo *root,
947
951
RelOptInfo *innerrel,
948
952
List *restrictlist,
949
953
JoinType jointype,
950
- bool *have_nonmergeable_clause )
954
+ bool *mergejoin_allowed )
951
955
{
952
956
List *result_list = NIL;
953
957
bool isouterjoin = IS_OUTER_JOIN(jointype);
958
+ bool have_nonmergeable_joinclause = false;
954
959
ListCell *l;
955
960
956
- *have_nonmergeable_clause = false;
957
-
958
961
foreach(l, restrictlist)
959
962
{
960
963
RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
961
964
962
965
/*
963
966
* If processing an outer join, only use its own join clauses in the
964
967
* merge. For inner joins we can use pushed-down clauses too. (Note:
965
- * we don't set have_nonmergeable_clause here because pushed-down
968
+ * we don't set have_nonmergeable_joinclause here because pushed-down
966
969
* clauses will become otherquals not joinquals.)
967
970
*/
968
971
if (isouterjoin && restrictinfo->is_pushed_down)
@@ -979,7 +982,7 @@ select_mergejoin_clauses(PlannerInfo *root,
979
982
* FALSE.)
980
983
*/
981
984
if (!restrictinfo->clause || !IsA(restrictinfo->clause, Const))
982
- *have_nonmergeable_clause = true;
985
+ have_nonmergeable_joinclause = true;
983
986
continue; /* not mergejoinable */
984
987
}
985
988
@@ -988,7 +991,7 @@ select_mergejoin_clauses(PlannerInfo *root,
988
991
*/
989
992
if (!clause_sides_match_join(restrictinfo, outerrel, innerrel))
990
993
{
991
- *have_nonmergeable_clause = true;
994
+ have_nonmergeable_joinclause = true;
992
995
continue; /* no good for these input relations */
993
996
}
994
997
@@ -1017,26 +1020,24 @@ select_mergejoin_clauses(PlannerInfo *root,
1017
1020
if (EC_MUST_BE_REDUNDANT(restrictinfo->left_ec) ||
1018
1021
EC_MUST_BE_REDUNDANT(restrictinfo->right_ec))
1019
1022
{
1020
- *have_nonmergeable_clause = true;
1023
+ have_nonmergeable_joinclause = true;
1021
1024
continue; /* can't handle redundant eclasses */
1022
1025
}
1023
1026
1024
1027
result_list = lappend(result_list, restrictinfo);
1025
1028
}
1026
1029
1027
1030
/*
1028
- * If it is not a right/full join then we don't need to insist on all the
1029
- * joinclauses being mergejoinable, so reset the flag. This simplifies
1030
- * the logic in add_paths_to_joinrel.
1031
+ * Report whether mergejoin is allowed (see comment at top of function).
1031
1032
*/
1032
1033
switch (jointype)
1033
1034
{
1034
1035
case JOIN_RIGHT:
1035
1036
case JOIN_FULL:
1037
+ *mergejoin_allowed = !have_nonmergeable_joinclause;
1036
1038
break;
1037
1039
default:
1038
- /* otherwise, it's OK to have nonmergeable join quals */
1039
- *have_nonmergeable_clause = false;
1040
+ *mergejoin_allowed = true;
1040
1041
break;
1041
1042
}
1042
1043
0 commit comments