diff options
Diffstat (limited to 'src/backend/utils/cache/catcache.c')
-rw-r--r-- | src/backend/utils/cache/catcache.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 6a0c020ff97..00f17d9edc6 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -19,6 +19,7 @@ #include "access/heapam.h" #include "access/relscan.h" #include "access/sysattr.h" +#include "access/tuptoaster.h" #include "access/valid.h" #include "catalog/pg_operator.h" #include "catalog/pg_type.h" @@ -1598,16 +1599,32 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, uint32 hashValue, Index hashIndex, bool negative) { CatCTup *ct; + HeapTuple dtp; MemoryContext oldcxt; /* + * If there are any out-of-line toasted fields in the tuple, expand them + * in-line. This saves cycles during later use of the catcache entry, + * and also protects us against the possibility of the toast tuples being + * freed before we attempt to fetch them, in case of something using a + * slightly stale catcache entry. + */ + if (HeapTupleHasExternal(ntp)) + dtp = toast_flatten_tuple(ntp, cache->cc_tupdesc); + else + dtp = ntp; + + /* * Allocate CatCTup header in cache memory, and copy the tuple there too. */ oldcxt = MemoryContextSwitchTo(CacheMemoryContext); ct = (CatCTup *) palloc(sizeof(CatCTup)); - heap_copytuple_with_tuple(ntp, &ct->tuple); + heap_copytuple_with_tuple(dtp, &ct->tuple); MemoryContextSwitchTo(oldcxt); + if (dtp != ntp) + heap_freetuple(dtp); + /* * Finish initializing the CatCTup header, and add it to the cache's * linked list and counts. |