* accumArrayResult - accumulate one (more) Datum for an array result * * astate is working state (can be NULL on first call) * dvalue/disnull represent the new Datum to append to the array * element_type is the Datum's type (must be a valid array element type) * rcontext is where to keep working state */
| 5237 | * rcontext is where to keep working state |
| 5238 | */ |
| 5239 | ArrayBuildState * |
| 5240 | accumArrayResult(ArrayBuildState *astate, |
| 5241 | Datum dvalue, bool disnull, |
| 5242 | Oid element_type, |
| 5243 | MemoryContext rcontext) |
| 5244 | { |
| 5245 | MemoryContext oldcontext; |
| 5246 | |
| 5247 | if (astate == NULL) |
| 5248 | { |
| 5249 | /* First time through --- initialize */ |
| 5250 | astate = initArrayResult(element_type, rcontext, true); |
| 5251 | } |
| 5252 | else |
| 5253 | { |
| 5254 | Assert(astate->element_type == element_type); |
| 5255 | } |
| 5256 | |
| 5257 | oldcontext = MemoryContextSwitchTo(astate->mcontext); |
| 5258 | |
| 5259 | /* enlarge dvalues[]/dnulls[] if needed */ |
| 5260 | if (astate->nelems >= astate->alen) |
| 5261 | { |
| 5262 | astate->alen *= 2; |
| 5263 | astate->dvalues = (Datum *) |
| 5264 | repalloc(astate->dvalues, astate->alen * sizeof(Datum)); |
| 5265 | astate->dnulls = (bool *) |
| 5266 | repalloc(astate->dnulls, astate->alen * sizeof(bool)); |
| 5267 | } |
| 5268 | |
| 5269 | /* |
| 5270 | * Ensure pass-by-ref stuff is copied into mcontext; and detoast it too if |
| 5271 | * it's varlena. (You might think that detoasting is not needed here |
| 5272 | * because construct_md_array can detoast the array elements later. |
| 5273 | * However, we must not let construct_md_array modify the ArrayBuildState |
| 5274 | * because that would mean array_agg_finalfn damages its input, which is |
| 5275 | * verboten. Also, this way frequently saves one copying step.) |
| 5276 | */ |
| 5277 | if (!disnull && !astate->typbyval) |
| 5278 | { |
| 5279 | if (astate->typlen == -1) |
| 5280 | dvalue = PointerGetDatum(PG_DETOAST_DATUM_COPY(dvalue)); |
| 5281 | else |
| 5282 | dvalue = datumCopy(dvalue, astate->typbyval, astate->typlen); |
| 5283 | } |
| 5284 | |
| 5285 | astate->dvalues[astate->nelems] = dvalue; |
| 5286 | astate->dnulls[astate->nelems] = disnull; |
| 5287 | astate->nelems++; |
| 5288 | |
| 5289 | MemoryContextSwitchTo(oldcontext); |
| 5290 | |
| 5291 | return astate; |
| 5292 | } |
| 5293 | |
| 5294 | /* |
| 5295 | * makeArrayResult - produce 1-D final result of accumArrayResult |