85#define StmtPlanRequiresRevalidation(plansource) \
86 ((plansource)->raw_parse_tree != NULL && \
87 stmt_requires_parse_analysis((plansource)->raw_parse_tree))
105 bool release_generic);
127 .
name =
"plancache reference",
194 const char *query_string,
201 Assert(query_string != NULL);
233 plansource->
context = source_context;
242 plansource->
gplan = NULL;
278 const char *query_string,
283 Assert(query_string != NULL);
310 plansource->
gplan = NULL;
368 List *querytree_list,
373 void *parserSetupArg,
395 else if (querytree_context != NULL)
450 memcpy(plansource->
param_types, param_types, num_params *
sizeof(
Oid));
492 elog(
ERROR,
"cannot save one-shot cached plan");
542 plansource->
magic = 0;
559 if (plansource->
gplan)
564 plansource->
gplan = NULL;
592 bool release_generic)
627 if (plansource->
gplan)
706 snapshot_set =
false;
745 if (resultDesc == NULL && plansource->
resultDesc == NULL)
749 else if (resultDesc == NULL || plansource->
resultDesc == NULL ||
755 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
756 errmsg(
"cached plan must not change result type")));
851 if (
plan->is_valid &&
plan->dependsOnRole &&
853 plan->is_valid =
false;
873 if (
plan->is_valid &&
876 plan->is_valid =
false;
964 snapshot_set =
false;
1006 "CachedPlan PlannedStmts",
1025 plan->stmt_list = plist;
1034 is_transient =
false;
1043 is_transient =
true;
1045 plan->dependsOnRole =
true;
1055 plan->context = plan_context;
1056 plan->stmt_context = stmt_context;
1058 plan->is_saved =
false;
1059 plan->is_reused =
false;
1060 plan->is_valid =
true;
1107 elog(
ERROR,
"UpdateCachedPlan() called in the wrong context: plansource->gplan is NULL");
1108 else if (
plan->is_valid)
1109 elog(
ERROR,
"UpdateCachedPlan() called in the wrong context: plansource->gplan->is_valid is true");
1110 else if (
plan->is_oneshot)
1111 elog(
ERROR,
"UpdateCachedPlan() called in the wrong context: plansource->gplan->is_oneshot is true");
1169 plan->is_valid =
true;
1185 double avg_custom_cost;
1192 if (boundParams == NULL)
1245 foreach(lc,
plan->stmt_list)
1254 if (include_planner)
1321 if (owner && !plansource->
is_saved)
1322 elog(
ERROR,
"cannot apply ResourceOwner to non-saved cached plan");
1338 plan->is_reused =
true;
1354 plan->is_saved =
true;
1414 if (customplan && plansource->
is_saved)
1417 plan->is_saved =
true;
1445 if (
plan->refcount == 0)
1451 if (!
plan->is_oneshot)
1512 if (
plan->dependsOnRole)
1537 foreach(lc,
plan->stmt_list)
1549 foreach(lc2, plannedstmt->
rtable)
1651 elog(
ERROR,
"cannot move a saved cached plan to another context");
1653 elog(
ERROR,
"cannot move a one-shot cached plan to another context");
1663 if (plansource->
gplan)
1695 elog(
ERROR,
"cannot copy a one-shot cached plan");
1727 newsource->
context = source_context;
1743 newsource->
gplan = NULL;
1855 cexpr->
context = cexpr_context;
1905 if (
stmt->canSetTag)
1920 foreach(lc1, stmt_list)
1979 foreach(lc, stmt_list)
2010 foreach(lc, parsetree->
rtable)
2044 foreach(lc, parsetree->
cteList)
2055 if (parsetree->hasSubLinks)
2157 if (plansource->
gplan)
2243 if (hashvalue == 0 ||
2248 if (plansource->
gplan)
2273 if (hashvalue == 0 ||
2306 if (hashvalue == 0 ||
2359 if (plansource->
gplan)
int bms_next_member(const Bitmapset *a, int prevbit)
#define OidIsValid(objectId)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
TupleDesc ExecCleanTypeFromTL(List *targetList)
Assert(PointerIsAligned(start, uint64))
#define dlist_foreach(iter, lhead)
static void dlist_delete(dlist_node *node)
static void dlist_push_tail(dlist_head *head, dlist_node *node)
#define DLIST_STATIC_INIT(name)
#define dlist_container(type, membername, ptr)
void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func, Datum arg)
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
List * list_copy(const List *oldlist)
bool list_member_oid(const List *list, Oid datum)
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
void MemoryContextReset(MemoryContext context)
char * pstrdup(const char *in)
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
MemoryContext MemoryContextGetParent(MemoryContext context)
MemoryContext CacheMemoryContext
void MemoryContextDelete(MemoryContext context)
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
#define AllocSetContextCreate
#define ALLOCSET_START_SMALL_SIZES
#define ALLOCSET_SMALL_SIZES
#define MemoryContextCopyAndSetIdentifier(cxt, id)
SearchPathMatcher * GetSearchPathMatcher(MemoryContext context)
bool SearchPathMatchesCurrentEnvironment(SearchPathMatcher *path)
SearchPathMatcher * CopySearchPathMatcher(SearchPathMatcher *path)
#define query_tree_walker(q, w, c, f)
#define expression_tree_walker(n, w, c)
#define QTW_IGNORE_RC_SUBQUERIES
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
void(* ParserSetupHook)(struct ParseState *pstate, void *arg)
#define CURSOR_OPT_GENERIC_PLAN
#define CURSOR_OPT_CUSTOM_PLAN
bool analyze_requires_snapshot(RawStmt *parseTree)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define linitial_node(type, l)
#define forboth(cell1, list1, cell2, list2)
#define list_nth_node(type, list, n)
void CachedPlanSetParentContext(CachedPlanSource *plansource, MemoryContext newcontext)
bool CachedPlanIsValid(CachedPlanSource *plansource)
static dlist_head cached_expression_list
void DropCachedPlan(CachedPlanSource *plansource)
static bool choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams)
bool CachedPlanAllowsSimpleValidityCheck(CachedPlanSource *plansource, CachedPlan *plan, ResourceOwner owner)
static void ReleaseGenericPlan(CachedPlanSource *plansource)
static List * RevalidateCachedQuery(CachedPlanSource *plansource, QueryEnvironment *queryEnv, bool release_generic)
static CachedPlan * BuildCachedPlan(CachedPlanSource *plansource, List *qlist, ParamListInfo boundParams, QueryEnvironment *queryEnv)
static bool CheckCachedPlan(CachedPlanSource *plansource)
void FreeCachedExpression(CachedExpression *cexpr)
void SaveCachedPlan(CachedPlanSource *plansource)
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)
static void ResourceOwnerRememberPlanCacheRef(ResourceOwner owner, CachedPlan *plan)
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)
CachedExpression * GetCachedExpression(Node *expr)
bool CachedPlanIsSimplyValid(CachedPlanSource *plansource, CachedPlan *plan, ResourceOwner owner)
CachedPlanSource * CreateOneShotCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)
static bool ScanQueryWalker(Node *node, bool *acquire)
static const ResourceOwnerDesc planref_resowner_desc
static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
CachedPlanSource * CreateCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)
static void PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue)
List * CachedPlanGetTargetList(CachedPlanSource *plansource, QueryEnvironment *queryEnv)
CachedPlanSource * CopyCachedPlan(CachedPlanSource *plansource)
void ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner)
static TupleDesc PlanCacheComputeResultDesc(List *stmt_list)
static dlist_head saved_plan_list
PlannedStmt * UpdateCachedPlan(CachedPlanSource *plansource, int query_index, QueryEnvironment *queryEnv)
static void AcquirePlannerLocks(List *stmt_list, bool acquire)
static void ResourceOwnerForgetPlanCacheRef(ResourceOwner owner, CachedPlan *plan)
static double cached_plan_cost(CachedPlan *plan, bool include_planner)
static void ResOwnerReleaseCachedPlan(Datum res)
static void ScanQueryForLocks(Query *parsetree, bool acquire)
void ReleaseAllPlanCacheRefsInOwner(ResourceOwner owner)
void ResetPlanCache(void)
static void PlanCacheRelCallback(Datum arg, Oid relid)
static Query * QueryListGetPrimaryStmt(List *stmts)
#define StmtPlanRequiresRevalidation(plansource)
static void AcquireExecutorLocks(List *stmt_list, bool acquire)
#define CACHEDPLANSOURCE_MAGIC
@ PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN
@ PLAN_CACHE_MODE_FORCE_GENERIC_PLAN
Expr * expression_planner_with_deps(Expr *expr, List **relationOids, List **invalItems)
List * pg_analyze_and_rewrite_withcb(RawStmt *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg, QueryEnvironment *queryEnv)
List * pg_plan_queries(List *querytrees, const char *query_string, int cursorOptions, ParamListInfo boundParams)
List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
PortalStrategy ChoosePortalStrategy(List *stmts)
List * FetchStatementTargetList(Node *stmt)
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
void ResourceOwnerReleaseAllOfKind(ResourceOwner owner, const ResourceOwnerDesc *kind)
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
void ResourceOwnerEnlarge(ResourceOwner owner)
#define RELEASE_PRIO_PLANCACHE_REFS
@ RESOURCE_RELEASE_AFTER_LOCKS
void extract_query_dependencies(Node *query, List **relationOids, List **invalItems, bool *hasRowSecurity)
Snapshot GetTransactionSnapshot(void)
void PushActiveSnapshot(Snapshot snapshot)
TransactionId TransactionXmin
bool ActiveSnapshotSet(void)
void PopActiveSnapshot(void)
struct CachedPlan * gplan
struct SearchPathMatcher * search_path
MemoryContext query_context
const char * query_string
ParserSetupHook parserSetup
struct RawStmt * raw_parse_tree
Bitmapset * unprunableRelids
#define InvalidTransactionId
#define TransactionIdEquals(id1, id2)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
void FreeTupleDesc(TupleDesc tupdesc)
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
bool equalRowTypes(TupleDesc tupdesc1, TupleDesc tupdesc2)
Query * UtilityContainsQuery(Node *parsetree)
TupleDesc UtilityTupleDescriptor(Node *parsetree)