/* *DefineAggregate * *"oldstyle"signalstheold(pre-8.2)stylewheretheaggregateinputtype *isspecifiedbyaBASETYPEelementintheparameters.Otherwise, *"args"isapair,whosefirstelementisalistofFunctionParameterstructs *definingtheagg'sarguments(bothdirectandaggregated),andwhosesecond *elementisanIntegernodewiththenumberofdirectargs,or-1ifthis *isn'tanordered-setaggregate. *"parameters"isalistofDefElemrepresentingtheagg'sdefinitionclauses.
*/
ObjectAddress
DefineAggregate(ParseState *pstate,
List *name,
List *args, bool oldstyle,
List *parameters, bool replace)
{ char *aggName;
Oid aggNamespace;
AclResult aclresult; char aggKind = AGGKIND_NORMAL;
List *transfuncName = NIL;
List *finalfuncName = NIL;
List *combinefuncName = NIL;
List *serialfuncName = NIL;
List *deserialfuncName = NIL;
List *mtransfuncName = NIL;
List *minvtransfuncName = NIL;
List *mfinalfuncName = NIL; bool finalfuncExtraArgs = false; bool mfinalfuncExtraArgs = false; char finalfuncModify = 0; char mfinalfuncModify = 0;
List *sortoperatorName = NIL; TypeName *baseType = NULL; TypeName *transType = NULL; TypeName *mtransType = NULL;
int32 transSpace = 0;
int32 mtransSpace = 0; char *initval = NULL; char *minitval = NULL; char *parallel = NULL; int numArgs; int numDirectArgs = 0;
oidvector *parameterTypes;
ArrayType *allParameterTypes;
ArrayType *parameterModes;
ArrayType *parameterNames;
List *parameterDefaults;
Oid variadicArgType;
Oid transTypeId;
Oid mtransTypeId = InvalidOid; char transTypeType; char mtransTypeType = 0; char proparallel = PROPARALLEL_UNSAFE;
ListCell *pl;
/* Convert list of names to a name and namespace */
aggNamespace = QualifiedNameGetCreationNamespace(name, &aggName);
/* Check we have creation rights in target namespace */
aclresult = object_aclcheck(NamespaceRelationId, aggNamespace, GetUserId(), ACL_CREATE); if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(aggNamespace));
/* Deconstruct the output of the aggr_args grammar production */ if (!oldstyle)
{
Assert(list_length(args) == 2);
numDirectArgs = intVal(lsecond(args)); if (numDirectArgs >= 0)
aggKind = AGGKIND_ORDERED_SET; else
numDirectArgs = 0;
args = linitial_node(List, args);
}
/* *makesurewehaveourrequireddefinitions
*/ if (transType == NULL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregate stype must be specified"))); if (transfuncName == NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregate sfunc must be specified")));
/* *ifmtransTypeisgiven,mtransfuncNameandminvtransfuncNamemustbeas *well;ifnot,thennoneofthemoving-aggregateoptionsshouldhave *beengiven.
*/ if (mtransType != NULL)
{ if (mtransfuncName == NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregate msfunc must be specified when mstype is specified"))); if (minvtransfuncName == NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregate minvfunc must be specified when mstype is specified")));
} else
{ if (mtransfuncName != NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregate msfunc must not be specified without mstype"))); if (minvtransfuncName != NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregate minvfunc must not be specified without mstype"))); if (mfinalfuncName != NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregate mfinalfunc must not be specified without mstype"))); if (mtransSpace != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregate msspace must not be specified without mstype"))); if (minitval != NULL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregate minitcond must not be specified without mstype")));
}
if (baseType != NULL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("basetype is redundant with aggregate input type specification")));
numArgs = list_length(args);
interpret_function_parameter_list(pstate,
args,
InvalidOid,
OBJECT_AGGREGATE,
¶meterTypes,
NULL,
&allParameterTypes,
¶meterModes,
¶meterNames,
NULL,
¶meterDefaults,
&variadicArgType,
&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);
}
/* *lookuptheaggregate'stranstype. * *transtypecan'tbeapseudo-type,sinceweneedtobeabletostore *valuesofthetranstype.However,wecanallowpolymorphictranstype *insomecases(AggregateCreatewillcheck).Also,weallow"internal" *forfunctionsthatwanttopasspointerstoprivatedatastructures; *butallowthatonlytosuperusers,sinceyoucouldcrashthesystem(or *worse)byconnectingupincompatibleinternal-usingfunctionsinan *aggregate.
*/
transTypeId = typenameTypeId(NULL, transType);
transTypeType = get_typtype(transTypeId); if (transTypeType == TYPTYPE_PSEUDO &&
!IsPolymorphicType(transTypeId))
{ if (transTypeId == INTERNALOID && superuser()) /* okay */ ; else
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregate transition data type cannot be %s",
format_type_be(transTypeId))));
}
if (serialfuncName && deserialfuncName)
{ /* *Serializationisonlyneeded/allowedfortranstypeINTERNAL.
*/ if (transTypeId != INTERNALOID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("serialization functions may be specified only when the aggregate transition data type is %s",
format_type_be(INTERNALOID))));
} elseif (serialfuncName || deserialfuncName)
{ /* *Cannotspecifyonefunctionwithouttheother.
*/
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("must specify both or neither of serialization and deserialization functions")));
}
/* *Ifamoving-aggregatetranstypeisspecified,lookthatup.Same *restrictionsasfortranstype.
*/ if (mtransType)
{
mtransTypeId = typenameTypeId(NULL, mtransType);
mtransTypeType = get_typtype(mtransTypeId); if (mtransTypeType == TYPTYPE_PSEUDO &&
!IsPolymorphicType(mtransTypeId))
{ if (mtransTypeId == INTERNALOID && superuser()) /* okay */ ; else
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregate transition data type cannot be %s",
format_type_be(mtransTypeId))));
}
}
/* *Ifwehaveaninitval,andit'snotforapseudotype(particularlya *polymorphictype),makesureit'sacceptabletothetype'sinput *function.Wewillstoretheinitvalastext,becausetheinput *functionisn'tnecessarilyimmutable(consider"now"fortimestamp), *andwewanttousetheruntimenotcreation-timeinterpretationofthe *value.However,ifit'sanincorrectvalueitseemsmuchmore *user-friendlytocomplainatCREATEAGGREGATEtime.
*/ if (initval && transTypeType != TYPTYPE_PSEUDO)
{
Oid typinput,
typioparam;
if (parallel)
{ if (strcmp(parallel, "safe") == 0)
proparallel = PROPARALLEL_SAFE; elseif (strcmp(parallel, "restricted") == 0)
proparallel = PROPARALLEL_RESTRICTED; elseif (strcmp(parallel, "unsafe") == 0)
proparallel = PROPARALLEL_UNSAFE; else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE")));
}
/* *Mostoftheargument-checkingisdoneinsideofAggregateCreate
*/ return AggregateCreate(aggName, /* aggregate name */
aggNamespace, /* namespace */
replace,
aggKind,
numArgs,
numDirectArgs,
parameterTypes,
PointerGetDatum(allParameterTypes),
PointerGetDatum(parameterModes),
PointerGetDatum(parameterNames),
parameterDefaults,
variadicArgType,
transfuncName, /* step function name */
finalfuncName, /* final function name */
combinefuncName, /* combine function name */
serialfuncName, /* serial function name */
deserialfuncName, /* deserial function name */
mtransfuncName, /* fwd trans function name */
minvtransfuncName, /* inv trans function name */
mfinalfuncName, /* final function name */
finalfuncExtraArgs,
mfinalfuncExtraArgs,
finalfuncModify,
mfinalfuncModify,
sortoperatorName, /* sort operator name */
transTypeId, /* transition data type */
transSpace, /* transition space */
mtransTypeId, /* transition data type */
mtransSpace, /* transition space */
initval, /* initial condition */
minitval, /* initial condition */
proparallel); /* parallel safe? */
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.