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