------------------------------------------------------------------------ general helper functions ------------------------------------------------------------------------ * @brief Aggregates an array to a composite struct. * * @param v Array. * @param init_val An initial value for element_function. * @param element_function Transition function. * @param finalize_function Final function. * @r
| 1622 | * @returns Whatever finalize_function returns. |
| 1623 | */ |
| 1624 | static Datum General_Array_to_Struct(ArrayType *v, void *init_val, |
| 1625 | void*(*element_function)(Datum,Oid,int,void*), |
| 1626 | Datum(*finalize_function)(void*,int,Oid)) { |
| 1627 | |
| 1628 | // dimensions |
| 1629 | int ndims = ARR_NDIM(v); |
| 1630 | if (ndims == 0) { |
| 1631 | elog(WARNING, "input are empty arrays."); |
| 1632 | return Float8GetDatum(0); |
| 1633 | } |
| 1634 | int *dims = ARR_DIMS(v); |
| 1635 | int nitems = ArrayGetNItems(ndims, dims); |
| 1636 | |
| 1637 | // type |
| 1638 | Oid element_type = ARR_ELEMTYPE(v); |
| 1639 | TypeCacheEntry *typentry = lookup_type_cache(element_type,TYPECACHE_CMP_PROC_FINFO); |
| 1640 | int type_size = typentry->typlen; |
| 1641 | bool typbyval = typentry->typbyval; |
| 1642 | char typalign = typentry->typalign; |
| 1643 | |
| 1644 | // iterate |
| 1645 | void* result = init_val; |
| 1646 | char *dat = ARR_DATA_PTR(v); |
| 1647 | int i = 0; |
| 1648 | int null_count = 0; |
| 1649 | int *lbs = ARR_LBOUND(v); |
| 1650 | if(ARR_HASNULL(v)){ |
| 1651 | bits8 *bitmap = ARR_NULLBITMAP(v); |
| 1652 | int bitmask = 1; |
| 1653 | for (i = 0; i < nitems; i++) { |
| 1654 | /* Get elements, checking for NULL */ |
| 1655 | if (!(bitmap && (*bitmap & bitmask) == 0)) { |
| 1656 | Datum elt = fetch_att(dat, typbyval, type_size); |
| 1657 | dat = att_addlength_pointer(dat, type_size, dat); |
| 1658 | dat = (char *) att_align_nominal(dat, typalign); |
| 1659 | |
| 1660 | // treating NaN as NULL |
| 1661 | if (!isnan(datum_float8_cast(elt,element_type))) { |
| 1662 | result = element_function(elt, |
| 1663 | element_type, |
| 1664 | lbs[0] + i, |
| 1665 | result); |
| 1666 | } else { |
| 1667 | null_count++; |
| 1668 | } |
| 1669 | }else{ |
| 1670 | null_count++; |
| 1671 | } |
| 1672 | |
| 1673 | /* advance bitmap pointers if any */ |
| 1674 | if (bitmap) { |
| 1675 | bitmask <<= 1; |
| 1676 | if (bitmask == 0x100) { |
| 1677 | bitmap++; |
| 1678 | bitmask = 1; |
| 1679 | } |
| 1680 | } |
| 1681 | } |
no test coverage detected