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