diff --git a/doc/src/sgml/ref/create_aggregate.sgml b/doc/src/sgml/ref/create_aggregate.sgml index 70362f6503..5eb0741c9c 100644 --- a/doc/src/sgml/ref/create_aggregate.sgml +++ b/doc/src/sgml/ref/create_aggregate.sgml @@ -1,5 +1,5 @@ @@ -20,8 +20,18 @@ PostgreSQL documentation +CREATE AGGREGATE name ( input_data_type ) ( + SFUNC = sfunc, + STYPE = state_data_type + [ , FINALFUNC = ffunc ] + [ , INITCOND = initial_condition ] + [ , SORTOP = sort_operator ] +) + +or the old syntax + CREATE AGGREGATE name ( - BASETYPE = input_data_type, + BASETYPE = base_type, SFUNC = sfunc, STYPE = state_data_type [ , FINALFUNC = ffunc ] @@ -87,7 +97,7 @@ CREATE AGGREGATE name ( An aggregate function may provide an initial condition, that is, an initial value for the internal state value. - This is specified and stored in the database as a column of type + This is specified and stored in the database as a value of type text, but it must be a valid external representation of a constant of the state value data type. If it is not supplied then the state value starts out null. @@ -146,8 +156,9 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1; Ordinarily, a data type's < operator is the proper sort operator for MIN, and > is the proper sort operator for MAX. Note that the optimization will never - actually take effect unless the specified operator is the less than or - greater than strategy member of a B-tree index operator class. + actually take effect unless the specified operator is the less + than or greater than strategy member of a B-tree + index operator class. @@ -170,13 +181,27 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1; The input data type on which this aggregate function operates. - This can be specified as "ANY" for an aggregate that + This can be specified as * for an aggregate that does not examine its input values (an example is count(*)). + + base_type + + + In the old syntax for CREATE AGGREGATE, the input data type + is specified by a basetype parameter rather than being + written next to the aggregate name. Note that this syntax allows + only one input parameter. To define an aggregate that does not examine + its input values, specify the basetype as + "ANY" (not *). + + + + sfunc diff --git a/doc/src/sgml/xaggr.sgml b/doc/src/sgml/xaggr.sgml index bbb4055b91..db6c077cbf 100644 --- a/doc/src/sgml/xaggr.sgml +++ b/doc/src/sgml/xaggr.sgml @@ -1,4 +1,4 @@ - + User-Defined Aggregates @@ -43,23 +43,24 @@ The aggregate definition would be: -CREATE AGGREGATE complex_sum ( +CREATE AGGREGATE sum (complex) +( sfunc = complex_add, - basetype = complex, stype = complex, initcond = '(0,0)' ); -SELECT complex_sum(a) FROM test_complex; +SELECT sum(a) FROM test_complex; - complex_sum -------------- + sum +----------- (34,53.9) - (In practice, we'd just name the aggregate sum and rely on - PostgreSQL to figure out which kind - of sum to apply to a column of type complex.) + (Notice that we are relying on function overloading: there is more than + one aggregate named sum, but + PostgreSQL can figure out which kind + of sum applies to a column of type complex.) @@ -99,9 +100,9 @@ SELECT complex_sum(a) FROM test_complex; looks like: -CREATE AGGREGATE avg ( +CREATE AGGREGATE avg (float8) +( sfunc = float8_accum, - basetype = float8, stype = float8[], finalfunc = float8_avg, initcond = '{0,0}' @@ -116,14 +117,14 @@ CREATE AGGREGATE avg ( See for an explanation of polymorphic functions. Going a step further, the aggregate function itself may be specified - with a polymorphic base type and state type, allowing a single + with a polymorphic input type and state type, allowing a single aggregate definition to serve for multiple input data types. Here is an example of a polymorphic aggregate: -CREATE AGGREGATE array_accum ( +CREATE AGGREGATE array_accum (anyelement) +( sfunc = array_append, - basetype = anyelement, stype = anyarray, initcond = '{}' ); @@ -167,7 +168,7 @@ SELECT attrelid::regclass, array_accum(atttypid) if (fcinfo->context && IsA(fcinfo->context, AggState)) - One reason for checking this is that when it is true, the left input + One reason for checking this is that when it is true, the first input must be a temporary transition value and can therefore safely be modified in-place rather than allocating a new copy. (This is the only case where it is safe for a function to modify a pass-by-reference input.) diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index 3c0855238e..7b954edd38 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.33 2006/03/14 22:48:18 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.34 2006/04/15 17:45:33 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -41,9 +41,13 @@ /* * DefineAggregate + * + * "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). */ void -DefineAggregate(List *names, List *parameters) +DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) { char *aggName; Oid aggNamespace; @@ -59,7 +63,7 @@ DefineAggregate(List *names, List *parameters) ListCell *pl; /* Convert list of names to a name and namespace */ - aggNamespace = QualifiedNameGetCreationNamespace(names, &aggName); + aggNamespace = QualifiedNameGetCreationNamespace(name, &aggName); /* Check we have creation rights in target namespace */ aclresult = pg_namespace_aclcheck(aggNamespace, GetUserId(), ACL_CREATE); @@ -103,10 +107,6 @@ DefineAggregate(List *names, List *parameters) /* * make sure we have our required definitions */ - if (baseType == NULL) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("aggregate basetype must be specified"))); if (transType == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), @@ -117,20 +117,63 @@ DefineAggregate(List *names, List *parameters) errmsg("aggregate sfunc must be specified"))); /* - * look up the aggregate's base type (input datatype) and transtype. + * look up the aggregate's input datatype. + */ + if (oldstyle) + { + /* + * Old style: use basetype parameter. This supports only one input. + * + * Historically we allowed the command to look like basetype = 'ANY' + * so we must do a case-insensitive comparison for the name ANY. Ugh. + */ + if (baseType == NULL) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("aggregate input type must be specified"))); + + if (pg_strcasecmp(TypeNameToString(baseType), "ANY") == 0) + baseTypeId = ANYOID; + else + baseTypeId = typenameTypeId(NULL, baseType); + } + else + { + /* + * New style: args is a list of TypeNames. For the moment, though, + * we allow at most one. + */ + if (baseType != NULL) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("basetype is redundant with aggregate input type specification"))); + + if (args == NIL) + { + /* special case for agg(*) */ + baseTypeId = ANYOID; + } + else if (list_length(args) != 1) + { + /* temporarily reject > 1 arg */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("aggregates can have only one input"))); + baseTypeId = InvalidOid; /* keep compiler quiet */ + } + else + { + baseTypeId = typenameTypeId(NULL, (TypeName *) linitial(args)); + } + } + + /* + * look up the aggregate's transtype. * - * We have historically allowed the command to look like basetype = 'ANY' - * so we must do a case-insensitive comparison for the name ANY. Ugh. - * - * basetype can be a pseudo-type, but transtype can't, since we need to be + * transtype can't be a pseudo-type, since we need to be * able to store values of the transtype. However, we can allow * polymorphic transtype in some cases (AggregateCreate will check). */ - if (pg_strcasecmp(TypeNameToString(baseType), "ANY") == 0) - baseTypeId = ANYOID; - else - baseTypeId = typenameTypeId(NULL, baseType); - transTypeId = typenameTypeId(NULL, transType); if (get_typtype(transTypeId) == 'p' && transTypeId != ANYARRAYOID && @@ -159,28 +202,16 @@ DefineAggregate(List *names, List *parameters) * Deletes an aggregate. */ void -RemoveAggregate(RemoveAggrStmt *stmt) +RemoveAggregate(RemoveFuncStmt *stmt) { - List *aggName = stmt->aggname; - TypeName *aggType = stmt->aggtype; - Oid basetypeID; + List *aggName = stmt->name; + List *aggArgs = stmt->args; Oid procOid; HeapTuple tup; ObjectAddress object; - /* - * if a basetype is passed in, then attempt to find an aggregate for that - * specific type. - * - * else attempt to find an aggregate with a basetype of ANYOID. This means - * that the aggregate is to apply to all basetypes (eg, COUNT). - */ - if (aggType) - basetypeID = typenameTypeId(NULL, aggType); - else - basetypeID = ANYOID; - - procOid = find_aggregate_func(aggName, basetypeID, false); + /* Look up function and make sure it's an aggregate */ + procOid = LookupAggNameTypeNames(aggName, aggArgs, false); /* * Find the function tuple, do permissions and validity checks @@ -198,8 +229,6 @@ RemoveAggregate(RemoveAggrStmt *stmt) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, NameListToString(aggName)); - /* find_aggregate_func already checked it is an aggregate */ - ReleaseSysCache(tup); /* @@ -214,9 +243,8 @@ RemoveAggregate(RemoveAggrStmt *stmt) void -RenameAggregate(List *name, TypeName *basetype, const char *newname) +RenameAggregate(List *name, List *args, const char *newname) { - Oid basetypeOid; Oid procOid; Oid namespaceOid; HeapTuple tup; @@ -224,20 +252,10 @@ RenameAggregate(List *name, TypeName *basetype, const char *newname) Relation rel; AclResult aclresult; - /* - * if a basetype is passed in, then attempt to find an aggregate for that - * specific type; else attempt to find an aggregate with a basetype of - * ANYOID. This means that the aggregate applies to all basetypes (eg, - * COUNT). - */ - if (basetype) - basetypeOid = typenameTypeId(NULL, basetype); - else - basetypeOid = ANYOID; - rel = heap_open(ProcedureRelationId, RowExclusiveLock); - procOid = find_aggregate_func(name, basetypeOid, false); + /* Look up function and make sure it's an aggregate */ + procOid = LookupAggNameTypeNames(name, args, false); tup = SearchSysCacheCopy(PROCOID, ObjectIdGetDatum(procOid), @@ -254,22 +272,13 @@ RenameAggregate(List *name, TypeName *basetype, const char *newname) PointerGetDatum(&procForm->proargtypes), ObjectIdGetDatum(namespaceOid), 0)) - { - if (basetypeOid == ANYOID) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_FUNCTION), - errmsg("function %s(*) already exists in schema \"%s\"", - newname, - get_namespace_name(namespaceOid)))); - else - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_FUNCTION), - errmsg("function %s already exists in schema \"%s\"", - funcname_signature_string(newname, - procForm->pronargs, - procForm->proargtypes.values), - get_namespace_name(namespaceOid)))); - } + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_FUNCTION), + errmsg("function %s already exists in schema \"%s\"", + funcname_signature_string(newname, + procForm->pronargs, + procForm->proargtypes.values), + get_namespace_name(namespaceOid)))); /* must be owner */ if (!pg_proc_ownercheck(procOid, GetUserId())) @@ -295,29 +304,18 @@ RenameAggregate(List *name, TypeName *basetype, const char *newname) * Change aggregate owner */ void -AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId) +AlterAggregateOwner(List *name, List *args, Oid newOwnerId) { - Oid basetypeOid; Oid procOid; HeapTuple tup; Form_pg_proc procForm; Relation rel; AclResult aclresult; - /* - * if a basetype is passed in, then attempt to find an aggregate for that - * specific type; else attempt to find an aggregate with a basetype of - * ANYOID. This means that the aggregate applies to all basetypes (eg, - * COUNT). - */ - if (basetype) - basetypeOid = typenameTypeId(NULL, basetype); - else - basetypeOid = ANYOID; - rel = heap_open(ProcedureRelationId, RowExclusiveLock); - procOid = find_aggregate_func(name, basetypeOid, false); + /* Look up function and make sure it's an aggregate */ + procOid = LookupAggNameTypeNames(name, args, false); tup = SearchSysCacheCopy(PROCOID, ObjectIdGetDatum(procOid), diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 3c99fd9e03..2b7c9250b3 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.18 2006/03/05 15:58:23 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.19 2006/04/15 17:45:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -47,9 +47,7 @@ ExecRenameStmt(RenameStmt *stmt) switch (stmt->renameType) { case OBJECT_AGGREGATE: - RenameAggregate(stmt->object, - (TypeName *) linitial(stmt->objarg), - stmt->newname); + RenameAggregate(stmt->object, stmt->objarg, stmt->newname); break; case OBJECT_CONVERSION: @@ -152,8 +150,12 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt) switch (stmt->objectType) { case OBJECT_AGGREGATE: + AlterFunctionNamespace(stmt->object, stmt->objarg, true, + stmt->newschema); + break; + case OBJECT_FUNCTION: - AlterFunctionNamespace(stmt->object, stmt->objarg, + AlterFunctionNamespace(stmt->object, stmt->objarg, false, stmt->newschema); break; @@ -186,9 +188,7 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt) switch (stmt->objectType) { case OBJECT_AGGREGATE: - AlterAggregateOwner(stmt->object, - (TypeName *) linitial(stmt->objarg), - newowner); + AlterAggregateOwner(stmt->object, stmt->objarg, newowner); break; case OBJECT_CONVERSION: @@ -204,6 +204,7 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt) break; case OBJECT_OPERATOR: + Assert(list_length(stmt->objarg) == 2); AlterOperatorOwner(stmt->object, (TypeName *) linitial(stmt->objarg), (TypeName *) lsecond(stmt->objarg), diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 07d8278525..ec4762750f 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -7,7 +7,7 @@ * Copyright (c) 1996-2006, PostgreSQL Global Development Group * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.88 2006/03/14 22:48:18 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.89 2006/04/15 17:45:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -868,28 +868,17 @@ CommentType(List *typename, char *comment) * * This routine is used to allow a user to provide comments on an * aggregate function. The aggregate function is determined by both - * its name and its argument type, which, with the comments are - * the three parameters handed to this routine. + * its name and its argument type(s). */ static void CommentAggregate(List *aggregate, List *arguments, char *comment) { - TypeName *aggtype = (TypeName *) linitial(arguments); - Oid baseoid, - oid; + Oid oid; - /* First, attempt to determine the base aggregate oid */ - if (aggtype) - baseoid = typenameTypeId(NULL, aggtype); - else - baseoid = ANYOID; - - /* Now, attempt to find the actual tuple in pg_proc */ - - oid = find_aggregate_func(aggregate, baseoid, false); + /* Look up function and make sure it's an aggregate */ + oid = LookupAggNameTypeNames(aggregate, arguments, false); /* Next, validate the user's attempt to comment */ - if (!pg_proc_ownercheck(oid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, NameListToString(aggregate)); diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 1da1cf66cb..96929a0d6c 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.73 2006/03/14 22:48:18 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.74 2006/04/15 17:45:34 tgl Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -678,7 +678,7 @@ CreateFunction(CreateFunctionStmt *stmt) void RemoveFunction(RemoveFuncStmt *stmt) { - List *functionName = stmt->funcname; + List *functionName = stmt->name; List *argTypes = stmt->args; /* list of TypeName nodes */ Oid funcOid; HeapTuple tup; @@ -1440,10 +1440,13 @@ DropCastById(Oid castOid) } /* - * Execute ALTER FUNCTION SET SCHEMA + * Execute ALTER FUNCTION/AGGREGATE SET SCHEMA + * + * These commands are identical except for the lookup procedure, so share code. */ void -AlterFunctionNamespace(List *name, List *argtypes, const char *newschema) +AlterFunctionNamespace(List *name, List *argtypes, bool isagg, + const char *newschema) { Oid procOid; Oid oldNspOid; @@ -1455,7 +1458,10 @@ AlterFunctionNamespace(List *name, List *argtypes, const char *newschema) procRel = heap_open(ProcedureRelationId, RowExclusiveLock); /* get function OID */ - procOid = LookupFuncNameTypeNames(name, argtypes, false); + if (isagg) + procOid = LookupAggNameTypeNames(name, argtypes, false); + else + procOid = LookupFuncNameTypeNames(name, argtypes, false); /* check permissions on function */ if (!pg_proc_ownercheck(procOid, GetUserId())) diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index c40dbf9d82..54f50a8477 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.29 2006/03/14 22:48:18 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.30 2006/04/15 17:45:34 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -201,15 +201,16 @@ DefineOperator(List *names, List *parameters) * Deletes an operator. */ void -RemoveOperator(RemoveOperStmt *stmt) +RemoveOperator(RemoveFuncStmt *stmt) { - List *operatorName = stmt->opname; + List *operatorName = stmt->name; TypeName *typeName1 = (TypeName *) linitial(stmt->args); TypeName *typeName2 = (TypeName *) lsecond(stmt->args); Oid operOid; HeapTuple tup; ObjectAddress object; + Assert(list_length(stmt->args) == 2); operOid = LookupOperNameTypeNames(NULL, operatorName, typeName1, typeName2, false, -1); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index c7e2a7fff8..cd8ebe1f5d 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.332 2006/03/23 00:19:29 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.333 2006/04/15 17:45:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1942,7 +1942,9 @@ _copyDefineStmt(DefineStmt *from) DefineStmt *newnode = makeNode(DefineStmt); COPY_SCALAR_FIELD(kind); + COPY_SCALAR_FIELD(oldstyle); COPY_NODE_FIELD(defnames); + COPY_NODE_FIELD(args); COPY_NODE_FIELD(definition); return newnode; @@ -2055,36 +2057,13 @@ _copyAlterFunctionStmt(AlterFunctionStmt *from) return newnode; } -static RemoveAggrStmt * -_copyRemoveAggrStmt(RemoveAggrStmt *from) -{ - RemoveAggrStmt *newnode = makeNode(RemoveAggrStmt); - - COPY_NODE_FIELD(aggname); - COPY_NODE_FIELD(aggtype); - COPY_SCALAR_FIELD(behavior); - - return newnode; -} - static RemoveFuncStmt * _copyRemoveFuncStmt(RemoveFuncStmt *from) { RemoveFuncStmt *newnode = makeNode(RemoveFuncStmt); - COPY_NODE_FIELD(funcname); - COPY_NODE_FIELD(args); - COPY_SCALAR_FIELD(behavior); - - return newnode; -} - -static RemoveOperStmt * -_copyRemoveOperStmt(RemoveOperStmt *from) -{ - RemoveOperStmt *newnode = makeNode(RemoveOperStmt); - - COPY_NODE_FIELD(opname); + COPY_SCALAR_FIELD(kind); + COPY_NODE_FIELD(name); COPY_NODE_FIELD(args); COPY_SCALAR_FIELD(behavior); @@ -3092,15 +3071,9 @@ copyObject(void *from) case T_AlterFunctionStmt: retval = _copyAlterFunctionStmt(from); break; - case T_RemoveAggrStmt: - retval = _copyRemoveAggrStmt(from); - break; case T_RemoveFuncStmt: retval = _copyRemoveFuncStmt(from); break; - case T_RemoveOperStmt: - retval = _copyRemoveOperStmt(from); - break; case T_RemoveOpClassStmt: retval = _copyRemoveOpClassStmt(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 8d413b87c5..9aa0b399b7 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -18,7 +18,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.268 2006/03/23 00:19:29 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.269 2006/04/15 17:45:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -909,7 +909,9 @@ static bool _equalDefineStmt(DefineStmt *a, DefineStmt *b) { COMPARE_SCALAR_FIELD(kind); + COMPARE_SCALAR_FIELD(oldstyle); COMPARE_NODE_FIELD(defnames); + COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(definition); return true; @@ -1006,30 +1008,11 @@ _equalAlterFunctionStmt(AlterFunctionStmt *a, AlterFunctionStmt *b) return true; } -static bool -_equalRemoveAggrStmt(RemoveAggrStmt *a, RemoveAggrStmt *b) -{ - COMPARE_NODE_FIELD(aggname); - COMPARE_NODE_FIELD(aggtype); - COMPARE_SCALAR_FIELD(behavior); - - return true; -} - static bool _equalRemoveFuncStmt(RemoveFuncStmt *a, RemoveFuncStmt *b) { - COMPARE_NODE_FIELD(funcname); - COMPARE_NODE_FIELD(args); - COMPARE_SCALAR_FIELD(behavior); - - return true; -} - -static bool -_equalRemoveOperStmt(RemoveOperStmt *a, RemoveOperStmt *b) -{ - COMPARE_NODE_FIELD(opname); + COMPARE_SCALAR_FIELD(kind); + COMPARE_NODE_FIELD(name); COMPARE_NODE_FIELD(args); COMPARE_SCALAR_FIELD(behavior); @@ -2112,15 +2095,9 @@ equal(void *a, void *b) case T_AlterFunctionStmt: retval = _equalAlterFunctionStmt(a, b); break; - case T_RemoveAggrStmt: - retval = _equalRemoveAggrStmt(a, b); - break; case T_RemoveFuncStmt: retval = _equalRemoveFuncStmt(a, b); break; - case T_RemoveOperStmt: - retval = _equalRemoveOperStmt(a, b); - break; case T_RemoveOpClassStmt: retval = _equalRemoveOpClassStmt(a, b); break; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 43277e4587..1c1c07bd1b 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.537 2006/03/23 00:19:29 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.538 2006/04/15 17:45:34 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -224,8 +224,9 @@ static void doNegateFloat(Value *v); %type stmtblock stmtmulti OptTableElementList TableElementList OptInherit definition - opt_distinct opt_definition func_args - func_args_list func_as createfunc_opt_list alterfunc_opt_list + opt_distinct opt_definition func_args func_args_list + func_as createfunc_opt_list alterfunc_opt_list + aggr_args aggr_args_list old_aggr_definition old_aggr_list oper_argtypes RuleActionList RuleActionMulti opt_column_list columnList opt_name_list sort_clause opt_sort_clause sortby_list index_params @@ -246,7 +247,7 @@ static void doNegateFloat(Value *v); %type createfunc_opt_item common_func_opt_item %type func_arg %type arg_class -%type func_return func_type aggr_argtype +%type func_return func_type %type TriggerForType OptTemp %type OnCommitOption @@ -285,7 +286,7 @@ static void doNegateFloat(Value *v); %type TableElement ConstraintElem TableFuncElement %type columnDef -%type def_elem +%type def_elem old_aggr_elem %type def_arg columnElem where_clause a_expr b_expr c_expr func_expr AexprConst indirection_el columnref in_expr having_clause func_table array_expr @@ -2671,11 +2672,24 @@ DropAssertStmt: *****************************************************************************/ DefineStmt: - CREATE AGGREGATE func_name definition + CREATE AGGREGATE func_name aggr_args definition { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_AGGREGATE; + n->oldstyle = false; n->defnames = $3; + n->args = $4; + n->definition = $5; + $$ = (Node *)n; + } + | CREATE AGGREGATE func_name old_aggr_definition + { + /* old-style (pre-8.2) syntax for CREATE AGGREGATE */ + DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_AGGREGATE; + n->oldstyle = true; + n->defnames = $3; + n->args = NIL; n->definition = $4; $$ = (Node *)n; } @@ -2683,7 +2697,9 @@ DefineStmt: { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_OPERATOR; + n->oldstyle = false; n->defnames = $3; + n->args = NIL; n->definition = $4; $$ = (Node *)n; } @@ -2691,7 +2707,9 @@ DefineStmt: { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_TYPE; + n->oldstyle = false; n->defnames = $3; + n->args = NIL; n->definition = $4; $$ = (Node *)n; } @@ -2700,7 +2718,9 @@ DefineStmt: /* Shell type (identified by lack of definition) */ DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_TYPE; + n->oldstyle = false; n->defnames = $3; + n->args = NIL; n->definition = NIL; $$ = (Node *)n; } @@ -2764,6 +2784,28 @@ def_arg: func_type { $$ = (Node *)$1; } | Sconst { $$ = (Node *)makeString($1); } ; +aggr_args: '(' aggr_args_list ')' { $$ = $2; } + | '(' '*' ')' { $$ = NIL; } + ; + +aggr_args_list: + Typename { $$ = list_make1($1); } + | aggr_args_list ',' Typename { $$ = lappend($1, $3); } + ; + +old_aggr_definition: '(' old_aggr_list ')' { $$ = $2; } + ; + +old_aggr_list: old_aggr_elem { $$ = list_make1($1); } + | old_aggr_list ',' old_aggr_elem { $$ = lappend($1, $3); } + ; + +old_aggr_elem: IDENT '=' def_arg + { + $$ = makeDefElem($1, (Node *)$3); + } + ; + /***************************************************************************** * @@ -2960,7 +3002,7 @@ TruncateStmt: * COMMENT ON [ [ DATABASE | DOMAIN | INDEX | SEQUENCE | TABLE | TYPE | VIEW | * CONVERSION | LANGUAGE | OPERATOR CLASS | LARGE OBJECT | * CAST | COLUMN | SCHEMA | TABLESPACE | ROLE ] | - * AGGREGATE () | + * AGGREGATE (arg1, ...) | * FUNCTION (arg1, arg2, ...) | * OPERATOR (leftoperand_typ, rightoperand_typ) | * TRIGGER ON | @@ -2980,14 +3022,13 @@ CommentStmt: n->comment = $6; $$ = (Node *) n; } - | COMMENT ON AGGREGATE func_name '(' aggr_argtype ')' - IS comment_text + | COMMENT ON AGGREGATE func_name aggr_args IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_AGGREGATE; n->objname = $4; - n->objargs = list_make1($6); - n->comment = $9; + n->objargs = $5; + n->comment = $7; $$ = (Node *) n; } | COMMENT ON FUNCTION func_name func_args IS comment_text @@ -3844,7 +3885,7 @@ opt_restrict: * QUERY: * * DROP FUNCTION funcname (arg1, arg2, ...) [ RESTRICT | CASCADE ] - * DROP AGGREGATE aggname (aggtype) [ RESTRICT | CASCADE ] + * DROP AGGREGATE aggname (arg1, ...) [ RESTRICT | CASCADE ] * DROP OPERATOR opname (leftoperand_typ, rightoperand_typ) [ RESTRICT | CASCADE ] * *****************************************************************************/ @@ -3853,7 +3894,8 @@ RemoveFuncStmt: DROP FUNCTION func_name func_args opt_drop_behavior { RemoveFuncStmt *n = makeNode(RemoveFuncStmt); - n->funcname = $3; + n->kind = OBJECT_FUNCTION; + n->name = $3; n->args = extractArgTypes($4); n->behavior = $5; $$ = (Node *)n; @@ -3861,26 +3903,23 @@ RemoveFuncStmt: ; RemoveAggrStmt: - DROP AGGREGATE func_name '(' aggr_argtype ')' opt_drop_behavior + DROP AGGREGATE func_name aggr_args opt_drop_behavior { - RemoveAggrStmt *n = makeNode(RemoveAggrStmt); - n->aggname = $3; - n->aggtype = $5; - n->behavior = $7; - $$ = (Node *)n; + RemoveFuncStmt *n = makeNode(RemoveFuncStmt); + n->kind = OBJECT_AGGREGATE; + n->name = $3; + n->args = $4; + n->behavior = $5; + $$ = (Node *)n; } ; -aggr_argtype: - Typename { $$ = $1; } - | '*' { $$ = NULL; } - ; - RemoveOperStmt: DROP OPERATOR any_operator '(' oper_argtypes ')' opt_drop_behavior { - RemoveOperStmt *n = makeNode(RemoveOperStmt); - n->opname = $3; + RemoveFuncStmt *n = makeNode(RemoveFuncStmt); + n->kind = OBJECT_OPERATOR; + n->name = $3; n->args = $5; n->behavior = $7; $$ = (Node *)n; @@ -4013,13 +4052,13 @@ opt_force: FORCE { $$ = TRUE; } * *****************************************************************************/ -RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name +RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name { RenameStmt *n = makeNode(RenameStmt); n->renameType = OBJECT_AGGREGATE; n->object = $3; - n->objarg = list_make1($5); - n->newname = $9; + n->objarg = $4; + n->newname = $7; $$ = (Node *)n; } | ALTER CONVERSION_P any_name RENAME TO name @@ -4153,13 +4192,13 @@ opt_column: COLUMN { $$ = COLUMN; } *****************************************************************************/ AlterObjectSchemaStmt: - ALTER AGGREGATE func_name '(' aggr_argtype ')' SET SCHEMA name + ALTER AGGREGATE func_name aggr_args SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); n->objectType = OBJECT_AGGREGATE; n->object = $3; - n->objarg = list_make1($5); - n->newschema = $9; + n->objarg = $4; + n->newschema = $7; $$ = (Node *)n; } | ALTER DOMAIN_P any_name SET SCHEMA name @@ -4211,13 +4250,13 @@ AlterObjectSchemaStmt: * *****************************************************************************/ -AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO RoleId +AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_AGGREGATE; n->object = $3; - n->objarg = list_make1($5); - n->newowner = $9; + n->objarg = $4; + n->newowner = $7; $$ = (Node *)n; } | ALTER CONVERSION_P any_name OWNER TO RoleId diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 35e826881f..d7c04620b2 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.185 2006/03/14 22:48:21 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.186 2006/04/15 17:45:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1115,65 +1115,6 @@ func_signature_string(List *funcname, int nargs, const Oid *argtypes) nargs, argtypes); } -/* - * find_aggregate_func - * Convenience routine to check that a function exists and is an - * aggregate. - * - * Note: basetype is ANYOID if we are looking for an aggregate on - * all types. - */ -Oid -find_aggregate_func(List *aggname, Oid basetype, bool noError) -{ - Oid oid; - HeapTuple ftup; - Form_pg_proc pform; - - oid = LookupFuncName(aggname, 1, &basetype, true); - - if (!OidIsValid(oid)) - { - if (noError) - return InvalidOid; - if (basetype == ANYOID) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("aggregate %s(*) does not exist", - NameListToString(aggname)))); - else - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("aggregate %s(%s) does not exist", - NameListToString(aggname), - format_type_be(basetype)))); - } - - /* Make sure it's an aggregate */ - ftup = SearchSysCache(PROCOID, - ObjectIdGetDatum(oid), - 0, 0, 0); - if (!HeapTupleIsValid(ftup)) /* should not happen */ - elog(ERROR, "cache lookup failed for function %u", oid); - pform = (Form_pg_proc) GETSTRUCT(ftup); - - if (!pform->proisagg) - { - ReleaseSysCache(ftup); - if (noError) - return InvalidOid; - /* we do not use the (*) notation for functions... */ - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("function %s(%s) is not an aggregate", - NameListToString(aggname), format_type_be(basetype)))); - } - - ReleaseSysCache(ftup); - - return oid; -} - /* * LookupFuncName * Given a possibly-qualified function name and a set of argument types, @@ -1246,3 +1187,101 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError) return LookupFuncName(funcname, argcount, argoids, noError); } + +/* + * LookupAggNameTypeNames + * Find an aggregate function given a name and list of TypeName nodes. + * + * This is almost like LookupFuncNameTypeNames, but the error messages refer + * to aggregates rather than plain functions, and we verify that the found + * function really is an aggregate, and we recognize the convention used by + * the grammar that agg(*) translates to a NIL list, which we have to treat + * as one ANY argument. (XXX this ought to be changed) + */ +Oid +LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError) +{ + Oid argoids[FUNC_MAX_ARGS]; + int argcount; + int i; + ListCell *args_item; + Oid oid; + HeapTuple ftup; + Form_pg_proc pform; + + argcount = list_length(argtypes); + if (argcount > FUNC_MAX_ARGS) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg("functions cannot have more than %d arguments", + FUNC_MAX_ARGS))); + + if (argcount == 0) + { + /* special case for agg(*) */ + argoids[0] = ANYOID; + argcount = 1; + } + else + { + args_item = list_head(argtypes); + for (i = 0; i < argcount; i++) + { + TypeName *t = (TypeName *) lfirst(args_item); + + argoids[i] = LookupTypeName(NULL, t); + + if (!OidIsValid(argoids[i])) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("type \"%s\" does not exist", + TypeNameToString(t)))); + + args_item = lnext(args_item); + } + } + + oid = LookupFuncName(aggname, argcount, argoids, true); + + if (!OidIsValid(oid)) + { + if (noError) + return InvalidOid; + if (argcount == 1 && argoids[0] == ANYOID) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("aggregate %s(*) does not exist", + NameListToString(aggname)))); + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("aggregate %s does not exist", + func_signature_string(aggname, + argcount, argoids)))); + } + + /* Make sure it's an aggregate */ + ftup = SearchSysCache(PROCOID, + ObjectIdGetDatum(oid), + 0, 0, 0); + if (!HeapTupleIsValid(ftup)) /* should not happen */ + elog(ERROR, "cache lookup failed for function %u", oid); + pform = (Form_pg_proc) GETSTRUCT(ftup); + + if (!pform->proisagg) + { + ReleaseSysCache(ftup); + if (noError) + return InvalidOid; + /* we do not use the (*) notation for functions... */ + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("function %s is not an aggregate", + func_signature_string(aggname, + argcount, argoids)))); + } + + ReleaseSysCache(ftup); + + return oid; +} diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 2a75ed24bb..b54d50702b 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.255 2006/03/05 15:58:40 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.256 2006/04/15 17:45:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -333,7 +333,6 @@ check_xact_readonly(Node *parsetree) case T_CreateTrigStmt: case T_CompositeTypeStmt: case T_ViewStmt: - case T_RemoveAggrStmt: case T_DropCastStmt: case T_DropStmt: case T_DropdbStmt: @@ -341,7 +340,6 @@ check_xact_readonly(Node *parsetree) case T_RemoveFuncStmt: case T_DropRoleStmt: case T_DropPLangStmt: - case T_RemoveOperStmt: case T_RemoveOpClassStmt: case T_DropPropertyStmt: case T_GrantStmt: @@ -730,7 +728,7 @@ ProcessUtility(Node *parsetree, break; /* - * **************** object creation / destruction ****************** + * **************** object creation / destruction ***************** */ case T_DefineStmt: { @@ -739,12 +737,15 @@ ProcessUtility(Node *parsetree, switch (stmt->kind) { case OBJECT_AGGREGATE: - DefineAggregate(stmt->defnames, stmt->definition); + DefineAggregate(stmt->defnames, stmt->args, + stmt->oldstyle, stmt->definition); break; case OBJECT_OPERATOR: + Assert(stmt->args == NIL); DefineOperator(stmt->defnames, stmt->definition); break; case OBJECT_TYPE: + Assert(stmt->args == NIL); DefineType(stmt->defnames, stmt->definition); break; default: @@ -815,16 +816,27 @@ ProcessUtility(Node *parsetree, AlterSequence((AlterSeqStmt *) parsetree); break; - case T_RemoveAggrStmt: - RemoveAggregate((RemoveAggrStmt *) parsetree); - break; - case T_RemoveFuncStmt: - RemoveFunction((RemoveFuncStmt *) parsetree); - break; + { + RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree; - case T_RemoveOperStmt: - RemoveOperator((RemoveOperStmt *) parsetree); + switch (stmt->kind) + { + case OBJECT_FUNCTION: + RemoveFunction(stmt); + break; + case OBJECT_AGGREGATE: + RemoveAggregate(stmt); + break; + case OBJECT_OPERATOR: + RemoveOperator(stmt); + break; + default: + elog(ERROR, "unrecognized object type: %d", + (int) stmt->kind); + break; + } + } break; case T_CreatedbStmt: @@ -1576,16 +1588,21 @@ CreateCommandTag(Node *parsetree) tag = "ALTER SEQUENCE"; break; - case T_RemoveAggrStmt: - tag = "DROP AGGREGATE"; - break; - case T_RemoveFuncStmt: - tag = "DROP FUNCTION"; - break; - - case T_RemoveOperStmt: - tag = "DROP OPERATOR"; + switch (((RemoveFuncStmt *) parsetree)->kind) + { + case OBJECT_FUNCTION: + tag = "DROP FUNCTION"; + break; + case OBJECT_AGGREGATE: + tag = "DROP AGGREGATE"; + break; + case OBJECT_OPERATOR: + tag = "DROP OPERATOR"; + break; + default: + tag = "???"; + } break; case T_CreatedbStmt: diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 99e061d2de..f6ed06f3db 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.71 2006/03/05 15:58:55 momjian Exp $ + * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.72 2006/04/15 17:45:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -57,22 +57,23 @@ extern void AlterFunction(AlterFunctionStmt *stmt); extern void CreateCast(CreateCastStmt *stmt); extern void DropCast(DropCastStmt *stmt); extern void DropCastById(Oid castOid); -extern void AlterFunctionNamespace(List *name, List *argtypes, +extern void AlterFunctionNamespace(List *name, List *argtypes, bool isagg, const char *newschema); /* commands/operatorcmds.c */ extern void DefineOperator(List *names, List *parameters); -extern void RemoveOperator(RemoveOperStmt *stmt); +extern void RemoveOperator(RemoveFuncStmt *stmt); extern void RemoveOperatorById(Oid operOid); extern void AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typename2, Oid newOwnerId); extern void AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId); /* commands/aggregatecmds.c */ -extern void DefineAggregate(List *names, List *parameters); -extern void RemoveAggregate(RemoveAggrStmt *stmt); -extern void RenameAggregate(List *name, TypeName *basetype, const char *newname); -extern void AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId); +extern void DefineAggregate(List *name, List *args, bool oldstyle, + List *parameters); +extern void RemoveAggregate(RemoveFuncStmt *stmt); +extern void RenameAggregate(List *name, List *args, const char *newname); +extern void AlterAggregateOwner(List *name, List *args, Oid newOwnerId); /* commands/opclasscmds.c */ extern void DefineOpClass(CreateOpClassStmt *stmt); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index b8415378d9..fe5ab018f5 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.184 2006/03/07 01:00:18 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.185 2006/04/15 17:45:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -241,9 +241,7 @@ typedef enum NodeTag T_IndexStmt, T_CreateFunctionStmt, T_AlterFunctionStmt, - T_RemoveAggrStmt, T_RemoveFuncStmt, - T_RemoveOperStmt, T_RenameStmt, T_RuleStmt, T_NotifyStmt, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index d6f7c4a95a..e4eb385df8 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.306 2006/03/23 00:19:30 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.307 2006/04/15 17:45:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1242,7 +1242,9 @@ typedef struct DefineStmt { NodeTag type; ObjectType kind; /* aggregate, operator, type */ + bool oldstyle; /* hack to signal old CREATE AGG syntax */ List *defnames; /* qualified name (list of Value strings) */ + List *args; /* a list of TypeName (if needed) */ List *definition; /* a list of DefElem */ } DefineStmt; @@ -1456,41 +1458,18 @@ typedef struct AlterFunctionStmt } AlterFunctionStmt; /* ---------------------- - * Drop Aggregate Statement - * ---------------------- - */ -typedef struct RemoveAggrStmt -{ - NodeTag type; - List *aggname; /* aggregate to drop */ - TypeName *aggtype; /* TypeName for input datatype, or NULL */ - DropBehavior behavior; /* RESTRICT or CASCADE behavior */ -} RemoveAggrStmt; - -/* ---------------------- - * Drop Function Statement + * Drop {Function|Aggregate|Operator} Statement * ---------------------- */ typedef struct RemoveFuncStmt { NodeTag type; - List *funcname; /* function to drop */ + ObjectType kind; /* function, aggregate, operator */ + List *name; /* qualified name of object to drop */ List *args; /* types of the arguments */ DropBehavior behavior; /* RESTRICT or CASCADE behavior */ } RemoveFuncStmt; -/* ---------------------- - * Drop Operator Statement - * ---------------------- - */ -typedef struct RemoveOperStmt -{ - NodeTag type; - List *opname; /* operator to drop */ - List *args; /* types of the arguments */ - DropBehavior behavior; /* RESTRICT or CASCADE behavior */ -} RemoveOperStmt; - /* ---------------------- * Drop Operator Class Statement * ---------------------- diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h index 13aa706a04..486e5ea44d 100644 --- a/src/include/parser/parse_func.h +++ b/src/include/parser/parse_func.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/parser/parse_func.h,v 1.55 2006/03/14 22:48:22 tgl Exp $ + * $PostgreSQL: pgsql/src/include/parser/parse_func.h,v 1.56 2006/04/15 17:45:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -72,11 +72,11 @@ extern const char *funcname_signature_string(const char *funcname, extern const char *func_signature_string(List *funcname, int nargs, const Oid *argtypes); -extern Oid find_aggregate_func(List *aggname, Oid basetype, bool noError); - extern Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError); extern Oid LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError); +extern Oid LookupAggNameTypeNames(List *aggname, List *argtypes, + bool noError); #endif /* PARSE_FUNC_H */ diff --git a/src/test/regress/expected/errors.out b/src/test/regress/expected/errors.out index 8c97e4106b..ba5ecedc0a 100644 --- a/src/test/regress/expected/errors.out +++ b/src/test/regress/expected/errors.out @@ -133,7 +133,7 @@ ERROR: function int2um(integer) does not exist create aggregate newcnt1 (sfunc = int4inc, stype = int4, initcond = '0'); -ERROR: aggregate basetype must be specified +ERROR: aggregate input type must be specified -- -- DROP INDEX