mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-05 19:09:58 +08:00
Make CREATE AGGREGATE complain if the initcond is invalid for the datatype.
The initial transition value is stored as a text string and not fed to the transition type's input function until runtime (so that values such as "now" don't get frozen at creation time). Previously, CREATE AGGREGATE didn't do anything with it but that, which meant that even erroneous values would be accepted and not complained of until the aggregate is used. This seems unhelpful, and it's confused at least one user, as in Rhys Stewart's recent report. It seems worth taking a few more cycles to invoke the input function and verify that the value is acceptable. We can't do this if the transition type is polymorphic, but in normal aggregates we know the actual transition type so we can call the right input function.
This commit is contained in:
parent
707263542e
commit
e1e60694b4
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user