Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f924911

Browse files
committed
Fix type checking for support functions of parallel VARIADIC aggregates.
The impact of VARIADIC on the combine/serialize/deserialize support functions of an aggregate wasn't thought through carefully. There is actually no impact, because variadicity isn't passed through to these functions (and it doesn't seem like it would need to be). However, lookup_agg_function was mistakenly told to check things as though it were passed through. The net result was that it was impossible to declare an aggregate that had both VARIADIC input and parallelism support functions. In passing, fix a runtime check in nodeAgg.c for the combine function's strictness to make its error message agree with the creation-time check. The previous message was actually backwards, and it doesn't seem like there's a good reason to have two versions of this message text anyway. Back-patch to 9.6 where parallel aggregation was introduced. Alexey Bashtanov; message fix by me Discussion: https://postgr.es/m/f86dde87-fef4-71eb-0480-62754aaca01b@imap.cc
1 parent 22e524d commit f924911

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

src/backend/catalog/pg_aggregate.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -409,16 +409,17 @@ AggregateCreate(const char *aggName,
409409
Oid combineType;
410410

411411
/*
412-
* Combine function must have 2 argument, each of which is the trans
413-
* type
412+
* Combine function must have 2 arguments, each of which is the trans
413+
* type. VARIADIC doesn't affect it.
414414
*/
415415
fnArgs[0] = aggTransType;
416416
fnArgs[1] = aggTransType;
417417

418-
combinefn = lookup_agg_function(aggcombinefnName, 2, fnArgs,
419-
variadicArgType, &combineType);
418+
combinefn = lookup_agg_function(aggcombinefnName, 2,
419+
fnArgs, InvalidOid,
420+
&combineType);
420421

421-
/* Ensure the return type matches the aggregates trans type */
422+
/* Ensure the return type matches the aggregate's trans type */
422423
if (combineType != aggTransType)
423424
ereport(ERROR,
424425
(errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -428,25 +429,26 @@ AggregateCreate(const char *aggName,
428429

429430
/*
430431
* A combine function to combine INTERNAL states must accept nulls and
431-
* ensure that the returned state is in the correct memory context.
432+
* ensure that the returned state is in the correct memory context. We
433+
* cannot directly check the latter, but we can check the former.
432434
*/
433435
if (aggTransType == INTERNALOID && func_strict(combinefn))
434436
ereport(ERROR,
435437
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
436438
errmsg("combine function with transition type %s must not be declared STRICT",
437439
format_type_be(aggTransType))));
438-
439440
}
440441

441442
/*
442443
* Validate the serialization function, if present.
443444
*/
444445
if (aggserialfnName)
445446
{
447+
/* signature is always serialize(internal) returns bytea */
446448
fnArgs[0] = INTERNALOID;
447449

448450
serialfn = lookup_agg_function(aggserialfnName, 1,
449-
fnArgs, variadicArgType,
451+
fnArgs, InvalidOid,
450452
&rettype);
451453

452454
if (rettype != BYTEAOID)
@@ -462,11 +464,12 @@ AggregateCreate(const char *aggName,
462464
*/
463465
if (aggdeserialfnName)
464466
{
467+
/* signature is always deserialize(bytea, internal) returns internal */
465468
fnArgs[0] = BYTEAOID;
466469
fnArgs[1] = INTERNALOID; /* dummy argument for type safety */
467470

468471
deserialfn = lookup_agg_function(aggdeserialfnName, 2,
469-
fnArgs, variadicArgType,
472+
fnArgs, InvalidOid,
470473
&rettype);
471474

472475
if (rettype != INTERNALOID)
@@ -770,7 +773,11 @@ AggregateCreate(const char *aggName,
770773

771774
/*
772775
* lookup_agg_function
773-
* common code for finding transfn, invtransfn, finalfn, and combinefn
776+
* common code for finding aggregate support functions
777+
*
778+
* fnName: possibly-schema-qualified function name
779+
* nargs, input_types: expected function argument types
780+
* variadicArgType: type of variadic argument if any, else InvalidOid
774781
*
775782
* Returns OID of function, and stores its return type into *rettype
776783
*

src/backend/executor/nodeAgg.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3049,8 +3049,8 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
30493049
if (pertrans->transfn.fn_strict && aggtranstype == INTERNALOID)
30503050
ereport(ERROR,
30513051
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
3052-
errmsg("combine function for aggregate %u must be declared as STRICT",
3053-
aggref->aggfnoid)));
3052+
errmsg("combine function with transition type %s must not be declared STRICT",
3053+
format_type_be(aggtranstype))));
30543054
}
30553055
else
30563056
{

0 commit comments

Comments
 (0)