* ARRAY_AGG(anynonarray) aggregate function */
| 475 | * ARRAY_AGG(anynonarray) aggregate function |
| 476 | */ |
| 477 | Datum |
| 478 | array_agg_transfn(PG_FUNCTION_ARGS) |
| 479 | { |
| 480 | Oid arg1_typeid = get_fn_expr_argtype(fcinfo->flinfo, 1); |
| 481 | MemoryContext aggcontext; |
| 482 | ArrayBuildState *state; |
| 483 | Datum elem; |
| 484 | |
| 485 | if (arg1_typeid == InvalidOid) |
| 486 | ereport(ERROR, |
| 487 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 488 | errmsg("could not determine input data type"))); |
| 489 | |
| 490 | /* |
| 491 | * Note: we do not need a run-time check about whether arg1_typeid is a |
| 492 | * valid array element type, because the parser would have verified that |
| 493 | * while resolving the input/result types of this polymorphic aggregate. |
| 494 | */ |
| 495 | |
| 496 | if (!AggCheckCallContext(fcinfo, &aggcontext)) |
| 497 | { |
| 498 | /* cannot be called directly because of internal-type argument */ |
| 499 | elog(ERROR, "array_agg_transfn called in non-aggregate context"); |
| 500 | } |
| 501 | |
| 502 | if (PG_ARGISNULL(0)) |
| 503 | state = initArrayResult(arg1_typeid, aggcontext, false); |
| 504 | else |
| 505 | state = (ArrayBuildState *) PG_GETARG_POINTER(0); |
| 506 | |
| 507 | elem = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1); |
| 508 | |
| 509 | state = accumArrayResult(state, |
| 510 | elem, |
| 511 | PG_ARGISNULL(1), |
| 512 | arg1_typeid, |
| 513 | aggcontext); |
| 514 | |
| 515 | /* |
| 516 | * The transition type for array_agg() is declared to be "internal", which |
| 517 | * is a pass-by-value type the same size as a pointer. So we can safely |
| 518 | * pass the ArrayBuildState pointer through nodeAgg.c's machinations. |
| 519 | */ |
| 520 | PG_RETURN_POINTER(state); |
| 521 | } |
| 522 | |
| 523 | Datum |
| 524 | array_agg_finalfn(PG_FUNCTION_ARGS) |
nothing calls this directly
no test coverage detected