256{
259 orig_selec;
260
261 /*
262 * Build a RestrictInfo from the new OR clause. We can assume it's valid
263 * as a base restriction clause.
264 */
266 orclause,
267 true,
268 false,
269 false,
270 false,
272 NULL,
273 NULL,
274 NULL);
275
276 /*
277 * Estimate its selectivity. (We could have done this earlier, but doing
278 * it on the RestrictInfo representation allows the result to get cached,
279 * saving work later.)
280 */
283
284 /*
285 * The clause is only worth adding to the query if it rejects a useful
286 * fraction of the base relation's rows; otherwise, it's just going to
287 * cause duplicate computation (since we will still have to check the
288 * original OR clause when the join is formed). Somewhat arbitrarily, we
289 * set the selectivity threshold at 0.9.
290 */
291 if (or_selec > 0.9)
292 return; /* forget it */
293
294 /*
295 * OK, add it to the rel's restriction-clause list.
296 */
300
301 /*
302 * Adjust the original join OR clause's cached selectivity to compensate
303 * for the selectivity of the added (but redundant) lower-level qual. This
304 * should result in the join rel getting approximately the same rows
305 * estimate as it would have gotten without all these shenanigans.
306 *
307 * XXX major hack alert: this depends on the assumption that the
308 * selectivity will stay cached.
309 *
310 * XXX another major hack: we adjust only norm_selec, the cached
311 * selectivity for JOIN_INNER semantics, even though the join clause
312 * might've been an outer-join clause. This is partly because we can't
313 * easily identify the relevant SpecialJoinInfo here, and partly because
314 * the linearity assumption we're making would fail anyway. (If it is an
315 * outer-join clause, "rel" must be on the nullable side, else we'd not
316 * have gotten here. So the computation of the join size is going to be
317 * quite nonlinear with respect to the size of "rel", so it's not clear
318 * how we ought to adjust outer_selec even if we could compute its
319 * original value correctly.)
320 */
321 if (or_selec > 0)
322 {
324
325 /*
326 * Make up a SpecialJoinInfo for JOIN_INNER semantics. (Compare
327 * approx_tuple_count() in costsize.c.)
328 */
333
334 /* Compute inner-join size */
337
338 /* And hack cached selectivity so join size remains the same */
339 join_or_rinfo->norm_selec = orig_selec / or_selec;
340 /* ensure result stays in sane range */
341 if (join_or_rinfo->norm_selec > 1)
342 join_or_rinfo->norm_selec = 1;
343 /* as explained above, we don't touch outer_selec */
344 }
345}
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
Selectivity clause_selectivity(PlannerInfo *root, Node *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
void init_dummy_sjinfo(SpecialJoinInfo *sjinfo, Relids left_relids, Relids right_relids)
List * lappend(List *list, void *datum)
RestrictInfo * make_restrictinfo(PlannerInfo *root, Expr *clause, bool is_pushed_down, bool has_clone, bool is_clone, bool pseudoconstant, Index security_level, Relids required_relids, Relids incompatible_relids, Relids outer_relids)
Index baserestrict_min_security