2
0

plancache.h 11 KB

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