@@ -279,6 +279,9 @@ static void cache_array_element_properties(TypeCacheEntry *typentry);
279
279
static bool record_fields_have_equality (TypeCacheEntry * typentry );
280
280
static bool record_fields_have_compare (TypeCacheEntry * typentry );
281
281
static 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 );
282
285
static void TypeCacheRelCallback (Datum arg , Oid relid );
283
286
static void TypeCacheOpcCallback (Datum arg , int cacheid , uint32 hashvalue );
284
287
static void TypeCacheConstrCallback (Datum arg , int cacheid , uint32 hashvalue );
@@ -480,9 +483,11 @@ lookup_type_cache(Oid type_id, int flags)
480
483
481
484
/*
482
485
* 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
484
487
* 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.)
486
491
*/
487
492
if (eq_opr == ARRAY_EQ_OP &&
488
493
!array_element_has_equality (typentry ))
@@ -517,7 +522,10 @@ lookup_type_cache(Oid type_id, int flags)
517
522
typentry -> btree_opintype ,
518
523
BTLessStrategyNumber );
519
524
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
+ */
521
529
if (lt_opr == ARRAY_LT_OP &&
522
530
!array_element_has_compare (typentry ))
523
531
lt_opr = InvalidOid ;
@@ -539,7 +547,10 @@ lookup_type_cache(Oid type_id, int flags)
539
547
typentry -> btree_opintype ,
540
548
BTGreaterStrategyNumber );
541
549
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
+ */
543
554
if (gt_opr == ARRAY_GT_OP &&
544
555
!array_element_has_compare (typentry ))
545
556
gt_opr = InvalidOid ;
@@ -561,7 +572,10 @@ lookup_type_cache(Oid type_id, int flags)
561
572
typentry -> btree_opintype ,
562
573
BTORDER_PROC );
563
574
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
+ */
565
579
if (cmp_proc == F_BTARRAYCMP &&
566
580
!array_element_has_compare (typentry ))
567
581
cmp_proc = InvalidOid ;
@@ -605,6 +619,13 @@ lookup_type_cache(Oid type_id, int flags)
605
619
!array_element_has_hashing (typentry ))
606
620
hash_proc = InvalidOid ;
607
621
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
+
608
629
/* Force update of hash_proc_finfo only if we're changing state */
609
630
if (typentry -> hash_proc != hash_proc )
610
631
typentry -> hash_proc_finfo .fn_oid = InvalidOid ;
@@ -642,6 +663,13 @@ lookup_type_cache(Oid type_id, int flags)
642
663
!array_element_has_extended_hashing (typentry ))
643
664
hash_extended_proc = InvalidOid ;
644
665
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
+
645
673
/* Force update of proc finfo only if we're changing state */
646
674
if (typentry -> hash_extended_proc != hash_extended_proc )
647
675
typentry -> hash_extended_proc_finfo .fn_oid = InvalidOid ;
@@ -1305,6 +1333,10 @@ cache_array_element_properties(TypeCacheEntry *typentry)
1305
1333
typentry -> flags |= TCFLAGS_CHECKED_ELEM_PROPERTIES ;
1306
1334
}
1307
1335
1336
+ /*
1337
+ * Likewise, some helper functions for composite types.
1338
+ */
1339
+
1308
1340
static bool
1309
1341
record_fields_have_equality (TypeCacheEntry * typentry )
1310
1342
{
@@ -1376,6 +1408,54 @@ cache_record_field_properties(TypeCacheEntry *typentry)
1376
1408
typentry -> flags |= TCFLAGS_CHECKED_FIELD_PROPERTIES ;
1377
1409
}
1378
1410
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
+
1379
1459
/*
1380
1460
* Make sure that RecordCacheArray is large enough to store 'typmod'.
1381
1461
*/
0 commit comments