Skip to content

Commit 5b9453b

Browse files
committed
Minor code clarity improvements in array_agg functions, and add a comment
about how this is playing fast and loose with the type system.
1 parent c23b6fa commit 5b9453b

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

src/backend/utils/adt/array_userfuncs.c

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Copyright (c) 2003-2008, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.24 2008/11/13 15:59:50 petere Exp $
9+
* $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.25 2008/11/14 00:12:08 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -467,33 +467,57 @@ create_singleton_array(FunctionCallInfo fcinfo,
467467
typlen, typbyval, typalign);
468468
}
469469

470+
471+
/*
472+
* ARRAY_AGG aggregate function
473+
*/
470474
Datum
471475
array_agg_transfn(PG_FUNCTION_ARGS)
472476
{
473477
Oid arg1_typeid = get_fn_expr_argtype(fcinfo->flinfo, 1);
478+
ArrayBuildState *state;
479+
Datum elem;
474480

475481
if (arg1_typeid == InvalidOid)
476-
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
477-
errmsg("could not determine input data type")));
482+
ereport(ERROR,
483+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
484+
errmsg("could not determine input data type")));
478485

479486
/* cannot be called directly because of internal-type argument */
480487
Assert(fcinfo->context && IsA(fcinfo->context, AggState));
481488

482-
PG_RETURN_POINTER(accumArrayResult(PG_ARGISNULL(0) ? NULL : (ArrayBuildState *) PG_GETARG_POINTER(0),
483-
PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1),
484-
PG_ARGISNULL(1),
485-
arg1_typeid,
486-
((AggState *) fcinfo->context)->aggcontext));
489+
state = PG_ARGISNULL(0) ? NULL : (ArrayBuildState *) PG_GETARG_POINTER(0);
490+
elem = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1);
491+
state = accumArrayResult(state,
492+
elem,
493+
PG_ARGISNULL(1),
494+
arg1_typeid,
495+
((AggState *) fcinfo->context)->aggcontext);
496+
497+
/*
498+
* We cheat quite a lot here by assuming that a pointer datum will be
499+
* preserved intact when nodeAgg.c thinks it is a value of type "internal".
500+
* This will in fact work because internal is stated to be pass-by-value
501+
* in pg_type.h, and nodeAgg will never do anything with a pass-by-value
502+
* transvalue except pass it around in Datum form. But it's mighty
503+
* shaky seeing that internal is also stated to be 4 bytes wide in
504+
* pg_type.h. If nodeAgg did put the value into a tuple this would
505+
* crash and burn on 64-bit machines.
506+
*/
507+
PG_RETURN_POINTER(state);
487508
}
488509

489510
Datum
490511
array_agg_finalfn(PG_FUNCTION_ARGS)
491512
{
513+
ArrayBuildState *state;
514+
492515
/* cannot be called directly because of internal-type argument */
493516
Assert(fcinfo->context && IsA(fcinfo->context, AggState));
494517

495518
if (PG_ARGISNULL(0))
496519
PG_RETURN_NULL(); /* returns null iff no input values */
497520

498-
PG_RETURN_ARRAYTYPE_P(makeArrayResult((ArrayBuildState *) PG_GETARG_POINTER(0), CurrentMemoryContext));
521+
state = (ArrayBuildState *) PG_GETARG_POINTER(0);
522+
PG_RETURN_ARRAYTYPE_P(makeArrayResult(state, CurrentMemoryContext));
499523
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy