@@ -279,6 +279,9 @@ static void cache_array_element_properties(TypeCacheEntry *typentry);
279279static bool record_fields_have_equality (TypeCacheEntry * typentry );
280280static bool record_fields_have_compare (TypeCacheEntry * typentry );
281281static void cache_record_field_properties (TypeCacheEntry * typentry );
282+ static bool range_element_has_hashing (TypeCacheEntry * typentry );
283+ static bool range_element_has_extended_hashing (TypeCacheEntry * typentry );
284+ static void cache_range_element_properties (TypeCacheEntry * typentry );
282285static void TypeCacheRelCallback (Datum arg , Oid relid );
283286static void TypeCacheOpcCallback (Datum arg , int cacheid , uint32 hashvalue );
284287static void TypeCacheConstrCallback (Datum arg , int cacheid , uint32 hashvalue );
@@ -480,9 +483,11 @@ lookup_type_cache(Oid type_id, int flags)
480483
481484 /*
482485 * If the proposed equality operator is array_eq or record_eq, check
483- * to see if the element type or column types support equality. If
486+ * to see if the element type or column types support equality. If
484487 * not, array_eq or record_eq would fail at runtime, so we don't want
485- * to report that the type has equality.
488+ * to report that the type has equality. (We can omit similar
489+ * checking for ranges because ranges can't be created in the first
490+ * place unless their subtypes support equality.)
486491 */
487492 if (eq_opr == ARRAY_EQ_OP &&
488493 !array_element_has_equality (typentry ))
@@ -517,7 +522,10 @@ lookup_type_cache(Oid type_id, int flags)
517522 typentry -> btree_opintype ,
518523 BTLessStrategyNumber );
519524
520- /* As above, make sure array_cmp or record_cmp will succeed */
525+ /*
526+ * As above, make sure array_cmp or record_cmp will succeed; but again
527+ * we need no special check for ranges.
528+ */
521529 if (lt_opr == ARRAY_LT_OP &&
522530 !array_element_has_compare (typentry ))
523531 lt_opr = InvalidOid ;
@@ -539,7 +547,10 @@ lookup_type_cache(Oid type_id, int flags)
539547 typentry -> btree_opintype ,
540548 BTGreaterStrategyNumber );
541549
542- /* As above, make sure array_cmp or record_cmp will succeed */
550+ /*
551+ * As above, make sure array_cmp or record_cmp will succeed; but again
552+ * we need no special check for ranges.
553+ */
543554 if (gt_opr == ARRAY_GT_OP &&
544555 !array_element_has_compare (typentry ))
545556 gt_opr = InvalidOid ;
@@ -561,7 +572,10 @@ lookup_type_cache(Oid type_id, int flags)
561572 typentry -> btree_opintype ,
562573 BTORDER_PROC );
563574
564- /* As above, make sure array_cmp or record_cmp will succeed */
575+ /*
576+ * As above, make sure array_cmp or record_cmp will succeed; but again
577+ * we need no special check for ranges.
578+ */
565579 if (cmp_proc == F_BTARRAYCMP &&
566580 !array_element_has_compare (typentry ))
567581 cmp_proc = InvalidOid ;
@@ -605,6 +619,13 @@ lookup_type_cache(Oid type_id, int flags)
605619 !array_element_has_hashing (typentry ))
606620 hash_proc = InvalidOid ;
607621
622+ /*
623+ * Likewise for hash_range.
624+ */
625+ if (hash_proc == F_HASH_RANGE &&
626+ !range_element_has_hashing (typentry ))
627+ hash_proc = InvalidOid ;
628+
608629 /* Force update of hash_proc_finfo only if we're changing state */
609630 if (typentry -> hash_proc != hash_proc )
610631 typentry -> hash_proc_finfo .fn_oid = InvalidOid ;
@@ -642,6 +663,13 @@ lookup_type_cache(Oid type_id, int flags)
642663 !array_element_has_extended_hashing (typentry ))
643664 hash_extended_proc = InvalidOid ;
644665
666+ /*
667+ * Likewise for hash_range_extended.
668+ */
669+ if (hash_extended_proc == F_HASH_RANGE_EXTENDED &&
670+ !range_element_has_extended_hashing (typentry ))
671+ hash_extended_proc = InvalidOid ;
672+
645673 /* Force update of proc finfo only if we're changing state */
646674 if (typentry -> hash_extended_proc != hash_extended_proc )
647675 typentry -> hash_extended_proc_finfo .fn_oid = InvalidOid ;
@@ -1305,6 +1333,10 @@ cache_array_element_properties(TypeCacheEntry *typentry)
13051333 typentry -> flags |= TCFLAGS_CHECKED_ELEM_PROPERTIES ;
13061334}
13071335
1336+ /*
1337+ * Likewise, some helper functions for composite types.
1338+ */
1339+
13081340static bool
13091341record_fields_have_equality (TypeCacheEntry * typentry )
13101342{
@@ -1376,6 +1408,54 @@ cache_record_field_properties(TypeCacheEntry *typentry)
13761408 typentry -> flags |= TCFLAGS_CHECKED_FIELD_PROPERTIES ;
13771409}
13781410
1411+ /*
1412+ * Likewise, some helper functions for range types.
1413+ *
1414+ * We can borrow the flag bits for array element properties to use for range
1415+ * element properties, since those flag bits otherwise have no use in a
1416+ * range type's typcache entry.
1417+ */
1418+
1419+ static bool
1420+ range_element_has_hashing (TypeCacheEntry * typentry )
1421+ {
1422+ if (!(typentry -> flags & TCFLAGS_CHECKED_ELEM_PROPERTIES ))
1423+ cache_range_element_properties (typentry );
1424+ return (typentry -> flags & TCFLAGS_HAVE_ELEM_HASHING ) != 0 ;
1425+ }
1426+
1427+ static bool
1428+ range_element_has_extended_hashing (TypeCacheEntry * typentry )
1429+ {
1430+ if (!(typentry -> flags & TCFLAGS_CHECKED_ELEM_PROPERTIES ))
1431+ cache_range_element_properties (typentry );
1432+ return (typentry -> flags & TCFLAGS_HAVE_ELEM_EXTENDED_HASHING ) != 0 ;
1433+ }
1434+
1435+ static void
1436+ cache_range_element_properties (TypeCacheEntry * typentry )
1437+ {
1438+ /* load up subtype link if we didn't already */
1439+ if (typentry -> rngelemtype == NULL &&
1440+ typentry -> typtype == TYPTYPE_RANGE )
1441+ load_rangetype_info (typentry );
1442+
1443+ if (typentry -> rngelemtype != NULL )
1444+ {
1445+ TypeCacheEntry * elementry ;
1446+
1447+ /* might need to calculate subtype's hash function properties */
1448+ elementry = lookup_type_cache (typentry -> rngelemtype -> type_id ,
1449+ TYPECACHE_HASH_PROC |
1450+ TYPECACHE_HASH_EXTENDED_PROC );
1451+ if (OidIsValid (elementry -> hash_proc ))
1452+ typentry -> flags |= TCFLAGS_HAVE_ELEM_HASHING ;
1453+ if (OidIsValid (elementry -> hash_extended_proc ))
1454+ typentry -> flags |= TCFLAGS_HAVE_ELEM_EXTENDED_HASHING ;
1455+ }
1456+ typentry -> flags |= TCFLAGS_CHECKED_ELEM_PROPERTIES ;
1457+ }
1458+
13791459/*
13801460 * Make sure that RecordCacheArray is large enough to store 'typmod'.
13811461 */
0 commit comments