@@ -1043,23 +1043,23 @@ min_join_parameterization(PlannerInfo *root,
1043
1043
* two joins had been done in syntactic order; else they won't match Vars
1044
1044
* appearing higher in the query tree. We need to do two things:
1045
1045
*
1046
- * First, sjinfo->commute_above_r is added to the nulling bitmaps of RHS Vars.
1047
- * This takes care of the case where we implement
1046
+ * First, we add the outer join's relid to the nulling bitmap only if the Var
1047
+ * or PHV actually comes from within the syntactically nullable side(s) of the
1048
+ * outer join. This takes care of the possibility that we have transformed
1049
+ * (A leftjoin B on (Pab)) leftjoin C on (Pbc)
1050
+ * to
1051
+ * A leftjoin (B leftjoin C on (Pbc)) on (Pab)
1052
+ * Here the now-upper A/B join must not mark C columns as nulled by itself.
1053
+ *
1054
+ * Second, if sjinfo->commute_above_r is already part of the joinrel then
1055
+ * it is added to the nulling bitmaps of nullable Vars. This takes care of
1056
+ * the reverse case where we implement
1048
1057
* A leftjoin (B leftjoin C on (Pbc)) on (Pab)
1049
1058
* as
1050
1059
* (A leftjoin B on (Pab)) leftjoin C on (Pbc)
1051
1060
* The C columns emitted by the B/C join need to be shown as nulled by both
1052
- * the B/C and A/B joins, even though they've not traversed the A/B join.
1053
- * (If the joins haven't been commuted, we are adding the nullingrel bits
1054
- * prematurely; but that's okay because the C columns can't be referenced
1055
- * between here and the upper join.)
1056
- *
1057
- * Second, if a RHS Var has any of the relids in sjinfo->commute_above_l
1058
- * already set in its nulling bitmap, then we *don't* add sjinfo->ojrelid
1059
- * to its nulling bitmap (but we do still add commute_above_r). This takes
1060
- * care of the reverse transformation: if the original syntax was
1061
- * (A leftjoin B on (Pab)) leftjoin C on (Pbc)
1062
- * then the now-upper A/B join must not mark C columns as nulled by itself.
1061
+ * the B/C and A/B joins, even though they've not physically traversed the
1062
+ * A/B join.
1063
1063
*/
1064
1064
static void
1065
1065
build_joinrel_tlist (PlannerInfo * root , RelOptInfo * joinrel ,
@@ -1095,10 +1095,12 @@ build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel,
1095
1095
phv = copyObject (phv );
1096
1096
/* See comments above to understand this logic */
1097
1097
if (sjinfo -> ojrelid != 0 &&
1098
- !bms_overlap (phv -> phnullingrels , sjinfo -> commute_above_l ))
1098
+ (bms_is_subset (phv -> phrels , sjinfo -> syn_righthand ) ||
1099
+ (sjinfo -> jointype == JOIN_FULL &&
1100
+ bms_is_subset (phv -> phrels , sjinfo -> syn_lefthand ))))
1099
1101
phv -> phnullingrels = bms_add_member (phv -> phnullingrels ,
1100
1102
sjinfo -> ojrelid );
1101
- if (sjinfo -> commute_above_r )
1103
+ if (bms_overlap ( sjinfo -> commute_above_r , joinrel -> relids ) )
1102
1104
phv -> phnullingrels = bms_add_members (phv -> phnullingrels ,
1103
1105
sjinfo -> commute_above_r );
1104
1106
}
@@ -1149,17 +1151,20 @@ build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel,
1149
1151
/*
1150
1152
* Add the Var to the output. If this join potentially nulls this
1151
1153
* input, we have to update the Var's varnullingrels, which means
1152
- * making a copy.
1154
+ * making a copy. But note that we don't ever add nullingrel bits to
1155
+ * row identity Vars (cf. comments in setrefs.c).
1153
1156
*/
1154
- if (can_null )
1157
+ if (can_null && var -> varno != ROWID_VAR )
1155
1158
{
1156
1159
var = copyObject (var );
1157
1160
/* See comments above to understand this logic */
1158
1161
if (sjinfo -> ojrelid != 0 &&
1159
- !bms_overlap (var -> varnullingrels , sjinfo -> commute_above_l ))
1162
+ (bms_is_member (var -> varno , sjinfo -> syn_righthand ) ||
1163
+ (sjinfo -> jointype == JOIN_FULL &&
1164
+ bms_is_member (var -> varno , sjinfo -> syn_lefthand ))))
1160
1165
var -> varnullingrels = bms_add_member (var -> varnullingrels ,
1161
1166
sjinfo -> ojrelid );
1162
- if (sjinfo -> commute_above_r )
1167
+ if (bms_overlap ( sjinfo -> commute_above_r , joinrel -> relids ) )
1163
1168
var -> varnullingrels = bms_add_members (var -> varnullingrels ,
1164
1169
sjinfo -> commute_above_r );
1165
1170
}
0 commit comments