* @brief Maps two arrays to a single array. * * @param v1 Array. * @param v2 Array. * @param element_function Map function. * @returns Mapped array. */
| 1791 | * @returns Mapped array. |
| 1792 | */ |
| 1793 | ArrayType* |
| 1794 | General_2Array_to_Array( |
| 1795 | ArrayType *v1, |
| 1796 | ArrayType *v2, |
| 1797 | Datum(*element_function)(Datum,Oid,Datum,Oid,Datum,Oid)) { |
| 1798 | |
| 1799 | // dimensions |
| 1800 | int ndims1 = ARR_NDIM(v1); |
| 1801 | int ndims2 = ARR_NDIM(v2); |
| 1802 | if (ndims1 != ndims2) { |
| 1803 | ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), |
| 1804 | errmsg("cannot perform operation arrays of different number of dimensions"), |
| 1805 | errdetail("Arrays with %d and %d dimensions are not compatible for this opertation.", |
| 1806 | ndims1, ndims2))); |
| 1807 | } |
| 1808 | if (ndims2 == 0) { |
| 1809 | elog(WARNING, "input are empty arrays."); |
| 1810 | return v1; |
| 1811 | } |
| 1812 | int *lbs1 = ARR_LBOUND(v1); |
| 1813 | int *lbs2 = ARR_LBOUND(v2); |
| 1814 | int *dims1 = ARR_DIMS(v1); |
| 1815 | int *dims2 = ARR_DIMS(v2); |
| 1816 | // for output array |
| 1817 | int ndims = ndims1; |
| 1818 | int *dims = (int *) palloc(ndims * sizeof(int)); |
| 1819 | int *lbs = (int *) palloc(ndims * sizeof(int)); |
| 1820 | int i = 0; |
| 1821 | for (i = 0; i < ndims; i++) { |
| 1822 | if (dims1[i] != dims2[i] || lbs1[i] != lbs2[i]) { |
| 1823 | ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), |
| 1824 | errmsg("cannot operate on arrays of different ranges of dimensions"), |
| 1825 | errdetail("Arrays with range [%d,%d] and [%d,%d] for dimension %d are not compatible for operations.", |
| 1826 | lbs1[i], lbs1[i] + dims1[i], lbs2[i], lbs2[i] + dims2[i], i))); |
| 1827 | } |
| 1828 | dims[i] = dims1[i]; |
| 1829 | lbs[i] = lbs1[i]; |
| 1830 | } |
| 1831 | int nitems = ArrayGetNItems(ndims, dims); |
| 1832 | |
| 1833 | // nulls |
| 1834 | if (ARR_HASNULL(v1) || ARR_HASNULL(v2)) { |
| 1835 | ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), |
| 1836 | errmsg("arrays cannot contain nulls"), |
| 1837 | errdetail("Arrays with element value NULL are not allowed."))); |
| 1838 | } |
| 1839 | |
| 1840 | // type |
| 1841 | // the function signature guarantees v1 and v2 are of same type |
| 1842 | Oid element_type = ARR_ELEMTYPE(v1); |
| 1843 | TypeCacheEntry *typentry = lookup_type_cache(element_type,TYPECACHE_CMP_PROC_FINFO); |
| 1844 | int type_size = typentry->typlen; |
| 1845 | bool typbyval = typentry->typbyval; |
| 1846 | char typalign = typentry->typalign; |
| 1847 | |
| 1848 | // allocate |
| 1849 | Datum *result = NULL; |
| 1850 | switch (element_type) { |
no outgoing calls
no test coverage detected