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