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