selfuncs.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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-2016, 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 "fmgr.h"
  18. #include "access/htup.h"
  19. #include "nodes/relation.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 pattern-match operators such as LIKE */
  36. #define DEFAULT_MATCH_SEL 0.005
  37. /* default number of distinct values in a table */
  38. #define DEFAULT_NUM_DISTINCT 200
  39. /* default selectivity estimate for boolean and null test nodes */
  40. #define DEFAULT_UNK_SEL 0.005
  41. #define DEFAULT_NOT_UNK_SEL (1.0 - DEFAULT_UNK_SEL)
  42. /*
  43. * Clamp a computed probability estimate (which may suffer from roundoff or
  44. * estimation errors) to valid range. Argument must be a float variable.
  45. */
  46. #define CLAMP_PROBABILITY(p) \
  47. do { \
  48. if (p < 0.0) \
  49. p = 0.0; \
  50. else if (p > 1.0) \
  51. p = 1.0; \
  52. } while (0)
  53. /* Return data from examine_variable and friends */
  54. typedef struct VariableStatData
  55. {
  56. Node *var; /* the Var or expression tree */
  57. RelOptInfo *rel; /* Relation, or NULL if not identifiable */
  58. HeapTuple statsTuple; /* pg_statistic tuple, or NULL if none */
  59. /* NB: if statsTuple!=NULL, it must be freed when caller is done */
  60. void (*freefunc) (HeapTuple tuple); /* how to free statsTuple */
  61. Oid vartype; /* exposed type of expression */
  62. Oid atttype; /* type to pass to get_attstatsslot */
  63. int32 atttypmod; /* typmod to pass to get_attstatsslot */
  64. bool isunique; /* matches unique index or DISTINCT clause */
  65. bool acl_ok; /* result of ACL check on table or column */
  66. } VariableStatData;
  67. #define ReleaseVariableStats(vardata) \
  68. do { \
  69. if (HeapTupleIsValid((vardata).statsTuple)) \
  70. (* (vardata).freefunc) ((vardata).statsTuple); \
  71. } while(0)
  72. typedef enum
  73. {
  74. Pattern_Type_Like, Pattern_Type_Like_IC,
  75. Pattern_Type_Regex, Pattern_Type_Regex_IC
  76. } Pattern_Type;
  77. typedef enum
  78. {
  79. Pattern_Prefix_None, Pattern_Prefix_Partial, Pattern_Prefix_Exact
  80. } Pattern_Prefix_Status;
  81. /*
  82. * deconstruct_indexquals is a simple function to examine the indexquals
  83. * attached to a proposed IndexPath. It returns a list of IndexQualInfo
  84. * structs, one per qual expression.
  85. */
  86. typedef struct
  87. {
  88. RestrictInfo *rinfo; /* the indexqual itself */
  89. int indexcol; /* zero-based index column number */
  90. bool varonleft; /* true if index column is on left of qual */
  91. Oid clause_op; /* qual's operator OID, if relevant */
  92. Node *other_operand; /* non-index operand of qual's operator */
  93. } IndexQualInfo;
  94. /*
  95. * genericcostestimate is a general-purpose estimator that can be used for
  96. * most index types. In some cases we use genericcostestimate as the base
  97. * code and then incorporate additional index-type-specific knowledge in
  98. * the type-specific calling function. To avoid code duplication, we make
  99. * genericcostestimate return a number of intermediate values as well as
  100. * its preliminary estimates of the output cost values. The GenericCosts
  101. * struct includes all these values.
  102. *
  103. * Callers should initialize all fields of GenericCosts to zero. In addition,
  104. * they can set numIndexTuples to some positive value if they have a better
  105. * than default way of estimating the number of leaf index tuples visited.
  106. */
  107. typedef struct
  108. {
  109. /* These are the values the cost estimator must return to the planner */
  110. Cost indexStartupCost; /* index-related startup cost */
  111. Cost indexTotalCost; /* total index-related scan cost */
  112. Selectivity indexSelectivity; /* selectivity of index */
  113. double indexCorrelation; /* order correlation of index */
  114. /* Intermediate values we obtain along the way */
  115. double numIndexPages; /* number of leaf pages visited */
  116. double numIndexTuples; /* number of leaf tuples visited */
  117. double spc_random_page_cost; /* relevant random_page_cost value */
  118. double num_sa_scans; /* # indexscans from ScalarArrayOps */
  119. } GenericCosts;
  120. /* Hooks for plugins to get control when we ask for stats */
  121. typedef bool (*get_relation_stats_hook_type) (PlannerInfo *root,
  122. RangeTblEntry *rte,
  123. AttrNumber attnum,
  124. VariableStatData *vardata);
  125. extern PGDLLIMPORT get_relation_stats_hook_type get_relation_stats_hook;
  126. typedef bool (*get_index_stats_hook_type) (PlannerInfo *root,
  127. Oid indexOid,
  128. AttrNumber indexattnum,
  129. VariableStatData *vardata);
  130. extern PGDLLIMPORT get_index_stats_hook_type get_index_stats_hook;
  131. /* Functions in selfuncs.c */
  132. extern void examine_variable(PlannerInfo *root, Node *node, int varRelid,
  133. VariableStatData *vardata);
  134. extern bool statistic_proc_security_check(VariableStatData *vardata, Oid func_oid);
  135. extern bool get_restriction_variable(PlannerInfo *root, List *args,
  136. int varRelid,
  137. VariableStatData *vardata, Node **other,
  138. bool *varonleft);
  139. extern void get_join_variables(PlannerInfo *root, List *args,
  140. SpecialJoinInfo *sjinfo,
  141. VariableStatData *vardata1,
  142. VariableStatData *vardata2,
  143. bool *join_is_reversed);
  144. extern double get_variable_numdistinct(VariableStatData *vardata,
  145. bool *isdefault);
  146. extern double mcv_selectivity(VariableStatData *vardata, FmgrInfo *opproc,
  147. Datum constval, bool varonleft,
  148. double *sumcommonp);
  149. extern double histogram_selectivity(VariableStatData *vardata, FmgrInfo *opproc,
  150. Datum constval, bool varonleft,
  151. int min_hist_size, int n_skip,
  152. int *hist_size);
  153. extern Pattern_Prefix_Status pattern_fixed_prefix(Const *patt,
  154. Pattern_Type ptype,
  155. Oid collation,
  156. Const **prefix,
  157. Selectivity *rest_selec);
  158. extern Const *make_greater_string(const Const *str_const, FmgrInfo *ltproc,
  159. Oid collation);
  160. extern Datum eqsel(PG_FUNCTION_ARGS);
  161. extern Datum neqsel(PG_FUNCTION_ARGS);
  162. extern Datum scalarltsel(PG_FUNCTION_ARGS);
  163. extern Datum scalargtsel(PG_FUNCTION_ARGS);
  164. extern Datum regexeqsel(PG_FUNCTION_ARGS);
  165. extern Datum icregexeqsel(PG_FUNCTION_ARGS);
  166. extern Datum likesel(PG_FUNCTION_ARGS);
  167. extern Datum iclikesel(PG_FUNCTION_ARGS);
  168. extern Datum regexnesel(PG_FUNCTION_ARGS);
  169. extern Datum icregexnesel(PG_FUNCTION_ARGS);
  170. extern Datum nlikesel(PG_FUNCTION_ARGS);
  171. extern Datum icnlikesel(PG_FUNCTION_ARGS);
  172. extern Datum eqjoinsel(PG_FUNCTION_ARGS);
  173. extern Datum neqjoinsel(PG_FUNCTION_ARGS);
  174. extern Datum scalarltjoinsel(PG_FUNCTION_ARGS);
  175. extern Datum scalargtjoinsel(PG_FUNCTION_ARGS);
  176. extern Datum regexeqjoinsel(PG_FUNCTION_ARGS);
  177. extern Datum icregexeqjoinsel(PG_FUNCTION_ARGS);
  178. extern Datum likejoinsel(PG_FUNCTION_ARGS);
  179. extern Datum iclikejoinsel(PG_FUNCTION_ARGS);
  180. extern Datum regexnejoinsel(PG_FUNCTION_ARGS);
  181. extern Datum icregexnejoinsel(PG_FUNCTION_ARGS);
  182. extern Datum nlikejoinsel(PG_FUNCTION_ARGS);
  183. extern Datum icnlikejoinsel(PG_FUNCTION_ARGS);
  184. extern Selectivity boolvarsel(PlannerInfo *root, Node *arg, int varRelid);
  185. extern Selectivity booltestsel(PlannerInfo *root, BoolTestType booltesttype,
  186. Node *arg, int varRelid,
  187. JoinType jointype, SpecialJoinInfo *sjinfo);
  188. extern Selectivity nulltestsel(PlannerInfo *root, NullTestType nulltesttype,
  189. Node *arg, int varRelid,
  190. JoinType jointype, SpecialJoinInfo *sjinfo);
  191. extern Selectivity scalararraysel(PlannerInfo *root,
  192. ScalarArrayOpExpr *clause,
  193. bool is_join_clause,
  194. int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo);
  195. extern int estimate_array_length(Node *arrayexpr);
  196. extern Selectivity rowcomparesel(PlannerInfo *root,
  197. RowCompareExpr *clause,
  198. int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo);
  199. extern void mergejoinscansel(PlannerInfo *root, Node *clause,
  200. Oid opfamily, int strategy, bool nulls_first,
  201. Selectivity *leftstart, Selectivity *leftend,
  202. Selectivity *rightstart, Selectivity *rightend);
  203. extern double estimate_num_groups(PlannerInfo *root, List *groupExprs,
  204. double input_rows, List **pgset);
  205. extern Selectivity estimate_hash_bucketsize(PlannerInfo *root, Node *hashkey,
  206. double nbuckets);
  207. extern List *deconstruct_indexquals(IndexPath *path);
  208. extern void genericcostestimate(PlannerInfo *root, IndexPath *path,
  209. double loop_count,
  210. List *qinfos,
  211. GenericCosts *costs);
  212. /* Functions in array_selfuncs.c */
  213. extern Selectivity scalararraysel_containment(PlannerInfo *root,
  214. Node *leftop, Node *rightop,
  215. Oid elemtype, bool isEquality, bool useOr,
  216. int varRelid);
  217. extern Datum arraycontsel(PG_FUNCTION_ARGS);
  218. extern Datum arraycontjoinsel(PG_FUNCTION_ARGS);
  219. #endif /* SELFUNCS_H */