Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

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