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