2
0

selfuncs.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*-------------------------------------------------------------------------
  2. *
  3. * selfuncs.h
  4. * Selectivity functions for standard operators, and assorted
  5. * infrastructure for selectivity and cost estimation.
  6. *
  7. *
  8. * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  9. * Portions Copyright (c) 1994, Regents of the University of California
  10. *
  11. * src/include/utils/selfuncs.h
  12. *
  13. *-------------------------------------------------------------------------
  14. */
  15. #ifndef SELFUNCS_H
  16. #define SELFUNCS_H
  17. #include "access/htup.h"
  18. #include "fmgr.h"
  19. #include "nodes/pathnodes.h"
  20. /*
  21. * Note: the default selectivity estimates are not chosen entirely at random.
  22. * We want them to be small enough to ensure that indexscans will be used if
  23. * available, for typical table densities of ~100 tuples/page. Thus, for
  24. * example, 0.01 is not quite small enough, since that makes it appear that
  25. * nearly all pages will be hit anyway. Also, since we sometimes estimate
  26. * eqsel as 1/num_distinct, we probably want DEFAULT_NUM_DISTINCT to equal
  27. * 1/DEFAULT_EQ_SEL.
  28. */
  29. /* default selectivity estimate for equalities such as "A = b" */
  30. #define DEFAULT_EQ_SEL 0.005
  31. /* default selectivity estimate for inequalities such as "A < b" */
  32. #define DEFAULT_INEQ_SEL 0.3333333333333333
  33. /* default selectivity estimate for range inequalities "A > b AND A < c" */
  34. #define DEFAULT_RANGE_INEQ_SEL 0.005
  35. /* default selectivity estimate for multirange inequalities "A > b AND A < c" */
  36. #define DEFAULT_MULTIRANGE_INEQ_SEL 0.005
  37. /* default selectivity estimate for pattern-match operators such as LIKE */
  38. #define DEFAULT_MATCH_SEL 0.005
  39. /* default selectivity estimate for other matching operators */
  40. #define DEFAULT_MATCHING_SEL 0.010
  41. /* default number of distinct values in a table */
  42. #define DEFAULT_NUM_DISTINCT 200
  43. /* default selectivity estimate for boolean and null test nodes */
  44. #define DEFAULT_UNK_SEL 0.005
  45. #define DEFAULT_NOT_UNK_SEL (1.0 - DEFAULT_UNK_SEL)
  46. /*
  47. * Clamp a computed probability estimate (which may suffer from roundoff or
  48. * estimation errors) to valid range. Argument must be a float variable.
  49. */
  50. #define CLAMP_PROBABILITY(p) \
  51. do { \
  52. if (p < 0.0) \
  53. p = 0.0; \
  54. else if (p > 1.0) \
  55. p = 1.0; \
  56. } while (0)
  57. /*
  58. * A set of flags which some selectivity estimation functions can pass back to
  59. * callers to provide further details about some assumptions which were made
  60. * during the estimation.
  61. */
  62. #define SELFLAG_USED_DEFAULT (1 << 0) /* Estimation fell back on one
  63. * of the DEFAULTs as defined
  64. * above. */
  65. typedef struct EstimationInfo
  66. {
  67. uint32 flags; /* Flags, as defined above to mark special
  68. * properties of the estimation. */
  69. } EstimationInfo;
  70. /* Return data from examine_variable and friends */
  71. typedef struct VariableStatData
  72. {
  73. Node *var; /* the Var or expression tree */
  74. RelOptInfo *rel; /* Relation, or NULL if not identifiable */
  75. HeapTuple statsTuple; /* pg_statistic tuple, or NULL if none */
  76. /* NB: if statsTuple!=NULL, it must be freed when caller is done */
  77. void (*freefunc) (HeapTuple tuple); /* how to free statsTuple */
  78. Oid vartype; /* exposed type of expression */
  79. Oid atttype; /* actual type (after stripping relabel) */
  80. int32 atttypmod; /* actual typmod (after stripping relabel) */
  81. bool isunique; /* matches unique index or DISTINCT clause */
  82. bool acl_ok; /* result of ACL check on table or column */
  83. } VariableStatData;
  84. #define ReleaseVariableStats(vardata) \
  85. do { \
  86. if (HeapTupleIsValid((vardata).statsTuple)) \
  87. (vardata).freefunc((vardata).statsTuple); \
  88. } while(0)
  89. /*
  90. * genericcostestimate is a general-purpose estimator that can be used for
  91. * most index types. In some cases we use genericcostestimate as the base
  92. * code and then incorporate additional index-type-specific knowledge in
  93. * the type-specific calling function. To avoid code duplication, we make
  94. * genericcostestimate return a number of intermediate values as well as
  95. * its preliminary estimates of the output cost values. The GenericCosts
  96. * struct includes all these values.
  97. *
  98. * Callers should initialize all fields of GenericCosts to zero. In addition,
  99. * they can set numIndexTuples to some positive value if they have a better
  100. * than default way of estimating the number of leaf index tuples visited.
  101. */
  102. typedef struct
  103. {
  104. /* These are the values the cost estimator must return to the planner */
  105. Cost indexStartupCost; /* index-related startup cost */
  106. Cost indexTotalCost; /* total index-related scan cost */
  107. Selectivity indexSelectivity; /* selectivity of index */
  108. double indexCorrelation; /* order correlation of index */
  109. /* Intermediate values we obtain along the way */
  110. double numIndexPages; /* number of leaf pages visited */
  111. double numIndexTuples; /* number of leaf tuples visited */
  112. double spc_random_page_cost; /* relevant random_page_cost value */
  113. double num_sa_scans; /* # indexscans from ScalarArrayOpExprs */
  114. } GenericCosts;
  115. /* Hooks for plugins to get control when we ask for stats */
  116. typedef bool (*get_relation_stats_hook_type) (PlannerInfo *root,
  117. RangeTblEntry *rte,
  118. AttrNumber attnum,
  119. VariableStatData *vardata);
  120. extern PGDLLIMPORT get_relation_stats_hook_type get_relation_stats_hook;
  121. typedef bool (*get_index_stats_hook_type) (PlannerInfo *root,
  122. Oid indexOid,
  123. AttrNumber indexattnum,
  124. VariableStatData *vardata);
  125. extern PGDLLIMPORT get_index_stats_hook_type get_index_stats_hook;
  126. /* Functions in selfuncs.c */
  127. extern void examine_variable(PlannerInfo *root, Node *node, int varRelid,
  128. VariableStatData *vardata);
  129. extern bool statistic_proc_security_check(VariableStatData *vardata, Oid func_oid);
  130. extern bool get_restriction_variable(PlannerInfo *root, List *args,
  131. int varRelid,
  132. VariableStatData *vardata, Node **other,
  133. bool *varonleft);
  134. extern void get_join_variables(PlannerInfo *root, List *args,
  135. SpecialJoinInfo *sjinfo,
  136. VariableStatData *vardata1,
  137. VariableStatData *vardata2,
  138. bool *join_is_reversed);
  139. extern double get_variable_numdistinct(VariableStatData *vardata,
  140. bool *isdefault);
  141. extern double mcv_selectivity(VariableStatData *vardata,
  142. FmgrInfo *opproc, Oid collation,
  143. Datum constval, bool varonleft,
  144. double *sumcommonp);
  145. extern double histogram_selectivity(VariableStatData *vardata,
  146. FmgrInfo *opproc, Oid collation,
  147. Datum constval, bool varonleft,
  148. int min_hist_size, int n_skip,
  149. int *hist_size);
  150. extern double generic_restriction_selectivity(PlannerInfo *root,
  151. Oid oproid, Oid collation,
  152. List *args, int varRelid,
  153. double default_selectivity);
  154. extern double ineq_histogram_selectivity(PlannerInfo *root,
  155. VariableStatData *vardata,
  156. Oid opoid, FmgrInfo *opproc,
  157. bool isgt, bool iseq,
  158. Oid collation,
  159. Datum constval, Oid consttype);
  160. extern double var_eq_const(VariableStatData *vardata,
  161. Oid oproid, Oid collation,
  162. Datum constval, bool constisnull,
  163. bool varonleft, bool negate);
  164. extern double var_eq_non_const(VariableStatData *vardata,
  165. Oid oproid, Oid collation,
  166. Node *other,
  167. bool varonleft, bool negate);
  168. extern Selectivity boolvarsel(PlannerInfo *root, Node *arg, int varRelid);
  169. extern Selectivity booltestsel(PlannerInfo *root, BoolTestType booltesttype,
  170. Node *arg, int varRelid,
  171. JoinType jointype, SpecialJoinInfo *sjinfo);
  172. extern Selectivity nulltestsel(PlannerInfo *root, NullTestType nulltesttype,
  173. Node *arg, int varRelid,
  174. JoinType jointype, SpecialJoinInfo *sjinfo);
  175. extern Selectivity scalararraysel(PlannerInfo *root,
  176. ScalarArrayOpExpr *clause,
  177. bool is_join_clause,
  178. int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo);
  179. extern int estimate_array_length(Node *arrayexpr);
  180. extern Selectivity rowcomparesel(PlannerInfo *root,
  181. RowCompareExpr *clause,
  182. int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo);
  183. extern void mergejoinscansel(PlannerInfo *root, Node *clause,
  184. Oid opfamily, int strategy, bool nulls_first,
  185. Selectivity *leftstart, Selectivity *leftend,
  186. Selectivity *rightstart, Selectivity *rightend);
  187. extern double estimate_num_groups(PlannerInfo *root, List *groupExprs,
  188. double input_rows, List **pgset,
  189. EstimationInfo *estinfo);
  190. extern void estimate_hash_bucket_stats(PlannerInfo *root,
  191. Node *hashkey, double nbuckets,
  192. Selectivity *mcv_freq,
  193. Selectivity *bucketsize_frac);
  194. extern double estimate_hashagg_tablesize(PlannerInfo *root, Path *path,
  195. const AggClauseCosts *agg_costs,
  196. double dNumGroups);
  197. extern List *get_quals_from_indexclauses(List *indexclauses);
  198. extern Cost index_other_operands_eval_cost(PlannerInfo *root,
  199. List *indexquals);
  200. extern List *add_predicate_to_index_quals(IndexOptInfo *index,
  201. List *indexQuals);
  202. extern void genericcostestimate(PlannerInfo *root, IndexPath *path,
  203. double loop_count,
  204. GenericCosts *costs);
  205. /* Functions in array_selfuncs.c */
  206. extern Selectivity scalararraysel_containment(PlannerInfo *root,
  207. Node *leftop, Node *rightop,
  208. Oid elemtype, bool isEquality, bool useOr,
  209. int varRelid);
  210. #endif /* SELFUNCS_H */