* array_replace/array_remove support * * Find all array entries matching (not distinct from) search/search_isnull, * and delete them if remove is true, else replace them with * replace/replace_isnull. Comparisons are done using the specified * collation. fcinfo is passed only for caching purposes. */
| 6257 | * collation. fcinfo is passed only for caching purposes. |
| 6258 | */ |
| 6259 | static ArrayType * |
| 6260 | array_replace_internal(ArrayType *array, |
| 6261 | Datum search, bool search_isnull, |
| 6262 | Datum replace, bool replace_isnull, |
| 6263 | bool remove, Oid collation, |
| 6264 | FunctionCallInfo fcinfo) |
| 6265 | { |
| 6266 | LOCAL_FCINFO(locfcinfo, 2); |
| 6267 | ArrayType *result; |
| 6268 | Oid element_type; |
| 6269 | Datum *values; |
| 6270 | bool *nulls; |
| 6271 | int *dim; |
| 6272 | int ndim; |
| 6273 | int nitems, |
| 6274 | nresult; |
| 6275 | int i; |
| 6276 | int32 nbytes = 0; |
| 6277 | int32 dataoffset; |
| 6278 | bool hasnulls; |
| 6279 | int typlen; |
| 6280 | bool typbyval; |
| 6281 | char typalign; |
| 6282 | char *arraydataptr; |
| 6283 | bits8 *bitmap; |
| 6284 | int bitmask; |
| 6285 | bool changed = false; |
| 6286 | TypeCacheEntry *typentry; |
| 6287 | |
| 6288 | element_type = ARR_ELEMTYPE(array); |
| 6289 | ndim = ARR_NDIM(array); |
| 6290 | dim = ARR_DIMS(array); |
| 6291 | nitems = ArrayGetNItems(ndim, dim); |
| 6292 | |
| 6293 | /* Return input array unmodified if it is empty */ |
| 6294 | if (nitems <= 0) |
| 6295 | return array; |
| 6296 | |
| 6297 | /* |
| 6298 | * We can't remove elements from multi-dimensional arrays, since the |
| 6299 | * result might not be rectangular. |
| 6300 | */ |
| 6301 | if (remove && ndim > 1) |
| 6302 | ereport(ERROR, |
| 6303 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 6304 | errmsg("removing elements from multidimensional arrays is not supported"))); |
| 6305 | |
| 6306 | /* |
| 6307 | * We arrange to look up the equality function only once per series of |
| 6308 | * calls, assuming the element type doesn't change underneath us. |
| 6309 | */ |
| 6310 | typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra; |
| 6311 | if (typentry == NULL || |
| 6312 | typentry->type_id != element_type) |
| 6313 | { |
| 6314 | typentry = lookup_type_cache(element_type, |
| 6315 | TYPECACHE_EQ_OPR_FINFO); |
| 6316 | if (!OidIsValid(typentry->eq_opr_finfo.fn_oid)) |
no test coverage detected