* deconstruct_array --- simple method for extracting data from an array * * array: array object to examine (must not be NULL) * elmtype, elmlen, elmbyval, elmalign: info for the datatype of the items * elemsp: return value, set to point to palloc'd array of Datum values * nullsp: return value, set to point to palloc'd array of isnull markers * nelemsp: return value, set to number of extract
| 3588 | * cycle by hard-wiring the type info as well. |
| 3589 | */ |
| 3590 | void |
| 3591 | deconstruct_array(ArrayType *array, |
| 3592 | Oid elmtype, |
| 3593 | int elmlen, bool elmbyval, char elmalign, |
| 3594 | Datum **elemsp, bool **nullsp, int *nelemsp) |
| 3595 | { |
| 3596 | Datum *elems; |
| 3597 | bool *nulls; |
| 3598 | int nelems; |
| 3599 | char *p; |
| 3600 | bits8 *bitmap; |
| 3601 | int bitmask; |
| 3602 | int i; |
| 3603 | |
| 3604 | Assert(ARR_ELEMTYPE(array) == elmtype); |
| 3605 | |
| 3606 | nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array)); |
| 3607 | *elemsp = elems = (Datum *) palloc(nelems * sizeof(Datum)); |
| 3608 | if (nullsp) |
| 3609 | *nullsp = nulls = (bool *) palloc0(nelems * sizeof(bool)); |
| 3610 | else |
| 3611 | nulls = NULL; |
| 3612 | *nelemsp = nelems; |
| 3613 | |
| 3614 | p = ARR_DATA_PTR(array); |
| 3615 | bitmap = ARR_NULLBITMAP(array); |
| 3616 | bitmask = 1; |
| 3617 | |
| 3618 | for (i = 0; i < nelems; i++) |
| 3619 | { |
| 3620 | /* Get source element, checking for NULL */ |
| 3621 | if (bitmap && (*bitmap & bitmask) == 0) |
| 3622 | { |
| 3623 | elems[i] = (Datum) 0; |
| 3624 | if (nulls) |
| 3625 | nulls[i] = true; |
| 3626 | else |
| 3627 | ereport(ERROR, |
| 3628 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), |
| 3629 | errmsg("null array element not allowed in this context"))); |
| 3630 | } |
| 3631 | else |
| 3632 | { |
| 3633 | elems[i] = fetch_att(p, elmbyval, elmlen); |
| 3634 | p = att_addlength_pointer(p, elmlen, p); |
| 3635 | p = (char *) att_align_nominal(p, elmalign); |
| 3636 | } |
| 3637 | |
| 3638 | /* advance bitmap pointer if any */ |
| 3639 | if (bitmap) |
| 3640 | { |
| 3641 | bitmask <<= 1; |
| 3642 | if (bitmask == 0x100 /* (1<<8) */) |
| 3643 | { |
| 3644 | bitmap++; |
| 3645 | bitmask = 1; |
| 3646 | } |
| 3647 | } |