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