]> granicus.if.org Git - postgresql/commitdiff
Expose an API for calculating catcache hash values.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 7 Mar 2012 19:51:13 +0000 (14:51 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 7 Mar 2012 19:51:13 +0000 (14:51 -0500)
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.

src/backend/optimizer/plan/setrefs.c
src/backend/utils/cache/catcache.c
src/backend/utils/cache/syscache.c
src/include/utils/catcache.h
src/include/utils/syscache.h

index 66d21b2b2c3defcabf969d0912a7611a11055b54..e1b48fb4f53061f5b06653c67275dc0b323bffd0 100644 (file)
@@ -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);
        }
index acd0518748d68d13c276e57f371a642d36885d21..ea3daa599ca000ca4cbe491a59ffb377ebdc56cb 100644 (file)
@@ -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
  *
index 78ce0b881a59c411d5e51f99fed84612e4c08f44..c365ec7597a8fb8e92c4df7e7da571f119d4f98e 100644 (file)
@@ -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
  */
index bc19ef0255f740d24dfbb42c48c2527f5863a6b0..d91700a07e373b25836d7baef9f6fe3d585d5f4d 100644 (file)
@@ -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);
index 0b539dba750174e1f32ce49b3cbd969ac7df3655..d59dd4e0c7038fa2796f4d30855548b31a7daad7 100644 (file)
@@ -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) \