diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index c99c07c454937e8a3e1605090ad4f393f1046c6f..b9f871182fa54aa03a9f63dcbca7a5790a1e34fc 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -61,6 +61,7 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) Oid *aggArgTypes; int numArgs; Oid transTypeId; + char transTypeType; ListCell *pl; /* Convert list of names to a name and namespace */ @@ -181,7 +182,8 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) * aggregate. */ transTypeId = typenameTypeId(NULL, transType); - if (get_typtype(transTypeId) == TYPTYPE_PSEUDO && + transTypeType = get_typtype(transTypeId); + if (transTypeType == TYPTYPE_PSEUDO && !IsPolymorphicType(transTypeId)) { if (transTypeId == INTERNALOID && superuser()) @@ -193,6 +195,24 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) format_type_be(transTypeId)))); } + /* + * If we have an initval, and it's not for a pseudotype (particularly a + * polymorphic type), make sure it's acceptable to the type's input + * function. We will store the initval as text, because the input + * function isn't necessarily immutable (consider "now" for timestamp), + * and we want to use the runtime not creation-time interpretation of the + * value. However, if it's an incorrect value it seems much more + * user-friendly to complain at CREATE AGGREGATE time. + */ + if (initval && transTypeType != TYPTYPE_PSEUDO) + { + Oid typinput, + typioparam; + + getTypeInputInfo(transTypeId, &typinput, &typioparam); + (void) OidInputFunctionCall(typinput, initval, typioparam, -1); + } + /* * Most of the argument-checking is done inside of AggregateCreate */