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