* UNNEST */
| 6133 | * UNNEST |
| 6134 | */ |
| 6135 | Datum |
| 6136 | array_unnest(PG_FUNCTION_ARGS) |
| 6137 | { |
| 6138 | typedef struct |
| 6139 | { |
| 6140 | array_iter iter; |
| 6141 | int nextelem; |
| 6142 | int numelems; |
| 6143 | int16 elmlen; |
| 6144 | bool elmbyval; |
| 6145 | char elmalign; |
| 6146 | } array_unnest_fctx; |
| 6147 | |
| 6148 | FuncCallContext *funcctx; |
| 6149 | array_unnest_fctx *fctx; |
| 6150 | MemoryContext oldcontext; |
| 6151 | |
| 6152 | /* stuff done only on the first call of the function */ |
| 6153 | if (SRF_IS_FIRSTCALL()) |
| 6154 | { |
| 6155 | AnyArrayType *arr; |
| 6156 | |
| 6157 | /* create a function context for cross-call persistence */ |
| 6158 | funcctx = SRF_FIRSTCALL_INIT(); |
| 6159 | |
| 6160 | /* |
| 6161 | * switch to memory context appropriate for multiple function calls |
| 6162 | */ |
| 6163 | oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); |
| 6164 | |
| 6165 | /* |
| 6166 | * Get the array value and detoast if needed. We can't do this |
| 6167 | * earlier because if we have to detoast, we want the detoasted copy |
| 6168 | * to be in multi_call_memory_ctx, so it will go away when we're done |
| 6169 | * and not before. (If no detoast happens, we assume the originally |
| 6170 | * passed array will stick around till then.) |
| 6171 | */ |
| 6172 | arr = PG_GETARG_ANY_ARRAY_P(0); |
| 6173 | |
| 6174 | /* allocate memory for user context */ |
| 6175 | fctx = (array_unnest_fctx *) palloc(sizeof(array_unnest_fctx)); |
| 6176 | |
| 6177 | /* initialize state */ |
| 6178 | array_iter_setup(&fctx->iter, arr); |
| 6179 | fctx->nextelem = 0; |
| 6180 | fctx->numelems = ArrayGetNItems(AARR_NDIM(arr), AARR_DIMS(arr)); |
| 6181 | |
| 6182 | if (VARATT_IS_EXPANDED_HEADER(arr)) |
| 6183 | { |
| 6184 | /* we can just grab the type data from expanded array */ |
| 6185 | fctx->elmlen = arr->xpn.typlen; |
| 6186 | fctx->elmbyval = arr->xpn.typbyval; |
| 6187 | fctx->elmalign = arr->xpn.typalign; |
| 6188 | } |
| 6189 | else |
| 6190 | get_typlenbyvalalign(AARR_ELEMTYPE(arr), |
| 6191 | &fctx->elmlen, |
| 6192 | &fctx->elmbyval, |
nothing calls this directly
no test coverage detected