From f44dac0d623783aa7bb3ab03eb9c91bb76d1ae87 Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Mon, 21 Apr 2025 01:40:32 +0300
Subject: [PATCH v1] Maintain RelIdToTypeIdCacheHash in TypeCacheOpcCallback()

b85a9d046efd introduced a new RelIdToTypeIdCacheHash, whose entries should
exist for typecache entries with TCFLAGS_HAVE_PG_TYPE_DATA flag set or any
of TCFLAGS_OPERATOR_FLAGS set or tupDesc set.  However, TypeCacheOpcCallback(),
which resets TCFLAGS_OPERATOR_FLAGS, was forgotten to update
RelIdToTypeIdCacheHash.

This commit adds a delete_rel_type_cache_if_needed() call to the
TypeCacheOpcCallback() function to maintain RelIdToTypeIdCacheHash after
resetting TCFLAGS_OPERATOR_FLAGS.

Also, this commit fixes the name of the delete_rel_type_cache_if_needed()
function in its mentions in the comments.

Reported-by: Noah Misch
Discussion: https://postgr.es/m/20250411203241.e9.nmisch%40google.com
---
 src/backend/utils/cache/typcache.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index ae65a1cce06..560f5595fda 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -2395,7 +2395,7 @@ InvalidateCompositeTypeCacheEntry(TypeCacheEntry *typentry)
 	/* Reset equality/comparison/hashing validity information */
 	typentry->flags &= ~TCFLAGS_OPERATOR_FLAGS;
 
-	/* Call delete_rel_type_cache() if we actually cleared something */
+	/* Call delete_rel_type_cache_if_needed() if we actually cleared something */
 	if (hadTupDescOrOpclass)
 		delete_rel_type_cache_if_needed(typentry);
 }
@@ -2542,7 +2542,7 @@ TypeCacheTypCallback(Datum arg, int cacheid, uint32 hashvalue)
 							 TCFLAGS_CHECKED_DOMAIN_CONSTRAINTS);
 
 		/*
-		 * Call delete_rel_type_cache() if we cleaned
+		 * Call delete_rel_type_cache_if_needed() if we cleaned
 		 * TCFLAGS_HAVE_PG_TYPE_DATA flag previously.
 		 */
 		if (hadPgTypeData)
@@ -2576,8 +2576,17 @@ TypeCacheOpcCallback(Datum arg, int cacheid, uint32 hashvalue)
 	hash_seq_init(&status, TypeCacheHash);
 	while ((typentry = (TypeCacheEntry *) hash_seq_search(&status)) != NULL)
 	{
+		bool		hadOpclass = (typentry->flags & TCFLAGS_OPERATOR_FLAGS);
+
 		/* Reset equality/comparison/hashing validity information */
 		typentry->flags &= ~TCFLAGS_OPERATOR_FLAGS;
+
+		/*
+		 * Call delete_rel_type_cache_if_needed() if we actually cleared
+		 * something
+		 */
+		if (hadOpclass)
+			delete_rel_type_cache_if_needed(typentry);
 	}
 }
 
-- 
2.39.5 (Apple Git-154)

