1 /*-------------------------------------------------------------------------
2  *
3  * plancache.c
4  *	  Plan cache management.
5  *
6  * The plan cache manager has two principal responsibilities: deciding when
7  * to use a generic plan versus a custom (parameter-value-specific) plan,
8  * and tracking whether cached plans need to be invalidated because of schema
9  * changes in the objects they depend on.
10  *
11  * The logic for choosing generic or custom plans is in choose_custom_plan,
12  * which see for comments.
13  *
14  * Cache invalidation is driven off sinval events.  Any CachedPlanSource
15  * that matches the event is marked invalid, as is its generic CachedPlan
16  * if it has one.  When (and if) the next demand for a cached plan occurs,
17  * parse analysis and rewrite is repeated to build a new valid query tree,
18  * and then planning is performed as normal.  We also force re-analysis and
19  * re-planning if the active search_path is different from the previous time
20  * or, if RLS is involved, if the user changes or the RLS environment changes.
21  *
22  * Note that if the sinval was a result of user DDL actions, parse analysis
23  * could throw an error, for example if a column referenced by the query is
24  * no longer present.  Another possibility is for the query's output tupdesc
25  * to change (for instance "SELECT *" might expand differently than before).
26  * The creator of a cached plan can specify whether it is allowable for the
27  * query to change output tupdesc on replan --- if so, it's up to the
28  * caller to notice changes and cope with them.
29  *
30  * Currently, we track exactly the dependencies of plans on relations,
31  * user-defined functions, and domains.  On relcache invalidation events or
32  * pg_proc or pg_type syscache invalidation events, we invalidate just those
33  * plans that depend on the particular object being modified.  (Note: this
34  * scheme assumes that any table modification that requires replanning will
35  * generate a relcache inval event.)  We also watch for inval events on
36  * certain other system catalogs, such as pg_namespace; but for them, our
37  * response is just to invalidate all plans.  We expect updates on those
38  * catalogs to be infrequent enough that more-detailed tracking is not worth
39  * the effort.
40  *
41  * In addition to full-fledged query plans, we provide a facility for
42  * detecting invalidations of simple scalar expressions.  This is fairly
43  * bare-bones; it's the caller's responsibility to build a new expression
44  * if the old one gets invalidated.
45  *
46  *
47  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
48  * Portions Copyright (c) 1994, Regents of the University of California
49  *
50  * IDENTIFICATION
51  *	  src/backend/utils/cache/plancache.c
52  *
53  *-------------------------------------------------------------------------
54  */
55 #include "postgres.h"
56 
57 #include <limits.h>
58 
59 #include "access/transam.h"
60 #include "catalog/namespace.h"
61 #include "executor/executor.h"
62 #include "miscadmin.h"
63 #include "nodes/nodeFuncs.h"
64 #include "optimizer/optimizer.h"
65 #include "parser/analyze.h"
66 #include "parser/parsetree.h"
67 #include "storage/lmgr.h"
68 #include "tcop/pquery.h"
69 #include "tcop/utility.h"
70 #include "utils/inval.h"
71 #include "utils/memutils.h"
72 #include "utils/resowner_private.h"
73 #include "utils/rls.h"
74 #include "utils/snapmgr.h"
75 #include "utils/syscache.h"
76 
77 
78 /*
79  * We must skip "overhead" operations that involve database access when the
80  * cached plan's subject statement is a transaction control command.
81  */
82 #define IsTransactionStmtPlan(plansource)  \
83 	((plansource)->raw_parse_tree && \
84 	 IsA((plansource)->raw_parse_tree->stmt, TransactionStmt))
85 
86 /*
87  * This is the head of the backend's list of "saved" CachedPlanSources (i.e.,
88  * those that are in long-lived storage and are examined for sinval events).
89  * We use a dlist instead of separate List cells so that we can guarantee
90  * to save a CachedPlanSource without error.
91  */
92 static dlist_head saved_plan_list = DLIST_STATIC_INIT(saved_plan_list);
93 
94 /*
95  * This is the head of the backend's list of CachedExpressions.
96  */
97 static dlist_head cached_expression_list = DLIST_STATIC_INIT(cached_expression_list);
98 
99 static void ReleaseGenericPlan(CachedPlanSource *plansource);
100 static List *RevalidateCachedQuery(CachedPlanSource *plansource,
101 								   QueryEnvironment *queryEnv);
102 static bool CheckCachedPlan(CachedPlanSource *plansource);
103 static CachedPlan *BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
104 								   ParamListInfo boundParams, QueryEnvironment *queryEnv);
105 static bool choose_custom_plan(CachedPlanSource *plansource,
106 							   ParamListInfo boundParams);
107 static double cached_plan_cost(CachedPlan *plan, bool include_planner);
108 static Query *QueryListGetPrimaryStmt(List *stmts);
109 static void AcquireExecutorLocks(List *stmt_list, bool acquire);
110 static void AcquirePlannerLocks(List *stmt_list, bool acquire);
111 static void ScanQueryForLocks(Query *parsetree, bool acquire);
112 static bool ScanQueryWalker(Node *node, bool *acquire);
113 static TupleDesc PlanCacheComputeResultDesc(List *stmt_list);
114 static void PlanCacheRelCallback(Datum arg, Oid relid);
115 static void PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue);
116 static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue);
117 
118 /* GUC parameter */
119 int			plan_cache_mode;
120 
121 /*
122  * InitPlanCache: initialize module during InitPostgres.
123  *
124  * All we need to do is hook into inval.c's callback lists.
125  */
126 void
InitPlanCache(void)127 InitPlanCache(void)
128 {
129 	CacheRegisterRelcacheCallback(PlanCacheRelCallback, (Datum) 0);
130 	CacheRegisterSyscacheCallback(PROCOID, PlanCacheObjectCallback, (Datum) 0);
131 	CacheRegisterSyscacheCallback(TYPEOID, PlanCacheObjectCallback, (Datum) 0);
132 	CacheRegisterSyscacheCallback(NAMESPACEOID, PlanCacheSysCallback, (Datum) 0);
133 	CacheRegisterSyscacheCallback(OPEROID, PlanCacheSysCallback, (Datum) 0);
134 	CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum) 0);
135 	CacheRegisterSyscacheCallback(FOREIGNSERVEROID, PlanCacheSysCallback, (Datum) 0);
136 	CacheRegisterSyscacheCallback(FOREIGNDATAWRAPPEROID, PlanCacheSysCallback, (Datum) 0);
137 }
138 
139 /*
140  * CreateCachedPlan: initially create a plan cache entry.
141  *
142  * Creation of a cached plan is divided into two steps, CreateCachedPlan and
143  * CompleteCachedPlan.  CreateCachedPlan should be called after running the
144  * query through raw_parser, but before doing parse analysis and rewrite;
145  * CompleteCachedPlan is called after that.  The reason for this arrangement
146  * is that it can save one round of copying of the raw parse tree, since
147  * the parser will normally scribble on the raw parse tree.  Callers would
148  * otherwise need to make an extra copy of the parse tree to ensure they
149  * still had a clean copy to present at plan cache creation time.
150  *
151  * All arguments presented to CreateCachedPlan are copied into a memory
152  * context created as a child of the call-time CurrentMemoryContext, which
153  * should be a reasonably short-lived working context that will go away in
154  * event of an error.  This ensures that the cached plan data structure will
155  * likewise disappear if an error occurs before we have fully constructed it.
156  * Once constructed, the cached plan can be made longer-lived, if needed,
157  * by calling SaveCachedPlan.
158  *
159  * raw_parse_tree: output of raw_parser(), or NULL if empty query
160  * query_string: original query text
161  * commandTag: command tag for query, or UNKNOWN if empty query
162  */
163 CachedPlanSource *
CreateCachedPlan(RawStmt * raw_parse_tree,const char * query_string,CommandTag commandTag)164 CreateCachedPlan(RawStmt *raw_parse_tree,
165 				 const char *query_string,
166 				 CommandTag commandTag)
167 {
168 	CachedPlanSource *plansource;
169 	MemoryContext source_context;
170 	MemoryContext oldcxt;
171 
172 	Assert(query_string != NULL);	/* required as of 8.4 */
173 
174 	/*
175 	 * Make a dedicated memory context for the CachedPlanSource and its
176 	 * permanent subsidiary data.  It's probably not going to be large, but
177 	 * just in case, allow it to grow large.  Initially it's a child of the
178 	 * caller's context (which we assume to be transient), so that it will be
179 	 * cleaned up on error.
180 	 */
181 	source_context = AllocSetContextCreate(CurrentMemoryContext,
182 										   "CachedPlanSource",
183 										   ALLOCSET_START_SMALL_SIZES);
184 
185 	/*
186 	 * Create and fill the CachedPlanSource struct within the new context.
187 	 * Most fields are just left empty for the moment.
188 	 */
189 	oldcxt = MemoryContextSwitchTo(source_context);
190 
191 	plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
192 	plansource->magic = CACHEDPLANSOURCE_MAGIC;
193 	plansource->raw_parse_tree = copyObject(raw_parse_tree);
194 	plansource->query_string = pstrdup(query_string);
195 	MemoryContextSetIdentifier(source_context, plansource->query_string);
196 	plansource->commandTag = commandTag;
197 	plansource->param_types = NULL;
198 	plansource->num_params = 0;
199 	plansource->parserSetup = NULL;
200 	plansource->parserSetupArg = NULL;
201 	plansource->cursor_options = 0;
202 	plansource->fixed_result = false;
203 	plansource->resultDesc = NULL;
204 	plansource->context = source_context;
205 	plansource->query_list = NIL;
206 	plansource->relationOids = NIL;
207 	plansource->invalItems = NIL;
208 	plansource->search_path = NULL;
209 	plansource->query_context = NULL;
210 	plansource->rewriteRoleId = InvalidOid;
211 	plansource->rewriteRowSecurity = false;
212 	plansource->dependsOnRLS = false;
213 	plansource->gplan = NULL;
214 	plansource->is_oneshot = false;
215 	plansource->is_complete = false;
216 	plansource->is_saved = false;
217 	plansource->is_valid = false;
218 	plansource->generation = 0;
219 	plansource->generic_cost = -1;
220 	plansource->total_custom_cost = 0;
221 	plansource->num_generic_plans = 0;
222 	plansource->num_custom_plans = 0;
223 
224 	MemoryContextSwitchTo(oldcxt);
225 
226 	return plansource;
227 }
228 
229 /*
230  * CreateOneShotCachedPlan: initially create a one-shot plan cache entry.
231  *
232  * This variant of CreateCachedPlan creates a plan cache entry that is meant
233  * to be used only once.  No data copying occurs: all data structures remain
234  * in the caller's memory context (which typically should get cleared after
235  * completing execution).  The CachedPlanSource struct itself is also created
236  * in that context.
237  *
238  * A one-shot plan cannot be saved or copied, since we make no effort to
239  * preserve the raw parse tree unmodified.  There is also no support for
240  * invalidation, so plan use must be completed in the current transaction,
241  * and DDL that might invalidate the querytree_list must be avoided as well.
242  *
243  * raw_parse_tree: output of raw_parser(), or NULL if empty query
244  * query_string: original query text
245  * commandTag: command tag for query, or NULL if empty query
246  */
247 CachedPlanSource *
CreateOneShotCachedPlan(RawStmt * raw_parse_tree,const char * query_string,CommandTag commandTag)248 CreateOneShotCachedPlan(RawStmt *raw_parse_tree,
249 						const char *query_string,
250 						CommandTag commandTag)
251 {
252 	CachedPlanSource *plansource;
253 
254 	Assert(query_string != NULL);	/* required as of 8.4 */
255 
256 	/*
257 	 * Create and fill the CachedPlanSource struct within the caller's memory
258 	 * context.  Most fields are just left empty for the moment.
259 	 */
260 	plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
261 	plansource->magic = CACHEDPLANSOURCE_MAGIC;
262 	plansource->raw_parse_tree = raw_parse_tree;
263 	plansource->query_string = query_string;
264 	plansource->commandTag = commandTag;
265 	plansource->param_types = NULL;
266 	plansource->num_params = 0;
267 	plansource->parserSetup = NULL;
268 	plansource->parserSetupArg = NULL;
269 	plansource->cursor_options = 0;
270 	plansource->fixed_result = false;
271 	plansource->resultDesc = NULL;
272 	plansource->context = CurrentMemoryContext;
273 	plansource->query_list = NIL;
274 	plansource->relationOids = NIL;
275 	plansource->invalItems = NIL;
276 	plansource->search_path = NULL;
277 	plansource->query_context = NULL;
278 	plansource->rewriteRoleId = InvalidOid;
279 	plansource->rewriteRowSecurity = false;
280 	plansource->dependsOnRLS = false;
281 	plansource->gplan = NULL;
282 	plansource->is_oneshot = true;
283 	plansource->is_complete = false;
284 	plansource->is_saved = false;
285 	plansource->is_valid = false;
286 	plansource->generation = 0;
287 	plansource->generic_cost = -1;
288 	plansource->total_custom_cost = 0;
289 	plansource->num_generic_plans = 0;
290 	plansource->num_custom_plans = 0;
291 
292 	return plansource;
293 }
294 
295 /*
296  * CompleteCachedPlan: second step of creating a plan cache entry.
297  *
298  * Pass in the analyzed-and-rewritten form of the query, as well as the
299  * required subsidiary data about parameters and such.  All passed values will
300  * be copied into the CachedPlanSource's memory, except as specified below.
301  * After this is called, GetCachedPlan can be called to obtain a plan, and
302  * optionally the CachedPlanSource can be saved using SaveCachedPlan.
303  *
304  * If querytree_context is not NULL, the querytree_list must be stored in that
305  * context (but the other parameters need not be).  The querytree_list is not
306  * copied, rather the given context is kept as the initial query_context of
307  * the CachedPlanSource.  (It should have been created as a child of the
308  * caller's working memory context, but it will now be reparented to belong
309  * to the CachedPlanSource.)  The querytree_context is normally the context in
310  * which the caller did raw parsing and parse analysis.  This approach saves
311  * one tree copying step compared to passing NULL, but leaves lots of extra
312  * cruft in the query_context, namely whatever extraneous stuff parse analysis
313  * created, as well as whatever went unused from the raw parse tree.  Using
314  * this option is a space-for-time tradeoff that is appropriate if the
315  * CachedPlanSource is not expected to survive long.
316  *
317  * plancache.c cannot know how to copy the data referenced by parserSetupArg,
318  * and it would often be inappropriate to do so anyway.  When using that
319  * option, it is caller's responsibility that the referenced data remains
320  * valid for as long as the CachedPlanSource exists.
321  *
322  * If the CachedPlanSource is a "oneshot" plan, then no querytree copying
323  * occurs at all, and querytree_context is ignored; it is caller's
324  * responsibility that the passed querytree_list is sufficiently long-lived.
325  *
326  * plansource: structure returned by CreateCachedPlan
327  * querytree_list: analyzed-and-rewritten form of query (list of Query nodes)
328  * querytree_context: memory context containing querytree_list,
329  *					  or NULL to copy querytree_list into a fresh context
330  * param_types: array of fixed parameter type OIDs, or NULL if none
331  * num_params: number of fixed parameters
332  * parserSetup: alternate method for handling query parameters
333  * parserSetupArg: data to pass to parserSetup
334  * cursor_options: options bitmask to pass to planner
335  * fixed_result: true to disallow future changes in query's result tupdesc
336  */
337 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)338 CompleteCachedPlan(CachedPlanSource *plansource,
339 				   List *querytree_list,
340 				   MemoryContext querytree_context,
341 				   Oid *param_types,
342 				   int num_params,
343 				   ParserSetupHook parserSetup,
344 				   void *parserSetupArg,
345 				   int cursor_options,
346 				   bool fixed_result)
347 {
348 	MemoryContext source_context = plansource->context;
349 	MemoryContext oldcxt = CurrentMemoryContext;
350 
351 	/* Assert caller is doing things in a sane order */
352 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
353 	Assert(!plansource->is_complete);
354 
355 	/*
356 	 * If caller supplied a querytree_context, reparent it underneath the
357 	 * CachedPlanSource's context; otherwise, create a suitable context and
358 	 * copy the querytree_list into it.  But no data copying should be done
359 	 * for one-shot plans; for those, assume the passed querytree_list is
360 	 * sufficiently long-lived.
361 	 */
362 	if (plansource->is_oneshot)
363 	{
364 		querytree_context = CurrentMemoryContext;
365 	}
366 	else if (querytree_context != NULL)
367 	{
368 		MemoryContextSetParent(querytree_context, source_context);
369 		MemoryContextSwitchTo(querytree_context);
370 	}
371 	else
372 	{
373 		/* Again, it's a good bet the querytree_context can be small */
374 		querytree_context = AllocSetContextCreate(source_context,
375 												  "CachedPlanQuery",
376 												  ALLOCSET_START_SMALL_SIZES);
377 		MemoryContextSwitchTo(querytree_context);
378 		querytree_list = copyObject(querytree_list);
379 	}
380 
381 	plansource->query_context = querytree_context;
382 	plansource->query_list = querytree_list;
383 
384 	if (!plansource->is_oneshot && !IsTransactionStmtPlan(plansource))
385 	{
386 		/*
387 		 * Use the planner machinery to extract dependencies.  Data is saved
388 		 * in query_context.  (We assume that not a lot of extra cruft is
389 		 * created by this call.)  We can skip this for one-shot plans, and
390 		 * transaction control commands have no such dependencies anyway.
391 		 */
392 		extract_query_dependencies((Node *) querytree_list,
393 								   &plansource->relationOids,
394 								   &plansource->invalItems,
395 								   &plansource->dependsOnRLS);
396 
397 		/* Update RLS info as well. */
398 		plansource->rewriteRoleId = GetUserId();
399 		plansource->rewriteRowSecurity = row_security;
400 
401 		/*
402 		 * Also save the current search_path in the query_context.  (This
403 		 * should not generate much extra cruft either, since almost certainly
404 		 * the path is already valid.)	Again, we don't really need this for
405 		 * one-shot plans; and we *must* skip this for transaction control
406 		 * commands, because this could result in catalog accesses.
407 		 */
408 		plansource->search_path = GetOverrideSearchPath(querytree_context);
409 	}
410 
411 	/*
412 	 * Save the final parameter types (or other parameter specification data)
413 	 * into the source_context, as well as our other parameters.  Also save
414 	 * the result tuple descriptor.
415 	 */
416 	MemoryContextSwitchTo(source_context);
417 
418 	if (num_params > 0)
419 	{
420 		plansource->param_types = (Oid *) palloc(num_params * sizeof(Oid));
421 		memcpy(plansource->param_types, param_types, num_params * sizeof(Oid));
422 	}
423 	else
424 		plansource->param_types = NULL;
425 	plansource->num_params = num_params;
426 	plansource->parserSetup = parserSetup;
427 	plansource->parserSetupArg = parserSetupArg;
428 	plansource->cursor_options = cursor_options;
429 	plansource->fixed_result = fixed_result;
430 	plansource->resultDesc = PlanCacheComputeResultDesc(querytree_list);
431 
432 	MemoryContextSwitchTo(oldcxt);
433 
434 	plansource->is_complete = true;
435 	plansource->is_valid = true;
436 }
437 
438 /*
439  * SaveCachedPlan: save a cached plan permanently
440  *
441  * This function moves the cached plan underneath CacheMemoryContext (making
442  * it live for the life of the backend, unless explicitly dropped), and adds
443  * it to the list of cached plans that are checked for invalidation when an
444  * sinval event occurs.
445  *
446  * This is guaranteed not to throw error, except for the caller-error case
447  * of trying to save a one-shot plan.  Callers typically depend on that
448  * since this is called just before or just after adding a pointer to the
449  * CachedPlanSource to some permanent data structure of their own.  Up until
450  * this is done, a CachedPlanSource is just transient data that will go away
451  * automatically on transaction abort.
452  */
453 void
SaveCachedPlan(CachedPlanSource * plansource)454 SaveCachedPlan(CachedPlanSource *plansource)
455 {
456 	/* Assert caller is doing things in a sane order */
457 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
458 	Assert(plansource->is_complete);
459 	Assert(!plansource->is_saved);
460 
461 	/* This seems worth a real test, though */
462 	if (plansource->is_oneshot)
463 		elog(ERROR, "cannot save one-shot cached plan");
464 
465 	/*
466 	 * In typical use, this function would be called before generating any
467 	 * plans from the CachedPlanSource.  If there is a generic plan, moving it
468 	 * into CacheMemoryContext would be pretty risky since it's unclear
469 	 * whether the caller has taken suitable care with making references
470 	 * long-lived.  Best thing to do seems to be to discard the plan.
471 	 */
472 	ReleaseGenericPlan(plansource);
473 
474 	/*
475 	 * Reparent the source memory context under CacheMemoryContext so that it
476 	 * will live indefinitely.  The query_context follows along since it's
477 	 * already a child of the other one.
478 	 */
479 	MemoryContextSetParent(plansource->context, CacheMemoryContext);
480 
481 	/*
482 	 * Add the entry to the global list of cached plans.
483 	 */
484 	dlist_push_tail(&saved_plan_list, &plansource->node);
485 
486 	plansource->is_saved = true;
487 }
488 
489 /*
490  * DropCachedPlan: destroy a cached plan.
491  *
492  * Actually this only destroys the CachedPlanSource: any referenced CachedPlan
493  * is released, but not destroyed until its refcount goes to zero.  That
494  * handles the situation where DropCachedPlan is called while the plan is
495  * still in use.
496  */
497 void
DropCachedPlan(CachedPlanSource * plansource)498 DropCachedPlan(CachedPlanSource *plansource)
499 {
500 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
501 
502 	/* If it's been saved, remove it from the list */
503 	if (plansource->is_saved)
504 	{
505 		dlist_delete(&plansource->node);
506 		plansource->is_saved = false;
507 	}
508 
509 	/* Decrement generic CachedPlan's refcount and drop if no longer needed */
510 	ReleaseGenericPlan(plansource);
511 
512 	/* Mark it no longer valid */
513 	plansource->magic = 0;
514 
515 	/*
516 	 * Remove the CachedPlanSource and all subsidiary data (including the
517 	 * query_context if any).  But if it's a one-shot we can't free anything.
518 	 */
519 	if (!plansource->is_oneshot)
520 		MemoryContextDelete(plansource->context);
521 }
522 
523 /*
524  * ReleaseGenericPlan: release a CachedPlanSource's generic plan, if any.
525  */
526 static void
ReleaseGenericPlan(CachedPlanSource * plansource)527 ReleaseGenericPlan(CachedPlanSource *plansource)
528 {
529 	/* Be paranoid about the possibility that ReleaseCachedPlan fails */
530 	if (plansource->gplan)
531 	{
532 		CachedPlan *plan = plansource->gplan;
533 
534 		Assert(plan->magic == CACHEDPLAN_MAGIC);
535 		plansource->gplan = NULL;
536 		ReleaseCachedPlan(plan, NULL);
537 	}
538 }
539 
540 /*
541  * RevalidateCachedQuery: ensure validity of analyzed-and-rewritten query tree.
542  *
543  * What we do here is re-acquire locks and redo parse analysis if necessary.
544  * On return, the query_list is valid and we have sufficient locks to begin
545  * planning.
546  *
547  * If any parse analysis activity is required, the caller's memory context is
548  * used for that work.
549  *
550  * The result value is the transient analyzed-and-rewritten query tree if we
551  * had to do re-analysis, and NIL otherwise.  (This is returned just to save
552  * a tree copying step in a subsequent BuildCachedPlan call.)
553  */
554 static List *
RevalidateCachedQuery(CachedPlanSource * plansource,QueryEnvironment * queryEnv)555 RevalidateCachedQuery(CachedPlanSource *plansource,
556 					  QueryEnvironment *queryEnv)
557 {
558 	bool		snapshot_set;
559 	RawStmt    *rawtree;
560 	List	   *tlist;			/* transient query-tree list */
561 	List	   *qlist;			/* permanent query-tree list */
562 	TupleDesc	resultDesc;
563 	MemoryContext querytree_context;
564 	MemoryContext oldcxt;
565 
566 	/*
567 	 * For one-shot plans, we do not support revalidation checking; it's
568 	 * assumed the query is parsed, planned, and executed in one transaction,
569 	 * so that no lock re-acquisition is necessary.  Also, there is never any
570 	 * need to revalidate plans for transaction control commands (and we
571 	 * mustn't risk any catalog accesses when handling those).
572 	 */
573 	if (plansource->is_oneshot || IsTransactionStmtPlan(plansource))
574 	{
575 		Assert(plansource->is_valid);
576 		return NIL;
577 	}
578 
579 	/*
580 	 * If the query is currently valid, we should have a saved search_path ---
581 	 * check to see if that matches the current environment.  If not, we want
582 	 * to force replan.
583 	 */
584 	if (plansource->is_valid)
585 	{
586 		Assert(plansource->search_path != NULL);
587 		if (!OverrideSearchPathMatchesCurrent(plansource->search_path))
588 		{
589 			/* Invalidate the querytree and generic plan */
590 			plansource->is_valid = false;
591 			if (plansource->gplan)
592 				plansource->gplan->is_valid = false;
593 		}
594 	}
595 
596 	/*
597 	 * If the query rewrite phase had a possible RLS dependency, we must redo
598 	 * it if either the role or the row_security setting has changed.
599 	 */
600 	if (plansource->is_valid && plansource->dependsOnRLS &&
601 		(plansource->rewriteRoleId != GetUserId() ||
602 		 plansource->rewriteRowSecurity != row_security))
603 		plansource->is_valid = false;
604 
605 	/*
606 	 * If the query is currently valid, acquire locks on the referenced
607 	 * objects; then check again.  We need to do it this way to cover the race
608 	 * condition that an invalidation message arrives before we get the locks.
609 	 */
610 	if (plansource->is_valid)
611 	{
612 		AcquirePlannerLocks(plansource->query_list, true);
613 
614 		/*
615 		 * By now, if any invalidation has happened, the inval callback
616 		 * functions will have marked the query invalid.
617 		 */
618 		if (plansource->is_valid)
619 		{
620 			/* Successfully revalidated and locked the query. */
621 			return NIL;
622 		}
623 
624 		/* Oops, the race case happened.  Release useless locks. */
625 		AcquirePlannerLocks(plansource->query_list, false);
626 	}
627 
628 	/*
629 	 * Discard the no-longer-useful query tree.  (Note: we don't want to do
630 	 * this any earlier, else we'd not have been able to release locks
631 	 * correctly in the race condition case.)
632 	 */
633 	plansource->is_valid = false;
634 	plansource->query_list = NIL;
635 	plansource->relationOids = NIL;
636 	plansource->invalItems = NIL;
637 	plansource->search_path = NULL;
638 
639 	/*
640 	 * Free the query_context.  We don't really expect MemoryContextDelete to
641 	 * fail, but just in case, make sure the CachedPlanSource is left in a
642 	 * reasonably sane state.  (The generic plan won't get unlinked yet, but
643 	 * that's acceptable.)
644 	 */
645 	if (plansource->query_context)
646 	{
647 		MemoryContext qcxt = plansource->query_context;
648 
649 		plansource->query_context = NULL;
650 		MemoryContextDelete(qcxt);
651 	}
652 
653 	/* Drop the generic plan reference if any */
654 	ReleaseGenericPlan(plansource);
655 
656 	/*
657 	 * Now re-do parse analysis and rewrite.  This not incidentally acquires
658 	 * the locks we need to do planning safely.
659 	 */
660 	Assert(plansource->is_complete);
661 
662 	/*
663 	 * If a snapshot is already set (the normal case), we can just use that
664 	 * for parsing/planning.  But if it isn't, install one.  Note: no point in
665 	 * checking whether parse analysis requires a snapshot; utility commands
666 	 * don't have invalidatable plans, so we'd not get here for such a
667 	 * command.
668 	 */
669 	snapshot_set = false;
670 	if (!ActiveSnapshotSet())
671 	{
672 		PushActiveSnapshot(GetTransactionSnapshot());
673 		snapshot_set = true;
674 	}
675 
676 	/*
677 	 * Run parse analysis and rule rewriting.  The parser tends to scribble on
678 	 * its input, so we must copy the raw parse tree to prevent corruption of
679 	 * the cache.
680 	 */
681 	rawtree = copyObject(plansource->raw_parse_tree);
682 	if (rawtree == NULL)
683 		tlist = NIL;
684 	else if (plansource->parserSetup != NULL)
685 		tlist = pg_analyze_and_rewrite_params(rawtree,
686 											  plansource->query_string,
687 											  plansource->parserSetup,
688 											  plansource->parserSetupArg,
689 											  queryEnv);
690 	else
691 		tlist = pg_analyze_and_rewrite(rawtree,
692 									   plansource->query_string,
693 									   plansource->param_types,
694 									   plansource->num_params,
695 									   queryEnv);
696 
697 	/* Release snapshot if we got one */
698 	if (snapshot_set)
699 		PopActiveSnapshot();
700 
701 	/*
702 	 * Check or update the result tupdesc.  XXX should we use a weaker
703 	 * condition than equalTupleDescs() here?
704 	 *
705 	 * We assume the parameter types didn't change from the first time, so no
706 	 * need to update that.
707 	 */
708 	resultDesc = PlanCacheComputeResultDesc(tlist);
709 	if (resultDesc == NULL && plansource->resultDesc == NULL)
710 	{
711 		/* OK, doesn't return tuples */
712 	}
713 	else if (resultDesc == NULL || plansource->resultDesc == NULL ||
714 			 !equalTupleDescs(resultDesc, plansource->resultDesc))
715 	{
716 		/* can we give a better error message? */
717 		if (plansource->fixed_result)
718 			ereport(ERROR,
719 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
720 					 errmsg("cached plan must not change result type")));
721 		oldcxt = MemoryContextSwitchTo(plansource->context);
722 		if (resultDesc)
723 			resultDesc = CreateTupleDescCopy(resultDesc);
724 		if (plansource->resultDesc)
725 			FreeTupleDesc(plansource->resultDesc);
726 		plansource->resultDesc = resultDesc;
727 		MemoryContextSwitchTo(oldcxt);
728 	}
729 
730 	/*
731 	 * Allocate new query_context and copy the completed querytree into it.
732 	 * It's transient until we complete the copying and dependency extraction.
733 	 */
734 	querytree_context = AllocSetContextCreate(CurrentMemoryContext,
735 											  "CachedPlanQuery",
736 											  ALLOCSET_START_SMALL_SIZES);
737 	oldcxt = MemoryContextSwitchTo(querytree_context);
738 
739 	qlist = copyObject(tlist);
740 
741 	/*
742 	 * Use the planner machinery to extract dependencies.  Data is saved in
743 	 * query_context.  (We assume that not a lot of extra cruft is created by
744 	 * this call.)
745 	 */
746 	extract_query_dependencies((Node *) qlist,
747 							   &plansource->relationOids,
748 							   &plansource->invalItems,
749 							   &plansource->dependsOnRLS);
750 
751 	/* Update RLS info as well. */
752 	plansource->rewriteRoleId = GetUserId();
753 	plansource->rewriteRowSecurity = row_security;
754 
755 	/*
756 	 * Also save the current search_path in the query_context.  (This should
757 	 * not generate much extra cruft either, since almost certainly the path
758 	 * is already valid.)
759 	 */
760 	plansource->search_path = GetOverrideSearchPath(querytree_context);
761 
762 	MemoryContextSwitchTo(oldcxt);
763 
764 	/* Now reparent the finished query_context and save the links */
765 	MemoryContextSetParent(querytree_context, plansource->context);
766 
767 	plansource->query_context = querytree_context;
768 	plansource->query_list = qlist;
769 
770 	/*
771 	 * Note: we do not reset generic_cost or total_custom_cost, although we
772 	 * could choose to do so.  If the DDL or statistics change that prompted
773 	 * the invalidation meant a significant change in the cost estimates, it
774 	 * would be better to reset those variables and start fresh; but often it
775 	 * doesn't, and we're better retaining our hard-won knowledge about the
776 	 * relative costs.
777 	 */
778 
779 	plansource->is_valid = true;
780 
781 	/* Return transient copy of querytrees for possible use in planning */
782 	return tlist;
783 }
784 
785 /*
786  * CheckCachedPlan: see if the CachedPlanSource's generic plan is valid.
787  *
788  * Caller must have already called RevalidateCachedQuery to verify that the
789  * querytree is up to date.
790  *
791  * On a "true" return, we have acquired the locks needed to run the plan.
792  * (We must do this for the "true" result to be race-condition-free.)
793  */
794 static bool
CheckCachedPlan(CachedPlanSource * plansource)795 CheckCachedPlan(CachedPlanSource *plansource)
796 {
797 	CachedPlan *plan = plansource->gplan;
798 
799 	/* Assert that caller checked the querytree */
800 	Assert(plansource->is_valid);
801 
802 	/* If there's no generic plan, just say "false" */
803 	if (!plan)
804 		return false;
805 
806 	Assert(plan->magic == CACHEDPLAN_MAGIC);
807 	/* Generic plans are never one-shot */
808 	Assert(!plan->is_oneshot);
809 
810 	/*
811 	 * If plan isn't valid for current role, we can't use it.
812 	 */
813 	if (plan->is_valid && plan->dependsOnRole &&
814 		plan->planRoleId != GetUserId())
815 		plan->is_valid = false;
816 
817 	/*
818 	 * If it appears valid, acquire locks and recheck; this is much the same
819 	 * logic as in RevalidateCachedQuery, but for a plan.
820 	 */
821 	if (plan->is_valid)
822 	{
823 		/*
824 		 * Plan must have positive refcount because it is referenced by
825 		 * plansource; so no need to fear it disappears under us here.
826 		 */
827 		Assert(plan->refcount > 0);
828 
829 		AcquireExecutorLocks(plan->stmt_list, true);
830 
831 		/*
832 		 * If plan was transient, check to see if TransactionXmin has
833 		 * advanced, and if so invalidate it.
834 		 */
835 		if (plan->is_valid &&
836 			TransactionIdIsValid(plan->saved_xmin) &&
837 			!TransactionIdEquals(plan->saved_xmin, TransactionXmin))
838 			plan->is_valid = false;
839 
840 		/*
841 		 * By now, if any invalidation has happened, the inval callback
842 		 * functions will have marked the plan invalid.
843 		 */
844 		if (plan->is_valid)
845 		{
846 			/* Successfully revalidated and locked the query. */
847 			return true;
848 		}
849 
850 		/* Oops, the race case happened.  Release useless locks. */
851 		AcquireExecutorLocks(plan->stmt_list, false);
852 	}
853 
854 	/*
855 	 * Plan has been invalidated, so unlink it from the parent and release it.
856 	 */
857 	ReleaseGenericPlan(plansource);
858 
859 	return false;
860 }
861 
862 /*
863  * BuildCachedPlan: construct a new CachedPlan from a CachedPlanSource.
864  *
865  * qlist should be the result value from a previous RevalidateCachedQuery,
866  * or it can be set to NIL if we need to re-copy the plansource's query_list.
867  *
868  * To build a generic, parameter-value-independent plan, pass NULL for
869  * boundParams.  To build a custom plan, pass the actual parameter values via
870  * boundParams.  For best effect, the PARAM_FLAG_CONST flag should be set on
871  * each parameter value; otherwise the planner will treat the value as a
872  * hint rather than a hard constant.
873  *
874  * Planning work is done in the caller's memory context.  The finished plan
875  * is in a child memory context, which typically should get reparented
876  * (unless this is a one-shot plan, in which case we don't copy the plan).
877  */
878 static CachedPlan *
BuildCachedPlan(CachedPlanSource * plansource,List * qlist,ParamListInfo boundParams,QueryEnvironment * queryEnv)879 BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
880 				ParamListInfo boundParams, QueryEnvironment *queryEnv)
881 {
882 	CachedPlan *plan;
883 	List	   *plist;
884 	bool		snapshot_set;
885 	bool		is_transient;
886 	MemoryContext plan_context;
887 	MemoryContext oldcxt = CurrentMemoryContext;
888 	ListCell   *lc;
889 
890 	/*
891 	 * Normally the querytree should be valid already, but if it's not,
892 	 * rebuild it.
893 	 *
894 	 * NOTE: GetCachedPlan should have called RevalidateCachedQuery first, so
895 	 * we ought to be holding sufficient locks to prevent any invalidation.
896 	 * However, if we're building a custom plan after having built and
897 	 * rejected a generic plan, it's possible to reach here with is_valid
898 	 * false due to an invalidation while making the generic plan.  In theory
899 	 * the invalidation must be a false positive, perhaps a consequence of an
900 	 * sinval reset event or the debug_discard_caches code.  But for safety,
901 	 * let's treat it as real and redo the RevalidateCachedQuery call.
902 	 */
903 	if (!plansource->is_valid)
904 		qlist = RevalidateCachedQuery(plansource, queryEnv);
905 
906 	/*
907 	 * If we don't already have a copy of the querytree list that can be
908 	 * scribbled on by the planner, make one.  For a one-shot plan, we assume
909 	 * it's okay to scribble on the original query_list.
910 	 */
911 	if (qlist == NIL)
912 	{
913 		if (!plansource->is_oneshot)
914 			qlist = copyObject(plansource->query_list);
915 		else
916 			qlist = plansource->query_list;
917 	}
918 
919 	/*
920 	 * If a snapshot is already set (the normal case), we can just use that
921 	 * for planning.  But if it isn't, and we need one, install one.
922 	 */
923 	snapshot_set = false;
924 	if (!ActiveSnapshotSet() &&
925 		plansource->raw_parse_tree &&
926 		analyze_requires_snapshot(plansource->raw_parse_tree))
927 	{
928 		PushActiveSnapshot(GetTransactionSnapshot());
929 		snapshot_set = true;
930 	}
931 
932 	/*
933 	 * Generate the plan.
934 	 */
935 	plist = pg_plan_queries(qlist, plansource->query_string,
936 							plansource->cursor_options, boundParams);
937 
938 	/* Release snapshot if we got one */
939 	if (snapshot_set)
940 		PopActiveSnapshot();
941 
942 	/*
943 	 * Normally we make a dedicated memory context for the CachedPlan and its
944 	 * subsidiary data.  (It's probably not going to be large, but just in
945 	 * case, allow it to grow large.  It's transient for the moment.)  But for
946 	 * a one-shot plan, we just leave it in the caller's memory context.
947 	 */
948 	if (!plansource->is_oneshot)
949 	{
950 		plan_context = AllocSetContextCreate(CurrentMemoryContext,
951 											 "CachedPlan",
952 											 ALLOCSET_START_SMALL_SIZES);
953 		MemoryContextCopyAndSetIdentifier(plan_context, plansource->query_string);
954 
955 		/*
956 		 * Copy plan into the new context.
957 		 */
958 		MemoryContextSwitchTo(plan_context);
959 
960 		plist = copyObject(plist);
961 	}
962 	else
963 		plan_context = CurrentMemoryContext;
964 
965 	/*
966 	 * Create and fill the CachedPlan struct within the new context.
967 	 */
968 	plan = (CachedPlan *) palloc(sizeof(CachedPlan));
969 	plan->magic = CACHEDPLAN_MAGIC;
970 	plan->stmt_list = plist;
971 
972 	/*
973 	 * CachedPlan is dependent on role either if RLS affected the rewrite
974 	 * phase or if a role dependency was injected during planning.  And it's
975 	 * transient if any plan is marked so.
976 	 */
977 	plan->planRoleId = GetUserId();
978 	plan->dependsOnRole = plansource->dependsOnRLS;
979 	is_transient = false;
980 	foreach(lc, plist)
981 	{
982 		PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
983 
984 		if (plannedstmt->commandType == CMD_UTILITY)
985 			continue;			/* Ignore utility statements */
986 
987 		if (plannedstmt->transientPlan)
988 			is_transient = true;
989 		if (plannedstmt->dependsOnRole)
990 			plan->dependsOnRole = true;
991 	}
992 	if (is_transient)
993 	{
994 		Assert(TransactionIdIsNormal(TransactionXmin));
995 		plan->saved_xmin = TransactionXmin;
996 	}
997 	else
998 		plan->saved_xmin = InvalidTransactionId;
999 	plan->refcount = 0;
1000 	plan->context = plan_context;
1001 	plan->is_oneshot = plansource->is_oneshot;
1002 	plan->is_saved = false;
1003 	plan->is_valid = true;
1004 
1005 	/* assign generation number to new plan */
1006 	plan->generation = ++(plansource->generation);
1007 
1008 	MemoryContextSwitchTo(oldcxt);
1009 
1010 	return plan;
1011 }
1012 
1013 /*
1014  * choose_custom_plan: choose whether to use custom or generic plan
1015  *
1016  * This defines the policy followed by GetCachedPlan.
1017  */
1018 static bool
choose_custom_plan(CachedPlanSource * plansource,ParamListInfo boundParams)1019 choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams)
1020 {
1021 	double		avg_custom_cost;
1022 
1023 	/* One-shot plans will always be considered custom */
1024 	if (plansource->is_oneshot)
1025 		return true;
1026 
1027 	/* Otherwise, never any point in a custom plan if there's no parameters */
1028 	if (boundParams == NULL)
1029 		return false;
1030 	/* ... nor for transaction control statements */
1031 	if (IsTransactionStmtPlan(plansource))
1032 		return false;
1033 
1034 	/* Let settings force the decision */
1035 	if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_GENERIC_PLAN)
1036 		return false;
1037 	if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN)
1038 		return true;
1039 
1040 	/* See if caller wants to force the decision */
1041 	if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN)
1042 		return false;
1043 	if (plansource->cursor_options & CURSOR_OPT_CUSTOM_PLAN)
1044 		return true;
1045 
1046 	/* Generate custom plans until we have done at least 5 (arbitrary) */
1047 	if (plansource->num_custom_plans < 5)
1048 		return true;
1049 
1050 	avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans;
1051 
1052 	/*
1053 	 * Prefer generic plan if it's less expensive than the average custom
1054 	 * plan.  (Because we include a charge for cost of planning in the
1055 	 * custom-plan costs, this means the generic plan only has to be less
1056 	 * expensive than the execution cost plus replan cost of the custom
1057 	 * plans.)
1058 	 *
1059 	 * Note that if generic_cost is -1 (indicating we've not yet determined
1060 	 * the generic plan cost), we'll always prefer generic at this point.
1061 	 */
1062 	if (plansource->generic_cost < avg_custom_cost)
1063 		return false;
1064 
1065 	return true;
1066 }
1067 
1068 /*
1069  * cached_plan_cost: calculate estimated cost of a plan
1070  *
1071  * If include_planner is true, also include the estimated cost of constructing
1072  * the plan.  (We must factor that into the cost of using a custom plan, but
1073  * we don't count it for a generic plan.)
1074  */
1075 static double
cached_plan_cost(CachedPlan * plan,bool include_planner)1076 cached_plan_cost(CachedPlan *plan, bool include_planner)
1077 {
1078 	double		result = 0;
1079 	ListCell   *lc;
1080 
1081 	foreach(lc, plan->stmt_list)
1082 	{
1083 		PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1084 
1085 		if (plannedstmt->commandType == CMD_UTILITY)
1086 			continue;			/* Ignore utility statements */
1087 
1088 		result += plannedstmt->planTree->total_cost;
1089 
1090 		if (include_planner)
1091 		{
1092 			/*
1093 			 * Currently we use a very crude estimate of planning effort based
1094 			 * on the number of relations in the finished plan's rangetable.
1095 			 * Join planning effort actually scales much worse than linearly
1096 			 * in the number of relations --- but only until the join collapse
1097 			 * limits kick in.  Also, while inheritance child relations surely
1098 			 * add to planning effort, they don't make the join situation
1099 			 * worse.  So the actual shape of the planning cost curve versus
1100 			 * number of relations isn't all that obvious.  It will take
1101 			 * considerable work to arrive at a less crude estimate, and for
1102 			 * now it's not clear that's worth doing.
1103 			 *
1104 			 * The other big difficulty here is that we don't have any very
1105 			 * good model of how planning cost compares to execution costs.
1106 			 * The current multiplier of 1000 * cpu_operator_cost is probably
1107 			 * on the low side, but we'll try this for awhile before making a
1108 			 * more aggressive correction.
1109 			 *
1110 			 * If we ever do write a more complicated estimator, it should
1111 			 * probably live in src/backend/optimizer/ not here.
1112 			 */
1113 			int			nrelations = list_length(plannedstmt->rtable);
1114 
1115 			result += 1000.0 * cpu_operator_cost * (nrelations + 1);
1116 		}
1117 	}
1118 
1119 	return result;
1120 }
1121 
1122 /*
1123  * GetCachedPlan: get a cached plan from a CachedPlanSource.
1124  *
1125  * This function hides the logic that decides whether to use a generic
1126  * plan or a custom plan for the given parameters: the caller does not know
1127  * which it will get.
1128  *
1129  * On return, the plan is valid and we have sufficient locks to begin
1130  * execution.
1131  *
1132  * On return, the refcount of the plan has been incremented; a later
1133  * ReleaseCachedPlan() call is expected.  If "owner" is not NULL then
1134  * the refcount has been reported to that ResourceOwner (note that this
1135  * is only supported for "saved" CachedPlanSources).
1136  *
1137  * Note: if any replanning activity is required, the caller's memory context
1138  * is used for that work.
1139  */
1140 CachedPlan *
GetCachedPlan(CachedPlanSource * plansource,ParamListInfo boundParams,ResourceOwner owner,QueryEnvironment * queryEnv)1141 GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams,
1142 			  ResourceOwner owner, QueryEnvironment *queryEnv)
1143 {
1144 	CachedPlan *plan = NULL;
1145 	List	   *qlist;
1146 	bool		customplan;
1147 
1148 	/* Assert caller is doing things in a sane order */
1149 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1150 	Assert(plansource->is_complete);
1151 	/* This seems worth a real test, though */
1152 	if (owner && !plansource->is_saved)
1153 		elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
1154 
1155 	/* Make sure the querytree list is valid and we have parse-time locks */
1156 	qlist = RevalidateCachedQuery(plansource, queryEnv);
1157 
1158 	/* Decide whether to use a custom plan */
1159 	customplan = choose_custom_plan(plansource, boundParams);
1160 
1161 	if (!customplan)
1162 	{
1163 		if (CheckCachedPlan(plansource))
1164 		{
1165 			/* We want a generic plan, and we already have a valid one */
1166 			plan = plansource->gplan;
1167 			Assert(plan->magic == CACHEDPLAN_MAGIC);
1168 		}
1169 		else
1170 		{
1171 			/* Build a new generic plan */
1172 			plan = BuildCachedPlan(plansource, qlist, NULL, queryEnv);
1173 			/* Just make real sure plansource->gplan is clear */
1174 			ReleaseGenericPlan(plansource);
1175 			/* Link the new generic plan into the plansource */
1176 			plansource->gplan = plan;
1177 			plan->refcount++;
1178 			/* Immediately reparent into appropriate context */
1179 			if (plansource->is_saved)
1180 			{
1181 				/* saved plans all live under CacheMemoryContext */
1182 				MemoryContextSetParent(plan->context, CacheMemoryContext);
1183 				plan->is_saved = true;
1184 			}
1185 			else
1186 			{
1187 				/* otherwise, it should be a sibling of the plansource */
1188 				MemoryContextSetParent(plan->context,
1189 									   MemoryContextGetParent(plansource->context));
1190 			}
1191 			/* Update generic_cost whenever we make a new generic plan */
1192 			plansource->generic_cost = cached_plan_cost(plan, false);
1193 
1194 			/*
1195 			 * If, based on the now-known value of generic_cost, we'd not have
1196 			 * chosen to use a generic plan, then forget it and make a custom
1197 			 * plan.  This is a bit of a wart but is necessary to avoid a
1198 			 * glitch in behavior when the custom plans are consistently big
1199 			 * winners; at some point we'll experiment with a generic plan and
1200 			 * find it's a loser, but we don't want to actually execute that
1201 			 * plan.
1202 			 */
1203 			customplan = choose_custom_plan(plansource, boundParams);
1204 
1205 			/*
1206 			 * If we choose to plan again, we need to re-copy the query_list,
1207 			 * since the planner probably scribbled on it.  We can force
1208 			 * BuildCachedPlan to do that by passing NIL.
1209 			 */
1210 			qlist = NIL;
1211 		}
1212 	}
1213 
1214 	if (customplan)
1215 	{
1216 		/* Build a custom plan */
1217 		plan = BuildCachedPlan(plansource, qlist, boundParams, queryEnv);
1218 		/* Accumulate total costs of custom plans */
1219 		plansource->total_custom_cost += cached_plan_cost(plan, true);
1220 
1221 		plansource->num_custom_plans++;
1222 	}
1223 	else
1224 	{
1225 		plansource->num_generic_plans++;
1226 	}
1227 
1228 	Assert(plan != NULL);
1229 
1230 	/* Flag the plan as in use by caller */
1231 	if (owner)
1232 		ResourceOwnerEnlargePlanCacheRefs(owner);
1233 	plan->refcount++;
1234 	if (owner)
1235 		ResourceOwnerRememberPlanCacheRef(owner, plan);
1236 
1237 	/*
1238 	 * Saved plans should be under CacheMemoryContext so they will not go away
1239 	 * until their reference count goes to zero.  In the generic-plan cases we
1240 	 * already took care of that, but for a custom plan, do it as soon as we
1241 	 * have created a reference-counted link.
1242 	 */
1243 	if (customplan && plansource->is_saved)
1244 	{
1245 		MemoryContextSetParent(plan->context, CacheMemoryContext);
1246 		plan->is_saved = true;
1247 	}
1248 
1249 	return plan;
1250 }
1251 
1252 /*
1253  * ReleaseCachedPlan: release active use of a cached plan.
1254  *
1255  * This decrements the reference count, and frees the plan if the count
1256  * has thereby gone to zero.  If "owner" is not NULL, it is assumed that
1257  * the reference count is managed by that ResourceOwner.
1258  *
1259  * Note: owner == NULL is used for releasing references that are in
1260  * persistent data structures, such as the parent CachedPlanSource or a
1261  * Portal.  Transient references should be protected by a resource owner.
1262  */
1263 void
ReleaseCachedPlan(CachedPlan * plan,ResourceOwner owner)1264 ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner)
1265 {
1266 	Assert(plan->magic == CACHEDPLAN_MAGIC);
1267 	if (owner)
1268 	{
1269 		Assert(plan->is_saved);
1270 		ResourceOwnerForgetPlanCacheRef(owner, plan);
1271 	}
1272 	Assert(plan->refcount > 0);
1273 	plan->refcount--;
1274 	if (plan->refcount == 0)
1275 	{
1276 		/* Mark it no longer valid */
1277 		plan->magic = 0;
1278 
1279 		/* One-shot plans do not own their context, so we can't free them */
1280 		if (!plan->is_oneshot)
1281 			MemoryContextDelete(plan->context);
1282 	}
1283 }
1284 
1285 /*
1286  * CachedPlanAllowsSimpleValidityCheck: can we use CachedPlanIsSimplyValid?
1287  *
1288  * This function, together with CachedPlanIsSimplyValid, provides a fast path
1289  * for revalidating "simple" generic plans.  The core requirement to be simple
1290  * is that the plan must not require taking any locks, which translates to
1291  * not touching any tables; this happens to match up well with an important
1292  * use-case in PL/pgSQL.  This function tests whether that's true, along
1293  * with checking some other corner cases that we'd rather not bother with
1294  * handling in the fast path.  (Note that it's still possible for such a plan
1295  * to be invalidated, for example due to a change in a function that was
1296  * inlined into the plan.)
1297  *
1298  * If the plan is simply valid, and "owner" is not NULL, record a refcount on
1299  * the plan in that resowner before returning.  It is caller's responsibility
1300  * to be sure that a refcount is held on any plan that's being actively used.
1301  *
1302  * This must only be called on known-valid generic plans (eg, ones just
1303  * returned by GetCachedPlan).  If it returns true, the caller may re-use
1304  * the cached plan as long as CachedPlanIsSimplyValid returns true; that
1305  * check is much cheaper than the full revalidation done by GetCachedPlan.
1306  * Nonetheless, no required checks are omitted.
1307  */
1308 bool
CachedPlanAllowsSimpleValidityCheck(CachedPlanSource * plansource,CachedPlan * plan,ResourceOwner owner)1309 CachedPlanAllowsSimpleValidityCheck(CachedPlanSource *plansource,
1310 									CachedPlan *plan, ResourceOwner owner)
1311 {
1312 	ListCell   *lc;
1313 
1314 	/*
1315 	 * Sanity-check that the caller gave us a validated generic plan.  Notice
1316 	 * that we *don't* assert plansource->is_valid as you might expect; that's
1317 	 * because it's possible that that's already false when GetCachedPlan
1318 	 * returns, e.g. because ResetPlanCache happened partway through.  We
1319 	 * should accept the plan as long as plan->is_valid is true, and expect to
1320 	 * replan after the next CachedPlanIsSimplyValid call.
1321 	 */
1322 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1323 	Assert(plan->magic == CACHEDPLAN_MAGIC);
1324 	Assert(plan->is_valid);
1325 	Assert(plan == plansource->gplan);
1326 	Assert(plansource->search_path != NULL);
1327 	Assert(OverrideSearchPathMatchesCurrent(plansource->search_path));
1328 
1329 	/* We don't support oneshot plans here. */
1330 	if (plansource->is_oneshot)
1331 		return false;
1332 	Assert(!plan->is_oneshot);
1333 
1334 	/*
1335 	 * If the plan is dependent on RLS considerations, or it's transient,
1336 	 * reject.  These things probably can't ever happen for table-free
1337 	 * queries, but for safety's sake let's check.
1338 	 */
1339 	if (plansource->dependsOnRLS)
1340 		return false;
1341 	if (plan->dependsOnRole)
1342 		return false;
1343 	if (TransactionIdIsValid(plan->saved_xmin))
1344 		return false;
1345 
1346 	/*
1347 	 * Reject if AcquirePlannerLocks would have anything to do.  This is
1348 	 * simplistic, but there's no need to inquire any more carefully; indeed,
1349 	 * for current callers it shouldn't even be possible to hit any of these
1350 	 * checks.
1351 	 */
1352 	foreach(lc, plansource->query_list)
1353 	{
1354 		Query	   *query = lfirst_node(Query, lc);
1355 
1356 		if (query->commandType == CMD_UTILITY)
1357 			return false;
1358 		if (query->rtable || query->cteList || query->hasSubLinks)
1359 			return false;
1360 	}
1361 
1362 	/*
1363 	 * Reject if AcquireExecutorLocks would have anything to do.  This is
1364 	 * probably unnecessary given the previous check, but let's be safe.
1365 	 */
1366 	foreach(lc, plan->stmt_list)
1367 	{
1368 		PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1369 		ListCell   *lc2;
1370 
1371 		if (plannedstmt->commandType == CMD_UTILITY)
1372 			return false;
1373 
1374 		/*
1375 		 * We have to grovel through the rtable because it's likely to contain
1376 		 * an RTE_RESULT relation, rather than being totally empty.
1377 		 */
1378 		foreach(lc2, plannedstmt->rtable)
1379 		{
1380 			RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
1381 
1382 			if (rte->rtekind == RTE_RELATION)
1383 				return false;
1384 		}
1385 	}
1386 
1387 	/*
1388 	 * Okay, it's simple.  Note that what we've primarily established here is
1389 	 * that no locks need be taken before checking the plan's is_valid flag.
1390 	 */
1391 
1392 	/* Bump refcount if requested. */
1393 	if (owner)
1394 	{
1395 		ResourceOwnerEnlargePlanCacheRefs(owner);
1396 		plan->refcount++;
1397 		ResourceOwnerRememberPlanCacheRef(owner, plan);
1398 	}
1399 
1400 	return true;
1401 }
1402 
1403 /*
1404  * CachedPlanIsSimplyValid: quick check for plan still being valid
1405  *
1406  * This function must not be used unless CachedPlanAllowsSimpleValidityCheck
1407  * previously said it was OK.
1408  *
1409  * If the plan is valid, and "owner" is not NULL, record a refcount on
1410  * the plan in that resowner before returning.  It is caller's responsibility
1411  * to be sure that a refcount is held on any plan that's being actively used.
1412  *
1413  * The code here is unconditionally safe as long as the only use of this
1414  * CachedPlanSource is in connection with the particular CachedPlan pointer
1415  * that's passed in.  If the plansource were being used for other purposes,
1416  * it's possible that its generic plan could be invalidated and regenerated
1417  * while the current caller wasn't looking, and then there could be a chance
1418  * collision of address between this caller's now-stale plan pointer and the
1419  * actual address of the new generic plan.  For current uses, that scenario
1420  * can't happen; but with a plansource shared across multiple uses, it'd be
1421  * advisable to also save plan->generation and verify that that still matches.
1422  */
1423 bool
CachedPlanIsSimplyValid(CachedPlanSource * plansource,CachedPlan * plan,ResourceOwner owner)1424 CachedPlanIsSimplyValid(CachedPlanSource *plansource, CachedPlan *plan,
1425 						ResourceOwner owner)
1426 {
1427 	/*
1428 	 * Careful here: since the caller doesn't necessarily hold a refcount on
1429 	 * the plan to start with, it's possible that "plan" is a dangling
1430 	 * pointer.  Don't dereference it until we've verified that it still
1431 	 * matches the plansource's gplan (which is either valid or NULL).
1432 	 */
1433 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1434 
1435 	/*
1436 	 * Has cache invalidation fired on this plan?  We can check this right
1437 	 * away since there are no locks that we'd need to acquire first.  Note
1438 	 * that here we *do* check plansource->is_valid, so as to force plan
1439 	 * rebuild if that's become false.
1440 	 */
1441 	if (!plansource->is_valid || plan != plansource->gplan || !plan->is_valid)
1442 		return false;
1443 
1444 	Assert(plan->magic == CACHEDPLAN_MAGIC);
1445 
1446 	/* Is the search_path still the same as when we made it? */
1447 	Assert(plansource->search_path != NULL);
1448 	if (!OverrideSearchPathMatchesCurrent(plansource->search_path))
1449 		return false;
1450 
1451 	/* It's still good.  Bump refcount if requested. */
1452 	if (owner)
1453 	{
1454 		ResourceOwnerEnlargePlanCacheRefs(owner);
1455 		plan->refcount++;
1456 		ResourceOwnerRememberPlanCacheRef(owner, plan);
1457 	}
1458 
1459 	return true;
1460 }
1461 
1462 /*
1463  * CachedPlanSetParentContext: move a CachedPlanSource to a new memory context
1464  *
1465  * This can only be applied to unsaved plans; once saved, a plan always
1466  * lives underneath CacheMemoryContext.
1467  */
1468 void
CachedPlanSetParentContext(CachedPlanSource * plansource,MemoryContext newcontext)1469 CachedPlanSetParentContext(CachedPlanSource *plansource,
1470 						   MemoryContext newcontext)
1471 {
1472 	/* Assert caller is doing things in a sane order */
1473 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1474 	Assert(plansource->is_complete);
1475 
1476 	/* These seem worth real tests, though */
1477 	if (plansource->is_saved)
1478 		elog(ERROR, "cannot move a saved cached plan to another context");
1479 	if (plansource->is_oneshot)
1480 		elog(ERROR, "cannot move a one-shot cached plan to another context");
1481 
1482 	/* OK, let the caller keep the plan where he wishes */
1483 	MemoryContextSetParent(plansource->context, newcontext);
1484 
1485 	/*
1486 	 * The query_context needs no special handling, since it's a child of
1487 	 * plansource->context.  But if there's a generic plan, it should be
1488 	 * maintained as a sibling of plansource->context.
1489 	 */
1490 	if (plansource->gplan)
1491 	{
1492 		Assert(plansource->gplan->magic == CACHEDPLAN_MAGIC);
1493 		MemoryContextSetParent(plansource->gplan->context, newcontext);
1494 	}
1495 }
1496 
1497 /*
1498  * CopyCachedPlan: make a copy of a CachedPlanSource
1499  *
1500  * This is a convenience routine that does the equivalent of
1501  * CreateCachedPlan + CompleteCachedPlan, using the data stored in the
1502  * input CachedPlanSource.  The result is therefore "unsaved" (regardless
1503  * of the state of the source), and we don't copy any generic plan either.
1504  * The result will be currently valid, or not, the same as the source.
1505  */
1506 CachedPlanSource *
CopyCachedPlan(CachedPlanSource * plansource)1507 CopyCachedPlan(CachedPlanSource *plansource)
1508 {
1509 	CachedPlanSource *newsource;
1510 	MemoryContext source_context;
1511 	MemoryContext querytree_context;
1512 	MemoryContext oldcxt;
1513 
1514 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1515 	Assert(plansource->is_complete);
1516 
1517 	/*
1518 	 * One-shot plans can't be copied, because we haven't taken care that
1519 	 * parsing/planning didn't scribble on the raw parse tree or querytrees.
1520 	 */
1521 	if (plansource->is_oneshot)
1522 		elog(ERROR, "cannot copy a one-shot cached plan");
1523 
1524 	source_context = AllocSetContextCreate(CurrentMemoryContext,
1525 										   "CachedPlanSource",
1526 										   ALLOCSET_START_SMALL_SIZES);
1527 
1528 	oldcxt = MemoryContextSwitchTo(source_context);
1529 
1530 	newsource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
1531 	newsource->magic = CACHEDPLANSOURCE_MAGIC;
1532 	newsource->raw_parse_tree = copyObject(plansource->raw_parse_tree);
1533 	newsource->query_string = pstrdup(plansource->query_string);
1534 	MemoryContextSetIdentifier(source_context, newsource->query_string);
1535 	newsource->commandTag = plansource->commandTag;
1536 	if (plansource->num_params > 0)
1537 	{
1538 		newsource->param_types = (Oid *)
1539 			palloc(plansource->num_params * sizeof(Oid));
1540 		memcpy(newsource->param_types, plansource->param_types,
1541 			   plansource->num_params * sizeof(Oid));
1542 	}
1543 	else
1544 		newsource->param_types = NULL;
1545 	newsource->num_params = plansource->num_params;
1546 	newsource->parserSetup = plansource->parserSetup;
1547 	newsource->parserSetupArg = plansource->parserSetupArg;
1548 	newsource->cursor_options = plansource->cursor_options;
1549 	newsource->fixed_result = plansource->fixed_result;
1550 	if (plansource->resultDesc)
1551 		newsource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
1552 	else
1553 		newsource->resultDesc = NULL;
1554 	newsource->context = source_context;
1555 
1556 	querytree_context = AllocSetContextCreate(source_context,
1557 											  "CachedPlanQuery",
1558 											  ALLOCSET_START_SMALL_SIZES);
1559 	MemoryContextSwitchTo(querytree_context);
1560 	newsource->query_list = copyObject(plansource->query_list);
1561 	newsource->relationOids = copyObject(plansource->relationOids);
1562 	newsource->invalItems = copyObject(plansource->invalItems);
1563 	if (plansource->search_path)
1564 		newsource->search_path = CopyOverrideSearchPath(plansource->search_path);
1565 	newsource->query_context = querytree_context;
1566 	newsource->rewriteRoleId = plansource->rewriteRoleId;
1567 	newsource->rewriteRowSecurity = plansource->rewriteRowSecurity;
1568 	newsource->dependsOnRLS = plansource->dependsOnRLS;
1569 
1570 	newsource->gplan = NULL;
1571 
1572 	newsource->is_oneshot = false;
1573 	newsource->is_complete = true;
1574 	newsource->is_saved = false;
1575 	newsource->is_valid = plansource->is_valid;
1576 	newsource->generation = plansource->generation;
1577 
1578 	/* We may as well copy any acquired cost knowledge */
1579 	newsource->generic_cost = plansource->generic_cost;
1580 	newsource->total_custom_cost = plansource->total_custom_cost;
1581 	newsource->num_generic_plans = plansource->num_generic_plans;
1582 	newsource->num_custom_plans = plansource->num_custom_plans;
1583 
1584 	MemoryContextSwitchTo(oldcxt);
1585 
1586 	return newsource;
1587 }
1588 
1589 /*
1590  * CachedPlanIsValid: test whether the rewritten querytree within a
1591  * CachedPlanSource is currently valid (that is, not marked as being in need
1592  * of revalidation).
1593  *
1594  * This result is only trustworthy (ie, free from race conditions) if
1595  * the caller has acquired locks on all the relations used in the plan.
1596  */
1597 bool
CachedPlanIsValid(CachedPlanSource * plansource)1598 CachedPlanIsValid(CachedPlanSource *plansource)
1599 {
1600 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1601 	return plansource->is_valid;
1602 }
1603 
1604 /*
1605  * CachedPlanGetTargetList: return tlist, if any, describing plan's output
1606  *
1607  * The result is guaranteed up-to-date.  However, it is local storage
1608  * within the cached plan, and may disappear next time the plan is updated.
1609  */
1610 List *
CachedPlanGetTargetList(CachedPlanSource * plansource,QueryEnvironment * queryEnv)1611 CachedPlanGetTargetList(CachedPlanSource *plansource,
1612 						QueryEnvironment *queryEnv)
1613 {
1614 	Query	   *pstmt;
1615 
1616 	/* Assert caller is doing things in a sane order */
1617 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1618 	Assert(plansource->is_complete);
1619 
1620 	/*
1621 	 * No work needed if statement doesn't return tuples (we assume this
1622 	 * feature cannot be changed by an invalidation)
1623 	 */
1624 	if (plansource->resultDesc == NULL)
1625 		return NIL;
1626 
1627 	/* Make sure the querytree list is valid and we have parse-time locks */
1628 	RevalidateCachedQuery(plansource, queryEnv);
1629 
1630 	/* Get the primary statement and find out what it returns */
1631 	pstmt = QueryListGetPrimaryStmt(plansource->query_list);
1632 
1633 	return FetchStatementTargetList((Node *) pstmt);
1634 }
1635 
1636 /*
1637  * GetCachedExpression: construct a CachedExpression for an expression.
1638  *
1639  * This performs the same transformations on the expression as
1640  * expression_planner(), ie, convert an expression as emitted by parse
1641  * analysis to be ready to pass to the executor.
1642  *
1643  * The result is stashed in a private, long-lived memory context.
1644  * (Note that this might leak a good deal of memory in the caller's
1645  * context before that.)  The passed-in expr tree is not modified.
1646  */
1647 CachedExpression *
GetCachedExpression(Node * expr)1648 GetCachedExpression(Node *expr)
1649 {
1650 	CachedExpression *cexpr;
1651 	List	   *relationOids;
1652 	List	   *invalItems;
1653 	MemoryContext cexpr_context;
1654 	MemoryContext oldcxt;
1655 
1656 	/*
1657 	 * Pass the expression through the planner, and collect dependencies.
1658 	 * Everything built here is leaked in the caller's context; that's
1659 	 * intentional to minimize the size of the permanent data structure.
1660 	 */
1661 	expr = (Node *) expression_planner_with_deps((Expr *) expr,
1662 												 &relationOids,
1663 												 &invalItems);
1664 
1665 	/*
1666 	 * Make a private memory context, and copy what we need into that.  To
1667 	 * avoid leaking a long-lived context if we fail while copying data, we
1668 	 * initially make the context under the caller's context.
1669 	 */
1670 	cexpr_context = AllocSetContextCreate(CurrentMemoryContext,
1671 										  "CachedExpression",
1672 										  ALLOCSET_SMALL_SIZES);
1673 
1674 	oldcxt = MemoryContextSwitchTo(cexpr_context);
1675 
1676 	cexpr = (CachedExpression *) palloc(sizeof(CachedExpression));
1677 	cexpr->magic = CACHEDEXPR_MAGIC;
1678 	cexpr->expr = copyObject(expr);
1679 	cexpr->is_valid = true;
1680 	cexpr->relationOids = copyObject(relationOids);
1681 	cexpr->invalItems = copyObject(invalItems);
1682 	cexpr->context = cexpr_context;
1683 
1684 	MemoryContextSwitchTo(oldcxt);
1685 
1686 	/*
1687 	 * Reparent the expr's memory context under CacheMemoryContext so that it
1688 	 * will live indefinitely.
1689 	 */
1690 	MemoryContextSetParent(cexpr_context, CacheMemoryContext);
1691 
1692 	/*
1693 	 * Add the entry to the global list of cached expressions.
1694 	 */
1695 	dlist_push_tail(&cached_expression_list, &cexpr->node);
1696 
1697 	return cexpr;
1698 }
1699 
1700 /*
1701  * FreeCachedExpression
1702  *		Delete a CachedExpression.
1703  */
1704 void
FreeCachedExpression(CachedExpression * cexpr)1705 FreeCachedExpression(CachedExpression *cexpr)
1706 {
1707 	/* Sanity check */
1708 	Assert(cexpr->magic == CACHEDEXPR_MAGIC);
1709 	/* Unlink from global list */
1710 	dlist_delete(&cexpr->node);
1711 	/* Free all storage associated with CachedExpression */
1712 	MemoryContextDelete(cexpr->context);
1713 }
1714 
1715 /*
1716  * QueryListGetPrimaryStmt
1717  *		Get the "primary" stmt within a list, ie, the one marked canSetTag.
1718  *
1719  * Returns NULL if no such stmt.  If multiple queries within the list are
1720  * marked canSetTag, returns the first one.  Neither of these cases should
1721  * occur in present usages of this function.
1722  */
1723 static Query *
QueryListGetPrimaryStmt(List * stmts)1724 QueryListGetPrimaryStmt(List *stmts)
1725 {
1726 	ListCell   *lc;
1727 
1728 	foreach(lc, stmts)
1729 	{
1730 		Query	   *stmt = lfirst_node(Query, lc);
1731 
1732 		if (stmt->canSetTag)
1733 			return stmt;
1734 	}
1735 	return NULL;
1736 }
1737 
1738 /*
1739  * AcquireExecutorLocks: acquire locks needed for execution of a cached plan;
1740  * or release them if acquire is false.
1741  */
1742 static void
AcquireExecutorLocks(List * stmt_list,bool acquire)1743 AcquireExecutorLocks(List *stmt_list, bool acquire)
1744 {
1745 	ListCell   *lc1;
1746 
1747 	foreach(lc1, stmt_list)
1748 	{
1749 		PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc1);
1750 		ListCell   *lc2;
1751 
1752 		if (plannedstmt->commandType == CMD_UTILITY)
1753 		{
1754 			/*
1755 			 * Ignore utility statements, except those (such as EXPLAIN) that
1756 			 * contain a parsed-but-not-planned query.  Note: it's okay to use
1757 			 * ScanQueryForLocks, even though the query hasn't been through
1758 			 * rule rewriting, because rewriting doesn't change the query
1759 			 * representation.
1760 			 */
1761 			Query	   *query = UtilityContainsQuery(plannedstmt->utilityStmt);
1762 
1763 			if (query)
1764 				ScanQueryForLocks(query, acquire);
1765 			continue;
1766 		}
1767 
1768 		foreach(lc2, plannedstmt->rtable)
1769 		{
1770 			RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
1771 
1772 			if (rte->rtekind != RTE_RELATION)
1773 				continue;
1774 
1775 			/*
1776 			 * Acquire the appropriate type of lock on each relation OID. Note
1777 			 * that we don't actually try to open the rel, and hence will not
1778 			 * fail if it's been dropped entirely --- we'll just transiently
1779 			 * acquire a non-conflicting lock.
1780 			 */
1781 			if (acquire)
1782 				LockRelationOid(rte->relid, rte->rellockmode);
1783 			else
1784 				UnlockRelationOid(rte->relid, rte->rellockmode);
1785 		}
1786 	}
1787 }
1788 
1789 /*
1790  * AcquirePlannerLocks: acquire locks needed for planning of a querytree list;
1791  * or release them if acquire is false.
1792  *
1793  * Note that we don't actually try to open the relations, and hence will not
1794  * fail if one has been dropped entirely --- we'll just transiently acquire
1795  * a non-conflicting lock.
1796  */
1797 static void
AcquirePlannerLocks(List * stmt_list,bool acquire)1798 AcquirePlannerLocks(List *stmt_list, bool acquire)
1799 {
1800 	ListCell   *lc;
1801 
1802 	foreach(lc, stmt_list)
1803 	{
1804 		Query	   *query = lfirst_node(Query, lc);
1805 
1806 		if (query->commandType == CMD_UTILITY)
1807 		{
1808 			/* Ignore utility statements, unless they contain a Query */
1809 			query = UtilityContainsQuery(query->utilityStmt);
1810 			if (query)
1811 				ScanQueryForLocks(query, acquire);
1812 			continue;
1813 		}
1814 
1815 		ScanQueryForLocks(query, acquire);
1816 	}
1817 }
1818 
1819 /*
1820  * ScanQueryForLocks: recursively scan one Query for AcquirePlannerLocks.
1821  */
1822 static void
ScanQueryForLocks(Query * parsetree,bool acquire)1823 ScanQueryForLocks(Query *parsetree, bool acquire)
1824 {
1825 	ListCell   *lc;
1826 
1827 	/* Shouldn't get called on utility commands */
1828 	Assert(parsetree->commandType != CMD_UTILITY);
1829 
1830 	/*
1831 	 * First, process RTEs of the current query level.
1832 	 */
1833 	foreach(lc, parsetree->rtable)
1834 	{
1835 		RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
1836 
1837 		switch (rte->rtekind)
1838 		{
1839 			case RTE_RELATION:
1840 				/* Acquire or release the appropriate type of lock */
1841 				if (acquire)
1842 					LockRelationOid(rte->relid, rte->rellockmode);
1843 				else
1844 					UnlockRelationOid(rte->relid, rte->rellockmode);
1845 				break;
1846 
1847 			case RTE_SUBQUERY:
1848 				/* Recurse into subquery-in-FROM */
1849 				ScanQueryForLocks(rte->subquery, acquire);
1850 				break;
1851 
1852 			default:
1853 				/* ignore other types of RTEs */
1854 				break;
1855 		}
1856 	}
1857 
1858 	/* Recurse into subquery-in-WITH */
1859 	foreach(lc, parsetree->cteList)
1860 	{
1861 		CommonTableExpr *cte = lfirst_node(CommonTableExpr, lc);
1862 
1863 		ScanQueryForLocks(castNode(Query, cte->ctequery), acquire);
1864 	}
1865 
1866 	/*
1867 	 * Recurse into sublink subqueries, too.  But we already did the ones in
1868 	 * the rtable and cteList.
1869 	 */
1870 	if (parsetree->hasSubLinks)
1871 	{
1872 		query_tree_walker(parsetree, ScanQueryWalker,
1873 						  (void *) &acquire,
1874 						  QTW_IGNORE_RC_SUBQUERIES);
1875 	}
1876 }
1877 
1878 /*
1879  * Walker to find sublink subqueries for ScanQueryForLocks
1880  */
1881 static bool
ScanQueryWalker(Node * node,bool * acquire)1882 ScanQueryWalker(Node *node, bool *acquire)
1883 {
1884 	if (node == NULL)
1885 		return false;
1886 	if (IsA(node, SubLink))
1887 	{
1888 		SubLink    *sub = (SubLink *) node;
1889 
1890 		/* Do what we came for */
1891 		ScanQueryForLocks(castNode(Query, sub->subselect), *acquire);
1892 		/* Fall through to process lefthand args of SubLink */
1893 	}
1894 
1895 	/*
1896 	 * Do NOT recurse into Query nodes, because ScanQueryForLocks already
1897 	 * processed subselects of subselects for us.
1898 	 */
1899 	return expression_tree_walker(node, ScanQueryWalker,
1900 								  (void *) acquire);
1901 }
1902 
1903 /*
1904  * PlanCacheComputeResultDesc: given a list of analyzed-and-rewritten Queries,
1905  * determine the result tupledesc it will produce.  Returns NULL if the
1906  * execution will not return tuples.
1907  *
1908  * Note: the result is created or copied into current memory context.
1909  */
1910 static TupleDesc
PlanCacheComputeResultDesc(List * stmt_list)1911 PlanCacheComputeResultDesc(List *stmt_list)
1912 {
1913 	Query	   *query;
1914 
1915 	switch (ChoosePortalStrategy(stmt_list))
1916 	{
1917 		case PORTAL_ONE_SELECT:
1918 		case PORTAL_ONE_MOD_WITH:
1919 			query = linitial_node(Query, stmt_list);
1920 			return ExecCleanTypeFromTL(query->targetList);
1921 
1922 		case PORTAL_ONE_RETURNING:
1923 			query = QueryListGetPrimaryStmt(stmt_list);
1924 			Assert(query->returningList);
1925 			return ExecCleanTypeFromTL(query->returningList);
1926 
1927 		case PORTAL_UTIL_SELECT:
1928 			query = linitial_node(Query, stmt_list);
1929 			Assert(query->utilityStmt);
1930 			return UtilityTupleDescriptor(query->utilityStmt);
1931 
1932 		case PORTAL_MULTI_QUERY:
1933 			/* will not return tuples */
1934 			break;
1935 	}
1936 	return NULL;
1937 }
1938 
1939 /*
1940  * PlanCacheRelCallback
1941  *		Relcache inval callback function
1942  *
1943  * Invalidate all plans mentioning the given rel, or all plans mentioning
1944  * any rel at all if relid == InvalidOid.
1945  */
1946 static void
PlanCacheRelCallback(Datum arg,Oid relid)1947 PlanCacheRelCallback(Datum arg, Oid relid)
1948 {
1949 	dlist_iter	iter;
1950 
1951 	dlist_foreach(iter, &saved_plan_list)
1952 	{
1953 		CachedPlanSource *plansource = dlist_container(CachedPlanSource,
1954 													   node, iter.cur);
1955 
1956 		Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1957 
1958 		/* No work if it's already invalidated */
1959 		if (!plansource->is_valid)
1960 			continue;
1961 
1962 		/* Never invalidate transaction control commands */
1963 		if (IsTransactionStmtPlan(plansource))
1964 			continue;
1965 
1966 		/*
1967 		 * Check the dependency list for the rewritten querytree.
1968 		 */
1969 		if ((relid == InvalidOid) ? plansource->relationOids != NIL :
1970 			list_member_oid(plansource->relationOids, relid))
1971 		{
1972 			/* Invalidate the querytree and generic plan */
1973 			plansource->is_valid = false;
1974 			if (plansource->gplan)
1975 				plansource->gplan->is_valid = false;
1976 		}
1977 
1978 		/*
1979 		 * The generic plan, if any, could have more dependencies than the
1980 		 * querytree does, so we have to check it too.
1981 		 */
1982 		if (plansource->gplan && plansource->gplan->is_valid)
1983 		{
1984 			ListCell   *lc;
1985 
1986 			foreach(lc, plansource->gplan->stmt_list)
1987 			{
1988 				PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1989 
1990 				if (plannedstmt->commandType == CMD_UTILITY)
1991 					continue;	/* Ignore utility statements */
1992 				if ((relid == InvalidOid) ? plannedstmt->relationOids != NIL :
1993 					list_member_oid(plannedstmt->relationOids, relid))
1994 				{
1995 					/* Invalidate the generic plan only */
1996 					plansource->gplan->is_valid = false;
1997 					break;		/* out of stmt_list scan */
1998 				}
1999 			}
2000 		}
2001 	}
2002 
2003 	/* Likewise check cached expressions */
2004 	dlist_foreach(iter, &cached_expression_list)
2005 	{
2006 		CachedExpression *cexpr = dlist_container(CachedExpression,
2007 												  node, iter.cur);
2008 
2009 		Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2010 
2011 		/* No work if it's already invalidated */
2012 		if (!cexpr->is_valid)
2013 			continue;
2014 
2015 		if ((relid == InvalidOid) ? cexpr->relationOids != NIL :
2016 			list_member_oid(cexpr->relationOids, relid))
2017 		{
2018 			cexpr->is_valid = false;
2019 		}
2020 	}
2021 }
2022 
2023 /*
2024  * PlanCacheObjectCallback
2025  *		Syscache inval callback function for PROCOID and TYPEOID caches
2026  *
2027  * Invalidate all plans mentioning the object with the specified hash value,
2028  * or all plans mentioning any member of this cache if hashvalue == 0.
2029  */
2030 static void
PlanCacheObjectCallback(Datum arg,int cacheid,uint32 hashvalue)2031 PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue)
2032 {
2033 	dlist_iter	iter;
2034 
2035 	dlist_foreach(iter, &saved_plan_list)
2036 	{
2037 		CachedPlanSource *plansource = dlist_container(CachedPlanSource,
2038 													   node, iter.cur);
2039 		ListCell   *lc;
2040 
2041 		Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
2042 
2043 		/* No work if it's already invalidated */
2044 		if (!plansource->is_valid)
2045 			continue;
2046 
2047 		/* Never invalidate transaction control commands */
2048 		if (IsTransactionStmtPlan(plansource))
2049 			continue;
2050 
2051 		/*
2052 		 * Check the dependency list for the rewritten querytree.
2053 		 */
2054 		foreach(lc, plansource->invalItems)
2055 		{
2056 			PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
2057 
2058 			if (item->cacheId != cacheid)
2059 				continue;
2060 			if (hashvalue == 0 ||
2061 				item->hashValue == hashvalue)
2062 			{
2063 				/* Invalidate the querytree and generic plan */
2064 				plansource->is_valid = false;
2065 				if (plansource->gplan)
2066 					plansource->gplan->is_valid = false;
2067 				break;
2068 			}
2069 		}
2070 
2071 		/*
2072 		 * The generic plan, if any, could have more dependencies than the
2073 		 * querytree does, so we have to check it too.
2074 		 */
2075 		if (plansource->gplan && plansource->gplan->is_valid)
2076 		{
2077 			foreach(lc, plansource->gplan->stmt_list)
2078 			{
2079 				PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
2080 				ListCell   *lc3;
2081 
2082 				if (plannedstmt->commandType == CMD_UTILITY)
2083 					continue;	/* Ignore utility statements */
2084 				foreach(lc3, plannedstmt->invalItems)
2085 				{
2086 					PlanInvalItem *item = (PlanInvalItem *) lfirst(lc3);
2087 
2088 					if (item->cacheId != cacheid)
2089 						continue;
2090 					if (hashvalue == 0 ||
2091 						item->hashValue == hashvalue)
2092 					{
2093 						/* Invalidate the generic plan only */
2094 						plansource->gplan->is_valid = false;
2095 						break;	/* out of invalItems scan */
2096 					}
2097 				}
2098 				if (!plansource->gplan->is_valid)
2099 					break;		/* out of stmt_list scan */
2100 			}
2101 		}
2102 	}
2103 
2104 	/* Likewise check cached expressions */
2105 	dlist_foreach(iter, &cached_expression_list)
2106 	{
2107 		CachedExpression *cexpr = dlist_container(CachedExpression,
2108 												  node, iter.cur);
2109 		ListCell   *lc;
2110 
2111 		Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2112 
2113 		/* No work if it's already invalidated */
2114 		if (!cexpr->is_valid)
2115 			continue;
2116 
2117 		foreach(lc, cexpr->invalItems)
2118 		{
2119 			PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
2120 
2121 			if (item->cacheId != cacheid)
2122 				continue;
2123 			if (hashvalue == 0 ||
2124 				item->hashValue == hashvalue)
2125 			{
2126 				cexpr->is_valid = false;
2127 				break;
2128 			}
2129 		}
2130 	}
2131 }
2132 
2133 /*
2134  * PlanCacheSysCallback
2135  *		Syscache inval callback function for other caches
2136  *
2137  * Just invalidate everything...
2138  */
2139 static void
PlanCacheSysCallback(Datum arg,int cacheid,uint32 hashvalue)2140 PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
2141 {
2142 	ResetPlanCache();
2143 }
2144 
2145 /*
2146  * ResetPlanCache: invalidate all cached plans.
2147  */
2148 void
ResetPlanCache(void)2149 ResetPlanCache(void)
2150 {
2151 	dlist_iter	iter;
2152 
2153 	dlist_foreach(iter, &saved_plan_list)
2154 	{
2155 		CachedPlanSource *plansource = dlist_container(CachedPlanSource,
2156 													   node, iter.cur);
2157 		ListCell   *lc;
2158 
2159 		Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
2160 
2161 		/* No work if it's already invalidated */
2162 		if (!plansource->is_valid)
2163 			continue;
2164 
2165 		/*
2166 		 * We *must not* mark transaction control statements as invalid,
2167 		 * particularly not ROLLBACK, because they may need to be executed in
2168 		 * aborted transactions when we can't revalidate them (cf bug #5269).
2169 		 */
2170 		if (IsTransactionStmtPlan(plansource))
2171 			continue;
2172 
2173 		/*
2174 		 * In general there is no point in invalidating utility statements
2175 		 * since they have no plans anyway.  So invalidate it only if it
2176 		 * contains at least one non-utility statement, or contains a utility
2177 		 * statement that contains a pre-analyzed query (which could have
2178 		 * dependencies.)
2179 		 */
2180 		foreach(lc, plansource->query_list)
2181 		{
2182 			Query	   *query = lfirst_node(Query, lc);
2183 
2184 			if (query->commandType != CMD_UTILITY ||
2185 				UtilityContainsQuery(query->utilityStmt))
2186 			{
2187 				/* non-utility statement, so invalidate */
2188 				plansource->is_valid = false;
2189 				if (plansource->gplan)
2190 					plansource->gplan->is_valid = false;
2191 				/* no need to look further */
2192 				break;
2193 			}
2194 		}
2195 	}
2196 
2197 	/* Likewise invalidate cached expressions */
2198 	dlist_foreach(iter, &cached_expression_list)
2199 	{
2200 		CachedExpression *cexpr = dlist_container(CachedExpression,
2201 												  node, iter.cur);
2202 
2203 		Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2204 
2205 		cexpr->is_valid = false;
2206 	}
2207 }
2208