aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/utils/cache/typcache.c59
1 files changed, 36 insertions, 23 deletions
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;
}