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