v2-0001-typcache-Make-initialization-more-resilient-on-OO.patch
text/plain
Filename: v2-0001-typcache-Make-initialization-more-resilient-on-OO.patch
Type: text/plain
Part: 0
Patch
Format: format-patch
Series: patch v2-0001
Subject: typcache: Make initialization more resilient on OOM
| File | + | − |
|---|---|---|
| src/backend/utils/cache/typcache.c | 33 | 24 |
From 8b2ecd4df82750ca98cf7e67244cb46b1e4239ed Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 18 Jun 2026 13:24:47 +0900
Subject: [PATCH v2] typcache: Make initialization more resilient on OOM
---
src/backend/utils/cache/typcache.c | 57 +++++++++++++++++-------------
1 file changed, 33 insertions(+), 24 deletions(-)
diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index da91a2ff1dd8..b96554a4b32e 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -392,50 +392,59 @@ lookup_type_cache(Oid type_id, int flags)
bool found;
int in_progress_offset;
- if (TypeCacheHash == NULL)
+ if (in_progress_list == NULL)
{
/* First time through: initialize the hash table */
HASHCTL ctl;
int allocsize;
- ctl.keysize = sizeof(Oid);
- ctl.entrysize = sizeof(TypeCacheEntry);
+ if (TypeCacheHash == NULL)
+ {
+ ctl.keysize = sizeof(Oid);
+ ctl.entrysize = sizeof(TypeCacheEntry);
- /*
- * TypeCacheEntry takes hash value from the system cache. For
- * TypeCacheHash we use the same hash in order to speedup search by
- * hash value. This is used by hash_seq_init_with_hash_value().
- */
- ctl.hash = type_cache_syshash;
+ /*
+ * TypeCacheEntry takes hash value from the system cache. For
+ * TypeCacheHash we use the same hash in order to speedup search
+ * by hash value. This is used by
+ * hash_seq_init_with_hash_value().
+ */
+ ctl.hash = type_cache_syshash;
- TypeCacheHash = hash_create("Type information cache", 64,
- &ctl, HASH_ELEM | HASH_FUNCTION);
+ TypeCacheHash = hash_create("Type information cache", 64,
+ &ctl, HASH_ELEM | HASH_FUNCTION);
+ }
- Assert(RelIdToTypeIdCacheHash == NULL);
-
- ctl.keysize = sizeof(Oid);
- ctl.entrysize = sizeof(RelIdToTypeIdCacheEntry);
- RelIdToTypeIdCacheHash = hash_create("Map from relid to OID of cached composite type", 64,
- &ctl, HASH_ELEM | HASH_BLOBS);
-
- /* Also set up callbacks for SI invalidations */
- CacheRegisterRelcacheCallback(TypeCacheRelCallback, (Datum) 0);
- CacheRegisterSyscacheCallback(TYPEOID, TypeCacheTypCallback, (Datum) 0);
- CacheRegisterSyscacheCallback(CLAOID, TypeCacheOpcCallback, (Datum) 0);
- CacheRegisterSyscacheCallback(CONSTROID, TypeCacheConstrCallback, (Datum) 0);
+ if (RelIdToTypeIdCacheHash == NULL)
+ {
+ ctl.keysize = sizeof(Oid);
+ ctl.entrysize = sizeof(RelIdToTypeIdCacheEntry);
+ RelIdToTypeIdCacheHash = hash_create("Map from relid to OID of cached composite type", 64,
+ &ctl, HASH_ELEM | HASH_BLOBS);
+ }
/* Also make sure CacheMemoryContext exists */
if (!CacheMemoryContext)
CreateCacheMemoryContext();
/*
- * reserve enough in_progress_list slots for many cases
+ * Reserve enough in_progress_list slots for many cases. This is
+ * the last allocation on purpose, done after the two others.
*/
allocsize = 4;
in_progress_list =
MemoryContextAlloc(CacheMemoryContext,
allocsize * sizeof(*in_progress_list));
in_progress_list_maxlen = allocsize;
+
+ /*
+ * Set up callbacks for SI invalidations. These are done last,
+ * once all the other initializations are done.
+ */
+ CacheRegisterRelcacheCallback(TypeCacheRelCallback, (Datum) 0);
+ CacheRegisterSyscacheCallback(TYPEOID, TypeCacheTypCallback, (Datum) 0);
+ CacheRegisterSyscacheCallback(CLAOID, TypeCacheOpcCallback, (Datum) 0);
+ CacheRegisterSyscacheCallback(CONSTROID, TypeCacheConstrCallback, (Datum) 0);
}
Assert(TypeCacheHash != NULL && RelIdToTypeIdCacheHash != NULL);
--
2.54.0