Commit ee33b95d authored by Tom Lane's avatar Tom Lane

Improve the plan cache invalidation mechanism to make it invalidate plans

when user-defined functions used in a plan are modified.  Also invalidate
plans when schemas, operators, or operator classes are modified; but for these
cases we just invalidate everything rather than tracking exact dependencies,
since these types of objects seldom change in a production database.

Tom Lane; loosely based on a patch by Martin Pihlak.
parent c06629c7
......@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.111 2008/09/01 20:42:43 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.112 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -187,7 +187,7 @@ static void recomputeNamespacePath(void);
static void InitTempTableNamespace(void);
static void RemoveTempRelations(Oid tempNamespaceId);
static void RemoveTempRelationsCallback(int code, Datum arg);
static void NamespaceCallback(Datum arg, Oid relid);
static void NamespaceCallback(Datum arg, int cacheid, ItemPointer tuplePtr);
/* These don't really need to appear in any header file */
Datum pg_table_is_visible(PG_FUNCTION_ARGS);
......@@ -3094,7 +3094,7 @@ InitializeSearchPath(void)
* Syscache inval callback function
*/
static void
NamespaceCallback(Datum arg, Oid relid)
NamespaceCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
{
/* Force search path to be recomputed on next use */
baseSearchPathValid = false;
......
......@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.404 2008/09/01 20:42:44 tgl Exp $
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.405 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -88,6 +88,7 @@ _copyPlannedStmt(PlannedStmt *from)
COPY_NODE_FIELD(returningLists);
COPY_NODE_FIELD(rowMarks);
COPY_NODE_FIELD(relationOids);
COPY_NODE_FIELD(invalItems);
COPY_SCALAR_FIELD(nParamExec);
return newnode;
......@@ -689,6 +690,21 @@ _copyLimit(Limit *from)
return newnode;
}
/*
* _copyPlanInvalItem
*/
static PlanInvalItem *
_copyPlanInvalItem(PlanInvalItem *from)
{
PlanInvalItem *newnode = makeNode(PlanInvalItem);
COPY_SCALAR_FIELD(cacheId);
/* tupleId isn't really a "scalar", but this works anyway */
COPY_SCALAR_FIELD(tupleId);
return newnode;
}
/* ****************************************************************
* primnodes.h copy functions
* ****************************************************************
......@@ -3157,6 +3173,9 @@ copyObject(void *from)
case T_Limit:
retval = _copyLimit(from);
break;
case T_PlanInvalItem:
retval = _copyPlanInvalItem(from);
break;
/*
* PRIMITIVE NODES
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.338 2008/09/01 20:42:44 tgl Exp $
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.339 2008/09/09 18:58:08 tgl Exp $
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
......@@ -255,6 +255,7 @@ _outPlannedStmt(StringInfo str, PlannedStmt *node)
WRITE_NODE_FIELD(returningLists);
WRITE_NODE_FIELD(rowMarks);
WRITE_NODE_FIELD(relationOids);
WRITE_NODE_FIELD(invalItems);
WRITE_INT_FIELD(nParamExec);
}
......@@ -593,6 +594,14 @@ _outUnique(StringInfo str, Unique *node)
appendStringInfo(str, " %u", node->uniqOperators[i]);
}
static void
_outHash(StringInfo str, Hash *node)
{
WRITE_NODE_TYPE("HASH");
_outPlanInfo(str, (Plan *) node);
}
static void
_outSetOp(StringInfo str, SetOp *node)
{
......@@ -631,11 +640,14 @@ _outLimit(StringInfo str, Limit *node)
}
static void
_outHash(StringInfo str, Hash *node)
_outPlanInvalItem(StringInfo str, PlanInvalItem *node)
{
WRITE_NODE_TYPE("HASH");
WRITE_NODE_TYPE("PLANINVALITEM");
_outPlanInfo(str, (Plan *) node);
WRITE_INT_FIELD(cacheId);
appendStringInfo(str, " :tupleId (%u,%u)",
ItemPointerGetBlockNumber(&node->tupleId),
ItemPointerGetOffsetNumber(&node->tupleId));
}
/*****************************************************************************
......@@ -1354,6 +1366,7 @@ _outPlannerGlobal(StringInfo str, PlannerGlobal *node)
WRITE_BITMAPSET_FIELD(rewindPlanIDs);
WRITE_NODE_FIELD(finalrtable);
WRITE_NODE_FIELD(relationOids);
WRITE_NODE_FIELD(invalItems);
}
static void
......@@ -2206,14 +2219,17 @@ _outNode(StringInfo str, void *obj)
case T_Unique:
_outUnique(str, obj);
break;
case T_Hash:
_outHash(str, obj);
break;
case T_SetOp:
_outSetOp(str, obj);
break;
case T_Limit:
_outLimit(str, obj);
break;
case T_Hash:
_outHash(str, obj);
case T_PlanInvalItem:
_outPlanInvalItem(str, obj);
break;
case T_Alias:
_outAlias(str, obj);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.242 2008/08/17 01:19:59 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.243 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -140,6 +140,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
glob->rewindPlanIDs = NULL;
glob->finalrtable = NIL;
glob->relationOids = NIL;
glob->invalItems = NIL;
glob->transientPlan = false;
/* Determine what fraction of the plan is likely to be scanned */
......@@ -213,6 +214,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
result->returningLists = root->returningLists;
result->rowMarks = parse->rowMarks;
result->relationOids = glob->relationOids;
result->invalItems = glob->invalItems;
result->nParamExec = list_length(glob->paramlist);
return result;
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.266 2008/08/28 23:09:46 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.267 2008/09/09 18:58:08 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
......@@ -50,6 +50,7 @@
typedef struct
{
ParamListInfo boundParams;
PlannerGlobal *glob;
List *active_fns;
Node *case_val;
bool estimate;
......@@ -1890,9 +1891,15 @@ eval_const_expressions(PlannerInfo *root, Node *node)
eval_const_expressions_context context;
if (root)
{
context.boundParams = root->glob->boundParams; /* bound Params */
context.glob = root->glob; /* for inlined-function dependencies */
}
else
{
context.boundParams = NULL;
context.glob = NULL;
}
context.active_fns = NIL; /* nothing being recursively simplified */
context.case_val = NULL; /* no CASE being examined */
context.estimate = false; /* safe transformations only */
......@@ -1921,6 +1928,8 @@ estimate_expression_value(PlannerInfo *root, Node *node)
eval_const_expressions_context context;
context.boundParams = root->glob->boundParams; /* bound Params */
/* we do not need to mark the plan as depending on inlined functions */
context.glob = NULL;
context.active_fns = NIL; /* nothing being recursively simplified */
context.case_val = NULL; /* no CASE being examined */
context.estimate = true; /* unsafe transformations OK */
......@@ -3468,6 +3477,13 @@ inline_function(Oid funcid, Oid result_type, List *args,
MemoryContextDelete(mycxt);
/*
* Since there is now no trace of the function in the plan tree, we
* must explicitly record the plan's dependency on the function.
*/
if (context->glob)
record_plan_function_dependency(context->glob, funcid);
/*
* Recursively try to simplify the modified expression. Here we must add
* the current function to the context list of active functions.
......@@ -3842,6 +3858,12 @@ inline_set_returning_function(PlannerInfo *root, Node *node)
error_context_stack = sqlerrcontext.previous;
ReleaseSysCache(func_tuple);
/*
* Since there is now no trace of the function in the plan tree, we
* must explicitly record the plan's dependency on the function.
*/
record_plan_function_dependency(root->glob, fexpr->funcid);
return querytree;
/* Here if func is not inlinable: release temp memory and return NULL */
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_oper.c,v 1.105 2008/08/28 23:09:47 tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_oper.c,v 1.106 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -79,7 +79,7 @@ static bool make_oper_cache_key(OprCacheKey *key, List *opname,
Oid ltypeId, Oid rtypeId);
static Oid find_oper_cache_entry(OprCacheKey *key);
static void make_oper_cache_entry(OprCacheKey *key, Oid opr_oid);
static void InvalidateOprCacheCallBack(Datum arg, Oid relid);
static void InvalidateOprCacheCallBack(Datum arg, int cacheid, ItemPointer tuplePtr);
/*
......@@ -1130,7 +1130,7 @@ make_oper_cache_entry(OprCacheKey *key, Oid opr_oid)
* Callback for pg_operator and pg_cast inval events
*/
static void
InvalidateOprCacheCallBack(Datum arg, Oid relid)
InvalidateOprCacheCallBack(Datum arg, int cacheid, ItemPointer tuplePtr)
{
HASH_SEQ_STATUS status;
OprCacheEntry *hentry;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.141 2008/09/08 00:47:40 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.142 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -92,7 +92,7 @@ static AclMode convert_tablespace_priv_string(text *priv_type_text);
static AclMode convert_role_priv_string(text *priv_type_text);
static AclResult pg_role_aclcheck(Oid role_oid, Oid roleid, AclMode mode);
static void RoleMembershipCacheCallback(Datum arg, Oid relid);
static void RoleMembershipCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr);
/*
......@@ -2822,7 +2822,7 @@ initialize_acl(void)
* Syscache inval callback function
*/
static void
RoleMembershipCacheCallback(Datum arg, Oid relid)
RoleMembershipCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
{
/* Force membership caches to be recomputed on next use */
cached_privs_role = InvalidOid;
......
......@@ -80,7 +80,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.86 2008/06/19 21:32:56 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.87 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -160,16 +160,25 @@ static TransInvalidationInfo *transInvalInfo = NULL;
* assumes there won't be very many of these at once; could improve if needed.
*/
#define MAX_CACHE_CALLBACKS 20
#define MAX_SYSCACHE_CALLBACKS 20
#define MAX_RELCACHE_CALLBACKS 5
static struct CACHECALLBACK
static struct SYSCACHECALLBACK
{
int16 id; /* cache number or message type id */
CacheCallbackFunction function;
int16 id; /* cache number */
SyscacheCallbackFunction function;
Datum arg;
} cache_callback_list[MAX_CACHE_CALLBACKS];
} syscache_callback_list[MAX_SYSCACHE_CALLBACKS];
static int cache_callback_count = 0;
static int syscache_callback_count = 0;
static struct RELCACHECALLBACK
{
RelcacheCallbackFunction function;
Datum arg;
} relcache_callback_list[MAX_RELCACHE_CALLBACKS];
static int relcache_callback_count = 0;
/* info values for 2PC callback */
#define TWOPHASE_INFO_MSG 0 /* SharedInvalidationMessage */
......@@ -484,12 +493,13 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
msg->cc.hashValue,
&msg->cc.tuplePtr);
for (i = 0; i < cache_callback_count; i++)
for (i = 0; i < syscache_callback_count; i++)
{
struct CACHECALLBACK *ccitem = cache_callback_list + i;
struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
if (ccitem->id == msg->cc.id)
(*ccitem->function) (ccitem->arg, InvalidOid);
(*ccitem->function) (ccitem->arg,
msg->cc.id, &msg->cc.tuplePtr);
}
}
}
......@@ -499,12 +509,11 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
{
RelationCacheInvalidateEntry(msg->rc.relId);
for (i = 0; i < cache_callback_count; i++)
for (i = 0; i < relcache_callback_count; i++)
{
struct CACHECALLBACK *ccitem = cache_callback_list + i;
struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
if (ccitem->id == SHAREDINVALRELCACHE_ID)
(*ccitem->function) (ccitem->arg, msg->rc.relId);
(*ccitem->function) (ccitem->arg, msg->rc.relId);
}
}
}
......@@ -539,9 +548,16 @@ InvalidateSystemCaches(void)
ResetCatalogCaches();
RelationCacheInvalidate(); /* gets smgr cache too */
for (i = 0; i < cache_callback_count; i++)
for (i = 0; i < syscache_callback_count; i++)
{
struct CACHECALLBACK *ccitem = cache_callback_list + i;
struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
(*ccitem->function) (ccitem->arg, ccitem->id, NULL);
}
for (i = 0; i < relcache_callback_count; i++)
{
struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
(*ccitem->function) (ccitem->arg, InvalidOid);
}
......@@ -1177,26 +1193,25 @@ CacheInvalidateRelcacheByRelid(Oid relid)
/*
* CacheRegisterSyscacheCallback
* Register the specified function to be called for all future
* invalidation events in the specified cache.
* invalidation events in the specified cache. The cache ID and the
* TID of the tuple being invalidated will be passed to the function.
*
* NOTE: currently, the OID argument to the callback routine is not
* provided for syscache callbacks; the routine doesn't really get any
* useful info as to exactly what changed. It should treat every call
* as a "cache flush" request.
* NOTE: NULL will be passed for the TID if a cache reset request is received.
* In this case the called routines should flush all cached state.
*/
void
CacheRegisterSyscacheCallback(int cacheid,
CacheCallbackFunction func,
SyscacheCallbackFunction func,
Datum arg)
{
if (cache_callback_count >= MAX_CACHE_CALLBACKS)
elog(FATAL, "out of cache_callback_list slots");
if (syscache_callback_count >= MAX_SYSCACHE_CALLBACKS)
elog(FATAL, "out of syscache_callback_list slots");
cache_callback_list[cache_callback_count].id = cacheid;
cache_callback_list[cache_callback_count].function = func;
cache_callback_list[cache_callback_count].arg = arg;
syscache_callback_list[syscache_callback_count].id = cacheid;
syscache_callback_list[syscache_callback_count].function = func;
syscache_callback_list[syscache_callback_count].arg = arg;
++cache_callback_count;
++syscache_callback_count;
}
/*
......@@ -1209,15 +1224,14 @@ CacheRegisterSyscacheCallback(int cacheid,
* In this case the called routines should flush all cached state.
*/
void
CacheRegisterRelcacheCallback(CacheCallbackFunction func,
CacheRegisterRelcacheCallback(RelcacheCallbackFunction func,
Datum arg)
{
if (cache_callback_count >= MAX_CACHE_CALLBACKS)
elog(FATAL, "out of cache_callback_list slots");
if (relcache_callback_count >= MAX_RELCACHE_CALLBACKS)
elog(FATAL, "out of relcache_callback_list slots");
cache_callback_list[cache_callback_count].id = SHAREDINVALRELCACHE_ID;
cache_callback_list[cache_callback_count].function = func;
cache_callback_list[cache_callback_count].arg = arg;
relcache_callback_list[relcache_callback_count].function = func;
relcache_callback_list[relcache_callback_count].arg = arg;
++cache_callback_count;
++relcache_callback_count;
}
This diff is collapsed.
......@@ -20,7 +20,7 @@
* Copyright (c) 2006-2008, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/ts_cache.c,v 1.7 2008/04/12 23:14:21 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/cache/ts_cache.c,v 1.8 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -79,18 +79,19 @@ static Oid TSCurrentConfigCache = InvalidOid;
/*
* We use this catcache callback to detect when a visible change to a TS
* We use this syscache callback to detect when a visible change to a TS
* catalog entry has been made, by either our own backend or another one.
* We don't get enough information to know *which* specific catalog row
* changed, so we have to invalidate all related cache entries. Fortunately,
* it seems unlikely that TS configuration changes will occur often enough
* for this to be a performance problem.
*
* In principle we could just flush the specific cache entry that changed,
* but given that TS configuration changes are probably infrequent, it
* doesn't seem worth the trouble to determine that; we just flush all the
* entries of the related hash table.
*
* We can use the same function for all TS caches by passing the hash
* table address as the "arg".
*/
static void
InvalidateTSCacheCallBack(Datum arg, Oid relid)
InvalidateTSCacheCallBack(Datum arg, int cacheid, ItemPointer tuplePtr)
{
HTAB *hash = (HTAB *) DatumGetPointer(arg);
HASH_SEQ_STATUS status;
......
......@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/superuser.c,v 1.37 2008/01/01 19:45:54 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/superuser.c,v 1.38 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -36,7 +36,7 @@ static Oid last_roleid = InvalidOid; /* InvalidOid == cache not valid */
static bool last_roleid_is_super = false;
static bool roleid_callback_registered = false;
static void RoleidCallback(Datum arg, Oid relid);
static void RoleidCallback(Datum arg, int cacheid, ItemPointer tuplePtr);
/*
......@@ -102,7 +102,7 @@ superuser_arg(Oid roleid)
* Syscache inval callback function
*/
static void
RoleidCallback(Datum arg, Oid relid)
RoleidCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
{
/* Invalidate our local cache in case role's superuserness changed */
last_roleid = InvalidOid;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.211 2008/08/30 01:39:14 tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.212 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -67,6 +67,8 @@ typedef enum NodeTag
T_Hash,
T_SetOp,
T_Limit,
/* this one isn't a subclass of Plan: */
T_PlanInvalItem,
/*
* TAGS FOR PLAN STATE NODES (execnodes.h)
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.102 2008/08/07 19:35:02 tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.103 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -17,6 +17,7 @@
#include "access/sdir.h"
#include "nodes/bitmapset.h"
#include "nodes/primnodes.h"
#include "storage/itemptr.h"
/* ----------------------------------------------------------------
......@@ -72,6 +73,8 @@ typedef struct PlannedStmt
List *relationOids; /* OIDs of relations the plan depends on */
List *invalItems; /* other dependencies, as PlanInvalItems */
int nParamExec; /* number of PARAM_EXEC Params used */
} PlannedStmt;
......@@ -559,4 +562,21 @@ typedef struct Limit
Node *limitCount; /* COUNT parameter, or NULL if none */
} Limit;
/*
* Plan invalidation info
*
* We track the objects on which a PlannedStmt depends in two ways:
* relations are recorded as a simple list of OIDs, and everything else
* is represented as a list of PlanInvalItems. A PlanInvalItem is designed
* to be used with the syscache invalidation mechanism, so it identifies a
* system catalog entry by cache ID and tuple TID.
*/
typedef struct PlanInvalItem
{
NodeTag type;
int cacheId; /* a syscache ID, see utils/syscache.h */
ItemPointerData tupleId; /* TID of the object's catalog tuple */
} PlanInvalItem;
#endif /* PLANNODES_H */
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.158 2008/08/14 18:48:00 tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.159 2008/09/09 18:58:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -74,6 +74,8 @@ typedef struct PlannerGlobal
List *relationOids; /* OIDs of relations the plan depends on */
List *invalItems; /* other dependencies, as PlanInvalItems */
bool transientPlan; /* redo plan when TransactionXmin changes? */
} PlannerGlobal;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.111 2008/08/14 18:48:00 tgl Exp $
* $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.112 2008/09/09 18:58:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -106,5 +106,9 @@ extern List *set_returning_clause_references(PlannerGlobal *glob,
extern void fix_opfuncids(Node *node);
extern void set_opfuncid(OpExpr *opexpr);
extern void set_sa_opfuncid(ScalarArrayOpExpr *opexpr);
extern void record_plan_function_dependency(PlannerGlobal *glob, Oid funcid);
extern void extract_query_dependencies(List *queries,
List **relationOids,
List **invalItems);
#endif /* PLANMAIN_H */
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/inval.h,v 1.43 2008/06/19 00:46:06 alvherre Exp $
* $PostgreSQL: pgsql/src/include/utils/inval.h,v 1.44 2008/09/09 18:58:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -18,7 +18,8 @@
#include "utils/relcache.h"
typedef void (*CacheCallbackFunction) (Datum arg, Oid relid);
typedef void (*SyscacheCallbackFunction) (Datum arg, int cacheid, ItemPointer tuplePtr);
typedef void (*RelcacheCallbackFunction) (Datum arg, Oid relid);
extern void AcceptInvalidationMessages(void);
......@@ -50,10 +51,10 @@ extern void CacheInvalidateRelcacheByTuple(HeapTuple classTuple);
extern void CacheInvalidateRelcacheByRelid(Oid relid);
extern void CacheRegisterSyscacheCallback(int cacheid,
CacheCallbackFunction func,
SyscacheCallbackFunction func,
Datum arg);
extern void CacheRegisterRelcacheCallback(CacheCallbackFunction func,
extern void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func,
Datum arg);
extern void inval_twophase_postcommit(TransactionId xid, uint16 info,
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/plancache.h,v 1.12 2008/07/18 20:26:06 tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/plancache.h,v 1.13 2008/09/09 18:58:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -79,6 +79,9 @@ typedef struct CachedPlan
int refcount; /* count of live references to this struct */
int generation; /* counter, starting at 1, for replans */
MemoryContext context; /* context containing this CachedPlan */
/* These fields are used only in the not-fully-planned case: */
List *relationOids; /* OIDs of relations the stmts depend on */
List *invalItems; /* other dependencies, as PlanInvalItems */
} CachedPlan;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment