diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c index 16c52c5a38a..a0a71dd86a8 100644 --- a/src/backend/utils/cache/typcache.c +++ b/src/backend/utils/cache/typcache.c @@ -79,22 +79,23 @@ static HTAB *TypeCacheHash = NULL; static TypeCacheEntry *firstDomainTypeEntry = NULL; /* Private flag bits in the TypeCacheEntry.flags field */ -#define TCFLAGS_CHECKED_BTREE_OPCLASS 0x0001 -#define TCFLAGS_CHECKED_HASH_OPCLASS 0x0002 -#define TCFLAGS_CHECKED_EQ_OPR 0x0004 -#define TCFLAGS_CHECKED_LT_OPR 0x0008 -#define TCFLAGS_CHECKED_GT_OPR 0x0010 -#define TCFLAGS_CHECKED_CMP_PROC 0x0020 -#define TCFLAGS_CHECKED_HASH_PROC 0x0040 -#define TCFLAGS_CHECKED_ELEM_PROPERTIES 0x0080 -#define TCFLAGS_HAVE_ELEM_EQUALITY 0x0100 -#define TCFLAGS_HAVE_ELEM_COMPARE 0x0200 -#define TCFLAGS_HAVE_ELEM_HASHING 0x0400 -#define TCFLAGS_CHECKED_FIELD_PROPERTIES 0x0800 -#define TCFLAGS_HAVE_FIELD_EQUALITY 0x1000 -#define TCFLAGS_HAVE_FIELD_COMPARE 0x2000 -#define TCFLAGS_CHECKED_DOMAIN_CONSTRAINTS 0x4000 -#define TCFLAGS_CHECKED_HASH_EXTENDED_PROC 0x8000 +#define TCFLAGS_CHECKED_BTREE_OPCLASS 0x000001 +#define TCFLAGS_CHECKED_HASH_OPCLASS 0x000002 +#define TCFLAGS_CHECKED_EQ_OPR 0x000004 +#define TCFLAGS_CHECKED_LT_OPR 0x000008 +#define TCFLAGS_CHECKED_GT_OPR 0x000010 +#define TCFLAGS_CHECKED_CMP_PROC 0x000020 +#define TCFLAGS_CHECKED_HASH_PROC 0x000040 +#define TCFLAGS_CHECKED_HASH_EXTENDED_PROC 0x000080 +#define TCFLAGS_CHECKED_ELEM_PROPERTIES 0x000100 +#define TCFLAGS_HAVE_ELEM_EQUALITY 0x000200 +#define TCFLAGS_HAVE_ELEM_COMPARE 0x000400 +#define TCFLAGS_HAVE_ELEM_HASHING 0x000800 +#define TCFLAGS_HAVE_ELEM_EXTENDED_HASHING 0x001000 +#define TCFLAGS_CHECKED_FIELD_PROPERTIES 0x002000 +#define TCFLAGS_HAVE_FIELD_EQUALITY 0x004000 +#define TCFLAGS_HAVE_FIELD_COMPARE 0x008000 +#define TCFLAGS_CHECKED_DOMAIN_CONSTRAINTS 0x010000 /* * Data stored about a domain type's constraints. Note that we do not create @@ -273,6 +274,7 @@ static List *prep_domain_constraints(List *constraints, MemoryContext execctx); static bool array_element_has_equality(TypeCacheEntry *typentry); static bool array_element_has_compare(TypeCacheEntry *typentry); static bool array_element_has_hashing(TypeCacheEntry *typentry); +static bool array_element_has_extended_hashing(TypeCacheEntry *typentry); static void cache_array_element_properties(TypeCacheEntry *typentry); static bool record_fields_have_equality(TypeCacheEntry *typentry); static bool record_fields_have_compare(TypeCacheEntry *typentry); @@ -451,8 +453,8 @@ lookup_type_cache(Oid type_id, int flags) * eq_opr; if we already found one from the btree opclass, that * decision is still good. */ - typentry->flags &= ~(TCFLAGS_CHECKED_HASH_PROC); - typentry->flags &= ~(TCFLAGS_CHECKED_HASH_EXTENDED_PROC); + typentry->flags &= ~(TCFLAGS_CHECKED_HASH_PROC | + TCFLAGS_CHECKED_HASH_EXTENDED_PROC); typentry->flags |= TCFLAGS_CHECKED_HASH_OPCLASS; } @@ -500,8 +502,8 @@ lookup_type_cache(Oid type_id, int flags) * equality operator. This is so we can ensure that the hash * functions match the operator. */ - typentry->flags &= ~(TCFLAGS_CHECKED_HASH_PROC); - typentry->flags &= ~(TCFLAGS_CHECKED_HASH_EXTENDED_PROC); + typentry->flags &= ~(TCFLAGS_CHECKED_HASH_PROC | + TCFLAGS_CHECKED_HASH_EXTENDED_PROC); typentry->flags |= TCFLAGS_CHECKED_EQ_OPR; } if ((flags & TYPECACHE_LT_OPR) && @@ -637,10 +639,10 @@ lookup_type_cache(Oid type_id, int flags) * we'll need more logic here to check that case too. */ if (hash_extended_proc == F_HASH_ARRAY_EXTENDED && - !array_element_has_hashing(typentry)) + !array_element_has_extended_hashing(typentry)) hash_extended_proc = InvalidOid; - /* Force update of hash_proc_finfo only if we're changing state */ + /* Force update of proc finfo only if we're changing state */ if (typentry->hash_extended_proc != hash_extended_proc) typentry->hash_extended_proc_finfo.fn_oid = InvalidOid; @@ -1269,6 +1271,14 @@ array_element_has_hashing(TypeCacheEntry *typentry) return (typentry->flags & TCFLAGS_HAVE_ELEM_HASHING) != 0; } +static bool +array_element_has_extended_hashing(TypeCacheEntry *typentry) +{ + if (!(typentry->flags & TCFLAGS_CHECKED_ELEM_PROPERTIES)) + cache_array_element_properties(typentry); + return (typentry->flags & TCFLAGS_HAVE_ELEM_EXTENDED_HASHING) != 0; +} + static void cache_array_element_properties(TypeCacheEntry *typentry) { @@ -1281,13 +1291,16 @@ cache_array_element_properties(TypeCacheEntry *typentry) elementry = lookup_type_cache(elem_type, TYPECACHE_EQ_OPR | TYPECACHE_CMP_PROC | - TYPECACHE_HASH_PROC); + TYPECACHE_HASH_PROC | + TYPECACHE_HASH_EXTENDED_PROC); if (OidIsValid(elementry->eq_opr)) typentry->flags |= TCFLAGS_HAVE_ELEM_EQUALITY; if (OidIsValid(elementry->cmp_proc)) typentry->flags |= TCFLAGS_HAVE_ELEM_COMPARE; if (OidIsValid(elementry->hash_proc)) typentry->flags |= TCFLAGS_HAVE_ELEM_HASHING; + if (OidIsValid(elementry->hash_extended_proc)) + typentry->flags |= TCFLAGS_HAVE_ELEM_EXTENDED_HASHING; } typentry->flags |= TCFLAGS_CHECKED_ELEM_PROPERTIES; }