diff options
Diffstat (limited to 'src/backend/commands/aggregatecmds.c')
-rw-r--r-- | src/backend/commands/aggregatecmds.c | 55 |
1 files changed, 39 insertions, 16 deletions
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index 4a03786210a..78af0924654 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -45,10 +45,12 @@ * * "oldstyle" signals the old (pre-8.2) style where the aggregate input type * is specified by a BASETYPE element in the parameters. Otherwise, - * "args" defines the input type(s). + * "args" is a list of FunctionParameter structs defining the agg's arguments. + * "parameters" is a list of DefElem representing the agg's definition clauses. */ Oid -DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) +DefineAggregate(List *name, List *args, bool oldstyle, List *parameters, + const char *queryString) { char *aggName; Oid aggNamespace; @@ -59,8 +61,12 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) TypeName *baseType = NULL; TypeName *transType = NULL; char *initval = NULL; - Oid *aggArgTypes; int numArgs; + oidvector *parameterTypes; + ArrayType *allParameterTypes; + ArrayType *parameterModes; + ArrayType *parameterNames; + List *parameterDefaults; Oid transTypeId; char transTypeType; ListCell *pl; @@ -131,6 +137,8 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) * Historically we allowed the command to look like basetype = 'ANY' * so we must do a case-insensitive comparison for the name ANY. Ugh. */ + Oid aggArgTypes[1]; + if (baseType == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), @@ -139,22 +147,26 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) if (pg_strcasecmp(TypeNameToString(baseType), "ANY") == 0) { numArgs = 0; - aggArgTypes = NULL; + aggArgTypes[0] = InvalidOid; } else { numArgs = 1; - aggArgTypes = (Oid *) palloc(sizeof(Oid)); aggArgTypes[0] = typenameTypeId(NULL, baseType); } + parameterTypes = buildoidvector(aggArgTypes, numArgs); + allParameterTypes = NULL; + parameterModes = NULL; + parameterNames = NULL; + parameterDefaults = NIL; } else { /* - * New style: args is a list of TypeNames (possibly zero of 'em). + * New style: args is a list of FunctionParameters (possibly zero of + * 'em). We share functioncmds.c's code for processing them. */ - ListCell *lc; - int i = 0; + Oid requiredResultType; if (baseType != NULL) ereport(ERROR, @@ -162,13 +174,20 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) errmsg("basetype is redundant with aggregate input type specification"))); numArgs = list_length(args); - aggArgTypes = (Oid *) palloc(sizeof(Oid) * numArgs); - foreach(lc, args) - { - TypeName *curTypeName = (TypeName *) lfirst(lc); - - aggArgTypes[i++] = typenameTypeId(NULL, curTypeName); - } + interpret_function_parameter_list(args, + InvalidOid, + true, /* is an aggregate */ + queryString, + ¶meterTypes, + &allParameterTypes, + ¶meterModes, + ¶meterNames, + ¶meterDefaults, + &requiredResultType); + /* Parameter defaults are not currently allowed by the grammar */ + Assert(parameterDefaults == NIL); + /* There shouldn't have been any OUT parameters, either */ + Assert(requiredResultType == InvalidOid); } /* @@ -219,8 +238,12 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) */ return AggregateCreate(aggName, /* aggregate name */ aggNamespace, /* namespace */ - aggArgTypes, /* input data type(s) */ numArgs, + parameterTypes, + PointerGetDatum(allParameterTypes), + PointerGetDatum(parameterModes), + PointerGetDatum(parameterNames), + parameterDefaults, transfuncName, /* step function name */ finalfuncName, /* final function name */ sortoperatorName, /* sort operator name */ |