@@ -109,6 +109,7 @@ static void distribute_quals_to_rels(PlannerInfo *root, List *clauses,
109
109
Relids qualscope ,
110
110
Relids ojscope ,
111
111
Relids outerjoin_nonnullable ,
112
+ Relids incompatible_relids ,
112
113
bool allow_equivalence ,
113
114
bool has_clone ,
114
115
bool is_clone ,
@@ -120,6 +121,7 @@ static void distribute_qual_to_rels(PlannerInfo *root, Node *clause,
120
121
Relids qualscope ,
121
122
Relids ojscope ,
122
123
Relids outerjoin_nonnullable ,
124
+ Relids incompatible_relids ,
123
125
bool allow_equivalence ,
124
126
bool has_clone ,
125
127
bool is_clone ,
@@ -1132,7 +1134,8 @@ deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem)
1132
1134
jtitem ,
1133
1135
NULL ,
1134
1136
root -> qual_security_level ,
1135
- jtitem -> qualscope , NULL , NULL ,
1137
+ jtitem -> qualscope ,
1138
+ NULL , NULL , NULL ,
1136
1139
true, false, false,
1137
1140
NULL );
1138
1141
@@ -1143,7 +1146,8 @@ deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem)
1143
1146
jtitem ,
1144
1147
NULL ,
1145
1148
root -> qual_security_level ,
1146
- jtitem -> qualscope , NULL , NULL ,
1149
+ jtitem -> qualscope ,
1150
+ NULL , NULL , NULL ,
1147
1151
true, false, false,
1148
1152
NULL );
1149
1153
}
@@ -1226,6 +1230,7 @@ deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem)
1226
1230
root -> qual_security_level ,
1227
1231
jtitem -> qualscope ,
1228
1232
ojscope , jtitem -> nonnullable_rels ,
1233
+ NULL , /* incompatible_relids */
1229
1234
true, /* allow_equivalence */
1230
1235
false, false, /* not clones */
1231
1236
postponed_oj_qual_list );
@@ -1285,6 +1290,7 @@ process_security_barrier_quals(PlannerInfo *root,
1285
1290
jtitem -> qualscope ,
1286
1291
jtitem -> qualscope ,
1287
1292
NULL ,
1293
+ NULL ,
1288
1294
true,
1289
1295
false, false, /* not clones */
1290
1296
NULL );
@@ -1887,6 +1893,7 @@ deconstruct_distribute_oj_quals(PlannerInfo *root,
1887
1893
{
1888
1894
Relids joins_above ;
1889
1895
Relids joins_below ;
1896
+ Relids incompatible_joins ;
1890
1897
Relids joins_so_far ;
1891
1898
List * quals ;
1892
1899
int save_last_rinfo_serial ;
@@ -1920,6 +1927,15 @@ deconstruct_distribute_oj_quals(PlannerInfo *root,
1920
1927
joins_below ,
1921
1928
NULL );
1922
1929
1930
+ /*
1931
+ * We'll need to mark the lower versions of the quals as not safe to
1932
+ * apply above not-yet-processed joins of the stack. This prevents
1933
+ * possibly applying a cloned qual at the wrong join level.
1934
+ */
1935
+ incompatible_joins = bms_union (joins_below , joins_above );
1936
+ incompatible_joins = bms_add_member (incompatible_joins ,
1937
+ sjinfo -> ojrelid );
1938
+
1923
1939
/*
1924
1940
* Each time we produce RestrictInfo(s) from these quals, reset the
1925
1941
* last_rinfo_serial counter, so that the RestrictInfos for the "same"
@@ -1979,13 +1995,19 @@ deconstruct_distribute_oj_quals(PlannerInfo *root,
1979
1995
* relation B will appear nulled by the syntactically-upper OJ
1980
1996
* within the Pbc clause, but those of relation C will not. (In
1981
1997
* the notation used by optimizer/README, we're converting a qual
1982
- * of the form Pbc to Pb*c.)
1998
+ * of the form Pbc to Pb*c.) Of course, we must also remove that
1999
+ * bit from the incompatible_joins value, else we'll make a qual
2000
+ * that can't be placed anywhere.
1983
2001
*/
1984
2002
if (above_sjinfo )
2003
+ {
1985
2004
quals = (List * )
1986
2005
add_nulling_relids ((Node * ) quals ,
1987
2006
sjinfo -> syn_lefthand ,
1988
2007
bms_make_singleton (othersj -> ojrelid ));
2008
+ incompatible_joins = bms_del_member (incompatible_joins ,
2009
+ othersj -> ojrelid );
2010
+ }
1989
2011
1990
2012
/* Compute qualscope and ojscope for this join level */
1991
2013
this_qualscope = bms_union (qualscope , joins_so_far );
@@ -2027,6 +2049,7 @@ deconstruct_distribute_oj_quals(PlannerInfo *root,
2027
2049
root -> qual_security_level ,
2028
2050
this_qualscope ,
2029
2051
this_ojscope , nonnullable_rels ,
2052
+ bms_copy (incompatible_joins ),
2030
2053
allow_equivalence ,
2031
2054
has_clone ,
2032
2055
is_clone ,
@@ -2039,13 +2062,17 @@ deconstruct_distribute_oj_quals(PlannerInfo *root,
2039
2062
* Vars coming from the lower join's RHS. (Again, we are
2040
2063
* converting a qual of the form Pbc to Pb*c, but now we are
2041
2064
* putting back bits that were there in the parser output and were
2042
- * temporarily stripped above.)
2065
+ * temporarily stripped above.) Update incompatible_joins too.
2043
2066
*/
2044
2067
if (below_sjinfo )
2068
+ {
2045
2069
quals = (List * )
2046
2070
add_nulling_relids ((Node * ) quals ,
2047
2071
othersj -> syn_righthand ,
2048
2072
bms_make_singleton (othersj -> ojrelid ));
2073
+ incompatible_joins = bms_del_member (incompatible_joins ,
2074
+ othersj -> ojrelid );
2075
+ }
2049
2076
2050
2077
/* ... and track joins processed so far */
2051
2078
joins_so_far = bms_add_member (joins_so_far , othersj -> ojrelid );
@@ -2060,6 +2087,7 @@ deconstruct_distribute_oj_quals(PlannerInfo *root,
2060
2087
root -> qual_security_level ,
2061
2088
qualscope ,
2062
2089
ojscope , nonnullable_rels ,
2090
+ NULL , /* incompatible_relids */
2063
2091
true, /* allow_equivalence */
2064
2092
false, false, /* not clones */
2065
2093
NULL ); /* no more postponement */
@@ -2086,6 +2114,7 @@ distribute_quals_to_rels(PlannerInfo *root, List *clauses,
2086
2114
Relids qualscope ,
2087
2115
Relids ojscope ,
2088
2116
Relids outerjoin_nonnullable ,
2117
+ Relids incompatible_relids ,
2089
2118
bool allow_equivalence ,
2090
2119
bool has_clone ,
2091
2120
bool is_clone ,
@@ -2104,6 +2133,7 @@ distribute_quals_to_rels(PlannerInfo *root, List *clauses,
2104
2133
qualscope ,
2105
2134
ojscope ,
2106
2135
outerjoin_nonnullable ,
2136
+ incompatible_relids ,
2107
2137
allow_equivalence ,
2108
2138
has_clone ,
2109
2139
is_clone ,
@@ -2135,6 +2165,9 @@ distribute_quals_to_rels(PlannerInfo *root, List *clauses,
2135
2165
* base+OJ rels appearing on the outer (nonnullable) side of the join
2136
2166
* (for FULL JOIN this includes both sides of the join, and must in fact
2137
2167
* equal qualscope)
2168
+ * 'incompatible_relids': the set of outer-join relid(s) that must not be
2169
+ * computed below this qual. We only bother to compute this for
2170
+ * "clone" quals, otherwise it can be left NULL.
2138
2171
* 'allow_equivalence': true if it's okay to convert clause into an
2139
2172
* EquivalenceClass
2140
2173
* 'has_clone': has_clone property to assign to the qual
@@ -2159,6 +2192,7 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
2159
2192
Relids qualscope ,
2160
2193
Relids ojscope ,
2161
2194
Relids outerjoin_nonnullable ,
2195
+ Relids incompatible_relids ,
2162
2196
bool allow_equivalence ,
2163
2197
bool has_clone ,
2164
2198
bool is_clone ,
@@ -2377,15 +2411,14 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
2377
2411
restrictinfo = make_restrictinfo (root ,
2378
2412
(Expr * ) clause ,
2379
2413
is_pushed_down ,
2414
+ has_clone ,
2415
+ is_clone ,
2380
2416
pseudoconstant ,
2381
2417
security_level ,
2382
2418
relids ,
2419
+ incompatible_relids ,
2383
2420
outerjoin_nonnullable );
2384
2421
2385
- /* Apply appropriate clone marking, too */
2386
- restrictinfo -> has_clone = has_clone ;
2387
- restrictinfo -> is_clone = is_clone ;
2388
-
2389
2422
/*
2390
2423
* If it's a join clause, add vars used in the clause to targetlists of
2391
2424
* their relations, so that they will be emitted by the plan nodes that
@@ -2750,9 +2783,12 @@ process_implied_equality(PlannerInfo *root,
2750
2783
restrictinfo = make_restrictinfo (root ,
2751
2784
(Expr * ) clause ,
2752
2785
true, /* is_pushed_down */
2786
+ false, /* !has_clone */
2787
+ false, /* !is_clone */
2753
2788
pseudoconstant ,
2754
2789
security_level ,
2755
2790
relids ,
2791
+ NULL , /* incompatible_relids */
2756
2792
NULL ); /* outer_relids */
2757
2793
2758
2794
/*
@@ -2841,9 +2877,12 @@ build_implied_join_equality(PlannerInfo *root,
2841
2877
restrictinfo = make_restrictinfo (root ,
2842
2878
clause ,
2843
2879
true, /* is_pushed_down */
2880
+ false, /* !has_clone */
2881
+ false, /* !is_clone */
2844
2882
false, /* pseudoconstant */
2845
2883
security_level , /* security_level */
2846
2884
qualscope , /* required_relids */
2885
+ NULL , /* incompatible_relids */
2847
2886
NULL ); /* outer_relids */
2848
2887
2849
2888
/* Set mergejoinability/hashjoinability flags */
0 commit comments