1 /*-------------------------------------------------------------------------
4 * RestrictInfo node manipulation routines.
6 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
13 *-------------------------------------------------------------------------
17 #include "optimizer/clauses.h"
18 #include "optimizer/cost.h"
19 #include "optimizer/paths.h"
20 #include "optimizer/predtest.h"
21 #include "optimizer/restrictinfo.h"
22 #include "optimizer/var.h"
25 static RestrictInfo
*make_restrictinfo_internal(Expr
*clause
,
28 bool outerjoin_delayed
,
30 Relids required_relids
,
31 Relids nullable_relids
);
32 static Expr
*make_sub_restrictinfos(Expr
*clause
,
34 bool outerjoin_delayed
,
36 Relids required_relids
,
37 Relids nullable_relids
);
38 static List
*select_nonredundant_join_list(List
*restrictinfo_list
,
39 List
*reference_list
);
40 static bool join_clause_is_redundant(RestrictInfo
*rinfo
,
41 List
*reference_list
);
47 * Build a RestrictInfo node containing the given subexpression.
49 * The is_pushed_down, outerjoin_delayed, and pseudoconstant flags for the
50 * RestrictInfo must be supplied by the caller, as well as the correct value
51 * for nullable_relids. required_relids can be NULL, in which case it
52 * defaults to the actual clause contents (i.e., clause_relids).
54 * We initialize fields that depend only on the given subexpression, leaving
55 * others that depend on context (or may never be needed at all) to be filled
59 make_restrictinfo(Expr
*clause
,
61 bool outerjoin_delayed
,
63 Relids required_relids
,
64 Relids nullable_relids
)
67 * If it's an OR clause, build a modified copy with RestrictInfos inserted
68 * above each subclause of the top-level AND/OR structure.
70 if (or_clause((Node
*) clause
))
71 return (RestrictInfo
*) make_sub_restrictinfos(clause
,
78 /* Shouldn't be an AND clause, else AND/OR flattening messed up */
79 Assert(!and_clause((Node
*) clause
));
81 return make_restrictinfo_internal(clause
,
91 * make_restrictinfo_from_bitmapqual
93 * Given the bitmapqual Path structure for a bitmap indexscan, generate
94 * RestrictInfo node(s) equivalent to the condition represented by the
95 * indexclauses of the Path structure.
97 * The result is a List (effectively, implicit-AND representation) of
100 * The caller must pass is_pushed_down, but we assume outerjoin_delayed
101 * and pseudoconstant are false and nullable_relids is NULL (no other
102 * kind of qual should ever get into a bitmapqual).
104 * If include_predicates is true, we add any partial index predicates to
105 * the explicit index quals. When this is not true, we return a condition
106 * that might be weaker than the actual scan represents.
108 * To do this through the normal make_restrictinfo() API, callers would have
109 * to strip off the RestrictInfo nodes present in the indexclauses lists, and
110 * then make_restrictinfo() would have to build new ones. It's better to have
111 * a specialized routine to allow sharing of RestrictInfos.
113 * The qual manipulations here are much the same as in create_bitmap_subplan;
114 * keep the two routines in sync!
117 make_restrictinfo_from_bitmapqual(Path
*bitmapqual
,
119 bool include_predicates
)
124 if (IsA(bitmapqual
, BitmapAndPath
))
126 BitmapAndPath
*apath
= (BitmapAndPath
*) bitmapqual
;
129 * There may well be redundant quals among the subplans, since a
130 * top-level WHERE qual might have gotten used to form several
131 * different index quals. We don't try exceedingly hard to eliminate
132 * redundancies, but we do eliminate obvious duplicates by using
133 * list_concat_unique.
136 foreach(l
, apath
->bitmapquals
)
140 sublist
= make_restrictinfo_from_bitmapqual((Path
*) lfirst(l
),
143 result
= list_concat_unique(result
, sublist
);
146 else if (IsA(bitmapqual
, BitmapOrPath
))
148 BitmapOrPath
*opath
= (BitmapOrPath
*) bitmapqual
;
150 List
*withoutris
= NIL
;
153 * Here, we only detect qual-free subplans. A qual-free subplan would
154 * cause us to generate "... OR true ..." which we may as well reduce
155 * to just "true". We do not try to eliminate redundant subclauses
156 * because (a) it's not as likely as in the AND case, and (b) we might
157 * well be working with hundreds or even thousands of OR conditions,
158 * perhaps from a long IN list. The performance of list_append_unique
159 * would be unacceptable.
161 foreach(l
, opath
->bitmapquals
)
165 sublist
= make_restrictinfo_from_bitmapqual((Path
*) lfirst(l
),
171 * If we find a qual-less subscan, it represents a constant
172 * TRUE, and hence the OR result is also constant TRUE, so we
179 * If the sublist contains multiple RestrictInfos, we create an
180 * AND subclause. If there's just one, we have to check if it's
181 * an OR clause, and if so flatten it to preserve AND/OR flatness
184 * We construct lists with and without sub-RestrictInfos, so as
185 * not to have to regenerate duplicate RestrictInfos below.
187 if (list_length(sublist
) > 1)
189 withris
= lappend(withris
, make_andclause(sublist
));
190 sublist
= get_actual_clauses(sublist
);
191 withoutris
= lappend(withoutris
, make_andclause(sublist
));
195 RestrictInfo
*subri
= (RestrictInfo
*) linitial(sublist
);
197 Assert(IsA(subri
, RestrictInfo
));
198 if (restriction_is_or_clause(subri
))
200 BoolExpr
*subor
= (BoolExpr
*) subri
->orclause
;
202 Assert(or_clause((Node
*) subor
));
203 withris
= list_concat(withris
,
204 list_copy(subor
->args
));
205 subor
= (BoolExpr
*) subri
->clause
;
206 Assert(or_clause((Node
*) subor
));
207 withoutris
= list_concat(withoutris
,
208 list_copy(subor
->args
));
212 withris
= lappend(withris
, subri
);
213 withoutris
= lappend(withoutris
, subri
->clause
);
219 * Avoid generating one-element ORs, which could happen due to
220 * redundancy elimination or ScalarArrayOpExpr quals.
222 if (list_length(withris
) <= 1)
226 /* Here's the magic part not available to outside callers */
228 list_make1(make_restrictinfo_internal(make_orclause(withoutris
),
229 make_orclause(withris
),
237 else if (IsA(bitmapqual
, IndexPath
))
239 IndexPath
*ipath
= (IndexPath
*) bitmapqual
;
241 result
= list_copy(ipath
->indexclauses
);
242 if (include_predicates
&& ipath
->indexinfo
->indpred
!= NIL
)
244 foreach(l
, ipath
->indexinfo
->indpred
)
246 Expr
*pred
= (Expr
*) lfirst(l
);
249 * We know that the index predicate must have been implied by
250 * the query condition as a whole, but it may or may not be
251 * implied by the conditions that got pushed into the
252 * bitmapqual. Avoid generating redundant conditions.
254 if (!predicate_implied_by(list_make1(pred
), result
))
255 result
= lappend(result
,
256 make_restrictinfo(pred
,
267 elog(ERROR
, "unrecognized node type: %d", nodeTag(bitmapqual
));
268 result
= NIL
; /* keep compiler quiet */
275 * make_restrictinfo_internal
277 * Common code for the main entry points and the recursive cases.
279 static RestrictInfo
*
280 make_restrictinfo_internal(Expr
*clause
,
283 bool outerjoin_delayed
,
285 Relids required_relids
,
286 Relids nullable_relids
)
288 RestrictInfo
*restrictinfo
= makeNode(RestrictInfo
);
290 restrictinfo
->clause
= clause
;
291 restrictinfo
->orclause
= orclause
;
292 restrictinfo
->is_pushed_down
= is_pushed_down
;
293 restrictinfo
->outerjoin_delayed
= outerjoin_delayed
;
294 restrictinfo
->pseudoconstant
= pseudoconstant
;
295 restrictinfo
->can_join
= false; /* may get set below */
296 restrictinfo
->nullable_relids
= nullable_relids
;
299 * If it's a binary opclause, set up left/right relids info. In any case
300 * set up the total clause relids info.
302 if (is_opclause(clause
) && list_length(((OpExpr
*) clause
)->args
) == 2)
304 restrictinfo
->left_relids
= pull_varnos(get_leftop(clause
));
305 restrictinfo
->right_relids
= pull_varnos(get_rightop(clause
));
307 restrictinfo
->clause_relids
= bms_union(restrictinfo
->left_relids
,
308 restrictinfo
->right_relids
);
311 * Does it look like a normal join clause, i.e., a binary operator
312 * relating expressions that come from distinct relations? If so we
313 * might be able to use it in a join algorithm. Note that this is a
314 * purely syntactic test that is made regardless of context.
316 if (!bms_is_empty(restrictinfo
->left_relids
) &&
317 !bms_is_empty(restrictinfo
->right_relids
) &&
318 !bms_overlap(restrictinfo
->left_relids
,
319 restrictinfo
->right_relids
))
321 restrictinfo
->can_join
= true;
322 /* pseudoconstant should certainly not be true */
323 Assert(!restrictinfo
->pseudoconstant
);
328 /* Not a binary opclause, so mark left/right relid sets as empty */
329 restrictinfo
->left_relids
= NULL
;
330 restrictinfo
->right_relids
= NULL
;
331 /* and get the total relid set the hard way */
332 restrictinfo
->clause_relids
= pull_varnos((Node
*) clause
);
335 /* required_relids defaults to clause_relids */
336 if (required_relids
!= NULL
)
337 restrictinfo
->required_relids
= required_relids
;
339 restrictinfo
->required_relids
= restrictinfo
->clause_relids
;
342 * Fill in all the cacheable fields with "not yet set" markers. None of
343 * these will be computed until/unless needed. Note in particular that we
344 * don't mark a binary opclause as mergejoinable or hashjoinable here;
345 * that happens only if it appears in the right context (top level of a
348 restrictinfo
->parent_ec
= NULL
;
350 restrictinfo
->eval_cost
.startup
= -1;
351 restrictinfo
->norm_selec
= -1;
352 restrictinfo
->outer_selec
= -1;
354 restrictinfo
->mergeopfamilies
= NIL
;
356 restrictinfo
->left_ec
= NULL
;
357 restrictinfo
->right_ec
= NULL
;
358 restrictinfo
->left_em
= NULL
;
359 restrictinfo
->right_em
= NULL
;
360 restrictinfo
->scansel_cache
= NIL
;
362 restrictinfo
->outer_is_left
= false;
364 restrictinfo
->hashjoinoperator
= InvalidOid
;
366 restrictinfo
->left_bucketsize
= -1;
367 restrictinfo
->right_bucketsize
= -1;
373 * Recursively insert sub-RestrictInfo nodes into a boolean expression.
375 * We put RestrictInfos above simple (non-AND/OR) clauses and above
376 * sub-OR clauses, but not above sub-AND clauses, because there's no need.
377 * This may seem odd but it is closely related to the fact that we use
378 * implicit-AND lists at top level of RestrictInfo lists. Only ORs and
379 * simple clauses are valid RestrictInfos.
381 * The same is_pushed_down, outerjoin_delayed, and pseudoconstant flag
382 * values can be applied to all RestrictInfo nodes in the result. Likewise
383 * for nullable_relids.
385 * The given required_relids are attached to our top-level output,
386 * but any OR-clause constituents are allowed to default to just the
390 make_sub_restrictinfos(Expr
*clause
,
392 bool outerjoin_delayed
,
394 Relids required_relids
,
395 Relids nullable_relids
)
397 if (or_clause((Node
*) clause
))
402 foreach(temp
, ((BoolExpr
*) clause
)->args
)
403 orlist
= lappend(orlist
,
404 make_sub_restrictinfos(lfirst(temp
),
410 return (Expr
*) make_restrictinfo_internal(clause
,
411 make_orclause(orlist
),
418 else if (and_clause((Node
*) clause
))
423 foreach(temp
, ((BoolExpr
*) clause
)->args
)
424 andlist
= lappend(andlist
,
425 make_sub_restrictinfos(lfirst(temp
),
431 return make_andclause(andlist
);
434 return (Expr
*) make_restrictinfo_internal(clause
,
444 * restriction_is_or_clause
446 * Returns t iff the restrictinfo node contains an 'or' clause.
449 restriction_is_or_clause(RestrictInfo
*restrictinfo
)
451 if (restrictinfo
->orclause
!= NULL
)
460 * Returns a list containing the bare clauses from 'restrictinfo_list'.
462 * This is only to be used in cases where none of the RestrictInfos can
463 * be pseudoconstant clauses (for instance, it's OK on indexqual lists).
466 get_actual_clauses(List
*restrictinfo_list
)
471 foreach(l
, restrictinfo_list
)
473 RestrictInfo
*rinfo
= (RestrictInfo
*) lfirst(l
);
475 Assert(IsA(rinfo
, RestrictInfo
));
477 Assert(!rinfo
->pseudoconstant
);
479 result
= lappend(result
, rinfo
->clause
);
485 * extract_actual_clauses
487 * Extract bare clauses from 'restrictinfo_list', returning either the
488 * regular ones or the pseudoconstant ones per 'pseudoconstant'.
491 extract_actual_clauses(List
*restrictinfo_list
,
497 foreach(l
, restrictinfo_list
)
499 RestrictInfo
*rinfo
= (RestrictInfo
*) lfirst(l
);
501 Assert(IsA(rinfo
, RestrictInfo
));
503 if (rinfo
->pseudoconstant
== pseudoconstant
)
504 result
= lappend(result
, rinfo
->clause
);
510 * extract_actual_join_clauses
512 * Extract bare clauses from 'restrictinfo_list', separating those that
513 * syntactically match the join level from those that were pushed down.
514 * Pseudoconstant clauses are excluded from the results.
516 * This is only used at outer joins, since for plain joins we don't care
517 * about pushed-down-ness.
520 extract_actual_join_clauses(List
*restrictinfo_list
,
529 foreach(l
, restrictinfo_list
)
531 RestrictInfo
*rinfo
= (RestrictInfo
*) lfirst(l
);
533 Assert(IsA(rinfo
, RestrictInfo
));
535 if (rinfo
->is_pushed_down
)
537 if (!rinfo
->pseudoconstant
)
538 *otherquals
= lappend(*otherquals
, rinfo
->clause
);
542 /* joinquals shouldn't have been marked pseudoconstant */
543 Assert(!rinfo
->pseudoconstant
);
544 *joinquals
= lappend(*joinquals
, rinfo
->clause
);
551 * select_nonredundant_join_clauses
553 * Given a list of RestrictInfo clauses that are to be applied in a join,
554 * select the ones that are not redundant with any clause that's enforced
555 * by the inner_path. This is used for nestloop joins, wherein any clause
556 * being used in an inner indexscan need not be checked again at the join.
558 * "Redundant" means either equal() or derived from the same EquivalenceClass.
559 * We have to check the latter because indxqual.c may select different derived
560 * clauses than were selected by generate_join_implied_equalities().
562 * Note that we are *not* checking for local redundancies within the given
563 * restrictinfo_list; that should have been handled elsewhere.
566 select_nonredundant_join_clauses(PlannerInfo
*root
,
567 List
*restrictinfo_list
,
570 if (IsA(inner_path
, IndexPath
))
573 * Check the index quals to see if any of them are join clauses.
575 * We can skip this if the index path is an ordinary indexpath and not
576 * a special innerjoin path, since it then wouldn't be using any join
579 IndexPath
*innerpath
= (IndexPath
*) inner_path
;
581 if (innerpath
->isjoininner
)
583 select_nonredundant_join_list(restrictinfo_list
,
584 innerpath
->indexclauses
);
586 else if (IsA(inner_path
, BitmapHeapPath
))
589 * Same deal for bitmapped index scans.
591 * Note: both here and above, we ignore any implicit index
592 * restrictions associated with the use of partial indexes. This is
593 * OK because we're only trying to prove we can dispense with some
594 * join quals; failing to prove that doesn't result in an incorrect
595 * plan. It's quite unlikely that a join qual could be proven
596 * redundant by an index predicate anyway. (Also, if we did manage to
597 * prove it, we'd have to have a special case for update targets; see
598 * notes about EvalPlanQual testing in create_indexscan_plan().)
600 BitmapHeapPath
*innerpath
= (BitmapHeapPath
*) inner_path
;
602 if (innerpath
->isjoininner
)
607 make_restrictinfo_from_bitmapqual(innerpath
->bitmapqual
,
611 select_nonredundant_join_list(restrictinfo_list
,
617 * XXX the inner path of a nestloop could also be an append relation whose
618 * elements use join quals. However, they might each use different quals;
619 * we could only remove join quals that are enforced by all the appendrel
620 * members. For the moment we don't bother to try.
623 return restrictinfo_list
;
627 * select_nonredundant_join_list
628 * Select the members of restrictinfo_list that are not redundant with
629 * any member of reference_list. See above for more info.
632 select_nonredundant_join_list(List
*restrictinfo_list
,
633 List
*reference_list
)
638 foreach(item
, restrictinfo_list
)
640 RestrictInfo
*rinfo
= (RestrictInfo
*) lfirst(item
);
642 /* drop it if redundant with any reference clause */
643 if (join_clause_is_redundant(rinfo
, reference_list
))
646 /* otherwise, add it to result list */
647 result
= lappend(result
, rinfo
);
654 * join_clause_is_redundant
655 * Test whether rinfo is redundant with any clause in reference_list.
658 join_clause_is_redundant(RestrictInfo
*rinfo
,
659 List
*reference_list
)
663 foreach(refitem
, reference_list
)
665 RestrictInfo
*refrinfo
= (RestrictInfo
*) lfirst(refitem
);
667 /* always consider exact duplicates redundant */
668 if (equal(rinfo
, refrinfo
))
671 /* check if derived from same EquivalenceClass */
672 if (rinfo
->parent_ec
!= NULL
&&
673 rinfo
->parent_ec
== refrinfo
->parent_ec
)