plan-inval-proc.patch
text/x-diff
Filename: plan-inval-proc.patch
Type: text/x-diff
Part: 0
Patch
Format: context
| File | + | − |
|---|---|---|
| src/backend/commands/functioncmds.c | 4 | 0 |
| src/backend/utils/cache/inval.c | 103 | 15 |
| src/backend/utils/cache/plancache.c | 21 | 0 |
| src/include/storage/sinval.h | 10 | 0 |
| src/include/utils/inval.h | 5 | 0 |
*** ./src/backend/commands/functioncmds.c.orig 2008-08-06 17:01:28.000000000 +0300
--- ./src/backend/commands/functioncmds.c 2008-08-06 19:10:51.000000000 +0300
***************
*** 59,64 ****
--- 59,65 ----
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
+ #include "utils/inval.h"
static void AlterFunctionOwner_internal(Relation rel, HeapTuple tup,
***************
*** 906,911 ****
--- 907,915 ----
object.objectSubId = 0;
performDeletion(&object, stmt->behavior);
+
+ /* Notify that cached plans should be replanned */
+ CacheInvalidateProcedure(funcOid);
}
/*
*** ./src/backend/utils/cache/inval.c.orig 2008-08-06 16:12:17.000000000 +0300
--- ./src/backend/utils/cache/inval.c 2008-08-06 18:01:24.000000000 +0300
***************
*** 115,121 ****
typedef struct InvalidationListHeader
{
InvalidationChunk *cclist; /* list of chunks holding catcache msgs */
! InvalidationChunk *rclist; /* list of chunks holding relcache/smgr msgs */
} InvalidationListHeader;
/*----------------
--- 115,121 ----
typedef struct InvalidationListHeader
{
InvalidationChunk *cclist; /* list of chunks holding catcache msgs */
! InvalidationChunk *rclist; /* list of chunks holding relcache/smgr/proc msgs */
} InvalidationListHeader;
/*----------------
***************
*** 177,182 ****
--- 177,183 ----
#define TWOPHASE_INFO_FILE_AFTER 2 /* relcache file inval */
static void PersistInvalidationMessage(SharedInvalidationMessage *msg);
+ static void CacheRegisterCallback(int cacheid, CacheCallbackFunction func, Datum arg);
/* ----------------------------------------------------------------
***************
*** 363,368 ****
--- 364,393 ----
}
/*
+ * Add a proc inval entry
+ */
+ static void
+ AddProcInvalidationMessage(InvalidationListHeader *hdr,
+ Oid dbId, Oid procId)
+ {
+ SharedInvalidationMessage msg;
+
+ /* Don't add a duplicate item */
+ /* We assume dbId need not be checked because it will never change */
+
+ /* XXX: for now, only keep one proc invalidation message per database */
+ ProcessMessageList(hdr->rclist,
+ if (msg->pm.id == SHAREDINVALPROC_ID)
+ return);
+
+ /* OK, add the item */
+ msg.pm.id = SHAREDINVALPROC_ID;
+ msg.pm.dbId = dbId;
+ msg.pm.procId = procId;
+ AddInvalidationMessage(&hdr->rclist, &msg);
+ }
+
+ /*
* Append one list of invalidation messages to another, resetting
* the source list to empty.
*/
***************
*** 465,470 ****
--- 490,512 ----
}
/*
+ * RegisterProcInvalidation
+ *
+ * As above, but register a procedure invalidation event.
+ */
+ static void
+ RegisterProcInvalidation(Oid dbId, Oid procId)
+ {
+ AddProcInvalidationMessage(&transInvalInfo->CurrentCmdInvalidMsgs,
+ dbId, procId);
+
+ /*
+ * As above, just in case there is not an associated catalog change.
+ */
+ (void) GetCurrentCommandId(true);
+ }
+
+ /*
* LocalExecuteInvalidationMessage
*
* Process a single invalidation message (which could be of any type).
***************
*** 516,521 ****
--- 558,577 ----
*/
smgrclosenode(msg->sm.rnode);
}
+ else if (msg->id == SHAREDINVALPROC_ID)
+ {
+ if (msg->rc.dbId == MyDatabaseId)
+ {
+ /* for now we just need to handle callback functions */
+ for (i = 0; i < cache_callback_count; i++)
+ {
+ struct CACHECALLBACK *ccitem = cache_callback_list + i;
+
+ if (ccitem->id == SHAREDINVALPROC_ID)
+ (*ccitem->function) (ccitem->arg, msg->rc.relId);
+ }
+ }
+ }
else
elog(FATAL, "unrecognized SI message id: %d", msg->id);
}
***************
*** 1175,1191 ****
}
/*
! * CacheRegisterSyscacheCallback
* Register the specified function to be called for all future
* invalidation events in the specified cache.
*
- * 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.
*/
! void
! CacheRegisterSyscacheCallback(int cacheid,
CacheCallbackFunction func,
Datum arg)
{
--- 1231,1254 ----
}
/*
! * CacheInvalidateProcedure
! * Register invalidation of the specified stored procedure.
! *
! */
! void
! CacheInvalidateProcedure(Oid procId)
! {
! RegisterProcInvalidation(MyDatabaseId, procId);
! }
!
! /*
! * CacheRegisterCallback
* Register the specified function to be called for all future
* invalidation events in the specified cache.
*
*/
! static void
! CacheRegisterCallback(int cacheid,
CacheCallbackFunction func,
Datum arg)
{
***************
*** 1199,1204 ****
--- 1262,1286 ----
++cache_callback_count;
}
+
+ /*
+ * CacheRegisterSyscacheCallback
+ * Register the specified function to be called for all future
+ * invalidation events in the specified cache.
+ *
+ * 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.
+ */
+ void
+ CacheRegisterSyscacheCallback(int cacheid,
+ CacheCallbackFunction func,
+ Datum arg)
+ {
+ CacheRegisterCallback(cacheid, func, arg);
+ }
+
/*
* CacheRegisterRelcacheCallback
* Register the specified function to be called for all future
***************
*** 1212,1223 ****
CacheRegisterRelcacheCallback(CacheCallbackFunction func,
Datum arg)
{
! if (cache_callback_count >= MAX_CACHE_CALLBACKS)
! elog(FATAL, "out of cache_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;
! ++cache_callback_count;
}
--- 1294,1311 ----
CacheRegisterRelcacheCallback(CacheCallbackFunction func,
Datum arg)
{
! CacheRegisterCallback(SHAREDINVALRELCACHE_ID, func, arg);
! }
! /*
! * CacheRegisterProcCallback
! * Register the specified function to be called for all future
! * proccache invalidation events. The OID of the procedure being
! * invalidated will be passed to the function.
! */
! void
! CacheRegisterProcCallback(CacheCallbackFunction func, Datum arg)
! {
! CacheRegisterCallback(SHAREDINVALPROC_ID, func, arg);
}
+
*** ./src/backend/utils/cache/plancache.c.orig 2008-08-06 16:43:11.000000000 +0300
--- ./src/backend/utils/cache/plancache.c 2008-08-06 18:34:30.000000000 +0300
***************
*** 82,87 ****
--- 82,88 ----
static bool rowmark_member(List *rowMarks, int rt_index);
static bool plan_list_is_transient(List *stmt_list);
static void PlanCacheCallback(Datum arg, Oid relid);
+ static void PlanCacheProcCallback(Datum arg, Oid procId);
static void InvalRelid(Oid relid, LOCKMODE lockmode,
InvalRelidContext *context);
***************
*** 95,100 ****
--- 96,102 ----
InitPlanCache(void)
{
CacheRegisterRelcacheCallback(PlanCacheCallback, (Datum) 0);
+ CacheRegisterProcCallback(PlanCacheProcCallback, (Datum) 0);
}
/*
***************
*** 925,930 ****
--- 927,951 ----
}
/*
+ * PlanCacheProcCallback
+ * Procedure inval callback function
+ *
+ * XXX: For now we just throw away everything.
+ */
+ static void
+ PlanCacheProcCallback(Datum arg, Oid procId)
+ {
+ ListCell *lc;
+
+ foreach(lc, cached_plans_list)
+ {
+ CachedPlanSource *ps = (CachedPlanSource *)lfirst(lc);
+ if (ps && ps->plan)
+ ps->plan->dead = true;
+ }
+ }
+
+ /*
* ResetPlanCache: drop all cached plans.
*/
void
*** ./src/include/storage/sinval.h.orig 2008-08-06 16:19:41.000000000 +0300
--- ./src/include/storage/sinval.h 2008-08-06 16:32:50.000000000 +0300
***************
*** 74,85 ****
--- 74,95 ----
RelFileNode rnode; /* physical file ID */
} SharedInvalSmgrMsg;
+ #define SHAREDINVALPROC_ID (-3)
+
+ typedef struct
+ {
+ int16 id; /* type field --- must be first */
+ Oid dbId; /* database ID */
+ Oid procId; /* procedure ID */
+ } SharedInvalProcMsg;
+
typedef union
{
int16 id; /* type field --- must be first */
SharedInvalCatcacheMsg cc;
SharedInvalRelcacheMsg rc;
SharedInvalSmgrMsg sm;
+ SharedInvalProcMsg pm;
} SharedInvalidationMessage;
*** ./src/include/utils/inval.h.orig 2008-08-06 16:27:58.000000000 +0300
--- ./src/include/utils/inval.h 2008-08-06 16:55:40.000000000 +0300
***************
*** 49,54 ****
--- 49,56 ----
extern void CacheInvalidateRelcacheByRelid(Oid relid);
+ extern void CacheInvalidateProcedure(Oid procId);
+
extern void CacheRegisterSyscacheCallback(int cacheid,
CacheCallbackFunction func,
Datum arg);
***************
*** 56,61 ****
--- 58,66 ----
extern void CacheRegisterRelcacheCallback(CacheCallbackFunction func,
Datum arg);
+ extern void CacheRegisterProcCallback(CacheCallbackFunction func,
+ Datum arg);
+
extern void inval_twophase_postcommit(TransactionId xid, uint16 info,
void *recdata, uint32 len);