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