1 /*-------------------------------------------------------------------------
4 * RestrictInfo node manipulation routines.
6 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.36 2005/06/05 22:32:56 tgl Exp $
13 *-------------------------------------------------------------------------
17 #include "optimizer/clauses.h"
18 #include "optimizer/cost.h"
19 #include "optimizer/paths.h"
20 #include "optimizer/restrictinfo.h"
21 #include "optimizer/var.h"
24 static RestrictInfo *make_restrictinfo_internal(Expr *clause,
27 bool valid_everywhere);
28 static Expr *make_sub_restrictinfos(Expr *clause,
30 bool valid_everywhere);
31 static RestrictInfo *join_clause_is_redundant(PlannerInfo *root,
40 * Build a RestrictInfo node containing the given subexpression.
42 * The is_pushed_down and valid_everywhere flags must be supplied by the
45 * We initialize fields that depend only on the given subexpression, leaving
46 * others that depend on context (or may never be needed at all) to be filled
50 make_restrictinfo(Expr *clause, bool is_pushed_down, bool valid_everywhere)
53 * If it's an OR clause, build a modified copy with RestrictInfos
54 * inserted above each subclause of the top-level AND/OR structure.
56 if (or_clause((Node *) clause))
57 return (RestrictInfo *) make_sub_restrictinfos(clause,
61 /* Shouldn't be an AND clause, else AND/OR flattening messed up */
62 Assert(!and_clause((Node *) clause));
64 return make_restrictinfo_internal(clause, NULL,
65 is_pushed_down, valid_everywhere);
69 * make_restrictinfo_from_bitmapqual
71 * Given the bitmapqual Path structure for a bitmap indexscan, generate
72 * RestrictInfo node(s) equivalent to the condition represented by the
73 * indexclauses of the Path structure.
75 * The result is a List since we might need to return multiple RestrictInfos.
77 * To do this through the normal make_restrictinfo() API, callers would have
78 * to strip off the RestrictInfo nodes present in the indexclauses lists, and
79 * then make_restrictinfo() would have to build new ones. It's better to have
80 * a specialized routine to allow sharing of RestrictInfos.
83 make_restrictinfo_from_bitmapqual(Path *bitmapqual,
85 bool valid_everywhere)
89 if (IsA(bitmapqual, BitmapAndPath))
91 BitmapAndPath *apath = (BitmapAndPath *) bitmapqual;
95 foreach(l, apath->bitmapquals)
99 sublist = make_restrictinfo_from_bitmapqual((Path *) lfirst(l),
102 result = list_concat(result, sublist);
105 else if (IsA(bitmapqual, BitmapOrPath))
107 BitmapOrPath *opath = (BitmapOrPath *) bitmapqual;
109 List *withoutris = NIL;
112 foreach(l, opath->bitmapquals)
116 sublist = make_restrictinfo_from_bitmapqual((Path *) lfirst(l),
121 /* constant TRUE input yields constant TRUE OR result */
122 /* (though this probably cannot happen) */
125 /* Create AND subclause with RestrictInfos */
126 withris = lappend(withris, make_ands_explicit(sublist));
127 /* And one without */
128 sublist = get_actual_clauses(sublist);
129 withoutris = lappend(withoutris, make_ands_explicit(sublist));
131 /* Here's the magic part not available to outside callers */
133 list_make1(make_restrictinfo_internal(make_orclause(withoutris),
134 make_orclause(withris),
138 else if (IsA(bitmapqual, IndexPath))
140 IndexPath *ipath = (IndexPath *) bitmapqual;
142 result = list_copy(ipath->indexclauses);
146 elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual));
147 result = NIL; /* keep compiler quiet */
154 * make_restrictinfo_internal
156 * Common code for the main entry points and the recursive cases.
158 static RestrictInfo *
159 make_restrictinfo_internal(Expr *clause, Expr *orclause,
160 bool is_pushed_down, bool valid_everywhere)
162 RestrictInfo *restrictinfo = makeNode(RestrictInfo);
164 restrictinfo->clause = clause;
165 restrictinfo->orclause = orclause;
166 restrictinfo->is_pushed_down = is_pushed_down;
167 restrictinfo->valid_everywhere = valid_everywhere;
168 restrictinfo->can_join = false; /* may get set below */
171 * If it's a binary opclause, set up left/right relids info. In any
172 * case set up the total clause relids info.
174 if (is_opclause(clause) && list_length(((OpExpr *) clause)->args) == 2)
176 restrictinfo->left_relids = pull_varnos(get_leftop(clause));
177 restrictinfo->right_relids = pull_varnos(get_rightop(clause));
179 restrictinfo->clause_relids = bms_union(restrictinfo->left_relids,
180 restrictinfo->right_relids);
183 * Does it look like a normal join clause, i.e., a binary operator
184 * relating expressions that come from distinct relations? If so
185 * we might be able to use it in a join algorithm. Note that this
186 * is a purely syntactic test that is made regardless of context.
188 if (!bms_is_empty(restrictinfo->left_relids) &&
189 !bms_is_empty(restrictinfo->right_relids) &&
190 !bms_overlap(restrictinfo->left_relids,
191 restrictinfo->right_relids))
192 restrictinfo->can_join = true;
196 /* Not a binary opclause, so mark left/right relid sets as empty */
197 restrictinfo->left_relids = NULL;
198 restrictinfo->right_relids = NULL;
199 /* and get the total relid set the hard way */
200 restrictinfo->clause_relids = pull_varnos((Node *) clause);
204 * Fill in all the cacheable fields with "not yet set" markers. None
205 * of these will be computed until/unless needed. Note in particular
206 * that we don't mark a binary opclause as mergejoinable or
207 * hashjoinable here; that happens only if it appears in the right
208 * context (top level of a joinclause list).
210 restrictinfo->eval_cost.startup = -1;
211 restrictinfo->this_selec = -1;
213 restrictinfo->mergejoinoperator = InvalidOid;
214 restrictinfo->left_sortop = InvalidOid;
215 restrictinfo->right_sortop = InvalidOid;
217 restrictinfo->left_pathkey = NIL;
218 restrictinfo->right_pathkey = NIL;
220 restrictinfo->left_mergescansel = -1;
221 restrictinfo->right_mergescansel = -1;
223 restrictinfo->hashjoinoperator = InvalidOid;
225 restrictinfo->left_bucketsize = -1;
226 restrictinfo->right_bucketsize = -1;
232 * Recursively insert sub-RestrictInfo nodes into a boolean expression.
234 * We put RestrictInfos above simple (non-AND/OR) clauses and above
235 * sub-OR clauses, but not above sub-AND clauses, because there's no need.
236 * This may seem odd but it is closely related to the fact that we use
237 * implicit-AND lists at top level of RestrictInfo lists. Only ORs and
238 * simple clauses are valid RestrictInfos.
241 make_sub_restrictinfos(Expr *clause, bool is_pushed_down,
242 bool valid_everywhere)
244 if (or_clause((Node *) clause))
249 foreach(temp, ((BoolExpr *) clause)->args)
250 orlist = lappend(orlist,
251 make_sub_restrictinfos(lfirst(temp),
254 return (Expr *) make_restrictinfo_internal(clause,
255 make_orclause(orlist),
259 else if (and_clause((Node *) clause))
264 foreach(temp, ((BoolExpr *) clause)->args)
265 andlist = lappend(andlist,
266 make_sub_restrictinfos(lfirst(temp),
269 return make_andclause(andlist);
272 return (Expr *) make_restrictinfo_internal(clause,
279 * restriction_is_or_clause
281 * Returns t iff the restrictinfo node contains an 'or' clause.
284 restriction_is_or_clause(RestrictInfo *restrictinfo)
286 if (restrictinfo->orclause != NULL)
295 * Returns a list containing the bare clauses from 'restrictinfo_list'.
298 get_actual_clauses(List *restrictinfo_list)
303 foreach(temp, restrictinfo_list)
305 RestrictInfo *rinfo = (RestrictInfo *) lfirst(temp);
307 Assert(IsA(rinfo, RestrictInfo));
309 result = lappend(result, rinfo->clause);
315 * get_actual_join_clauses
317 * Extract clauses from 'restrictinfo_list', separating those that
318 * syntactically match the join level from those that were pushed down.
321 get_actual_join_clauses(List *restrictinfo_list,
322 List **joinquals, List **otherquals)
329 foreach(temp, restrictinfo_list)
331 RestrictInfo *clause = (RestrictInfo *) lfirst(temp);
333 if (clause->is_pushed_down)
334 *otherquals = lappend(*otherquals, clause->clause);
336 *joinquals = lappend(*joinquals, clause->clause);
341 * remove_redundant_join_clauses
343 * Given a list of RestrictInfo clauses that are to be applied in a join,
344 * remove any duplicate or redundant clauses.
346 * We must eliminate duplicates when forming the restrictlist for a joinrel,
347 * since we will see many of the same clauses arriving from both input
348 * relations. Also, if a clause is a mergejoinable clause, it's possible that
349 * it is redundant with previous clauses (see optimizer/README for
350 * discussion). We detect that case and omit the redundant clause from the
353 * The result is a fresh List, but it points to the same member nodes
354 * as were in the input.
357 remove_redundant_join_clauses(PlannerInfo *root, List *restrictinfo_list,
365 * If there are any redundant clauses, we want to eliminate the ones
366 * that are more expensive in favor of the ones that are less so. Run
367 * cost_qual_eval() to ensure the eval_cost fields are set up.
369 cost_qual_eval(&cost, restrictinfo_list);
372 * We don't have enough knowledge yet to be able to estimate the
373 * number of times a clause might be evaluated, so it's hard to weight
374 * the startup and per-tuple costs appropriately. For now just weight
377 #define CLAUSECOST(r) ((r)->eval_cost.startup + (r)->eval_cost.per_tuple)
379 foreach(item, restrictinfo_list)
381 RestrictInfo *rinfo = (RestrictInfo *) lfirst(item);
382 RestrictInfo *prevrinfo;
384 /* is it redundant with any prior clause? */
385 prevrinfo = join_clause_is_redundant(root, rinfo, result, isouterjoin);
386 if (prevrinfo == NULL)
388 /* no, so add it to result list */
389 result = lappend(result, rinfo);
391 else if (CLAUSECOST(rinfo) < CLAUSECOST(prevrinfo))
393 /* keep this one, drop the previous one */
394 result = list_delete_ptr(result, prevrinfo);
395 result = lappend(result, rinfo);
397 /* else, drop this one */
404 * select_nonredundant_join_clauses
406 * Given a list of RestrictInfo clauses that are to be applied in a join,
407 * select the ones that are not redundant with any clause in the
410 * This is similar to remove_redundant_join_clauses, but we are looking for
411 * redundancies with a separate list of clauses (i.e., clauses that have
412 * already been applied below the join itself).
414 * Note that we assume the given restrictinfo_list has already been checked
415 * for local redundancies, so we don't check again.
418 select_nonredundant_join_clauses(PlannerInfo *root,
419 List *restrictinfo_list,
420 List *reference_list,
426 foreach(item, restrictinfo_list)
428 RestrictInfo *rinfo = (RestrictInfo *) lfirst(item);
430 /* drop it if redundant with any reference clause */
431 if (join_clause_is_redundant(root, rinfo, reference_list, isouterjoin) != NULL)
434 /* otherwise, add it to result list */
435 result = lappend(result, rinfo);
442 * join_clause_is_redundant
443 * If rinfo is redundant with any clause in reference_list,
444 * return one such clause; otherwise return NULL.
446 * This is the guts of both remove_redundant_join_clauses and
447 * select_nonredundant_join_clauses. See the docs above for motivation.
449 * We can detect redundant mergejoinable clauses very cheaply by using their
450 * left and right pathkeys, which uniquely identify the sets of equijoined
451 * variables in question. All the members of a pathkey set that are in the
452 * left relation have already been forced to be equal; likewise for those in
453 * the right relation. So, we need to have only one clause that checks
454 * equality between any set member on the left and any member on the right;
455 * by transitivity, all the rest are then equal.
457 * However, clauses that are of the form "var expr = const expr" cannot be
458 * eliminated as redundant. This is because when there are const expressions
459 * in a pathkey set, generate_implied_equalities() suppresses "var = var"
460 * clauses in favor of "var = const" clauses. We cannot afford to drop any
461 * of the latter, even though they might seem redundant by the pathkey
464 * Weird special case: if we have two clauses that seem redundant
465 * except one is pushed down into an outer join and the other isn't,
466 * then they're not really redundant, because one constrains the
467 * joined rows after addition of null fill rows, and the other doesn't.
469 static RestrictInfo *
470 join_clause_is_redundant(PlannerInfo *root,
472 List *reference_list,
477 /* always consider exact duplicates redundant */
478 foreach(refitem, reference_list)
480 RestrictInfo *refrinfo = (RestrictInfo *) lfirst(refitem);
482 if (equal(rinfo, refrinfo))
486 /* check for redundant merge clauses */
487 if (rinfo->mergejoinoperator != InvalidOid)
489 /* do the cheap test first: is it a "var = const" clause? */
490 if (bms_is_empty(rinfo->left_relids) ||
491 bms_is_empty(rinfo->right_relids))
492 return NULL; /* var = const, so not redundant */
494 cache_mergeclause_pathkeys(root, rinfo);
496 foreach(refitem, reference_list)
498 RestrictInfo *refrinfo = (RestrictInfo *) lfirst(refitem);
500 if (refrinfo->mergejoinoperator != InvalidOid)
502 cache_mergeclause_pathkeys(root, refrinfo);
504 if (rinfo->left_pathkey == refrinfo->left_pathkey &&
505 rinfo->right_pathkey == refrinfo->right_pathkey &&
506 (rinfo->is_pushed_down == refrinfo->is_pushed_down ||
509 /* Yup, it's redundant */
516 /* otherwise, not redundant */