Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5b9453b

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 parentc23b6fa commit5b9453b

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
Oidarg1_typeid=get_fn_expr_argtype(fcinfo->flinfo,1);
478+
ArrayBuildState*state;
479+
Datumelem;
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)

[8]ページ先頭

©2009-2025 Movatter.jp