1 /*-------------------------------------------------------------------------
4 * Plan cache management.
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.
11 * The logic for choosing generic or custom plans is in choose_custom_plan,
12 * which see for comments.
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.
20 * Note that if the sinval was a result of user DDL actions, parse analysis
21 * could throw an error, for example if a column referenced by the query is
22 * no longer present. The creator of a cached plan can specify whether it
23 * is allowable for the query to change output tupdesc on replan (this
24 * could happen with "SELECT *" for example) --- if so, it's up to the
25 * caller to notice changes and cope with them.
27 * Currently, we track exactly the dependencies of plans on relations and
28 * user-defined functions. On relcache invalidation events or pg_proc
29 * syscache invalidation events, we invalidate just those plans that depend
30 * on the particular object being modified. (Note: this scheme assumes
31 * that any table modification that requires replanning will generate a
32 * relcache inval event.) We also watch for inval events on certain other
33 * system catalogs, such as pg_namespace; but for them, our response is
34 * just to invalidate all plans. We expect updates on those catalogs to
35 * be infrequent enough that more-detailed tracking is not worth the effort.
38 * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
39 * Portions Copyright (c) 1994, Regents of the University of California
42 * src/backend/utils/cache/plancache.c
44 *-------------------------------------------------------------------------
50 #include "access/transam.h"
51 #include "catalog/namespace.h"
52 #include "executor/executor.h"
53 #include "executor/spi.h"
54 #include "nodes/nodeFuncs.h"
55 #include "optimizer/planmain.h"
56 #include "optimizer/prep.h"
57 #include "parser/analyze.h"
58 #include "parser/parsetree.h"
59 #include "storage/lmgr.h"
60 #include "tcop/pquery.h"
61 #include "tcop/utility.h"
62 #include "utils/inval.h"
63 #include "utils/memutils.h"
64 #include "utils/resowner_private.h"
65 #include "utils/snapmgr.h"
66 #include "utils/syscache.h"
70 * This is the head of the backend's list of "saved" CachedPlanSources (i.e.,
71 * those that are in long-lived storage and are examined for sinval events).
72 * We thread the structs manually instead of using List cells so that we can
73 * guarantee to save a CachedPlanSource without error.
75 static CachedPlanSource *first_saved_plan = NULL;
77 static void ReleaseGenericPlan(CachedPlanSource *plansource);
78 static List *RevalidateCachedQuery(CachedPlanSource *plansource);
79 static bool CheckCachedPlan(CachedPlanSource *plansource);
80 static CachedPlan *BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
81 ParamListInfo boundParams);
82 static bool choose_custom_plan(CachedPlanSource *plansource,
83 ParamListInfo boundParams);
84 static double cached_plan_cost(CachedPlan *plan);
85 static void AcquireExecutorLocks(List *stmt_list, bool acquire);
86 static void AcquirePlannerLocks(List *stmt_list, bool acquire);
87 static void ScanQueryForLocks(Query *parsetree, bool acquire);
88 static bool ScanQueryWalker(Node *node, bool *acquire);
89 static bool plan_list_is_transient(List *stmt_list);
90 static TupleDesc PlanCacheComputeResultDesc(List *stmt_list);
91 static void PlanCacheRelCallback(Datum arg, Oid relid);
92 static void PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue);
93 static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue);
97 * InitPlanCache: initialize module during InitPostgres.
99 * All we need to do is hook into inval.c's callback lists.
104 CacheRegisterRelcacheCallback(PlanCacheRelCallback, (Datum) 0);
105 CacheRegisterSyscacheCallback(PROCOID, PlanCacheFuncCallback, (Datum) 0);
106 CacheRegisterSyscacheCallback(NAMESPACEOID, PlanCacheSysCallback, (Datum) 0);
107 CacheRegisterSyscacheCallback(OPEROID, PlanCacheSysCallback, (Datum) 0);
108 CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum) 0);
112 * CreateCachedPlan: initially create a plan cache entry.
114 * Creation of a cached plan is divided into two steps, CreateCachedPlan and
115 * CompleteCachedPlan. CreateCachedPlan should be called after running the
116 * query through raw_parser, but before doing parse analysis and rewrite;
117 * CompleteCachedPlan is called after that. The reason for this arrangement
118 * is that it can save one round of copying of the raw parse tree, since
119 * the parser will normally scribble on the raw parse tree. Callers would
120 * otherwise need to make an extra copy of the parse tree to ensure they
121 * still had a clean copy to present at plan cache creation time.
123 * All arguments presented to CreateCachedPlan are copied into a memory
124 * context created as a child of the call-time CurrentMemoryContext, which
125 * should be a reasonably short-lived working context that will go away in
126 * event of an error. This ensures that the cached plan data structure will
127 * likewise disappear if an error occurs before we have fully constructed it.
128 * Once constructed, the cached plan can be made longer-lived, if needed,
129 * by calling SaveCachedPlan.
131 * raw_parse_tree: output of raw_parser()
132 * query_string: original query text
133 * commandTag: compile-time-constant tag for query, or NULL if empty query
136 CreateCachedPlan(Node *raw_parse_tree,
137 const char *query_string,
138 const char *commandTag)
140 CachedPlanSource *plansource;
141 MemoryContext source_context;
142 MemoryContext oldcxt;
144 Assert(query_string != NULL); /* required as of 8.4 */
147 * Make a dedicated memory context for the CachedPlanSource and its
148 * permanent subsidiary data. It's probably not going to be large, but
149 * just in case, use the default maxsize parameter. Initially it's a
150 * child of the caller's context (which we assume to be transient), so
151 * that it will be cleaned up on error.
153 source_context = AllocSetContextCreate(CurrentMemoryContext,
155 ALLOCSET_SMALL_MINSIZE,
156 ALLOCSET_SMALL_INITSIZE,
157 ALLOCSET_DEFAULT_MAXSIZE);
160 * Create and fill the CachedPlanSource struct within the new context.
161 * Most fields are just left empty for the moment.
163 oldcxt = MemoryContextSwitchTo(source_context);
165 plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
166 plansource->magic = CACHEDPLANSOURCE_MAGIC;
167 plansource->raw_parse_tree = copyObject(raw_parse_tree);
168 plansource->query_string = pstrdup(query_string);
169 plansource->commandTag = commandTag;
170 plansource->param_types = NULL;
171 plansource->num_params = 0;
172 plansource->parserSetup = NULL;
173 plansource->parserSetupArg = NULL;
174 plansource->cursor_options = 0;
175 plansource->fixed_result = false;
176 plansource->resultDesc = NULL;
177 plansource->search_path = NULL;
178 plansource->context = source_context;
179 plansource->query_list = NIL;
180 plansource->relationOids = NIL;
181 plansource->invalItems = NIL;
182 plansource->query_context = NULL;
183 plansource->gplan = NULL;
184 plansource->is_oneshot = false;
185 plansource->is_complete = false;
186 plansource->is_saved = false;
187 plansource->is_valid = false;
188 plansource->generation = 0;
189 plansource->next_saved = NULL;
190 plansource->generic_cost = -1;
191 plansource->total_custom_cost = 0;
192 plansource->num_custom_plans = 0;
194 MemoryContextSwitchTo(oldcxt);
200 * CreateOneShotCachedPlan: initially create a one-shot plan cache entry.
202 * This variant of CreateCachedPlan creates a plan cache entry that is meant
203 * to be used only once. No data copying occurs: all data structures remain
204 * in the caller's memory context (which typically should get cleared after
205 * completing execution). The CachedPlanSource struct itself is also created
208 * A one-shot plan cannot be saved or copied, since we make no effort to
209 * preserve the raw parse tree unmodified. There is also no support for
210 * invalidation, so plan use must be completed in the current transaction,
211 * and DDL that might invalidate the querytree_list must be avoided as well.
213 * raw_parse_tree: output of raw_parser()
214 * query_string: original query text
215 * commandTag: compile-time-constant tag for query, or NULL if empty query
218 CreateOneShotCachedPlan(Node *raw_parse_tree,
219 const char *query_string,
220 const char *commandTag)
222 CachedPlanSource *plansource;
224 Assert(query_string != NULL); /* required as of 8.4 */
227 * Create and fill the CachedPlanSource struct within the caller's memory
228 * context. Most fields are just left empty for the moment.
230 plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
231 plansource->magic = CACHEDPLANSOURCE_MAGIC;
232 plansource->raw_parse_tree = raw_parse_tree;
233 plansource->query_string = query_string;
234 plansource->commandTag = commandTag;
235 plansource->param_types = NULL;
236 plansource->num_params = 0;
237 plansource->parserSetup = NULL;
238 plansource->parserSetupArg = NULL;
239 plansource->cursor_options = 0;
240 plansource->fixed_result = false;
241 plansource->resultDesc = NULL;
242 plansource->search_path = NULL;
243 plansource->context = CurrentMemoryContext;
244 plansource->query_list = NIL;
245 plansource->relationOids = NIL;
246 plansource->invalItems = NIL;
247 plansource->query_context = NULL;
248 plansource->gplan = NULL;
249 plansource->is_oneshot = true;
250 plansource->is_complete = false;
251 plansource->is_saved = false;
252 plansource->is_valid = false;
253 plansource->generation = 0;
254 plansource->next_saved = NULL;
255 plansource->generic_cost = -1;
256 plansource->total_custom_cost = 0;
257 plansource->num_custom_plans = 0;
263 * CompleteCachedPlan: second step of creating a plan cache entry.
265 * Pass in the analyzed-and-rewritten form of the query, as well as the
266 * required subsidiary data about parameters and such. All passed values will
267 * be copied into the CachedPlanSource's memory, except as specified below.
268 * After this is called, GetCachedPlan can be called to obtain a plan, and
269 * optionally the CachedPlanSource can be saved using SaveCachedPlan.
271 * If querytree_context is not NULL, the querytree_list must be stored in that
272 * context (but the other parameters need not be). The querytree_list is not
273 * copied, rather the given context is kept as the initial query_context of
274 * the CachedPlanSource. (It should have been created as a child of the
275 * caller's working memory context, but it will now be reparented to belong
276 * to the CachedPlanSource.) The querytree_context is normally the context in
277 * which the caller did raw parsing and parse analysis. This approach saves
278 * one tree copying step compared to passing NULL, but leaves lots of extra
279 * cruft in the query_context, namely whatever extraneous stuff parse analysis
280 * created, as well as whatever went unused from the raw parse tree. Using
281 * this option is a space-for-time tradeoff that is appropriate if the
282 * CachedPlanSource is not expected to survive long.
284 * plancache.c cannot know how to copy the data referenced by parserSetupArg,
285 * and it would often be inappropriate to do so anyway. When using that
286 * option, it is caller's responsibility that the referenced data remains
287 * valid for as long as the CachedPlanSource exists.
289 * If the CachedPlanSource is a "oneshot" plan, then no querytree copying
290 * occurs at all, and querytree_context is ignored; it is caller's
291 * responsibility that the passed querytree_list is sufficiently long-lived.
293 * plansource: structure returned by CreateCachedPlan
294 * querytree_list: analyzed-and-rewritten form of query (list of Query nodes)
295 * querytree_context: memory context containing querytree_list,
296 * or NULL to copy querytree_list into a fresh context
297 * param_types: array of fixed parameter type OIDs, or NULL if none
298 * num_params: number of fixed parameters
299 * parserSetup: alternate method for handling query parameters
300 * parserSetupArg: data to pass to parserSetup
301 * cursor_options: options bitmask to pass to planner
302 * fixed_result: TRUE to disallow future changes in query's result tupdesc
305 CompleteCachedPlan(CachedPlanSource *plansource,
306 List *querytree_list,
307 MemoryContext querytree_context,
310 ParserSetupHook parserSetup,
311 void *parserSetupArg,
315 MemoryContext source_context = plansource->context;
316 MemoryContext oldcxt = CurrentMemoryContext;
318 /* Assert caller is doing things in a sane order */
319 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
320 Assert(!plansource->is_complete);
323 * If caller supplied a querytree_context, reparent it underneath the
324 * CachedPlanSource's context; otherwise, create a suitable context and
325 * copy the querytree_list into it. But no data copying should be done
326 * for one-shot plans; for those, assume the passed querytree_list is
327 * sufficiently long-lived.
329 if (plansource->is_oneshot)
331 querytree_context = CurrentMemoryContext;
333 else if (querytree_context != NULL)
335 MemoryContextSetParent(querytree_context, source_context);
336 MemoryContextSwitchTo(querytree_context);
340 /* Again, it's a good bet the querytree_context can be small */
341 querytree_context = AllocSetContextCreate(source_context,
343 ALLOCSET_SMALL_MINSIZE,
344 ALLOCSET_SMALL_INITSIZE,
345 ALLOCSET_DEFAULT_MAXSIZE);
346 MemoryContextSwitchTo(querytree_context);
347 querytree_list = (List *) copyObject(querytree_list);
350 plansource->query_context = querytree_context;
351 plansource->query_list = querytree_list;
354 * Use the planner machinery to extract dependencies. Data is saved in
355 * query_context. (We assume that not a lot of extra cruft is created by
356 * this call.) We can skip this for one-shot plans.
358 if (!plansource->is_oneshot)
359 extract_query_dependencies((Node *) querytree_list,
360 &plansource->relationOids,
361 &plansource->invalItems);
364 * Save the final parameter types (or other parameter specification data)
365 * into the source_context, as well as our other parameters. Also save
366 * the result tuple descriptor.
368 MemoryContextSwitchTo(source_context);
372 plansource->param_types = (Oid *) palloc(num_params * sizeof(Oid));
373 memcpy(plansource->param_types, param_types, num_params * sizeof(Oid));
376 plansource->param_types = NULL;
377 plansource->num_params = num_params;
378 plansource->parserSetup = parserSetup;
379 plansource->parserSetupArg = parserSetupArg;
380 plansource->cursor_options = cursor_options;
381 plansource->fixed_result = fixed_result;
382 plansource->resultDesc = PlanCacheComputeResultDesc(querytree_list);
384 MemoryContextSwitchTo(oldcxt);
387 * Fetch current search_path into dedicated context, but do any
388 * recalculation work required in caller's context.
390 plansource->search_path = GetOverrideSearchPath(source_context);
392 plansource->is_complete = true;
393 plansource->is_valid = true;
397 * SaveCachedPlan: save a cached plan permanently
399 * This function moves the cached plan underneath CacheMemoryContext (making
400 * it live for the life of the backend, unless explicitly dropped), and adds
401 * it to the list of cached plans that are checked for invalidation when an
402 * sinval event occurs.
404 * This is guaranteed not to throw error, except for the caller-error case
405 * of trying to save a one-shot plan. Callers typically depend on that
406 * since this is called just before or just after adding a pointer to the
407 * CachedPlanSource to some permanent data structure of their own. Up until
408 * this is done, a CachedPlanSource is just transient data that will go away
409 * automatically on transaction abort.
412 SaveCachedPlan(CachedPlanSource *plansource)
414 /* Assert caller is doing things in a sane order */
415 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
416 Assert(plansource->is_complete);
417 Assert(!plansource->is_saved);
419 /* This seems worth a real test, though */
420 if (plansource->is_oneshot)
421 elog(ERROR, "cannot save one-shot cached plan");
424 * In typical use, this function would be called before generating any
425 * plans from the CachedPlanSource. If there is a generic plan, moving it
426 * into CacheMemoryContext would be pretty risky since it's unclear
427 * whether the caller has taken suitable care with making references
428 * long-lived. Best thing to do seems to be to discard the plan.
430 ReleaseGenericPlan(plansource);
433 * Reparent the source memory context under CacheMemoryContext so that it
434 * will live indefinitely. The query_context follows along since it's
435 * already a child of the other one.
437 MemoryContextSetParent(plansource->context, CacheMemoryContext);
440 * Add the entry to the global list of cached plans.
442 plansource->next_saved = first_saved_plan;
443 first_saved_plan = plansource;
445 plansource->is_saved = true;
449 * DropCachedPlan: destroy a cached plan.
451 * Actually this only destroys the CachedPlanSource: any referenced CachedPlan
452 * is released, but not destroyed until its refcount goes to zero. That
453 * handles the situation where DropCachedPlan is called while the plan is
457 DropCachedPlan(CachedPlanSource *plansource)
459 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
461 /* If it's been saved, remove it from the list */
462 if (plansource->is_saved)
464 if (first_saved_plan == plansource)
465 first_saved_plan = plansource->next_saved;
468 CachedPlanSource *psrc;
470 for (psrc = first_saved_plan; psrc; psrc = psrc->next_saved)
472 if (psrc->next_saved == plansource)
474 psrc->next_saved = plansource->next_saved;
479 plansource->is_saved = false;
482 /* Decrement generic CachePlan's refcount and drop if no longer needed */
483 ReleaseGenericPlan(plansource);
485 /* Mark it no longer valid */
486 plansource->magic = 0;
489 * Remove the CachedPlanSource and all subsidiary data (including the
490 * query_context if any). But if it's a one-shot we can't free anything.
492 if (!plansource->is_oneshot)
493 MemoryContextDelete(plansource->context);
497 * ReleaseGenericPlan: release a CachedPlanSource's generic plan, if any.
500 ReleaseGenericPlan(CachedPlanSource *plansource)
502 /* Be paranoid about the possibility that ReleaseCachedPlan fails */
503 if (plansource->gplan)
505 CachedPlan *plan = plansource->gplan;
507 Assert(plan->magic == CACHEDPLAN_MAGIC);
508 plansource->gplan = NULL;
509 ReleaseCachedPlan(plan, false);
514 * RevalidateCachedQuery: ensure validity of analyzed-and-rewritten query tree.
516 * What we do here is re-acquire locks and redo parse analysis if necessary.
517 * On return, the query_list is valid and we have sufficient locks to begin
520 * If any parse analysis activity is required, the caller's memory context is
521 * used for that work.
523 * The result value is the transient analyzed-and-rewritten query tree if we
524 * had to do re-analysis, and NIL otherwise. (This is returned just to save
525 * a tree copying step in a subsequent BuildCachedPlan call.)
528 RevalidateCachedQuery(CachedPlanSource *plansource)
532 List *tlist; /* transient query-tree list */
533 List *qlist; /* permanent query-tree list */
534 TupleDesc resultDesc;
535 MemoryContext querytree_context;
536 MemoryContext oldcxt;
539 * For one-shot plans, we do not support revalidation checking; it's
540 * assumed the query is parsed, planned, and executed in one transaction,
541 * so that no lock re-acquisition is necessary.
543 if (plansource->is_oneshot)
545 Assert(plansource->is_valid);
550 * If the query is currently valid, acquire locks on the referenced
551 * objects; then check again. We need to do it this way to cover the race
552 * condition that an invalidation message arrives before we get the locks.
554 if (plansource->is_valid)
556 AcquirePlannerLocks(plansource->query_list, true);
559 * By now, if any invalidation has happened, the inval callback
560 * functions will have marked the query invalid.
562 if (plansource->is_valid)
564 /* Successfully revalidated and locked the query. */
568 /* Ooops, the race case happened. Release useless locks. */
569 AcquirePlannerLocks(plansource->query_list, false);
573 * Discard the no-longer-useful query tree. (Note: we don't want to do
574 * this any earlier, else we'd not have been able to release locks
575 * correctly in the race condition case.)
577 plansource->is_valid = false;
578 plansource->query_list = NIL;
579 plansource->relationOids = NIL;
580 plansource->invalItems = NIL;
583 * Free the query_context. We don't really expect MemoryContextDelete to
584 * fail, but just in case, make sure the CachedPlanSource is left in a
585 * reasonably sane state. (The generic plan won't get unlinked yet, but
586 * that's acceptable.)
588 if (plansource->query_context)
590 MemoryContext qcxt = plansource->query_context;
592 plansource->query_context = NULL;
593 MemoryContextDelete(qcxt);
596 /* Drop the generic plan reference if any */
597 ReleaseGenericPlan(plansource);
600 * Now re-do parse analysis and rewrite. This not incidentally acquires
601 * the locks we need to do planning safely.
603 Assert(plansource->is_complete);
606 * Restore the search_path that was in use when the plan was made. See
607 * comments for PushOverrideSearchPath about limitations of this.
609 * (XXX is there anything else we really need to restore?)
611 PushOverrideSearchPath(plansource->search_path);
614 * If a snapshot is already set (the normal case), we can just use that
615 * for parsing/planning. But if it isn't, install one. Note: no point in
616 * checking whether parse analysis requires a snapshot; utility commands
617 * don't have invalidatable plans, so we'd not get here for such a
620 snapshot_set = false;
621 if (!ActiveSnapshotSet())
623 PushActiveSnapshot(GetTransactionSnapshot());
628 * Run parse analysis and rule rewriting. The parser tends to scribble on
629 * its input, so we must copy the raw parse tree to prevent corruption of
632 rawtree = copyObject(plansource->raw_parse_tree);
633 if (plansource->parserSetup != NULL)
634 tlist = pg_analyze_and_rewrite_params(rawtree,
635 plansource->query_string,
636 plansource->parserSetup,
637 plansource->parserSetupArg);
639 tlist = pg_analyze_and_rewrite(rawtree,
640 plansource->query_string,
641 plansource->param_types,
642 plansource->num_params);
644 /* Release snapshot if we got one */
648 /* Now we can restore current search path */
649 PopOverrideSearchPath();
652 * Check or update the result tupdesc. XXX should we use a weaker
653 * condition than equalTupleDescs() here?
655 * We assume the parameter types didn't change from the first time, so no
656 * need to update that.
658 resultDesc = PlanCacheComputeResultDesc(tlist);
659 if (resultDesc == NULL && plansource->resultDesc == NULL)
661 /* OK, doesn't return tuples */
663 else if (resultDesc == NULL || plansource->resultDesc == NULL ||
664 !equalTupleDescs(resultDesc, plansource->resultDesc))
666 /* can we give a better error message? */
667 if (plansource->fixed_result)
669 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
670 errmsg("cached plan must not change result type")));
671 oldcxt = MemoryContextSwitchTo(plansource->context);
673 resultDesc = CreateTupleDescCopy(resultDesc);
674 if (plansource->resultDesc)
675 FreeTupleDesc(plansource->resultDesc);
676 plansource->resultDesc = resultDesc;
677 MemoryContextSwitchTo(oldcxt);
681 * Allocate new query_context and copy the completed querytree into it.
682 * It's transient until we complete the copying and dependency extraction.
684 querytree_context = AllocSetContextCreate(CurrentMemoryContext,
686 ALLOCSET_SMALL_MINSIZE,
687 ALLOCSET_SMALL_INITSIZE,
688 ALLOCSET_DEFAULT_MAXSIZE);
689 oldcxt = MemoryContextSwitchTo(querytree_context);
691 qlist = (List *) copyObject(tlist);
694 * Use the planner machinery to extract dependencies. Data is saved in
695 * query_context. (We assume that not a lot of extra cruft is created by
698 extract_query_dependencies((Node *) qlist,
699 &plansource->relationOids,
700 &plansource->invalItems);
702 MemoryContextSwitchTo(oldcxt);
704 /* Now reparent the finished query_context and save the links */
705 MemoryContextSetParent(querytree_context, plansource->context);
707 plansource->query_context = querytree_context;
708 plansource->query_list = qlist;
711 * Note: we do not reset generic_cost or total_custom_cost, although we
712 * could choose to do so. If the DDL or statistics change that prompted
713 * the invalidation meant a significant change in the cost estimates, it
714 * would be better to reset those variables and start fresh; but often it
715 * doesn't, and we're better retaining our hard-won knowledge about the
719 plansource->is_valid = true;
721 /* Return transient copy of querytrees for possible use in planning */
726 * CheckCachedPlan: see if the CachedPlanSource's generic plan is valid.
728 * Caller must have already called RevalidateCachedQuery to verify that the
729 * querytree is up to date.
731 * On a "true" return, we have acquired the locks needed to run the plan.
732 * (We must do this for the "true" result to be race-condition-free.)
735 CheckCachedPlan(CachedPlanSource *plansource)
737 CachedPlan *plan = plansource->gplan;
739 /* Assert that caller checked the querytree */
740 Assert(plansource->is_valid);
742 /* If there's no generic plan, just say "false" */
746 Assert(plan->magic == CACHEDPLAN_MAGIC);
747 /* Generic plans are never one-shot */
748 Assert(!plan->is_oneshot);
751 * If it appears valid, acquire locks and recheck; this is much the same
752 * logic as in RevalidateCachedQuery, but for a plan.
757 * Plan must have positive refcount because it is referenced by
758 * plansource; so no need to fear it disappears under us here.
760 Assert(plan->refcount > 0);
762 AcquireExecutorLocks(plan->stmt_list, true);
765 * If plan was transient, check to see if TransactionXmin has
766 * advanced, and if so invalidate it.
768 if (plan->is_valid &&
769 TransactionIdIsValid(plan->saved_xmin) &&
770 !TransactionIdEquals(plan->saved_xmin, TransactionXmin))
771 plan->is_valid = false;
774 * By now, if any invalidation has happened, the inval callback
775 * functions will have marked the plan invalid.
779 /* Successfully revalidated and locked the query. */
783 /* Ooops, the race case happened. Release useless locks. */
784 AcquireExecutorLocks(plan->stmt_list, false);
788 * Plan has been invalidated, so unlink it from the parent and release it.
790 ReleaseGenericPlan(plansource);
796 * BuildCachedPlan: construct a new CachedPlan from a CachedPlanSource.
798 * qlist should be the result value from a previous RevalidateCachedQuery,
799 * or it can be set to NIL if we need to re-copy the plansource's query_list.
801 * To build a generic, parameter-value-independent plan, pass NULL for
802 * boundParams. To build a custom plan, pass the actual parameter values via
803 * boundParams. For best effect, the PARAM_FLAG_CONST flag should be set on
804 * each parameter value; otherwise the planner will treat the value as a
805 * hint rather than a hard constant.
807 * Planning work is done in the caller's memory context. The finished plan
808 * is in a child memory context, which typically should get reparented
809 * (unless this is a one-shot plan, in which case we don't copy the plan).
812 BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
813 ParamListInfo boundParams)
819 MemoryContext plan_context;
820 MemoryContext oldcxt = CurrentMemoryContext;
823 * Normally the querytree should be valid already, but if it's not,
826 * NOTE: GetCachedPlan should have called RevalidateCachedQuery first, so
827 * we ought to be holding sufficient locks to prevent any invalidation.
828 * However, if we're building a custom plan after having built and
829 * rejected a generic plan, it's possible to reach here with is_valid
830 * false due to an invalidation while making the generic plan. In theory
831 * the invalidation must be a false positive, perhaps a consequence of an
832 * sinval reset event or the CLOBBER_CACHE_ALWAYS debug code. But for
833 * safety, let's treat it as real and redo the RevalidateCachedQuery call.
835 if (!plansource->is_valid)
836 qlist = RevalidateCachedQuery(plansource);
839 * If we don't already have a copy of the querytree list that can be
840 * scribbled on by the planner, make one. For a one-shot plan, we assume
841 * it's okay to scribble on the original query_list.
845 if (!plansource->is_oneshot)
846 qlist = (List *) copyObject(plansource->query_list);
848 qlist = plansource->query_list;
852 * Restore the search_path that was in use when the plan was made. See
853 * comments for PushOverrideSearchPath about limitations of this.
855 * (XXX is there anything else we really need to restore?)
857 * Note: it's a bit annoying to do this and snapshot-setting twice in the
858 * case where we have to do both re-analysis and re-planning. However,
859 * until there's some evidence that the cost is actually meaningful
860 * compared to parse analysis + planning, I'm not going to contort the
861 * code enough to avoid that.
863 PushOverrideSearchPath(plansource->search_path);
866 * If a snapshot is already set (the normal case), we can just use that
867 * for planning. But if it isn't, and we need one, install one.
869 snapshot_set = false;
870 if (!ActiveSnapshotSet() &&
871 analyze_requires_snapshot(plansource->raw_parse_tree))
873 PushActiveSnapshot(GetTransactionSnapshot());
878 * The planner may try to call SPI-using functions, which causes a problem
879 * if we're already inside one. Rather than expect all SPI-using code to
880 * do SPI_push whenever a replan could happen, it seems best to take care
883 spi_pushed = SPI_push_conditional();
888 plist = pg_plan_queries(qlist, plansource->cursor_options, boundParams);
890 /* Clean up SPI state */
891 SPI_pop_conditional(spi_pushed);
893 /* Release snapshot if we got one */
897 /* Now we can restore current search path */
898 PopOverrideSearchPath();
901 * Normally we make a dedicated memory context for the CachedPlan and its
902 * subsidiary data. (It's probably not going to be large, but just in
903 * case, use the default maxsize parameter. It's transient for the
904 * moment.) But for a one-shot plan, we just leave it in the caller's
907 if (!plansource->is_oneshot)
909 plan_context = AllocSetContextCreate(CurrentMemoryContext,
911 ALLOCSET_SMALL_MINSIZE,
912 ALLOCSET_SMALL_INITSIZE,
913 ALLOCSET_DEFAULT_MAXSIZE);
916 * Copy plan into the new context.
918 MemoryContextSwitchTo(plan_context);
920 plist = (List *) copyObject(plist);
923 plan_context = CurrentMemoryContext;
926 * Create and fill the CachedPlan struct within the new context.
928 plan = (CachedPlan *) palloc(sizeof(CachedPlan));
929 plan->magic = CACHEDPLAN_MAGIC;
930 plan->stmt_list = plist;
931 if (plan_list_is_transient(plist))
933 Assert(TransactionIdIsNormal(TransactionXmin));
934 plan->saved_xmin = TransactionXmin;
937 plan->saved_xmin = InvalidTransactionId;
939 plan->context = plan_context;
940 plan->is_oneshot = plansource->is_oneshot;
941 plan->is_saved = false;
942 plan->is_valid = true;
944 /* assign generation number to new plan */
945 plan->generation = ++(plansource->generation);
947 MemoryContextSwitchTo(oldcxt);
953 * choose_custom_plan: choose whether to use custom or generic plan
955 * This defines the policy followed by GetCachedPlan.
958 choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams)
960 double avg_custom_cost;
962 /* One-shot plans will always be considered custom */
963 if (plansource->is_oneshot)
966 /* Otherwise, never any point in a custom plan if there's no parameters */
967 if (boundParams == NULL)
970 /* See if caller wants to force the decision */
971 if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN)
973 if (plansource->cursor_options & CURSOR_OPT_CUSTOM_PLAN)
976 /* Generate custom plans until we have done at least 5 (arbitrary) */
977 if (plansource->num_custom_plans < 5)
980 avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans;
983 * Prefer generic plan if it's less than 10% more expensive than average
984 * custom plan. This threshold is a bit arbitrary; it'd be better if we
985 * had some means of comparing planning time to the estimated runtime cost
988 * Note that if generic_cost is -1 (indicating we've not yet determined
989 * the generic plan cost), we'll always prefer generic at this point.
991 if (plansource->generic_cost < avg_custom_cost * 1.1)
998 * cached_plan_cost: calculate estimated cost of a plan
1001 cached_plan_cost(CachedPlan *plan)
1006 foreach(lc, plan->stmt_list)
1008 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1010 if (!IsA(plannedstmt, PlannedStmt))
1011 continue; /* Ignore utility statements */
1013 result += plannedstmt->planTree->total_cost;
1020 * GetCachedPlan: get a cached plan from a CachedPlanSource.
1022 * This function hides the logic that decides whether to use a generic
1023 * plan or a custom plan for the given parameters: the caller does not know
1024 * which it will get.
1026 * On return, the plan is valid and we have sufficient locks to begin
1029 * On return, the refcount of the plan has been incremented; a later
1030 * ReleaseCachedPlan() call is expected. The refcount has been reported
1031 * to the CurrentResourceOwner if useResOwner is true (note that that must
1032 * only be true if it's a "saved" CachedPlanSource).
1034 * Note: if any replanning activity is required, the caller's memory context
1035 * is used for that work.
1038 GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams,
1045 /* Assert caller is doing things in a sane order */
1046 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1047 Assert(plansource->is_complete);
1048 /* This seems worth a real test, though */
1049 if (useResOwner && !plansource->is_saved)
1050 elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
1052 /* Make sure the querytree list is valid and we have parse-time locks */
1053 qlist = RevalidateCachedQuery(plansource);
1055 /* Decide whether to use a custom plan */
1056 customplan = choose_custom_plan(plansource, boundParams);
1060 if (CheckCachedPlan(plansource))
1062 /* We want a generic plan, and we already have a valid one */
1063 plan = plansource->gplan;
1064 Assert(plan->magic == CACHEDPLAN_MAGIC);
1068 /* Build a new generic plan */
1069 plan = BuildCachedPlan(plansource, qlist, NULL);
1070 /* Just make real sure plansource->gplan is clear */
1071 ReleaseGenericPlan(plansource);
1072 /* Link the new generic plan into the plansource */
1073 plansource->gplan = plan;
1075 /* Immediately reparent into appropriate context */
1076 if (plansource->is_saved)
1078 /* saved plans all live under CacheMemoryContext */
1079 MemoryContextSetParent(plan->context, CacheMemoryContext);
1080 plan->is_saved = true;
1084 /* otherwise, it should be a sibling of the plansource */
1085 MemoryContextSetParent(plan->context,
1086 MemoryContextGetParent(plansource->context));
1088 /* Update generic_cost whenever we make a new generic plan */
1089 plansource->generic_cost = cached_plan_cost(plan);
1092 * If, based on the now-known value of generic_cost, we'd not have
1093 * chosen to use a generic plan, then forget it and make a custom
1094 * plan. This is a bit of a wart but is necessary to avoid a
1095 * glitch in behavior when the custom plans are consistently big
1096 * winners; at some point we'll experiment with a generic plan and
1097 * find it's a loser, but we don't want to actually execute that
1100 customplan = choose_custom_plan(plansource, boundParams);
1103 * If we choose to plan again, we need to re-copy the query_list,
1104 * since the planner probably scribbled on it. We can force
1105 * BuildCachedPlan to do that by passing NIL.
1113 /* Build a custom plan */
1114 plan = BuildCachedPlan(plansource, qlist, boundParams);
1115 /* Accumulate total costs of custom plans, but 'ware overflow */
1116 if (plansource->num_custom_plans < INT_MAX)
1118 plansource->total_custom_cost += cached_plan_cost(plan);
1119 plansource->num_custom_plans++;
1123 /* Flag the plan as in use by caller */
1125 ResourceOwnerEnlargePlanCacheRefs(CurrentResourceOwner);
1128 ResourceOwnerRememberPlanCacheRef(CurrentResourceOwner, plan);
1131 * Saved plans should be under CacheMemoryContext so they will not go away
1132 * until their reference count goes to zero. In the generic-plan cases we
1133 * already took care of that, but for a custom plan, do it as soon as we
1134 * have created a reference-counted link.
1136 if (customplan && plansource->is_saved)
1138 MemoryContextSetParent(plan->context, CacheMemoryContext);
1139 plan->is_saved = true;
1146 * ReleaseCachedPlan: release active use of a cached plan.
1148 * This decrements the reference count, and frees the plan if the count
1149 * has thereby gone to zero. If useResOwner is true, it is assumed that
1150 * the reference count is managed by the CurrentResourceOwner.
1152 * Note: useResOwner = false is used for releasing references that are in
1153 * persistent data structures, such as the parent CachedPlanSource or a
1154 * Portal. Transient references should be protected by a resource owner.
1157 ReleaseCachedPlan(CachedPlan *plan, bool useResOwner)
1159 Assert(plan->magic == CACHEDPLAN_MAGIC);
1162 Assert(plan->is_saved);
1163 ResourceOwnerForgetPlanCacheRef(CurrentResourceOwner, plan);
1165 Assert(plan->refcount > 0);
1167 if (plan->refcount == 0)
1169 /* Mark it no longer valid */
1172 /* One-shot plans do not own their context, so we can't free them */
1173 if (!plan->is_oneshot)
1174 MemoryContextDelete(plan->context);
1179 * CachedPlanSetParentContext: move a CachedPlanSource to a new memory context
1181 * This can only be applied to unsaved plans; once saved, a plan always
1182 * lives underneath CacheMemoryContext.
1185 CachedPlanSetParentContext(CachedPlanSource *plansource,
1186 MemoryContext newcontext)
1188 /* Assert caller is doing things in a sane order */
1189 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1190 Assert(plansource->is_complete);
1192 /* These seem worth real tests, though */
1193 if (plansource->is_saved)
1194 elog(ERROR, "cannot move a saved cached plan to another context");
1195 if (plansource->is_oneshot)
1196 elog(ERROR, "cannot move a one-shot cached plan to another context");
1198 /* OK, let the caller keep the plan where he wishes */
1199 MemoryContextSetParent(plansource->context, newcontext);
1202 * The query_context needs no special handling, since it's a child of
1203 * plansource->context. But if there's a generic plan, it should be
1204 * maintained as a sibling of plansource->context.
1206 if (plansource->gplan)
1208 Assert(plansource->gplan->magic == CACHEDPLAN_MAGIC);
1209 MemoryContextSetParent(plansource->gplan->context, newcontext);
1214 * CopyCachedPlan: make a copy of a CachedPlanSource
1216 * This is a convenience routine that does the equivalent of
1217 * CreateCachedPlan + CompleteCachedPlan, using the data stored in the
1218 * input CachedPlanSource. The result is therefore "unsaved" (regardless
1219 * of the state of the source), and we don't copy any generic plan either.
1220 * The result will be currently valid, or not, the same as the source.
1223 CopyCachedPlan(CachedPlanSource *plansource)
1225 CachedPlanSource *newsource;
1226 MemoryContext source_context;
1227 MemoryContext querytree_context;
1228 MemoryContext oldcxt;
1230 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1231 Assert(plansource->is_complete);
1234 * One-shot plans can't be copied, because we haven't taken care that
1235 * parsing/planning didn't scribble on the raw parse tree or querytrees.
1237 if (plansource->is_oneshot)
1238 elog(ERROR, "cannot copy a one-shot cached plan");
1240 source_context = AllocSetContextCreate(CurrentMemoryContext,
1242 ALLOCSET_SMALL_MINSIZE,
1243 ALLOCSET_SMALL_INITSIZE,
1244 ALLOCSET_DEFAULT_MAXSIZE);
1246 oldcxt = MemoryContextSwitchTo(source_context);
1248 newsource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
1249 newsource->magic = CACHEDPLANSOURCE_MAGIC;
1250 newsource->raw_parse_tree = copyObject(plansource->raw_parse_tree);
1251 newsource->query_string = pstrdup(plansource->query_string);
1252 newsource->commandTag = plansource->commandTag;
1253 if (plansource->num_params > 0)
1255 newsource->param_types = (Oid *)
1256 palloc(plansource->num_params * sizeof(Oid));
1257 memcpy(newsource->param_types, plansource->param_types,
1258 plansource->num_params * sizeof(Oid));
1261 newsource->param_types = NULL;
1262 newsource->num_params = plansource->num_params;
1263 newsource->parserSetup = plansource->parserSetup;
1264 newsource->parserSetupArg = plansource->parserSetupArg;
1265 newsource->cursor_options = plansource->cursor_options;
1266 newsource->fixed_result = plansource->fixed_result;
1267 if (plansource->resultDesc)
1268 newsource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
1270 newsource->resultDesc = NULL;
1271 newsource->search_path = CopyOverrideSearchPath(plansource->search_path);
1272 newsource->context = source_context;
1274 querytree_context = AllocSetContextCreate(source_context,
1276 ALLOCSET_SMALL_MINSIZE,
1277 ALLOCSET_SMALL_INITSIZE,
1278 ALLOCSET_DEFAULT_MAXSIZE);
1279 MemoryContextSwitchTo(querytree_context);
1280 newsource->query_list = (List *) copyObject(plansource->query_list);
1281 newsource->relationOids = (List *) copyObject(plansource->relationOids);
1282 newsource->invalItems = (List *) copyObject(plansource->invalItems);
1283 newsource->query_context = querytree_context;
1285 newsource->gplan = NULL;
1287 newsource->is_oneshot = false;
1288 newsource->is_complete = true;
1289 newsource->is_saved = false;
1290 newsource->is_valid = plansource->is_valid;
1291 newsource->generation = plansource->generation;
1292 newsource->next_saved = NULL;
1294 /* We may as well copy any acquired cost knowledge */
1295 newsource->generic_cost = plansource->generic_cost;
1296 newsource->total_custom_cost = plansource->total_custom_cost;
1297 newsource->num_custom_plans = plansource->num_custom_plans;
1299 MemoryContextSwitchTo(oldcxt);
1305 * CachedPlanIsValid: test whether the rewritten querytree within a
1306 * CachedPlanSource is currently valid (that is, not marked as being in need
1309 * This result is only trustworthy (ie, free from race conditions) if
1310 * the caller has acquired locks on all the relations used in the plan.
1313 CachedPlanIsValid(CachedPlanSource *plansource)
1315 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1316 return plansource->is_valid;
1320 * CachedPlanGetTargetList: return tlist, if any, describing plan's output
1322 * The result is guaranteed up-to-date. However, it is local storage
1323 * within the cached plan, and may disappear next time the plan is updated.
1326 CachedPlanGetTargetList(CachedPlanSource *plansource)
1330 /* Assert caller is doing things in a sane order */
1331 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1332 Assert(plansource->is_complete);
1335 * No work needed if statement doesn't return tuples (we assume this
1336 * feature cannot be changed by an invalidation)
1338 if (plansource->resultDesc == NULL)
1341 /* Make sure the querytree list is valid and we have parse-time locks */
1342 RevalidateCachedQuery(plansource);
1344 /* Get the primary statement and find out what it returns */
1345 pstmt = PortalListGetPrimaryStmt(plansource->query_list);
1347 return FetchStatementTargetList(pstmt);
1351 * AcquireExecutorLocks: acquire locks needed for execution of a cached plan;
1352 * or release them if acquire is false.
1355 AcquireExecutorLocks(List *stmt_list, bool acquire)
1359 foreach(lc1, stmt_list)
1361 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc1);
1365 Assert(!IsA(plannedstmt, Query));
1366 if (!IsA(plannedstmt, PlannedStmt))
1369 * Ignore utility statements, except those (such as EXPLAIN) that
1370 * contain a parsed-but-not-planned query. Note: it's okay to use
1371 * ScanQueryForLocks, even though the query hasn't been through
1372 * rule rewriting, because rewriting doesn't change the query
1375 Query *query = UtilityContainsQuery((Node *) plannedstmt);
1378 ScanQueryForLocks(query, acquire);
1383 foreach(lc2, plannedstmt->rtable)
1385 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
1391 if (rte->rtekind != RTE_RELATION)
1395 * Acquire the appropriate type of lock on each relation OID. Note
1396 * that we don't actually try to open the rel, and hence will not
1397 * fail if it's been dropped entirely --- we'll just transiently
1398 * acquire a non-conflicting lock.
1400 if (list_member_int(plannedstmt->resultRelations, rt_index))
1401 lockmode = RowExclusiveLock;
1402 else if ((rc = get_plan_rowmark(plannedstmt->rowMarks, rt_index)) != NULL &&
1403 RowMarkRequiresRowShareLock(rc->markType))
1404 lockmode = RowShareLock;
1406 lockmode = AccessShareLock;
1409 LockRelationOid(rte->relid, lockmode);
1411 UnlockRelationOid(rte->relid, lockmode);
1417 * AcquirePlannerLocks: acquire locks needed for planning of a querytree list;
1418 * or release them if acquire is false.
1420 * Note that we don't actually try to open the relations, and hence will not
1421 * fail if one has been dropped entirely --- we'll just transiently acquire
1422 * a non-conflicting lock.
1425 AcquirePlannerLocks(List *stmt_list, bool acquire)
1429 foreach(lc, stmt_list)
1431 Query *query = (Query *) lfirst(lc);
1433 Assert(IsA(query, Query));
1435 if (query->commandType == CMD_UTILITY)
1437 /* Ignore utility statements, unless they contain a Query */
1438 query = UtilityContainsQuery(query->utilityStmt);
1440 ScanQueryForLocks(query, acquire);
1444 ScanQueryForLocks(query, acquire);
1449 * ScanQueryForLocks: recursively scan one Query for AcquirePlannerLocks.
1452 ScanQueryForLocks(Query *parsetree, bool acquire)
1457 /* Shouldn't get called on utility commands */
1458 Assert(parsetree->commandType != CMD_UTILITY);
1461 * First, process RTEs of the current query level.
1464 foreach(lc, parsetree->rtable)
1466 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
1470 switch (rte->rtekind)
1473 /* Acquire or release the appropriate type of lock */
1474 if (rt_index == parsetree->resultRelation)
1475 lockmode = RowExclusiveLock;
1476 else if (get_parse_rowmark(parsetree, rt_index) != NULL)
1477 lockmode = RowShareLock;
1479 lockmode = AccessShareLock;
1481 LockRelationOid(rte->relid, lockmode);
1483 UnlockRelationOid(rte->relid, lockmode);
1487 /* Recurse into subquery-in-FROM */
1488 ScanQueryForLocks(rte->subquery, acquire);
1492 /* ignore other types of RTEs */
1497 /* Recurse into subquery-in-WITH */
1498 foreach(lc, parsetree->cteList)
1500 CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
1502 ScanQueryForLocks((Query *) cte->ctequery, acquire);
1506 * Recurse into sublink subqueries, too. But we already did the ones in
1507 * the rtable and cteList.
1509 if (parsetree->hasSubLinks)
1511 query_tree_walker(parsetree, ScanQueryWalker,
1513 QTW_IGNORE_RC_SUBQUERIES);
1518 * Walker to find sublink subqueries for ScanQueryForLocks
1521 ScanQueryWalker(Node *node, bool *acquire)
1525 if (IsA(node, SubLink))
1527 SubLink *sub = (SubLink *) node;
1529 /* Do what we came for */
1530 ScanQueryForLocks((Query *) sub->subselect, *acquire);
1531 /* Fall through to process lefthand args of SubLink */
1535 * Do NOT recurse into Query nodes, because ScanQueryForLocks already
1536 * processed subselects of subselects for us.
1538 return expression_tree_walker(node, ScanQueryWalker,
1543 * plan_list_is_transient: check if any of the plans in the list are transient.
1546 plan_list_is_transient(List *stmt_list)
1550 foreach(lc, stmt_list)
1552 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1554 if (!IsA(plannedstmt, PlannedStmt))
1555 continue; /* Ignore utility statements */
1557 if (plannedstmt->transientPlan)
1565 * PlanCacheComputeResultDesc: given a list of analyzed-and-rewritten Queries,
1566 * determine the result tupledesc it will produce. Returns NULL if the
1567 * execution will not return tuples.
1569 * Note: the result is created or copied into current memory context.
1572 PlanCacheComputeResultDesc(List *stmt_list)
1576 switch (ChoosePortalStrategy(stmt_list))
1578 case PORTAL_ONE_SELECT:
1579 case PORTAL_ONE_MOD_WITH:
1580 query = (Query *) linitial(stmt_list);
1581 Assert(IsA(query, Query));
1582 return ExecCleanTypeFromTL(query->targetList, false);
1584 case PORTAL_ONE_RETURNING:
1585 query = (Query *) PortalListGetPrimaryStmt(stmt_list);
1586 Assert(IsA(query, Query));
1587 Assert(query->returningList);
1588 return ExecCleanTypeFromTL(query->returningList, false);
1590 case PORTAL_UTIL_SELECT:
1591 query = (Query *) linitial(stmt_list);
1592 Assert(IsA(query, Query));
1593 Assert(query->utilityStmt);
1594 return UtilityTupleDescriptor(query->utilityStmt);
1596 case PORTAL_MULTI_QUERY:
1597 /* will not return tuples */
1604 * PlanCacheRelCallback
1605 * Relcache inval callback function
1607 * Invalidate all plans mentioning the given rel, or all plans mentioning
1608 * any rel at all if relid == InvalidOid.
1611 PlanCacheRelCallback(Datum arg, Oid relid)
1613 CachedPlanSource *plansource;
1615 for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
1617 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1619 /* No work if it's already invalidated */
1620 if (!plansource->is_valid)
1624 * Check the dependency list for the rewritten querytree.
1626 if ((relid == InvalidOid) ? plansource->relationOids != NIL :
1627 list_member_oid(plansource->relationOids, relid))
1629 /* Invalidate the querytree and generic plan */
1630 plansource->is_valid = false;
1631 if (plansource->gplan)
1632 plansource->gplan->is_valid = false;
1636 * The generic plan, if any, could have more dependencies than the
1637 * querytree does, so we have to check it too.
1639 if (plansource->gplan && plansource->gplan->is_valid)
1643 foreach(lc, plansource->gplan->stmt_list)
1645 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1647 Assert(!IsA(plannedstmt, Query));
1648 if (!IsA(plannedstmt, PlannedStmt))
1649 continue; /* Ignore utility statements */
1650 if ((relid == InvalidOid) ? plannedstmt->relationOids != NIL :
1651 list_member_oid(plannedstmt->relationOids, relid))
1653 /* Invalidate the generic plan only */
1654 plansource->gplan->is_valid = false;
1655 break; /* out of stmt_list scan */
1663 * PlanCacheFuncCallback
1664 * Syscache inval callback function for PROCOID cache
1666 * Invalidate all plans mentioning the object with the specified hash value,
1667 * or all plans mentioning any member of this cache if hashvalue == 0.
1669 * Note that the coding would support use for multiple caches, but right
1670 * now only user-defined functions are tracked this way.
1673 PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue)
1675 CachedPlanSource *plansource;
1677 for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
1681 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1683 /* No work if it's already invalidated */
1684 if (!plansource->is_valid)
1688 * Check the dependency list for the rewritten querytree.
1690 foreach(lc, plansource->invalItems)
1692 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
1694 if (item->cacheId != cacheid)
1696 if (hashvalue == 0 ||
1697 item->hashValue == hashvalue)
1699 /* Invalidate the querytree and generic plan */
1700 plansource->is_valid = false;
1701 if (plansource->gplan)
1702 plansource->gplan->is_valid = false;
1708 * The generic plan, if any, could have more dependencies than the
1709 * querytree does, so we have to check it too.
1711 if (plansource->gplan && plansource->gplan->is_valid)
1713 foreach(lc, plansource->gplan->stmt_list)
1715 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1718 Assert(!IsA(plannedstmt, Query));
1719 if (!IsA(plannedstmt, PlannedStmt))
1720 continue; /* Ignore utility statements */
1721 foreach(lc3, plannedstmt->invalItems)
1723 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc3);
1725 if (item->cacheId != cacheid)
1727 if (hashvalue == 0 ||
1728 item->hashValue == hashvalue)
1730 /* Invalidate the generic plan only */
1731 plansource->gplan->is_valid = false;
1732 break; /* out of invalItems scan */
1735 if (!plansource->gplan->is_valid)
1736 break; /* out of stmt_list scan */
1743 * PlanCacheSysCallback
1744 * Syscache inval callback function for other caches
1746 * Just invalidate everything...
1749 PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
1755 * ResetPlanCache: invalidate all cached plans.
1758 ResetPlanCache(void)
1760 CachedPlanSource *plansource;
1762 for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
1766 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1768 /* No work if it's already invalidated */
1769 if (!plansource->is_valid)
1773 * We *must not* mark transaction control statements as invalid,
1774 * particularly not ROLLBACK, because they may need to be executed in
1775 * aborted transactions when we can't revalidate them (cf bug #5269).
1776 * In general there is no point in invalidating utility statements
1777 * since they have no plans anyway. So invalidate it only if it
1778 * contains at least one non-utility statement, or contains a utility
1779 * statement that contains a pre-analyzed query (which could have
1782 foreach(lc, plansource->query_list)
1784 Query *query = (Query *) lfirst(lc);
1786 Assert(IsA(query, Query));
1787 if (query->commandType != CMD_UTILITY ||
1788 UtilityContainsQuery(query->utilityStmt))
1790 /* non-utility statement, so invalidate */
1791 plansource->is_valid = false;
1792 if (plansource->gplan)
1793 plansource->gplan->is_valid = false;
1794 /* no need to look further */