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