PostgreSQL Source Code  git master
clausesel.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * clausesel.c
4  * Routines to compute clause selectivities
5  *
6  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/optimizer/path/clausesel.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "nodes/makefuncs.h"
18 #include "nodes/nodeFuncs.h"
19 #include "optimizer/clauses.h"
20 #include "optimizer/cost.h"
21 #include "optimizer/optimizer.h"
22 #include "optimizer/pathnode.h"
23 #include "optimizer/plancat.h"
24 #include "statistics/statistics.h"
25 #include "utils/fmgroids.h"
26 #include "utils/lsyscache.h"
27 #include "utils/selfuncs.h"
28 
29 /*
30  * Data structure for accumulating info about possible range-query
31  * clause pairs in clauselist_selectivity.
32  */
33 typedef struct RangeQueryClause
34 {
35  struct RangeQueryClause *next; /* next in linked list */
36  Node *var; /* The common variable of the clauses */
37  bool have_lobound; /* found a low-bound clause yet? */
38  bool have_hibound; /* found a high-bound clause yet? */
39  Selectivity lobound; /* Selectivity of a var > something clause */
40  Selectivity hibound; /* Selectivity of a var < something clause */
42 
43 static void addRangeClause(RangeQueryClause **rqlist, Node *clause,
44  bool varonleft, bool isLTsel, Selectivity s2);
46  List *clauses);
47 
48 /****************************************************************************
49  * ROUTINES TO COMPUTE SELECTIVITIES
50  ****************************************************************************/
51 
52 /*
53  * clauselist_selectivity -
54  * Compute the selectivity of an implicitly-ANDed list of boolean
55  * expression clauses. The list can be empty, in which case 1.0
56  * must be returned. List elements may be either RestrictInfos
57  * or bare expression clauses --- the former is preferred since
58  * it allows caching of results.
59  *
60  * See clause_selectivity() for the meaning of the additional parameters.
61  *
62  * The basic approach is to apply extended statistics first, on as many
63  * clauses as possible, in order to capture cross-column dependencies etc.
64  * The remaining clauses are then estimated using regular statistics tracked
65  * for individual columns. This is done by simply passing the clauses to
66  * clauselist_selectivity_simple.
67  */
70  List *clauses,
71  int varRelid,
72  JoinType jointype,
73  SpecialJoinInfo *sjinfo)
74 {
75  Selectivity s1 = 1.0;
76  RelOptInfo *rel;
77  Bitmapset *estimatedclauses = NULL;
78 
79  /*
80  * Determine if these clauses reference a single relation. If so, and if
81  * it has extended statistics, try to apply those.
82  */
83  rel = find_single_rel_for_clauses(root, clauses);
84  if (rel && rel->rtekind == RTE_RELATION && rel->statlist != NIL)
85  {
86  /*
87  * Estimate as many clauses as possible using extended statistics.
88  *
89  * 'estimatedclauses' tracks the 0-based list position index of
90  * clauses that we've estimated using extended statistics, and that
91  * should be ignored.
92  */
93  s1 *= statext_clauselist_selectivity(root, clauses, varRelid,
94  jointype, sjinfo, rel,
95  &estimatedclauses);
96  }
97 
98  /*
99  * Apply normal selectivity estimates for the remaining clauses, passing
100  * 'estimatedclauses' so that it skips already estimated ones.
101  */
102  return s1 * clauselist_selectivity_simple(root, clauses, varRelid,
103  jointype, sjinfo,
104  estimatedclauses);
105 }
106 
107 /*
108  * clauselist_selectivity_simple -
109  * Compute the selectivity of an implicitly-ANDed list of boolean
110  * expression clauses. The list can be empty, in which case 1.0
111  * must be returned. List elements may be either RestrictInfos
112  * or bare expression clauses --- the former is preferred since
113  * it allows caching of results. The estimatedclauses bitmap tracks
114  * clauses that have already been estimated by other means.
115  *
116  * See clause_selectivity() for the meaning of the additional parameters.
117  *
118  * Our basic approach is to take the product of the selectivities of the
119  * subclauses. However, that's only right if the subclauses have independent
120  * probabilities, and in reality they are often NOT independent. So,
121  * we want to be smarter where we can.
122  *
123  * We also recognize "range queries", such as "x > 34 AND x < 42". Clauses
124  * are recognized as possible range query components if they are restriction
125  * opclauses whose operators have scalarltsel or a related function as their
126  * restriction selectivity estimator. We pair up clauses of this form that
127  * refer to the same variable. An unpairable clause of this kind is simply
128  * multiplied into the selectivity product in the normal way. But when we
129  * find a pair, we know that the selectivities represent the relative
130  * positions of the low and high bounds within the column's range, so instead
131  * of figuring the selectivity as hisel * losel, we can figure it as hisel +
132  * losel - 1. (To visualize this, see that hisel is the fraction of the range
133  * below the high bound, while losel is the fraction above the low bound; so
134  * hisel can be interpreted directly as a 0..1 value but we need to convert
135  * losel to 1-losel before interpreting it as a value. Then the available
136  * range is 1-losel to hisel. However, this calculation double-excludes
137  * nulls, so really we need hisel + losel + null_frac - 1.)
138  *
139  * If either selectivity is exactly DEFAULT_INEQ_SEL, we forget this equation
140  * and instead use DEFAULT_RANGE_INEQ_SEL. The same applies if the equation
141  * yields an impossible (negative) result.
142  *
143  * A free side-effect is that we can recognize redundant inequalities such
144  * as "x < 4 AND x < 5"; only the tighter constraint will be counted.
145  *
146  * Of course this is all very dependent on the behavior of the inequality
147  * selectivity functions; perhaps some day we can generalize the approach.
148  */
151  List *clauses,
152  int varRelid,
153  JoinType jointype,
154  SpecialJoinInfo *sjinfo,
155  Bitmapset *estimatedclauses)
156 {
157  Selectivity s1 = 1.0;
158  RangeQueryClause *rqlist = NULL;
159  ListCell *l;
160  int listidx;
161 
162  /*
163  * If there's exactly one clause (and it was not estimated yet), just go
164  * directly to clause_selectivity(). None of what we might do below is
165  * relevant.
166  */
167  if (list_length(clauses) == 1 && bms_is_empty(estimatedclauses))
168  return clause_selectivity(root, (Node *) linitial(clauses),
169  varRelid, jointype, sjinfo);
170 
171  /*
172  * Anything that doesn't look like a potential rangequery clause gets
173  * multiplied into s1 and forgotten. Anything that does gets inserted into
174  * an rqlist entry.
175  */
176  listidx = -1;
177  foreach(l, clauses)
178  {
179  Node *clause = (Node *) lfirst(l);
180  RestrictInfo *rinfo;
181  Selectivity s2;
182 
183  listidx++;
184 
185  /*
186  * Skip this clause if it's already been estimated by some other
187  * statistics above.
188  */
189  if (bms_is_member(listidx, estimatedclauses))
190  continue;
191 
192  /* Always compute the selectivity using clause_selectivity */
193  s2 = clause_selectivity(root, clause, varRelid, jointype, sjinfo);
194 
195  /*
196  * Check for being passed a RestrictInfo.
197  *
198  * If it's a pseudoconstant RestrictInfo, then s2 is either 1.0 or
199  * 0.0; just use that rather than looking for range pairs.
200  */
201  if (IsA(clause, RestrictInfo))
202  {
203  rinfo = (RestrictInfo *) clause;
204  if (rinfo->pseudoconstant)
205  {
206  s1 = s1 * s2;
207  continue;
208  }
209  clause = (Node *) rinfo->clause;
210  }
211  else
212  rinfo = NULL;
213 
214  /*
215  * See if it looks like a restriction clause with a pseudoconstant on
216  * one side. (Anything more complicated than that might not behave in
217  * the simple way we are expecting.) Most of the tests here can be
218  * done more efficiently with rinfo than without.
219  */
220  if (is_opclause(clause) && list_length(((OpExpr *) clause)->args) == 2)
221  {
222  OpExpr *expr = (OpExpr *) clause;
223  bool varonleft = true;
224  bool ok;
225 
226  if (rinfo)
227  {
228  ok = (bms_membership(rinfo->clause_relids) == BMS_SINGLETON) &&
230  rinfo->right_relids) ||
231  (varonleft = false,
233  rinfo->left_relids)));
234  }
235  else
236  {
237  ok = (NumRelids(clause) == 1) &&
239  (varonleft = false,
241  }
242 
243  if (ok)
244  {
245  /*
246  * If it's not a "<"/"<="/">"/">=" operator, just merge the
247  * selectivity in generically. But if it's the right oprrest,
248  * add the clause to rqlist for later processing.
249  */
250  switch (get_oprrest(expr->opno))
251  {
252  case F_SCALARLTSEL:
253  case F_SCALARLESEL:
254  addRangeClause(&rqlist, clause,
255  varonleft, true, s2);
256  break;
257  case F_SCALARGTSEL:
258  case F_SCALARGESEL:
259  addRangeClause(&rqlist, clause,
260  varonleft, false, s2);
261  break;
262  default:
263  /* Just merge the selectivity in generically */
264  s1 = s1 * s2;
265  break;
266  }
267  continue; /* drop to loop bottom */
268  }
269  }
270 
271  /* Not the right form, so treat it generically. */
272  s1 = s1 * s2;
273  }
274 
275  /*
276  * Now scan the rangequery pair list.
277  */
278  while (rqlist != NULL)
279  {
280  RangeQueryClause *rqnext;
281 
282  if (rqlist->have_lobound && rqlist->have_hibound)
283  {
284  /* Successfully matched a pair of range clauses */
285  Selectivity s2;
286 
287  /*
288  * Exact equality to the default value probably means the
289  * selectivity function punted. This is not airtight but should
290  * be good enough.
291  */
292  if (rqlist->hibound == DEFAULT_INEQ_SEL ||
293  rqlist->lobound == DEFAULT_INEQ_SEL)
294  {
296  }
297  else
298  {
299  s2 = rqlist->hibound + rqlist->lobound - 1.0;
300 
301  /* Adjust for double-exclusion of NULLs */
302  s2 += nulltestsel(root, IS_NULL, rqlist->var,
303  varRelid, jointype, sjinfo);
304 
305  /*
306  * A zero or slightly negative s2 should be converted into a
307  * small positive value; we probably are dealing with a very
308  * tight range and got a bogus result due to roundoff errors.
309  * However, if s2 is very negative, then we probably have
310  * default selectivity estimates on one or both sides of the
311  * range that we failed to recognize above for some reason.
312  */
313  if (s2 <= 0.0)
314  {
315  if (s2 < -0.01)
316  {
317  /*
318  * No data available --- use a default estimate that
319  * is small, but not real small.
320  */
322  }
323  else
324  {
325  /*
326  * It's just roundoff error; use a small positive
327  * value
328  */
329  s2 = 1.0e-10;
330  }
331  }
332  }
333  /* Merge in the selectivity of the pair of clauses */
334  s1 *= s2;
335  }
336  else
337  {
338  /* Only found one of a pair, merge it in generically */
339  if (rqlist->have_lobound)
340  s1 *= rqlist->lobound;
341  else
342  s1 *= rqlist->hibound;
343  }
344  /* release storage and advance */
345  rqnext = rqlist->next;
346  pfree(rqlist);
347  rqlist = rqnext;
348  }
349 
350  return s1;
351 }
352 
353 /*
354  * addRangeClause --- add a new range clause for clauselist_selectivity
355  *
356  * Here is where we try to match up pairs of range-query clauses
357  */
358 static void
360  bool varonleft, bool isLTsel, Selectivity s2)
361 {
362  RangeQueryClause *rqelem;
363  Node *var;
364  bool is_lobound;
365 
366  if (varonleft)
367  {
368  var = get_leftop((Expr *) clause);
369  is_lobound = !isLTsel; /* x < something is high bound */
370  }
371  else
372  {
373  var = get_rightop((Expr *) clause);
374  is_lobound = isLTsel; /* something < x is low bound */
375  }
376 
377  for (rqelem = *rqlist; rqelem; rqelem = rqelem->next)
378  {
379  /*
380  * We use full equal() here because the "var" might be a function of
381  * one or more attributes of the same relation...
382  */
383  if (!equal(var, rqelem->var))
384  continue;
385  /* Found the right group to put this clause in */
386  if (is_lobound)
387  {
388  if (!rqelem->have_lobound)
389  {
390  rqelem->have_lobound = true;
391  rqelem->lobound = s2;
392  }
393  else
394  {
395 
396  /*------
397  * We have found two similar clauses, such as
398  * x < y AND x <= z.
399  * Keep only the more restrictive one.
400  *------
401  */
402  if (rqelem->lobound > s2)
403  rqelem->lobound = s2;
404  }
405  }
406  else
407  {
408  if (!rqelem->have_hibound)
409  {
410  rqelem->have_hibound = true;
411  rqelem->hibound = s2;
412  }
413  else
414  {
415 
416  /*------
417  * We have found two similar clauses, such as
418  * x > y AND x >= z.
419  * Keep only the more restrictive one.
420  *------
421  */
422  if (rqelem->hibound > s2)
423  rqelem->hibound = s2;
424  }
425  }
426  return;
427  }
428 
429  /* No matching var found, so make a new clause-pair data structure */
430  rqelem = (RangeQueryClause *) palloc(sizeof(RangeQueryClause));
431  rqelem->var = var;
432  if (is_lobound)
433  {
434  rqelem->have_lobound = true;
435  rqelem->have_hibound = false;
436  rqelem->lobound = s2;
437  }
438  else
439  {
440  rqelem->have_lobound = false;
441  rqelem->have_hibound = true;
442  rqelem->hibound = s2;
443  }
444  rqelem->next = *rqlist;
445  *rqlist = rqelem;
446 }
447 
448 /*
449  * find_single_rel_for_clauses
450  * Examine each clause in 'clauses' and determine if all clauses
451  * reference only a single relation. If so return that relation,
452  * otherwise return NULL.
453  */
454 static RelOptInfo *
456 {
457  int lastrelid = 0;
458  ListCell *l;
459 
460  foreach(l, clauses)
461  {
462  RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
463  int relid;
464 
465  /*
466  * If we have a list of bare clauses rather than RestrictInfos, we
467  * could pull out their relids the hard way with pull_varnos().
468  * However, currently the extended-stats machinery won't do anything
469  * with non-RestrictInfo clauses anyway, so there's no point in
470  * spending extra cycles; just fail if that's what we have.
471  */
472  if (!IsA(rinfo, RestrictInfo))
473  return NULL;
474 
475  if (bms_is_empty(rinfo->clause_relids))
476  continue; /* we can ignore variable-free clauses */
477  if (!bms_get_singleton_member(rinfo->clause_relids, &relid))
478  return NULL; /* multiple relations in this clause */
479  if (lastrelid == 0)
480  lastrelid = relid; /* first clause referencing a relation */
481  else if (relid != lastrelid)
482  return NULL; /* relation not same as last one */
483  }
484 
485  if (lastrelid != 0)
486  return find_base_rel(root, lastrelid);
487 
488  return NULL; /* no clauses */
489 }
490 
491 /*
492  * bms_is_subset_singleton
493  *
494  * Same result as bms_is_subset(s, bms_make_singleton(x)),
495  * but a little faster and doesn't leak memory.
496  *
497  * Is this of use anywhere else? If so move to bitmapset.c ...
498  */
499 static bool
501 {
502  switch (bms_membership(s))
503  {
504  case BMS_EMPTY_SET:
505  return true;
506  case BMS_SINGLETON:
507  return bms_is_member(x, s);
508  case BMS_MULTIPLE:
509  return false;
510  }
511  /* can't get here... */
512  return false;
513 }
514 
515 /*
516  * treat_as_join_clause -
517  * Decide whether an operator clause is to be handled by the
518  * restriction or join estimator. Subroutine for clause_selectivity().
519  */
520 static inline bool
522  int varRelid, SpecialJoinInfo *sjinfo)
523 {
524  if (varRelid != 0)
525  {
526  /*
527  * Caller is forcing restriction mode (eg, because we are examining an
528  * inner indexscan qual).
529  */
530  return false;
531  }
532  else if (sjinfo == NULL)
533  {
534  /*
535  * It must be a restriction clause, since it's being evaluated at a
536  * scan node.
537  */
538  return false;
539  }
540  else
541  {
542  /*
543  * Otherwise, it's a join if there's more than one relation used. We
544  * can optimize this calculation if an rinfo was passed.
545  *
546  * XXX Since we know the clause is being evaluated at a join, the
547  * only way it could be single-relation is if it was delayed by outer
548  * joins. Although we can make use of the restriction qual estimators
549  * anyway, it seems likely that we ought to account for the
550  * probability of injected nulls somehow.
551  */
552  if (rinfo)
553  return (bms_membership(rinfo->clause_relids) == BMS_MULTIPLE);
554  else
555  return (NumRelids(clause) > 1);
556  }
557 }
558 
559 
560 /*
561  * clause_selectivity -
562  * Compute the selectivity of a general boolean expression clause.
563  *
564  * The clause can be either a RestrictInfo or a plain expression. If it's
565  * a RestrictInfo, we try to cache the selectivity for possible re-use,
566  * so passing RestrictInfos is preferred.
567  *
568  * varRelid is either 0 or a rangetable index.
569  *
570  * When varRelid is not 0, only variables belonging to that relation are
571  * considered in computing selectivity; other vars are treated as constants
572  * of unknown values. This is appropriate for estimating the selectivity of
573  * a join clause that is being used as a restriction clause in a scan of a
574  * nestloop join's inner relation --- varRelid should then be the ID of the
575  * inner relation.
576  *
577  * When varRelid is 0, all variables are treated as variables. This
578  * is appropriate for ordinary join clauses and restriction clauses.
579  *
580  * jointype is the join type, if the clause is a join clause. Pass JOIN_INNER
581  * if the clause isn't a join clause.
582  *
583  * sjinfo is NULL for a non-join clause, otherwise it provides additional
584  * context information about the join being performed. There are some
585  * special cases:
586  * 1. For a special (not INNER) join, sjinfo is always a member of
587  * root->join_info_list.
588  * 2. For an INNER join, sjinfo is just a transient struct, and only the
589  * relids and jointype fields in it can be trusted.
590  * It is possible for jointype to be different from sjinfo->jointype.
591  * This indicates we are considering a variant join: either with
592  * the LHS and RHS switched, or with one input unique-ified.
593  *
594  * Note: when passing nonzero varRelid, it's normally appropriate to set
595  * jointype == JOIN_INNER, sjinfo == NULL, even if the clause is really a
596  * join clause; because we aren't treating it as a join clause.
597  */
600  Node *clause,
601  int varRelid,
602  JoinType jointype,
603  SpecialJoinInfo *sjinfo)
604 {
605  Selectivity s1 = 0.5; /* default for any unhandled clause type */
606  RestrictInfo *rinfo = NULL;
607  bool cacheable = false;
608 
609  if (clause == NULL) /* can this still happen? */
610  return s1;
611 
612  if (IsA(clause, RestrictInfo))
613  {
614  rinfo = (RestrictInfo *) clause;
615 
616  /*
617  * If the clause is marked pseudoconstant, then it will be used as a
618  * gating qual and should not affect selectivity estimates; hence
619  * return 1.0. The only exception is that a constant FALSE may be
620  * taken as having selectivity 0.0, since it will surely mean no rows
621  * out of the plan. This case is simple enough that we need not
622  * bother caching the result.
623  */
624  if (rinfo->pseudoconstant)
625  {
626  if (!IsA(rinfo->clause, Const))
627  return (Selectivity) 1.0;
628  }
629 
630  /*
631  * If the clause is marked redundant, always return 1.0.
632  */
633  if (rinfo->norm_selec > 1)
634  return (Selectivity) 1.0;
635 
636  /*
637  * If possible, cache the result of the selectivity calculation for
638  * the clause. We can cache if varRelid is zero or the clause
639  * contains only vars of that relid --- otherwise varRelid will affect
640  * the result, so mustn't cache. Outer join quals might be examined
641  * with either their join's actual jointype or JOIN_INNER, so we need
642  * two cache variables to remember both cases. Note: we assume the
643  * result won't change if we are switching the input relations or
644  * considering a unique-ified case, so we only need one cache variable
645  * for all non-JOIN_INNER cases.
646  */
647  if (varRelid == 0 ||
648  bms_is_subset_singleton(rinfo->clause_relids, varRelid))
649  {
650  /* Cacheable --- do we already have the result? */
651  if (jointype == JOIN_INNER)
652  {
653  if (rinfo->norm_selec >= 0)
654  return rinfo->norm_selec;
655  }
656  else
657  {
658  if (rinfo->outer_selec >= 0)
659  return rinfo->outer_selec;
660  }
661  cacheable = true;
662  }
663 
664  /*
665  * Proceed with examination of contained clause. If the clause is an
666  * OR-clause, we want to look at the variant with sub-RestrictInfos,
667  * so that per-subclause selectivities can be cached.
668  */
669  if (rinfo->orclause)
670  clause = (Node *) rinfo->orclause;
671  else
672  clause = (Node *) rinfo->clause;
673  }
674 
675  if (IsA(clause, Var))
676  {
677  Var *var = (Var *) clause;
678 
679  /*
680  * We probably shouldn't ever see an uplevel Var here, but if we do,
681  * return the default selectivity...
682  */
683  if (var->varlevelsup == 0 &&
684  (varRelid == 0 || varRelid == (int) var->varno))
685  {
686  /* Use the restriction selectivity function for a bool Var */
687  s1 = boolvarsel(root, (Node *) var, varRelid);
688  }
689  }
690  else if (IsA(clause, Const))
691  {
692  /* bool constant is pretty easy... */
693  Const *con = (Const *) clause;
694 
695  s1 = con->constisnull ? 0.0 :
696  DatumGetBool(con->constvalue) ? 1.0 : 0.0;
697  }
698  else if (IsA(clause, Param))
699  {
700  /* see if we can replace the Param */
701  Node *subst = estimate_expression_value(root, clause);
702 
703  if (IsA(subst, Const))
704  {
705  /* bool constant is pretty easy... */
706  Const *con = (Const *) subst;
707 
708  s1 = con->constisnull ? 0.0 :
709  DatumGetBool(con->constvalue) ? 1.0 : 0.0;
710  }
711  else
712  {
713  /* XXX any way to do better than default? */
714  }
715  }
716  else if (is_notclause(clause))
717  {
718  /* inverse of the selectivity of the underlying clause */
719  s1 = 1.0 - clause_selectivity(root,
720  (Node *) get_notclausearg((Expr *) clause),
721  varRelid,
722  jointype,
723  sjinfo);
724  }
725  else if (is_andclause(clause))
726  {
727  /* share code with clauselist_selectivity() */
728  s1 = clauselist_selectivity(root,
729  ((BoolExpr *) clause)->args,
730  varRelid,
731  jointype,
732  sjinfo);
733  }
734  else if (is_orclause(clause))
735  {
736  /*
737  * Selectivities for an OR clause are computed as s1+s2 - s1*s2 to
738  * account for the probable overlap of selected tuple sets.
739  *
740  * XXX is this too conservative?
741  */
742  ListCell *arg;
743 
744  s1 = 0.0;
745  foreach(arg, ((BoolExpr *) clause)->args)
746  {
748  (Node *) lfirst(arg),
749  varRelid,
750  jointype,
751  sjinfo);
752 
753  s1 = s1 + s2 - s1 * s2;
754  }
755  }
756  else if (is_opclause(clause) || IsA(clause, DistinctExpr))
757  {
758  OpExpr *opclause = (OpExpr *) clause;
759  Oid opno = opclause->opno;
760 
761  if (treat_as_join_clause(clause, rinfo, varRelid, sjinfo))
762  {
763  /* Estimate selectivity for a join clause. */
764  s1 = join_selectivity(root, opno,
765  opclause->args,
766  opclause->inputcollid,
767  jointype,
768  sjinfo);
769  }
770  else
771  {
772  /* Estimate selectivity for a restriction clause. */
773  s1 = restriction_selectivity(root, opno,
774  opclause->args,
775  opclause->inputcollid,
776  varRelid);
777  }
778 
779  /*
780  * DistinctExpr has the same representation as OpExpr, but the
781  * contained operator is "=" not "<>", so we must negate the result.
782  * This estimation method doesn't give the right behavior for nulls,
783  * but it's better than doing nothing.
784  */
785  if (IsA(clause, DistinctExpr))
786  s1 = 1.0 - s1;
787  }
788  else if (is_funcclause(clause))
789  {
790  FuncExpr *funcclause = (FuncExpr *) clause;
791 
792  /* Try to get an estimate from the support function, if any */
793  s1 = function_selectivity(root,
794  funcclause->funcid,
795  funcclause->args,
796  funcclause->inputcollid,
797  treat_as_join_clause(clause, rinfo,
798  varRelid, sjinfo),
799  varRelid,
800  jointype,
801  sjinfo);
802  }
803  else if (IsA(clause, ScalarArrayOpExpr))
804  {
805  /* Use node specific selectivity calculation function */
806  s1 = scalararraysel(root,
807  (ScalarArrayOpExpr *) clause,
808  treat_as_join_clause(clause, rinfo,
809  varRelid, sjinfo),
810  varRelid,
811  jointype,
812  sjinfo);
813  }
814  else if (IsA(clause, RowCompareExpr))
815  {
816  /* Use node specific selectivity calculation function */
817  s1 = rowcomparesel(root,
818  (RowCompareExpr *) clause,
819  varRelid,
820  jointype,
821  sjinfo);
822  }
823  else if (IsA(clause, NullTest))
824  {
825  /* Use node specific selectivity calculation function */
826  s1 = nulltestsel(root,
827  ((NullTest *) clause)->nulltesttype,
828  (Node *) ((NullTest *) clause)->arg,
829  varRelid,
830  jointype,
831  sjinfo);
832  }
833  else if (IsA(clause, BooleanTest))
834  {
835  /* Use node specific selectivity calculation function */
836  s1 = booltestsel(root,
837  ((BooleanTest *) clause)->booltesttype,
838  (Node *) ((BooleanTest *) clause)->arg,
839  varRelid,
840  jointype,
841  sjinfo);
842  }
843  else if (IsA(clause, CurrentOfExpr))
844  {
845  /* CURRENT OF selects at most one row of its table */
846  CurrentOfExpr *cexpr = (CurrentOfExpr *) clause;
847  RelOptInfo *crel = find_base_rel(root, cexpr->cvarno);
848 
849  if (crel->tuples > 0)
850  s1 = 1.0 / crel->tuples;
851  }
852  else if (IsA(clause, RelabelType))
853  {
854  /* Not sure this case is needed, but it can't hurt */
855  s1 = clause_selectivity(root,
856  (Node *) ((RelabelType *) clause)->arg,
857  varRelid,
858  jointype,
859  sjinfo);
860  }
861  else if (IsA(clause, CoerceToDomain))
862  {
863  /* Not sure this case is needed, but it can't hurt */
864  s1 = clause_selectivity(root,
865  (Node *) ((CoerceToDomain *) clause)->arg,
866  varRelid,
867  jointype,
868  sjinfo);
869  }
870  else
871  {
872  /*
873  * For anything else, see if we can consider it as a boolean variable.
874  * This only works if it's an immutable expression in Vars of a single
875  * relation; but there's no point in us checking that here because
876  * boolvarsel() will do it internally, and return a suitable default
877  * selectivity if not.
878  */
879  s1 = boolvarsel(root, clause, varRelid);
880  }
881 
882  /* Cache the result if possible */
883  if (cacheable)
884  {
885  if (jointype == JOIN_INNER)
886  rinfo->norm_selec = s1;
887  else
888  rinfo->outer_selec = s1;
889  }
890 
891 #ifdef SELECTIVITY_DEBUG
892  elog(DEBUG4, "clause_selectivity: s1 %f", s1);
893 #endif /* SELECTIVITY_DEBUG */
894 
895  return s1;
896 }
Datum constvalue
Definition: primnodes.h:214
#define NIL
Definition: pg_list.h:65
#define IsA(nodeptr, _type_)
Definition: nodes.h:580
List * statlist
Definition: pathnodes.h:703
bool is_pseudo_constant_clause_relids(Node *clause, Relids relids)
Definition: clauses.c:2143
Index varlevelsup
Definition: primnodes.h:191
List * args
Definition: primnodes.h:477
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:3032
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Definition: clauses.c:2320
static bool is_orclause(const void *clause)
Definition: nodeFuncs.h:106
Expr * orclause
Definition: pathnodes.h:2016
#define DEFAULT_INEQ_SEL
Definition: selfuncs.h:37
Selectivity restriction_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, int varRelid)
Definition: plancat.c:1763
double tuples
Definition: pathnodes.h:705
Selectivity rowcomparesel(PlannerInfo *root, RowCompareExpr *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: selfuncs.c:2170
Relids clause_relids
Definition: pathnodes.h:2000
bool pseudoconstant
Definition: pathnodes.h:1993
static bool is_andclause(const void *clause)
Definition: nodeFuncs.h:97
Definition: nodes.h:529
Relids left_relids
Definition: pathnodes.h:2012
bool bms_get_singleton_member(const Bitmapset *a, int *member)
Definition: bitmapset.c:615
double Selectivity
Definition: nodes.h:662
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:181
#define DEBUG4
Definition: elog.h:22
Selectivity clauselist_selectivity_simple(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, Bitmapset *estimatedclauses)
Definition: clausesel.c:150
#define lsecond(l)
Definition: pg_list.h:200
Selectivity scalararraysel(PlannerInfo *root, ScalarArrayOpExpr *clause, bool is_join_clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: selfuncs.c:1813
static bool is_funcclause(const void *clause)
Definition: nodeFuncs.h:59
Selectivity norm_selec
Definition: pathnodes.h:2023
JoinType
Definition: nodes.h:696
static bool treat_as_join_clause(Node *clause, RestrictInfo *rinfo, int varRelid, SpecialJoinInfo *sjinfo)
Definition: clausesel.c:521
static bool bms_is_subset_singleton(const Bitmapset *s, int x)
Definition: clausesel.c:500
void pfree(void *pointer)
Definition: mcxt.c:1057
#define linitial(l)
Definition: pg_list.h:195
Oid funcid
Definition: primnodes.h:469
char * s1
Selectivity nulltestsel(PlannerInfo *root, NullTestType nulltesttype, Node *arg, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: selfuncs.c:1695
Selectivity function_selectivity(PlannerInfo *root, Oid funcid, List *args, Oid inputcollid, bool is_join, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: plancat.c:1843
Selectivity clause_selectivity(PlannerInfo *root, Node *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: clausesel.c:599
#define DatumGetBool(X)
Definition: postgres.h:393
Selectivity outer_selec
Definition: pathnodes.h:2026
bool is_pseudo_constant_clause(Node *clause)
Definition: clauses.c:2123
static Node * get_leftop(const void *clause)
Definition: nodeFuncs.h:73
struct RangeQueryClause * next
Definition: clausesel.c:35
Selectivity statext_clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, RelOptInfo *rel, Bitmapset **estimatedclauses)
static void addRangeClause(RangeQueryClause **rqlist, Node *clause, bool varonleft, bool isLTsel, Selectivity s2)
Definition: clausesel.c:359
Selectivity hibound
Definition: clausesel.c:40
Expr * clause
Definition: pathnodes.h:1985
Selectivity lobound
Definition: clausesel.c:39
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:701
Index varno
Definition: primnodes.h:184
static bool is_notclause(const void *clause)
Definition: nodeFuncs.h:115
RegProcedure get_oprrest(Oid opno)
Definition: lsyscache.c:1469
BMS_Membership bms_membership(const Bitmapset *a)
Definition: bitmapset.c:672
char * s2
RTEKind rtekind
Definition: pathnodes.h:695
static Node * get_rightop(const void *clause)
Definition: nodeFuncs.h:85
static RelOptInfo * find_single_rel_for_clauses(PlannerInfo *root, List *clauses)
Definition: clausesel.c:455
static Expr * get_notclausearg(const void *notclause)
Definition: nodeFuncs.h:124
Relids right_relids
Definition: pathnodes.h:2013
Oid inputcollid
Definition: primnodes.h:476
struct RangeQueryClause RangeQueryClause
#define lfirst(lc)
Definition: pg_list.h:190
static int list_length(const List *l)
Definition: pg_list.h:169
Oid inputcollid
Definition: primnodes.h:521
void * palloc(Size size)
Definition: mcxt.c:950
#define elog(elevel,...)
Definition: elog.h:214
#define DEFAULT_RANGE_INEQ_SEL
Definition: selfuncs.h:40
void * arg
Selectivity join_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: plancat.c:1802
Oid opno
Definition: primnodes.h:516
static bool is_opclause(const void *clause)
Definition: nodeFuncs.h:66
Selectivity clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: clausesel.c:69
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
Definition: relnode.c:374
List * args
Definition: primnodes.h:522
Selectivity booltestsel(PlannerInfo *root, BoolTestType booltesttype, Node *arg, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: selfuncs.c:1537
Selectivity boolvarsel(PlannerInfo *root, Node *arg, int varRelid)
Definition: selfuncs.c:1509
Definition: pg_list.h:50
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:427
bool constisnull
Definition: primnodes.h:215
int NumRelids(Node *clause)
Definition: clauses.c:2165