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-2019, 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
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: compile-time-constant tag for query, or NULL if empty query
162  */
163 CachedPlanSource *
164 CreateCachedPlan(RawStmt *raw_parse_tree,
165 				 const char *query_string,
166 				 const char *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: compile-time-constant tag for query, or NULL if empty query
245  */
246 CachedPlanSource *
247 CreateOneShotCachedPlan(RawStmt *raw_parse_tree,
248 						const char *query_string,
249 						const char *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
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
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
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
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 *
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
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 *
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->cursor_options, boundParams);
934 
935 	/* Release snapshot if we got one */
936 	if (snapshot_set)
937 		PopActiveSnapshot();
938 
939 	/*
940 	 * Normally we make a dedicated memory context for the CachedPlan and its
941 	 * subsidiary data.  (It's probably not going to be large, but just in
942 	 * case, allow it to grow large.  It's transient for the moment.)  But for
943 	 * a one-shot plan, we just leave it in the caller's memory context.
944 	 */
945 	if (!plansource->is_oneshot)
946 	{
947 		plan_context = AllocSetContextCreate(CurrentMemoryContext,
948 											 "CachedPlan",
949 											 ALLOCSET_START_SMALL_SIZES);
950 		MemoryContextCopyAndSetIdentifier(plan_context, plansource->query_string);
951 
952 		/*
953 		 * Copy plan into the new context.
954 		 */
955 		MemoryContextSwitchTo(plan_context);
956 
957 		plist = copyObject(plist);
958 	}
959 	else
960 		plan_context = CurrentMemoryContext;
961 
962 	/*
963 	 * Create and fill the CachedPlan struct within the new context.
964 	 */
965 	plan = (CachedPlan *) palloc(sizeof(CachedPlan));
966 	plan->magic = CACHEDPLAN_MAGIC;
967 	plan->stmt_list = plist;
968 
969 	/*
970 	 * CachedPlan is dependent on role either if RLS affected the rewrite
971 	 * phase or if a role dependency was injected during planning.  And it's
972 	 * transient if any plan is marked so.
973 	 */
974 	plan->planRoleId = GetUserId();
975 	plan->dependsOnRole = plansource->dependsOnRLS;
976 	is_transient = false;
977 	foreach(lc, plist)
978 	{
979 		PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
980 
981 		if (plannedstmt->commandType == CMD_UTILITY)
982 			continue;			/* Ignore utility statements */
983 
984 		if (plannedstmt->transientPlan)
985 			is_transient = true;
986 		if (plannedstmt->dependsOnRole)
987 			plan->dependsOnRole = true;
988 	}
989 	if (is_transient)
990 	{
991 		Assert(TransactionIdIsNormal(TransactionXmin));
992 		plan->saved_xmin = TransactionXmin;
993 	}
994 	else
995 		plan->saved_xmin = InvalidTransactionId;
996 	plan->refcount = 0;
997 	plan->context = plan_context;
998 	plan->is_oneshot = plansource->is_oneshot;
999 	plan->is_saved = false;
1000 	plan->is_valid = true;
1001 
1002 	/* assign generation number to new plan */
1003 	plan->generation = ++(plansource->generation);
1004 
1005 	MemoryContextSwitchTo(oldcxt);
1006 
1007 	return plan;
1008 }
1009 
1010 /*
1011  * choose_custom_plan: choose whether to use custom or generic plan
1012  *
1013  * This defines the policy followed by GetCachedPlan.
1014  */
1015 static bool
1016 choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams)
1017 {
1018 	double		avg_custom_cost;
1019 
1020 	/* One-shot plans will always be considered custom */
1021 	if (plansource->is_oneshot)
1022 		return true;
1023 
1024 	/* Otherwise, never any point in a custom plan if there's no parameters */
1025 	if (boundParams == NULL)
1026 		return false;
1027 	/* ... nor for transaction control statements */
1028 	if (IsTransactionStmtPlan(plansource))
1029 		return false;
1030 
1031 	/* Let settings force the decision */
1032 	if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_GENERIC_PLAN)
1033 		return false;
1034 	if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN)
1035 		return true;
1036 
1037 	/* See if caller wants to force the decision */
1038 	if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN)
1039 		return false;
1040 	if (plansource->cursor_options & CURSOR_OPT_CUSTOM_PLAN)
1041 		return true;
1042 
1043 	/* Generate custom plans until we have done at least 5 (arbitrary) */
1044 	if (plansource->num_custom_plans < 5)
1045 		return true;
1046 
1047 	avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans;
1048 
1049 	/*
1050 	 * Prefer generic plan if it's less expensive than the average custom
1051 	 * plan.  (Because we include a charge for cost of planning in the
1052 	 * custom-plan costs, this means the generic plan only has to be less
1053 	 * expensive than the execution cost plus replan cost of the custom
1054 	 * plans.)
1055 	 *
1056 	 * Note that if generic_cost is -1 (indicating we've not yet determined
1057 	 * the generic plan cost), we'll always prefer generic at this point.
1058 	 */
1059 	if (plansource->generic_cost < avg_custom_cost)
1060 		return false;
1061 
1062 	return true;
1063 }
1064 
1065 /*
1066  * cached_plan_cost: calculate estimated cost of a plan
1067  *
1068  * If include_planner is true, also include the estimated cost of constructing
1069  * the plan.  (We must factor that into the cost of using a custom plan, but
1070  * we don't count it for a generic plan.)
1071  */
1072 static double
1073 cached_plan_cost(CachedPlan *plan, bool include_planner)
1074 {
1075 	double		result = 0;
1076 	ListCell   *lc;
1077 
1078 	foreach(lc, plan->stmt_list)
1079 	{
1080 		PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1081 
1082 		if (plannedstmt->commandType == CMD_UTILITY)
1083 			continue;			/* Ignore utility statements */
1084 
1085 		result += plannedstmt->planTree->total_cost;
1086 
1087 		if (include_planner)
1088 		{
1089 			/*
1090 			 * Currently we use a very crude estimate of planning effort based
1091 			 * on the number of relations in the finished plan's rangetable.
1092 			 * Join planning effort actually scales much worse than linearly
1093 			 * in the number of relations --- but only until the join collapse
1094 			 * limits kick in.  Also, while inheritance child relations surely
1095 			 * add to planning effort, they don't make the join situation
1096 			 * worse.  So the actual shape of the planning cost curve versus
1097 			 * number of relations isn't all that obvious.  It will take
1098 			 * considerable work to arrive at a less crude estimate, and for
1099 			 * now it's not clear that's worth doing.
1100 			 *
1101 			 * The other big difficulty here is that we don't have any very
1102 			 * good model of how planning cost compares to execution costs.
1103 			 * The current multiplier of 1000 * cpu_operator_cost is probably
1104 			 * on the low side, but we'll try this for awhile before making a
1105 			 * more aggressive correction.
1106 			 *
1107 			 * If we ever do write a more complicated estimator, it should
1108 			 * probably live in src/backend/optimizer/ not here.
1109 			 */
1110 			int			nrelations = list_length(plannedstmt->rtable);
1111 
1112 			result += 1000.0 * cpu_operator_cost * (nrelations + 1);
1113 		}
1114 	}
1115 
1116 	return result;
1117 }
1118 
1119 /*
1120  * GetCachedPlan: get a cached plan from a CachedPlanSource.
1121  *
1122  * This function hides the logic that decides whether to use a generic
1123  * plan or a custom plan for the given parameters: the caller does not know
1124  * which it will get.
1125  *
1126  * On return, the plan is valid and we have sufficient locks to begin
1127  * execution.
1128  *
1129  * On return, the refcount of the plan has been incremented; a later
1130  * ReleaseCachedPlan() call is expected.  The refcount has been reported
1131  * to the CurrentResourceOwner if useResOwner is true (note that that must
1132  * only be true if it's a "saved" CachedPlanSource).
1133  *
1134  * Note: if any replanning activity is required, the caller's memory context
1135  * is used for that work.
1136  */
1137 CachedPlan *
1138 GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams,
1139 			  bool useResOwner, QueryEnvironment *queryEnv)
1140 {
1141 	CachedPlan *plan = NULL;
1142 	List	   *qlist;
1143 	bool		customplan;
1144 
1145 	/* Assert caller is doing things in a sane order */
1146 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1147 	Assert(plansource->is_complete);
1148 	/* This seems worth a real test, though */
1149 	if (useResOwner && !plansource->is_saved)
1150 		elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
1151 
1152 	/* Make sure the querytree list is valid and we have parse-time locks */
1153 	qlist = RevalidateCachedQuery(plansource, queryEnv);
1154 
1155 	/* Decide whether to use a custom plan */
1156 	customplan = choose_custom_plan(plansource, boundParams);
1157 
1158 	if (!customplan)
1159 	{
1160 		if (CheckCachedPlan(plansource))
1161 		{
1162 			/* We want a generic plan, and we already have a valid one */
1163 			plan = plansource->gplan;
1164 			Assert(plan->magic == CACHEDPLAN_MAGIC);
1165 		}
1166 		else
1167 		{
1168 			/* Build a new generic plan */
1169 			plan = BuildCachedPlan(plansource, qlist, NULL, queryEnv);
1170 			/* Just make real sure plansource->gplan is clear */
1171 			ReleaseGenericPlan(plansource);
1172 			/* Link the new generic plan into the plansource */
1173 			plansource->gplan = plan;
1174 			plan->refcount++;
1175 			/* Immediately reparent into appropriate context */
1176 			if (plansource->is_saved)
1177 			{
1178 				/* saved plans all live under CacheMemoryContext */
1179 				MemoryContextSetParent(plan->context, CacheMemoryContext);
1180 				plan->is_saved = true;
1181 			}
1182 			else
1183 			{
1184 				/* otherwise, it should be a sibling of the plansource */
1185 				MemoryContextSetParent(plan->context,
1186 									   MemoryContextGetParent(plansource->context));
1187 			}
1188 			/* Update generic_cost whenever we make a new generic plan */
1189 			plansource->generic_cost = cached_plan_cost(plan, false);
1190 
1191 			/*
1192 			 * If, based on the now-known value of generic_cost, we'd not have
1193 			 * chosen to use a generic plan, then forget it and make a custom
1194 			 * plan.  This is a bit of a wart but is necessary to avoid a
1195 			 * glitch in behavior when the custom plans are consistently big
1196 			 * winners; at some point we'll experiment with a generic plan and
1197 			 * find it's a loser, but we don't want to actually execute that
1198 			 * plan.
1199 			 */
1200 			customplan = choose_custom_plan(plansource, boundParams);
1201 
1202 			/*
1203 			 * If we choose to plan again, we need to re-copy the query_list,
1204 			 * since the planner probably scribbled on it.  We can force
1205 			 * BuildCachedPlan to do that by passing NIL.
1206 			 */
1207 			qlist = NIL;
1208 		}
1209 	}
1210 
1211 	if (customplan)
1212 	{
1213 		/* Build a custom plan */
1214 		plan = BuildCachedPlan(plansource, qlist, boundParams, queryEnv);
1215 		/* Accumulate total costs of custom plans, but 'ware overflow */
1216 		if (plansource->num_custom_plans < INT_MAX)
1217 		{
1218 			plansource->total_custom_cost += cached_plan_cost(plan, true);
1219 			plansource->num_custom_plans++;
1220 		}
1221 	}
1222 
1223 	Assert(plan != NULL);
1224 
1225 	/* Flag the plan as in use by caller */
1226 	if (useResOwner)
1227 		ResourceOwnerEnlargePlanCacheRefs(CurrentResourceOwner);
1228 	plan->refcount++;
1229 	if (useResOwner)
1230 		ResourceOwnerRememberPlanCacheRef(CurrentResourceOwner, plan);
1231 
1232 	/*
1233 	 * Saved plans should be under CacheMemoryContext so they will not go away
1234 	 * until their reference count goes to zero.  In the generic-plan cases we
1235 	 * already took care of that, but for a custom plan, do it as soon as we
1236 	 * have created a reference-counted link.
1237 	 */
1238 	if (customplan && plansource->is_saved)
1239 	{
1240 		MemoryContextSetParent(plan->context, CacheMemoryContext);
1241 		plan->is_saved = true;
1242 	}
1243 
1244 	return plan;
1245 }
1246 
1247 /*
1248  * ReleaseCachedPlan: release active use of a cached plan.
1249  *
1250  * This decrements the reference count, and frees the plan if the count
1251  * has thereby gone to zero.  If useResOwner is true, it is assumed that
1252  * the reference count is managed by the CurrentResourceOwner.
1253  *
1254  * Note: useResOwner = false is used for releasing references that are in
1255  * persistent data structures, such as the parent CachedPlanSource or a
1256  * Portal.  Transient references should be protected by a resource owner.
1257  */
1258 void
1259 ReleaseCachedPlan(CachedPlan *plan, bool useResOwner)
1260 {
1261 	Assert(plan->magic == CACHEDPLAN_MAGIC);
1262 	if (useResOwner)
1263 	{
1264 		Assert(plan->is_saved);
1265 		ResourceOwnerForgetPlanCacheRef(CurrentResourceOwner, plan);
1266 	}
1267 	Assert(plan->refcount > 0);
1268 	plan->refcount--;
1269 	if (plan->refcount == 0)
1270 	{
1271 		/* Mark it no longer valid */
1272 		plan->magic = 0;
1273 
1274 		/* One-shot plans do not own their context, so we can't free them */
1275 		if (!plan->is_oneshot)
1276 			MemoryContextDelete(plan->context);
1277 	}
1278 }
1279 
1280 /*
1281  * CachedPlanSetParentContext: move a CachedPlanSource to a new memory context
1282  *
1283  * This can only be applied to unsaved plans; once saved, a plan always
1284  * lives underneath CacheMemoryContext.
1285  */
1286 void
1287 CachedPlanSetParentContext(CachedPlanSource *plansource,
1288 						   MemoryContext newcontext)
1289 {
1290 	/* Assert caller is doing things in a sane order */
1291 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1292 	Assert(plansource->is_complete);
1293 
1294 	/* These seem worth real tests, though */
1295 	if (plansource->is_saved)
1296 		elog(ERROR, "cannot move a saved cached plan to another context");
1297 	if (plansource->is_oneshot)
1298 		elog(ERROR, "cannot move a one-shot cached plan to another context");
1299 
1300 	/* OK, let the caller keep the plan where he wishes */
1301 	MemoryContextSetParent(plansource->context, newcontext);
1302 
1303 	/*
1304 	 * The query_context needs no special handling, since it's a child of
1305 	 * plansource->context.  But if there's a generic plan, it should be
1306 	 * maintained as a sibling of plansource->context.
1307 	 */
1308 	if (plansource->gplan)
1309 	{
1310 		Assert(plansource->gplan->magic == CACHEDPLAN_MAGIC);
1311 		MemoryContextSetParent(plansource->gplan->context, newcontext);
1312 	}
1313 }
1314 
1315 /*
1316  * CopyCachedPlan: make a copy of a CachedPlanSource
1317  *
1318  * This is a convenience routine that does the equivalent of
1319  * CreateCachedPlan + CompleteCachedPlan, using the data stored in the
1320  * input CachedPlanSource.  The result is therefore "unsaved" (regardless
1321  * of the state of the source), and we don't copy any generic plan either.
1322  * The result will be currently valid, or not, the same as the source.
1323  */
1324 CachedPlanSource *
1325 CopyCachedPlan(CachedPlanSource *plansource)
1326 {
1327 	CachedPlanSource *newsource;
1328 	MemoryContext source_context;
1329 	MemoryContext querytree_context;
1330 	MemoryContext oldcxt;
1331 
1332 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1333 	Assert(plansource->is_complete);
1334 
1335 	/*
1336 	 * One-shot plans can't be copied, because we haven't taken care that
1337 	 * parsing/planning didn't scribble on the raw parse tree or querytrees.
1338 	 */
1339 	if (plansource->is_oneshot)
1340 		elog(ERROR, "cannot copy a one-shot cached plan");
1341 
1342 	source_context = AllocSetContextCreate(CurrentMemoryContext,
1343 										   "CachedPlanSource",
1344 										   ALLOCSET_START_SMALL_SIZES);
1345 
1346 	oldcxt = MemoryContextSwitchTo(source_context);
1347 
1348 	newsource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
1349 	newsource->magic = CACHEDPLANSOURCE_MAGIC;
1350 	newsource->raw_parse_tree = copyObject(plansource->raw_parse_tree);
1351 	newsource->query_string = pstrdup(plansource->query_string);
1352 	MemoryContextSetIdentifier(source_context, newsource->query_string);
1353 	newsource->commandTag = plansource->commandTag;
1354 	if (plansource->num_params > 0)
1355 	{
1356 		newsource->param_types = (Oid *)
1357 			palloc(plansource->num_params * sizeof(Oid));
1358 		memcpy(newsource->param_types, plansource->param_types,
1359 			   plansource->num_params * sizeof(Oid));
1360 	}
1361 	else
1362 		newsource->param_types = NULL;
1363 	newsource->num_params = plansource->num_params;
1364 	newsource->parserSetup = plansource->parserSetup;
1365 	newsource->parserSetupArg = plansource->parserSetupArg;
1366 	newsource->cursor_options = plansource->cursor_options;
1367 	newsource->fixed_result = plansource->fixed_result;
1368 	if (plansource->resultDesc)
1369 		newsource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
1370 	else
1371 		newsource->resultDesc = NULL;
1372 	newsource->context = source_context;
1373 
1374 	querytree_context = AllocSetContextCreate(source_context,
1375 											  "CachedPlanQuery",
1376 											  ALLOCSET_START_SMALL_SIZES);
1377 	MemoryContextSwitchTo(querytree_context);
1378 	newsource->query_list = copyObject(plansource->query_list);
1379 	newsource->relationOids = copyObject(plansource->relationOids);
1380 	newsource->invalItems = copyObject(plansource->invalItems);
1381 	if (plansource->search_path)
1382 		newsource->search_path = CopyOverrideSearchPath(plansource->search_path);
1383 	newsource->query_context = querytree_context;
1384 	newsource->rewriteRoleId = plansource->rewriteRoleId;
1385 	newsource->rewriteRowSecurity = plansource->rewriteRowSecurity;
1386 	newsource->dependsOnRLS = plansource->dependsOnRLS;
1387 
1388 	newsource->gplan = NULL;
1389 
1390 	newsource->is_oneshot = false;
1391 	newsource->is_complete = true;
1392 	newsource->is_saved = false;
1393 	newsource->is_valid = plansource->is_valid;
1394 	newsource->generation = plansource->generation;
1395 
1396 	/* We may as well copy any acquired cost knowledge */
1397 	newsource->generic_cost = plansource->generic_cost;
1398 	newsource->total_custom_cost = plansource->total_custom_cost;
1399 	newsource->num_custom_plans = plansource->num_custom_plans;
1400 
1401 	MemoryContextSwitchTo(oldcxt);
1402 
1403 	return newsource;
1404 }
1405 
1406 /*
1407  * CachedPlanIsValid: test whether the rewritten querytree within a
1408  * CachedPlanSource is currently valid (that is, not marked as being in need
1409  * of revalidation).
1410  *
1411  * This result is only trustworthy (ie, free from race conditions) if
1412  * the caller has acquired locks on all the relations used in the plan.
1413  */
1414 bool
1415 CachedPlanIsValid(CachedPlanSource *plansource)
1416 {
1417 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1418 	return plansource->is_valid;
1419 }
1420 
1421 /*
1422  * CachedPlanGetTargetList: return tlist, if any, describing plan's output
1423  *
1424  * The result is guaranteed up-to-date.  However, it is local storage
1425  * within the cached plan, and may disappear next time the plan is updated.
1426  */
1427 List *
1428 CachedPlanGetTargetList(CachedPlanSource *plansource,
1429 						QueryEnvironment *queryEnv)
1430 {
1431 	Query	   *pstmt;
1432 
1433 	/* Assert caller is doing things in a sane order */
1434 	Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1435 	Assert(plansource->is_complete);
1436 
1437 	/*
1438 	 * No work needed if statement doesn't return tuples (we assume this
1439 	 * feature cannot be changed by an invalidation)
1440 	 */
1441 	if (plansource->resultDesc == NULL)
1442 		return NIL;
1443 
1444 	/* Make sure the querytree list is valid and we have parse-time locks */
1445 	RevalidateCachedQuery(plansource, queryEnv);
1446 
1447 	/* Get the primary statement and find out what it returns */
1448 	pstmt = QueryListGetPrimaryStmt(plansource->query_list);
1449 
1450 	return FetchStatementTargetList((Node *) pstmt);
1451 }
1452 
1453 /*
1454  * GetCachedExpression: construct a CachedExpression for an expression.
1455  *
1456  * This performs the same transformations on the expression as
1457  * expression_planner(), ie, convert an expression as emitted by parse
1458  * analysis to be ready to pass to the executor.
1459  *
1460  * The result is stashed in a private, long-lived memory context.
1461  * (Note that this might leak a good deal of memory in the caller's
1462  * context before that.)  The passed-in expr tree is not modified.
1463  */
1464 CachedExpression *
1465 GetCachedExpression(Node *expr)
1466 {
1467 	CachedExpression *cexpr;
1468 	List	   *relationOids;
1469 	List	   *invalItems;
1470 	MemoryContext cexpr_context;
1471 	MemoryContext oldcxt;
1472 
1473 	/*
1474 	 * Pass the expression through the planner, and collect dependencies.
1475 	 * Everything built here is leaked in the caller's context; that's
1476 	 * intentional to minimize the size of the permanent data structure.
1477 	 */
1478 	expr = (Node *) expression_planner_with_deps((Expr *) expr,
1479 												 &relationOids,
1480 												 &invalItems);
1481 
1482 	/*
1483 	 * Make a private memory context, and copy what we need into that.  To
1484 	 * avoid leaking a long-lived context if we fail while copying data, we
1485 	 * initially make the context under the caller's context.
1486 	 */
1487 	cexpr_context = AllocSetContextCreate(CurrentMemoryContext,
1488 										  "CachedExpression",
1489 										  ALLOCSET_SMALL_SIZES);
1490 
1491 	oldcxt = MemoryContextSwitchTo(cexpr_context);
1492 
1493 	cexpr = (CachedExpression *) palloc(sizeof(CachedExpression));
1494 	cexpr->magic = CACHEDEXPR_MAGIC;
1495 	cexpr->expr = copyObject(expr);
1496 	cexpr->is_valid = true;
1497 	cexpr->relationOids = copyObject(relationOids);
1498 	cexpr->invalItems = copyObject(invalItems);
1499 	cexpr->context = cexpr_context;
1500 
1501 	MemoryContextSwitchTo(oldcxt);
1502 
1503 	/*
1504 	 * Reparent the expr's memory context under CacheMemoryContext so that it
1505 	 * will live indefinitely.
1506 	 */
1507 	MemoryContextSetParent(cexpr_context, CacheMemoryContext);
1508 
1509 	/*
1510 	 * Add the entry to the global list of cached expressions.
1511 	 */
1512 	dlist_push_tail(&cached_expression_list, &cexpr->node);
1513 
1514 	return cexpr;
1515 }
1516 
1517 /*
1518  * FreeCachedExpression
1519  *		Delete a CachedExpression.
1520  */
1521 void
1522 FreeCachedExpression(CachedExpression *cexpr)
1523 {
1524 	/* Sanity check */
1525 	Assert(cexpr->magic == CACHEDEXPR_MAGIC);
1526 	/* Unlink from global list */
1527 	dlist_delete(&cexpr->node);
1528 	/* Free all storage associated with CachedExpression */
1529 	MemoryContextDelete(cexpr->context);
1530 }
1531 
1532 /*
1533  * QueryListGetPrimaryStmt
1534  *		Get the "primary" stmt within a list, ie, the one marked canSetTag.
1535  *
1536  * Returns NULL if no such stmt.  If multiple queries within the list are
1537  * marked canSetTag, returns the first one.  Neither of these cases should
1538  * occur in present usages of this function.
1539  */
1540 static Query *
1541 QueryListGetPrimaryStmt(List *stmts)
1542 {
1543 	ListCell   *lc;
1544 
1545 	foreach(lc, stmts)
1546 	{
1547 		Query	   *stmt = lfirst_node(Query, lc);
1548 
1549 		if (stmt->canSetTag)
1550 			return stmt;
1551 	}
1552 	return NULL;
1553 }
1554 
1555 /*
1556  * AcquireExecutorLocks: acquire locks needed for execution of a cached plan;
1557  * or release them if acquire is false.
1558  */
1559 static void
1560 AcquireExecutorLocks(List *stmt_list, bool acquire)
1561 {
1562 	ListCell   *lc1;
1563 
1564 	foreach(lc1, stmt_list)
1565 	{
1566 		PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc1);
1567 		ListCell   *lc2;
1568 
1569 		if (plannedstmt->commandType == CMD_UTILITY)
1570 		{
1571 			/*
1572 			 * Ignore utility statements, except those (such as EXPLAIN) that
1573 			 * contain a parsed-but-not-planned query.  Note: it's okay to use
1574 			 * ScanQueryForLocks, even though the query hasn't been through
1575 			 * rule rewriting, because rewriting doesn't change the query
1576 			 * representation.
1577 			 */
1578 			Query	   *query = UtilityContainsQuery(plannedstmt->utilityStmt);
1579 
1580 			if (query)
1581 				ScanQueryForLocks(query, acquire);
1582 			continue;
1583 		}
1584 
1585 		foreach(lc2, plannedstmt->rtable)
1586 		{
1587 			RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
1588 
1589 			if (rte->rtekind != RTE_RELATION)
1590 				continue;
1591 
1592 			/*
1593 			 * Acquire the appropriate type of lock on each relation OID. Note
1594 			 * that we don't actually try to open the rel, and hence will not
1595 			 * fail if it's been dropped entirely --- we'll just transiently
1596 			 * acquire a non-conflicting lock.
1597 			 */
1598 			if (acquire)
1599 				LockRelationOid(rte->relid, rte->rellockmode);
1600 			else
1601 				UnlockRelationOid(rte->relid, rte->rellockmode);
1602 		}
1603 	}
1604 }
1605 
1606 /*
1607  * AcquirePlannerLocks: acquire locks needed for planning of a querytree list;
1608  * or release them if acquire is false.
1609  *
1610  * Note that we don't actually try to open the relations, and hence will not
1611  * fail if one has been dropped entirely --- we'll just transiently acquire
1612  * a non-conflicting lock.
1613  */
1614 static void
1615 AcquirePlannerLocks(List *stmt_list, bool acquire)
1616 {
1617 	ListCell   *lc;
1618 
1619 	foreach(lc, stmt_list)
1620 	{
1621 		Query	   *query = lfirst_node(Query, lc);
1622 
1623 		if (query->commandType == CMD_UTILITY)
1624 		{
1625 			/* Ignore utility statements, unless they contain a Query */
1626 			query = UtilityContainsQuery(query->utilityStmt);
1627 			if (query)
1628 				ScanQueryForLocks(query, acquire);
1629 			continue;
1630 		}
1631 
1632 		ScanQueryForLocks(query, acquire);
1633 	}
1634 }
1635 
1636 /*
1637  * ScanQueryForLocks: recursively scan one Query for AcquirePlannerLocks.
1638  */
1639 static void
1640 ScanQueryForLocks(Query *parsetree, bool acquire)
1641 {
1642 	ListCell   *lc;
1643 
1644 	/* Shouldn't get called on utility commands */
1645 	Assert(parsetree->commandType != CMD_UTILITY);
1646 
1647 	/*
1648 	 * First, process RTEs of the current query level.
1649 	 */
1650 	foreach(lc, parsetree->rtable)
1651 	{
1652 		RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
1653 
1654 		switch (rte->rtekind)
1655 		{
1656 			case RTE_RELATION:
1657 				/* Acquire or release the appropriate type of lock */
1658 				if (acquire)
1659 					LockRelationOid(rte->relid, rte->rellockmode);
1660 				else
1661 					UnlockRelationOid(rte->relid, rte->rellockmode);
1662 				break;
1663 
1664 			case RTE_SUBQUERY:
1665 				/* Recurse into subquery-in-FROM */
1666 				ScanQueryForLocks(rte->subquery, acquire);
1667 				break;
1668 
1669 			default:
1670 				/* ignore other types of RTEs */
1671 				break;
1672 		}
1673 	}
1674 
1675 	/* Recurse into subquery-in-WITH */
1676 	foreach(lc, parsetree->cteList)
1677 	{
1678 		CommonTableExpr *cte = lfirst_node(CommonTableExpr, lc);
1679 
1680 		ScanQueryForLocks(castNode(Query, cte->ctequery), acquire);
1681 	}
1682 
1683 	/*
1684 	 * Recurse into sublink subqueries, too.  But we already did the ones in
1685 	 * the rtable and cteList.
1686 	 */
1687 	if (parsetree->hasSubLinks)
1688 	{
1689 		query_tree_walker(parsetree, ScanQueryWalker,
1690 						  (void *) &acquire,
1691 						  QTW_IGNORE_RC_SUBQUERIES);
1692 	}
1693 }
1694 
1695 /*
1696  * Walker to find sublink subqueries for ScanQueryForLocks
1697  */
1698 static bool
1699 ScanQueryWalker(Node *node, bool *acquire)
1700 {
1701 	if (node == NULL)
1702 		return false;
1703 	if (IsA(node, SubLink))
1704 	{
1705 		SubLink    *sub = (SubLink *) node;
1706 
1707 		/* Do what we came for */
1708 		ScanQueryForLocks(castNode(Query, sub->subselect), *acquire);
1709 		/* Fall through to process lefthand args of SubLink */
1710 	}
1711 
1712 	/*
1713 	 * Do NOT recurse into Query nodes, because ScanQueryForLocks already
1714 	 * processed subselects of subselects for us.
1715 	 */
1716 	return expression_tree_walker(node, ScanQueryWalker,
1717 								  (void *) acquire);
1718 }
1719 
1720 /*
1721  * PlanCacheComputeResultDesc: given a list of analyzed-and-rewritten Queries,
1722  * determine the result tupledesc it will produce.  Returns NULL if the
1723  * execution will not return tuples.
1724  *
1725  * Note: the result is created or copied into current memory context.
1726  */
1727 static TupleDesc
1728 PlanCacheComputeResultDesc(List *stmt_list)
1729 {
1730 	Query	   *query;
1731 
1732 	switch (ChoosePortalStrategy(stmt_list))
1733 	{
1734 		case PORTAL_ONE_SELECT:
1735 		case PORTAL_ONE_MOD_WITH:
1736 			query = linitial_node(Query, stmt_list);
1737 			return ExecCleanTypeFromTL(query->targetList);
1738 
1739 		case PORTAL_ONE_RETURNING:
1740 			query = QueryListGetPrimaryStmt(stmt_list);
1741 			Assert(query->returningList);
1742 			return ExecCleanTypeFromTL(query->returningList);
1743 
1744 		case PORTAL_UTIL_SELECT:
1745 			query = linitial_node(Query, stmt_list);
1746 			Assert(query->utilityStmt);
1747 			return UtilityTupleDescriptor(query->utilityStmt);
1748 
1749 		case PORTAL_MULTI_QUERY:
1750 			/* will not return tuples */
1751 			break;
1752 	}
1753 	return NULL;
1754 }
1755 
1756 /*
1757  * PlanCacheRelCallback
1758  *		Relcache inval callback function
1759  *
1760  * Invalidate all plans mentioning the given rel, or all plans mentioning
1761  * any rel at all if relid == InvalidOid.
1762  */
1763 static void
1764 PlanCacheRelCallback(Datum arg, Oid relid)
1765 {
1766 	dlist_iter	iter;
1767 
1768 	dlist_foreach(iter, &saved_plan_list)
1769 	{
1770 		CachedPlanSource *plansource = dlist_container(CachedPlanSource,
1771 													   node, iter.cur);
1772 
1773 		Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1774 
1775 		/* No work if it's already invalidated */
1776 		if (!plansource->is_valid)
1777 			continue;
1778 
1779 		/* Never invalidate transaction control commands */
1780 		if (IsTransactionStmtPlan(plansource))
1781 			continue;
1782 
1783 		/*
1784 		 * Check the dependency list for the rewritten querytree.
1785 		 */
1786 		if ((relid == InvalidOid) ? plansource->relationOids != NIL :
1787 			list_member_oid(plansource->relationOids, relid))
1788 		{
1789 			/* Invalidate the querytree and generic plan */
1790 			plansource->is_valid = false;
1791 			if (plansource->gplan)
1792 				plansource->gplan->is_valid = false;
1793 		}
1794 
1795 		/*
1796 		 * The generic plan, if any, could have more dependencies than the
1797 		 * querytree does, so we have to check it too.
1798 		 */
1799 		if (plansource->gplan && plansource->gplan->is_valid)
1800 		{
1801 			ListCell   *lc;
1802 
1803 			foreach(lc, plansource->gplan->stmt_list)
1804 			{
1805 				PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1806 
1807 				if (plannedstmt->commandType == CMD_UTILITY)
1808 					continue;	/* Ignore utility statements */
1809 				if ((relid == InvalidOid) ? plannedstmt->relationOids != NIL :
1810 					list_member_oid(plannedstmt->relationOids, relid))
1811 				{
1812 					/* Invalidate the generic plan only */
1813 					plansource->gplan->is_valid = false;
1814 					break;		/* out of stmt_list scan */
1815 				}
1816 			}
1817 		}
1818 	}
1819 
1820 	/* Likewise check cached expressions */
1821 	dlist_foreach(iter, &cached_expression_list)
1822 	{
1823 		CachedExpression *cexpr = dlist_container(CachedExpression,
1824 												  node, iter.cur);
1825 
1826 		Assert(cexpr->magic == CACHEDEXPR_MAGIC);
1827 
1828 		/* No work if it's already invalidated */
1829 		if (!cexpr->is_valid)
1830 			continue;
1831 
1832 		if ((relid == InvalidOid) ? cexpr->relationOids != NIL :
1833 			list_member_oid(cexpr->relationOids, relid))
1834 		{
1835 			cexpr->is_valid = false;
1836 		}
1837 	}
1838 }
1839 
1840 /*
1841  * PlanCacheObjectCallback
1842  *		Syscache inval callback function for PROCOID and TYPEOID caches
1843  *
1844  * Invalidate all plans mentioning the object with the specified hash value,
1845  * or all plans mentioning any member of this cache if hashvalue == 0.
1846  */
1847 static void
1848 PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue)
1849 {
1850 	dlist_iter	iter;
1851 
1852 	dlist_foreach(iter, &saved_plan_list)
1853 	{
1854 		CachedPlanSource *plansource = dlist_container(CachedPlanSource,
1855 													   node, iter.cur);
1856 		ListCell   *lc;
1857 
1858 		Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1859 
1860 		/* No work if it's already invalidated */
1861 		if (!plansource->is_valid)
1862 			continue;
1863 
1864 		/* Never invalidate transaction control commands */
1865 		if (IsTransactionStmtPlan(plansource))
1866 			continue;
1867 
1868 		/*
1869 		 * Check the dependency list for the rewritten querytree.
1870 		 */
1871 		foreach(lc, plansource->invalItems)
1872 		{
1873 			PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
1874 
1875 			if (item->cacheId != cacheid)
1876 				continue;
1877 			if (hashvalue == 0 ||
1878 				item->hashValue == hashvalue)
1879 			{
1880 				/* Invalidate the querytree and generic plan */
1881 				plansource->is_valid = false;
1882 				if (plansource->gplan)
1883 					plansource->gplan->is_valid = false;
1884 				break;
1885 			}
1886 		}
1887 
1888 		/*
1889 		 * The generic plan, if any, could have more dependencies than the
1890 		 * querytree does, so we have to check it too.
1891 		 */
1892 		if (plansource->gplan && plansource->gplan->is_valid)
1893 		{
1894 			foreach(lc, plansource->gplan->stmt_list)
1895 			{
1896 				PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1897 				ListCell   *lc3;
1898 
1899 				if (plannedstmt->commandType == CMD_UTILITY)
1900 					continue;	/* Ignore utility statements */
1901 				foreach(lc3, plannedstmt->invalItems)
1902 				{
1903 					PlanInvalItem *item = (PlanInvalItem *) lfirst(lc3);
1904 
1905 					if (item->cacheId != cacheid)
1906 						continue;
1907 					if (hashvalue == 0 ||
1908 						item->hashValue == hashvalue)
1909 					{
1910 						/* Invalidate the generic plan only */
1911 						plansource->gplan->is_valid = false;
1912 						break;	/* out of invalItems scan */
1913 					}
1914 				}
1915 				if (!plansource->gplan->is_valid)
1916 					break;		/* out of stmt_list scan */
1917 			}
1918 		}
1919 	}
1920 
1921 	/* Likewise check cached expressions */
1922 	dlist_foreach(iter, &cached_expression_list)
1923 	{
1924 		CachedExpression *cexpr = dlist_container(CachedExpression,
1925 												  node, iter.cur);
1926 		ListCell   *lc;
1927 
1928 		Assert(cexpr->magic == CACHEDEXPR_MAGIC);
1929 
1930 		/* No work if it's already invalidated */
1931 		if (!cexpr->is_valid)
1932 			continue;
1933 
1934 		foreach(lc, cexpr->invalItems)
1935 		{
1936 			PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
1937 
1938 			if (item->cacheId != cacheid)
1939 				continue;
1940 			if (hashvalue == 0 ||
1941 				item->hashValue == hashvalue)
1942 			{
1943 				cexpr->is_valid = false;
1944 				break;
1945 			}
1946 		}
1947 	}
1948 }
1949 
1950 /*
1951  * PlanCacheSysCallback
1952  *		Syscache inval callback function for other caches
1953  *
1954  * Just invalidate everything...
1955  */
1956 static void
1957 PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
1958 {
1959 	ResetPlanCache();
1960 }
1961 
1962 /*
1963  * ResetPlanCache: invalidate all cached plans.
1964  */
1965 void
1966 ResetPlanCache(void)
1967 {
1968 	dlist_iter	iter;
1969 
1970 	dlist_foreach(iter, &saved_plan_list)
1971 	{
1972 		CachedPlanSource *plansource = dlist_container(CachedPlanSource,
1973 													   node, iter.cur);
1974 		ListCell   *lc;
1975 
1976 		Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1977 
1978 		/* No work if it's already invalidated */
1979 		if (!plansource->is_valid)
1980 			continue;
1981 
1982 		/*
1983 		 * We *must not* mark transaction control statements as invalid,
1984 		 * particularly not ROLLBACK, because they may need to be executed in
1985 		 * aborted transactions when we can't revalidate them (cf bug #5269).
1986 		 */
1987 		if (IsTransactionStmtPlan(plansource))
1988 			continue;
1989 
1990 		/*
1991 		 * In general there is no point in invalidating utility statements
1992 		 * since they have no plans anyway.  So invalidate it only if it
1993 		 * contains at least one non-utility statement, or contains a utility
1994 		 * statement that contains a pre-analyzed query (which could have
1995 		 * dependencies.)
1996 		 */
1997 		foreach(lc, plansource->query_list)
1998 		{
1999 			Query	   *query = lfirst_node(Query, lc);
2000 
2001 			if (query->commandType != CMD_UTILITY ||
2002 				UtilityContainsQuery(query->utilityStmt))
2003 			{
2004 				/* non-utility statement, so invalidate */
2005 				plansource->is_valid = false;
2006 				if (plansource->gplan)
2007 					plansource->gplan->is_valid = false;
2008 				/* no need to look further */
2009 				break;
2010 			}
2011 		}
2012 	}
2013 
2014 	/* Likewise invalidate cached expressions */
2015 	dlist_foreach(iter, &cached_expression_list)
2016 	{
2017 		CachedExpression *cexpr = dlist_container(CachedExpression,
2018 												  node, iter.cur);
2019 
2020 		Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2021 
2022 		cexpr->is_valid = false;
2023 	}
2024 }
2025