00001 /*------------------------------------------------------------------------- 00002 * 00003 * plancache.h 00004 * Plan cache definitions. 00005 * 00006 * See plancache.c for comments. 00007 * 00008 * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group 00009 * Portions Copyright (c) 1994, Regents of the University of California 00010 * 00011 * src/include/utils/plancache.h 00012 * 00013 *------------------------------------------------------------------------- 00014 */ 00015 #ifndef PLANCACHE_H 00016 #define PLANCACHE_H 00017 00018 #include "access/tupdesc.h" 00019 #include "nodes/params.h" 00020 00021 #define CACHEDPLANSOURCE_MAGIC 195726186 00022 #define CACHEDPLAN_MAGIC 953717834 00023 00024 /* 00025 * CachedPlanSource (which might better have been called CachedQuery) 00026 * represents a SQL query that we expect to use multiple times. It stores 00027 * the query source text, the raw parse tree, and the analyzed-and-rewritten 00028 * query tree, as well as adjunct data. Cache invalidation can happen as a 00029 * result of DDL affecting objects used by the query. In that case we discard 00030 * the analyzed-and-rewritten query tree, and rebuild it when next needed. 00031 * 00032 * An actual execution plan, represented by CachedPlan, is derived from the 00033 * CachedPlanSource when we need to execute the query. The plan could be 00034 * either generic (usable with any set of plan parameters) or custom (for a 00035 * specific set of parameters). plancache.c contains the logic that decides 00036 * which way to do it for any particular execution. If we are using a generic 00037 * cached plan then it is meant to be re-used across multiple executions, so 00038 * callers must always treat CachedPlans as read-only. 00039 * 00040 * Once successfully built and "saved", CachedPlanSources typically live 00041 * for the life of the backend, although they can be dropped explicitly. 00042 * CachedPlans are reference-counted and go away automatically when the last 00043 * reference is dropped. A CachedPlan can outlive the CachedPlanSource it 00044 * was created from. 00045 * 00046 * An "unsaved" CachedPlanSource can be used for generating plans, but it 00047 * lives in transient storage and will not be updated in response to sinval 00048 * events. 00049 * 00050 * CachedPlans made from saved CachedPlanSources are likewise in permanent 00051 * storage, so to avoid memory leaks, the reference-counted references to them 00052 * must be held in permanent data structures or ResourceOwners. CachedPlans 00053 * made from unsaved CachedPlanSources are in children of the caller's 00054 * memory context, so references to them should not be longer-lived than 00055 * that context. (Reference counting is somewhat pro forma in that case, 00056 * though it may be useful if the CachedPlan can be discarded early.) 00057 * 00058 * A CachedPlanSource has two associated memory contexts: one that holds the 00059 * struct itself, the query source text and the raw parse tree, and another 00060 * context that holds the rewritten query tree and associated data. This 00061 * allows the query tree to be discarded easily when it is invalidated. 00062 * 00063 * Some callers wish to use the CachedPlan API even with one-shot queries 00064 * that have no reason to be saved at all. We therefore support a "oneshot" 00065 * variant that does no data copying or invalidation checking. In this case 00066 * there are no separate memory contexts: the CachedPlanSource struct and 00067 * all subsidiary data live in the caller's CurrentMemoryContext, and there 00068 * is no way to free memory short of clearing that entire context. A oneshot 00069 * plan is always treated as unsaved. 00070 * 00071 * Note: the string referenced by commandTag is not subsidiary storage; 00072 * it is assumed to be a compile-time-constant string. As with portals, 00073 * commandTag shall be NULL if and only if the original query string (before 00074 * rewriting) was an empty string. 00075 */ 00076 typedef struct CachedPlanSource 00077 { 00078 int magic; /* should equal CACHEDPLANSOURCE_MAGIC */ 00079 Node *raw_parse_tree; /* output of raw_parser() */ 00080 const char *query_string; /* source text of query */ 00081 const char *commandTag; /* command tag (a constant!), or NULL */ 00082 Oid *param_types; /* array of parameter type OIDs, or NULL */ 00083 int num_params; /* length of param_types array */ 00084 ParserSetupHook parserSetup; /* alternative parameter spec method */ 00085 void *parserSetupArg; 00086 int cursor_options; /* cursor options used for planning */ 00087 bool fixed_result; /* disallow change in result tupdesc? */ 00088 TupleDesc resultDesc; /* result type; NULL = doesn't return tuples */ 00089 MemoryContext context; /* memory context holding all above */ 00090 /* These fields describe the current analyzed-and-rewritten query tree: */ 00091 List *query_list; /* list of Query nodes, or NIL if not valid */ 00092 List *relationOids; /* OIDs of relations the queries depend on */ 00093 List *invalItems; /* other dependencies, as PlanInvalItems */ 00094 struct OverrideSearchPath *search_path; /* search_path used for 00095 * parsing and planning */ 00096 MemoryContext query_context; /* context holding the above, or NULL */ 00097 /* If we have a generic plan, this is a reference-counted link to it: */ 00098 struct CachedPlan *gplan; /* generic plan, or NULL if not valid */ 00099 /* Some state flags: */ 00100 bool is_oneshot; /* is it a "oneshot" plan? */ 00101 bool is_complete; /* has CompleteCachedPlan been done? */ 00102 bool is_saved; /* has CachedPlanSource been "saved"? */ 00103 bool is_valid; /* is the query_list currently valid? */ 00104 int generation; /* increments each time we create a plan */ 00105 /* If CachedPlanSource has been saved, it is a member of a global list */ 00106 struct CachedPlanSource *next_saved; /* list link, if so */ 00107 /* State kept to help decide whether to use custom or generic plans: */ 00108 double generic_cost; /* cost of generic plan, or -1 if not known */ 00109 double total_custom_cost; /* total cost of custom plans so far */ 00110 int num_custom_plans; /* number of plans included in total */ 00111 } CachedPlanSource; 00112 00113 /* 00114 * CachedPlan represents an execution plan derived from a CachedPlanSource. 00115 * The reference count includes both the link from the parent CachedPlanSource 00116 * (if any), and any active plan executions, so the plan can be discarded 00117 * exactly when refcount goes to zero. Both the struct itself and the 00118 * subsidiary data live in the context denoted by the context field. 00119 * This makes it easy to free a no-longer-needed cached plan. (However, 00120 * if is_oneshot is true, the context does not belong solely to the CachedPlan 00121 * so no freeing is possible.) 00122 */ 00123 typedef struct CachedPlan 00124 { 00125 int magic; /* should equal CACHEDPLAN_MAGIC */ 00126 List *stmt_list; /* list of statement nodes (PlannedStmts and 00127 * bare utility statements) */ 00128 bool is_oneshot; /* is it a "oneshot" plan? */ 00129 bool is_saved; /* is CachedPlan in a long-lived context? */ 00130 bool is_valid; /* is the stmt_list currently valid? */ 00131 TransactionId saved_xmin; /* if valid, replan when TransactionXmin 00132 * changes from this value */ 00133 int generation; /* parent's generation number for this plan */ 00134 int refcount; /* count of live references to this struct */ 00135 MemoryContext context; /* context containing this CachedPlan */ 00136 } CachedPlan; 00137 00138 00139 extern void InitPlanCache(void); 00140 extern void ResetPlanCache(void); 00141 00142 extern CachedPlanSource *CreateCachedPlan(Node *raw_parse_tree, 00143 const char *query_string, 00144 const char *commandTag); 00145 extern CachedPlanSource *CreateOneShotCachedPlan(Node *raw_parse_tree, 00146 const char *query_string, 00147 const char *commandTag); 00148 extern void CompleteCachedPlan(CachedPlanSource *plansource, 00149 List *querytree_list, 00150 MemoryContext querytree_context, 00151 Oid *param_types, 00152 int num_params, 00153 ParserSetupHook parserSetup, 00154 void *parserSetupArg, 00155 int cursor_options, 00156 bool fixed_result); 00157 00158 extern void SaveCachedPlan(CachedPlanSource *plansource); 00159 extern void DropCachedPlan(CachedPlanSource *plansource); 00160 00161 extern void CachedPlanSetParentContext(CachedPlanSource *plansource, 00162 MemoryContext newcontext); 00163 00164 extern CachedPlanSource *CopyCachedPlan(CachedPlanSource *plansource); 00165 00166 extern bool CachedPlanIsValid(CachedPlanSource *plansource); 00167 00168 extern List *CachedPlanGetTargetList(CachedPlanSource *plansource); 00169 00170 extern CachedPlan *GetCachedPlan(CachedPlanSource *plansource, 00171 ParamListInfo boundParams, 00172 bool useResOwner); 00173 extern void ReleaseCachedPlan(CachedPlan *plan, bool useResOwner); 00174 00175 #endif /* PLANCACHE_H */