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.
731  *
732  * We assume the parameter types didn't change from the first time, so no
733  * need to update that.
734  */
735  resultDesc = PlanCacheComputeResultDesc(tlist);
736  if (resultDesc == NULL && plansource->resultDesc == NULL)
737  {
738  /* OK, doesn't return tuples */
739  }
740  else if (resultDesc == NULL || plansource->resultDesc == NULL ||
741  !equalRowTypes(resultDesc, plansource->resultDesc))
742  {
743  /* can we give a better error message? */
744  if (plansource->fixed_result)
745  ereport(ERROR,
746  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
747  errmsg("cached plan must not change result type")));
748  oldcxt = MemoryContextSwitchTo(plansource->context);
749  if (resultDesc)
750  resultDesc = CreateTupleDescCopy(resultDesc);
751  if (plansource->resultDesc)
752  FreeTupleDesc(plansource->resultDesc);
753  plansource->resultDesc = resultDesc;
754  MemoryContextSwitchTo(oldcxt);
755  }
756 
757  /*
758  * Allocate new query_context and copy the completed querytree into it.
759  * It's transient until we complete the copying and dependency extraction.
760  */
761  querytree_context = AllocSetContextCreate(CurrentMemoryContext,
762  "CachedPlanQuery",
764  oldcxt = MemoryContextSwitchTo(querytree_context);
765 
766  qlist = copyObject(tlist);
767 
768  /*
769  * Use the planner machinery to extract dependencies. Data is saved in
770  * query_context. (We assume that not a lot of extra cruft is created by
771  * this call.)
772  */
774  &plansource->relationOids,
775  &plansource->invalItems,
776  &plansource->dependsOnRLS);
777 
778  /* Update RLS info as well. */
779  plansource->rewriteRoleId = GetUserId();
780  plansource->rewriteRowSecurity = row_security;
781 
782  /*
783  * Also save the current search_path in the query_context. (This should
784  * not generate much extra cruft either, since almost certainly the path
785  * is already valid.)
786  */
787  plansource->search_path = GetSearchPathMatcher(querytree_context);
788 
789  MemoryContextSwitchTo(oldcxt);
790 
791  /* Now reparent the finished query_context and save the links */
792  MemoryContextSetParent(querytree_context, plansource->context);
793 
794  plansource->query_context = querytree_context;
795  plansource->query_list = qlist;
796 
797  /*
798  * Note: we do not reset generic_cost or total_custom_cost, although we
799  * could choose to do so. If the DDL or statistics change that prompted
800  * the invalidation meant a significant change in the cost estimates, it
801  * would be better to reset those variables and start fresh; but often it
802  * doesn't, and we're better retaining our hard-won knowledge about the
803  * relative costs.
804  */
805 
806  plansource->is_valid = true;
807 
808  /* Return transient copy of querytrees for possible use in planning */
809  return tlist;
810 }
811 
812 /*
813  * CheckCachedPlan: see if the CachedPlanSource's generic plan is valid.
814  *
815  * Caller must have already called RevalidateCachedQuery to verify that the
816  * querytree is up to date.
817  *
818  * On a "true" return, we have acquired the locks needed to run the plan.
819  * (We must do this for the "true" result to be race-condition-free.)
820  */
821 static bool
823 {
824  CachedPlan *plan = plansource->gplan;
825 
826  /* Assert that caller checked the querytree */
827  Assert(plansource->is_valid);
828 
829  /* If there's no generic plan, just say "false" */
830  if (!plan)
831  return false;
832 
833  Assert(plan->magic == CACHEDPLAN_MAGIC);
834  /* Generic plans are never one-shot */
835  Assert(!plan->is_oneshot);
836 
837  /*
838  * If plan isn't valid for current role, we can't use it.
839  */
840  if (plan->is_valid && plan->dependsOnRole &&
841  plan->planRoleId != GetUserId())
842  plan->is_valid = false;
843 
844  /*
845  * If it appears valid, acquire locks and recheck; this is much the same
846  * logic as in RevalidateCachedQuery, but for a plan.
847  */
848  if (plan->is_valid)
849  {
850  /*
851  * Plan must have positive refcount because it is referenced by
852  * plansource; so no need to fear it disappears under us here.
853  */
854  Assert(plan->refcount > 0);
855 
856  AcquireExecutorLocks(plan->stmt_list, true);
857 
858  /*
859  * If plan was transient, check to see if TransactionXmin has
860  * advanced, and if so invalidate it.
861  */
862  if (plan->is_valid &&
863  TransactionIdIsValid(plan->saved_xmin) &&
865  plan->is_valid = false;
866 
867  /*
868  * By now, if any invalidation has happened, the inval callback
869  * functions will have marked the plan invalid.
870  */
871  if (plan->is_valid)
872  {
873  /* Successfully revalidated and locked the query. */
874  return true;
875  }
876 
877  /* Oops, the race case happened. Release useless locks. */
878  AcquireExecutorLocks(plan->stmt_list, false);
879  }
880 
881  /*
882  * Plan has been invalidated, so unlink it from the parent and release it.
883  */
884  ReleaseGenericPlan(plansource);
885 
886  return false;
887 }
888 
889 /*
890  * BuildCachedPlan: construct a new CachedPlan from a CachedPlanSource.
891  *
892  * qlist should be the result value from a previous RevalidateCachedQuery,
893  * or it can be set to NIL if we need to re-copy the plansource's query_list.
894  *
895  * To build a generic, parameter-value-independent plan, pass NULL for
896  * boundParams. To build a custom plan, pass the actual parameter values via
897  * boundParams. For best effect, the PARAM_FLAG_CONST flag should be set on
898  * each parameter value; otherwise the planner will treat the value as a
899  * hint rather than a hard constant.
900  *
901  * Planning work is done in the caller's memory context. The finished plan
902  * is in a child memory context, which typically should get reparented
903  * (unless this is a one-shot plan, in which case we don't copy the plan).
904  */
905 static CachedPlan *
907  ParamListInfo boundParams, QueryEnvironment *queryEnv)
908 {
909  CachedPlan *plan;
910  List *plist;
911  bool snapshot_set;
912  bool is_transient;
913  MemoryContext plan_context;
915  ListCell *lc;
916 
917  /*
918  * Normally the querytree should be valid already, but if it's not,
919  * rebuild it.
920  *
921  * NOTE: GetCachedPlan should have called RevalidateCachedQuery first, so
922  * we ought to be holding sufficient locks to prevent any invalidation.
923  * However, if we're building a custom plan after having built and
924  * rejected a generic plan, it's possible to reach here with is_valid
925  * false due to an invalidation while making the generic plan. In theory
926  * the invalidation must be a false positive, perhaps a consequence of an
927  * sinval reset event or the debug_discard_caches code. But for safety,
928  * let's treat it as real and redo the RevalidateCachedQuery call.
929  */
930  if (!plansource->is_valid)
931  qlist = RevalidateCachedQuery(plansource, queryEnv);
932 
933  /*
934  * If we don't already have a copy of the querytree list that can be
935  * scribbled on by the planner, make one. For a one-shot plan, we assume
936  * it's okay to scribble on the original query_list.
937  */
938  if (qlist == NIL)
939  {
940  if (!plansource->is_oneshot)
941  qlist = copyObject(plansource->query_list);
942  else
943  qlist = plansource->query_list;
944  }
945 
946  /*
947  * If a snapshot is already set (the normal case), we can just use that
948  * for planning. But if it isn't, and we need one, install one.
949  */
950  snapshot_set = false;
951  if (!ActiveSnapshotSet() &&
952  plansource->raw_parse_tree &&
954  {
956  snapshot_set = true;
957  }
958 
959  /*
960  * Generate the plan.
961  */
962  plist = pg_plan_queries(qlist, plansource->query_string,
963  plansource->cursor_options, boundParams);
964 
965  /* Release snapshot if we got one */
966  if (snapshot_set)
968 
969  /*
970  * Normally we make a dedicated memory context for the CachedPlan and its
971  * subsidiary data. (It's probably not going to be large, but just in
972  * case, allow it to grow large. It's transient for the moment.) But for
973  * a one-shot plan, we just leave it in the caller's memory context.
974  */
975  if (!plansource->is_oneshot)
976  {
978  "CachedPlan",
980  MemoryContextCopyAndSetIdentifier(plan_context, plansource->query_string);
981 
982  /*
983  * Copy plan into the new context.
984  */
985  MemoryContextSwitchTo(plan_context);
986 
987  plist = copyObject(plist);
988  }
989  else
990  plan_context = CurrentMemoryContext;
991 
992  /*
993  * Create and fill the CachedPlan struct within the new context.
994  */
995  plan = (CachedPlan *) palloc(sizeof(CachedPlan));
996  plan->magic = CACHEDPLAN_MAGIC;
997  plan->stmt_list = plist;
998 
999  /*
1000  * CachedPlan is dependent on role either if RLS affected the rewrite
1001  * phase or if a role dependency was injected during planning. And it's
1002  * transient if any plan is marked so.
1003  */
1004  plan->planRoleId = GetUserId();
1005  plan->dependsOnRole = plansource->dependsOnRLS;
1006  is_transient = false;
1007  foreach(lc, plist)
1008  {
1009  PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1010 
1011  if (plannedstmt->commandType == CMD_UTILITY)
1012  continue; /* Ignore utility statements */
1013 
1014  if (plannedstmt->transientPlan)
1015  is_transient = true;
1016  if (plannedstmt->dependsOnRole)
1017  plan->dependsOnRole = true;
1018  }
1019  if (is_transient)
1020  {
1022  plan->saved_xmin = TransactionXmin;
1023  }
1024  else
1025  plan->saved_xmin = InvalidTransactionId;
1026  plan->refcount = 0;
1027  plan->context = plan_context;
1028  plan->is_oneshot = plansource->is_oneshot;
1029  plan->is_saved = false;
1030  plan->is_valid = true;
1031 
1032  /* assign generation number to new plan */
1033  plan->generation = ++(plansource->generation);
1034 
1035  MemoryContextSwitchTo(oldcxt);
1036 
1037  return plan;
1038 }
1039 
1040 /*
1041  * choose_custom_plan: choose whether to use custom or generic plan
1042  *
1043  * This defines the policy followed by GetCachedPlan.
1044  */
1045 static bool
1047 {
1048  double avg_custom_cost;
1049 
1050  /* One-shot plans will always be considered custom */
1051  if (plansource->is_oneshot)
1052  return true;
1053 
1054  /* Otherwise, never any point in a custom plan if there's no parameters */
1055  if (boundParams == NULL)
1056  return false;
1057  /* ... nor when planning would be a no-op */
1058  if (!StmtPlanRequiresRevalidation(plansource))
1059  return false;
1060 
1061  /* Let settings force the decision */
1063  return false;
1065  return true;
1066 
1067  /* See if caller wants to force the decision */
1068  if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN)
1069  return false;
1070  if (plansource->cursor_options & CURSOR_OPT_CUSTOM_PLAN)
1071  return true;
1072 
1073  /* Generate custom plans until we have done at least 5 (arbitrary) */
1074  if (plansource->num_custom_plans < 5)
1075  return true;
1076 
1077  avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans;
1078 
1079  /*
1080  * Prefer generic plan if it's less expensive than the average custom
1081  * plan. (Because we include a charge for cost of planning in the
1082  * custom-plan costs, this means the generic plan only has to be less
1083  * expensive than the execution cost plus replan cost of the custom
1084  * plans.)
1085  *
1086  * Note that if generic_cost is -1 (indicating we've not yet determined
1087  * the generic plan cost), we'll always prefer generic at this point.
1088  */
1089  if (plansource->generic_cost < avg_custom_cost)
1090  return false;
1091 
1092  return true;
1093 }
1094 
1095 /*
1096  * cached_plan_cost: calculate estimated cost of a plan
1097  *
1098  * If include_planner is true, also include the estimated cost of constructing
1099  * the plan. (We must factor that into the cost of using a custom plan, but
1100  * we don't count it for a generic plan.)
1101  */
1102 static double
1103 cached_plan_cost(CachedPlan *plan, bool include_planner)
1104 {
1105  double result = 0;
1106  ListCell *lc;
1107 
1108  foreach(lc, plan->stmt_list)
1109  {
1110  PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1111 
1112  if (plannedstmt->commandType == CMD_UTILITY)
1113  continue; /* Ignore utility statements */
1114 
1115  result += plannedstmt->planTree->total_cost;
1116 
1117  if (include_planner)
1118  {
1119  /*
1120  * Currently we use a very crude estimate of planning effort based
1121  * on the number of relations in the finished plan's rangetable.
1122  * Join planning effort actually scales much worse than linearly
1123  * in the number of relations --- but only until the join collapse
1124  * limits kick in. Also, while inheritance child relations surely
1125  * add to planning effort, they don't make the join situation
1126  * worse. So the actual shape of the planning cost curve versus
1127  * number of relations isn't all that obvious. It will take
1128  * considerable work to arrive at a less crude estimate, and for
1129  * now it's not clear that's worth doing.
1130  *
1131  * The other big difficulty here is that we don't have any very
1132  * good model of how planning cost compares to execution costs.
1133  * The current multiplier of 1000 * cpu_operator_cost is probably
1134  * on the low side, but we'll try this for awhile before making a
1135  * more aggressive correction.
1136  *
1137  * If we ever do write a more complicated estimator, it should
1138  * probably live in src/backend/optimizer/ not here.
1139  */
1140  int nrelations = list_length(plannedstmt->rtable);
1141 
1142  result += 1000.0 * cpu_operator_cost * (nrelations + 1);
1143  }
1144  }
1145 
1146  return result;
1147 }
1148 
1149 /*
1150  * GetCachedPlan: get a cached plan from a CachedPlanSource.
1151  *
1152  * This function hides the logic that decides whether to use a generic
1153  * plan or a custom plan for the given parameters: the caller does not know
1154  * which it will get.
1155  *
1156  * On return, the plan is valid and we have sufficient locks to begin
1157  * execution.
1158  *
1159  * On return, the refcount of the plan has been incremented; a later
1160  * ReleaseCachedPlan() call is expected. If "owner" is not NULL then
1161  * the refcount has been reported to that ResourceOwner (note that this
1162  * is only supported for "saved" CachedPlanSources).
1163  *
1164  * Note: if any replanning activity is required, the caller's memory context
1165  * is used for that work.
1166  */
1167 CachedPlan *
1169  ResourceOwner owner, QueryEnvironment *queryEnv)
1170 {
1171  CachedPlan *plan = NULL;
1172  List *qlist;
1173  bool customplan;
1174 
1175  /* Assert caller is doing things in a sane order */
1176  Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1177  Assert(plansource->is_complete);
1178  /* This seems worth a real test, though */
1179  if (owner && !plansource->is_saved)
1180  elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
1181 
1182  /* Make sure the querytree list is valid and we have parse-time locks */
1183  qlist = RevalidateCachedQuery(plansource, queryEnv);
1184 
1185  /* Decide whether to use a custom plan */
1186  customplan = choose_custom_plan(plansource, boundParams);
1187 
1188  if (!customplan)
1189  {
1190  if (CheckCachedPlan(plansource))
1191  {
1192  /* We want a generic plan, and we already have a valid one */
1193  plan = plansource->gplan;
1194  Assert(plan->magic == CACHEDPLAN_MAGIC);
1195  }
1196  else
1197  {
1198  /* Build a new generic plan */
1199  plan = BuildCachedPlan(plansource, qlist, NULL, queryEnv);
1200  /* Just make real sure plansource->gplan is clear */
1201  ReleaseGenericPlan(plansource);
1202  /* Link the new generic plan into the plansource */
1203  plansource->gplan = plan;
1204  plan->refcount++;
1205  /* Immediately reparent into appropriate context */
1206  if (plansource->is_saved)
1207  {
1208  /* saved plans all live under CacheMemoryContext */
1210  plan->is_saved = true;
1211  }
1212  else
1213  {
1214  /* otherwise, it should be a sibling of the plansource */
1215  MemoryContextSetParent(plan->context,
1216  MemoryContextGetParent(plansource->context));
1217  }
1218  /* Update generic_cost whenever we make a new generic plan */
1219  plansource->generic_cost = cached_plan_cost(plan, false);
1220 
1221  /*
1222  * If, based on the now-known value of generic_cost, we'd not have
1223  * chosen to use a generic plan, then forget it and make a custom
1224  * plan. This is a bit of a wart but is necessary to avoid a
1225  * glitch in behavior when the custom plans are consistently big
1226  * winners; at some point we'll experiment with a generic plan and
1227  * find it's a loser, but we don't want to actually execute that
1228  * plan.
1229  */
1230  customplan = choose_custom_plan(plansource, boundParams);
1231 
1232  /*
1233  * If we choose to plan again, we need to re-copy the query_list,
1234  * since the planner probably scribbled on it. We can force
1235  * BuildCachedPlan to do that by passing NIL.
1236  */
1237  qlist = NIL;
1238  }
1239  }
1240 
1241  if (customplan)
1242  {
1243  /* Build a custom plan */
1244  plan = BuildCachedPlan(plansource, qlist, boundParams, queryEnv);
1245  /* Accumulate total costs of custom plans */
1246  plansource->total_custom_cost += cached_plan_cost(plan, true);
1247 
1248  plansource->num_custom_plans++;
1249  }
1250  else
1251  {
1252  plansource->num_generic_plans++;
1253  }
1254 
1255  Assert(plan != NULL);
1256 
1257  /* Flag the plan as in use by caller */
1258  if (owner)
1259  ResourceOwnerEnlarge(owner);
1260  plan->refcount++;
1261  if (owner)
1263 
1264  /*
1265  * Saved plans should be under CacheMemoryContext so they will not go away
1266  * until their reference count goes to zero. In the generic-plan cases we
1267  * already took care of that, but for a custom plan, do it as soon as we
1268  * have created a reference-counted link.
1269  */
1270  if (customplan && plansource->is_saved)
1271  {
1273  plan->is_saved = true;
1274  }
1275 
1276  return plan;
1277 }
1278 
1279 /*
1280  * ReleaseCachedPlan: release active use of a cached plan.
1281  *
1282  * This decrements the reference count, and frees the plan if the count
1283  * has thereby gone to zero. If "owner" is not NULL, it is assumed that
1284  * the reference count is managed by that ResourceOwner.
1285  *
1286  * Note: owner == NULL is used for releasing references that are in
1287  * persistent data structures, such as the parent CachedPlanSource or a
1288  * Portal. Transient references should be protected by a resource owner.
1289  */
1290 void
1292 {
1293  Assert(plan->magic == CACHEDPLAN_MAGIC);
1294  if (owner)
1295  {
1296  Assert(plan->is_saved);
1298  }
1299  Assert(plan->refcount > 0);
1300  plan->refcount--;
1301  if (plan->refcount == 0)
1302  {
1303  /* Mark it no longer valid */
1304  plan->magic = 0;
1305 
1306  /* One-shot plans do not own their context, so we can't free them */
1307  if (!plan->is_oneshot)
1308  MemoryContextDelete(plan->context);
1309  }
1310 }
1311 
1312 /*
1313  * CachedPlanAllowsSimpleValidityCheck: can we use CachedPlanIsSimplyValid?
1314  *
1315  * This function, together with CachedPlanIsSimplyValid, provides a fast path
1316  * for revalidating "simple" generic plans. The core requirement to be simple
1317  * is that the plan must not require taking any locks, which translates to
1318  * not touching any tables; this happens to match up well with an important
1319  * use-case in PL/pgSQL. This function tests whether that's true, along
1320  * with checking some other corner cases that we'd rather not bother with
1321  * handling in the fast path. (Note that it's still possible for such a plan
1322  * to be invalidated, for example due to a change in a function that was
1323  * inlined into the plan.)
1324  *
1325  * If the plan is simply valid, and "owner" is not NULL, record a refcount on
1326  * the plan in that resowner before returning. It is caller's responsibility
1327  * to be sure that a refcount is held on any plan that's being actively used.
1328  *
1329  * This must only be called on known-valid generic plans (eg, ones just
1330  * returned by GetCachedPlan). If it returns true, the caller may re-use
1331  * the cached plan as long as CachedPlanIsSimplyValid returns true; that
1332  * check is much cheaper than the full revalidation done by GetCachedPlan.
1333  * Nonetheless, no required checks are omitted.
1334  */
1335 bool
1337  CachedPlan *plan, ResourceOwner owner)
1338 {
1339  ListCell *lc;
1340 
1341  /*
1342  * Sanity-check that the caller gave us a validated generic plan. Notice
1343  * that we *don't* assert plansource->is_valid as you might expect; that's
1344  * because it's possible that that's already false when GetCachedPlan
1345  * returns, e.g. because ResetPlanCache happened partway through. We
1346  * should accept the plan as long as plan->is_valid is true, and expect to
1347  * replan after the next CachedPlanIsSimplyValid call.
1348  */
1349  Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1350  Assert(plan->magic == CACHEDPLAN_MAGIC);
1351  Assert(plan->is_valid);
1352  Assert(plan == plansource->gplan);
1353  Assert(plansource->search_path != NULL);
1355 
1356  /* We don't support oneshot plans here. */
1357  if (plansource->is_oneshot)
1358  return false;
1359  Assert(!plan->is_oneshot);
1360 
1361  /*
1362  * If the plan is dependent on RLS considerations, or it's transient,
1363  * reject. These things probably can't ever happen for table-free
1364  * queries, but for safety's sake let's check.
1365  */
1366  if (plansource->dependsOnRLS)
1367  return false;
1368  if (plan->dependsOnRole)
1369  return false;
1370  if (TransactionIdIsValid(plan->saved_xmin))
1371  return false;
1372 
1373  /*
1374  * Reject if AcquirePlannerLocks would have anything to do. This is
1375  * simplistic, but there's no need to inquire any more carefully; indeed,
1376  * for current callers it shouldn't even be possible to hit any of these
1377  * checks.
1378  */
1379  foreach(lc, plansource->query_list)
1380  {
1381  Query *query = lfirst_node(Query, lc);
1382 
1383  if (query->commandType == CMD_UTILITY)
1384  return false;
1385  if (query->rtable || query->cteList || query->hasSubLinks)
1386  return false;
1387  }
1388 
1389  /*
1390  * Reject if AcquireExecutorLocks would have anything to do. This is
1391  * probably unnecessary given the previous check, but let's be safe.
1392  */
1393  foreach(lc, plan->stmt_list)
1394  {
1395  PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1396  ListCell *lc2;
1397 
1398  if (plannedstmt->commandType == CMD_UTILITY)
1399  return false;
1400 
1401  /*
1402  * We have to grovel through the rtable because it's likely to contain
1403  * an RTE_RESULT relation, rather than being totally empty.
1404  */
1405  foreach(lc2, plannedstmt->rtable)
1406  {
1407  RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
1408 
1409  if (rte->rtekind == RTE_RELATION)
1410  return false;
1411  }
1412  }
1413 
1414  /*
1415  * Okay, it's simple. Note that what we've primarily established here is
1416  * that no locks need be taken before checking the plan's is_valid flag.
1417  */
1418 
1419  /* Bump refcount if requested. */
1420  if (owner)
1421  {
1422  ResourceOwnerEnlarge(owner);
1423  plan->refcount++;
1425  }
1426 
1427  return true;
1428 }
1429 
1430 /*
1431  * CachedPlanIsSimplyValid: quick check for plan still being valid
1432  *
1433  * This function must not be used unless CachedPlanAllowsSimpleValidityCheck
1434  * previously said it was OK.
1435  *
1436  * If the plan is valid, and "owner" is not NULL, record a refcount on
1437  * the plan in that resowner before returning. It is caller's responsibility
1438  * to be sure that a refcount is held on any plan that's being actively used.
1439  *
1440  * The code here is unconditionally safe as long as the only use of this
1441  * CachedPlanSource is in connection with the particular CachedPlan pointer
1442  * that's passed in. If the plansource were being used for other purposes,
1443  * it's possible that its generic plan could be invalidated and regenerated
1444  * while the current caller wasn't looking, and then there could be a chance
1445  * collision of address between this caller's now-stale plan pointer and the
1446  * actual address of the new generic plan. For current uses, that scenario
1447  * can't happen; but with a plansource shared across multiple uses, it'd be
1448  * advisable to also save plan->generation and verify that that still matches.
1449  */
1450 bool
1452  ResourceOwner owner)
1453 {
1454  /*
1455  * Careful here: since the caller doesn't necessarily hold a refcount on
1456  * the plan to start with, it's possible that "plan" is a dangling
1457  * pointer. Don't dereference it until we've verified that it still
1458  * matches the plansource's gplan (which is either valid or NULL).
1459  */
1460  Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1461 
1462  /*
1463  * Has cache invalidation fired on this plan? We can check this right
1464  * away since there are no locks that we'd need to acquire first. Note
1465  * that here we *do* check plansource->is_valid, so as to force plan
1466  * rebuild if that's become false.
1467  */
1468  if (!plansource->is_valid ||
1469  plan == NULL || plan != plansource->gplan ||
1470  !plan->is_valid)
1471  return false;
1472 
1473  Assert(plan->magic == CACHEDPLAN_MAGIC);
1474 
1475  /* Is the search_path still the same as when we made it? */
1476  Assert(plansource->search_path != NULL);
1478  return false;
1479 
1480  /* It's still good. Bump refcount if requested. */
1481  if (owner)
1482  {
1483  ResourceOwnerEnlarge(owner);
1484  plan->refcount++;
1486  }
1487 
1488  return true;
1489 }
1490 
1491 /*
1492  * CachedPlanSetParentContext: move a CachedPlanSource to a new memory context
1493  *
1494  * This can only be applied to unsaved plans; once saved, a plan always
1495  * lives underneath CacheMemoryContext.
1496  */
1497 void
1499  MemoryContext newcontext)
1500 {
1501  /* Assert caller is doing things in a sane order */
1502  Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1503  Assert(plansource->is_complete);
1504 
1505  /* These seem worth real tests, though */
1506  if (plansource->is_saved)
1507  elog(ERROR, "cannot move a saved cached plan to another context");
1508  if (plansource->is_oneshot)
1509  elog(ERROR, "cannot move a one-shot cached plan to another context");
1510 
1511  /* OK, let the caller keep the plan where he wishes */
1512  MemoryContextSetParent(plansource->context, newcontext);
1513 
1514  /*
1515  * The query_context needs no special handling, since it's a child of
1516  * plansource->context. But if there's a generic plan, it should be
1517  * maintained as a sibling of plansource->context.
1518  */
1519  if (plansource->gplan)
1520  {
1521  Assert(plansource->gplan->magic == CACHEDPLAN_MAGIC);
1522  MemoryContextSetParent(plansource->gplan->context, newcontext);
1523  }
1524 }
1525 
1526 /*
1527  * CopyCachedPlan: make a copy of a CachedPlanSource
1528  *
1529  * This is a convenience routine that does the equivalent of
1530  * CreateCachedPlan + CompleteCachedPlan, using the data stored in the
1531  * input CachedPlanSource. The result is therefore "unsaved" (regardless
1532  * of the state of the source), and we don't copy any generic plan either.
1533  * The result will be currently valid, or not, the same as the source.
1534  */
1537 {
1538  CachedPlanSource *newsource;
1539  MemoryContext source_context;
1540  MemoryContext querytree_context;
1541  MemoryContext oldcxt;
1542 
1543  Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1544  Assert(plansource->is_complete);
1545 
1546  /*
1547  * One-shot plans can't be copied, because we haven't taken care that
1548  * parsing/planning didn't scribble on the raw parse tree or querytrees.
1549  */
1550  if (plansource->is_oneshot)
1551  elog(ERROR, "cannot copy a one-shot cached plan");
1552 
1554  "CachedPlanSource",
1556 
1557  oldcxt = MemoryContextSwitchTo(source_context);
1558 
1559  newsource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
1560  newsource->magic = CACHEDPLANSOURCE_MAGIC;
1561  newsource->raw_parse_tree = copyObject(plansource->raw_parse_tree);
1562  newsource->query_string = pstrdup(plansource->query_string);
1563  MemoryContextSetIdentifier(source_context, newsource->query_string);
1564  newsource->commandTag = plansource->commandTag;
1565  if (plansource->num_params > 0)
1566  {
1567  newsource->param_types = (Oid *)
1568  palloc(plansource->num_params * sizeof(Oid));
1569  memcpy(newsource->param_types, plansource->param_types,
1570  plansource->num_params * sizeof(Oid));
1571  }
1572  else
1573  newsource->param_types = NULL;
1574  newsource->num_params = plansource->num_params;
1575  newsource->parserSetup = plansource->parserSetup;
1576  newsource->parserSetupArg = plansource->parserSetupArg;
1577  newsource->cursor_options = plansource->cursor_options;
1578  newsource->fixed_result = plansource->fixed_result;
1579  if (plansource->resultDesc)
1580  newsource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
1581  else
1582  newsource->resultDesc = NULL;
1583  newsource->context = source_context;
1584 
1585  querytree_context = AllocSetContextCreate(source_context,
1586  "CachedPlanQuery",
1588  MemoryContextSwitchTo(querytree_context);
1589  newsource->query_list = copyObject(plansource->query_list);
1590  newsource->relationOids = copyObject(plansource->relationOids);
1591  newsource->invalItems = copyObject(plansource->invalItems);
1592  if (plansource->search_path)
1593  newsource->search_path = CopySearchPathMatcher(plansource->search_path);
1594  newsource->query_context = querytree_context;
1595  newsource->rewriteRoleId = plansource->rewriteRoleId;
1596  newsource->rewriteRowSecurity = plansource->rewriteRowSecurity;
1597  newsource->dependsOnRLS = plansource->dependsOnRLS;
1598 
1599  newsource->gplan = NULL;
1600 
1601  newsource->is_oneshot = false;
1602  newsource->is_complete = true;
1603  newsource->is_saved = false;
1604  newsource->is_valid = plansource->is_valid;
1605  newsource->generation = plansource->generation;
1606 
1607  /* We may as well copy any acquired cost knowledge */
1608  newsource->generic_cost = plansource->generic_cost;
1609  newsource->total_custom_cost = plansource->total_custom_cost;
1610  newsource->num_generic_plans = plansource->num_generic_plans;
1611  newsource->num_custom_plans = plansource->num_custom_plans;
1612 
1613  MemoryContextSwitchTo(oldcxt);
1614 
1615  return newsource;
1616 }
1617 
1618 /*
1619  * CachedPlanIsValid: test whether the rewritten querytree within a
1620  * CachedPlanSource is currently valid (that is, not marked as being in need
1621  * of revalidation).
1622  *
1623  * This result is only trustworthy (ie, free from race conditions) if
1624  * the caller has acquired locks on all the relations used in the plan.
1625  */
1626 bool
1628 {
1629  Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1630  return plansource->is_valid;
1631 }
1632 
1633 /*
1634  * CachedPlanGetTargetList: return tlist, if any, describing plan's output
1635  *
1636  * The result is guaranteed up-to-date. However, it is local storage
1637  * within the cached plan, and may disappear next time the plan is updated.
1638  */
1639 List *
1641  QueryEnvironment *queryEnv)
1642 {
1643  Query *pstmt;
1644 
1645  /* Assert caller is doing things in a sane order */
1646  Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1647  Assert(plansource->is_complete);
1648 
1649  /*
1650  * No work needed if statement doesn't return tuples (we assume this
1651  * feature cannot be changed by an invalidation)
1652  */
1653  if (plansource->resultDesc == NULL)
1654  return NIL;
1655 
1656  /* Make sure the querytree list is valid and we have parse-time locks */
1657  RevalidateCachedQuery(plansource, queryEnv);
1658 
1659  /* Get the primary statement and find out what it returns */
1660  pstmt = QueryListGetPrimaryStmt(plansource->query_list);
1661 
1662  return FetchStatementTargetList((Node *) pstmt);
1663 }
1664 
1665 /*
1666  * GetCachedExpression: construct a CachedExpression for an expression.
1667  *
1668  * This performs the same transformations on the expression as
1669  * expression_planner(), ie, convert an expression as emitted by parse
1670  * analysis to be ready to pass to the executor.
1671  *
1672  * The result is stashed in a private, long-lived memory context.
1673  * (Note that this might leak a good deal of memory in the caller's
1674  * context before that.) The passed-in expr tree is not modified.
1675  */
1678 {
1679  CachedExpression *cexpr;
1680  List *relationOids;
1681  List *invalItems;
1682  MemoryContext cexpr_context;
1683  MemoryContext oldcxt;
1684 
1685  /*
1686  * Pass the expression through the planner, and collect dependencies.
1687  * Everything built here is leaked in the caller's context; that's
1688  * intentional to minimize the size of the permanent data structure.
1689  */
1690  expr = (Node *) expression_planner_with_deps((Expr *) expr,
1691  &relationOids,
1692  &invalItems);
1693 
1694  /*
1695  * Make a private memory context, and copy what we need into that. To
1696  * avoid leaking a long-lived context if we fail while copying data, we
1697  * initially make the context under the caller's context.
1698  */
1700  "CachedExpression",
1702 
1703  oldcxt = MemoryContextSwitchTo(cexpr_context);
1704 
1705  cexpr = (CachedExpression *) palloc(sizeof(CachedExpression));
1706  cexpr->magic = CACHEDEXPR_MAGIC;
1707  cexpr->expr = copyObject(expr);
1708  cexpr->is_valid = true;
1709  cexpr->relationOids = copyObject(relationOids);
1710  cexpr->invalItems = copyObject(invalItems);
1711  cexpr->context = cexpr_context;
1712 
1713  MemoryContextSwitchTo(oldcxt);
1714 
1715  /*
1716  * Reparent the expr's memory context under CacheMemoryContext so that it
1717  * will live indefinitely.
1718  */
1720 
1721  /*
1722  * Add the entry to the global list of cached expressions.
1723  */
1725 
1726  return cexpr;
1727 }
1728 
1729 /*
1730  * FreeCachedExpression
1731  * Delete a CachedExpression.
1732  */
1733 void
1735 {
1736  /* Sanity check */
1737  Assert(cexpr->magic == CACHEDEXPR_MAGIC);
1738  /* Unlink from global list */
1739  dlist_delete(&cexpr->node);
1740  /* Free all storage associated with CachedExpression */
1741  MemoryContextDelete(cexpr->context);
1742 }
1743 
1744 /*
1745  * QueryListGetPrimaryStmt
1746  * Get the "primary" stmt within a list, ie, the one marked canSetTag.
1747  *
1748  * Returns NULL if no such stmt. If multiple queries within the list are
1749  * marked canSetTag, returns the first one. Neither of these cases should
1750  * occur in present usages of this function.
1751  */
1752 static Query *
1754 {
1755  ListCell *lc;
1756 
1757  foreach(lc, stmts)
1758  {
1759  Query *stmt = lfirst_node(Query, lc);
1760 
1761  if (stmt->canSetTag)
1762  return stmt;
1763  }
1764  return NULL;
1765 }
1766 
1767 /*
1768  * AcquireExecutorLocks: acquire locks needed for execution of a cached plan;
1769  * or release them if acquire is false.
1770  */
1771 static void
1772 AcquireExecutorLocks(List *stmt_list, bool acquire)
1773 {
1774  ListCell *lc1;
1775 
1776  foreach(lc1, stmt_list)
1777  {
1778  PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc1);
1779  ListCell *lc2;
1780 
1781  if (plannedstmt->commandType == CMD_UTILITY)
1782  {
1783  /*
1784  * Ignore utility statements, except those (such as EXPLAIN) that
1785  * contain a parsed-but-not-planned query. Note: it's okay to use
1786  * ScanQueryForLocks, even though the query hasn't been through
1787  * rule rewriting, because rewriting doesn't change the query
1788  * representation.
1789  */
1790  Query *query = UtilityContainsQuery(plannedstmt->utilityStmt);
1791 
1792  if (query)
1793  ScanQueryForLocks(query, acquire);
1794  continue;
1795  }
1796 
1797  foreach(lc2, plannedstmt->rtable)
1798  {
1799  RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
1800 
1801  if (!(rte->rtekind == RTE_RELATION ||
1802  (rte->rtekind == RTE_SUBQUERY && OidIsValid(rte->relid))))
1803  continue;
1804 
1805  /*
1806  * Acquire the appropriate type of lock on each relation OID. Note
1807  * that we don't actually try to open the rel, and hence will not
1808  * fail if it's been dropped entirely --- we'll just transiently
1809  * acquire a non-conflicting lock.
1810  */
1811  if (acquire)
1812  LockRelationOid(rte->relid, rte->rellockmode);
1813  else
1814  UnlockRelationOid(rte->relid, rte->rellockmode);
1815  }
1816  }
1817 }
1818 
1819 /*
1820  * AcquirePlannerLocks: acquire locks needed for planning of a querytree list;
1821  * or release them if acquire is false.
1822  *
1823  * Note that we don't actually try to open the relations, and hence will not
1824  * fail if one has been dropped entirely --- we'll just transiently acquire
1825  * a non-conflicting lock.
1826  */
1827 static void
1828 AcquirePlannerLocks(List *stmt_list, bool acquire)
1829 {
1830  ListCell *lc;
1831 
1832  foreach(lc, stmt_list)
1833  {
1834  Query *query = lfirst_node(Query, lc);
1835 
1836  if (query->commandType == CMD_UTILITY)
1837  {
1838  /* Ignore utility statements, unless they contain a Query */
1839  query = UtilityContainsQuery(query->utilityStmt);
1840  if (query)
1841  ScanQueryForLocks(query, acquire);
1842  continue;
1843  }
1844 
1845  ScanQueryForLocks(query, acquire);
1846  }
1847 }
1848 
1849 /*
1850  * ScanQueryForLocks: recursively scan one Query for AcquirePlannerLocks.
1851  */
1852 static void
1853 ScanQueryForLocks(Query *parsetree, bool acquire)
1854 {
1855  ListCell *lc;
1856 
1857  /* Shouldn't get called on utility commands */
1858  Assert(parsetree->commandType != CMD_UTILITY);
1859 
1860  /*
1861  * First, process RTEs of the current query level.
1862  */
1863  foreach(lc, parsetree->rtable)
1864  {
1865  RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
1866 
1867  switch (rte->rtekind)
1868  {
1869  case RTE_RELATION:
1870  /* Acquire or release the appropriate type of lock */
1871  if (acquire)
1872  LockRelationOid(rte->relid, rte->rellockmode);
1873  else
1874  UnlockRelationOid(rte->relid, rte->rellockmode);
1875  break;
1876 
1877  case RTE_SUBQUERY:
1878  /* If this was a view, must lock/unlock the view */
1879  if (OidIsValid(rte->relid))
1880  {
1881  if (acquire)
1882  LockRelationOid(rte->relid, rte->rellockmode);
1883  else
1884  UnlockRelationOid(rte->relid, rte->rellockmode);
1885  }
1886  /* Recurse into subquery-in-FROM */
1887  ScanQueryForLocks(rte->subquery, acquire);
1888  break;
1889 
1890  default:
1891  /* ignore other types of RTEs */
1892  break;
1893  }
1894  }
1895 
1896  /* Recurse into subquery-in-WITH */
1897  foreach(lc, parsetree->cteList)
1898  {
1900 
1901  ScanQueryForLocks(castNode(Query, cte->ctequery), acquire);
1902  }
1903 
1904  /*
1905  * Recurse into sublink subqueries, too. But we already did the ones in
1906  * the rtable and cteList.
1907  */
1908  if (parsetree->hasSubLinks)
1909  {
1911  (void *) &acquire,
1913  }
1914 }
1915 
1916 /*
1917  * Walker to find sublink subqueries for ScanQueryForLocks
1918  */
1919 static bool
1920 ScanQueryWalker(Node *node, bool *acquire)
1921 {
1922  if (node == NULL)
1923  return false;
1924  if (IsA(node, SubLink))
1925  {
1926  SubLink *sub = (SubLink *) node;
1927 
1928  /* Do what we came for */
1929  ScanQueryForLocks(castNode(Query, sub->subselect), *acquire);
1930  /* Fall through to process lefthand args of SubLink */
1931  }
1932 
1933  /*
1934  * Do NOT recurse into Query nodes, because ScanQueryForLocks already
1935  * processed subselects of subselects for us.
1936  */
1938  (void *) acquire);
1939 }
1940 
1941 /*
1942  * PlanCacheComputeResultDesc: given a list of analyzed-and-rewritten Queries,
1943  * determine the result tupledesc it will produce. Returns NULL if the
1944  * execution will not return tuples.
1945  *
1946  * Note: the result is created or copied into current memory context.
1947  */
1948 static TupleDesc
1950 {
1951  Query *query;
1952 
1953  switch (ChoosePortalStrategy(stmt_list))
1954  {
1955  case PORTAL_ONE_SELECT:
1956  case PORTAL_ONE_MOD_WITH:
1957  query = linitial_node(Query, stmt_list);
1958  return ExecCleanTypeFromTL(query->targetList);
1959 
1960  case PORTAL_ONE_RETURNING:
1961  query = QueryListGetPrimaryStmt(stmt_list);
1962  Assert(query->returningList);
1963  return ExecCleanTypeFromTL(query->returningList);
1964 
1965  case PORTAL_UTIL_SELECT:
1966  query = linitial_node(Query, stmt_list);
1967  Assert(query->utilityStmt);
1968  return UtilityTupleDescriptor(query->utilityStmt);
1969 
1970  case PORTAL_MULTI_QUERY:
1971  /* will not return tuples */
1972  break;
1973  }
1974  return NULL;
1975 }
1976 
1977 /*
1978  * PlanCacheRelCallback
1979  * Relcache inval callback function
1980  *
1981  * Invalidate all plans mentioning the given rel, or all plans mentioning
1982  * any rel at all if relid == InvalidOid.
1983  */
1984 static void
1986 {
1987  dlist_iter iter;
1988 
1990  {
1992  node, iter.cur);
1993 
1994  Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1995 
1996  /* No work if it's already invalidated */
1997  if (!plansource->is_valid)
1998  continue;
1999 
2000  /* Never invalidate if parse/plan would be a no-op anyway */
2001  if (!StmtPlanRequiresRevalidation(plansource))
2002  continue;
2003 
2004  /*
2005  * Check the dependency list for the rewritten querytree.
2006  */
2007  if ((relid == InvalidOid) ? plansource->relationOids != NIL :
2008  list_member_oid(plansource->relationOids, relid))
2009  {
2010  /* Invalidate the querytree and generic plan */
2011  plansource->is_valid = false;
2012  if (plansource->gplan)
2013  plansource->gplan->is_valid = false;
2014  }
2015 
2016  /*
2017  * The generic plan, if any, could have more dependencies than the
2018  * querytree does, so we have to check it too.
2019  */
2020  if (plansource->gplan && plansource->gplan->is_valid)
2021  {
2022  ListCell *lc;
2023 
2024  foreach(lc, plansource->gplan->stmt_list)
2025  {
2026  PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
2027 
2028  if (plannedstmt->commandType == CMD_UTILITY)
2029  continue; /* Ignore utility statements */
2030  if ((relid == InvalidOid) ? plannedstmt->relationOids != NIL :
2031  list_member_oid(plannedstmt->relationOids, relid))
2032  {
2033  /* Invalidate the generic plan only */
2034  plansource->gplan->is_valid = false;
2035  break; /* out of stmt_list scan */
2036  }
2037  }
2038  }
2039  }
2040 
2041  /* Likewise check cached expressions */
2043  {
2045  node, iter.cur);
2046 
2047  Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2048 
2049  /* No work if it's already invalidated */
2050  if (!cexpr->is_valid)
2051  continue;
2052 
2053  if ((relid == InvalidOid) ? cexpr->relationOids != NIL :
2054  list_member_oid(cexpr->relationOids, relid))
2055  {
2056  cexpr->is_valid = false;
2057  }
2058  }
2059 }
2060 
2061 /*
2062  * PlanCacheObjectCallback
2063  * Syscache inval callback function for PROCOID and TYPEOID caches
2064  *
2065  * Invalidate all plans mentioning the object with the specified hash value,
2066  * or all plans mentioning any member of this cache if hashvalue == 0.
2067  */
2068 static void
2069 PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue)
2070 {
2071  dlist_iter iter;
2072 
2074  {
2076  node, iter.cur);
2077  ListCell *lc;
2078 
2079  Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
2080 
2081  /* No work if it's already invalidated */
2082  if (!plansource->is_valid)
2083  continue;
2084 
2085  /* Never invalidate if parse/plan would be a no-op anyway */
2086  if (!StmtPlanRequiresRevalidation(plansource))
2087  continue;
2088 
2089  /*
2090  * Check the dependency list for the rewritten querytree.
2091  */
2092  foreach(lc, plansource->invalItems)
2093  {
2094  PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
2095 
2096  if (item->cacheId != cacheid)
2097  continue;
2098  if (hashvalue == 0 ||
2099  item->hashValue == hashvalue)
2100  {
2101  /* Invalidate the querytree and generic plan */
2102  plansource->is_valid = false;
2103  if (plansource->gplan)
2104  plansource->gplan->is_valid = false;
2105  break;
2106  }
2107  }
2108 
2109  /*
2110  * The generic plan, if any, could have more dependencies than the
2111  * querytree does, so we have to check it too.
2112  */
2113  if (plansource->gplan && plansource->gplan->is_valid)
2114  {
2115  foreach(lc, plansource->gplan->stmt_list)
2116  {
2117  PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
2118  ListCell *lc3;
2119 
2120  if (plannedstmt->commandType == CMD_UTILITY)
2121  continue; /* Ignore utility statements */
2122  foreach(lc3, plannedstmt->invalItems)
2123  {
2124  PlanInvalItem *item = (PlanInvalItem *) lfirst(lc3);
2125 
2126  if (item->cacheId != cacheid)
2127  continue;
2128  if (hashvalue == 0 ||
2129  item->hashValue == hashvalue)
2130  {
2131  /* Invalidate the generic plan only */
2132  plansource->gplan->is_valid = false;
2133  break; /* out of invalItems scan */
2134  }
2135  }
2136  if (!plansource->gplan->is_valid)
2137  break; /* out of stmt_list scan */
2138  }
2139  }
2140  }
2141 
2142  /* Likewise check cached expressions */
2144  {
2146  node, iter.cur);
2147  ListCell *lc;
2148 
2149  Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2150 
2151  /* No work if it's already invalidated */
2152  if (!cexpr->is_valid)
2153  continue;
2154 
2155  foreach(lc, cexpr->invalItems)
2156  {
2157  PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
2158 
2159  if (item->cacheId != cacheid)
2160  continue;
2161  if (hashvalue == 0 ||
2162  item->hashValue == hashvalue)
2163  {
2164  cexpr->is_valid = false;
2165  break;
2166  }
2167  }
2168  }
2169 }
2170 
2171 /*
2172  * PlanCacheSysCallback
2173  * Syscache inval callback function for other caches
2174  *
2175  * Just invalidate everything...
2176  */
2177 static void
2178 PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
2179 {
2180  ResetPlanCache();
2181 }
2182 
2183 /*
2184  * ResetPlanCache: invalidate all cached plans.
2185  */
2186 void
2188 {
2189  dlist_iter iter;
2190 
2192  {
2194  node, iter.cur);
2195 
2196  Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
2197 
2198  /* No work if it's already invalidated */
2199  if (!plansource->is_valid)
2200  continue;
2201 
2202  /*
2203  * We *must not* mark transaction control statements as invalid,
2204  * particularly not ROLLBACK, because they may need to be executed in
2205  * aborted transactions when we can't revalidate them (cf bug #5269).
2206  * In general there's no point in invalidating statements for which a
2207  * new parse analysis/rewrite/plan cycle would certainly give the same
2208  * results.
2209  */
2210  if (!StmtPlanRequiresRevalidation(plansource))
2211  continue;
2212 
2213  plansource->is_valid = false;
2214  if (plansource->gplan)
2215  plansource->gplan->is_valid = false;
2216  }
2217 
2218  /* Likewise invalidate cached expressions */
2220  {
2222  node, iter.cur);
2223 
2224  Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2225 
2226  cexpr->is_valid = false;
2227  }
2228 }
2229 
2230 /*
2231  * Release all CachedPlans remembered by 'owner'
2232  */
2233 void
2235 {
2237 }
2238 
2239 /* ResourceOwner callbacks */
2240 
2241 static void
2243 {
2245 }
unsigned int uint32
Definition: c.h:506
#define Assert(condition)
Definition: c.h:858
#define OidIsValid(objectId)
Definition: c.h:775
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:2037
bool row_security
Definition: guc_tables.c:513
#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
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:637
char * pstrdup(const char *in)
Definition: mcxt.c:1695
void * palloc0(Size size)
Definition: mcxt.c:1346
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
MemoryContext MemoryContextGetParent(MemoryContext context)
Definition: mcxt.c:731
MemoryContext CacheMemoryContext
Definition: mcxt.c:152
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
void * palloc(Size size)
Definition: mcxt.c:1316
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
Definition: mcxt.c:612
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_START_SMALL_SIZES
Definition: memutils.h:177
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:170
#define MemoryContextCopyAndSetIdentifier(cxt, id)
Definition: memutils.h:101
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:224
@ CMD_UTILITY
Definition: nodes.h:270
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
void(* ParserSetupHook)(struct ParseState *pstate, void *arg)
Definition: params.h:108
@ RTE_SUBQUERY
Definition: parsenodes.h:1029
@ RTE_RELATION
Definition: parsenodes.h:1028
#define CURSOR_OPT_GENERIC_PLAN
Definition: parsenodes.h:3300
#define CURSOR_OPT_CUSTOM_PLAN
Definition: parsenodes.h:3301
bool analyze_requires_snapshot(RawStmt *parseTree)
Definition: analyze.c:485
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:1498
bool CachedPlanIsValid(CachedPlanSource *plansource)
Definition: plancache.c:1627
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:1046
List * CachedPlanGetTargetList(CachedPlanSource *plansource, QueryEnvironment *queryEnv)
Definition: plancache.c:1640
bool CachedPlanAllowsSimpleValidityCheck(CachedPlanSource *plansource, CachedPlan *plan, ResourceOwner owner)
Definition: plancache.c:1336
static void ReleaseGenericPlan(CachedPlanSource *plansource)
Definition: plancache.c:555
static CachedPlan * BuildCachedPlan(CachedPlanSource *plansource, List *qlist, ParamListInfo boundParams, QueryEnvironment *queryEnv)
Definition: plancache.c:906
static bool CheckCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:822
int plan_cache_mode
Definition: plancache.c:147
void FreeCachedExpression(CachedExpression *cexpr)
Definition: plancache.c:1734
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:1451
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)
Definition: plancache.c:1168
static bool ScanQueryWalker(Node *node, bool *acquire)
Definition: plancache.c:1920
static const ResourceOwnerDesc planref_resowner_desc
Definition: plancache.c:124
static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: plancache.c:2178
static List * RevalidateCachedQuery(CachedPlanSource *plansource, QueryEnvironment *queryEnv)
Definition: plancache.c:583
CachedExpression * GetCachedExpression(Node *expr)
Definition: plancache.c:1677
static void PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: plancache.c:2069
void ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner)
Definition: plancache.c:1291
static TupleDesc PlanCacheComputeResultDesc(List *stmt_list)
Definition: plancache.c:1949
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:1828
static void ResourceOwnerForgetPlanCacheRef(ResourceOwner owner, CachedPlan *plan)
Definition: plancache.c:140
static double cached_plan_cost(CachedPlan *plan, bool include_planner)
Definition: plancache.c:1103
static void ResOwnerReleaseCachedPlan(Datum res)
Definition: plancache.c:2242
static void ScanQueryForLocks(Query *parsetree, bool acquire)
Definition: plancache.c:1853
void ReleaseAllPlanCacheRefsInOwner(ResourceOwner owner)
Definition: plancache.c:2234
void ResetPlanCache(void)
Definition: plancache.c:2187
CachedPlanSource * CreateOneShotCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)
Definition: plancache.c:276
CachedPlanSource * CopyCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:1536
static void PlanCacheRelCallback(Datum arg, Oid relid)
Definition: plancache.c:1985
static Query * QueryListGetPrimaryStmt(List *stmts)
Definition: plancache.c:1753
#define StmtPlanRequiresRevalidation(plansource)
Definition: plancache.c:85
static void AcquireExecutorLocks(List *stmt_list, bool acquire)
Definition: plancache.c:1772
#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:6484
@ 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:764
List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
Definition: postgres.c:671
List * pg_plan_queries(List *querytrees, const char *query_string, int cursorOptions, ParamListInfo boundParams)
Definition: postgres.c:972
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
MemoryContextSwitchTo(old_ctx)
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:3541
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:1573
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:198
List * cteList
Definition: parsenodes.h:166
List * rtable
Definition: parsenodes.h:168
CmdType commandType
Definition: parsenodes.h:121
Node * utilityStmt
Definition: parsenodes.h:136
List * targetList
Definition: parsenodes.h:191
Query * subquery
Definition: parsenodes.h:1114
RTEKind rtekind
Definition: parsenodes.h:1057
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 equalRowTypes(TupleDesc tupdesc1, TupleDesc tupdesc2)
Definition: tupdesc.c:586
Query * UtilityContainsQuery(Node *parsetree)
Definition: utility.c:2176
TupleDesc UtilityTupleDescriptor(Node *parsetree)
Definition: utility.c:2081