Skip to content

Commit a8f1efc

Browse files
committed
Fix misimplementation of typcache logic for extended hashing.
The previous coding would report that an array type supports extended hashing if its element type supports regular hashing. This bug is only latent at the moment, since AFAICS there is not yet any code that depends on checking presence of extended-hashing support to make any decisions. (And in any case it wouldn't matter unless the element type has only regular hashing, which isn't true of any core data type.) But that doesn't make it less broken. Extend the cache_array_element_properties infrastructure to check this properly.
1 parent 2959213 commit a8f1efc

File tree

1 file changed

+36
-23
lines changed

1 file changed

+36
-23
lines changed

src/backend/utils/cache/typcache.c

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -79,22 +79,23 @@ static HTAB *TypeCacheHash = NULL;
7979
static TypeCacheEntry *firstDomainTypeEntry = NULL;
8080

8181
/* Private flag bits in the TypeCacheEntry.flags field */
82-
#define TCFLAGS_CHECKED_BTREE_OPCLASS 0x0001
83-
#define TCFLAGS_CHECKED_HASH_OPCLASS 0x0002
84-
#define TCFLAGS_CHECKED_EQ_OPR 0x0004
85-
#define TCFLAGS_CHECKED_LT_OPR 0x0008
86-
#define TCFLAGS_CHECKED_GT_OPR 0x0010
87-
#define TCFLAGS_CHECKED_CMP_PROC 0x0020
88-
#define TCFLAGS_CHECKED_HASH_PROC 0x0040
89-
#define TCFLAGS_CHECKED_ELEM_PROPERTIES 0x0080
90-
#define TCFLAGS_HAVE_ELEM_EQUALITY 0x0100
91-
#define TCFLAGS_HAVE_ELEM_COMPARE 0x0200
92-
#define TCFLAGS_HAVE_ELEM_HASHING 0x0400
93-
#define TCFLAGS_CHECKED_FIELD_PROPERTIES 0x0800
94-
#define TCFLAGS_HAVE_FIELD_EQUALITY 0x1000
95-
#define TCFLAGS_HAVE_FIELD_COMPARE 0x2000
96-
#define TCFLAGS_CHECKED_DOMAIN_CONSTRAINTS 0x4000
97-
#define TCFLAGS_CHECKED_HASH_EXTENDED_PROC 0x8000
82+
#define TCFLAGS_CHECKED_BTREE_OPCLASS 0x000001
83+
#define TCFLAGS_CHECKED_HASH_OPCLASS 0x000002
84+
#define TCFLAGS_CHECKED_EQ_OPR 0x000004
85+
#define TCFLAGS_CHECKED_LT_OPR 0x000008
86+
#define TCFLAGS_CHECKED_GT_OPR 0x000010
87+
#define TCFLAGS_CHECKED_CMP_PROC 0x000020
88+
#define TCFLAGS_CHECKED_HASH_PROC 0x000040
89+
#define TCFLAGS_CHECKED_HASH_EXTENDED_PROC 0x000080
90+
#define TCFLAGS_CHECKED_ELEM_PROPERTIES 0x000100
91+
#define TCFLAGS_HAVE_ELEM_EQUALITY 0x000200
92+
#define TCFLAGS_HAVE_ELEM_COMPARE 0x000400
93+
#define TCFLAGS_HAVE_ELEM_HASHING 0x000800
94+
#define TCFLAGS_HAVE_ELEM_EXTENDED_HASHING 0x001000
95+
#define TCFLAGS_CHECKED_FIELD_PROPERTIES 0x002000
96+
#define TCFLAGS_HAVE_FIELD_EQUALITY 0x004000
97+
#define TCFLAGS_HAVE_FIELD_COMPARE 0x008000
98+
#define TCFLAGS_CHECKED_DOMAIN_CONSTRAINTS 0x010000
9899

99100
/*
100101
* 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);
273274
static bool array_element_has_equality(TypeCacheEntry *typentry);
274275
static bool array_element_has_compare(TypeCacheEntry *typentry);
275276
static bool array_element_has_hashing(TypeCacheEntry *typentry);
277+
static bool array_element_has_extended_hashing(TypeCacheEntry *typentry);
276278
static void cache_array_element_properties(TypeCacheEntry *typentry);
277279
static bool record_fields_have_equality(TypeCacheEntry *typentry);
278280
static bool record_fields_have_compare(TypeCacheEntry *typentry);
@@ -451,8 +453,8 @@ lookup_type_cache(Oid type_id, int flags)
451453
* eq_opr; if we already found one from the btree opclass, that
452454
* decision is still good.
453455
*/
454-
typentry->flags &= ~(TCFLAGS_CHECKED_HASH_PROC);
455-
typentry->flags &= ~(TCFLAGS_CHECKED_HASH_EXTENDED_PROC);
456+
typentry->flags &= ~(TCFLAGS_CHECKED_HASH_PROC |
457+
TCFLAGS_CHECKED_HASH_EXTENDED_PROC);
456458
typentry->flags |= TCFLAGS_CHECKED_HASH_OPCLASS;
457459
}
458460

@@ -500,8 +502,8 @@ lookup_type_cache(Oid type_id, int flags)
500502
* equality operator. This is so we can ensure that the hash
501503
* functions match the operator.
502504
*/
503-
typentry->flags &= ~(TCFLAGS_CHECKED_HASH_PROC);
504-
typentry->flags &= ~(TCFLAGS_CHECKED_HASH_EXTENDED_PROC);
505+
typentry->flags &= ~(TCFLAGS_CHECKED_HASH_PROC |
506+
TCFLAGS_CHECKED_HASH_EXTENDED_PROC);
505507
typentry->flags |= TCFLAGS_CHECKED_EQ_OPR;
506508
}
507509
if ((flags & TYPECACHE_LT_OPR) &&
@@ -637,10 +639,10 @@ lookup_type_cache(Oid type_id, int flags)
637639
* we'll need more logic here to check that case too.
638640
*/
639641
if (hash_extended_proc == F_HASH_ARRAY_EXTENDED &&
640-
!array_element_has_hashing(typentry))
642+
!array_element_has_extended_hashing(typentry))
641643
hash_extended_proc = InvalidOid;
642644

643-
/* Force update of hash_proc_finfo only if we're changing state */
645+
/* Force update of proc finfo only if we're changing state */
644646
if (typentry->hash_extended_proc != hash_extended_proc)
645647
typentry->hash_extended_proc_finfo.fn_oid = InvalidOid;
646648

@@ -1269,6 +1271,14 @@ array_element_has_hashing(TypeCacheEntry *typentry)
12691271
return (typentry->flags & TCFLAGS_HAVE_ELEM_HASHING) != 0;
12701272
}
12711273

1274+
static bool
1275+
array_element_has_extended_hashing(TypeCacheEntry *typentry)
1276+
{
1277+
if (!(typentry->flags & TCFLAGS_CHECKED_ELEM_PROPERTIES))
1278+
cache_array_element_properties(typentry);
1279+
return (typentry->flags & TCFLAGS_HAVE_ELEM_EXTENDED_HASHING) != 0;
1280+
}
1281+
12721282
static void
12731283
cache_array_element_properties(TypeCacheEntry *typentry)
12741284
{
@@ -1281,13 +1291,16 @@ cache_array_element_properties(TypeCacheEntry *typentry)
12811291
elementry = lookup_type_cache(elem_type,
12821292
TYPECACHE_EQ_OPR |
12831293
TYPECACHE_CMP_PROC |
1284-
TYPECACHE_HASH_PROC);
1294+
TYPECACHE_HASH_PROC |
1295+
TYPECACHE_HASH_EXTENDED_PROC);
12851296
if (OidIsValid(elementry->eq_opr))
12861297
typentry->flags |= TCFLAGS_HAVE_ELEM_EQUALITY;
12871298
if (OidIsValid(elementry->cmp_proc))
12881299
typentry->flags |= TCFLAGS_HAVE_ELEM_COMPARE;
12891300
if (OidIsValid(elementry->hash_proc))
12901301
typentry->flags |= TCFLAGS_HAVE_ELEM_HASHING;
1302+
if (OidIsValid(elementry->hash_extended_proc))
1303+
typentry->flags |= TCFLAGS_HAVE_ELEM_EXTENDED_HASHING;
12911304
}
12921305
typentry->flags |= TCFLAGS_CHECKED_ELEM_PROPERTIES;
12931306
}

0 commit comments

Comments
 (0)