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
20 * or, if RLS is involved, if the user changes or the RLS environment changes.
22 * Note that if the sinval was a result of user DDL actions, parse analysis
23 * could throw an error, for example if a column referenced by the query is
24 * no longer present. Another possibility is for the query's output tupdesc
25 * to change (for instance "SELECT *" might expand differently than before).
26 * The creator of a cached plan can specify whether it is allowable for the
27 * query to change output tupdesc on replan --- if so, it's up to the
28 * caller to notice changes and cope with them.
30 * Currently, we track exactly the dependencies of plans on relations,
31 * user-defined functions, and domains. On relcache invalidation events or
32 * pg_proc or pg_type syscache invalidation events, we invalidate just those
33 * plans that depend on the particular object being modified. (Note: this
34 * scheme assumes that any table modification that requires replanning will
35 * generate a relcache inval event.) We also watch for inval events on
36 * certain other system catalogs, such as pg_namespace; but for them, our
37 * response is just to invalidate all plans. We expect updates on those
38 * catalogs to be infrequent enough that more-detailed tracking is not worth
41 * In addition to full-fledged query plans, we provide a facility for
42 * detecting invalidations of simple scalar expressions. This is fairly
43 * bare-bones; it's the caller's responsibility to build a new expression
44 * if the old one gets invalidated.
47 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
48 * Portions Copyright (c) 1994, Regents of the University of California
51 * src/backend/utils/cache/plancache.c
53 *-------------------------------------------------------------------------
59 #include "access/transam.h"
60 #include "catalog/namespace.h"
61 #include "executor/executor.h"
62 #include "miscadmin.h"
63 #include "nodes/nodeFuncs.h"
64 #include "optimizer/cost.h"
65 #include "optimizer/planmain.h"
66 #include "optimizer/planner.h"
67 #include "optimizer/prep.h"
68 #include "parser/analyze.h"
69 #include "parser/parsetree.h"
70 #include "storage/lmgr.h"
71 #include "tcop/pquery.h"
72 #include "tcop/utility.h"
73 #include "utils/inval.h"
74 #include "utils/memutils.h"
75 #include "utils/resowner_private.h"
76 #include "utils/rls.h"
77 #include "utils/snapmgr.h"
78 #include "utils/syscache.h"
82 * We must skip "overhead" operations that involve database access when the
83 * cached plan's subject statement is a transaction control command.
85 #define IsTransactionStmtPlan(plansource) \
86 ((plansource)->raw_parse_tree && \
87 IsA((plansource)->raw_parse_tree->stmt, TransactionStmt))
90 * This is the head of the backend's list of "saved" CachedPlanSources (i.e.,
91 * those that are in long-lived storage and are examined for sinval events).
92 * We use a dlist instead of separate List cells so that we can guarantee
93 * to save a CachedPlanSource without error.
95 static dlist_head saved_plan_list = DLIST_STATIC_INIT(saved_plan_list);
98 * This is the head of the backend's list of CachedExpressions.
100 static dlist_head cached_expression_list = DLIST_STATIC_INIT(cached_expression_list);
102 static void ReleaseGenericPlan(CachedPlanSource *plansource);
103 static List *RevalidateCachedQuery(CachedPlanSource *plansource,
104 QueryEnvironment *queryEnv);
105 static bool CheckCachedPlan(CachedPlanSource *plansource);
106 static CachedPlan *BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
107 ParamListInfo boundParams, QueryEnvironment *queryEnv);
108 static bool choose_custom_plan(CachedPlanSource *plansource,
109 ParamListInfo boundParams);
110 static double cached_plan_cost(CachedPlan *plan, bool include_planner);
111 static Query *QueryListGetPrimaryStmt(List *stmts);
112 static void AcquireExecutorLocks(List *stmt_list, bool acquire);
113 static void AcquirePlannerLocks(List *stmt_list, bool acquire);
114 static void ScanQueryForLocks(Query *parsetree, bool acquire);
115 static bool ScanQueryWalker(Node *node, bool *acquire);
116 static TupleDesc PlanCacheComputeResultDesc(List *stmt_list);
117 static void PlanCacheRelCallback(Datum arg, Oid relid);
118 static void PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue);
119 static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue);
125 * InitPlanCache: initialize module during InitPostgres.
127 * All we need to do is hook into inval.c's callback lists.
132 CacheRegisterRelcacheCallback(PlanCacheRelCallback, (Datum) 0);
133 CacheRegisterSyscacheCallback(PROCOID, PlanCacheObjectCallback, (Datum) 0);
134 CacheRegisterSyscacheCallback(TYPEOID, PlanCacheObjectCallback, (Datum) 0);
135 CacheRegisterSyscacheCallback(NAMESPACEOID, PlanCacheSysCallback, (Datum) 0);
136 CacheRegisterSyscacheCallback(OPEROID, PlanCacheSysCallback, (Datum) 0);
137 CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum) 0);
138 CacheRegisterSyscacheCallback(FOREIGNSERVEROID, PlanCacheSysCallback, (Datum) 0);
139 CacheRegisterSyscacheCallback(FOREIGNDATAWRAPPEROID, PlanCacheSysCallback, (Datum) 0);
143 * CreateCachedPlan: initially create a plan cache entry.
145 * Creation of a cached plan is divided into two steps, CreateCachedPlan and
146 * CompleteCachedPlan. CreateCachedPlan should be called after running the
147 * query through raw_parser, but before doing parse analysis and rewrite;
148 * CompleteCachedPlan is called after that. The reason for this arrangement
149 * is that it can save one round of copying of the raw parse tree, since
150 * the parser will normally scribble on the raw parse tree. Callers would
151 * otherwise need to make an extra copy of the parse tree to ensure they
152 * still had a clean copy to present at plan cache creation time.
154 * All arguments presented to CreateCachedPlan are copied into a memory
155 * context created as a child of the call-time CurrentMemoryContext, which
156 * should be a reasonably short-lived working context that will go away in
157 * event of an error. This ensures that the cached plan data structure will
158 * likewise disappear if an error occurs before we have fully constructed it.
159 * Once constructed, the cached plan can be made longer-lived, if needed,
160 * by calling SaveCachedPlan.
162 * raw_parse_tree: output of raw_parser(), or NULL if empty query
163 * query_string: original query text
164 * commandTag: compile-time-constant tag for query, or NULL if empty query
167 CreateCachedPlan(RawStmt *raw_parse_tree,
168 const char *query_string,
169 const char *commandTag)
171 CachedPlanSource *plansource;
172 MemoryContext source_context;
173 MemoryContext oldcxt;
175 Assert(query_string != NULL); /* required as of 8.4 */
178 * Make a dedicated memory context for the CachedPlanSource and its
179 * permanent subsidiary data. It's probably not going to be large, but
180 * just in case, allow it to grow large. Initially it's a child of the
181 * caller's context (which we assume to be transient), so that it will be
182 * cleaned up on error.
184 source_context = AllocSetContextCreate(CurrentMemoryContext,
186 ALLOCSET_START_SMALL_SIZES);
189 * Create and fill the CachedPlanSource struct within the new context.
190 * Most fields are just left empty for the moment.
192 oldcxt = MemoryContextSwitchTo(source_context);
194 plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
195 plansource->magic = CACHEDPLANSOURCE_MAGIC;
196 plansource->raw_parse_tree = copyObject(raw_parse_tree);
197 plansource->query_string = pstrdup(query_string);
198 MemoryContextSetIdentifier(source_context, plansource->query_string);
199 plansource->commandTag = commandTag;
200 plansource->param_types = NULL;
201 plansource->num_params = 0;
202 plansource->parserSetup = NULL;
203 plansource->parserSetupArg = NULL;
204 plansource->cursor_options = 0;
205 plansource->fixed_result = false;
206 plansource->resultDesc = NULL;
207 plansource->context = source_context;
208 plansource->query_list = NIL;
209 plansource->relationOids = NIL;
210 plansource->invalItems = NIL;
211 plansource->search_path = NULL;
212 plansource->query_context = NULL;
213 plansource->rewriteRoleId = InvalidOid;
214 plansource->rewriteRowSecurity = false;
215 plansource->dependsOnRLS = false;
216 plansource->gplan = NULL;
217 plansource->is_oneshot = false;
218 plansource->is_complete = false;
219 plansource->is_saved = false;
220 plansource->is_valid = false;
221 plansource->generation = 0;
222 plansource->generic_cost = -1;
223 plansource->total_custom_cost = 0;
224 plansource->num_custom_plans = 0;
226 MemoryContextSwitchTo(oldcxt);
232 * CreateOneShotCachedPlan: initially create a one-shot plan cache entry.
234 * This variant of CreateCachedPlan creates a plan cache entry that is meant
235 * to be used only once. No data copying occurs: all data structures remain
236 * in the caller's memory context (which typically should get cleared after
237 * completing execution). The CachedPlanSource struct itself is also created
240 * A one-shot plan cannot be saved or copied, since we make no effort to
241 * preserve the raw parse tree unmodified. There is also no support for
242 * invalidation, so plan use must be completed in the current transaction,
243 * and DDL that might invalidate the querytree_list must be avoided as well.
245 * raw_parse_tree: output of raw_parser(), or NULL if empty query
246 * query_string: original query text
247 * commandTag: compile-time-constant tag for query, or NULL if empty query
250 CreateOneShotCachedPlan(RawStmt *raw_parse_tree,
251 const char *query_string,
252 const char *commandTag)
254 CachedPlanSource *plansource;
256 Assert(query_string != NULL); /* required as of 8.4 */
259 * Create and fill the CachedPlanSource struct within the caller's memory
260 * context. Most fields are just left empty for the moment.
262 plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
263 plansource->magic = CACHEDPLANSOURCE_MAGIC;
264 plansource->raw_parse_tree = raw_parse_tree;
265 plansource->query_string = query_string;
266 plansource->commandTag = commandTag;
267 plansource->param_types = NULL;
268 plansource->num_params = 0;
269 plansource->parserSetup = NULL;
270 plansource->parserSetupArg = NULL;
271 plansource->cursor_options = 0;
272 plansource->fixed_result = false;
273 plansource->resultDesc = NULL;
274 plansource->context = CurrentMemoryContext;
275 plansource->query_list = NIL;
276 plansource->relationOids = NIL;
277 plansource->invalItems = NIL;
278 plansource->search_path = NULL;
279 plansource->query_context = NULL;
280 plansource->rewriteRoleId = InvalidOid;
281 plansource->rewriteRowSecurity = false;
282 plansource->dependsOnRLS = false;
283 plansource->gplan = NULL;
284 plansource->is_oneshot = true;
285 plansource->is_complete = false;
286 plansource->is_saved = false;
287 plansource->is_valid = false;
288 plansource->generation = 0;
289 plansource->generic_cost = -1;
290 plansource->total_custom_cost = 0;
291 plansource->num_custom_plans = 0;
297 * CompleteCachedPlan: second step of creating a plan cache entry.
299 * Pass in the analyzed-and-rewritten form of the query, as well as the
300 * required subsidiary data about parameters and such. All passed values will
301 * be copied into the CachedPlanSource's memory, except as specified below.
302 * After this is called, GetCachedPlan can be called to obtain a plan, and
303 * optionally the CachedPlanSource can be saved using SaveCachedPlan.
305 * If querytree_context is not NULL, the querytree_list must be stored in that
306 * context (but the other parameters need not be). The querytree_list is not
307 * copied, rather the given context is kept as the initial query_context of
308 * the CachedPlanSource. (It should have been created as a child of the
309 * caller's working memory context, but it will now be reparented to belong
310 * to the CachedPlanSource.) The querytree_context is normally the context in
311 * which the caller did raw parsing and parse analysis. This approach saves
312 * one tree copying step compared to passing NULL, but leaves lots of extra
313 * cruft in the query_context, namely whatever extraneous stuff parse analysis
314 * created, as well as whatever went unused from the raw parse tree. Using
315 * this option is a space-for-time tradeoff that is appropriate if the
316 * CachedPlanSource is not expected to survive long.
318 * plancache.c cannot know how to copy the data referenced by parserSetupArg,
319 * and it would often be inappropriate to do so anyway. When using that
320 * option, it is caller's responsibility that the referenced data remains
321 * valid for as long as the CachedPlanSource exists.
323 * If the CachedPlanSource is a "oneshot" plan, then no querytree copying
324 * occurs at all, and querytree_context is ignored; it is caller's
325 * responsibility that the passed querytree_list is sufficiently long-lived.
327 * plansource: structure returned by CreateCachedPlan
328 * querytree_list: analyzed-and-rewritten form of query (list of Query nodes)
329 * querytree_context: memory context containing querytree_list,
330 * or NULL to copy querytree_list into a fresh context
331 * param_types: array of fixed parameter type OIDs, or NULL if none
332 * num_params: number of fixed parameters
333 * parserSetup: alternate method for handling query parameters
334 * parserSetupArg: data to pass to parserSetup
335 * cursor_options: options bitmask to pass to planner
336 * fixed_result: true to disallow future changes in query's result tupdesc
339 CompleteCachedPlan(CachedPlanSource *plansource,
340 List *querytree_list,
341 MemoryContext querytree_context,
344 ParserSetupHook parserSetup,
345 void *parserSetupArg,
349 MemoryContext source_context = plansource->context;
350 MemoryContext oldcxt = CurrentMemoryContext;
352 /* Assert caller is doing things in a sane order */
353 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
354 Assert(!plansource->is_complete);
357 * If caller supplied a querytree_context, reparent it underneath the
358 * CachedPlanSource's context; otherwise, create a suitable context and
359 * copy the querytree_list into it. But no data copying should be done
360 * for one-shot plans; for those, assume the passed querytree_list is
361 * sufficiently long-lived.
363 if (plansource->is_oneshot)
365 querytree_context = CurrentMemoryContext;
367 else if (querytree_context != NULL)
369 MemoryContextSetParent(querytree_context, source_context);
370 MemoryContextSwitchTo(querytree_context);
374 /* Again, it's a good bet the querytree_context can be small */
375 querytree_context = AllocSetContextCreate(source_context,
377 ALLOCSET_START_SMALL_SIZES);
378 MemoryContextSwitchTo(querytree_context);
379 querytree_list = copyObject(querytree_list);
382 plansource->query_context = querytree_context;
383 plansource->query_list = querytree_list;
385 if (!plansource->is_oneshot && !IsTransactionStmtPlan(plansource))
388 * Use the planner machinery to extract dependencies. Data is saved
389 * in query_context. (We assume that not a lot of extra cruft is
390 * created by this call.) We can skip this for one-shot plans, and
391 * transaction control commands have no such dependencies anyway.
393 extract_query_dependencies((Node *) querytree_list,
394 &plansource->relationOids,
395 &plansource->invalItems,
396 &plansource->dependsOnRLS);
398 /* Update RLS info as well. */
399 plansource->rewriteRoleId = GetUserId();
400 plansource->rewriteRowSecurity = row_security;
403 * Also save the current search_path in the query_context. (This
404 * should not generate much extra cruft either, since almost certainly
405 * the path is already valid.) Again, we don't really need this for
406 * one-shot plans; and we *must* skip this for transaction control
407 * commands, because this could result in catalog accesses.
409 plansource->search_path = GetOverrideSearchPath(querytree_context);
413 * Save the final parameter types (or other parameter specification data)
414 * into the source_context, as well as our other parameters. Also save
415 * the result tuple descriptor.
417 MemoryContextSwitchTo(source_context);
421 plansource->param_types = (Oid *) palloc(num_params * sizeof(Oid));
422 memcpy(plansource->param_types, param_types, num_params * sizeof(Oid));
425 plansource->param_types = NULL;
426 plansource->num_params = num_params;
427 plansource->parserSetup = parserSetup;
428 plansource->parserSetupArg = parserSetupArg;
429 plansource->cursor_options = cursor_options;
430 plansource->fixed_result = fixed_result;
431 plansource->resultDesc = PlanCacheComputeResultDesc(querytree_list);
433 MemoryContextSwitchTo(oldcxt);
435 plansource->is_complete = true;
436 plansource->is_valid = true;
440 * SaveCachedPlan: save a cached plan permanently
442 * This function moves the cached plan underneath CacheMemoryContext (making
443 * it live for the life of the backend, unless explicitly dropped), and adds
444 * it to the list of cached plans that are checked for invalidation when an
445 * sinval event occurs.
447 * This is guaranteed not to throw error, except for the caller-error case
448 * of trying to save a one-shot plan. Callers typically depend on that
449 * since this is called just before or just after adding a pointer to the
450 * CachedPlanSource to some permanent data structure of their own. Up until
451 * this is done, a CachedPlanSource is just transient data that will go away
452 * automatically on transaction abort.
455 SaveCachedPlan(CachedPlanSource *plansource)
457 /* Assert caller is doing things in a sane order */
458 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
459 Assert(plansource->is_complete);
460 Assert(!plansource->is_saved);
462 /* This seems worth a real test, though */
463 if (plansource->is_oneshot)
464 elog(ERROR, "cannot save one-shot cached plan");
467 * In typical use, this function would be called before generating any
468 * plans from the CachedPlanSource. If there is a generic plan, moving it
469 * into CacheMemoryContext would be pretty risky since it's unclear
470 * whether the caller has taken suitable care with making references
471 * long-lived. Best thing to do seems to be to discard the plan.
473 ReleaseGenericPlan(plansource);
476 * Reparent the source memory context under CacheMemoryContext so that it
477 * will live indefinitely. The query_context follows along since it's
478 * already a child of the other one.
480 MemoryContextSetParent(plansource->context, CacheMemoryContext);
483 * Add the entry to the global list of cached plans.
485 dlist_push_tail(&saved_plan_list, &plansource->node);
487 plansource->is_saved = true;
491 * DropCachedPlan: destroy a cached plan.
493 * Actually this only destroys the CachedPlanSource: any referenced CachedPlan
494 * is released, but not destroyed until its refcount goes to zero. That
495 * handles the situation where DropCachedPlan is called while the plan is
499 DropCachedPlan(CachedPlanSource *plansource)
501 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
503 /* If it's been saved, remove it from the list */
504 if (plansource->is_saved)
506 dlist_delete(&plansource->node);
507 plansource->is_saved = false;
510 /* Decrement generic CachePlan's refcount and drop if no longer needed */
511 ReleaseGenericPlan(plansource);
513 /* Mark it no longer valid */
514 plansource->magic = 0;
517 * Remove the CachedPlanSource and all subsidiary data (including the
518 * query_context if any). But if it's a one-shot we can't free anything.
520 if (!plansource->is_oneshot)
521 MemoryContextDelete(plansource->context);
525 * ReleaseGenericPlan: release a CachedPlanSource's generic plan, if any.
528 ReleaseGenericPlan(CachedPlanSource *plansource)
530 /* Be paranoid about the possibility that ReleaseCachedPlan fails */
531 if (plansource->gplan)
533 CachedPlan *plan = plansource->gplan;
535 Assert(plan->magic == CACHEDPLAN_MAGIC);
536 plansource->gplan = NULL;
537 ReleaseCachedPlan(plan, false);
542 * RevalidateCachedQuery: ensure validity of analyzed-and-rewritten query tree.
544 * What we do here is re-acquire locks and redo parse analysis if necessary.
545 * On return, the query_list is valid and we have sufficient locks to begin
548 * If any parse analysis activity is required, the caller's memory context is
549 * used for that work.
551 * The result value is the transient analyzed-and-rewritten query tree if we
552 * had to do re-analysis, and NIL otherwise. (This is returned just to save
553 * a tree copying step in a subsequent BuildCachedPlan call.)
556 RevalidateCachedQuery(CachedPlanSource *plansource,
557 QueryEnvironment *queryEnv)
561 List *tlist; /* transient query-tree list */
562 List *qlist; /* permanent query-tree list */
563 TupleDesc resultDesc;
564 MemoryContext querytree_context;
565 MemoryContext oldcxt;
568 * For one-shot plans, we do not support revalidation checking; it's
569 * assumed the query is parsed, planned, and executed in one transaction,
570 * so that no lock re-acquisition is necessary. Also, there is never any
571 * need to revalidate plans for transaction control commands (and we
572 * mustn't risk any catalog accesses when handling those).
574 if (plansource->is_oneshot || IsTransactionStmtPlan(plansource))
576 Assert(plansource->is_valid);
581 * If the query is currently valid, we should have a saved search_path ---
582 * check to see if that matches the current environment. If not, we want
585 if (plansource->is_valid)
587 Assert(plansource->search_path != NULL);
588 if (!OverrideSearchPathMatchesCurrent(plansource->search_path))
590 /* Invalidate the querytree and generic plan */
591 plansource->is_valid = false;
592 if (plansource->gplan)
593 plansource->gplan->is_valid = false;
598 * If the query rewrite phase had a possible RLS dependency, we must redo
599 * it if either the role or the row_security setting has changed.
601 if (plansource->is_valid && plansource->dependsOnRLS &&
602 (plansource->rewriteRoleId != GetUserId() ||
603 plansource->rewriteRowSecurity != row_security))
604 plansource->is_valid = false;
607 * If the query is currently valid, acquire locks on the referenced
608 * objects; then check again. We need to do it this way to cover the race
609 * condition that an invalidation message arrives before we get the locks.
611 if (plansource->is_valid)
613 AcquirePlannerLocks(plansource->query_list, true);
616 * By now, if any invalidation has happened, the inval callback
617 * functions will have marked the query invalid.
619 if (plansource->is_valid)
621 /* Successfully revalidated and locked the query. */
625 /* Oops, the race case happened. Release useless locks. */
626 AcquirePlannerLocks(plansource->query_list, false);
630 * Discard the no-longer-useful query tree. (Note: we don't want to do
631 * this any earlier, else we'd not have been able to release locks
632 * correctly in the race condition case.)
634 plansource->is_valid = false;
635 plansource->query_list = NIL;
636 plansource->relationOids = NIL;
637 plansource->invalItems = NIL;
638 plansource->search_path = NULL;
641 * Free the query_context. We don't really expect MemoryContextDelete to
642 * fail, but just in case, make sure the CachedPlanSource is left in a
643 * reasonably sane state. (The generic plan won't get unlinked yet, but
644 * that's acceptable.)
646 if (plansource->query_context)
648 MemoryContext qcxt = plansource->query_context;
650 plansource->query_context = NULL;
651 MemoryContextDelete(qcxt);
654 /* Drop the generic plan reference if any */
655 ReleaseGenericPlan(plansource);
658 * Now re-do parse analysis and rewrite. This not incidentally acquires
659 * the locks we need to do planning safely.
661 Assert(plansource->is_complete);
664 * If a snapshot is already set (the normal case), we can just use that
665 * for parsing/planning. But if it isn't, install one. Note: no point in
666 * checking whether parse analysis requires a snapshot; utility commands
667 * don't have invalidatable plans, so we'd not get here for such a
670 snapshot_set = false;
671 if (!ActiveSnapshotSet())
673 PushActiveSnapshot(GetTransactionSnapshot());
678 * Run parse analysis and rule rewriting. The parser tends to scribble on
679 * its input, so we must copy the raw parse tree to prevent corruption of
682 rawtree = copyObject(plansource->raw_parse_tree);
685 else if (plansource->parserSetup != NULL)
686 tlist = pg_analyze_and_rewrite_params(rawtree,
687 plansource->query_string,
688 plansource->parserSetup,
689 plansource->parserSetupArg,
692 tlist = pg_analyze_and_rewrite(rawtree,
693 plansource->query_string,
694 plansource->param_types,
695 plansource->num_params,
698 /* Release snapshot if we got one */
703 * Check or update the result tupdesc. XXX should we use a weaker
704 * condition than equalTupleDescs() here?
706 * We assume the parameter types didn't change from the first time, so no
707 * need to update that.
709 resultDesc = PlanCacheComputeResultDesc(tlist);
710 if (resultDesc == NULL && plansource->resultDesc == NULL)
712 /* OK, doesn't return tuples */
714 else if (resultDesc == NULL || plansource->resultDesc == NULL ||
715 !equalTupleDescs(resultDesc, plansource->resultDesc))
717 /* can we give a better error message? */
718 if (plansource->fixed_result)
720 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
721 errmsg("cached plan must not change result type")));
722 oldcxt = MemoryContextSwitchTo(plansource->context);
724 resultDesc = CreateTupleDescCopy(resultDesc);
725 if (plansource->resultDesc)
726 FreeTupleDesc(plansource->resultDesc);
727 plansource->resultDesc = resultDesc;
728 MemoryContextSwitchTo(oldcxt);
732 * Allocate new query_context and copy the completed querytree into it.
733 * It's transient until we complete the copying and dependency extraction.
735 querytree_context = AllocSetContextCreate(CurrentMemoryContext,
737 ALLOCSET_START_SMALL_SIZES);
738 oldcxt = MemoryContextSwitchTo(querytree_context);
740 qlist = copyObject(tlist);
743 * Use the planner machinery to extract dependencies. Data is saved in
744 * query_context. (We assume that not a lot of extra cruft is created by
747 extract_query_dependencies((Node *) qlist,
748 &plansource->relationOids,
749 &plansource->invalItems,
750 &plansource->dependsOnRLS);
752 /* Update RLS info as well. */
753 plansource->rewriteRoleId = GetUserId();
754 plansource->rewriteRowSecurity = row_security;
757 * Also save the current search_path in the query_context. (This should
758 * not generate much extra cruft either, since almost certainly the path
761 plansource->search_path = GetOverrideSearchPath(querytree_context);
763 MemoryContextSwitchTo(oldcxt);
765 /* Now reparent the finished query_context and save the links */
766 MemoryContextSetParent(querytree_context, plansource->context);
768 plansource->query_context = querytree_context;
769 plansource->query_list = qlist;
772 * Note: we do not reset generic_cost or total_custom_cost, although we
773 * could choose to do so. If the DDL or statistics change that prompted
774 * the invalidation meant a significant change in the cost estimates, it
775 * would be better to reset those variables and start fresh; but often it
776 * doesn't, and we're better retaining our hard-won knowledge about the
780 plansource->is_valid = true;
782 /* Return transient copy of querytrees for possible use in planning */
787 * CheckCachedPlan: see if the CachedPlanSource's generic plan is valid.
789 * Caller must have already called RevalidateCachedQuery to verify that the
790 * querytree is up to date.
792 * On a "true" return, we have acquired the locks needed to run the plan.
793 * (We must do this for the "true" result to be race-condition-free.)
796 CheckCachedPlan(CachedPlanSource *plansource)
798 CachedPlan *plan = plansource->gplan;
800 /* Assert that caller checked the querytree */
801 Assert(plansource->is_valid);
803 /* If there's no generic plan, just say "false" */
807 Assert(plan->magic == CACHEDPLAN_MAGIC);
808 /* Generic plans are never one-shot */
809 Assert(!plan->is_oneshot);
812 * If plan isn't valid for current role, we can't use it.
814 if (plan->is_valid && plan->dependsOnRole &&
815 plan->planRoleId != GetUserId())
816 plan->is_valid = false;
819 * If it appears valid, acquire locks and recheck; this is much the same
820 * logic as in RevalidateCachedQuery, but for a plan.
825 * Plan must have positive refcount because it is referenced by
826 * plansource; so no need to fear it disappears under us here.
828 Assert(plan->refcount > 0);
830 AcquireExecutorLocks(plan->stmt_list, true);
833 * If plan was transient, check to see if TransactionXmin has
834 * advanced, and if so invalidate it.
836 if (plan->is_valid &&
837 TransactionIdIsValid(plan->saved_xmin) &&
838 !TransactionIdEquals(plan->saved_xmin, TransactionXmin))
839 plan->is_valid = false;
842 * By now, if any invalidation has happened, the inval callback
843 * functions will have marked the plan invalid.
847 /* Successfully revalidated and locked the query. */
851 /* Oops, the race case happened. Release useless locks. */
852 AcquireExecutorLocks(plan->stmt_list, false);
856 * Plan has been invalidated, so unlink it from the parent and release it.
858 ReleaseGenericPlan(plansource);
864 * BuildCachedPlan: construct a new CachedPlan from a CachedPlanSource.
866 * qlist should be the result value from a previous RevalidateCachedQuery,
867 * or it can be set to NIL if we need to re-copy the plansource's query_list.
869 * To build a generic, parameter-value-independent plan, pass NULL for
870 * boundParams. To build a custom plan, pass the actual parameter values via
871 * boundParams. For best effect, the PARAM_FLAG_CONST flag should be set on
872 * each parameter value; otherwise the planner will treat the value as a
873 * hint rather than a hard constant.
875 * Planning work is done in the caller's memory context. The finished plan
876 * is in a child memory context, which typically should get reparented
877 * (unless this is a one-shot plan, in which case we don't copy the plan).
880 BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
881 ParamListInfo boundParams, QueryEnvironment *queryEnv)
887 MemoryContext plan_context;
888 MemoryContext oldcxt = CurrentMemoryContext;
892 * Normally the querytree should be valid already, but if it's not,
895 * NOTE: GetCachedPlan should have called RevalidateCachedQuery first, so
896 * we ought to be holding sufficient locks to prevent any invalidation.
897 * However, if we're building a custom plan after having built and
898 * rejected a generic plan, it's possible to reach here with is_valid
899 * false due to an invalidation while making the generic plan. In theory
900 * the invalidation must be a false positive, perhaps a consequence of an
901 * sinval reset event or the CLOBBER_CACHE_ALWAYS debug code. But for
902 * safety, let's treat it as real and redo the RevalidateCachedQuery call.
904 if (!plansource->is_valid)
905 qlist = RevalidateCachedQuery(plansource, queryEnv);
908 * If we don't already have a copy of the querytree list that can be
909 * scribbled on by the planner, make one. For a one-shot plan, we assume
910 * it's okay to scribble on the original query_list.
914 if (!plansource->is_oneshot)
915 qlist = copyObject(plansource->query_list);
917 qlist = plansource->query_list;
921 * If a snapshot is already set (the normal case), we can just use that
922 * for planning. But if it isn't, and we need one, install one.
924 snapshot_set = false;
925 if (!ActiveSnapshotSet() &&
926 plansource->raw_parse_tree &&
927 analyze_requires_snapshot(plansource->raw_parse_tree))
929 PushActiveSnapshot(GetTransactionSnapshot());
936 plist = pg_plan_queries(qlist, plansource->cursor_options, boundParams);
938 /* Release snapshot if we got one */
943 * Normally we make a dedicated memory context for the CachedPlan and its
944 * subsidiary data. (It's probably not going to be large, but just in
945 * case, allow it to grow large. It's transient for the moment.) But for
946 * a one-shot plan, we just leave it in the caller's memory context.
948 if (!plansource->is_oneshot)
950 plan_context = AllocSetContextCreate(CurrentMemoryContext,
952 ALLOCSET_START_SMALL_SIZES);
953 MemoryContextCopyAndSetIdentifier(plan_context, plansource->query_string);
956 * Copy plan into the new context.
958 MemoryContextSwitchTo(plan_context);
960 plist = copyObject(plist);
963 plan_context = CurrentMemoryContext;
966 * Create and fill the CachedPlan struct within the new context.
968 plan = (CachedPlan *) palloc(sizeof(CachedPlan));
969 plan->magic = CACHEDPLAN_MAGIC;
970 plan->stmt_list = plist;
973 * CachedPlan is dependent on role either if RLS affected the rewrite
974 * phase or if a role dependency was injected during planning. And it's
975 * transient if any plan is marked so.
977 plan->planRoleId = GetUserId();
978 plan->dependsOnRole = plansource->dependsOnRLS;
979 is_transient = false;
982 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
984 if (plannedstmt->commandType == CMD_UTILITY)
985 continue; /* Ignore utility statements */
987 if (plannedstmt->transientPlan)
989 if (plannedstmt->dependsOnRole)
990 plan->dependsOnRole = true;
994 Assert(TransactionIdIsNormal(TransactionXmin));
995 plan->saved_xmin = TransactionXmin;
998 plan->saved_xmin = InvalidTransactionId;
1000 plan->context = plan_context;
1001 plan->is_oneshot = plansource->is_oneshot;
1002 plan->is_saved = false;
1003 plan->is_valid = true;
1005 /* assign generation number to new plan */
1006 plan->generation = ++(plansource->generation);
1008 MemoryContextSwitchTo(oldcxt);
1014 * choose_custom_plan: choose whether to use custom or generic plan
1016 * This defines the policy followed by GetCachedPlan.
1019 choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams)
1021 double avg_custom_cost;
1023 /* One-shot plans will always be considered custom */
1024 if (plansource->is_oneshot)
1027 /* Otherwise, never any point in a custom plan if there's no parameters */
1028 if (boundParams == NULL)
1030 /* ... nor for transaction control statements */
1031 if (IsTransactionStmtPlan(plansource))
1034 /* Let settings force the decision */
1035 if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_GENERIC_PLAN)
1037 if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN)
1040 /* See if caller wants to force the decision */
1041 if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN)
1043 if (plansource->cursor_options & CURSOR_OPT_CUSTOM_PLAN)
1046 /* Generate custom plans until we have done at least 5 (arbitrary) */
1047 if (plansource->num_custom_plans < 5)
1050 avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans;
1053 * Prefer generic plan if it's less expensive than the average custom
1054 * plan. (Because we include a charge for cost of planning in the
1055 * custom-plan costs, this means the generic plan only has to be less
1056 * expensive than the execution cost plus replan cost of the custom
1059 * Note that if generic_cost is -1 (indicating we've not yet determined
1060 * the generic plan cost), we'll always prefer generic at this point.
1062 if (plansource->generic_cost < avg_custom_cost)
1069 * cached_plan_cost: calculate estimated cost of a plan
1071 * If include_planner is true, also include the estimated cost of constructing
1072 * the plan. (We must factor that into the cost of using a custom plan, but
1073 * we don't count it for a generic plan.)
1076 cached_plan_cost(CachedPlan *plan, bool include_planner)
1081 foreach(lc, plan->stmt_list)
1083 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1085 if (plannedstmt->commandType == CMD_UTILITY)
1086 continue; /* Ignore utility statements */
1088 result += plannedstmt->planTree->total_cost;
1090 if (include_planner)
1093 * Currently we use a very crude estimate of planning effort based
1094 * on the number of relations in the finished plan's rangetable.
1095 * Join planning effort actually scales much worse than linearly
1096 * in the number of relations --- but only until the join collapse
1097 * limits kick in. Also, while inheritance child relations surely
1098 * add to planning effort, they don't make the join situation
1099 * worse. So the actual shape of the planning cost curve versus
1100 * number of relations isn't all that obvious. It will take
1101 * considerable work to arrive at a less crude estimate, and for
1102 * now it's not clear that's worth doing.
1104 * The other big difficulty here is that we don't have any very
1105 * good model of how planning cost compares to execution costs.
1106 * The current multiplier of 1000 * cpu_operator_cost is probably
1107 * on the low side, but we'll try this for awhile before making a
1108 * more aggressive correction.
1110 * If we ever do write a more complicated estimator, it should
1111 * probably live in src/backend/optimizer/ not here.
1113 int nrelations = list_length(plannedstmt->rtable);
1115 result += 1000.0 * cpu_operator_cost * (nrelations + 1);
1123 * GetCachedPlan: get a cached plan from a CachedPlanSource.
1125 * This function hides the logic that decides whether to use a generic
1126 * plan or a custom plan for the given parameters: the caller does not know
1127 * which it will get.
1129 * On return, the plan is valid and we have sufficient locks to begin
1132 * On return, the refcount of the plan has been incremented; a later
1133 * ReleaseCachedPlan() call is expected. The refcount has been reported
1134 * to the CurrentResourceOwner if useResOwner is true (note that that must
1135 * only be true if it's a "saved" CachedPlanSource).
1137 * Note: if any replanning activity is required, the caller's memory context
1138 * is used for that work.
1141 GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams,
1142 bool useResOwner, QueryEnvironment *queryEnv)
1144 CachedPlan *plan = NULL;
1148 /* Assert caller is doing things in a sane order */
1149 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1150 Assert(plansource->is_complete);
1151 /* This seems worth a real test, though */
1152 if (useResOwner && !plansource->is_saved)
1153 elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
1155 /* Make sure the querytree list is valid and we have parse-time locks */
1156 qlist = RevalidateCachedQuery(plansource, queryEnv);
1158 /* Decide whether to use a custom plan */
1159 customplan = choose_custom_plan(plansource, boundParams);
1163 if (CheckCachedPlan(plansource))
1165 /* We want a generic plan, and we already have a valid one */
1166 plan = plansource->gplan;
1167 Assert(plan->magic == CACHEDPLAN_MAGIC);
1171 /* Build a new generic plan */
1172 plan = BuildCachedPlan(plansource, qlist, NULL, queryEnv);
1173 /* Just make real sure plansource->gplan is clear */
1174 ReleaseGenericPlan(plansource);
1175 /* Link the new generic plan into the plansource */
1176 plansource->gplan = plan;
1178 /* Immediately reparent into appropriate context */
1179 if (plansource->is_saved)
1181 /* saved plans all live under CacheMemoryContext */
1182 MemoryContextSetParent(plan->context, CacheMemoryContext);
1183 plan->is_saved = true;
1187 /* otherwise, it should be a sibling of the plansource */
1188 MemoryContextSetParent(plan->context,
1189 MemoryContextGetParent(plansource->context));
1191 /* Update generic_cost whenever we make a new generic plan */
1192 plansource->generic_cost = cached_plan_cost(plan, false);
1195 * If, based on the now-known value of generic_cost, we'd not have
1196 * chosen to use a generic plan, then forget it and make a custom
1197 * plan. This is a bit of a wart but is necessary to avoid a
1198 * glitch in behavior when the custom plans are consistently big
1199 * winners; at some point we'll experiment with a generic plan and
1200 * find it's a loser, but we don't want to actually execute that
1203 customplan = choose_custom_plan(plansource, boundParams);
1206 * If we choose to plan again, we need to re-copy the query_list,
1207 * since the planner probably scribbled on it. We can force
1208 * BuildCachedPlan to do that by passing NIL.
1216 /* Build a custom plan */
1217 plan = BuildCachedPlan(plansource, qlist, boundParams, queryEnv);
1218 /* Accumulate total costs of custom plans, but 'ware overflow */
1219 if (plansource->num_custom_plans < INT_MAX)
1221 plansource->total_custom_cost += cached_plan_cost(plan, true);
1222 plansource->num_custom_plans++;
1226 Assert(plan != NULL);
1228 /* Flag the plan as in use by caller */
1230 ResourceOwnerEnlargePlanCacheRefs(CurrentResourceOwner);
1233 ResourceOwnerRememberPlanCacheRef(CurrentResourceOwner, plan);
1236 * Saved plans should be under CacheMemoryContext so they will not go away
1237 * until their reference count goes to zero. In the generic-plan cases we
1238 * already took care of that, but for a custom plan, do it as soon as we
1239 * have created a reference-counted link.
1241 if (customplan && plansource->is_saved)
1243 MemoryContextSetParent(plan->context, CacheMemoryContext);
1244 plan->is_saved = true;
1251 * ReleaseCachedPlan: release active use of a cached plan.
1253 * This decrements the reference count, and frees the plan if the count
1254 * has thereby gone to zero. If useResOwner is true, it is assumed that
1255 * the reference count is managed by the CurrentResourceOwner.
1257 * Note: useResOwner = false is used for releasing references that are in
1258 * persistent data structures, such as the parent CachedPlanSource or a
1259 * Portal. Transient references should be protected by a resource owner.
1262 ReleaseCachedPlan(CachedPlan *plan, bool useResOwner)
1264 Assert(plan->magic == CACHEDPLAN_MAGIC);
1267 Assert(plan->is_saved);
1268 ResourceOwnerForgetPlanCacheRef(CurrentResourceOwner, plan);
1270 Assert(plan->refcount > 0);
1272 if (plan->refcount == 0)
1274 /* Mark it no longer valid */
1277 /* One-shot plans do not own their context, so we can't free them */
1278 if (!plan->is_oneshot)
1279 MemoryContextDelete(plan->context);
1284 * CachedPlanSetParentContext: move a CachedPlanSource to a new memory context
1286 * This can only be applied to unsaved plans; once saved, a plan always
1287 * lives underneath CacheMemoryContext.
1290 CachedPlanSetParentContext(CachedPlanSource *plansource,
1291 MemoryContext newcontext)
1293 /* Assert caller is doing things in a sane order */
1294 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1295 Assert(plansource->is_complete);
1297 /* These seem worth real tests, though */
1298 if (plansource->is_saved)
1299 elog(ERROR, "cannot move a saved cached plan to another context");
1300 if (plansource->is_oneshot)
1301 elog(ERROR, "cannot move a one-shot cached plan to another context");
1303 /* OK, let the caller keep the plan where he wishes */
1304 MemoryContextSetParent(plansource->context, newcontext);
1307 * The query_context needs no special handling, since it's a child of
1308 * plansource->context. But if there's a generic plan, it should be
1309 * maintained as a sibling of plansource->context.
1311 if (plansource->gplan)
1313 Assert(plansource->gplan->magic == CACHEDPLAN_MAGIC);
1314 MemoryContextSetParent(plansource->gplan->context, newcontext);
1319 * CopyCachedPlan: make a copy of a CachedPlanSource
1321 * This is a convenience routine that does the equivalent of
1322 * CreateCachedPlan + CompleteCachedPlan, using the data stored in the
1323 * input CachedPlanSource. The result is therefore "unsaved" (regardless
1324 * of the state of the source), and we don't copy any generic plan either.
1325 * The result will be currently valid, or not, the same as the source.
1328 CopyCachedPlan(CachedPlanSource *plansource)
1330 CachedPlanSource *newsource;
1331 MemoryContext source_context;
1332 MemoryContext querytree_context;
1333 MemoryContext oldcxt;
1335 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1336 Assert(plansource->is_complete);
1339 * One-shot plans can't be copied, because we haven't taken care that
1340 * parsing/planning didn't scribble on the raw parse tree or querytrees.
1342 if (plansource->is_oneshot)
1343 elog(ERROR, "cannot copy a one-shot cached plan");
1345 source_context = AllocSetContextCreate(CurrentMemoryContext,
1347 ALLOCSET_START_SMALL_SIZES);
1349 oldcxt = MemoryContextSwitchTo(source_context);
1351 newsource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
1352 newsource->magic = CACHEDPLANSOURCE_MAGIC;
1353 newsource->raw_parse_tree = copyObject(plansource->raw_parse_tree);
1354 newsource->query_string = pstrdup(plansource->query_string);
1355 MemoryContextSetIdentifier(source_context, newsource->query_string);
1356 newsource->commandTag = plansource->commandTag;
1357 if (plansource->num_params > 0)
1359 newsource->param_types = (Oid *)
1360 palloc(plansource->num_params * sizeof(Oid));
1361 memcpy(newsource->param_types, plansource->param_types,
1362 plansource->num_params * sizeof(Oid));
1365 newsource->param_types = NULL;
1366 newsource->num_params = plansource->num_params;
1367 newsource->parserSetup = plansource->parserSetup;
1368 newsource->parserSetupArg = plansource->parserSetupArg;
1369 newsource->cursor_options = plansource->cursor_options;
1370 newsource->fixed_result = plansource->fixed_result;
1371 if (plansource->resultDesc)
1372 newsource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
1374 newsource->resultDesc = NULL;
1375 newsource->context = source_context;
1377 querytree_context = AllocSetContextCreate(source_context,
1379 ALLOCSET_START_SMALL_SIZES);
1380 MemoryContextSwitchTo(querytree_context);
1381 newsource->query_list = copyObject(plansource->query_list);
1382 newsource->relationOids = copyObject(plansource->relationOids);
1383 newsource->invalItems = copyObject(plansource->invalItems);
1384 if (plansource->search_path)
1385 newsource->search_path = CopyOverrideSearchPath(plansource->search_path);
1386 newsource->query_context = querytree_context;
1387 newsource->rewriteRoleId = plansource->rewriteRoleId;
1388 newsource->rewriteRowSecurity = plansource->rewriteRowSecurity;
1389 newsource->dependsOnRLS = plansource->dependsOnRLS;
1391 newsource->gplan = NULL;
1393 newsource->is_oneshot = false;
1394 newsource->is_complete = true;
1395 newsource->is_saved = false;
1396 newsource->is_valid = plansource->is_valid;
1397 newsource->generation = plansource->generation;
1399 /* We may as well copy any acquired cost knowledge */
1400 newsource->generic_cost = plansource->generic_cost;
1401 newsource->total_custom_cost = plansource->total_custom_cost;
1402 newsource->num_custom_plans = plansource->num_custom_plans;
1404 MemoryContextSwitchTo(oldcxt);
1410 * CachedPlanIsValid: test whether the rewritten querytree within a
1411 * CachedPlanSource is currently valid (that is, not marked as being in need
1414 * This result is only trustworthy (ie, free from race conditions) if
1415 * the caller has acquired locks on all the relations used in the plan.
1418 CachedPlanIsValid(CachedPlanSource *plansource)
1420 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1421 return plansource->is_valid;
1425 * CachedPlanGetTargetList: return tlist, if any, describing plan's output
1427 * The result is guaranteed up-to-date. However, it is local storage
1428 * within the cached plan, and may disappear next time the plan is updated.
1431 CachedPlanGetTargetList(CachedPlanSource *plansource,
1432 QueryEnvironment *queryEnv)
1436 /* Assert caller is doing things in a sane order */
1437 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1438 Assert(plansource->is_complete);
1441 * No work needed if statement doesn't return tuples (we assume this
1442 * feature cannot be changed by an invalidation)
1444 if (plansource->resultDesc == NULL)
1447 /* Make sure the querytree list is valid and we have parse-time locks */
1448 RevalidateCachedQuery(plansource, queryEnv);
1450 /* Get the primary statement and find out what it returns */
1451 pstmt = QueryListGetPrimaryStmt(plansource->query_list);
1453 return FetchStatementTargetList((Node *) pstmt);
1457 * GetCachedExpression: construct a CachedExpression for an expression.
1459 * This performs the same transformations on the expression as
1460 * expression_planner(), ie, convert an expression as emitted by parse
1461 * analysis to be ready to pass to the executor.
1463 * The result is stashed in a private, long-lived memory context.
1464 * (Note that this might leak a good deal of memory in the caller's
1465 * context before that.) The passed-in expr tree is not modified.
1468 GetCachedExpression(Node *expr)
1470 CachedExpression *cexpr;
1473 MemoryContext cexpr_context;
1474 MemoryContext oldcxt;
1477 * Pass the expression through the planner, and collect dependencies.
1478 * Everything built here is leaked in the caller's context; that's
1479 * intentional to minimize the size of the permanent data structure.
1481 expr = (Node *) expression_planner_with_deps((Expr *) expr,
1486 * Make a private memory context, and copy what we need into that. To
1487 * avoid leaking a long-lived context if we fail while copying data, we
1488 * initially make the context under the caller's context.
1490 cexpr_context = AllocSetContextCreate(CurrentMemoryContext,
1492 ALLOCSET_SMALL_SIZES);
1494 oldcxt = MemoryContextSwitchTo(cexpr_context);
1496 cexpr = (CachedExpression *) palloc(sizeof(CachedExpression));
1497 cexpr->magic = CACHEDEXPR_MAGIC;
1498 cexpr->expr = copyObject(expr);
1499 cexpr->is_valid = true;
1500 cexpr->relationOids = copyObject(relationOids);
1501 cexpr->invalItems = copyObject(invalItems);
1502 cexpr->context = cexpr_context;
1504 MemoryContextSwitchTo(oldcxt);
1507 * Reparent the expr's memory context under CacheMemoryContext so that it
1508 * will live indefinitely.
1510 MemoryContextSetParent(cexpr_context, CacheMemoryContext);
1513 * Add the entry to the global list of cached expressions.
1515 dlist_push_tail(&cached_expression_list, &cexpr->node);
1521 * FreeCachedExpression
1522 * Delete a CachedExpression.
1525 FreeCachedExpression(CachedExpression *cexpr)
1528 Assert(cexpr->magic == CACHEDEXPR_MAGIC);
1529 /* Unlink from global list */
1530 dlist_delete(&cexpr->node);
1531 /* Free all storage associated with CachedExpression */
1532 MemoryContextDelete(cexpr->context);
1536 * QueryListGetPrimaryStmt
1537 * Get the "primary" stmt within a list, ie, the one marked canSetTag.
1539 * Returns NULL if no such stmt. If multiple queries within the list are
1540 * marked canSetTag, returns the first one. Neither of these cases should
1541 * occur in present usages of this function.
1544 QueryListGetPrimaryStmt(List *stmts)
1550 Query *stmt = lfirst_node(Query, lc);
1552 if (stmt->canSetTag)
1559 * AcquireExecutorLocks: acquire locks needed for execution of a cached plan;
1560 * or release them if acquire is false.
1563 AcquireExecutorLocks(List *stmt_list, bool acquire)
1567 foreach(lc1, stmt_list)
1569 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc1);
1572 if (plannedstmt->commandType == CMD_UTILITY)
1575 * Ignore utility statements, except those (such as EXPLAIN) that
1576 * contain a parsed-but-not-planned query. Note: it's okay to use
1577 * ScanQueryForLocks, even though the query hasn't been through
1578 * rule rewriting, because rewriting doesn't change the query
1581 Query *query = UtilityContainsQuery(plannedstmt->utilityStmt);
1584 ScanQueryForLocks(query, acquire);
1588 foreach(lc2, plannedstmt->rtable)
1590 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
1592 if (rte->rtekind != RTE_RELATION)
1596 * Acquire the appropriate type of lock on each relation OID. Note
1597 * that we don't actually try to open the rel, and hence will not
1598 * fail if it's been dropped entirely --- we'll just transiently
1599 * acquire a non-conflicting lock.
1602 LockRelationOid(rte->relid, rte->rellockmode);
1604 UnlockRelationOid(rte->relid, rte->rellockmode);
1610 * AcquirePlannerLocks: acquire locks needed for planning of a querytree list;
1611 * or release them if acquire is false.
1613 * Note that we don't actually try to open the relations, and hence will not
1614 * fail if one has been dropped entirely --- we'll just transiently acquire
1615 * a non-conflicting lock.
1618 AcquirePlannerLocks(List *stmt_list, bool acquire)
1622 foreach(lc, stmt_list)
1624 Query *query = lfirst_node(Query, lc);
1626 if (query->commandType == CMD_UTILITY)
1628 /* Ignore utility statements, unless they contain a Query */
1629 query = UtilityContainsQuery(query->utilityStmt);
1631 ScanQueryForLocks(query, acquire);
1635 ScanQueryForLocks(query, acquire);
1640 * ScanQueryForLocks: recursively scan one Query for AcquirePlannerLocks.
1643 ScanQueryForLocks(Query *parsetree, bool acquire)
1647 /* Shouldn't get called on utility commands */
1648 Assert(parsetree->commandType != CMD_UTILITY);
1651 * First, process RTEs of the current query level.
1653 foreach(lc, parsetree->rtable)
1655 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
1657 switch (rte->rtekind)
1660 /* Acquire or release the appropriate type of lock */
1662 LockRelationOid(rte->relid, rte->rellockmode);
1664 UnlockRelationOid(rte->relid, rte->rellockmode);
1668 /* Recurse into subquery-in-FROM */
1669 ScanQueryForLocks(rte->subquery, acquire);
1673 /* ignore other types of RTEs */
1678 /* Recurse into subquery-in-WITH */
1679 foreach(lc, parsetree->cteList)
1681 CommonTableExpr *cte = lfirst_node(CommonTableExpr, lc);
1683 ScanQueryForLocks(castNode(Query, cte->ctequery), acquire);
1687 * Recurse into sublink subqueries, too. But we already did the ones in
1688 * the rtable and cteList.
1690 if (parsetree->hasSubLinks)
1692 query_tree_walker(parsetree, ScanQueryWalker,
1694 QTW_IGNORE_RC_SUBQUERIES);
1699 * Walker to find sublink subqueries for ScanQueryForLocks
1702 ScanQueryWalker(Node *node, bool *acquire)
1706 if (IsA(node, SubLink))
1708 SubLink *sub = (SubLink *) node;
1710 /* Do what we came for */
1711 ScanQueryForLocks(castNode(Query, sub->subselect), *acquire);
1712 /* Fall through to process lefthand args of SubLink */
1716 * Do NOT recurse into Query nodes, because ScanQueryForLocks already
1717 * processed subselects of subselects for us.
1719 return expression_tree_walker(node, ScanQueryWalker,
1724 * PlanCacheComputeResultDesc: given a list of analyzed-and-rewritten Queries,
1725 * determine the result tupledesc it will produce. Returns NULL if the
1726 * execution will not return tuples.
1728 * Note: the result is created or copied into current memory context.
1731 PlanCacheComputeResultDesc(List *stmt_list)
1735 switch (ChoosePortalStrategy(stmt_list))
1737 case PORTAL_ONE_SELECT:
1738 case PORTAL_ONE_MOD_WITH:
1739 query = linitial_node(Query, stmt_list);
1740 return ExecCleanTypeFromTL(query->targetList);
1742 case PORTAL_ONE_RETURNING:
1743 query = QueryListGetPrimaryStmt(stmt_list);
1744 Assert(query->returningList);
1745 return ExecCleanTypeFromTL(query->returningList);
1747 case PORTAL_UTIL_SELECT:
1748 query = linitial_node(Query, stmt_list);
1749 Assert(query->utilityStmt);
1750 return UtilityTupleDescriptor(query->utilityStmt);
1752 case PORTAL_MULTI_QUERY:
1753 /* will not return tuples */
1760 * PlanCacheRelCallback
1761 * Relcache inval callback function
1763 * Invalidate all plans mentioning the given rel, or all plans mentioning
1764 * any rel at all if relid == InvalidOid.
1767 PlanCacheRelCallback(Datum arg, Oid relid)
1771 dlist_foreach(iter, &saved_plan_list)
1773 CachedPlanSource *plansource = dlist_container(CachedPlanSource,
1776 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1778 /* No work if it's already invalidated */
1779 if (!plansource->is_valid)
1782 /* Never invalidate transaction control commands */
1783 if (IsTransactionStmtPlan(plansource))
1787 * Check the dependency list for the rewritten querytree.
1789 if ((relid == InvalidOid) ? plansource->relationOids != NIL :
1790 list_member_oid(plansource->relationOids, relid))
1792 /* Invalidate the querytree and generic plan */
1793 plansource->is_valid = false;
1794 if (plansource->gplan)
1795 plansource->gplan->is_valid = false;
1799 * The generic plan, if any, could have more dependencies than the
1800 * querytree does, so we have to check it too.
1802 if (plansource->gplan && plansource->gplan->is_valid)
1806 foreach(lc, plansource->gplan->stmt_list)
1808 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1810 if (plannedstmt->commandType == CMD_UTILITY)
1811 continue; /* Ignore utility statements */
1812 if ((relid == InvalidOid) ? plannedstmt->relationOids != NIL :
1813 list_member_oid(plannedstmt->relationOids, relid))
1815 /* Invalidate the generic plan only */
1816 plansource->gplan->is_valid = false;
1817 break; /* out of stmt_list scan */
1823 /* Likewise check cached expressions */
1824 dlist_foreach(iter, &cached_expression_list)
1826 CachedExpression *cexpr = dlist_container(CachedExpression,
1829 Assert(cexpr->magic == CACHEDEXPR_MAGIC);
1831 /* No work if it's already invalidated */
1832 if (!cexpr->is_valid)
1835 if ((relid == InvalidOid) ? cexpr->relationOids != NIL :
1836 list_member_oid(cexpr->relationOids, relid))
1838 cexpr->is_valid = false;
1844 * PlanCacheObjectCallback
1845 * Syscache inval callback function for PROCOID and TYPEOID caches
1847 * Invalidate all plans mentioning the object with the specified hash value,
1848 * or all plans mentioning any member of this cache if hashvalue == 0.
1851 PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue)
1855 dlist_foreach(iter, &saved_plan_list)
1857 CachedPlanSource *plansource = dlist_container(CachedPlanSource,
1861 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1863 /* No work if it's already invalidated */
1864 if (!plansource->is_valid)
1867 /* Never invalidate transaction control commands */
1868 if (IsTransactionStmtPlan(plansource))
1872 * Check the dependency list for the rewritten querytree.
1874 foreach(lc, plansource->invalItems)
1876 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
1878 if (item->cacheId != cacheid)
1880 if (hashvalue == 0 ||
1881 item->hashValue == hashvalue)
1883 /* Invalidate the querytree and generic plan */
1884 plansource->is_valid = false;
1885 if (plansource->gplan)
1886 plansource->gplan->is_valid = false;
1892 * The generic plan, if any, could have more dependencies than the
1893 * querytree does, so we have to check it too.
1895 if (plansource->gplan && plansource->gplan->is_valid)
1897 foreach(lc, plansource->gplan->stmt_list)
1899 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1902 if (plannedstmt->commandType == CMD_UTILITY)
1903 continue; /* Ignore utility statements */
1904 foreach(lc3, plannedstmt->invalItems)
1906 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc3);
1908 if (item->cacheId != cacheid)
1910 if (hashvalue == 0 ||
1911 item->hashValue == hashvalue)
1913 /* Invalidate the generic plan only */
1914 plansource->gplan->is_valid = false;
1915 break; /* out of invalItems scan */
1918 if (!plansource->gplan->is_valid)
1919 break; /* out of stmt_list scan */
1924 /* Likewise check cached expressions */
1925 dlist_foreach(iter, &cached_expression_list)
1927 CachedExpression *cexpr = dlist_container(CachedExpression,
1931 Assert(cexpr->magic == CACHEDEXPR_MAGIC);
1933 /* No work if it's already invalidated */
1934 if (!cexpr->is_valid)
1937 foreach(lc, cexpr->invalItems)
1939 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
1941 if (item->cacheId != cacheid)
1943 if (hashvalue == 0 ||
1944 item->hashValue == hashvalue)
1946 cexpr->is_valid = false;
1954 * PlanCacheSysCallback
1955 * Syscache inval callback function for other caches
1957 * Just invalidate everything...
1960 PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
1966 * ResetPlanCache: invalidate all cached plans.
1969 ResetPlanCache(void)
1973 dlist_foreach(iter, &saved_plan_list)
1975 CachedPlanSource *plansource = dlist_container(CachedPlanSource,
1979 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1981 /* No work if it's already invalidated */
1982 if (!plansource->is_valid)
1986 * We *must not* mark transaction control statements as invalid,
1987 * particularly not ROLLBACK, because they may need to be executed in
1988 * aborted transactions when we can't revalidate them (cf bug #5269).
1990 if (IsTransactionStmtPlan(plansource))
1994 * In general there is no point in invalidating utility statements
1995 * since they have no plans anyway. So invalidate it only if it
1996 * contains at least one non-utility statement, or contains a utility
1997 * statement that contains a pre-analyzed query (which could have
2000 foreach(lc, plansource->query_list)
2002 Query *query = lfirst_node(Query, lc);
2004 if (query->commandType != CMD_UTILITY ||
2005 UtilityContainsQuery(query->utilityStmt))
2007 /* non-utility statement, so invalidate */
2008 plansource->is_valid = false;
2009 if (plansource->gplan)
2010 plansource->gplan->is_valid = false;
2011 /* no need to look further */
2017 /* Likewise invalidate cached expressions */
2018 dlist_foreach(iter, &cached_expression_list)
2020 CachedExpression *cexpr = dlist_container(CachedExpression,
2023 Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2025 cexpr->is_valid = false;