PostgreSQL Source Code git master
plancache.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * plancache.c
4 * Plan cache management.
5 *
6 * The plan cache manager has two principal responsibilities: deciding when
7 * to use a generic plan versus a custom (parameter-value-specific) plan,
8 * and tracking whether cached plans need to be invalidated because of schema
9 * changes in the objects they depend on.
10 *
11 * The logic for choosing generic or custom plans is in choose_custom_plan,
12 * which see for comments.
13 *
14 * Cache invalidation is driven off sinval events. Any CachedPlanSource
15 * that matches the event is marked invalid, as is its generic CachedPlan
16 * if it has one. When (and if) the next demand for a cached plan occurs,
17 * parse analysis and/or rewrite is repeated to build a new valid query tree,
18 * and then planning is performed as normal. We also force re-analysis and
19 * re-planning if the active search_path is different from the previous time
20 * or, if RLS is involved, if the user changes or the RLS environment changes.
21 *
22 * Note that if the sinval was a result of user DDL actions, parse analysis
23 * could throw an error, for example if a column referenced by the query is
24 * no longer present. Another possibility is for the query's output tupdesc
25 * to change (for instance "SELECT *" might expand differently than before).
26 * The creator of a cached plan can specify whether it is allowable for the
27 * query to change output tupdesc on replan --- if so, it's up to the
28 * caller to notice changes and cope with them.
29 *
30 * Currently, we track exactly the dependencies of plans on relations,
31 * user-defined functions, and domains. On relcache invalidation events or
32 * pg_proc or pg_type syscache invalidation events, we invalidate just those
33 * plans that depend on the particular object being modified. (Note: this
34 * scheme assumes that any table modification that requires replanning will
35 * generate a relcache inval event.) We also watch for inval events on
36 * certain other system catalogs, such as pg_namespace; but for them, our
37 * response is just to invalidate all plans. We expect updates on those
38 * catalogs to be infrequent enough that more-detailed tracking is not worth
39 * the effort.
40 *
41 * In addition to full-fledged query plans, we provide a facility for
42 * detecting invalidations of simple scalar expressions. This is fairly
43 * bare-bones; it's the caller's responsibility to build a new expression
44 * if the old one gets invalidated.
45 *
46 *
47 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
48 * Portions Copyright (c) 1994, Regents of the University of California
49 *
50 * IDENTIFICATION
51 * src/backend/utils/cache/plancache.c
52 *
53 *-------------------------------------------------------------------------
54 */
55#include "postgres.h"
56
57#include <limits.h>
58
59#include "access/transam.h"
60#include "catalog/namespace.h"
61#include "executor/executor.h"
62#include "miscadmin.h"
63#include "nodes/nodeFuncs.h"
64#include "optimizer/optimizer.h"
65#include "parser/analyze.h"
67#include "storage/lmgr.h"
68#include "tcop/pquery.h"
69#include "tcop/utility.h"
70#include "utils/inval.h"
71#include "utils/memutils.h"
72#include "utils/resowner.h"
73#include "utils/rls.h"
74#include "utils/snapmgr.h"
75#include "utils/syscache.h"
76
77
78/*
79 * This is the head of the backend's list of "saved" CachedPlanSources (i.e.,
80 * those that are in long-lived storage and are examined for sinval events).
81 * We use a dlist instead of separate List cells so that we can guarantee
82 * to save a CachedPlanSource without error.
83 */
85
86/*
87 * This is the head of the backend's list of CachedExpressions.
88 */
90
91static void ReleaseGenericPlan(CachedPlanSource *plansource);
92static bool StmtPlanRequiresRevalidation(CachedPlanSource *plansource);
93static bool BuildingPlanRequiresSnapshot(CachedPlanSource *plansource);
95 QueryEnvironment *queryEnv);
96static bool CheckCachedPlan(CachedPlanSource *plansource);
97static CachedPlan *BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
98 ParamListInfo boundParams, QueryEnvironment *queryEnv);
99static bool choose_custom_plan(CachedPlanSource *plansource,
100 ParamListInfo boundParams);
101static double cached_plan_cost(CachedPlan *plan, bool include_planner);
102static Query *QueryListGetPrimaryStmt(List *stmts);
103static void AcquireExecutorLocks(List *stmt_list, bool acquire);
104static void AcquirePlannerLocks(List *stmt_list, bool acquire);
105static void ScanQueryForLocks(Query *parsetree, bool acquire);
106static bool ScanQueryWalker(Node *node, bool *acquire);
107static TupleDesc PlanCacheComputeResultDesc(List *stmt_list);
108static void PlanCacheRelCallback(Datum arg, Oid relid);
109static void PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue);
110static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue);
111
112/* ResourceOwner callbacks to track plancache references */
113static void ResOwnerReleaseCachedPlan(Datum res);
114
116{
117 .name = "plancache reference",
118 .release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
119 .release_priority = RELEASE_PRIO_PLANCACHE_REFS,
120 .ReleaseResource = ResOwnerReleaseCachedPlan,
121 .DebugPrint = NULL /* the default message is fine */
122};
123
124/* Convenience wrappers over ResourceOwnerRemember/Forget */
125static inline void
127{
129}
130static inline void
132{
134}
135
136
137/* GUC parameter */
139
140/*
141 * InitPlanCache: initialize module during InitPostgres.
142 *
143 * All we need to do is hook into inval.c's callback lists.
144 */
145void
147{
155 CacheRegisterSyscacheCallback(FOREIGNDATAWRAPPEROID, PlanCacheSysCallback, (Datum) 0);
156}
157
158/*
159 * CreateCachedPlan: initially create a plan cache entry for a raw parse tree.
160 *
161 * Creation of a cached plan is divided into two steps, CreateCachedPlan and
162 * CompleteCachedPlan. CreateCachedPlan should be called after running the
163 * query through raw_parser, but before doing parse analysis and rewrite;
164 * CompleteCachedPlan is called after that. The reason for this arrangement
165 * is that it can save one round of copying of the raw parse tree, since
166 * the parser will normally scribble on the raw parse tree. Callers would
167 * otherwise need to make an extra copy of the parse tree to ensure they
168 * still had a clean copy to present at plan cache creation time.
169 *
170 * All arguments presented to CreateCachedPlan are copied into a memory
171 * context created as a child of the call-time CurrentMemoryContext, which
172 * should be a reasonably short-lived working context that will go away in
173 * event of an error. This ensures that the cached plan data structure will
174 * likewise disappear if an error occurs before we have fully constructed it.
175 * Once constructed, the cached plan can be made longer-lived, if needed,
176 * by calling SaveCachedPlan.
177 *
178 * raw_parse_tree: output of raw_parser(), or NULL if empty query
179 * query_string: original query text
180 * commandTag: command tag for query, or UNKNOWN if empty query
181 */
183CreateCachedPlan(RawStmt *raw_parse_tree,
184 const char *query_string,
185 CommandTag commandTag)
186{
187 CachedPlanSource *plansource;
188 MemoryContext source_context;
189 MemoryContext oldcxt;
190
191 Assert(query_string != NULL); /* required as of 8.4 */
192
193 /*
194 * Make a dedicated memory context for the CachedPlanSource and its
195 * permanent subsidiary data. It's probably not going to be large, but
196 * just in case, allow it to grow large. Initially it's a child of the
197 * caller's context (which we assume to be transient), so that it will be
198 * cleaned up on error.
199 */
201 "CachedPlanSource",
203
204 /*
205 * Create and fill the CachedPlanSource struct within the new context.
206 * Most fields are just left empty for the moment.
207 */
208 oldcxt = MemoryContextSwitchTo(source_context);
209
210 plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
211 plansource->magic = CACHEDPLANSOURCE_MAGIC;
212 plansource->raw_parse_tree = copyObject(raw_parse_tree);
213 plansource->analyzed_parse_tree = NULL;
214 plansource->query_string = pstrdup(query_string);
215 MemoryContextSetIdentifier(source_context, plansource->query_string);
216 plansource->commandTag = commandTag;
217 plansource->param_types = NULL;
218 plansource->num_params = 0;
219 plansource->parserSetup = NULL;
220 plansource->parserSetupArg = NULL;
221 plansource->postRewrite = NULL;
222 plansource->postRewriteArg = NULL;
223 plansource->cursor_options = 0;
224 plansource->fixed_result = false;
225 plansource->resultDesc = NULL;
226 plansource->context = source_context;
227 plansource->query_list = NIL;
228 plansource->relationOids = NIL;
229 plansource->invalItems = NIL;
230 plansource->search_path = NULL;
231 plansource->query_context = NULL;
232 plansource->rewriteRoleId = InvalidOid;
233 plansource->rewriteRowSecurity = false;
234 plansource->dependsOnRLS = false;
235 plansource->gplan = NULL;
236 plansource->is_oneshot = false;
237 plansource->is_complete = false;
238 plansource->is_saved = false;
239 plansource->is_valid = false;
240 plansource->generation = 0;
241 plansource->generic_cost = -1;
242 plansource->total_custom_cost = 0;
243 plansource->num_generic_plans = 0;
244 plansource->num_custom_plans = 0;
245
246 MemoryContextSwitchTo(oldcxt);
247
248 return plansource;
249}
250
251/*
252 * CreateCachedPlanForQuery: initially create a plan cache entry for a Query.
253 *
254 * This is used in the same way as CreateCachedPlan, except that the source
255 * query has already been through parse analysis, and the plancache will never
256 * try to re-do that step.
257 *
258 * Currently this is used only for new-style SQL functions, where we have a
259 * Query from the function's prosqlbody, but no source text. The query_string
260 * is typically empty, but is required anyway.
261 */
263CreateCachedPlanForQuery(Query *analyzed_parse_tree,
264 const char *query_string,
265 CommandTag commandTag)
266{
267 CachedPlanSource *plansource;
268 MemoryContext oldcxt;
269
270 /* Rather than duplicating CreateCachedPlan, just do this: */
271 plansource = CreateCachedPlan(NULL, query_string, commandTag);
272 oldcxt = MemoryContextSwitchTo(plansource->context);
273 plansource->analyzed_parse_tree = copyObject(analyzed_parse_tree);
274 MemoryContextSwitchTo(oldcxt);
275
276 return plansource;
277}
278
279/*
280 * CreateOneShotCachedPlan: initially create a one-shot plan cache entry.
281 *
282 * This variant of CreateCachedPlan creates a plan cache entry that is meant
283 * to be used only once. No data copying occurs: all data structures remain
284 * in the caller's memory context (which typically should get cleared after
285 * completing execution). The CachedPlanSource struct itself is also created
286 * in that context.
287 *
288 * A one-shot plan cannot be saved or copied, since we make no effort to
289 * preserve the raw parse tree unmodified. There is also no support for
290 * invalidation, so plan use must be completed in the current transaction,
291 * and DDL that might invalidate the querytree_list must be avoided as well.
292 *
293 * raw_parse_tree: output of raw_parser(), or NULL if empty query
294 * query_string: original query text
295 * commandTag: command tag for query, or NULL if empty query
296 */
299 const char *query_string,
300 CommandTag commandTag)
301{
302 CachedPlanSource *plansource;
303
304 Assert(query_string != NULL); /* required as of 8.4 */
305
306 /*
307 * Create and fill the CachedPlanSource struct within the caller's memory
308 * context. Most fields are just left empty for the moment.
309 */
310 plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
311 plansource->magic = CACHEDPLANSOURCE_MAGIC;
312 plansource->raw_parse_tree = raw_parse_tree;
313 plansource->analyzed_parse_tree = NULL;
314 plansource->query_string = query_string;
315 plansource->commandTag = commandTag;
316 plansource->param_types = NULL;
317 plansource->num_params = 0;
318 plansource->parserSetup = NULL;
319 plansource->parserSetupArg = NULL;
320 plansource->postRewrite = NULL;
321 plansource->postRewriteArg = NULL;
322 plansource->cursor_options = 0;
323 plansource->fixed_result = false;
324 plansource->resultDesc = NULL;
325 plansource->context = CurrentMemoryContext;
326 plansource->query_list = NIL;
327 plansource->relationOids = NIL;
328 plansource->invalItems = NIL;
329 plansource->search_path = NULL;
330 plansource->query_context = NULL;
331 plansource->rewriteRoleId = InvalidOid;
332 plansource->rewriteRowSecurity = false;
333 plansource->dependsOnRLS = false;
334 plansource->gplan = NULL;
335 plansource->is_oneshot = true;
336 plansource->is_complete = false;
337 plansource->is_saved = false;
338 plansource->is_valid = false;
339 plansource->generation = 0;
340 plansource->generic_cost = -1;
341 plansource->total_custom_cost = 0;
342 plansource->num_generic_plans = 0;
343 plansource->num_custom_plans = 0;
344
345 return plansource;
346}
347
348/*
349 * CompleteCachedPlan: second step of creating a plan cache entry.
350 *
351 * Pass in the analyzed-and-rewritten form of the query, as well as the
352 * required subsidiary data about parameters and such. All passed values will
353 * be copied into the CachedPlanSource's memory, except as specified below.
354 * After this is called, GetCachedPlan can be called to obtain a plan, and
355 * optionally the CachedPlanSource can be saved using SaveCachedPlan.
356 *
357 * If querytree_context is not NULL, the querytree_list must be stored in that
358 * context (but the other parameters need not be). The querytree_list is not
359 * copied, rather the given context is kept as the initial query_context of
360 * the CachedPlanSource. (It should have been created as a child of the
361 * caller's working memory context, but it will now be reparented to belong
362 * to the CachedPlanSource.) The querytree_context is normally the context in
363 * which the caller did raw parsing and parse analysis. This approach saves
364 * one tree copying step compared to passing NULL, but leaves lots of extra
365 * cruft in the query_context, namely whatever extraneous stuff parse analysis
366 * created, as well as whatever went unused from the raw parse tree. Using
367 * this option is a space-for-time tradeoff that is appropriate if the
368 * CachedPlanSource is not expected to survive long.
369 *
370 * plancache.c cannot know how to copy the data referenced by parserSetupArg,
371 * and it would often be inappropriate to do so anyway. When using that
372 * option, it is caller's responsibility that the referenced data remains
373 * valid for as long as the CachedPlanSource exists.
374 *
375 * If the CachedPlanSource is a "oneshot" plan, then no querytree copying
376 * occurs at all, and querytree_context is ignored; it is caller's
377 * responsibility that the passed querytree_list is sufficiently long-lived.
378 *
379 * plansource: structure returned by CreateCachedPlan
380 * querytree_list: analyzed-and-rewritten form of query (list of Query nodes)
381 * querytree_context: memory context containing querytree_list,
382 * or NULL to copy querytree_list into a fresh context
383 * param_types: array of fixed parameter type OIDs, or NULL if none
384 * num_params: number of fixed parameters
385 * parserSetup: alternate method for handling query parameters
386 * parserSetupArg: data to pass to parserSetup
387 * cursor_options: options bitmask to pass to planner
388 * fixed_result: true to disallow future changes in query's result tupdesc
389 */
390void
392 List *querytree_list,
393 MemoryContext querytree_context,
394 Oid *param_types,
395 int num_params,
396 ParserSetupHook parserSetup,
397 void *parserSetupArg,
398 int cursor_options,
399 bool fixed_result)
400{
401 MemoryContext source_context = plansource->context;
403
404 /* Assert caller is doing things in a sane order */
405 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
406 Assert(!plansource->is_complete);
407
408 /*
409 * If caller supplied a querytree_context, reparent it underneath the
410 * CachedPlanSource's context; otherwise, create a suitable context and
411 * copy the querytree_list into it. But no data copying should be done
412 * for one-shot plans; for those, assume the passed querytree_list is
413 * sufficiently long-lived.
414 */
415 if (plansource->is_oneshot)
416 {
417 querytree_context = CurrentMemoryContext;
418 }
419 else if (querytree_context != NULL)
420 {
421 MemoryContextSetParent(querytree_context, source_context);
422 MemoryContextSwitchTo(querytree_context);
423 }
424 else
425 {
426 /* Again, it's a good bet the querytree_context can be small */
427 querytree_context = AllocSetContextCreate(source_context,
428 "CachedPlanQuery",
430 MemoryContextSwitchTo(querytree_context);
431 querytree_list = copyObject(querytree_list);
432 }
433
434 plansource->query_context = querytree_context;
435 plansource->query_list = querytree_list;
436
437 if (!plansource->is_oneshot && StmtPlanRequiresRevalidation(plansource))
438 {
439 /*
440 * Use the planner machinery to extract dependencies. Data is saved
441 * in query_context. (We assume that not a lot of extra cruft is
442 * created by this call.) We can skip this for one-shot plans, and
443 * plans not needing revalidation have no such dependencies anyway.
444 */
445 extract_query_dependencies((Node *) querytree_list,
446 &plansource->relationOids,
447 &plansource->invalItems,
448 &plansource->dependsOnRLS);
449
450 /* Update RLS info as well. */
451 plansource->rewriteRoleId = GetUserId();
452 plansource->rewriteRowSecurity = row_security;
453
454 /*
455 * Also save the current search_path in the query_context. (This
456 * should not generate much extra cruft either, since almost certainly
457 * the path is already valid.) Again, we don't really need this for
458 * one-shot plans; and we *must* skip this for transaction control
459 * commands, because this could result in catalog accesses.
460 */
461 plansource->search_path = GetSearchPathMatcher(querytree_context);
462 }
463
464 /*
465 * Save the final parameter types (or other parameter specification data)
466 * into the source_context, as well as our other parameters. Also save
467 * the result tuple descriptor.
468 */
469 MemoryContextSwitchTo(source_context);
470
471 if (num_params > 0)
472 {
473 plansource->param_types = (Oid *) palloc(num_params * sizeof(Oid));
474 memcpy(plansource->param_types, param_types, num_params * sizeof(Oid));
475 }
476 else
477 plansource->param_types = NULL;
478 plansource->num_params = num_params;
479 plansource->parserSetup = parserSetup;
480 plansource->parserSetupArg = parserSetupArg;
481 plansource->cursor_options = cursor_options;
482 plansource->fixed_result = fixed_result;
483 plansource->resultDesc = PlanCacheComputeResultDesc(querytree_list);
484
485 MemoryContextSwitchTo(oldcxt);
486
487 plansource->is_complete = true;
488 plansource->is_valid = true;
489}
490
491/*
492 * SetPostRewriteHook: set a hook to modify post-rewrite query trees
493 *
494 * Some callers have a need to modify the query trees between rewriting and
495 * planning. In the initial call to CompleteCachedPlan, it's assumed such
496 * work was already done on the querytree_list. However, if we're forced
497 * to replan, it will need to be done over. The caller can set this hook
498 * to provide code to make that happen.
499 *
500 * postRewriteArg is just passed verbatim to the hook. As with parserSetupArg,
501 * it is caller's responsibility that the referenced data remains
502 * valid for as long as the CachedPlanSource exists.
503 */
504void
506 PostRewriteHook postRewrite,
507 void *postRewriteArg)
508{
509 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
510 plansource->postRewrite = postRewrite;
511 plansource->postRewriteArg = postRewriteArg;
512}
513
514/*
515 * SaveCachedPlan: save a cached plan permanently
516 *
517 * This function moves the cached plan underneath CacheMemoryContext (making
518 * it live for the life of the backend, unless explicitly dropped), and adds
519 * it to the list of cached plans that are checked for invalidation when an
520 * sinval event occurs.
521 *
522 * This is guaranteed not to throw error, except for the caller-error case
523 * of trying to save a one-shot plan. Callers typically depend on that
524 * since this is called just before or just after adding a pointer to the
525 * CachedPlanSource to some permanent data structure of their own. Up until
526 * this is done, a CachedPlanSource is just transient data that will go away
527 * automatically on transaction abort.
528 */
529void
531{
532 /* Assert caller is doing things in a sane order */
533 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
534 Assert(plansource->is_complete);
535 Assert(!plansource->is_saved);
536
537 /* This seems worth a real test, though */
538 if (plansource->is_oneshot)
539 elog(ERROR, "cannot save one-shot cached plan");
540
541 /*
542 * In typical use, this function would be called before generating any
543 * plans from the CachedPlanSource. If there is a generic plan, moving it
544 * into CacheMemoryContext would be pretty risky since it's unclear
545 * whether the caller has taken suitable care with making references
546 * long-lived. Best thing to do seems to be to discard the plan.
547 */
548 ReleaseGenericPlan(plansource);
549
550 /*
551 * Reparent the source memory context under CacheMemoryContext so that it
552 * will live indefinitely. The query_context follows along since it's
553 * already a child of the other one.
554 */
556
557 /*
558 * Add the entry to the global list of cached plans.
559 */
560 dlist_push_tail(&saved_plan_list, &plansource->node);
561
562 plansource->is_saved = true;
563}
564
565/*
566 * DropCachedPlan: destroy a cached plan.
567 *
568 * Actually this only destroys the CachedPlanSource: any referenced CachedPlan
569 * is released, but not destroyed until its refcount goes to zero. That
570 * handles the situation where DropCachedPlan is called while the plan is
571 * still in use.
572 */
573void
575{
576 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
577
578 /* If it's been saved, remove it from the list */
579 if (plansource->is_saved)
580 {
581 dlist_delete(&plansource->node);
582 plansource->is_saved = false;
583 }
584
585 /* Decrement generic CachedPlan's refcount and drop if no longer needed */
586 ReleaseGenericPlan(plansource);
587
588 /* Mark it no longer valid */
589 plansource->magic = 0;
590
591 /*
592 * Remove the CachedPlanSource and all subsidiary data (including the
593 * query_context if any). But if it's a one-shot we can't free anything.
594 */
595 if (!plansource->is_oneshot)
596 MemoryContextDelete(plansource->context);
597}
598
599/*
600 * ReleaseGenericPlan: release a CachedPlanSource's generic plan, if any.
601 */
602static void
604{
605 /* Be paranoid about the possibility that ReleaseCachedPlan fails */
606 if (plansource->gplan)
607 {
608 CachedPlan *plan = plansource->gplan;
609
610 Assert(plan->magic == CACHEDPLAN_MAGIC);
611 plansource->gplan = NULL;
612 ReleaseCachedPlan(plan, NULL);
613 }
614}
615
616/*
617 * We must skip "overhead" operations that involve database access when the
618 * cached plan's subject statement is a transaction control command or one
619 * that requires a snapshot not to be set yet (such as SET or LOCK). More
620 * generally, statements that do not require parse analysis/rewrite/plan
621 * activity never need to be revalidated, so we can treat them all like that.
622 * For the convenience of postgres.c, treat empty statements that way too.
623 */
624static bool
626{
627 if (plansource->raw_parse_tree != NULL)
629 else if (plansource->analyzed_parse_tree != NULL)
631 /* empty query never needs revalidation */
632 return false;
633}
634
635/*
636 * Determine if creating a plan for this CachedPlanSource requires a snapshot.
637 * In fact this function matches StmtPlanRequiresRevalidation(), but we want
638 * to preserve the distinction between stmt_requires_parse_analysis() and
639 * analyze_requires_snapshot().
640 */
641static bool
643{
644 if (plansource->raw_parse_tree != NULL)
645 return analyze_requires_snapshot(plansource->raw_parse_tree);
646 else if (plansource->analyzed_parse_tree != NULL)
648 /* empty query never needs a snapshot */
649 return false;
650}
651
652/*
653 * RevalidateCachedQuery: ensure validity of analyzed-and-rewritten query tree.
654 *
655 * What we do here is re-acquire locks and redo parse analysis if necessary.
656 * On return, the query_list is valid and we have sufficient locks to begin
657 * planning.
658 *
659 * If any parse analysis activity is required, the caller's memory context is
660 * used for that work.
661 *
662 * The result value is the transient analyzed-and-rewritten query tree if we
663 * had to do re-analysis, and NIL otherwise. (This is returned just to save
664 * a tree copying step in a subsequent BuildCachedPlan call.)
665 */
666static List *
668 QueryEnvironment *queryEnv)
669{
670 bool snapshot_set;
671 List *tlist; /* transient query-tree list */
672 List *qlist; /* permanent query-tree list */
673 TupleDesc resultDesc;
674 MemoryContext querytree_context;
675 MemoryContext oldcxt;
676
677 /*
678 * For one-shot plans, we do not support revalidation checking; it's
679 * assumed the query is parsed, planned, and executed in one transaction,
680 * so that no lock re-acquisition is necessary. Also, if the statement
681 * type can't require revalidation, we needn't do anything (and we mustn't
682 * risk catalog accesses when handling, eg, transaction control commands).
683 */
684 if (plansource->is_oneshot || !StmtPlanRequiresRevalidation(plansource))
685 {
686 Assert(plansource->is_valid);
687 return NIL;
688 }
689
690 /*
691 * If the query is currently valid, we should have a saved search_path ---
692 * check to see if that matches the current environment. If not, we want
693 * to force replan. (We could almost ignore this consideration when
694 * working from an analyzed parse tree; but there are scenarios where
695 * planning can have search_path-dependent results, for example if it
696 * inlines an old-style SQL function.)
697 */
698 if (plansource->is_valid)
699 {
700 Assert(plansource->search_path != NULL);
702 {
703 /* Invalidate the querytree and generic plan */
704 plansource->is_valid = false;
705 if (plansource->gplan)
706 plansource->gplan->is_valid = false;
707 }
708 }
709
710 /*
711 * If the query rewrite phase had a possible RLS dependency, we must redo
712 * it if either the role or the row_security setting has changed.
713 */
714 if (plansource->is_valid && plansource->dependsOnRLS &&
715 (plansource->rewriteRoleId != GetUserId() ||
716 plansource->rewriteRowSecurity != row_security))
717 plansource->is_valid = false;
718
719 /*
720 * If the query is currently valid, acquire locks on the referenced
721 * objects; then check again. We need to do it this way to cover the race
722 * condition that an invalidation message arrives before we get the locks.
723 */
724 if (plansource->is_valid)
725 {
726 AcquirePlannerLocks(plansource->query_list, true);
727
728 /*
729 * By now, if any invalidation has happened, the inval callback
730 * functions will have marked the query invalid.
731 */
732 if (plansource->is_valid)
733 {
734 /* Successfully revalidated and locked the query. */
735 return NIL;
736 }
737
738 /* Oops, the race case happened. Release useless locks. */
739 AcquirePlannerLocks(plansource->query_list, false);
740 }
741
742 /*
743 * Discard the no-longer-useful rewritten query tree. (Note: we don't
744 * want to do this any earlier, else we'd not have been able to release
745 * locks correctly in the race condition case.)
746 */
747 plansource->is_valid = false;
748 plansource->query_list = NIL;
749 plansource->relationOids = NIL;
750 plansource->invalItems = NIL;
751 plansource->search_path = NULL;
752
753 /*
754 * Free the query_context. We don't really expect MemoryContextDelete to
755 * fail, but just in case, make sure the CachedPlanSource is left in a
756 * reasonably sane state. (The generic plan won't get unlinked yet, but
757 * that's acceptable.)
758 */
759 if (plansource->query_context)
760 {
761 MemoryContext qcxt = plansource->query_context;
762
763 plansource->query_context = NULL;
765 }
766
767 /* Drop the generic plan reference if any */
768 ReleaseGenericPlan(plansource);
769
770 /*
771 * Now re-do parse analysis and rewrite. This not incidentally acquires
772 * the locks we need to do planning safely.
773 */
774 Assert(plansource->is_complete);
775
776 /*
777 * If a snapshot is already set (the normal case), we can just use that
778 * for parsing/planning. But if it isn't, install one. Note: no point in
779 * checking whether parse analysis requires a snapshot; utility commands
780 * don't have invalidatable plans, so we'd not get here for such a
781 * command.
782 */
783 snapshot_set = false;
784 if (!ActiveSnapshotSet())
785 {
787 snapshot_set = true;
788 }
789
790 /*
791 * Run parse analysis (if needed) and rule rewriting.
792 */
793 if (plansource->raw_parse_tree != NULL)
794 {
795 /* Source is raw parse tree */
796 RawStmt *rawtree;
797
798 /*
799 * The parser tends to scribble on its input, so we must copy the raw
800 * parse tree to prevent corruption of the cache.
801 */
802 rawtree = copyObject(plansource->raw_parse_tree);
803 if (plansource->parserSetup != NULL)
804 tlist = pg_analyze_and_rewrite_withcb(rawtree,
805 plansource->query_string,
806 plansource->parserSetup,
807 plansource->parserSetupArg,
808 queryEnv);
809 else
811 plansource->query_string,
812 plansource->param_types,
813 plansource->num_params,
814 queryEnv);
815 }
816 else if (plansource->analyzed_parse_tree != NULL)
817 {
818 /* Source is pre-analyzed query, so we only need to rewrite */
819 Query *analyzed_tree;
820
821 /* The rewriter scribbles on its input, too, so copy */
822 analyzed_tree = copyObject(plansource->analyzed_parse_tree);
823 /* Acquire locks needed before rewriting ... */
824 AcquireRewriteLocks(analyzed_tree, true, false);
825 /* ... and do it */
826 tlist = pg_rewrite_query(analyzed_tree);
827 }
828 else
829 {
830 /* Empty query, nothing to do */
831 tlist = NIL;
832 }
833
834 /* Apply post-rewrite callback if there is one */
835 if (plansource->postRewrite != NULL)
836 plansource->postRewrite(tlist, plansource->postRewriteArg);
837
838 /* Release snapshot if we got one */
839 if (snapshot_set)
841
842 /*
843 * Check or update the result tupdesc.
844 *
845 * We assume the parameter types didn't change from the first time, so no
846 * need to update that.
847 */
848 resultDesc = PlanCacheComputeResultDesc(tlist);
849 if (resultDesc == NULL && plansource->resultDesc == NULL)
850 {
851 /* OK, doesn't return tuples */
852 }
853 else if (resultDesc == NULL || plansource->resultDesc == NULL ||
854 !equalRowTypes(resultDesc, plansource->resultDesc))
855 {
856 /* can we give a better error message? */
857 if (plansource->fixed_result)
859 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
860 errmsg("cached plan must not change result type")));
861 oldcxt = MemoryContextSwitchTo(plansource->context);
862 if (resultDesc)
863 resultDesc = CreateTupleDescCopy(resultDesc);
864 if (plansource->resultDesc)
865 FreeTupleDesc(plansource->resultDesc);
866 plansource->resultDesc = resultDesc;
867 MemoryContextSwitchTo(oldcxt);
868 }
869
870 /*
871 * Allocate new query_context and copy the completed querytree into it.
872 * It's transient until we complete the copying and dependency extraction.
873 */
875 "CachedPlanQuery",
877 oldcxt = MemoryContextSwitchTo(querytree_context);
878
879 qlist = copyObject(tlist);
880
881 /*
882 * Use the planner machinery to extract dependencies. Data is saved in
883 * query_context. (We assume that not a lot of extra cruft is created by
884 * this call.)
885 */
887 &plansource->relationOids,
888 &plansource->invalItems,
889 &plansource->dependsOnRLS);
890
891 /* Update RLS info as well. */
892 plansource->rewriteRoleId = GetUserId();
893 plansource->rewriteRowSecurity = row_security;
894
895 /*
896 * Also save the current search_path in the query_context. (This should
897 * not generate much extra cruft either, since almost certainly the path
898 * is already valid.)
899 */
900 plansource->search_path = GetSearchPathMatcher(querytree_context);
901
902 MemoryContextSwitchTo(oldcxt);
903
904 /* Now reparent the finished query_context and save the links */
905 MemoryContextSetParent(querytree_context, plansource->context);
906
907 plansource->query_context = querytree_context;
908 plansource->query_list = qlist;
909
910 /*
911 * Note: we do not reset generic_cost or total_custom_cost, although we
912 * could choose to do so. If the DDL or statistics change that prompted
913 * the invalidation meant a significant change in the cost estimates, it
914 * would be better to reset those variables and start fresh; but often it
915 * doesn't, and we're better retaining our hard-won knowledge about the
916 * relative costs.
917 */
918
919 plansource->is_valid = true;
920
921 /* Return transient copy of querytrees for possible use in planning */
922 return tlist;
923}
924
925/*
926 * CheckCachedPlan: see if the CachedPlanSource's generic plan is valid.
927 *
928 * Caller must have already called RevalidateCachedQuery to verify that the
929 * querytree is up to date.
930 *
931 * On a "true" return, we have acquired the locks needed to run the plan.
932 * (We must do this for the "true" result to be race-condition-free.)
933 */
934static bool
936{
937 CachedPlan *plan = plansource->gplan;
938
939 /* Assert that caller checked the querytree */
940 Assert(plansource->is_valid);
941
942 /* If there's no generic plan, just say "false" */
943 if (!plan)
944 return false;
945
946 Assert(plan->magic == CACHEDPLAN_MAGIC);
947 /* Generic plans are never one-shot */
948 Assert(!plan->is_oneshot);
949
950 /*
951 * If plan isn't valid for current role, we can't use it.
952 */
953 if (plan->is_valid && plan->dependsOnRole &&
954 plan->planRoleId != GetUserId())
955 plan->is_valid = false;
956
957 /*
958 * If it appears valid, acquire locks and recheck; this is much the same
959 * logic as in RevalidateCachedQuery, but for a plan.
960 */
961 if (plan->is_valid)
962 {
963 /*
964 * Plan must have positive refcount because it is referenced by
965 * plansource; so no need to fear it disappears under us here.
966 */
967 Assert(plan->refcount > 0);
968
969 AcquireExecutorLocks(plan->stmt_list, true);
970
971 /*
972 * If plan was transient, check to see if TransactionXmin has
973 * advanced, and if so invalidate it.
974 */
975 if (plan->is_valid &&
976 TransactionIdIsValid(plan->saved_xmin) &&
978 plan->is_valid = false;
979
980 /*
981 * By now, if any invalidation has happened, the inval callback
982 * functions will have marked the plan invalid.
983 */
984 if (plan->is_valid)
985 {
986 /* Successfully revalidated and locked the query. */
987 return true;
988 }
989
990 /* Oops, the race case happened. Release useless locks. */
991 AcquireExecutorLocks(plan->stmt_list, false);
992 }
993
994 /*
995 * Plan has been invalidated, so unlink it from the parent and release it.
996 */
997 ReleaseGenericPlan(plansource);
998
999 return false;
1000}
1001
1002/*
1003 * BuildCachedPlan: construct a new CachedPlan from a CachedPlanSource.
1004 *
1005 * qlist should be the result value from a previous RevalidateCachedQuery,
1006 * or it can be set to NIL if we need to re-copy the plansource's query_list.
1007 *
1008 * To build a generic, parameter-value-independent plan, pass NULL for
1009 * boundParams. To build a custom plan, pass the actual parameter values via
1010 * boundParams. For best effect, the PARAM_FLAG_CONST flag should be set on
1011 * each parameter value; otherwise the planner will treat the value as a
1012 * hint rather than a hard constant.
1013 *
1014 * Planning work is done in the caller's memory context. The finished plan
1015 * is in a child memory context, which typically should get reparented
1016 * (unless this is a one-shot plan, in which case we don't copy the plan).
1017 */
1018static CachedPlan *
1020 ParamListInfo boundParams, QueryEnvironment *queryEnv)
1021{
1023 List *plist;
1024 bool snapshot_set;
1025 bool is_transient;
1026 MemoryContext plan_context;
1028 ListCell *lc;
1029
1030 /*
1031 * Normally the querytree should be valid already, but if it's not,
1032 * rebuild it.
1033 *
1034 * NOTE: GetCachedPlan should have called RevalidateCachedQuery first, so
1035 * we ought to be holding sufficient locks to prevent any invalidation.
1036 * However, if we're building a custom plan after having built and
1037 * rejected a generic plan, it's possible to reach here with is_valid
1038 * false due to an invalidation while making the generic plan. In theory
1039 * the invalidation must be a false positive, perhaps a consequence of an
1040 * sinval reset event or the debug_discard_caches code. But for safety,
1041 * let's treat it as real and redo the RevalidateCachedQuery call.
1042 */
1043 if (!plansource->is_valid)
1044 qlist = RevalidateCachedQuery(plansource, queryEnv);
1045
1046 /*
1047 * If we don't already have a copy of the querytree list that can be
1048 * scribbled on by the planner, make one. For a one-shot plan, we assume
1049 * it's okay to scribble on the original query_list.
1050 */
1051 if (qlist == NIL)
1052 {
1053 if (!plansource->is_oneshot)
1054 qlist = copyObject(plansource->query_list);
1055 else
1056 qlist = plansource->query_list;
1057 }
1058
1059 /*
1060 * If a snapshot is already set (the normal case), we can just use that
1061 * for planning. But if it isn't, and we need one, install one.
1062 */
1063 snapshot_set = false;
1064 if (!ActiveSnapshotSet() &&
1065 BuildingPlanRequiresSnapshot(plansource))
1066 {
1068 snapshot_set = true;
1069 }
1070
1071 /*
1072 * Generate the plan.
1073 */
1074 plist = pg_plan_queries(qlist, plansource->query_string,
1075 plansource->cursor_options, boundParams);
1076
1077 /* Release snapshot if we got one */
1078 if (snapshot_set)
1080
1081 /*
1082 * Normally we make a dedicated memory context for the CachedPlan and its
1083 * subsidiary data. (It's probably not going to be large, but just in
1084 * case, allow it to grow large. It's transient for the moment.) But for
1085 * a one-shot plan, we just leave it in the caller's memory context.
1086 */
1087 if (!plansource->is_oneshot)
1088 {
1090 "CachedPlan",
1092 MemoryContextCopyAndSetIdentifier(plan_context, plansource->query_string);
1093
1094 /*
1095 * Copy plan into the new context.
1096 */
1097 MemoryContextSwitchTo(plan_context);
1098
1099 plist = copyObject(plist);
1100 }
1101 else
1102 plan_context = CurrentMemoryContext;
1103
1104 /*
1105 * Create and fill the CachedPlan struct within the new context.
1106 */
1107 plan = (CachedPlan *) palloc(sizeof(CachedPlan));
1108 plan->magic = CACHEDPLAN_MAGIC;
1109 plan->stmt_list = plist;
1110
1111 /*
1112 * CachedPlan is dependent on role either if RLS affected the rewrite
1113 * phase or if a role dependency was injected during planning. And it's
1114 * transient if any plan is marked so.
1115 */
1116 plan->planRoleId = GetUserId();
1117 plan->dependsOnRole = plansource->dependsOnRLS;
1118 is_transient = false;
1119 foreach(lc, plist)
1120 {
1121 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1122
1123 if (plannedstmt->commandType == CMD_UTILITY)
1124 continue; /* Ignore utility statements */
1125
1126 if (plannedstmt->transientPlan)
1127 is_transient = true;
1128 if (plannedstmt->dependsOnRole)
1129 plan->dependsOnRole = true;
1130 }
1131 if (is_transient)
1132 {
1134 plan->saved_xmin = TransactionXmin;
1135 }
1136 else
1137 plan->saved_xmin = InvalidTransactionId;
1138 plan->refcount = 0;
1139 plan->context = plan_context;
1140 plan->is_oneshot = plansource->is_oneshot;
1141 plan->is_saved = false;
1142 plan->is_valid = true;
1143
1144 /* assign generation number to new plan */
1145 plan->generation = ++(plansource->generation);
1146
1147 MemoryContextSwitchTo(oldcxt);
1148
1149 return plan;
1150}
1151
1152/*
1153 * choose_custom_plan: choose whether to use custom or generic plan
1154 *
1155 * This defines the policy followed by GetCachedPlan.
1156 */
1157static bool
1159{
1160 double avg_custom_cost;
1161
1162 /* One-shot plans will always be considered custom */
1163 if (plansource->is_oneshot)
1164 return true;
1165
1166 /* Otherwise, never any point in a custom plan if there's no parameters */
1167 if (boundParams == NULL)
1168 return false;
1169 /* ... nor when planning would be a no-op */
1170 if (!StmtPlanRequiresRevalidation(plansource))
1171 return false;
1172
1173 /* Let settings force the decision */
1175 return false;
1177 return true;
1178
1179 /* See if caller wants to force the decision */
1180 if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN)
1181 return false;
1182 if (plansource->cursor_options & CURSOR_OPT_CUSTOM_PLAN)
1183 return true;
1184
1185 /* Generate custom plans until we have done at least 5 (arbitrary) */
1186 if (plansource->num_custom_plans < 5)
1187 return true;
1188
1189 avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans;
1190
1191 /*
1192 * Prefer generic plan if it's less expensive than the average custom
1193 * plan. (Because we include a charge for cost of planning in the
1194 * custom-plan costs, this means the generic plan only has to be less
1195 * expensive than the execution cost plus replan cost of the custom
1196 * plans.)
1197 *
1198 * Note that if generic_cost is -1 (indicating we've not yet determined
1199 * the generic plan cost), we'll always prefer generic at this point.
1200 */
1201 if (plansource->generic_cost < avg_custom_cost)
1202 return false;
1203
1204 return true;
1205}
1206
1207/*
1208 * cached_plan_cost: calculate estimated cost of a plan
1209 *
1210 * If include_planner is true, also include the estimated cost of constructing
1211 * the plan. (We must factor that into the cost of using a custom plan, but
1212 * we don't count it for a generic plan.)
1213 */
1214static double
1215cached_plan_cost(CachedPlan *plan, bool include_planner)
1216{
1217 double result = 0;
1218 ListCell *lc;
1219
1220 foreach(lc, plan->stmt_list)
1221 {
1222 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1223
1224 if (plannedstmt->commandType == CMD_UTILITY)
1225 continue; /* Ignore utility statements */
1226
1227 result += plannedstmt->planTree->total_cost;
1228
1229 if (include_planner)
1230 {
1231 /*
1232 * Currently we use a very crude estimate of planning effort based
1233 * on the number of relations in the finished plan's rangetable.
1234 * Join planning effort actually scales much worse than linearly
1235 * in the number of relations --- but only until the join collapse
1236 * limits kick in. Also, while inheritance child relations surely
1237 * add to planning effort, they don't make the join situation
1238 * worse. So the actual shape of the planning cost curve versus
1239 * number of relations isn't all that obvious. It will take
1240 * considerable work to arrive at a less crude estimate, and for
1241 * now it's not clear that's worth doing.
1242 *
1243 * The other big difficulty here is that we don't have any very
1244 * good model of how planning cost compares to execution costs.
1245 * The current multiplier of 1000 * cpu_operator_cost is probably
1246 * on the low side, but we'll try this for awhile before making a
1247 * more aggressive correction.
1248 *
1249 * If we ever do write a more complicated estimator, it should
1250 * probably live in src/backend/optimizer/ not here.
1251 */
1252 int nrelations = list_length(plannedstmt->rtable);
1253
1254 result += 1000.0 * cpu_operator_cost * (nrelations + 1);
1255 }
1256 }
1257
1258 return result;
1259}
1260
1261/*
1262 * GetCachedPlan: get a cached plan from a CachedPlanSource.
1263 *
1264 * This function hides the logic that decides whether to use a generic
1265 * plan or a custom plan for the given parameters: the caller does not know
1266 * which it will get.
1267 *
1268 * On return, the plan is valid and we have sufficient locks to begin
1269 * execution.
1270 *
1271 * On return, the refcount of the plan has been incremented; a later
1272 * ReleaseCachedPlan() call is expected. If "owner" is not NULL then
1273 * the refcount has been reported to that ResourceOwner (note that this
1274 * is only supported for "saved" CachedPlanSources).
1275 *
1276 * Note: if any replanning activity is required, the caller's memory context
1277 * is used for that work.
1278 */
1279CachedPlan *
1281 ResourceOwner owner, QueryEnvironment *queryEnv)
1282{
1283 CachedPlan *plan = NULL;
1284 List *qlist;
1285 bool customplan;
1286
1287 /* Assert caller is doing things in a sane order */
1288 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1289 Assert(plansource->is_complete);
1290 /* This seems worth a real test, though */
1291 if (owner && !plansource->is_saved)
1292 elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
1293
1294 /* Make sure the querytree list is valid and we have parse-time locks */
1295 qlist = RevalidateCachedQuery(plansource, queryEnv);
1296
1297 /* Decide whether to use a custom plan */
1298 customplan = choose_custom_plan(plansource, boundParams);
1299
1300 if (!customplan)
1301 {
1302 if (CheckCachedPlan(plansource))
1303 {
1304 /* We want a generic plan, and we already have a valid one */
1305 plan = plansource->gplan;
1306 Assert(plan->magic == CACHEDPLAN_MAGIC);
1307 }
1308 else
1309 {
1310 /* Build a new generic plan */
1311 plan = BuildCachedPlan(plansource, qlist, NULL, queryEnv);
1312 /* Just make real sure plansource->gplan is clear */
1313 ReleaseGenericPlan(plansource);
1314 /* Link the new generic plan into the plansource */
1315 plansource->gplan = plan;
1316 plan->refcount++;
1317 /* Immediately reparent into appropriate context */
1318 if (plansource->is_saved)
1319 {
1320 /* saved plans all live under CacheMemoryContext */
1322 plan->is_saved = true;
1323 }
1324 else
1325 {
1326 /* otherwise, it should be a sibling of the plansource */
1328 MemoryContextGetParent(plansource->context));
1329 }
1330 /* Update generic_cost whenever we make a new generic plan */
1331 plansource->generic_cost = cached_plan_cost(plan, false);
1332
1333 /*
1334 * If, based on the now-known value of generic_cost, we'd not have
1335 * chosen to use a generic plan, then forget it and make a custom
1336 * plan. This is a bit of a wart but is necessary to avoid a
1337 * glitch in behavior when the custom plans are consistently big
1338 * winners; at some point we'll experiment with a generic plan and
1339 * find it's a loser, but we don't want to actually execute that
1340 * plan.
1341 */
1342 customplan = choose_custom_plan(plansource, boundParams);
1343
1344 /*
1345 * If we choose to plan again, we need to re-copy the query_list,
1346 * since the planner probably scribbled on it. We can force
1347 * BuildCachedPlan to do that by passing NIL.
1348 */
1349 qlist = NIL;
1350 }
1351 }
1352
1353 if (customplan)
1354 {
1355 /* Build a custom plan */
1356 plan = BuildCachedPlan(plansource, qlist, boundParams, queryEnv);
1357 /* Accumulate total costs of custom plans */
1358 plansource->total_custom_cost += cached_plan_cost(plan, true);
1359
1360 plansource->num_custom_plans++;
1361 }
1362 else
1363 {
1364 plansource->num_generic_plans++;
1365 }
1366
1367 Assert(plan != NULL);
1368
1369 /* Flag the plan as in use by caller */
1370 if (owner)
1371 ResourceOwnerEnlarge(owner);
1372 plan->refcount++;
1373 if (owner)
1375
1376 /*
1377 * Saved plans should be under CacheMemoryContext so they will not go away
1378 * until their reference count goes to zero. In the generic-plan cases we
1379 * already took care of that, but for a custom plan, do it as soon as we
1380 * have created a reference-counted link.
1381 */
1382 if (customplan && plansource->is_saved)
1383 {
1385 plan->is_saved = true;
1386 }
1387
1388 return plan;
1389}
1390
1391/*
1392 * ReleaseCachedPlan: release active use of a cached plan.
1393 *
1394 * This decrements the reference count, and frees the plan if the count
1395 * has thereby gone to zero. If "owner" is not NULL, it is assumed that
1396 * the reference count is managed by that ResourceOwner.
1397 *
1398 * Note: owner == NULL is used for releasing references that are in
1399 * persistent data structures, such as the parent CachedPlanSource or a
1400 * Portal. Transient references should be protected by a resource owner.
1401 */
1402void
1404{
1405 Assert(plan->magic == CACHEDPLAN_MAGIC);
1406 if (owner)
1407 {
1408 Assert(plan->is_saved);
1410 }
1411 Assert(plan->refcount > 0);
1412 plan->refcount--;
1413 if (plan->refcount == 0)
1414 {
1415 /* Mark it no longer valid */
1416 plan->magic = 0;
1417
1418 /* One-shot plans do not own their context, so we can't free them */
1419 if (!plan->is_oneshot)
1420 MemoryContextDelete(plan->context);
1421 }
1422}
1423
1424/*
1425 * CachedPlanAllowsSimpleValidityCheck: can we use CachedPlanIsSimplyValid?
1426 *
1427 * This function, together with CachedPlanIsSimplyValid, provides a fast path
1428 * for revalidating "simple" generic plans. The core requirement to be simple
1429 * is that the plan must not require taking any locks, which translates to
1430 * not touching any tables; this happens to match up well with an important
1431 * use-case in PL/pgSQL. This function tests whether that's true, along
1432 * with checking some other corner cases that we'd rather not bother with
1433 * handling in the fast path. (Note that it's still possible for such a plan
1434 * to be invalidated, for example due to a change in a function that was
1435 * inlined into the plan.)
1436 *
1437 * If the plan is simply valid, and "owner" is not NULL, record a refcount on
1438 * the plan in that resowner before returning. It is caller's responsibility
1439 * to be sure that a refcount is held on any plan that's being actively used.
1440 *
1441 * This must only be called on known-valid generic plans (eg, ones just
1442 * returned by GetCachedPlan). If it returns true, the caller may re-use
1443 * the cached plan as long as CachedPlanIsSimplyValid returns true; that
1444 * check is much cheaper than the full revalidation done by GetCachedPlan.
1445 * Nonetheless, no required checks are omitted.
1446 */
1447bool
1450{
1451 ListCell *lc;
1452
1453 /*
1454 * Sanity-check that the caller gave us a validated generic plan. Notice
1455 * that we *don't* assert plansource->is_valid as you might expect; that's
1456 * because it's possible that that's already false when GetCachedPlan
1457 * returns, e.g. because ResetPlanCache happened partway through. We
1458 * should accept the plan as long as plan->is_valid is true, and expect to
1459 * replan after the next CachedPlanIsSimplyValid call.
1460 */
1461 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1462 Assert(plan->magic == CACHEDPLAN_MAGIC);
1463 Assert(plan->is_valid);
1464 Assert(plan == plansource->gplan);
1465 Assert(plansource->search_path != NULL);
1467
1468 /* We don't support oneshot plans here. */
1469 if (plansource->is_oneshot)
1470 return false;
1471 Assert(!plan->is_oneshot);
1472
1473 /*
1474 * If the plan is dependent on RLS considerations, or it's transient,
1475 * reject. These things probably can't ever happen for table-free
1476 * queries, but for safety's sake let's check.
1477 */
1478 if (plansource->dependsOnRLS)
1479 return false;
1480 if (plan->dependsOnRole)
1481 return false;
1482 if (TransactionIdIsValid(plan->saved_xmin))
1483 return false;
1484
1485 /*
1486 * Reject if AcquirePlannerLocks would have anything to do. This is
1487 * simplistic, but there's no need to inquire any more carefully; indeed,
1488 * for current callers it shouldn't even be possible to hit any of these
1489 * checks.
1490 */
1491 foreach(lc, plansource->query_list)
1492 {
1493 Query *query = lfirst_node(Query, lc);
1494
1495 if (query->commandType == CMD_UTILITY)
1496 return false;
1497 if (query->rtable || query->cteList || query->hasSubLinks)
1498 return false;
1499 }
1500
1501 /*
1502 * Reject if AcquireExecutorLocks would have anything to do. This is
1503 * probably unnecessary given the previous check, but let's be safe.
1504 */
1505 foreach(lc, plan->stmt_list)
1506 {
1507 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1508 ListCell *lc2;
1509
1510 if (plannedstmt->commandType == CMD_UTILITY)
1511 return false;
1512
1513 /*
1514 * We have to grovel through the rtable because it's likely to contain
1515 * an RTE_RESULT relation, rather than being totally empty.
1516 */
1517 foreach(lc2, plannedstmt->rtable)
1518 {
1519 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
1520
1521 if (rte->rtekind == RTE_RELATION)
1522 return false;
1523 }
1524 }
1525
1526 /*
1527 * Okay, it's simple. Note that what we've primarily established here is
1528 * that no locks need be taken before checking the plan's is_valid flag.
1529 */
1530
1531 /* Bump refcount if requested. */
1532 if (owner)
1533 {
1534 ResourceOwnerEnlarge(owner);
1535 plan->refcount++;
1537 }
1538
1539 return true;
1540}
1541
1542/*
1543 * CachedPlanIsSimplyValid: quick check for plan still being valid
1544 *
1545 * This function must not be used unless CachedPlanAllowsSimpleValidityCheck
1546 * previously said it was OK.
1547 *
1548 * If the plan is valid, and "owner" is not NULL, record a refcount on
1549 * the plan in that resowner before returning. It is caller's responsibility
1550 * to be sure that a refcount is held on any plan that's being actively used.
1551 *
1552 * The code here is unconditionally safe as long as the only use of this
1553 * CachedPlanSource is in connection with the particular CachedPlan pointer
1554 * that's passed in. If the plansource were being used for other purposes,
1555 * it's possible that its generic plan could be invalidated and regenerated
1556 * while the current caller wasn't looking, and then there could be a chance
1557 * collision of address between this caller's now-stale plan pointer and the
1558 * actual address of the new generic plan. For current uses, that scenario
1559 * can't happen; but with a plansource shared across multiple uses, it'd be
1560 * advisable to also save plan->generation and verify that that still matches.
1561 */
1562bool
1564 ResourceOwner owner)
1565{
1566 /*
1567 * Careful here: since the caller doesn't necessarily hold a refcount on
1568 * the plan to start with, it's possible that "plan" is a dangling
1569 * pointer. Don't dereference it until we've verified that it still
1570 * matches the plansource's gplan (which is either valid or NULL).
1571 */
1572 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1573
1574 /*
1575 * Has cache invalidation fired on this plan? We can check this right
1576 * away since there are no locks that we'd need to acquire first. Note
1577 * that here we *do* check plansource->is_valid, so as to force plan
1578 * rebuild if that's become false.
1579 */
1580 if (!plansource->is_valid ||
1581 plan == NULL || plan != plansource->gplan ||
1582 !plan->is_valid)
1583 return false;
1584
1585 Assert(plan->magic == CACHEDPLAN_MAGIC);
1586
1587 /* Is the search_path still the same as when we made it? */
1588 Assert(plansource->search_path != NULL);
1590 return false;
1591
1592 /* It's still good. Bump refcount if requested. */
1593 if (owner)
1594 {
1595 ResourceOwnerEnlarge(owner);
1596 plan->refcount++;
1598 }
1599
1600 return true;
1601}
1602
1603/*
1604 * CachedPlanSetParentContext: move a CachedPlanSource to a new memory context
1605 *
1606 * This can only be applied to unsaved plans; once saved, a plan always
1607 * lives underneath CacheMemoryContext.
1608 */
1609void
1611 MemoryContext newcontext)
1612{
1613 /* Assert caller is doing things in a sane order */
1614 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1615 Assert(plansource->is_complete);
1616
1617 /* These seem worth real tests, though */
1618 if (plansource->is_saved)
1619 elog(ERROR, "cannot move a saved cached plan to another context");
1620 if (plansource->is_oneshot)
1621 elog(ERROR, "cannot move a one-shot cached plan to another context");
1622
1623 /* OK, let the caller keep the plan where he wishes */
1624 MemoryContextSetParent(plansource->context, newcontext);
1625
1626 /*
1627 * The query_context needs no special handling, since it's a child of
1628 * plansource->context. But if there's a generic plan, it should be
1629 * maintained as a sibling of plansource->context.
1630 */
1631 if (plansource->gplan)
1632 {
1633 Assert(plansource->gplan->magic == CACHEDPLAN_MAGIC);
1634 MemoryContextSetParent(plansource->gplan->context, newcontext);
1635 }
1636}
1637
1638/*
1639 * CopyCachedPlan: make a copy of a CachedPlanSource
1640 *
1641 * This is a convenience routine that does the equivalent of
1642 * CreateCachedPlan + CompleteCachedPlan, using the data stored in the
1643 * input CachedPlanSource. The result is therefore "unsaved" (regardless
1644 * of the state of the source), and we don't copy any generic plan either.
1645 * The result will be currently valid, or not, the same as the source.
1646 */
1649{
1650 CachedPlanSource *newsource;
1651 MemoryContext source_context;
1652 MemoryContext querytree_context;
1653 MemoryContext oldcxt;
1654
1655 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1656 Assert(plansource->is_complete);
1657
1658 /*
1659 * One-shot plans can't be copied, because we haven't taken care that
1660 * parsing/planning didn't scribble on the raw parse tree or querytrees.
1661 */
1662 if (plansource->is_oneshot)
1663 elog(ERROR, "cannot copy a one-shot cached plan");
1664
1666 "CachedPlanSource",
1668
1669 oldcxt = MemoryContextSwitchTo(source_context);
1670
1671 newsource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
1672 newsource->magic = CACHEDPLANSOURCE_MAGIC;
1673 newsource->raw_parse_tree = copyObject(plansource->raw_parse_tree);
1674 newsource->analyzed_parse_tree = copyObject(plansource->analyzed_parse_tree);
1675 newsource->query_string = pstrdup(plansource->query_string);
1676 MemoryContextSetIdentifier(source_context, newsource->query_string);
1677 newsource->commandTag = plansource->commandTag;
1678 if (plansource->num_params > 0)
1679 {
1680 newsource->param_types = (Oid *)
1681 palloc(plansource->num_params * sizeof(Oid));
1682 memcpy(newsource->param_types, plansource->param_types,
1683 plansource->num_params * sizeof(Oid));
1684 }
1685 else
1686 newsource->param_types = NULL;
1687 newsource->num_params = plansource->num_params;
1688 newsource->parserSetup = plansource->parserSetup;
1689 newsource->parserSetupArg = plansource->parserSetupArg;
1690 newsource->postRewrite = plansource->postRewrite;
1691 newsource->postRewriteArg = plansource->postRewriteArg;
1692 newsource->cursor_options = plansource->cursor_options;
1693 newsource->fixed_result = plansource->fixed_result;
1694 if (plansource->resultDesc)
1695 newsource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
1696 else
1697 newsource->resultDesc = NULL;
1698 newsource->context = source_context;
1699
1700 querytree_context = AllocSetContextCreate(source_context,
1701 "CachedPlanQuery",
1703 MemoryContextSwitchTo(querytree_context);
1704 newsource->query_list = copyObject(plansource->query_list);
1705 newsource->relationOids = copyObject(plansource->relationOids);
1706 newsource->invalItems = copyObject(plansource->invalItems);
1707 if (plansource->search_path)
1708 newsource->search_path = CopySearchPathMatcher(plansource->search_path);
1709 newsource->query_context = querytree_context;
1710 newsource->rewriteRoleId = plansource->rewriteRoleId;
1711 newsource->rewriteRowSecurity = plansource->rewriteRowSecurity;
1712 newsource->dependsOnRLS = plansource->dependsOnRLS;
1713
1714 newsource->gplan = NULL;
1715
1716 newsource->is_oneshot = false;
1717 newsource->is_complete = true;
1718 newsource->is_saved = false;
1719 newsource->is_valid = plansource->is_valid;
1720 newsource->generation = plansource->generation;
1721
1722 /* We may as well copy any acquired cost knowledge */
1723 newsource->generic_cost = plansource->generic_cost;
1724 newsource->total_custom_cost = plansource->total_custom_cost;
1725 newsource->num_generic_plans = plansource->num_generic_plans;
1726 newsource->num_custom_plans = plansource->num_custom_plans;
1727
1728 MemoryContextSwitchTo(oldcxt);
1729
1730 return newsource;
1731}
1732
1733/*
1734 * CachedPlanIsValid: test whether the rewritten querytree within a
1735 * CachedPlanSource is currently valid (that is, not marked as being in need
1736 * of revalidation).
1737 *
1738 * This result is only trustworthy (ie, free from race conditions) if
1739 * the caller has acquired locks on all the relations used in the plan.
1740 */
1741bool
1743{
1744 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1745 return plansource->is_valid;
1746}
1747
1748/*
1749 * CachedPlanGetTargetList: return tlist, if any, describing plan's output
1750 *
1751 * The result is guaranteed up-to-date. However, it is local storage
1752 * within the cached plan, and may disappear next time the plan is updated.
1753 */
1754List *
1756 QueryEnvironment *queryEnv)
1757{
1758 Query *pstmt;
1759
1760 /* Assert caller is doing things in a sane order */
1761 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1762 Assert(plansource->is_complete);
1763
1764 /*
1765 * No work needed if statement doesn't return tuples (we assume this
1766 * feature cannot be changed by an invalidation)
1767 */
1768 if (plansource->resultDesc == NULL)
1769 return NIL;
1770
1771 /* Make sure the querytree list is valid and we have parse-time locks */
1772 RevalidateCachedQuery(plansource, queryEnv);
1773
1774 /* Get the primary statement and find out what it returns */
1775 pstmt = QueryListGetPrimaryStmt(plansource->query_list);
1776
1777 return FetchStatementTargetList((Node *) pstmt);
1778}
1779
1780/*
1781 * GetCachedExpression: construct a CachedExpression for an expression.
1782 *
1783 * This performs the same transformations on the expression as
1784 * expression_planner(), ie, convert an expression as emitted by parse
1785 * analysis to be ready to pass to the executor.
1786 *
1787 * The result is stashed in a private, long-lived memory context.
1788 * (Note that this might leak a good deal of memory in the caller's
1789 * context before that.) The passed-in expr tree is not modified.
1790 */
1793{
1794 CachedExpression *cexpr;
1795 List *relationOids;
1796 List *invalItems;
1797 MemoryContext cexpr_context;
1798 MemoryContext oldcxt;
1799
1800 /*
1801 * Pass the expression through the planner, and collect dependencies.
1802 * Everything built here is leaked in the caller's context; that's
1803 * intentional to minimize the size of the permanent data structure.
1804 */
1805 expr = (Node *) expression_planner_with_deps((Expr *) expr,
1806 &relationOids,
1807 &invalItems);
1808
1809 /*
1810 * Make a private memory context, and copy what we need into that. To
1811 * avoid leaking a long-lived context if we fail while copying data, we
1812 * initially make the context under the caller's context.
1813 */
1815 "CachedExpression",
1817
1818 oldcxt = MemoryContextSwitchTo(cexpr_context);
1819
1820 cexpr = (CachedExpression *) palloc(sizeof(CachedExpression));
1821 cexpr->magic = CACHEDEXPR_MAGIC;
1822 cexpr->expr = copyObject(expr);
1823 cexpr->is_valid = true;
1824 cexpr->relationOids = copyObject(relationOids);
1825 cexpr->invalItems = copyObject(invalItems);
1826 cexpr->context = cexpr_context;
1827
1828 MemoryContextSwitchTo(oldcxt);
1829
1830 /*
1831 * Reparent the expr's memory context under CacheMemoryContext so that it
1832 * will live indefinitely.
1833 */
1835
1836 /*
1837 * Add the entry to the global list of cached expressions.
1838 */
1840
1841 return cexpr;
1842}
1843
1844/*
1845 * FreeCachedExpression
1846 * Delete a CachedExpression.
1847 */
1848void
1850{
1851 /* Sanity check */
1852 Assert(cexpr->magic == CACHEDEXPR_MAGIC);
1853 /* Unlink from global list */
1854 dlist_delete(&cexpr->node);
1855 /* Free all storage associated with CachedExpression */
1857}
1858
1859/*
1860 * QueryListGetPrimaryStmt
1861 * Get the "primary" stmt within a list, ie, the one marked canSetTag.
1862 *
1863 * Returns NULL if no such stmt. If multiple queries within the list are
1864 * marked canSetTag, returns the first one. Neither of these cases should
1865 * occur in present usages of this function.
1866 */
1867static Query *
1869{
1870 ListCell *lc;
1871
1872 foreach(lc, stmts)
1873 {
1874 Query *stmt = lfirst_node(Query, lc);
1875
1876 if (stmt->canSetTag)
1877 return stmt;
1878 }
1879 return NULL;
1880}
1881
1882/*
1883 * AcquireExecutorLocks: acquire locks needed for execution of a cached plan;
1884 * or release them if acquire is false.
1885 */
1886static void
1887AcquireExecutorLocks(List *stmt_list, bool acquire)
1888{
1889 ListCell *lc1;
1890
1891 foreach(lc1, stmt_list)
1892 {
1893 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc1);
1894 ListCell *lc2;
1895
1896 if (plannedstmt->commandType == CMD_UTILITY)
1897 {
1898 /*
1899 * Ignore utility statements, except those (such as EXPLAIN) that
1900 * contain a parsed-but-not-planned query. Note: it's okay to use
1901 * ScanQueryForLocks, even though the query hasn't been through
1902 * rule rewriting, because rewriting doesn't change the query
1903 * representation.
1904 */
1905 Query *query = UtilityContainsQuery(plannedstmt->utilityStmt);
1906
1907 if (query)
1908 ScanQueryForLocks(query, acquire);
1909 continue;
1910 }
1911
1912 foreach(lc2, plannedstmt->rtable)
1913 {
1914 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
1915
1916 if (!(rte->rtekind == RTE_RELATION ||
1917 (rte->rtekind == RTE_SUBQUERY && OidIsValid(rte->relid))))
1918 continue;
1919
1920 /*
1921 * Acquire the appropriate type of lock on each relation OID. Note
1922 * that we don't actually try to open the rel, and hence will not
1923 * fail if it's been dropped entirely --- we'll just transiently
1924 * acquire a non-conflicting lock.
1925 */
1926 if (acquire)
1927 LockRelationOid(rte->relid, rte->rellockmode);
1928 else
1929 UnlockRelationOid(rte->relid, rte->rellockmode);
1930 }
1931 }
1932}
1933
1934/*
1935 * AcquirePlannerLocks: acquire locks needed for planning of a querytree list;
1936 * or release them if acquire is false.
1937 *
1938 * Note that we don't actually try to open the relations, and hence will not
1939 * fail if one has been dropped entirely --- we'll just transiently acquire
1940 * a non-conflicting lock.
1941 */
1942static void
1943AcquirePlannerLocks(List *stmt_list, bool acquire)
1944{
1945 ListCell *lc;
1946
1947 foreach(lc, stmt_list)
1948 {
1949 Query *query = lfirst_node(Query, lc);
1950
1951 if (query->commandType == CMD_UTILITY)
1952 {
1953 /* Ignore utility statements, unless they contain a Query */
1954 query = UtilityContainsQuery(query->utilityStmt);
1955 if (query)
1956 ScanQueryForLocks(query, acquire);
1957 continue;
1958 }
1959
1960 ScanQueryForLocks(query, acquire);
1961 }
1962}
1963
1964/*
1965 * ScanQueryForLocks: recursively scan one Query for AcquirePlannerLocks.
1966 */
1967static void
1968ScanQueryForLocks(Query *parsetree, bool acquire)
1969{
1970 ListCell *lc;
1971
1972 /* Shouldn't get called on utility commands */
1973 Assert(parsetree->commandType != CMD_UTILITY);
1974
1975 /*
1976 * First, process RTEs of the current query level.
1977 */
1978 foreach(lc, parsetree->rtable)
1979 {
1980 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
1981
1982 switch (rte->rtekind)
1983 {
1984 case RTE_RELATION:
1985 /* Acquire or release the appropriate type of lock */
1986 if (acquire)
1987 LockRelationOid(rte->relid, rte->rellockmode);
1988 else
1989 UnlockRelationOid(rte->relid, rte->rellockmode);
1990 break;
1991
1992 case RTE_SUBQUERY:
1993 /* If this was a view, must lock/unlock the view */
1994 if (OidIsValid(rte->relid))
1995 {
1996 if (acquire)
1997 LockRelationOid(rte->relid, rte->rellockmode);
1998 else
1999 UnlockRelationOid(rte->relid, rte->rellockmode);
2000 }
2001 /* Recurse into subquery-in-FROM */
2002 ScanQueryForLocks(rte->subquery, acquire);
2003 break;
2004
2005 default:
2006 /* ignore other types of RTEs */
2007 break;
2008 }
2009 }
2010
2011 /* Recurse into subquery-in-WITH */
2012 foreach(lc, parsetree->cteList)
2013 {
2015
2016 ScanQueryForLocks(castNode(Query, cte->ctequery), acquire);
2017 }
2018
2019 /*
2020 * Recurse into sublink subqueries, too. But we already did the ones in
2021 * the rtable and cteList.
2022 */
2023 if (parsetree->hasSubLinks)
2024 {
2025 query_tree_walker(parsetree, ScanQueryWalker, &acquire,
2027 }
2028}
2029
2030/*
2031 * Walker to find sublink subqueries for ScanQueryForLocks
2032 */
2033static bool
2034ScanQueryWalker(Node *node, bool *acquire)
2035{
2036 if (node == NULL)
2037 return false;
2038 if (IsA(node, SubLink))
2039 {
2040 SubLink *sub = (SubLink *) node;
2041
2042 /* Do what we came for */
2043 ScanQueryForLocks(castNode(Query, sub->subselect), *acquire);
2044 /* Fall through to process lefthand args of SubLink */
2045 }
2046
2047 /*
2048 * Do NOT recurse into Query nodes, because ScanQueryForLocks already
2049 * processed subselects of subselects for us.
2050 */
2051 return expression_tree_walker(node, ScanQueryWalker, acquire);
2052}
2053
2054/*
2055 * PlanCacheComputeResultDesc: given a list of analyzed-and-rewritten Queries,
2056 * determine the result tupledesc it will produce. Returns NULL if the
2057 * execution will not return tuples.
2058 *
2059 * Note: the result is created or copied into current memory context.
2060 */
2061static TupleDesc
2063{
2064 Query *query;
2065
2066 switch (ChoosePortalStrategy(stmt_list))
2067 {
2068 case PORTAL_ONE_SELECT:
2070 query = linitial_node(Query, stmt_list);
2071 return ExecCleanTypeFromTL(query->targetList);
2072
2074 query = QueryListGetPrimaryStmt(stmt_list);
2075 Assert(query->returningList);
2076 return ExecCleanTypeFromTL(query->returningList);
2077
2078 case PORTAL_UTIL_SELECT:
2079 query = linitial_node(Query, stmt_list);
2080 Assert(query->utilityStmt);
2081 return UtilityTupleDescriptor(query->utilityStmt);
2082
2083 case PORTAL_MULTI_QUERY:
2084 /* will not return tuples */
2085 break;
2086 }
2087 return NULL;
2088}
2089
2090/*
2091 * PlanCacheRelCallback
2092 * Relcache inval callback function
2093 *
2094 * Invalidate all plans mentioning the given rel, or all plans mentioning
2095 * any rel at all if relid == InvalidOid.
2096 */
2097static void
2099{
2100 dlist_iter iter;
2101
2103 {
2105 node, iter.cur);
2106
2107 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
2108
2109 /* No work if it's already invalidated */
2110 if (!plansource->is_valid)
2111 continue;
2112
2113 /* Never invalidate if parse/plan would be a no-op anyway */
2114 if (!StmtPlanRequiresRevalidation(plansource))
2115 continue;
2116
2117 /*
2118 * Check the dependency list for the rewritten querytree.
2119 */
2120 if ((relid == InvalidOid) ? plansource->relationOids != NIL :
2121 list_member_oid(plansource->relationOids, relid))
2122 {
2123 /* Invalidate the querytree and generic plan */
2124 plansource->is_valid = false;
2125 if (plansource->gplan)
2126 plansource->gplan->is_valid = false;
2127 }
2128
2129 /*
2130 * The generic plan, if any, could have more dependencies than the
2131 * querytree does, so we have to check it too.
2132 */
2133 if (plansource->gplan && plansource->gplan->is_valid)
2134 {
2135 ListCell *lc;
2136
2137 foreach(lc, plansource->gplan->stmt_list)
2138 {
2139 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
2140
2141 if (plannedstmt->commandType == CMD_UTILITY)
2142 continue; /* Ignore utility statements */
2143 if ((relid == InvalidOid) ? plannedstmt->relationOids != NIL :
2144 list_member_oid(plannedstmt->relationOids, relid))
2145 {
2146 /* Invalidate the generic plan only */
2147 plansource->gplan->is_valid = false;
2148 break; /* out of stmt_list scan */
2149 }
2150 }
2151 }
2152 }
2153
2154 /* Likewise check cached expressions */
2156 {
2158 node, iter.cur);
2159
2160 Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2161
2162 /* No work if it's already invalidated */
2163 if (!cexpr->is_valid)
2164 continue;
2165
2166 if ((relid == InvalidOid) ? cexpr->relationOids != NIL :
2167 list_member_oid(cexpr->relationOids, relid))
2168 {
2169 cexpr->is_valid = false;
2170 }
2171 }
2172}
2173
2174/*
2175 * PlanCacheObjectCallback
2176 * Syscache inval callback function for PROCOID and TYPEOID caches
2177 *
2178 * Invalidate all plans mentioning the object with the specified hash value,
2179 * or all plans mentioning any member of this cache if hashvalue == 0.
2180 */
2181static void
2182PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue)
2183{
2184 dlist_iter iter;
2185
2187 {
2189 node, iter.cur);
2190 ListCell *lc;
2191
2192 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
2193
2194 /* No work if it's already invalidated */
2195 if (!plansource->is_valid)
2196 continue;
2197
2198 /* Never invalidate if parse/plan would be a no-op anyway */
2199 if (!StmtPlanRequiresRevalidation(plansource))
2200 continue;
2201
2202 /*
2203 * Check the dependency list for the rewritten querytree.
2204 */
2205 foreach(lc, plansource->invalItems)
2206 {
2207 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
2208
2209 if (item->cacheId != cacheid)
2210 continue;
2211 if (hashvalue == 0 ||
2212 item->hashValue == hashvalue)
2213 {
2214 /* Invalidate the querytree and generic plan */
2215 plansource->is_valid = false;
2216 if (plansource->gplan)
2217 plansource->gplan->is_valid = false;
2218 break;
2219 }
2220 }
2221
2222 /*
2223 * The generic plan, if any, could have more dependencies than the
2224 * querytree does, so we have to check it too.
2225 */
2226 if (plansource->gplan && plansource->gplan->is_valid)
2227 {
2228 foreach(lc, plansource->gplan->stmt_list)
2229 {
2230 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
2231 ListCell *lc3;
2232
2233 if (plannedstmt->commandType == CMD_UTILITY)
2234 continue; /* Ignore utility statements */
2235 foreach(lc3, plannedstmt->invalItems)
2236 {
2237 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc3);
2238
2239 if (item->cacheId != cacheid)
2240 continue;
2241 if (hashvalue == 0 ||
2242 item->hashValue == hashvalue)
2243 {
2244 /* Invalidate the generic plan only */
2245 plansource->gplan->is_valid = false;
2246 break; /* out of invalItems scan */
2247 }
2248 }
2249 if (!plansource->gplan->is_valid)
2250 break; /* out of stmt_list scan */
2251 }
2252 }
2253 }
2254
2255 /* Likewise check cached expressions */
2257 {
2259 node, iter.cur);
2260 ListCell *lc;
2261
2262 Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2263
2264 /* No work if it's already invalidated */
2265 if (!cexpr->is_valid)
2266 continue;
2267
2268 foreach(lc, cexpr->invalItems)
2269 {
2270 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
2271
2272 if (item->cacheId != cacheid)
2273 continue;
2274 if (hashvalue == 0 ||
2275 item->hashValue == hashvalue)
2276 {
2277 cexpr->is_valid = false;
2278 break;
2279 }
2280 }
2281 }
2282}
2283
2284/*
2285 * PlanCacheSysCallback
2286 * Syscache inval callback function for other caches
2287 *
2288 * Just invalidate everything...
2289 */
2290static void
2291PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
2292{
2294}
2295
2296/*
2297 * ResetPlanCache: invalidate all cached plans.
2298 */
2299void
2301{
2302 dlist_iter iter;
2303
2305 {
2307 node, iter.cur);
2308
2309 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
2310
2311 /* No work if it's already invalidated */
2312 if (!plansource->is_valid)
2313 continue;
2314
2315 /*
2316 * We *must not* mark transaction control statements as invalid,
2317 * particularly not ROLLBACK, because they may need to be executed in
2318 * aborted transactions when we can't revalidate them (cf bug #5269).
2319 * In general there's no point in invalidating statements for which a
2320 * new parse analysis/rewrite/plan cycle would certainly give the same
2321 * results.
2322 */
2323 if (!StmtPlanRequiresRevalidation(plansource))
2324 continue;
2325
2326 plansource->is_valid = false;
2327 if (plansource->gplan)
2328 plansource->gplan->is_valid = false;
2329 }
2330
2331 /* Likewise invalidate cached expressions */
2333 {
2335 node, iter.cur);
2336
2337 Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2338
2339 cexpr->is_valid = false;
2340 }
2341}
2342
2343/*
2344 * Release all CachedPlans remembered by 'owner'
2345 */
2346void
2348{
2350}
2351
2352/* ResourceOwner callbacks */
2353
2354static void
2356{
2358}
uint32_t uint32
Definition: c.h:502
#define OidIsValid(objectId)
Definition: c.h:746
CommandTag
Definition: cmdtag.h:23
double cpu_operator_cost
Definition: costsize.c:134
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
TupleDesc ExecCleanTypeFromTL(List *targetList)
Definition: execTuples.c:2139
bool row_security
Definition: guc_tables.c:527
Assert(PointerIsAligned(start, uint64))
#define dlist_foreach(iter, lhead)
Definition: ilist.h:623
static void dlist_delete(dlist_node *node)
Definition: ilist.h:405
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition: ilist.h:364
#define DLIST_STATIC_INIT(name)
Definition: ilist.h:281
#define dlist_container(type, membername, ptr)
Definition: ilist.h:593
#define stmt
Definition: indent_codes.h:59
void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func, Datum arg)
Definition: inval.c:1854
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1812
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:722
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:229
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:107
char * pstrdup(const char *in)
Definition: mcxt.c:1703
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:637
void * palloc0(Size size)
Definition: mcxt.c:1351
void * palloc(Size size)
Definition: mcxt.c:1321
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
MemoryContext MemoryContextGetParent(MemoryContext context)
Definition: mcxt.c:731
MemoryContext CacheMemoryContext
Definition: mcxt.c:152
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
Definition: mcxt.c:612
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_START_SMALL_SIZES
Definition: memutils.h:177
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:170
#define MemoryContextCopyAndSetIdentifier(cxt, id)
Definition: memutils.h:101
Oid GetUserId(void)
Definition: miscinit.c:520
SearchPathMatcher * GetSearchPathMatcher(MemoryContext context)
Definition: namespace.c:3852
bool SearchPathMatchesCurrentEnvironment(SearchPathMatcher *path)
Definition: namespace.c:3911
SearchPathMatcher * CopySearchPathMatcher(SearchPathMatcher *path)
Definition: namespace.c:3889
#define query_tree_walker(q, w, c, f)
Definition: nodeFuncs.h:158
#define expression_tree_walker(n, w, c)
Definition: nodeFuncs.h:153
#define QTW_IGNORE_RC_SUBQUERIES
Definition: nodeFuncs.h:24
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
#define copyObject(obj)
Definition: nodes.h:230
@ CMD_UTILITY
Definition: nodes.h:276
#define castNode(_type_, nodeptr)
Definition: nodes.h:182
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
void(* ParserSetupHook)(struct ParseState *pstate, void *arg)
Definition: params.h:108
@ RTE_SUBQUERY
Definition: parsenodes.h:1027
@ RTE_RELATION
Definition: parsenodes.h:1026
#define CURSOR_OPT_GENERIC_PLAN
Definition: parsenodes.h:3383
#define CURSOR_OPT_CUSTOM_PLAN
Definition: parsenodes.h:3384
bool analyze_requires_snapshot(RawStmt *parseTree)
Definition: analyze.c:571
bool query_requires_rewrite_plan(Query *query)
Definition: analyze.c:600
bool stmt_requires_parse_analysis(RawStmt *parseTree)
Definition: analyze.c:527
void * arg
#define lfirst(lc)
Definition: pg_list.h:172
#define lfirst_node(type, lc)
Definition: pg_list.h:176
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial_node(type, l)
Definition: pg_list.h:181
#define NIL
Definition: pg_list.h:68
#define plan(x)
Definition: pg_regress.c:161
void CachedPlanSetParentContext(CachedPlanSource *plansource, MemoryContext newcontext)
Definition: plancache.c:1610
bool CachedPlanIsValid(CachedPlanSource *plansource)
Definition: plancache.c:1742
static dlist_head cached_expression_list
Definition: plancache.c:89
void DropCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:574
static bool choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams)
Definition: plancache.c:1158
bool CachedPlanAllowsSimpleValidityCheck(CachedPlanSource *plansource, CachedPlan *plan, ResourceOwner owner)
Definition: plancache.c:1448
static void ReleaseGenericPlan(CachedPlanSource *plansource)
Definition: plancache.c:603
static CachedPlan * BuildCachedPlan(CachedPlanSource *plansource, List *qlist, ParamListInfo boundParams, QueryEnvironment *queryEnv)
Definition: plancache.c:1019
static bool CheckCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:935
int plan_cache_mode
Definition: plancache.c:138
void FreeCachedExpression(CachedExpression *cexpr)
Definition: plancache.c:1849
void SaveCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:530
static bool StmtPlanRequiresRevalidation(CachedPlanSource *plansource)
Definition: plancache.c:625
void CompleteCachedPlan(CachedPlanSource *plansource, List *querytree_list, MemoryContext querytree_context, Oid *param_types, int num_params, ParserSetupHook parserSetup, void *parserSetupArg, int cursor_options, bool fixed_result)
Definition: plancache.c:391
static void ResourceOwnerRememberPlanCacheRef(ResourceOwner owner, CachedPlan *plan)
Definition: plancache.c:126
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)
Definition: plancache.c:1280
CachedExpression * GetCachedExpression(Node *expr)
Definition: plancache.c:1792
bool CachedPlanIsSimplyValid(CachedPlanSource *plansource, CachedPlan *plan, ResourceOwner owner)
Definition: plancache.c:1563
CachedPlanSource * CreateOneShotCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)
Definition: plancache.c:298
CachedPlanSource * CreateCachedPlanForQuery(Query *analyzed_parse_tree, const char *query_string, CommandTag commandTag)
Definition: plancache.c:263
static bool ScanQueryWalker(Node *node, bool *acquire)
Definition: plancache.c:2034
void SetPostRewriteHook(CachedPlanSource *plansource, PostRewriteHook postRewrite, void *postRewriteArg)
Definition: plancache.c:505
static const ResourceOwnerDesc planref_resowner_desc
Definition: plancache.c:115
static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: plancache.c:2291
static List * RevalidateCachedQuery(CachedPlanSource *plansource, QueryEnvironment *queryEnv)
Definition: plancache.c:667
CachedPlanSource * CreateCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)
Definition: plancache.c:183
static void PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: plancache.c:2182
List * CachedPlanGetTargetList(CachedPlanSource *plansource, QueryEnvironment *queryEnv)
Definition: plancache.c:1755
CachedPlanSource * CopyCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:1648
void ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner)
Definition: plancache.c:1403
static TupleDesc PlanCacheComputeResultDesc(List *stmt_list)
Definition: plancache.c:2062
static dlist_head saved_plan_list
Definition: plancache.c:84
void InitPlanCache(void)
Definition: plancache.c:146
static void AcquirePlannerLocks(List *stmt_list, bool acquire)
Definition: plancache.c:1943
static void ResourceOwnerForgetPlanCacheRef(ResourceOwner owner, CachedPlan *plan)
Definition: plancache.c:131
static double cached_plan_cost(CachedPlan *plan, bool include_planner)
Definition: plancache.c:1215
static void ResOwnerReleaseCachedPlan(Datum res)
Definition: plancache.c:2355
static void ScanQueryForLocks(Query *parsetree, bool acquire)
Definition: plancache.c:1968
void ReleaseAllPlanCacheRefsInOwner(ResourceOwner owner)
Definition: plancache.c:2347
void ResetPlanCache(void)
Definition: plancache.c:2300
static void PlanCacheRelCallback(Datum arg, Oid relid)
Definition: plancache.c:2098
static Query * QueryListGetPrimaryStmt(List *stmts)
Definition: plancache.c:1868
static bool BuildingPlanRequiresSnapshot(CachedPlanSource *plansource)
Definition: plancache.c:642
static void AcquireExecutorLocks(List *stmt_list, bool acquire)
Definition: plancache.c:1887
void(* PostRewriteHook)(List *querytree_list, void *arg)
Definition: plancache.h:42
#define CACHEDPLAN_MAGIC
Definition: plancache.h:45
#define CACHEDPLANSOURCE_MAGIC
Definition: plancache.h:44
#define CACHEDEXPR_MAGIC
Definition: plancache.h:46
@ PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN
Definition: plancache.h:35
@ PLAN_CACHE_MODE_FORCE_GENERIC_PLAN
Definition: plancache.h:34
@ PLAN_CACHE_MODE_AUTO
Definition: plancache.h:33
Expr * expression_planner_with_deps(Expr *expr, List **relationOids, List **invalItems)
Definition: planner.c:6718
@ PORTAL_ONE_RETURNING
Definition: portal.h:92
@ PORTAL_MULTI_QUERY
Definition: portal.h:95
@ PORTAL_ONE_SELECT
Definition: portal.h:91
@ PORTAL_ONE_MOD_WITH
Definition: portal.h:93
@ PORTAL_UTIL_SELECT
Definition: portal.h:94
List * pg_analyze_and_rewrite_withcb(RawStmt *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg, QueryEnvironment *queryEnv)
Definition: postgres.c:758
List * pg_plan_queries(List *querytrees, const char *query_string, int cursorOptions, ParamListInfo boundParams)
Definition: postgres.c:970
List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
Definition: postgres.c:665
List * pg_rewrite_query(Query *query)
Definition: postgres.c:798
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
uintptr_t Datum
Definition: postgres.h:69
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
#define InvalidOid
Definition: postgres_ext.h:35
unsigned int Oid
Definition: postgres_ext.h:30
PortalStrategy ChoosePortalStrategy(List *stmts)
Definition: pquery.c:210
List * FetchStatementTargetList(Node *stmt)
Definition: pquery.c:349
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:564
void ResourceOwnerReleaseAllOfKind(ResourceOwner owner, const ResourceOwnerDesc *kind)
Definition: resowner.c:818
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:524
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:452
#define RELEASE_PRIO_PLANCACHE_REFS
Definition: resowner.h:73
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:56
void AcquireRewriteLocks(Query *parsetree, bool forExecute, bool forUpdatePushedDown)
void extract_query_dependencies(Node *query, List **relationOids, List **invalItems, bool *hasRowSecurity)
Definition: setrefs.c:3631
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:271
void PushActiveSnapshot(Snapshot snapshot)
Definition: snapmgr.c:669
TransactionId TransactionXmin
Definition: snapmgr.c:158
bool ActiveSnapshotSet(void)
Definition: snapmgr.c:799
void PopActiveSnapshot(void)
Definition: snapmgr.c:762
List * relationOids
Definition: plancache.h:193
MemoryContext context
Definition: plancache.h:195
dlist_node node
Definition: plancache.h:196
List * invalItems
Definition: plancache.h:194
dlist_node node
Definition: plancache.h:141
struct CachedPlan * gplan
Definition: plancache.h:133
PostRewriteHook postRewrite
Definition: plancache.h:116
struct Query * analyzed_parse_tree
Definition: plancache.h:109
struct SearchPathMatcher * search_path
Definition: plancache.h:126
MemoryContext query_context
Definition: plancache.h:128
CommandTag commandTag
Definition: plancache.h:111
double total_custom_cost
Definition: plancache.h:144
MemoryContext context
Definition: plancache.h:121
List * invalItems
Definition: plancache.h:125
const char * query_string
Definition: plancache.h:110
ParserSetupHook parserSetup
Definition: plancache.h:114
struct RawStmt * raw_parse_tree
Definition: plancache.h:108
TupleDesc resultDesc
Definition: plancache.h:120
int64 num_custom_plans
Definition: plancache.h:145
int64 num_generic_plans
Definition: plancache.h:146
bool rewriteRowSecurity
Definition: plancache.h:130
List * query_list
Definition: plancache.h:123
void * postRewriteArg
Definition: plancache.h:117
List * relationOids
Definition: plancache.h:124
double generic_cost
Definition: plancache.h:143
void * parserSetupArg
Definition: plancache.h:115
bool is_valid
Definition: plancache.h:165
MemoryContext context
Definition: plancache.h:172
List * stmt_list
Definition: plancache.h:162
Definition: pg_list.h:54
Definition: nodes.h:135
uint32 hashValue
Definition: plannodes.h:1747
Cost total_cost
Definition: plannodes.h:172
struct Plan * planTree
Definition: plannodes.h:83
List * invalItems
Definition: plannodes.h:126
bool transientPlan
Definition: plannodes.h:71
List * relationOids
Definition: plannodes.h:123
bool dependsOnRole
Definition: plannodes.h:74
CmdType commandType
Definition: plannodes.h:53
Node * utilityStmt
Definition: plannodes.h:132
List * rtable
Definition: plannodes.h:91
List * returningList
Definition: parsenodes.h:209
List * cteList
Definition: parsenodes.h:168
List * rtable
Definition: parsenodes.h:170
CmdType commandType
Definition: parsenodes.h:121
Node * utilityStmt
Definition: parsenodes.h:136
List * targetList
Definition: parsenodes.h:193
Query * subquery
Definition: parsenodes.h:1118
RTEKind rtekind
Definition: parsenodes.h:1061
const char * name
Definition: resowner.h:93
dlist_node * cur
Definition: ilist.h:179
#define InvalidTransactionId
Definition: transam.h:31
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:495
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:245
bool equalRowTypes(TupleDesc tupdesc1, TupleDesc tupdesc2)
Definition: tupdesc.c:770
Query * UtilityContainsQuery(Node *parsetree)
Definition: utility.c:2179
TupleDesc UtilityTupleDescriptor(Node *parsetree)
Definition: utility.c:2084