mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-17 19:30:00 +08:00
Expose an API for calculating catcache hash values.
Now that cache invalidation callbacks get only a hash value, and not a tuple TID (per commits632ae6829f
andb5282aa893
), the only way they can restrict what they invalidate is to know what the hash values mean. setrefs.c was doing this via a hard-wired assumption but that seems pretty grotty, and it'll only get worse as more cases come up. So let's expose a calculation function that takes the same parameters as SearchSysCache. Per complaint from Marko Kreen.
This commit is contained in:
parent
e685a8e665
commit
d4bf3c9c94
@ -15,7 +15,6 @@
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/hash.h"
|
||||
#include "access/transam.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
@ -1830,14 +1829,11 @@ record_plan_function_dependency(PlannerInfo *root, Oid funcid)
|
||||
/*
|
||||
* It would work to use any syscache on pg_proc, but the easiest is
|
||||
* PROCOID since we already have the function's OID at hand. Note
|
||||
* that plancache.c knows we use PROCOID. Also, we're perhaps
|
||||
* assuming more than we should about how CatalogCacheComputeHashValue
|
||||
* computes hash values...
|
||||
* that plancache.c knows we use PROCOID.
|
||||
*/
|
||||
inval_item->cacheId = PROCOID;
|
||||
inval_item->hashValue =
|
||||
DatumGetUInt32(DirectFunctionCall1(hashoid,
|
||||
ObjectIdGetDatum(funcid)));
|
||||
inval_item->hashValue = GetSysCacheHashValue1(PROCOID,
|
||||
ObjectIdGetDatum(funcid));
|
||||
|
||||
root->glob->invalItems = lappend(root->glob->invalItems, inval_item);
|
||||
}
|
||||
|
40
src/backend/utils/cache/catcache.c
vendored
40
src/backend/utils/cache/catcache.c
vendored
@ -1281,6 +1281,46 @@ ReleaseCatCache(HeapTuple tuple)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GetCatCacheHashValue
|
||||
*
|
||||
* Compute the hash value for a given set of search keys.
|
||||
*
|
||||
* The reason for exposing this as part of the API is that the hash value is
|
||||
* exposed in cache invalidation operations, so there are places outside the
|
||||
* catcache code that need to be able to compute the hash values.
|
||||
*/
|
||||
uint32
|
||||
GetCatCacheHashValue(CatCache *cache,
|
||||
Datum v1,
|
||||
Datum v2,
|
||||
Datum v3,
|
||||
Datum v4)
|
||||
{
|
||||
ScanKeyData cur_skey[CATCACHE_MAXKEYS];
|
||||
|
||||
/*
|
||||
* one-time startup overhead for each cache
|
||||
*/
|
||||
if (cache->cc_tupdesc == NULL)
|
||||
CatalogCacheInitializeCache(cache);
|
||||
|
||||
/*
|
||||
* initialize the search key information
|
||||
*/
|
||||
memcpy(cur_skey, cache->cc_skey, sizeof(cur_skey));
|
||||
cur_skey[0].sk_argument = v1;
|
||||
cur_skey[1].sk_argument = v2;
|
||||
cur_skey[2].sk_argument = v3;
|
||||
cur_skey[3].sk_argument = v4;
|
||||
|
||||
/*
|
||||
* calculate the hash value
|
||||
*/
|
||||
return CatalogCacheComputeHashValue(cache, cache->cc_nkeys, cur_skey);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SearchCatCacheList
|
||||
*
|
||||
|
24
src/backend/utils/cache/syscache.c
vendored
24
src/backend/utils/cache/syscache.c
vendored
@ -1050,6 +1050,30 @@ SysCacheGetAttr(int cacheId, HeapTuple tup,
|
||||
isNull);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetSysCacheHashValue
|
||||
*
|
||||
* Get the hash value that would be used for a tuple in the specified cache
|
||||
* with the given search keys.
|
||||
*
|
||||
* The reason for exposing this as part of the API is that the hash value is
|
||||
* exposed in cache invalidation operations, so there are places outside the
|
||||
* catcache code that need to be able to compute the hash values.
|
||||
*/
|
||||
uint32
|
||||
GetSysCacheHashValue(int cacheId,
|
||||
Datum key1,
|
||||
Datum key2,
|
||||
Datum key3,
|
||||
Datum key4)
|
||||
{
|
||||
if (cacheId < 0 || cacheId >= SysCacheSize ||
|
||||
!PointerIsValid(SysCache[cacheId]))
|
||||
elog(ERROR, "invalid cache ID: %d", cacheId);
|
||||
|
||||
return GetCatCacheHashValue(SysCache[cacheId], key1, key2, key3, key4);
|
||||
}
|
||||
|
||||
/*
|
||||
* List-search interface
|
||||
*/
|
||||
|
@ -174,6 +174,10 @@ extern HeapTuple SearchCatCache(CatCache *cache,
|
||||
Datum v3, Datum v4);
|
||||
extern void ReleaseCatCache(HeapTuple tuple);
|
||||
|
||||
extern uint32 GetCatCacheHashValue(CatCache *cache,
|
||||
Datum v1, Datum v2,
|
||||
Datum v3, Datum v4);
|
||||
|
||||
extern CatCList *SearchCatCacheList(CatCache *cache, int nkeys,
|
||||
Datum v1, Datum v2,
|
||||
Datum v3, Datum v4);
|
||||
|
@ -113,6 +113,9 @@ extern bool SearchSysCacheExistsAttName(Oid relid, const char *attname);
|
||||
extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup,
|
||||
AttrNumber attributeNumber, bool *isNull);
|
||||
|
||||
extern uint32 GetSysCacheHashValue(int cacheId,
|
||||
Datum key1, Datum key2, Datum key3, Datum key4);
|
||||
|
||||
/* list-search interface. Users of this must import catcache.h too */
|
||||
extern struct catclist *SearchSysCacheList(int cacheId, int nkeys,
|
||||
Datum key1, Datum key2, Datum key3, Datum key4);
|
||||
@ -158,6 +161,15 @@ extern struct catclist *SearchSysCacheList(int cacheId, int nkeys,
|
||||
#define GetSysCacheOid4(cacheId, key1, key2, key3, key4) \
|
||||
GetSysCacheOid(cacheId, key1, key2, key3, key4)
|
||||
|
||||
#define GetSysCacheHashValue1(cacheId, key1) \
|
||||
GetSysCacheHashValue(cacheId, key1, 0, 0, 0)
|
||||
#define GetSysCacheHashValue2(cacheId, key1, key2) \
|
||||
GetSysCacheHashValue(cacheId, key1, key2, 0, 0)
|
||||
#define GetSysCacheHashValue3(cacheId, key1, key2, key3) \
|
||||
GetSysCacheHashValue(cacheId, key1, key2, key3, 0)
|
||||
#define GetSysCacheHashValue4(cacheId, key1, key2, key3, key4) \
|
||||
GetSysCacheHashValue(cacheId, key1, key2, key3, key4)
|
||||
|
||||
#define SearchSysCacheList1(cacheId, key1) \
|
||||
SearchSysCacheList(cacheId, 1, key1, 0, 0, 0)
|
||||
#define SearchSysCacheList2(cacheId, key1, key2) \
|
||||
|
Loading…
Reference in New Issue
Block a user