gooderp18绿色标准版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
10KB

  1. /*-------------------------------------------------------------------------
  2. *
  3. * plancache.h
  4. * Plan cache definitions.
  5. *
  6. * See plancache.c for comments.
  7. *
  8. * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
  9. * Portions Copyright (c) 1994, Regents of the University of California
  10. *
  11. * src/include/utils/plancache.h
  12. *
  13. *-------------------------------------------------------------------------
  14. */
  15. #ifndef PLANCACHE_H
  16. #define PLANCACHE_H
  17. #include "access/tupdesc.h"
  18. #include "lib/ilist.h"
  19. #include "nodes/params.h"
  20. #include "utils/queryenvironment.h"
  21. /* Forward declaration, to avoid including parsenodes.h here */
  22. struct RawStmt;
  23. /* possible values for plan_cache_mode */
  24. typedef enum
  25. {
  26. PLAN_CACHE_MODE_AUTO,
  27. PLAN_CACHE_MODE_FORCE_GENERIC_PLAN,
  28. PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN
  29. } PlanCacheMode;
  30. /* GUC parameter */
  31. extern int plan_cache_mode;
  32. #define CACHEDPLANSOURCE_MAGIC 195726186
  33. #define CACHEDPLAN_MAGIC 953717834
  34. #define CACHEDEXPR_MAGIC 838275847
  35. /*
  36. * CachedPlanSource (which might better have been called CachedQuery)
  37. * represents a SQL query that we expect to use multiple times. It stores
  38. * the query source text, the raw parse tree, and the analyzed-and-rewritten
  39. * query tree, as well as adjunct data. Cache invalidation can happen as a
  40. * result of DDL affecting objects used by the query. In that case we discard
  41. * the analyzed-and-rewritten query tree, and rebuild it when next needed.
  42. *
  43. * An actual execution plan, represented by CachedPlan, is derived from the
  44. * CachedPlanSource when we need to execute the query. The plan could be
  45. * either generic (usable with any set of plan parameters) or custom (for a
  46. * specific set of parameters). plancache.c contains the logic that decides
  47. * which way to do it for any particular execution. If we are using a generic
  48. * cached plan then it is meant to be re-used across multiple executions, so
  49. * callers must always treat CachedPlans as read-only.
  50. *
  51. * Once successfully built and "saved", CachedPlanSources typically live
  52. * for the life of the backend, although they can be dropped explicitly.
  53. * CachedPlans are reference-counted and go away automatically when the last
  54. * reference is dropped. A CachedPlan can outlive the CachedPlanSource it
  55. * was created from.
  56. *
  57. * An "unsaved" CachedPlanSource can be used for generating plans, but it
  58. * lives in transient storage and will not be updated in response to sinval
  59. * events.
  60. *
  61. * CachedPlans made from saved CachedPlanSources are likewise in permanent
  62. * storage, so to avoid memory leaks, the reference-counted references to them
  63. * must be held in permanent data structures or ResourceOwners. CachedPlans
  64. * made from unsaved CachedPlanSources are in children of the caller's
  65. * memory context, so references to them should not be longer-lived than
  66. * that context. (Reference counting is somewhat pro forma in that case,
  67. * though it may be useful if the CachedPlan can be discarded early.)
  68. *
  69. * A CachedPlanSource has two associated memory contexts: one that holds the
  70. * struct itself, the query source text and the raw parse tree, and another
  71. * context that holds the rewritten query tree and associated data. This
  72. * allows the query tree to be discarded easily when it is invalidated.
  73. *
  74. * Some callers wish to use the CachedPlan API even with one-shot queries
  75. * that have no reason to be saved at all. We therefore support a "oneshot"
  76. * variant that does no data copying or invalidation checking. In this case
  77. * there are no separate memory contexts: the CachedPlanSource struct and
  78. * all subsidiary data live in the caller's CurrentMemoryContext, and there
  79. * is no way to free memory short of clearing that entire context. A oneshot
  80. * plan is always treated as unsaved.
  81. *
  82. * Note: the string referenced by commandTag is not subsidiary storage;
  83. * it is assumed to be a compile-time-constant string. As with portals,
  84. * commandTag shall be NULL if and only if the original query string (before
  85. * rewriting) was an empty string.
  86. */
  87. typedef struct CachedPlanSource
  88. {
  89. int magic; /* should equal CACHEDPLANSOURCE_MAGIC */
  90. struct RawStmt *raw_parse_tree; /* output of raw_parser(), or NULL */
  91. const char *query_string; /* source text of query */
  92. const char *commandTag; /* command tag (a constant!), or NULL */
  93. Oid *param_types; /* array of parameter type OIDs, or NULL */
  94. int num_params; /* length of param_types array */
  95. ParserSetupHook parserSetup; /* alternative parameter spec method */
  96. void *parserSetupArg;
  97. int cursor_options; /* cursor options used for planning */
  98. bool fixed_result; /* disallow change in result tupdesc? */
  99. TupleDesc resultDesc; /* result type; NULL = doesn't return tuples */
  100. MemoryContext context; /* memory context holding all above */
  101. /* These fields describe the current analyzed-and-rewritten query tree: */
  102. List *query_list; /* list of Query nodes, or NIL if not valid */
  103. List *relationOids; /* OIDs of relations the queries depend on */
  104. List *invalItems; /* other dependencies, as PlanInvalItems */
  105. struct OverrideSearchPath *search_path; /* search_path used for parsing
  106. * and planning */
  107. MemoryContext query_context; /* context holding the above, or NULL */
  108. Oid rewriteRoleId; /* Role ID we did rewriting for */
  109. bool rewriteRowSecurity; /* row_security used during rewrite */
  110. bool dependsOnRLS; /* is rewritten query specific to the above? */
  111. /* If we have a generic plan, this is a reference-counted link to it: */
  112. struct CachedPlan *gplan; /* generic plan, or NULL if not valid */
  113. /* Some state flags: */
  114. bool is_oneshot; /* is it a "oneshot" plan? */
  115. bool is_complete; /* has CompleteCachedPlan been done? */
  116. bool is_saved; /* has CachedPlanSource been "saved"? */
  117. bool is_valid; /* is the query_list currently valid? */
  118. int generation; /* increments each time we create a plan */
  119. /* If CachedPlanSource has been saved, it is a member of a global list */
  120. dlist_node node; /* list link, if is_saved */
  121. /* State kept to help decide whether to use custom or generic plans: */
  122. double generic_cost; /* cost of generic plan, or -1 if not known */
  123. double total_custom_cost; /* total cost of custom plans so far */
  124. int num_custom_plans; /* number of plans included in total */
  125. } CachedPlanSource;
  126. /*
  127. * CachedPlan represents an execution plan derived from a CachedPlanSource.
  128. * The reference count includes both the link from the parent CachedPlanSource
  129. * (if any), and any active plan executions, so the plan can be discarded
  130. * exactly when refcount goes to zero. Both the struct itself and the
  131. * subsidiary data live in the context denoted by the context field.
  132. * This makes it easy to free a no-longer-needed cached plan. (However,
  133. * if is_oneshot is true, the context does not belong solely to the CachedPlan
  134. * so no freeing is possible.)
  135. */
  136. typedef struct CachedPlan
  137. {
  138. int magic; /* should equal CACHEDPLAN_MAGIC */
  139. List *stmt_list; /* list of PlannedStmts */
  140. bool is_oneshot; /* is it a "oneshot" plan? */
  141. bool is_saved; /* is CachedPlan in a long-lived context? */
  142. bool is_valid; /* is the stmt_list currently valid? */
  143. Oid planRoleId; /* Role ID the plan was created for */
  144. bool dependsOnRole; /* is plan specific to that role? */
  145. TransactionId saved_xmin; /* if valid, replan when TransactionXmin
  146. * changes from this value */
  147. int generation; /* parent's generation number for this plan */
  148. int refcount; /* count of live references to this struct */
  149. MemoryContext context; /* context containing this CachedPlan */
  150. } CachedPlan;
  151. /*
  152. * CachedExpression is a low-overhead mechanism for caching the planned form
  153. * of standalone scalar expressions. While such expressions are not usually
  154. * subject to cache invalidation events, that can happen, for example because
  155. * of replacement of a SQL function that was inlined into the expression.
  156. * The plancache takes care of storing the expression tree and marking it
  157. * invalid if a cache invalidation occurs, but the caller must notice the
  158. * !is_valid status and discard the obsolete expression without reusing it.
  159. * We do not store the original parse tree, only the planned expression;
  160. * this is an optimization based on the assumption that we usually will not
  161. * need to replan for the life of the session.
  162. */
  163. typedef struct CachedExpression
  164. {
  165. int magic; /* should equal CACHEDEXPR_MAGIC */
  166. Node *expr; /* planned form of expression */
  167. bool is_valid; /* is the expression still valid? */
  168. /* remaining fields should be treated as private to plancache.c: */
  169. List *relationOids; /* OIDs of relations the expr depends on */
  170. List *invalItems; /* other dependencies, as PlanInvalItems */
  171. MemoryContext context; /* context containing this CachedExpression */
  172. dlist_node node; /* link in global list of CachedExpressions */
  173. } CachedExpression;
  174. extern void InitPlanCache(void);
  175. extern void ResetPlanCache(void);
  176. extern CachedPlanSource *CreateCachedPlan(struct RawStmt *raw_parse_tree,
  177. const char *query_string,
  178. const char *commandTag);
  179. extern CachedPlanSource *CreateOneShotCachedPlan(struct RawStmt *raw_parse_tree,
  180. const char *query_string,
  181. const char *commandTag);
  182. extern void CompleteCachedPlan(CachedPlanSource *plansource,
  183. List *querytree_list,
  184. MemoryContext querytree_context,
  185. Oid *param_types,
  186. int num_params,
  187. ParserSetupHook parserSetup,
  188. void *parserSetupArg,
  189. int cursor_options,
  190. bool fixed_result);
  191. extern void SaveCachedPlan(CachedPlanSource *plansource);
  192. extern void DropCachedPlan(CachedPlanSource *plansource);
  193. extern void CachedPlanSetParentContext(CachedPlanSource *plansource,
  194. MemoryContext newcontext);
  195. extern CachedPlanSource *CopyCachedPlan(CachedPlanSource *plansource);
  196. extern bool CachedPlanIsValid(CachedPlanSource *plansource);
  197. extern List *CachedPlanGetTargetList(CachedPlanSource *plansource,
  198. QueryEnvironment *queryEnv);
  199. extern CachedPlan *GetCachedPlan(CachedPlanSource *plansource,
  200. ParamListInfo boundParams,
  201. bool useResOwner,
  202. QueryEnvironment *queryEnv);
  203. extern void ReleaseCachedPlan(CachedPlan *plan, bool useResOwner);
  204. extern CachedExpression *GetCachedExpression(Node *expr);
  205. extern void FreeCachedExpression(CachedExpression *cexpr);
  206. #endif /* PLANCACHE_H */
上海开阖软件有限公司 沪ICP备12045867号-1