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. We also force re-analysis and
19 * re-planning if the active search_path is different from the previous time.
21 * Note that if the sinval was a result of user DDL actions, parse analysis
22 * could throw an error, for example if a column referenced by the query is
23 * no longer present. Another possibility is for the query's output tupdesc
24 * to change (for instance "SELECT *" might expand differently than before).
25 * The creator of a cached plan can specify whether it is allowable for the
26 * query to change output tupdesc on replan --- if so, it's up to the
27 * caller to notice changes and cope with them.
29 * Currently, we track exactly the dependencies of plans on relations and
30 * user-defined functions. On relcache invalidation events or pg_proc
31 * syscache invalidation events, we invalidate just those plans that depend
32 * on the particular object being modified. (Note: this scheme assumes
33 * that any table modification that requires replanning will generate a
34 * relcache inval event.) We also watch for inval events on certain other
35 * system catalogs, such as pg_namespace; but for them, our response is
36 * just to invalidate all plans. We expect updates on those catalogs to
37 * be infrequent enough that more-detailed tracking is not worth the effort.
40 * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
41 * Portions Copyright (c) 1994, Regents of the University of California
44 * src/backend/utils/cache/plancache.c
46 *-------------------------------------------------------------------------
52 #include "access/transam.h"
53 #include "catalog/namespace.h"
54 #include "executor/executor.h"
55 #include "executor/spi.h"
56 #include "nodes/nodeFuncs.h"
57 #include "optimizer/cost.h"
58 #include "optimizer/planmain.h"
59 #include "optimizer/prep.h"
60 #include "parser/analyze.h"
61 #include "parser/parsetree.h"
62 #include "storage/lmgr.h"
63 #include "tcop/pquery.h"
64 #include "tcop/utility.h"
65 #include "utils/inval.h"
66 #include "utils/memutils.h"
67 #include "utils/resowner_private.h"
68 #include "utils/snapmgr.h"
69 #include "utils/syscache.h"
73 * We must skip "overhead" operations that involve database access when the
74 * cached plan's subject statement is a transaction control command.
76 #define IsTransactionStmtPlan(plansource) \
77 ((plansource)->raw_parse_tree && \
78 IsA((plansource)->raw_parse_tree, TransactionStmt))
81 * This is the head of the backend's list of "saved" CachedPlanSources (i.e.,
82 * those that are in long-lived storage and are examined for sinval events).
83 * We thread the structs manually instead of using List cells so that we can
84 * guarantee to save a CachedPlanSource without error.
86 static CachedPlanSource *first_saved_plan = NULL;
88 static void ReleaseGenericPlan(CachedPlanSource *plansource);
89 static List *RevalidateCachedQuery(CachedPlanSource *plansource);
90 static bool CheckCachedPlan(CachedPlanSource *plansource);
91 static CachedPlan *BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
92 ParamListInfo boundParams);
93 static bool choose_custom_plan(CachedPlanSource *plansource,
94 ParamListInfo boundParams);
95 static double cached_plan_cost(CachedPlan *plan, bool include_planner);
96 static void AcquireExecutorLocks(List *stmt_list, bool acquire);
97 static void AcquirePlannerLocks(List *stmt_list, bool acquire);
98 static void ScanQueryForLocks(Query *parsetree, bool acquire);
99 static bool ScanQueryWalker(Node *node, bool *acquire);
100 static bool plan_list_is_transient(List *stmt_list);
101 static TupleDesc PlanCacheComputeResultDesc(List *stmt_list);
102 static void PlanCacheRelCallback(Datum arg, Oid relid);
103 static void PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue);
104 static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue);
108 * InitPlanCache: initialize module during InitPostgres.
110 * All we need to do is hook into inval.c's callback lists.
115 CacheRegisterRelcacheCallback(PlanCacheRelCallback, (Datum) 0);
116 CacheRegisterSyscacheCallback(PROCOID, PlanCacheFuncCallback, (Datum) 0);
117 CacheRegisterSyscacheCallback(NAMESPACEOID, PlanCacheSysCallback, (Datum) 0);
118 CacheRegisterSyscacheCallback(OPEROID, PlanCacheSysCallback, (Datum) 0);
119 CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum) 0);
123 * CreateCachedPlan: initially create a plan cache entry.
125 * Creation of a cached plan is divided into two steps, CreateCachedPlan and
126 * CompleteCachedPlan. CreateCachedPlan should be called after running the
127 * query through raw_parser, but before doing parse analysis and rewrite;
128 * CompleteCachedPlan is called after that. The reason for this arrangement
129 * is that it can save one round of copying of the raw parse tree, since
130 * the parser will normally scribble on the raw parse tree. Callers would
131 * otherwise need to make an extra copy of the parse tree to ensure they
132 * still had a clean copy to present at plan cache creation time.
134 * All arguments presented to CreateCachedPlan are copied into a memory
135 * context created as a child of the call-time CurrentMemoryContext, which
136 * should be a reasonably short-lived working context that will go away in
137 * event of an error. This ensures that the cached plan data structure will
138 * likewise disappear if an error occurs before we have fully constructed it.
139 * Once constructed, the cached plan can be made longer-lived, if needed,
140 * by calling SaveCachedPlan.
142 * raw_parse_tree: output of raw_parser()
143 * query_string: original query text
144 * commandTag: compile-time-constant tag for query, or NULL if empty query
147 CreateCachedPlan(Node *raw_parse_tree,
148 const char *query_string,
149 const char *commandTag)
151 CachedPlanSource *plansource;
152 MemoryContext source_context;
153 MemoryContext oldcxt;
155 Assert(query_string != NULL); /* required as of 8.4 */
158 * Make a dedicated memory context for the CachedPlanSource and its
159 * permanent subsidiary data. It's probably not going to be large, but
160 * just in case, use the default maxsize parameter. Initially it's a
161 * child of the caller's context (which we assume to be transient), so
162 * that it will be cleaned up on error.
164 source_context = AllocSetContextCreate(CurrentMemoryContext,
166 ALLOCSET_SMALL_MINSIZE,
167 ALLOCSET_SMALL_INITSIZE,
168 ALLOCSET_DEFAULT_MAXSIZE);
171 * Create and fill the CachedPlanSource struct within the new context.
172 * Most fields are just left empty for the moment.
174 oldcxt = MemoryContextSwitchTo(source_context);
176 plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
177 plansource->magic = CACHEDPLANSOURCE_MAGIC;
178 plansource->raw_parse_tree = copyObject(raw_parse_tree);
179 plansource->query_string = pstrdup(query_string);
180 plansource->commandTag = commandTag;
181 plansource->param_types = NULL;
182 plansource->num_params = 0;
183 plansource->parserSetup = NULL;
184 plansource->parserSetupArg = NULL;
185 plansource->cursor_options = 0;
186 plansource->fixed_result = false;
187 plansource->resultDesc = NULL;
188 plansource->context = source_context;
189 plansource->query_list = NIL;
190 plansource->relationOids = NIL;
191 plansource->invalItems = NIL;
192 plansource->search_path = NULL;
193 plansource->query_context = NULL;
194 plansource->gplan = NULL;
195 plansource->is_oneshot = false;
196 plansource->is_complete = false;
197 plansource->is_saved = false;
198 plansource->is_valid = false;
199 plansource->generation = 0;
200 plansource->next_saved = NULL;
201 plansource->generic_cost = -1;
202 plansource->total_custom_cost = 0;
203 plansource->num_custom_plans = 0;
205 MemoryContextSwitchTo(oldcxt);
211 * CreateOneShotCachedPlan: initially create a one-shot plan cache entry.
213 * This variant of CreateCachedPlan creates a plan cache entry that is meant
214 * to be used only once. No data copying occurs: all data structures remain
215 * in the caller's memory context (which typically should get cleared after
216 * completing execution). The CachedPlanSource struct itself is also created
219 * A one-shot plan cannot be saved or copied, since we make no effort to
220 * preserve the raw parse tree unmodified. There is also no support for
221 * invalidation, so plan use must be completed in the current transaction,
222 * and DDL that might invalidate the querytree_list must be avoided as well.
224 * raw_parse_tree: output of raw_parser()
225 * query_string: original query text
226 * commandTag: compile-time-constant tag for query, or NULL if empty query
229 CreateOneShotCachedPlan(Node *raw_parse_tree,
230 const char *query_string,
231 const char *commandTag)
233 CachedPlanSource *plansource;
235 Assert(query_string != NULL); /* required as of 8.4 */
238 * Create and fill the CachedPlanSource struct within the caller's memory
239 * context. Most fields are just left empty for the moment.
241 plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
242 plansource->magic = CACHEDPLANSOURCE_MAGIC;
243 plansource->raw_parse_tree = raw_parse_tree;
244 plansource->query_string = query_string;
245 plansource->commandTag = commandTag;
246 plansource->param_types = NULL;
247 plansource->num_params = 0;
248 plansource->parserSetup = NULL;
249 plansource->parserSetupArg = NULL;
250 plansource->cursor_options = 0;
251 plansource->fixed_result = false;
252 plansource->resultDesc = NULL;
253 plansource->context = CurrentMemoryContext;
254 plansource->query_list = NIL;
255 plansource->relationOids = NIL;
256 plansource->invalItems = NIL;
257 plansource->search_path = NULL;
258 plansource->query_context = NULL;
259 plansource->gplan = NULL;
260 plansource->is_oneshot = true;
261 plansource->is_complete = false;
262 plansource->is_saved = false;
263 plansource->is_valid = false;
264 plansource->generation = 0;
265 plansource->next_saved = NULL;
266 plansource->generic_cost = -1;
267 plansource->total_custom_cost = 0;
268 plansource->num_custom_plans = 0;
274 * CompleteCachedPlan: second step of creating a plan cache entry.
276 * Pass in the analyzed-and-rewritten form of the query, as well as the
277 * required subsidiary data about parameters and such. All passed values will
278 * be copied into the CachedPlanSource's memory, except as specified below.
279 * After this is called, GetCachedPlan can be called to obtain a plan, and
280 * optionally the CachedPlanSource can be saved using SaveCachedPlan.
282 * If querytree_context is not NULL, the querytree_list must be stored in that
283 * context (but the other parameters need not be). The querytree_list is not
284 * copied, rather the given context is kept as the initial query_context of
285 * the CachedPlanSource. (It should have been created as a child of the
286 * caller's working memory context, but it will now be reparented to belong
287 * to the CachedPlanSource.) The querytree_context is normally the context in
288 * which the caller did raw parsing and parse analysis. This approach saves
289 * one tree copying step compared to passing NULL, but leaves lots of extra
290 * cruft in the query_context, namely whatever extraneous stuff parse analysis
291 * created, as well as whatever went unused from the raw parse tree. Using
292 * this option is a space-for-time tradeoff that is appropriate if the
293 * CachedPlanSource is not expected to survive long.
295 * plancache.c cannot know how to copy the data referenced by parserSetupArg,
296 * and it would often be inappropriate to do so anyway. When using that
297 * option, it is caller's responsibility that the referenced data remains
298 * valid for as long as the CachedPlanSource exists.
300 * If the CachedPlanSource is a "oneshot" plan, then no querytree copying
301 * occurs at all, and querytree_context is ignored; it is caller's
302 * responsibility that the passed querytree_list is sufficiently long-lived.
304 * plansource: structure returned by CreateCachedPlan
305 * querytree_list: analyzed-and-rewritten form of query (list of Query nodes)
306 * querytree_context: memory context containing querytree_list,
307 * or NULL to copy querytree_list into a fresh context
308 * param_types: array of fixed parameter type OIDs, or NULL if none
309 * num_params: number of fixed parameters
310 * parserSetup: alternate method for handling query parameters
311 * parserSetupArg: data to pass to parserSetup
312 * cursor_options: options bitmask to pass to planner
313 * fixed_result: TRUE to disallow future changes in query's result tupdesc
316 CompleteCachedPlan(CachedPlanSource *plansource,
317 List *querytree_list,
318 MemoryContext querytree_context,
321 ParserSetupHook parserSetup,
322 void *parserSetupArg,
326 MemoryContext source_context = plansource->context;
327 MemoryContext oldcxt = CurrentMemoryContext;
329 /* Assert caller is doing things in a sane order */
330 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
331 Assert(!plansource->is_complete);
334 * If caller supplied a querytree_context, reparent it underneath the
335 * CachedPlanSource's context; otherwise, create a suitable context and
336 * copy the querytree_list into it. But no data copying should be done
337 * for one-shot plans; for those, assume the passed querytree_list is
338 * sufficiently long-lived.
340 if (plansource->is_oneshot)
342 querytree_context = CurrentMemoryContext;
344 else if (querytree_context != NULL)
346 MemoryContextSetParent(querytree_context, source_context);
347 MemoryContextSwitchTo(querytree_context);
351 /* Again, it's a good bet the querytree_context can be small */
352 querytree_context = AllocSetContextCreate(source_context,
354 ALLOCSET_SMALL_MINSIZE,
355 ALLOCSET_SMALL_INITSIZE,
356 ALLOCSET_DEFAULT_MAXSIZE);
357 MemoryContextSwitchTo(querytree_context);
358 querytree_list = (List *) copyObject(querytree_list);
361 plansource->query_context = querytree_context;
362 plansource->query_list = querytree_list;
364 if (!plansource->is_oneshot && !IsTransactionStmtPlan(plansource))
367 * Use the planner machinery to extract dependencies. Data is saved
368 * in query_context. (We assume that not a lot of extra cruft is
369 * created by this call.) We can skip this for one-shot plans, and
370 * transaction control commands have no such dependencies anyway.
372 extract_query_dependencies((Node *) querytree_list,
373 &plansource->relationOids,
374 &plansource->invalItems);
377 * Also save the current search_path in the query_context. (This
378 * should not generate much extra cruft either, since almost certainly
379 * the path is already valid.) Again, we don't really need this for
380 * one-shot plans; and we *must* skip this for transaction control
381 * commands, because this could result in catalog accesses.
383 plansource->search_path = GetOverrideSearchPath(querytree_context);
387 * Save the final parameter types (or other parameter specification data)
388 * into the source_context, as well as our other parameters. Also save
389 * the result tuple descriptor.
391 MemoryContextSwitchTo(source_context);
395 plansource->param_types = (Oid *) palloc(num_params * sizeof(Oid));
396 memcpy(plansource->param_types, param_types, num_params * sizeof(Oid));
399 plansource->param_types = NULL;
400 plansource->num_params = num_params;
401 plansource->parserSetup = parserSetup;
402 plansource->parserSetupArg = parserSetupArg;
403 plansource->cursor_options = cursor_options;
404 plansource->fixed_result = fixed_result;
405 plansource->resultDesc = PlanCacheComputeResultDesc(querytree_list);
407 MemoryContextSwitchTo(oldcxt);
409 plansource->is_complete = true;
410 plansource->is_valid = true;
414 * SaveCachedPlan: save a cached plan permanently
416 * This function moves the cached plan underneath CacheMemoryContext (making
417 * it live for the life of the backend, unless explicitly dropped), and adds
418 * it to the list of cached plans that are checked for invalidation when an
419 * sinval event occurs.
421 * This is guaranteed not to throw error, except for the caller-error case
422 * of trying to save a one-shot plan. Callers typically depend on that
423 * since this is called just before or just after adding a pointer to the
424 * CachedPlanSource to some permanent data structure of their own. Up until
425 * this is done, a CachedPlanSource is just transient data that will go away
426 * automatically on transaction abort.
429 SaveCachedPlan(CachedPlanSource *plansource)
431 /* Assert caller is doing things in a sane order */
432 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
433 Assert(plansource->is_complete);
434 Assert(!plansource->is_saved);
436 /* This seems worth a real test, though */
437 if (plansource->is_oneshot)
438 elog(ERROR, "cannot save one-shot cached plan");
441 * In typical use, this function would be called before generating any
442 * plans from the CachedPlanSource. If there is a generic plan, moving it
443 * into CacheMemoryContext would be pretty risky since it's unclear
444 * whether the caller has taken suitable care with making references
445 * long-lived. Best thing to do seems to be to discard the plan.
447 ReleaseGenericPlan(plansource);
450 * Reparent the source memory context under CacheMemoryContext so that it
451 * will live indefinitely. The query_context follows along since it's
452 * already a child of the other one.
454 MemoryContextSetParent(plansource->context, CacheMemoryContext);
457 * Add the entry to the global list of cached plans.
459 plansource->next_saved = first_saved_plan;
460 first_saved_plan = plansource;
462 plansource->is_saved = true;
466 * DropCachedPlan: destroy a cached plan.
468 * Actually this only destroys the CachedPlanSource: any referenced CachedPlan
469 * is released, but not destroyed until its refcount goes to zero. That
470 * handles the situation where DropCachedPlan is called while the plan is
474 DropCachedPlan(CachedPlanSource *plansource)
476 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
478 /* If it's been saved, remove it from the list */
479 if (plansource->is_saved)
481 if (first_saved_plan == plansource)
482 first_saved_plan = plansource->next_saved;
485 CachedPlanSource *psrc;
487 for (psrc = first_saved_plan; psrc; psrc = psrc->next_saved)
489 if (psrc->next_saved == plansource)
491 psrc->next_saved = plansource->next_saved;
496 plansource->is_saved = false;
499 /* Decrement generic CachePlan's refcount and drop if no longer needed */
500 ReleaseGenericPlan(plansource);
502 /* Mark it no longer valid */
503 plansource->magic = 0;
506 * Remove the CachedPlanSource and all subsidiary data (including the
507 * query_context if any). But if it's a one-shot we can't free anything.
509 if (!plansource->is_oneshot)
510 MemoryContextDelete(plansource->context);
514 * ReleaseGenericPlan: release a CachedPlanSource's generic plan, if any.
517 ReleaseGenericPlan(CachedPlanSource *plansource)
519 /* Be paranoid about the possibility that ReleaseCachedPlan fails */
520 if (plansource->gplan)
522 CachedPlan *plan = plansource->gplan;
524 Assert(plan->magic == CACHEDPLAN_MAGIC);
525 plansource->gplan = NULL;
526 ReleaseCachedPlan(plan, false);
531 * RevalidateCachedQuery: ensure validity of analyzed-and-rewritten query tree.
533 * What we do here is re-acquire locks and redo parse analysis if necessary.
534 * On return, the query_list is valid and we have sufficient locks to begin
537 * If any parse analysis activity is required, the caller's memory context is
538 * used for that work.
540 * The result value is the transient analyzed-and-rewritten query tree if we
541 * had to do re-analysis, and NIL otherwise. (This is returned just to save
542 * a tree copying step in a subsequent BuildCachedPlan call.)
545 RevalidateCachedQuery(CachedPlanSource *plansource)
549 List *tlist; /* transient query-tree list */
550 List *qlist; /* permanent query-tree list */
551 TupleDesc resultDesc;
552 MemoryContext querytree_context;
553 MemoryContext oldcxt;
556 * For one-shot plans, we do not support revalidation checking; it's
557 * assumed the query is parsed, planned, and executed in one transaction,
558 * so that no lock re-acquisition is necessary. Also, there is never any
559 * need to revalidate plans for transaction control commands (and we
560 * mustn't risk any catalog accesses when handling those).
562 if (plansource->is_oneshot || IsTransactionStmtPlan(plansource))
564 Assert(plansource->is_valid);
569 * If the query is currently valid, we should have a saved search_path ---
570 * check to see if that matches the current environment. If not, we want
573 if (plansource->is_valid)
575 Assert(plansource->search_path != NULL);
576 if (!OverrideSearchPathMatchesCurrent(plansource->search_path))
578 /* Invalidate the querytree and generic plan */
579 plansource->is_valid = false;
580 if (plansource->gplan)
581 plansource->gplan->is_valid = false;
586 * If the query is currently valid, acquire locks on the referenced
587 * objects; then check again. We need to do it this way to cover the race
588 * condition that an invalidation message arrives before we get the locks.
590 if (plansource->is_valid)
592 AcquirePlannerLocks(plansource->query_list, true);
595 * By now, if any invalidation has happened, the inval callback
596 * functions will have marked the query invalid.
598 if (plansource->is_valid)
600 /* Successfully revalidated and locked the query. */
604 /* Ooops, the race case happened. Release useless locks. */
605 AcquirePlannerLocks(plansource->query_list, false);
609 * Discard the no-longer-useful query tree. (Note: we don't want to do
610 * this any earlier, else we'd not have been able to release locks
611 * correctly in the race condition case.)
613 plansource->is_valid = false;
614 plansource->query_list = NIL;
615 plansource->relationOids = NIL;
616 plansource->invalItems = NIL;
617 plansource->search_path = NULL;
620 * Free the query_context. We don't really expect MemoryContextDelete to
621 * fail, but just in case, make sure the CachedPlanSource is left in a
622 * reasonably sane state. (The generic plan won't get unlinked yet, but
623 * that's acceptable.)
625 if (plansource->query_context)
627 MemoryContext qcxt = plansource->query_context;
629 plansource->query_context = NULL;
630 MemoryContextDelete(qcxt);
633 /* Drop the generic plan reference if any */
634 ReleaseGenericPlan(plansource);
637 * Now re-do parse analysis and rewrite. This not incidentally acquires
638 * the locks we need to do planning safely.
640 Assert(plansource->is_complete);
643 * If a snapshot is already set (the normal case), we can just use that
644 * for parsing/planning. But if it isn't, install one. Note: no point in
645 * checking whether parse analysis requires a snapshot; utility commands
646 * don't have invalidatable plans, so we'd not get here for such a
649 snapshot_set = false;
650 if (!ActiveSnapshotSet())
652 PushActiveSnapshot(GetTransactionSnapshot());
657 * Run parse analysis and rule rewriting. The parser tends to scribble on
658 * its input, so we must copy the raw parse tree to prevent corruption of
661 rawtree = copyObject(plansource->raw_parse_tree);
662 if (plansource->parserSetup != NULL)
663 tlist = pg_analyze_and_rewrite_params(rawtree,
664 plansource->query_string,
665 plansource->parserSetup,
666 plansource->parserSetupArg);
668 tlist = pg_analyze_and_rewrite(rawtree,
669 plansource->query_string,
670 plansource->param_types,
671 plansource->num_params);
673 /* Release snapshot if we got one */
678 * Check or update the result tupdesc. XXX should we use a weaker
679 * condition than equalTupleDescs() here?
681 * We assume the parameter types didn't change from the first time, so no
682 * need to update that.
684 resultDesc = PlanCacheComputeResultDesc(tlist);
685 if (resultDesc == NULL && plansource->resultDesc == NULL)
687 /* OK, doesn't return tuples */
689 else if (resultDesc == NULL || plansource->resultDesc == NULL ||
690 !equalTupleDescs(resultDesc, plansource->resultDesc))
692 /* can we give a better error message? */
693 if (plansource->fixed_result)
695 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
696 errmsg("cached plan must not change result type")));
697 oldcxt = MemoryContextSwitchTo(plansource->context);
699 resultDesc = CreateTupleDescCopy(resultDesc);
700 if (plansource->resultDesc)
701 FreeTupleDesc(plansource->resultDesc);
702 plansource->resultDesc = resultDesc;
703 MemoryContextSwitchTo(oldcxt);
707 * Allocate new query_context and copy the completed querytree into it.
708 * It's transient until we complete the copying and dependency extraction.
710 querytree_context = AllocSetContextCreate(CurrentMemoryContext,
712 ALLOCSET_SMALL_MINSIZE,
713 ALLOCSET_SMALL_INITSIZE,
714 ALLOCSET_DEFAULT_MAXSIZE);
715 oldcxt = MemoryContextSwitchTo(querytree_context);
717 qlist = (List *) copyObject(tlist);
720 * Use the planner machinery to extract dependencies. Data is saved in
721 * query_context. (We assume that not a lot of extra cruft is created by
724 extract_query_dependencies((Node *) qlist,
725 &plansource->relationOids,
726 &plansource->invalItems);
729 * Also save the current search_path in the query_context. (This should
730 * not generate much extra cruft either, since almost certainly the path
733 plansource->search_path = GetOverrideSearchPath(querytree_context);
735 MemoryContextSwitchTo(oldcxt);
737 /* Now reparent the finished query_context and save the links */
738 MemoryContextSetParent(querytree_context, plansource->context);
740 plansource->query_context = querytree_context;
741 plansource->query_list = qlist;
744 * Note: we do not reset generic_cost or total_custom_cost, although we
745 * could choose to do so. If the DDL or statistics change that prompted
746 * the invalidation meant a significant change in the cost estimates, it
747 * would be better to reset those variables and start fresh; but often it
748 * doesn't, and we're better retaining our hard-won knowledge about the
752 plansource->is_valid = true;
754 /* Return transient copy of querytrees for possible use in planning */
759 * CheckCachedPlan: see if the CachedPlanSource's generic plan is valid.
761 * Caller must have already called RevalidateCachedQuery to verify that the
762 * querytree is up to date.
764 * On a "true" return, we have acquired the locks needed to run the plan.
765 * (We must do this for the "true" result to be race-condition-free.)
768 CheckCachedPlan(CachedPlanSource *plansource)
770 CachedPlan *plan = plansource->gplan;
772 /* Assert that caller checked the querytree */
773 Assert(plansource->is_valid);
775 /* If there's no generic plan, just say "false" */
779 Assert(plan->magic == CACHEDPLAN_MAGIC);
780 /* Generic plans are never one-shot */
781 Assert(!plan->is_oneshot);
784 * If it appears valid, acquire locks and recheck; this is much the same
785 * logic as in RevalidateCachedQuery, but for a plan.
790 * Plan must have positive refcount because it is referenced by
791 * plansource; so no need to fear it disappears under us here.
793 Assert(plan->refcount > 0);
795 AcquireExecutorLocks(plan->stmt_list, true);
798 * If plan was transient, check to see if TransactionXmin has
799 * advanced, and if so invalidate it.
801 if (plan->is_valid &&
802 TransactionIdIsValid(plan->saved_xmin) &&
803 !TransactionIdEquals(plan->saved_xmin, TransactionXmin))
804 plan->is_valid = false;
807 * By now, if any invalidation has happened, the inval callback
808 * functions will have marked the plan invalid.
812 /* Successfully revalidated and locked the query. */
816 /* Ooops, the race case happened. Release useless locks. */
817 AcquireExecutorLocks(plan->stmt_list, false);
821 * Plan has been invalidated, so unlink it from the parent and release it.
823 ReleaseGenericPlan(plansource);
829 * BuildCachedPlan: construct a new CachedPlan from a CachedPlanSource.
831 * qlist should be the result value from a previous RevalidateCachedQuery,
832 * or it can be set to NIL if we need to re-copy the plansource's query_list.
834 * To build a generic, parameter-value-independent plan, pass NULL for
835 * boundParams. To build a custom plan, pass the actual parameter values via
836 * boundParams. For best effect, the PARAM_FLAG_CONST flag should be set on
837 * each parameter value; otherwise the planner will treat the value as a
838 * hint rather than a hard constant.
840 * Planning work is done in the caller's memory context. The finished plan
841 * is in a child memory context, which typically should get reparented
842 * (unless this is a one-shot plan, in which case we don't copy the plan).
845 BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
846 ParamListInfo boundParams)
852 MemoryContext plan_context;
853 MemoryContext oldcxt = CurrentMemoryContext;
856 * Normally the querytree should be valid already, but if it's not,
859 * NOTE: GetCachedPlan should have called RevalidateCachedQuery first, so
860 * we ought to be holding sufficient locks to prevent any invalidation.
861 * However, if we're building a custom plan after having built and
862 * rejected a generic plan, it's possible to reach here with is_valid
863 * false due to an invalidation while making the generic plan. In theory
864 * the invalidation must be a false positive, perhaps a consequence of an
865 * sinval reset event or the CLOBBER_CACHE_ALWAYS debug code. But for
866 * safety, let's treat it as real and redo the RevalidateCachedQuery call.
868 if (!plansource->is_valid)
869 qlist = RevalidateCachedQuery(plansource);
872 * If we don't already have a copy of the querytree list that can be
873 * scribbled on by the planner, make one. For a one-shot plan, we assume
874 * it's okay to scribble on the original query_list.
878 if (!plansource->is_oneshot)
879 qlist = (List *) copyObject(plansource->query_list);
881 qlist = plansource->query_list;
885 * If a snapshot is already set (the normal case), we can just use that
886 * for planning. But if it isn't, and we need one, install one.
888 snapshot_set = false;
889 if (!ActiveSnapshotSet() &&
890 analyze_requires_snapshot(plansource->raw_parse_tree))
892 PushActiveSnapshot(GetTransactionSnapshot());
897 * The planner may try to call SPI-using functions, which causes a problem
898 * if we're already inside one. Rather than expect all SPI-using code to
899 * do SPI_push whenever a replan could happen, it seems best to take care
902 spi_pushed = SPI_push_conditional();
907 plist = pg_plan_queries(qlist, plansource->cursor_options, boundParams);
909 /* Clean up SPI state */
910 SPI_pop_conditional(spi_pushed);
912 /* Release snapshot if we got one */
917 * Normally we make a dedicated memory context for the CachedPlan and its
918 * subsidiary data. (It's probably not going to be large, but just in
919 * case, use the default maxsize parameter. It's transient for the
920 * moment.) But for a one-shot plan, we just leave it in the caller's
923 if (!plansource->is_oneshot)
925 plan_context = AllocSetContextCreate(CurrentMemoryContext,
927 ALLOCSET_SMALL_MINSIZE,
928 ALLOCSET_SMALL_INITSIZE,
929 ALLOCSET_DEFAULT_MAXSIZE);
932 * Copy plan into the new context.
934 MemoryContextSwitchTo(plan_context);
936 plist = (List *) copyObject(plist);
939 plan_context = CurrentMemoryContext;
942 * Create and fill the CachedPlan struct within the new context.
944 plan = (CachedPlan *) palloc(sizeof(CachedPlan));
945 plan->magic = CACHEDPLAN_MAGIC;
946 plan->stmt_list = plist;
947 if (plan_list_is_transient(plist))
949 Assert(TransactionIdIsNormal(TransactionXmin));
950 plan->saved_xmin = TransactionXmin;
953 plan->saved_xmin = InvalidTransactionId;
955 plan->context = plan_context;
956 plan->is_oneshot = plansource->is_oneshot;
957 plan->is_saved = false;
958 plan->is_valid = true;
960 /* assign generation number to new plan */
961 plan->generation = ++(plansource->generation);
963 MemoryContextSwitchTo(oldcxt);
969 * choose_custom_plan: choose whether to use custom or generic plan
971 * This defines the policy followed by GetCachedPlan.
974 choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams)
976 double avg_custom_cost;
978 /* One-shot plans will always be considered custom */
979 if (plansource->is_oneshot)
982 /* Otherwise, never any point in a custom plan if there's no parameters */
983 if (boundParams == NULL)
985 /* ... nor for transaction control statements */
986 if (IsTransactionStmtPlan(plansource))
989 /* See if caller wants to force the decision */
990 if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN)
992 if (plansource->cursor_options & CURSOR_OPT_CUSTOM_PLAN)
995 /* Generate custom plans until we have done at least 5 (arbitrary) */
996 if (plansource->num_custom_plans < 5)
999 avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans;
1002 * Prefer generic plan if it's less expensive than the average custom
1003 * plan. (Because we include a charge for cost of planning in the
1004 * custom-plan costs, this means the generic plan only has to be less
1005 * expensive than the execution cost plus replan cost of the custom
1008 * Note that if generic_cost is -1 (indicating we've not yet determined
1009 * the generic plan cost), we'll always prefer generic at this point.
1011 if (plansource->generic_cost < avg_custom_cost)
1018 * cached_plan_cost: calculate estimated cost of a plan
1020 * If include_planner is true, also include the estimated cost of constructing
1021 * the plan. (We must factor that into the cost of using a custom plan, but
1022 * we don't count it for a generic plan.)
1025 cached_plan_cost(CachedPlan *plan, bool include_planner)
1030 foreach(lc, plan->stmt_list)
1032 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1034 if (!IsA(plannedstmt, PlannedStmt))
1035 continue; /* Ignore utility statements */
1037 result += plannedstmt->planTree->total_cost;
1039 if (include_planner)
1042 * Currently we use a very crude estimate of planning effort based
1043 * on the number of relations in the finished plan's rangetable.
1044 * Join planning effort actually scales much worse than linearly
1045 * in the number of relations --- but only until the join collapse
1046 * limits kick in. Also, while inheritance child relations surely
1047 * add to planning effort, they don't make the join situation
1048 * worse. So the actual shape of the planning cost curve versus
1049 * number of relations isn't all that obvious. It will take
1050 * considerable work to arrive at a less crude estimate, and for
1051 * now it's not clear that's worth doing.
1053 * The other big difficulty here is that we don't have any very
1054 * good model of how planning cost compares to execution costs.
1055 * The current multiplier of 1000 * cpu_operator_cost is probably
1056 * on the low side, but we'll try this for awhile before making a
1057 * more aggressive correction.
1059 * If we ever do write a more complicated estimator, it should
1060 * probably live in src/backend/optimizer/ not here.
1062 int nrelations = list_length(plannedstmt->rtable);
1064 result += 1000.0 * cpu_operator_cost * (nrelations + 1);
1072 * GetCachedPlan: get a cached plan from a CachedPlanSource.
1074 * This function hides the logic that decides whether to use a generic
1075 * plan or a custom plan for the given parameters: the caller does not know
1076 * which it will get.
1078 * On return, the plan is valid and we have sufficient locks to begin
1081 * On return, the refcount of the plan has been incremented; a later
1082 * ReleaseCachedPlan() call is expected. The refcount has been reported
1083 * to the CurrentResourceOwner if useResOwner is true (note that that must
1084 * only be true if it's a "saved" CachedPlanSource).
1086 * Note: if any replanning activity is required, the caller's memory context
1087 * is used for that work.
1090 GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams,
1097 /* Assert caller is doing things in a sane order */
1098 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1099 Assert(plansource->is_complete);
1100 /* This seems worth a real test, though */
1101 if (useResOwner && !plansource->is_saved)
1102 elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
1104 /* Make sure the querytree list is valid and we have parse-time locks */
1105 qlist = RevalidateCachedQuery(plansource);
1107 /* Decide whether to use a custom plan */
1108 customplan = choose_custom_plan(plansource, boundParams);
1112 if (CheckCachedPlan(plansource))
1114 /* We want a generic plan, and we already have a valid one */
1115 plan = plansource->gplan;
1116 Assert(plan->magic == CACHEDPLAN_MAGIC);
1120 /* Build a new generic plan */
1121 plan = BuildCachedPlan(plansource, qlist, NULL);
1122 /* Just make real sure plansource->gplan is clear */
1123 ReleaseGenericPlan(plansource);
1124 /* Link the new generic plan into the plansource */
1125 plansource->gplan = plan;
1127 /* Immediately reparent into appropriate context */
1128 if (plansource->is_saved)
1130 /* saved plans all live under CacheMemoryContext */
1131 MemoryContextSetParent(plan->context, CacheMemoryContext);
1132 plan->is_saved = true;
1136 /* otherwise, it should be a sibling of the plansource */
1137 MemoryContextSetParent(plan->context,
1138 MemoryContextGetParent(plansource->context));
1140 /* Update generic_cost whenever we make a new generic plan */
1141 plansource->generic_cost = cached_plan_cost(plan, false);
1144 * If, based on the now-known value of generic_cost, we'd not have
1145 * chosen to use a generic plan, then forget it and make a custom
1146 * plan. This is a bit of a wart but is necessary to avoid a
1147 * glitch in behavior when the custom plans are consistently big
1148 * winners; at some point we'll experiment with a generic plan and
1149 * find it's a loser, but we don't want to actually execute that
1152 customplan = choose_custom_plan(plansource, boundParams);
1155 * If we choose to plan again, we need to re-copy the query_list,
1156 * since the planner probably scribbled on it. We can force
1157 * BuildCachedPlan to do that by passing NIL.
1165 /* Build a custom plan */
1166 plan = BuildCachedPlan(plansource, qlist, boundParams);
1167 /* Accumulate total costs of custom plans, but 'ware overflow */
1168 if (plansource->num_custom_plans < INT_MAX)
1170 plansource->total_custom_cost += cached_plan_cost(plan, true);
1171 plansource->num_custom_plans++;
1175 /* Flag the plan as in use by caller */
1177 ResourceOwnerEnlargePlanCacheRefs(CurrentResourceOwner);
1180 ResourceOwnerRememberPlanCacheRef(CurrentResourceOwner, plan);
1183 * Saved plans should be under CacheMemoryContext so they will not go away
1184 * until their reference count goes to zero. In the generic-plan cases we
1185 * already took care of that, but for a custom plan, do it as soon as we
1186 * have created a reference-counted link.
1188 if (customplan && plansource->is_saved)
1190 MemoryContextSetParent(plan->context, CacheMemoryContext);
1191 plan->is_saved = true;
1198 * ReleaseCachedPlan: release active use of a cached plan.
1200 * This decrements the reference count, and frees the plan if the count
1201 * has thereby gone to zero. If useResOwner is true, it is assumed that
1202 * the reference count is managed by the CurrentResourceOwner.
1204 * Note: useResOwner = false is used for releasing references that are in
1205 * persistent data structures, such as the parent CachedPlanSource or a
1206 * Portal. Transient references should be protected by a resource owner.
1209 ReleaseCachedPlan(CachedPlan *plan, bool useResOwner)
1211 Assert(plan->magic == CACHEDPLAN_MAGIC);
1214 Assert(plan->is_saved);
1215 ResourceOwnerForgetPlanCacheRef(CurrentResourceOwner, plan);
1217 Assert(plan->refcount > 0);
1219 if (plan->refcount == 0)
1221 /* Mark it no longer valid */
1224 /* One-shot plans do not own their context, so we can't free them */
1225 if (!plan->is_oneshot)
1226 MemoryContextDelete(plan->context);
1231 * CachedPlanSetParentContext: move a CachedPlanSource to a new memory context
1233 * This can only be applied to unsaved plans; once saved, a plan always
1234 * lives underneath CacheMemoryContext.
1237 CachedPlanSetParentContext(CachedPlanSource *plansource,
1238 MemoryContext newcontext)
1240 /* Assert caller is doing things in a sane order */
1241 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1242 Assert(plansource->is_complete);
1244 /* These seem worth real tests, though */
1245 if (plansource->is_saved)
1246 elog(ERROR, "cannot move a saved cached plan to another context");
1247 if (plansource->is_oneshot)
1248 elog(ERROR, "cannot move a one-shot cached plan to another context");
1250 /* OK, let the caller keep the plan where he wishes */
1251 MemoryContextSetParent(plansource->context, newcontext);
1254 * The query_context needs no special handling, since it's a child of
1255 * plansource->context. But if there's a generic plan, it should be
1256 * maintained as a sibling of plansource->context.
1258 if (plansource->gplan)
1260 Assert(plansource->gplan->magic == CACHEDPLAN_MAGIC);
1261 MemoryContextSetParent(plansource->gplan->context, newcontext);
1266 * CopyCachedPlan: make a copy of a CachedPlanSource
1268 * This is a convenience routine that does the equivalent of
1269 * CreateCachedPlan + CompleteCachedPlan, using the data stored in the
1270 * input CachedPlanSource. The result is therefore "unsaved" (regardless
1271 * of the state of the source), and we don't copy any generic plan either.
1272 * The result will be currently valid, or not, the same as the source.
1275 CopyCachedPlan(CachedPlanSource *plansource)
1277 CachedPlanSource *newsource;
1278 MemoryContext source_context;
1279 MemoryContext querytree_context;
1280 MemoryContext oldcxt;
1282 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1283 Assert(plansource->is_complete);
1286 * One-shot plans can't be copied, because we haven't taken care that
1287 * parsing/planning didn't scribble on the raw parse tree or querytrees.
1289 if (plansource->is_oneshot)
1290 elog(ERROR, "cannot copy a one-shot cached plan");
1292 source_context = AllocSetContextCreate(CurrentMemoryContext,
1294 ALLOCSET_SMALL_MINSIZE,
1295 ALLOCSET_SMALL_INITSIZE,
1296 ALLOCSET_DEFAULT_MAXSIZE);
1298 oldcxt = MemoryContextSwitchTo(source_context);
1300 newsource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
1301 newsource->magic = CACHEDPLANSOURCE_MAGIC;
1302 newsource->raw_parse_tree = copyObject(plansource->raw_parse_tree);
1303 newsource->query_string = pstrdup(plansource->query_string);
1304 newsource->commandTag = plansource->commandTag;
1305 if (plansource->num_params > 0)
1307 newsource->param_types = (Oid *)
1308 palloc(plansource->num_params * sizeof(Oid));
1309 memcpy(newsource->param_types, plansource->param_types,
1310 plansource->num_params * sizeof(Oid));
1313 newsource->param_types = NULL;
1314 newsource->num_params = plansource->num_params;
1315 newsource->parserSetup = plansource->parserSetup;
1316 newsource->parserSetupArg = plansource->parserSetupArg;
1317 newsource->cursor_options = plansource->cursor_options;
1318 newsource->fixed_result = plansource->fixed_result;
1319 if (plansource->resultDesc)
1320 newsource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
1322 newsource->resultDesc = NULL;
1323 newsource->context = source_context;
1325 querytree_context = AllocSetContextCreate(source_context,
1327 ALLOCSET_SMALL_MINSIZE,
1328 ALLOCSET_SMALL_INITSIZE,
1329 ALLOCSET_DEFAULT_MAXSIZE);
1330 MemoryContextSwitchTo(querytree_context);
1331 newsource->query_list = (List *) copyObject(plansource->query_list);
1332 newsource->relationOids = (List *) copyObject(plansource->relationOids);
1333 newsource->invalItems = (List *) copyObject(plansource->invalItems);
1334 if (plansource->search_path)
1335 newsource->search_path = CopyOverrideSearchPath(plansource->search_path);
1336 newsource->query_context = querytree_context;
1338 newsource->gplan = NULL;
1340 newsource->is_oneshot = false;
1341 newsource->is_complete = true;
1342 newsource->is_saved = false;
1343 newsource->is_valid = plansource->is_valid;
1344 newsource->generation = plansource->generation;
1345 newsource->next_saved = NULL;
1347 /* We may as well copy any acquired cost knowledge */
1348 newsource->generic_cost = plansource->generic_cost;
1349 newsource->total_custom_cost = plansource->total_custom_cost;
1350 newsource->num_custom_plans = plansource->num_custom_plans;
1352 MemoryContextSwitchTo(oldcxt);
1358 * CachedPlanIsValid: test whether the rewritten querytree within a
1359 * CachedPlanSource is currently valid (that is, not marked as being in need
1362 * This result is only trustworthy (ie, free from race conditions) if
1363 * the caller has acquired locks on all the relations used in the plan.
1366 CachedPlanIsValid(CachedPlanSource *plansource)
1368 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1369 return plansource->is_valid;
1373 * CachedPlanGetTargetList: return tlist, if any, describing plan's output
1375 * The result is guaranteed up-to-date. However, it is local storage
1376 * within the cached plan, and may disappear next time the plan is updated.
1379 CachedPlanGetTargetList(CachedPlanSource *plansource)
1383 /* Assert caller is doing things in a sane order */
1384 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1385 Assert(plansource->is_complete);
1388 * No work needed if statement doesn't return tuples (we assume this
1389 * feature cannot be changed by an invalidation)
1391 if (plansource->resultDesc == NULL)
1394 /* Make sure the querytree list is valid and we have parse-time locks */
1395 RevalidateCachedQuery(plansource);
1397 /* Get the primary statement and find out what it returns */
1398 pstmt = PortalListGetPrimaryStmt(plansource->query_list);
1400 return FetchStatementTargetList(pstmt);
1404 * AcquireExecutorLocks: acquire locks needed for execution of a cached plan;
1405 * or release them if acquire is false.
1408 AcquireExecutorLocks(List *stmt_list, bool acquire)
1412 foreach(lc1, stmt_list)
1414 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc1);
1418 Assert(!IsA(plannedstmt, Query));
1419 if (!IsA(plannedstmt, PlannedStmt))
1422 * Ignore utility statements, except those (such as EXPLAIN) that
1423 * contain a parsed-but-not-planned query. Note: it's okay to use
1424 * ScanQueryForLocks, even though the query hasn't been through
1425 * rule rewriting, because rewriting doesn't change the query
1428 Query *query = UtilityContainsQuery((Node *) plannedstmt);
1431 ScanQueryForLocks(query, acquire);
1436 foreach(lc2, plannedstmt->rtable)
1438 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
1444 if (rte->rtekind != RTE_RELATION)
1448 * Acquire the appropriate type of lock on each relation OID. Note
1449 * that we don't actually try to open the rel, and hence will not
1450 * fail if it's been dropped entirely --- we'll just transiently
1451 * acquire a non-conflicting lock.
1453 if (list_member_int(plannedstmt->resultRelations, rt_index))
1454 lockmode = RowExclusiveLock;
1455 else if ((rc = get_plan_rowmark(plannedstmt->rowMarks, rt_index)) != NULL &&
1456 RowMarkRequiresRowShareLock(rc->markType))
1457 lockmode = RowShareLock;
1459 lockmode = AccessShareLock;
1462 LockRelationOid(rte->relid, lockmode);
1464 UnlockRelationOid(rte->relid, lockmode);
1470 * AcquirePlannerLocks: acquire locks needed for planning of a querytree list;
1471 * or release them if acquire is false.
1473 * Note that we don't actually try to open the relations, and hence will not
1474 * fail if one has been dropped entirely --- we'll just transiently acquire
1475 * a non-conflicting lock.
1478 AcquirePlannerLocks(List *stmt_list, bool acquire)
1482 foreach(lc, stmt_list)
1484 Query *query = (Query *) lfirst(lc);
1486 Assert(IsA(query, Query));
1488 if (query->commandType == CMD_UTILITY)
1490 /* Ignore utility statements, unless they contain a Query */
1491 query = UtilityContainsQuery(query->utilityStmt);
1493 ScanQueryForLocks(query, acquire);
1497 ScanQueryForLocks(query, acquire);
1502 * ScanQueryForLocks: recursively scan one Query for AcquirePlannerLocks.
1505 ScanQueryForLocks(Query *parsetree, bool acquire)
1510 /* Shouldn't get called on utility commands */
1511 Assert(parsetree->commandType != CMD_UTILITY);
1514 * First, process RTEs of the current query level.
1517 foreach(lc, parsetree->rtable)
1519 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
1523 switch (rte->rtekind)
1526 /* Acquire or release the appropriate type of lock */
1527 if (rt_index == parsetree->resultRelation)
1528 lockmode = RowExclusiveLock;
1529 else if (get_parse_rowmark(parsetree, rt_index) != NULL)
1530 lockmode = RowShareLock;
1532 lockmode = AccessShareLock;
1534 LockRelationOid(rte->relid, lockmode);
1536 UnlockRelationOid(rte->relid, lockmode);
1540 /* Recurse into subquery-in-FROM */
1541 ScanQueryForLocks(rte->subquery, acquire);
1545 /* ignore other types of RTEs */
1550 /* Recurse into subquery-in-WITH */
1551 foreach(lc, parsetree->cteList)
1553 CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
1555 ScanQueryForLocks((Query *) cte->ctequery, acquire);
1559 * Recurse into sublink subqueries, too. But we already did the ones in
1560 * the rtable and cteList.
1562 if (parsetree->hasSubLinks)
1564 query_tree_walker(parsetree, ScanQueryWalker,
1566 QTW_IGNORE_RC_SUBQUERIES);
1571 * Walker to find sublink subqueries for ScanQueryForLocks
1574 ScanQueryWalker(Node *node, bool *acquire)
1578 if (IsA(node, SubLink))
1580 SubLink *sub = (SubLink *) node;
1582 /* Do what we came for */
1583 ScanQueryForLocks((Query *) sub->subselect, *acquire);
1584 /* Fall through to process lefthand args of SubLink */
1588 * Do NOT recurse into Query nodes, because ScanQueryForLocks already
1589 * processed subselects of subselects for us.
1591 return expression_tree_walker(node, ScanQueryWalker,
1596 * plan_list_is_transient: check if any of the plans in the list are transient.
1599 plan_list_is_transient(List *stmt_list)
1603 foreach(lc, stmt_list)
1605 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1607 if (!IsA(plannedstmt, PlannedStmt))
1608 continue; /* Ignore utility statements */
1610 if (plannedstmt->transientPlan)
1618 * PlanCacheComputeResultDesc: given a list of analyzed-and-rewritten Queries,
1619 * determine the result tupledesc it will produce. Returns NULL if the
1620 * execution will not return tuples.
1622 * Note: the result is created or copied into current memory context.
1625 PlanCacheComputeResultDesc(List *stmt_list)
1629 switch (ChoosePortalStrategy(stmt_list))
1631 case PORTAL_ONE_SELECT:
1632 case PORTAL_ONE_MOD_WITH:
1633 query = (Query *) linitial(stmt_list);
1634 Assert(IsA(query, Query));
1635 return ExecCleanTypeFromTL(query->targetList, false);
1637 case PORTAL_ONE_RETURNING:
1638 query = (Query *) PortalListGetPrimaryStmt(stmt_list);
1639 Assert(IsA(query, Query));
1640 Assert(query->returningList);
1641 return ExecCleanTypeFromTL(query->returningList, false);
1643 case PORTAL_UTIL_SELECT:
1644 query = (Query *) linitial(stmt_list);
1645 Assert(IsA(query, Query));
1646 Assert(query->utilityStmt);
1647 return UtilityTupleDescriptor(query->utilityStmt);
1649 case PORTAL_MULTI_QUERY:
1650 /* will not return tuples */
1657 * PlanCacheRelCallback
1658 * Relcache inval callback function
1660 * Invalidate all plans mentioning the given rel, or all plans mentioning
1661 * any rel at all if relid == InvalidOid.
1664 PlanCacheRelCallback(Datum arg, Oid relid)
1666 CachedPlanSource *plansource;
1668 for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
1670 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1672 /* No work if it's already invalidated */
1673 if (!plansource->is_valid)
1676 /* Never invalidate transaction control commands */
1677 if (IsTransactionStmtPlan(plansource))
1681 * Check the dependency list for the rewritten querytree.
1683 if ((relid == InvalidOid) ? plansource->relationOids != NIL :
1684 list_member_oid(plansource->relationOids, relid))
1686 /* Invalidate the querytree and generic plan */
1687 plansource->is_valid = false;
1688 if (plansource->gplan)
1689 plansource->gplan->is_valid = false;
1693 * The generic plan, if any, could have more dependencies than the
1694 * querytree does, so we have to check it too.
1696 if (plansource->gplan && plansource->gplan->is_valid)
1700 foreach(lc, plansource->gplan->stmt_list)
1702 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1704 Assert(!IsA(plannedstmt, Query));
1705 if (!IsA(plannedstmt, PlannedStmt))
1706 continue; /* Ignore utility statements */
1707 if ((relid == InvalidOid) ? plannedstmt->relationOids != NIL :
1708 list_member_oid(plannedstmt->relationOids, relid))
1710 /* Invalidate the generic plan only */
1711 plansource->gplan->is_valid = false;
1712 break; /* out of stmt_list scan */
1720 * PlanCacheFuncCallback
1721 * Syscache inval callback function for PROCOID cache
1723 * Invalidate all plans mentioning the object with the specified hash value,
1724 * or all plans mentioning any member of this cache if hashvalue == 0.
1726 * Note that the coding would support use for multiple caches, but right
1727 * now only user-defined functions are tracked this way.
1730 PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue)
1732 CachedPlanSource *plansource;
1734 for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
1738 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1740 /* No work if it's already invalidated */
1741 if (!plansource->is_valid)
1744 /* Never invalidate transaction control commands */
1745 if (IsTransactionStmtPlan(plansource))
1749 * Check the dependency list for the rewritten querytree.
1751 foreach(lc, plansource->invalItems)
1753 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
1755 if (item->cacheId != cacheid)
1757 if (hashvalue == 0 ||
1758 item->hashValue == hashvalue)
1760 /* Invalidate the querytree and generic plan */
1761 plansource->is_valid = false;
1762 if (plansource->gplan)
1763 plansource->gplan->is_valid = false;
1769 * The generic plan, if any, could have more dependencies than the
1770 * querytree does, so we have to check it too.
1772 if (plansource->gplan && plansource->gplan->is_valid)
1774 foreach(lc, plansource->gplan->stmt_list)
1776 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1779 Assert(!IsA(plannedstmt, Query));
1780 if (!IsA(plannedstmt, PlannedStmt))
1781 continue; /* Ignore utility statements */
1782 foreach(lc3, plannedstmt->invalItems)
1784 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc3);
1786 if (item->cacheId != cacheid)
1788 if (hashvalue == 0 ||
1789 item->hashValue == hashvalue)
1791 /* Invalidate the generic plan only */
1792 plansource->gplan->is_valid = false;
1793 break; /* out of invalItems scan */
1796 if (!plansource->gplan->is_valid)
1797 break; /* out of stmt_list scan */
1804 * PlanCacheSysCallback
1805 * Syscache inval callback function for other caches
1807 * Just invalidate everything...
1810 PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
1816 * ResetPlanCache: invalidate all cached plans.
1819 ResetPlanCache(void)
1821 CachedPlanSource *plansource;
1823 for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
1827 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1829 /* No work if it's already invalidated */
1830 if (!plansource->is_valid)
1834 * We *must not* mark transaction control statements as invalid,
1835 * particularly not ROLLBACK, because they may need to be executed in
1836 * aborted transactions when we can't revalidate them (cf bug #5269).
1838 if (IsTransactionStmtPlan(plansource))
1842 * In general there is no point in invalidating utility statements
1843 * since they have no plans anyway. So invalidate it only if it
1844 * contains at least one non-utility statement, or contains a utility
1845 * statement that contains a pre-analyzed query (which could have
1848 foreach(lc, plansource->query_list)
1850 Query *query = (Query *) lfirst(lc);
1852 Assert(IsA(query, Query));
1853 if (query->commandType != CMD_UTILITY ||
1854 UtilityContainsQuery(query->utilityStmt))
1856 /* non-utility statement, so invalidate */
1857 plansource->is_valid = false;
1858 if (plansource->gplan)
1859 plansource->gplan->is_valid = false;
1860 /* no need to look further */