* array_map() * * Map an array through an arbitrary expression. Return a new array with * the same dimensions and each source element transformed by the given, * already-compiled expression. Each source element is placed in the * innermost_caseval/innermost_casenull fields of the ExprState. * * Parameters are: * * arrayd: Datum representing array argument. * * exprstate: ExprState repre
| 3207 | * NB: caller should be running in econtext's per-tuple memory context. |
| 3208 | */ |
| 3209 | Datum |
| 3210 | array_map(Datum arrayd, |
| 3211 | ExprState *exprstate, ExprContext *econtext, |
| 3212 | Oid retType, ArrayMapState *amstate) |
| 3213 | { |
| 3214 | AnyArrayType *v = DatumGetAnyArrayP(arrayd); |
| 3215 | ArrayType *result; |
| 3216 | Datum *values; |
| 3217 | bool *nulls; |
| 3218 | int *dim; |
| 3219 | int ndim; |
| 3220 | int nitems; |
| 3221 | int i; |
| 3222 | int32 nbytes = 0; |
| 3223 | int32 dataoffset; |
| 3224 | bool hasnulls; |
| 3225 | Oid inpType; |
| 3226 | int inp_typlen; |
| 3227 | bool inp_typbyval; |
| 3228 | char inp_typalign; |
| 3229 | int typlen; |
| 3230 | bool typbyval; |
| 3231 | char typalign; |
| 3232 | array_iter iter; |
| 3233 | ArrayMetaState *inp_extra; |
| 3234 | ArrayMetaState *ret_extra; |
| 3235 | Datum *transform_source = exprstate->innermost_caseval; |
| 3236 | bool *transform_source_isnull = exprstate->innermost_casenull; |
| 3237 | |
| 3238 | inpType = AARR_ELEMTYPE(v); |
| 3239 | ndim = AARR_NDIM(v); |
| 3240 | dim = AARR_DIMS(v); |
| 3241 | nitems = ArrayGetNItems(ndim, dim); |
| 3242 | |
| 3243 | /* Check for empty array */ |
| 3244 | if (nitems <= 0) |
| 3245 | { |
| 3246 | /* Return empty array */ |
| 3247 | return PointerGetDatum(construct_empty_array(retType)); |
| 3248 | } |
| 3249 | |
| 3250 | /* |
| 3251 | * We arrange to look up info about input and return element types only |
| 3252 | * once per series of calls, assuming the element type doesn't change |
| 3253 | * underneath us. |
| 3254 | */ |
| 3255 | inp_extra = &amstate->inp_extra; |
| 3256 | ret_extra = &amstate->ret_extra; |
| 3257 | |
| 3258 | if (inp_extra->element_type != inpType) |
| 3259 | { |
| 3260 | get_typlenbyvalalign(inpType, |
| 3261 | &inp_extra->typlen, |
| 3262 | &inp_extra->typbyval, |
| 3263 | &inp_extra->typalign); |
| 3264 | inp_extra->element_type = inpType; |
| 3265 | } |
| 3266 | inp_typlen = inp_extra->typlen; |
no test coverage detected