PostgreSQL Source Code git master
Loading...
Searching...
No Matches
plancache.h File Reference
#include "access/tupdesc.h"
#include "lib/ilist.h"
#include "nodes/params.h"
#include "tcop/cmdtag.h"
#include "utils/queryenvironment.h"
#include "utils/resowner.h"
Include dependency graph for plancache.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  CachedPlanSource
 
struct  CachedPlan
 
struct  CachedExpression
 

Macros

#define CACHEDPLANSOURCE_MAGIC   195726186
 
#define CACHEDPLAN_MAGIC   953717834
 
#define CACHEDEXPR_MAGIC   838275847
 

Typedefs

typedef struct Query Query
 
typedef struct RawStmt RawStmt
 
typedef void(* PostRewriteHook) (List *querytree_list, void *arg)
 
typedef struct CachedPlanSource CachedPlanSource
 
typedef struct CachedPlan CachedPlan
 
typedef struct CachedExpression CachedExpression
 

Enumerations

enum  PlanCacheMode { PLAN_CACHE_MODE_AUTO , PLAN_CACHE_MODE_FORCE_GENERIC_PLAN , PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN }
 

Functions

void InitPlanCache (void)
 
void ResetPlanCache (void)
 
void ReleaseAllPlanCacheRefsInOwner (ResourceOwner owner)
 
CachedPlanSourceCreateCachedPlan (RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)
 
CachedPlanSourceCreateCachedPlanForQuery (Query *analyzed_parse_tree, const char *query_string, CommandTag commandTag)
 
CachedPlanSourceCreateOneShotCachedPlan (RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)
 
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)
 
void SetPostRewriteHook (CachedPlanSource *plansource, PostRewriteHook postRewrite, void *postRewriteArg)
 
void SaveCachedPlan (CachedPlanSource *plansource)
 
void DropCachedPlan (CachedPlanSource *plansource)
 
void CachedPlanSetParentContext (CachedPlanSource *plansource, MemoryContext newcontext)
 
CachedPlanSourceCopyCachedPlan (CachedPlanSource *plansource)
 
bool CachedPlanIsValid (CachedPlanSource *plansource)
 
ListCachedPlanGetTargetList (CachedPlanSource *plansource, QueryEnvironment *queryEnv)
 
CachedPlanGetCachedPlan (CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)
 
void ReleaseCachedPlan (CachedPlan *plan, ResourceOwner owner)
 
bool CachedPlanAllowsSimpleValidityCheck (CachedPlanSource *plansource, CachedPlan *plan, ResourceOwner owner)
 
bool CachedPlanIsSimplyValid (CachedPlanSource *plansource, CachedPlan *plan, ResourceOwner owner)
 
CachedExpressionGetCachedExpression (Node *expr)
 
void FreeCachedExpression (CachedExpression *cexpr)
 

Variables

PGDLLIMPORT int plan_cache_mode
 

Macro Definition Documentation

◆ CACHEDEXPR_MAGIC

#define CACHEDEXPR_MAGIC   838275847

Definition at line 46 of file plancache.h.

◆ CACHEDPLAN_MAGIC

#define CACHEDPLAN_MAGIC   953717834

Definition at line 45 of file plancache.h.

◆ CACHEDPLANSOURCE_MAGIC

#define CACHEDPLANSOURCE_MAGIC   195726186

Definition at line 44 of file plancache.h.

Typedef Documentation

◆ CachedExpression

◆ CachedPlan

◆ CachedPlanSource

◆ PostRewriteHook

typedef void(* PostRewriteHook) (List *querytree_list, void *arg)

Definition at line 42 of file plancache.h.

◆ Query

Definition at line 27 of file plancache.h.

◆ RawStmt

Definition at line 28 of file plancache.h.

Enumeration Type Documentation

◆ PlanCacheMode

Enumerator
PLAN_CACHE_MODE_AUTO 
PLAN_CACHE_MODE_FORCE_GENERIC_PLAN 
PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN 

Definition at line 31 of file plancache.h.

32{
PlanCacheMode
Definition plancache.h:32
@ 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

Function Documentation

◆ CachedPlanAllowsSimpleValidityCheck()

bool CachedPlanAllowsSimpleValidityCheck ( CachedPlanSource plansource,
CachedPlan plan,
ResourceOwner  owner 
)
extern

Definition at line 1473 of file plancache.c.

1475{
1476 ListCell *lc;
1477
1478 /*
1479 * Sanity-check that the caller gave us a validated generic plan. Notice
1480 * that we *don't* assert plansource->is_valid as you might expect; that's
1481 * because it's possible that that's already false when GetCachedPlan
1482 * returns, e.g. because ResetPlanCache happened partway through. We
1483 * should accept the plan as long as plan->is_valid is true, and expect to
1484 * replan after the next CachedPlanIsSimplyValid call.
1485 */
1486 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1487 Assert(plan->magic == CACHEDPLAN_MAGIC);
1488 Assert(plan->is_valid);
1489 Assert(plan == plansource->gplan);
1490 Assert(plansource->search_path != NULL);
1492
1493 /* We don't support oneshot plans here. */
1494 if (plansource->is_oneshot)
1495 return false;
1496 Assert(!plan->is_oneshot);
1497
1498 /*
1499 * If the plan is dependent on RLS considerations, or it's transient,
1500 * reject. These things probably can't ever happen for table-free
1501 * queries, but for safety's sake let's check.
1502 */
1503 if (plansource->dependsOnRLS)
1504 return false;
1505 if (plan->dependsOnRole)
1506 return false;
1507 if (TransactionIdIsValid(plan->saved_xmin))
1508 return false;
1509
1510 /*
1511 * Reject if AcquirePlannerLocks would have anything to do. This is
1512 * simplistic, but there's no need to inquire any more carefully; indeed,
1513 * for current callers it shouldn't even be possible to hit any of these
1514 * checks.
1515 */
1516 foreach(lc, plansource->query_list)
1517 {
1518 Query *query = lfirst_node(Query, lc);
1519
1520 if (query->commandType == CMD_UTILITY)
1521 return false;
1522 if (query->rtable || query->cteList || query->hasSubLinks)
1523 return false;
1524 }
1525
1526 /*
1527 * Reject if AcquireExecutorLocks would have anything to do. This is
1528 * probably unnecessary given the previous check, but let's be safe.
1529 */
1530 foreach(lc, plan->stmt_list)
1531 {
1532 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
1533 ListCell *lc2;
1534
1535 if (plannedstmt->commandType == CMD_UTILITY)
1536 return false;
1537
1538 /*
1539 * We have to grovel through the rtable because it's likely to contain
1540 * an RTE_RESULT relation, rather than being totally empty.
1541 */
1542 foreach(lc2, plannedstmt->rtable)
1543 {
1545
1546 if (rte->rtekind == RTE_RELATION)
1547 return false;
1548 }
1549 }
1550
1551 /*
1552 * Okay, it's simple. Note that what we've primarily established here is
1553 * that no locks need be taken before checking the plan's is_valid flag.
1554 */
1555
1556 /* Bump refcount if requested. */
1557 if (owner)
1558 {
1559 ResourceOwnerEnlarge(owner);
1560 plan->refcount++;
1562 }
1563
1564 return true;
1565}
#define Assert(condition)
Definition c.h:885
bool SearchPathMatchesCurrentEnvironment(SearchPathMatcher *path)
Definition namespace.c:3983
@ CMD_UTILITY
Definition nodes.h:280
@ RTE_RELATION
#define lfirst(lc)
Definition pg_list.h:172
#define lfirst_node(type, lc)
Definition pg_list.h:176
#define plan(x)
Definition pg_regress.c:161
static void ResourceOwnerRememberPlanCacheRef(ResourceOwner owner, CachedPlan *plan)
Definition plancache.c:128
#define CACHEDPLAN_MAGIC
Definition plancache.h:45
#define CACHEDPLANSOURCE_MAGIC
Definition plancache.h:44
static int fb(int x)
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition resowner.c:449
struct CachedPlan * gplan
Definition plancache.h:133
struct SearchPathMatcher * search_path
Definition plancache.h:126
CmdType commandType
Definition plannodes.h:68
List * rtable
Definition plannodes.h:109
List * cteList
Definition parsenodes.h:173
List * rtable
Definition parsenodes.h:175
CmdType commandType
Definition parsenodes.h:121
#define TransactionIdIsValid(xid)
Definition transam.h:41

References Assert, CACHEDPLAN_MAGIC, CACHEDPLANSOURCE_MAGIC, CMD_UTILITY, Query::commandType, PlannedStmt::commandType, Query::cteList, CachedPlanSource::dependsOnRLS, fb(), CachedPlanSource::gplan, CachedPlanSource::is_oneshot, lfirst, lfirst_node, CachedPlanSource::magic, plan, CachedPlanSource::query_list, ResourceOwnerEnlarge(), ResourceOwnerRememberPlanCacheRef(), Query::rtable, PlannedStmt::rtable, RTE_RELATION, CachedPlanSource::search_path, SearchPathMatchesCurrentEnvironment(), and TransactionIdIsValid.

Referenced by exec_eval_simple_expr(), and exec_simple_check_plan().

◆ CachedPlanGetTargetList()

List * CachedPlanGetTargetList ( CachedPlanSource plansource,
QueryEnvironment queryEnv 
)
extern

Definition at line 1779 of file plancache.c.

1781{
1782 Query *pstmt;
1783
1784 /* Assert caller is doing things in a sane order */
1785 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1786 Assert(plansource->is_complete);
1787
1788 /*
1789 * No work needed if statement doesn't return tuples (we assume this
1790 * feature cannot be changed by an invalidation)
1791 */
1792 if (plansource->resultDesc == NULL)
1793 return NIL;
1794
1795 /* Make sure the querytree list is valid and we have parse-time locks */
1796 RevalidateCachedQuery(plansource, queryEnv);
1797
1798 /* Get the primary statement and find out what it returns */
1799 pstmt = QueryListGetPrimaryStmt(plansource->query_list);
1800
1801 return FetchStatementTargetList((Node *) pstmt);
1802}
#define NIL
Definition pg_list.h:68
static List * RevalidateCachedQuery(CachedPlanSource *plansource, QueryEnvironment *queryEnv)
Definition plancache.c:684
static Query * QueryListGetPrimaryStmt(List *stmts)
Definition plancache.c:1892
List * FetchStatementTargetList(Node *stmt)
Definition pquery.c:344
TupleDesc resultDesc
Definition plancache.h:120
Definition nodes.h:135

References Assert, CACHEDPLANSOURCE_MAGIC, fb(), FetchStatementTargetList(), CachedPlanSource::is_complete, CachedPlanSource::magic, NIL, CachedPlanSource::query_list, QueryListGetPrimaryStmt(), CachedPlanSource::resultDesc, and RevalidateCachedQuery().

Referenced by exec_describe_statement_message(), and FetchPreparedStatementTargetList().

◆ CachedPlanIsSimplyValid()

bool CachedPlanIsSimplyValid ( CachedPlanSource plansource,
CachedPlan plan,
ResourceOwner  owner 
)
extern

Definition at line 1588 of file plancache.c.

1590{
1591 /*
1592 * Careful here: since the caller doesn't necessarily hold a refcount on
1593 * the plan to start with, it's possible that "plan" is a dangling
1594 * pointer. Don't dereference it until we've verified that it still
1595 * matches the plansource's gplan (which is either valid or NULL).
1596 */
1597 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1598
1599 /*
1600 * Has cache invalidation fired on this plan? We can check this right
1601 * away since there are no locks that we'd need to acquire first. Note
1602 * that here we *do* check plansource->is_valid, so as to force plan
1603 * rebuild if that's become false.
1604 */
1605 if (!plansource->is_valid ||
1606 plan == NULL || plan != plansource->gplan ||
1607 !plan->is_valid)
1608 return false;
1609
1610 Assert(plan->magic == CACHEDPLAN_MAGIC);
1611
1612 /* Is the search_path still the same as when we made it? */
1613 Assert(plansource->search_path != NULL);
1615 return false;
1616
1617 /* It's still good. Bump refcount if requested. */
1618 if (owner)
1619 {
1620 ResourceOwnerEnlarge(owner);
1621 plan->refcount++;
1623 }
1624
1625 return true;
1626}
bool is_valid
Definition plancache.h:165

References Assert, CACHEDPLAN_MAGIC, CACHEDPLANSOURCE_MAGIC, fb(), CachedPlanSource::gplan, CachedPlanSource::is_valid, CachedPlan::is_valid, CachedPlanSource::magic, plan, ResourceOwnerEnlarge(), ResourceOwnerRememberPlanCacheRef(), CachedPlanSource::search_path, and SearchPathMatchesCurrentEnvironment().

Referenced by exec_eval_simple_expr().

◆ CachedPlanIsValid()

bool CachedPlanIsValid ( CachedPlanSource plansource)
extern

Definition at line 1766 of file plancache.c.

1767{
1768 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1769 return plansource->is_valid;
1770}

References Assert, CACHEDPLANSOURCE_MAGIC, CachedPlanSource::is_valid, and CachedPlanSource::magic.

Referenced by SPI_plan_is_valid().

◆ CachedPlanSetParentContext()

void CachedPlanSetParentContext ( CachedPlanSource plansource,
MemoryContext  newcontext 
)
extern

Definition at line 1635 of file plancache.c.

1637{
1638 /* Assert caller is doing things in a sane order */
1639 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1640 Assert(plansource->is_complete);
1641
1642 /* These seem worth real tests, though */
1643 if (plansource->is_saved)
1644 elog(ERROR, "cannot move a saved cached plan to another context");
1645 if (plansource->is_oneshot)
1646 elog(ERROR, "cannot move a one-shot cached plan to another context");
1647
1648 /* OK, let the caller keep the plan where he wishes */
1650
1651 /*
1652 * The query_context needs no special handling, since it's a child of
1653 * plansource->context. But if there's a generic plan, it should be
1654 * maintained as a sibling of plansource->context.
1655 */
1656 if (plansource->gplan)
1657 {
1658 Assert(plansource->gplan->magic == CACHEDPLAN_MAGIC);
1660 }
1661}
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition mcxt.c:686
MemoryContext context
Definition plancache.h:121
MemoryContext context
Definition plancache.h:172

References Assert, CACHEDPLAN_MAGIC, CACHEDPLANSOURCE_MAGIC, CachedPlanSource::context, CachedPlan::context, elog, ERROR, fb(), CachedPlanSource::gplan, CachedPlanSource::is_complete, CachedPlanSource::is_oneshot, CachedPlanSource::is_saved, CachedPlanSource::magic, CachedPlan::magic, and MemoryContextSetParent().

Referenced by _SPI_make_plan_non_temp().

◆ CompleteCachedPlan()

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 
)
extern

Definition at line 393 of file plancache.c.

402{
405
406 /* Assert caller is doing things in a sane order */
407 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
408 Assert(!plansource->is_complete);
409
410 /*
411 * If caller supplied a querytree_context, reparent it underneath the
412 * CachedPlanSource's context; otherwise, create a suitable context and
413 * copy the querytree_list into it. But no data copying should be done
414 * for one-shot plans; for those, assume the passed querytree_list is
415 * sufficiently long-lived.
416 */
417 if (plansource->is_oneshot)
418 {
420 }
421 else if (querytree_context != NULL)
422 {
425 }
426 else
427 {
428 /* Again, it's a good bet the querytree_context can be small */
430 "CachedPlanQuery",
434 }
435
436 plansource->query_context = querytree_context;
437 plansource->query_list = querytree_list;
438
439 if (!plansource->is_oneshot && StmtPlanRequiresRevalidation(plansource))
440 {
441 /*
442 * Use the planner machinery to extract dependencies. Data is saved
443 * in query_context. (We assume that not a lot of extra cruft is
444 * created by this call.) We can skip this for one-shot plans, and
445 * plans not needing revalidation have no such dependencies anyway.
446 */
448 &plansource->relationOids,
449 &plansource->invalItems,
450 &plansource->dependsOnRLS);
451
452 /* Update RLS info as well. */
453 plansource->rewriteRoleId = GetUserId();
454 plansource->rewriteRowSecurity = row_security;
455
456 /*
457 * Also save the current search_path in the query_context. (This
458 * should not generate much extra cruft either, since almost certainly
459 * the path is already valid.) Again, we don't really need this for
460 * one-shot plans; and we *must* skip this for transaction control
461 * commands, because this could result in catalog accesses.
462 */
464 }
465
466 /*
467 * Save the final parameter types (or other parameter specification data)
468 * into the source_context, as well as our other parameters.
469 */
471
472 if (num_params > 0)
473 {
474 plansource->param_types = palloc_array(Oid, num_params);
475 memcpy(plansource->param_types, param_types, num_params * sizeof(Oid));
476 }
477 else
478 plansource->param_types = NULL;
479 plansource->num_params = num_params;
480 plansource->parserSetup = parserSetup;
481 plansource->parserSetupArg = parserSetupArg;
482 plansource->cursor_options = cursor_options;
483 plansource->fixed_result = fixed_result;
484
485 /*
486 * Also save the result tuple descriptor. PlanCacheComputeResultDesc may
487 * leak some cruft; normally we just accept that to save a copy step, but
488 * in USE_VALGRIND mode be tidy by running it in the caller's context.
489 */
490#ifdef USE_VALGRIND
493 if (plansource->resultDesc)
494 {
496 plansource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
498 }
499#else
502#endif
503
504 plansource->is_complete = true;
505 plansource->is_valid = true;
506}
#define palloc_array(type, count)
Definition fe_memutils.h:76
bool row_security
Definition guc_tables.c:538
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_START_SMALL_SIZES
Definition memutils.h:177
Oid GetUserId(void)
Definition miscinit.c:469
SearchPathMatcher * GetSearchPathMatcher(MemoryContext context)
Definition namespace.c:3924
#define copyObject(obj)
Definition nodes.h:232
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
static bool StmtPlanRequiresRevalidation(CachedPlanSource *plansource)
Definition plancache.c:642
static TupleDesc PlanCacheComputeResultDesc(List *stmt_list)
Definition plancache.c:2086
unsigned int Oid
void extract_query_dependencies(Node *query, List **relationOids, List **invalItems, bool *hasRowSecurity)
Definition setrefs.c:3707
MemoryContext query_context
Definition plancache.h:128
ParserSetupHook parserSetup
Definition plancache.h:114
bool rewriteRowSecurity
Definition plancache.h:130
List * relationOids
Definition plancache.h:124
void * parserSetupArg
Definition plancache.h:115
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition tupdesc.c:235

References ALLOCSET_START_SMALL_SIZES, AllocSetContextCreate, Assert, CACHEDPLANSOURCE_MAGIC, CachedPlanSource::context, copyObject, CreateTupleDescCopy(), CurrentMemoryContext, CachedPlanSource::cursor_options, CachedPlanSource::dependsOnRLS, extract_query_dependencies(), fb(), CachedPlanSource::fixed_result, GetSearchPathMatcher(), GetUserId(), CachedPlanSource::invalItems, CachedPlanSource::is_complete, CachedPlanSource::is_oneshot, CachedPlanSource::is_valid, CachedPlanSource::magic, MemoryContextSetParent(), MemoryContextSwitchTo(), CachedPlanSource::num_params, palloc_array, CachedPlanSource::param_types, CachedPlanSource::parserSetup, CachedPlanSource::parserSetupArg, PlanCacheComputeResultDesc(), CachedPlanSource::query_context, CachedPlanSource::query_list, CachedPlanSource::relationOids, CachedPlanSource::resultDesc, CachedPlanSource::rewriteRoleId, CachedPlanSource::rewriteRowSecurity, row_security, CachedPlanSource::search_path, and StmtPlanRequiresRevalidation().

Referenced by _SPI_execute_plan(), _SPI_prepare_plan(), exec_parse_message(), prepare_next_query(), and PrepareQuery().

◆ CopyCachedPlan()

CachedPlanSource * CopyCachedPlan ( CachedPlanSource plansource)
extern

Definition at line 1673 of file plancache.c.

1674{
1679
1680 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1681 Assert(plansource->is_complete);
1682
1683 /*
1684 * One-shot plans can't be copied, because we haven't taken care that
1685 * parsing/planning didn't scribble on the raw parse tree or querytrees.
1686 */
1687 if (plansource->is_oneshot)
1688 elog(ERROR, "cannot copy a one-shot cached plan");
1689
1691 "CachedPlanSource",
1693
1695
1698 newsource->raw_parse_tree = copyObject(plansource->raw_parse_tree);
1699 newsource->analyzed_parse_tree = copyObject(plansource->analyzed_parse_tree);
1700 newsource->query_string = pstrdup(plansource->query_string);
1702 newsource->commandTag = plansource->commandTag;
1703 if (plansource->num_params > 0)
1704 {
1705 newsource->param_types = palloc_array(Oid, plansource->num_params);
1706 memcpy(newsource->param_types, plansource->param_types,
1707 plansource->num_params * sizeof(Oid));
1708 }
1709 else
1710 newsource->param_types = NULL;
1711 newsource->num_params = plansource->num_params;
1712 newsource->parserSetup = plansource->parserSetup;
1713 newsource->parserSetupArg = plansource->parserSetupArg;
1714 newsource->postRewrite = plansource->postRewrite;
1715 newsource->postRewriteArg = plansource->postRewriteArg;
1716 newsource->cursor_options = plansource->cursor_options;
1717 newsource->fixed_result = plansource->fixed_result;
1718 if (plansource->resultDesc)
1719 newsource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
1720 else
1721 newsource->resultDesc = NULL;
1722 newsource->context = source_context;
1723
1725 "CachedPlanQuery",
1728 newsource->query_list = copyObject(plansource->query_list);
1729 newsource->relationOids = copyObject(plansource->relationOids);
1730 newsource->invalItems = copyObject(plansource->invalItems);
1731 if (plansource->search_path)
1732 newsource->search_path = CopySearchPathMatcher(plansource->search_path);
1733 newsource->query_context = querytree_context;
1734 newsource->rewriteRoleId = plansource->rewriteRoleId;
1735 newsource->rewriteRowSecurity = plansource->rewriteRowSecurity;
1736 newsource->dependsOnRLS = plansource->dependsOnRLS;
1737
1738 newsource->gplan = NULL;
1739
1740 newsource->is_oneshot = false;
1741 newsource->is_complete = true;
1742 newsource->is_saved = false;
1743 newsource->is_valid = plansource->is_valid;
1744 newsource->generation = plansource->generation;
1745
1746 /* We may as well copy any acquired cost knowledge */
1747 newsource->generic_cost = plansource->generic_cost;
1748 newsource->total_custom_cost = plansource->total_custom_cost;
1749 newsource->num_generic_plans = plansource->num_generic_plans;
1750 newsource->num_custom_plans = plansource->num_custom_plans;
1751
1753
1754 return newsource;
1755}
#define palloc0_object(type)
Definition fe_memutils.h:75
char * pstrdup(const char *in)
Definition mcxt.c:1781
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
Definition mcxt.c:661
SearchPathMatcher * CopySearchPathMatcher(SearchPathMatcher *path)
Definition namespace.c:3961
PostRewriteHook postRewrite
Definition plancache.h:116
Query * analyzed_parse_tree
Definition plancache.h:109
RawStmt * raw_parse_tree
Definition plancache.h:108
CommandTag commandTag
Definition plancache.h:111
double total_custom_cost
Definition plancache.h:144
const char * query_string
Definition plancache.h:110
int64 num_custom_plans
Definition plancache.h:145
int64 num_generic_plans
Definition plancache.h:146
void * postRewriteArg
Definition plancache.h:117
double generic_cost
Definition plancache.h:143

References ALLOCSET_START_SMALL_SIZES, AllocSetContextCreate, CachedPlanSource::analyzed_parse_tree, Assert, CACHEDPLANSOURCE_MAGIC, CachedPlanSource::commandTag, copyObject, CopySearchPathMatcher(), CreateTupleDescCopy(), CurrentMemoryContext, CachedPlanSource::cursor_options, CachedPlanSource::dependsOnRLS, elog, ERROR, fb(), CachedPlanSource::fixed_result, CachedPlanSource::generation, CachedPlanSource::generic_cost, CachedPlanSource::invalItems, CachedPlanSource::is_complete, CachedPlanSource::is_oneshot, CachedPlanSource::is_valid, CachedPlanSource::magic, MemoryContextSetIdentifier(), MemoryContextSwitchTo(), CachedPlanSource::num_custom_plans, CachedPlanSource::num_generic_plans, CachedPlanSource::num_params, palloc0_object, palloc_array, CachedPlanSource::param_types, CachedPlanSource::parserSetup, CachedPlanSource::parserSetupArg, CachedPlanSource::postRewrite, CachedPlanSource::postRewriteArg, pstrdup(), CachedPlanSource::query_list, CachedPlanSource::query_string, CachedPlanSource::raw_parse_tree, CachedPlanSource::relationOids, CachedPlanSource::resultDesc, CachedPlanSource::rewriteRoleId, CachedPlanSource::rewriteRowSecurity, CachedPlanSource::search_path, and CachedPlanSource::total_custom_cost.

Referenced by _SPI_save_plan().

◆ CreateCachedPlan()

CachedPlanSource * CreateCachedPlan ( RawStmt raw_parse_tree,
const char query_string,
CommandTag  commandTag 
)
extern

Definition at line 185 of file plancache.c.

188{
189 CachedPlanSource *plansource;
192
193 Assert(query_string != NULL); /* required as of 8.4 */
194
195 /*
196 * Make a dedicated memory context for the CachedPlanSource and its
197 * permanent subsidiary data. It's probably not going to be large, but
198 * just in case, allow it to grow large. Initially it's a child of the
199 * caller's context (which we assume to be transient), so that it will be
200 * cleaned up on error.
201 */
203 "CachedPlanSource",
205
206 /*
207 * Create and fill the CachedPlanSource struct within the new context.
208 * Most fields are just left empty for the moment.
209 */
211
212 plansource = palloc0_object(CachedPlanSource);
213 plansource->magic = CACHEDPLANSOURCE_MAGIC;
214 plansource->raw_parse_tree = copyObject(raw_parse_tree);
215 plansource->analyzed_parse_tree = NULL;
216 plansource->query_string = pstrdup(query_string);
218 plansource->commandTag = commandTag;
219 plansource->param_types = NULL;
220 plansource->num_params = 0;
221 plansource->parserSetup = NULL;
222 plansource->parserSetupArg = NULL;
223 plansource->postRewrite = NULL;
224 plansource->postRewriteArg = NULL;
225 plansource->cursor_options = 0;
226 plansource->fixed_result = false;
227 plansource->resultDesc = NULL;
228 plansource->context = source_context;
229 plansource->query_list = NIL;
230 plansource->relationOids = NIL;
231 plansource->invalItems = NIL;
232 plansource->search_path = NULL;
233 plansource->query_context = NULL;
234 plansource->rewriteRoleId = InvalidOid;
235 plansource->rewriteRowSecurity = false;
236 plansource->dependsOnRLS = false;
237 plansource->gplan = NULL;
238 plansource->is_oneshot = false;
239 plansource->is_complete = false;
240 plansource->is_saved = false;
241 plansource->is_valid = false;
242 plansource->generation = 0;
243 plansource->generic_cost = -1;
244 plansource->total_custom_cost = 0;
245 plansource->num_generic_plans = 0;
246 plansource->num_custom_plans = 0;
247
249
250 return plansource;
251}
#define InvalidOid

References ALLOCSET_START_SMALL_SIZES, AllocSetContextCreate, CachedPlanSource::analyzed_parse_tree, Assert, CACHEDPLANSOURCE_MAGIC, CachedPlanSource::commandTag, CachedPlanSource::context, copyObject, CurrentMemoryContext, CachedPlanSource::cursor_options, CachedPlanSource::dependsOnRLS, fb(), CachedPlanSource::fixed_result, CachedPlanSource::generation, CachedPlanSource::generic_cost, CachedPlanSource::gplan, InvalidOid, CachedPlanSource::invalItems, CachedPlanSource::is_complete, CachedPlanSource::is_oneshot, CachedPlanSource::is_saved, CachedPlanSource::is_valid, CachedPlanSource::magic, MemoryContextSetIdentifier(), MemoryContextSwitchTo(), NIL, CachedPlanSource::num_custom_plans, CachedPlanSource::num_generic_plans, CachedPlanSource::num_params, palloc0_object, CachedPlanSource::param_types, CachedPlanSource::parserSetup, CachedPlanSource::parserSetupArg, CachedPlanSource::postRewrite, CachedPlanSource::postRewriteArg, pstrdup(), CachedPlanSource::query_context, CachedPlanSource::query_list, CachedPlanSource::query_string, CachedPlanSource::raw_parse_tree, CachedPlanSource::relationOids, CachedPlanSource::resultDesc, CachedPlanSource::rewriteRoleId, CachedPlanSource::rewriteRowSecurity, CachedPlanSource::search_path, and CachedPlanSource::total_custom_cost.

Referenced by _SPI_prepare_plan(), CreateCachedPlanForQuery(), exec_parse_message(), prepare_next_query(), and PrepareQuery().

◆ CreateCachedPlanForQuery()

CachedPlanSource * CreateCachedPlanForQuery ( Query analyzed_parse_tree,
const char query_string,
CommandTag  commandTag 
)
extern

Definition at line 265 of file plancache.c.

268{
269 CachedPlanSource *plansource;
271
272 /* Rather than duplicating CreateCachedPlan, just do this: */
273 plansource = CreateCachedPlan(NULL, query_string, commandTag);
274 oldcxt = MemoryContextSwitchTo(plansource->context);
275 plansource->analyzed_parse_tree = copyObject(analyzed_parse_tree);
277
278 return plansource;
279}
CachedPlanSource * CreateCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)
Definition plancache.c:185

References CachedPlanSource::analyzed_parse_tree, CachedPlanSource::context, copyObject, CreateCachedPlan(), fb(), and MemoryContextSwitchTo().

Referenced by prepare_next_query().

◆ CreateOneShotCachedPlan()

CachedPlanSource * CreateOneShotCachedPlan ( RawStmt raw_parse_tree,
const char query_string,
CommandTag  commandTag 
)
extern

Definition at line 300 of file plancache.c.

303{
304 CachedPlanSource *plansource;
305
306 Assert(query_string != NULL); /* required as of 8.4 */
307
308 /*
309 * Create and fill the CachedPlanSource struct within the caller's memory
310 * context. Most fields are just left empty for the moment.
311 */
312 plansource = palloc0_object(CachedPlanSource);
313 plansource->magic = CACHEDPLANSOURCE_MAGIC;
314 plansource->raw_parse_tree = raw_parse_tree;
315 plansource->analyzed_parse_tree = NULL;
316 plansource->query_string = query_string;
317 plansource->commandTag = commandTag;
318 plansource->param_types = NULL;
319 plansource->num_params = 0;
320 plansource->parserSetup = NULL;
321 plansource->parserSetupArg = NULL;
322 plansource->postRewrite = NULL;
323 plansource->postRewriteArg = NULL;
324 plansource->cursor_options = 0;
325 plansource->fixed_result = false;
326 plansource->resultDesc = NULL;
327 plansource->context = CurrentMemoryContext;
328 plansource->query_list = NIL;
329 plansource->relationOids = NIL;
330 plansource->invalItems = NIL;
331 plansource->search_path = NULL;
332 plansource->query_context = NULL;
333 plansource->rewriteRoleId = InvalidOid;
334 plansource->rewriteRowSecurity = false;
335 plansource->dependsOnRLS = false;
336 plansource->gplan = NULL;
337 plansource->is_oneshot = true;
338 plansource->is_complete = false;
339 plansource->is_saved = false;
340 plansource->is_valid = false;
341 plansource->generation = 0;
342 plansource->generic_cost = -1;
343 plansource->total_custom_cost = 0;
344 plansource->num_generic_plans = 0;
345 plansource->num_custom_plans = 0;
346
347 return plansource;
348}

References CachedPlanSource::analyzed_parse_tree, Assert, CACHEDPLANSOURCE_MAGIC, CachedPlanSource::commandTag, CachedPlanSource::context, CurrentMemoryContext, CachedPlanSource::cursor_options, CachedPlanSource::dependsOnRLS, fb(), CachedPlanSource::fixed_result, CachedPlanSource::generation, CachedPlanSource::generic_cost, CachedPlanSource::gplan, InvalidOid, CachedPlanSource::invalItems, CachedPlanSource::is_complete, CachedPlanSource::is_oneshot, CachedPlanSource::is_saved, CachedPlanSource::is_valid, CachedPlanSource::magic, NIL, CachedPlanSource::num_custom_plans, CachedPlanSource::num_generic_plans, CachedPlanSource::num_params, palloc0_object, CachedPlanSource::param_types, CachedPlanSource::parserSetup, CachedPlanSource::parserSetupArg, CachedPlanSource::postRewrite, CachedPlanSource::postRewriteArg, CachedPlanSource::query_context, CachedPlanSource::query_list, CachedPlanSource::query_string, CachedPlanSource::raw_parse_tree, CachedPlanSource::relationOids, CachedPlanSource::resultDesc, CachedPlanSource::rewriteRoleId, CachedPlanSource::rewriteRowSecurity, CachedPlanSource::search_path, and CachedPlanSource::total_custom_cost.

Referenced by _SPI_prepare_oneshot_plan().

◆ DropCachedPlan()

void DropCachedPlan ( CachedPlanSource plansource)
extern

Definition at line 591 of file plancache.c.

592{
593 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
594
595 /* If it's been saved, remove it from the list */
596 if (plansource->is_saved)
597 {
598 dlist_delete(&plansource->node);
599 plansource->is_saved = false;
600 }
601
602 /* Decrement generic CachedPlan's refcount and drop if no longer needed */
603 ReleaseGenericPlan(plansource);
604
605 /* Mark it no longer valid */
606 plansource->magic = 0;
607
608 /*
609 * Remove the CachedPlanSource and all subsidiary data (including the
610 * query_context if any). But if it's a one-shot we can't free anything.
611 */
612 if (!plansource->is_oneshot)
613 MemoryContextDelete(plansource->context);
614}
static void dlist_delete(dlist_node *node)
Definition ilist.h:405
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472
static void ReleaseGenericPlan(CachedPlanSource *plansource)
Definition plancache.c:620
dlist_node node
Definition plancache.h:141

References Assert, CACHEDPLANSOURCE_MAGIC, CachedPlanSource::context, dlist_delete(), CachedPlanSource::is_oneshot, CachedPlanSource::is_saved, CachedPlanSource::magic, MemoryContextDelete(), CachedPlanSource::node, and ReleaseGenericPlan().

Referenced by drop_unnamed_stmt(), DropAllPreparedStatements(), DropPreparedStatement(), SPI_freeplan(), and sql_delete_callback().

◆ FreeCachedExpression()

void FreeCachedExpression ( CachedExpression cexpr)
extern

Definition at line 1873 of file plancache.c.

1874{
1875 /* Sanity check */
1876 Assert(cexpr->magic == CACHEDEXPR_MAGIC);
1877 /* Unlink from global list */
1878 dlist_delete(&cexpr->node);
1879 /* Free all storage associated with CachedExpression */
1881}
#define CACHEDEXPR_MAGIC
Definition plancache.h:46
MemoryContext context
Definition plancache.h:195
dlist_node node
Definition plancache.h:196

References Assert, CACHEDEXPR_MAGIC, CachedExpression::context, dlist_delete(), CachedExpression::magic, MemoryContextDelete(), and CachedExpression::node.

Referenced by get_cast_hashentry().

◆ GetCachedExpression()

CachedExpression * GetCachedExpression ( Node expr)
extern

Definition at line 1816 of file plancache.c.

1817{
1818 CachedExpression *cexpr;
1819 List *relationOids;
1820 List *invalItems;
1823
1824 /*
1825 * Pass the expression through the planner, and collect dependencies.
1826 * Everything built here is leaked in the caller's context; that's
1827 * intentional to minimize the size of the permanent data structure.
1828 */
1829 expr = (Node *) expression_planner_with_deps((Expr *) expr,
1830 &relationOids,
1831 &invalItems);
1832
1833 /*
1834 * Make a private memory context, and copy what we need into that. To
1835 * avoid leaking a long-lived context if we fail while copying data, we
1836 * initially make the context under the caller's context.
1837 */
1839 "CachedExpression",
1841
1843
1845 cexpr->magic = CACHEDEXPR_MAGIC;
1846 cexpr->expr = copyObject(expr);
1847 cexpr->is_valid = true;
1848 cexpr->relationOids = copyObject(relationOids);
1849 cexpr->invalItems = copyObject(invalItems);
1850 cexpr->context = cexpr_context;
1851
1853
1854 /*
1855 * Reparent the expr's memory context under CacheMemoryContext so that it
1856 * will live indefinitely.
1857 */
1859
1860 /*
1861 * Add the entry to the global list of cached expressions.
1862 */
1864
1865 return cexpr;
1866}
#define palloc_object(type)
Definition fe_memutils.h:74
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition ilist.h:364
MemoryContext CacheMemoryContext
Definition mcxt.c:169
#define ALLOCSET_SMALL_SIZES
Definition memutils.h:170
static dlist_head cached_expression_list
Definition plancache.c:89
Expr * expression_planner_with_deps(Expr *expr, List **relationOids, List **invalItems)
Definition planner.c:6846
List * relationOids
Definition plancache.h:193
Definition pg_list.h:54

References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, cached_expression_list, CACHEDEXPR_MAGIC, CacheMemoryContext, CachedExpression::context, copyObject, CurrentMemoryContext, dlist_push_tail(), CachedExpression::expr, expression_planner_with_deps(), fb(), CachedExpression::invalItems, CachedExpression::is_valid, CachedExpression::magic, MemoryContextSetParent(), MemoryContextSwitchTo(), CachedExpression::node, palloc_object, and CachedExpression::relationOids.

Referenced by get_cast_hashentry().

◆ GetCachedPlan()

CachedPlan * GetCachedPlan ( CachedPlanSource plansource,
ParamListInfo  boundParams,
ResourceOwner  owner,
QueryEnvironment queryEnv 
)
extern

Definition at line 1297 of file plancache.c.

1299{
1300 CachedPlan *plan = NULL;
1301 List *qlist;
1302 bool customplan;
1303 ListCell *lc;
1304
1305 /* Assert caller is doing things in a sane order */
1306 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1307 Assert(plansource->is_complete);
1308 /* This seems worth a real test, though */
1309 if (owner && !plansource->is_saved)
1310 elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
1311
1312 /* Make sure the querytree list is valid and we have parse-time locks */
1313 qlist = RevalidateCachedQuery(plansource, queryEnv);
1314
1315 /* Decide whether to use a custom plan */
1316 customplan = choose_custom_plan(plansource, boundParams);
1317
1318 if (!customplan)
1319 {
1320 if (CheckCachedPlan(plansource))
1321 {
1322 /* We want a generic plan, and we already have a valid one */
1323 plan = plansource->gplan;
1324 Assert(plan->magic == CACHEDPLAN_MAGIC);
1325 }
1326 else
1327 {
1328 /* Build a new generic plan */
1329 plan = BuildCachedPlan(plansource, qlist, NULL, queryEnv);
1330 /* Just make real sure plansource->gplan is clear */
1331 ReleaseGenericPlan(plansource);
1332 /* Link the new generic plan into the plansource */
1333 plansource->gplan = plan;
1334 plan->refcount++;
1335 /* Immediately reparent into appropriate context */
1336 if (plansource->is_saved)
1337 {
1338 /* saved plans all live under CacheMemoryContext */
1340 plan->is_saved = true;
1341 }
1342 else
1343 {
1344 /* otherwise, it should be a sibling of the plansource */
1346 MemoryContextGetParent(plansource->context));
1347 }
1348 /* Update generic_cost whenever we make a new generic plan */
1349 plansource->generic_cost = cached_plan_cost(plan, false);
1350
1351 /*
1352 * If, based on the now-known value of generic_cost, we'd not have
1353 * chosen to use a generic plan, then forget it and make a custom
1354 * plan. This is a bit of a wart but is necessary to avoid a
1355 * glitch in behavior when the custom plans are consistently big
1356 * winners; at some point we'll experiment with a generic plan and
1357 * find it's a loser, but we don't want to actually execute that
1358 * plan.
1359 */
1360 customplan = choose_custom_plan(plansource, boundParams);
1361
1362 /*
1363 * If we choose to plan again, we need to re-copy the query_list,
1364 * since the planner probably scribbled on it. We can force
1365 * BuildCachedPlan to do that by passing NIL.
1366 */
1367 qlist = NIL;
1368 }
1369 }
1370
1371 if (customplan)
1372 {
1373 /* Build a custom plan */
1374 plan = BuildCachedPlan(plansource, qlist, boundParams, queryEnv);
1375 /* Accumulate total costs of custom plans */
1376 plansource->total_custom_cost += cached_plan_cost(plan, true);
1377
1378 plansource->num_custom_plans++;
1379 }
1380 else
1381 {
1382 plansource->num_generic_plans++;
1383 }
1384
1385 Assert(plan != NULL);
1386
1387 /* Flag the plan as in use by caller */
1388 if (owner)
1389 ResourceOwnerEnlarge(owner);
1390 plan->refcount++;
1391 if (owner)
1393
1394 /*
1395 * Saved plans should be under CacheMemoryContext so they will not go away
1396 * until their reference count goes to zero. In the generic-plan cases we
1397 * already took care of that, but for a custom plan, do it as soon as we
1398 * have created a reference-counted link.
1399 */
1400 if (customplan && plansource->is_saved)
1401 {
1403 plan->is_saved = true;
1404 }
1405
1406 foreach(lc, plan->stmt_list)
1407 {
1408 PlannedStmt *pstmt = (PlannedStmt *) lfirst(lc);
1409
1411 }
1412
1413 return plan;
1414}
MemoryContext MemoryContextGetParent(MemoryContext context)
Definition mcxt.c:780
static bool choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams)
Definition plancache.c:1175
static CachedPlan * BuildCachedPlan(CachedPlanSource *plansource, List *qlist, ParamListInfo boundParams, QueryEnvironment *queryEnv)
Definition plancache.c:1036
static bool CheckCachedPlan(CachedPlanSource *plansource)
Definition plancache.c:952
static double cached_plan_cost(CachedPlan *plan, bool include_planner)
Definition plancache.c:1232
@ PLAN_STMT_CACHE_CUSTOM
Definition plannodes.h:43
@ PLAN_STMT_CACHE_GENERIC
Definition plannodes.h:42
PlannedStmtOrigin planOrigin
Definition plannodes.h:77

References Assert, BuildCachedPlan(), cached_plan_cost(), CACHEDPLAN_MAGIC, CACHEDPLANSOURCE_MAGIC, CacheMemoryContext, CheckCachedPlan(), choose_custom_plan(), CachedPlanSource::context, elog, ERROR, fb(), CachedPlanSource::generic_cost, CachedPlanSource::gplan, CachedPlanSource::is_complete, CachedPlanSource::is_saved, lfirst, CachedPlanSource::magic, MemoryContextGetParent(), MemoryContextSetParent(), NIL, CachedPlanSource::num_custom_plans, CachedPlanSource::num_generic_plans, plan, PLAN_STMT_CACHE_CUSTOM, PLAN_STMT_CACHE_GENERIC, PlannedStmt::planOrigin, CachedPlan::refcount, ReleaseGenericPlan(), ResourceOwnerEnlarge(), ResourceOwnerRememberPlanCacheRef(), RevalidateCachedQuery(), and CachedPlanSource::total_custom_cost.

Referenced by _SPI_execute_plan(), exec_bind_message(), ExecuteQuery(), ExplainExecuteQuery(), init_execution_state(), SPI_cursor_open_internal(), and SPI_plan_get_cached_plan().

◆ InitPlanCache()

void InitPlanCache ( void  )
extern

Definition at line 148 of file plancache.c.

149{
158}
void CacheRegisterSyscacheCallback(SysCacheIdentifier cacheid, SyscacheCallbackFunction func, Datum arg)
Definition inval.c:1816
void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func, Datum arg)
Definition inval.c:1858
static void PlanCacheSysCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
Definition plancache.c:2315
static void PlanCacheRelCallback(Datum arg, Oid relid)
Definition plancache.c:2122
static void PlanCacheObjectCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
Definition plancache.c:2206
uint64_t Datum
Definition postgres.h:70

References CacheRegisterRelcacheCallback(), CacheRegisterSyscacheCallback(), fb(), PlanCacheObjectCallback(), PlanCacheRelCallback(), and PlanCacheSysCallback().

Referenced by InitPostgres().

◆ ReleaseAllPlanCacheRefsInOwner()

void ReleaseAllPlanCacheRefsInOwner ( ResourceOwner  owner)
extern

Definition at line 2371 of file plancache.c.

2372{
2374}
static const ResourceOwnerDesc planref_resowner_desc
Definition plancache.c:117
void ResourceOwnerReleaseAllOfKind(ResourceOwner owner, const ResourceOwnerDesc *kind)
Definition resowner.c:815

References planref_resowner_desc, and ResourceOwnerReleaseAllOfKind().

Referenced by plpgsql_call_handler(), plpgsql_inline_handler(), and plpgsql_xact_cb().

◆ ReleaseCachedPlan()

void ReleaseCachedPlan ( CachedPlan plan,
ResourceOwner  owner 
)
extern

Definition at line 1428 of file plancache.c.

1429{
1430 Assert(plan->magic == CACHEDPLAN_MAGIC);
1431 if (owner)
1432 {
1433 Assert(plan->is_saved);
1435 }
1436 Assert(plan->refcount > 0);
1437 plan->refcount--;
1438 if (plan->refcount == 0)
1439 {
1440 /* Mark it no longer valid */
1441 plan->magic = 0;
1442
1443 /* One-shot plans do not own their context, so we can't free them */
1444 if (!plan->is_oneshot)
1445 MemoryContextDelete(plan->context);
1446 }
1447}
static void ResourceOwnerForgetPlanCacheRef(ResourceOwner owner, CachedPlan *plan)
Definition plancache.c:133

References Assert, CACHEDPLAN_MAGIC, MemoryContextDelete(), plan, and ResourceOwnerForgetPlanCacheRef().

Referenced by _SPI_execute_plan(), exec_eval_simple_expr(), exec_simple_check_plan(), ExplainExecuteQuery(), init_execution_state(), make_callstmt_target(), PortalReleaseCachedPlan(), ReleaseGenericPlan(), ResOwnerReleaseCachedPlan(), ShutdownSQLFunction(), and SPI_cursor_open_internal().

◆ ResetPlanCache()

void ResetPlanCache ( void  )
extern

Definition at line 2324 of file plancache.c.

2325{
2326 dlist_iter iter;
2327
2329 {
2331 node, iter.cur);
2332
2333 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
2334
2335 /* No work if it's already invalidated */
2336 if (!plansource->is_valid)
2337 continue;
2338
2339 /*
2340 * We *must not* mark transaction control statements as invalid,
2341 * particularly not ROLLBACK, because they may need to be executed in
2342 * aborted transactions when we can't revalidate them (cf bug #5269).
2343 * In general there's no point in invalidating statements for which a
2344 * new parse analysis/rewrite/plan cycle would certainly give the same
2345 * results.
2346 */
2347 if (!StmtPlanRequiresRevalidation(plansource))
2348 continue;
2349
2350 plansource->is_valid = false;
2351 if (plansource->gplan)
2352 plansource->gplan->is_valid = false;
2353 }
2354
2355 /* Likewise invalidate cached expressions */
2357 {
2359 node, iter.cur);
2360
2361 Assert(cexpr->magic == CACHEDEXPR_MAGIC);
2362
2363 cexpr->is_valid = false;
2364 }
2365}
#define dlist_foreach(iter, lhead)
Definition ilist.h:623
#define dlist_container(type, membername, ptr)
Definition ilist.h:593
static dlist_head saved_plan_list
Definition plancache.c:84
dlist_node * cur
Definition ilist.h:179

References Assert, cached_expression_list, CACHEDEXPR_MAGIC, CACHEDPLANSOURCE_MAGIC, dlist_iter::cur, dlist_container, dlist_foreach, CachedPlanSource::gplan, CachedPlanSource::is_valid, CachedPlan::is_valid, CachedExpression::is_valid, CachedPlanSource::magic, CachedExpression::magic, saved_plan_list, and StmtPlanRequiresRevalidation().

Referenced by assign_session_replication_role(), DiscardAll(), DiscardCommand(), and PlanCacheSysCallback().

◆ SaveCachedPlan()

void SaveCachedPlan ( CachedPlanSource plansource)
extern

Definition at line 547 of file plancache.c.

548{
549 /* Assert caller is doing things in a sane order */
550 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
551 Assert(plansource->is_complete);
552 Assert(!plansource->is_saved);
553
554 /* This seems worth a real test, though */
555 if (plansource->is_oneshot)
556 elog(ERROR, "cannot save one-shot cached plan");
557
558 /*
559 * In typical use, this function would be called before generating any
560 * plans from the CachedPlanSource. If there is a generic plan, moving it
561 * into CacheMemoryContext would be pretty risky since it's unclear
562 * whether the caller has taken suitable care with making references
563 * long-lived. Best thing to do seems to be to discard the plan.
564 */
565 ReleaseGenericPlan(plansource);
566
567 /*
568 * Reparent the source memory context under CacheMemoryContext so that it
569 * will live indefinitely. The query_context follows along since it's
570 * already a child of the other one.
571 */
573
574 /*
575 * Add the entry to the global list of cached plans.
576 */
577 dlist_push_tail(&saved_plan_list, &plansource->node);
578
579 plansource->is_saved = true;
580}

References Assert, CACHEDPLANSOURCE_MAGIC, CacheMemoryContext, CachedPlanSource::context, dlist_push_tail(), elog, ERROR, CachedPlanSource::is_complete, CachedPlanSource::is_oneshot, CachedPlanSource::is_saved, CachedPlanSource::magic, MemoryContextSetParent(), CachedPlanSource::node, ReleaseGenericPlan(), and saved_plan_list.

Referenced by _SPI_save_plan(), exec_parse_message(), prepare_next_query(), SPI_keepplan(), and StorePreparedStatement().

◆ SetPostRewriteHook()

void SetPostRewriteHook ( CachedPlanSource plansource,
PostRewriteHook  postRewrite,
void postRewriteArg 
)
extern

Definition at line 522 of file plancache.c.

525{
526 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
527 plansource->postRewrite = postRewrite;
528 plansource->postRewriteArg = postRewriteArg;
529}

References Assert, CACHEDPLANSOURCE_MAGIC, CachedPlanSource::magic, CachedPlanSource::postRewrite, and CachedPlanSource::postRewriteArg.

Referenced by prepare_next_query().

Variable Documentation

◆ plan_cache_mode

PGDLLIMPORT int plan_cache_mode
extern

Definition at line 140 of file plancache.c.

Referenced by choose_custom_plan().