| 4046 | */ |
| 4047 | |
| 4048 | Datum |
| 4049 | hash_array(PG_FUNCTION_ARGS) |
| 4050 | { |
| 4051 | LOCAL_FCINFO(locfcinfo, 1); |
| 4052 | AnyArrayType *array = PG_GETARG_ANY_ARRAY_P(0); |
| 4053 | int ndims = AARR_NDIM(array); |
| 4054 | int *dims = AARR_DIMS(array); |
| 4055 | Oid element_type = AARR_ELEMTYPE(array); |
| 4056 | uint32 result = 1; |
| 4057 | int nitems; |
| 4058 | TypeCacheEntry *typentry; |
| 4059 | int typlen; |
| 4060 | bool typbyval; |
| 4061 | char typalign; |
| 4062 | int i; |
| 4063 | array_iter iter; |
| 4064 | |
| 4065 | /* |
| 4066 | * We arrange to look up the hash function only once per series of calls, |
| 4067 | * assuming the element type doesn't change underneath us. The typcache |
| 4068 | * is used so that we have no memory leakage when being used as an index |
| 4069 | * support function. |
| 4070 | */ |
| 4071 | typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra; |
| 4072 | if (typentry == NULL || |
| 4073 | typentry->type_id != element_type) |
| 4074 | { |
| 4075 | typentry = lookup_type_cache(element_type, |
| 4076 | TYPECACHE_HASH_PROC_FINFO); |
| 4077 | if (!OidIsValid(typentry->hash_proc_finfo.fn_oid) && element_type != RECORDOID) |
| 4078 | ereport(ERROR, |
| 4079 | (errcode(ERRCODE_UNDEFINED_FUNCTION), |
| 4080 | errmsg("could not identify a hash function for type %s", |
| 4081 | format_type_be(element_type)))); |
| 4082 | |
| 4083 | /* |
| 4084 | * The type cache doesn't believe that record is hashable (see |
| 4085 | * cache_record_field_properties()), but since we're here, we're |
| 4086 | * committed to hashing, so we can assume it does. Worst case, if any |
| 4087 | * components of the record don't support hashing, we will fail at |
| 4088 | * execution. |
| 4089 | */ |
| 4090 | if (element_type == RECORDOID) |
| 4091 | { |
| 4092 | MemoryContext oldcontext; |
| 4093 | TypeCacheEntry *record_typentry; |
| 4094 | |
| 4095 | oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt); |
| 4096 | |
| 4097 | /* |
| 4098 | * Make fake type cache entry structure. Note that we can't just |
| 4099 | * modify typentry, since that points directly into the type cache. |
| 4100 | */ |
| 4101 | record_typentry = palloc0(sizeof(*record_typentry)); |
| 4102 | record_typentry->type_id = element_type; |
| 4103 | |
| 4104 | /* fill in what we need below */ |
| 4105 | record_typentry->typlen = typentry->typlen; |
nothing calls this directly
no test coverage detected