aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-03-07 14:51:13 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2012-03-07 14:51:13 -0500
commitd4bf3c9c94305e692349fb6fe0c67e483b72ae87 (patch)
treef8b6fb180e026683ad7a06ab723e98eb86986c9d /src
parente685a8e6651b0e55996e6eba6917302607866793 (diff)
downloadpostgresql-d4bf3c9c94305e692349fb6fe0c67e483b72ae87.tar.gz
postgresql-d4bf3c9c94305e692349fb6fe0c67e483b72ae87.zip
Expose an API for calculating catcache hash values.
Now that cache invalidation callbacks get only a hash value, and not a tuple TID (per commits 632ae6829f7abda34e15082c91d9dfb3fc0f298b and b5282aa893e565b7844f8237462cb843438cdd5e), 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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/plan/setrefs.c10
-rw-r--r--src/backend/utils/cache/catcache.c40
-rw-r--r--src/backend/utils/cache/syscache.c24
-rw-r--r--src/include/utils/catcache.h4
-rw-r--r--src/include/utils/syscache.h12
5 files changed, 83 insertions, 7 deletions
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 66d21b2b2c3..e1b48fb4f53 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -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);
}
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index acd0518748d..ea3daa599ca 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -1282,6 +1282,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
*
* Generate a list of all tuples matching a partial key (that is,
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 78ce0b881a5..c365ec7597a 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -1051,6 +1051,30 @@ SysCacheGetAttr(int cacheId, HeapTuple tup,
}
/*
+ * 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
*/
struct catclist *
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index bc19ef0255f..d91700a07e3 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -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);
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 0b539dba750..d59dd4e0c70 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -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) \