aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_func.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-07-27 19:52:07 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-07-27 19:52:07 +0000
commit108fe4730152058f9b576969d08898b39bf7fc38 (patch)
tree15a7d14be8267612cdfed4de8af86993b37f9997 /src/backend/parser/parse_func.c
parentc2d1138351f89d0705f71cf935a56b9a2e28ed24 (diff)
downloadpostgresql-108fe4730152058f9b576969d08898b39bf7fc38.tar.gz
postgresql-108fe4730152058f9b576969d08898b39bf7fc38.zip
Aggregate functions now support multiple input arguments. I also took
the opportunity to treat COUNT(*) as a zero-argument aggregate instead of the old hack that equated it to COUNT(1); this is materially cleaner (no more weird ANYOID cases) and ought to be at least a tiny bit faster. Original patch by Sergey Koposov; review, documentation, simple regression tests, pg_dump and psql support by moi.
Diffstat (limited to 'src/backend/parser/parse_func.c')
-rw-r--r--src/backend/parser/parse_func.c54
1 files changed, 26 insertions, 28 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index aa0632a3898..b1b53164f80 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.188 2006/07/14 14:52:22 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.189 2006/07/27 19:52:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -259,10 +259,21 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
aggref->aggfnoid = funcid;
aggref->aggtype = rettype;
- aggref->target = linitial(fargs);
+ aggref->args = fargs;
aggref->aggstar = agg_star;
aggref->aggdistinct = agg_distinct;
+ /*
+ * Reject attempt to call a parameterless aggregate without (*)
+ * syntax. This is mere pedantry but some folks insisted ...
+ */
+ if (fargs == NIL && !agg_star)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("%s(*) must be used to call a parameterless aggregate function",
+ NameListToString(funcname)),
+ parser_errposition(pstate, location)));
+
/* parse_agg.c does additional aggregate-specific processing */
transformAggregateCall(pstate, aggref);
@@ -1194,9 +1205,7 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
*
* 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)
+ * function really is an aggregate.
*/
Oid
LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
@@ -1204,7 +1213,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
Oid argoids[FUNC_MAX_ARGS];
int argcount;
int i;
- ListCell *args_item;
+ ListCell *lc;
Oid oid;
HeapTuple ftup;
Form_pg_proc pform;
@@ -1216,29 +1225,18 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
errmsg("functions cannot have more than %d arguments",
FUNC_MAX_ARGS)));
- if (argcount == 0)
- {
- /* special case for agg(*) */
- argoids[0] = ANYOID;
- argcount = 1;
- }
- else
+ i = 0;
+ foreach(lc, argtypes)
{
- 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))));
+ TypeName *t = (TypeName *) lfirst(lc);
- args_item = lnext(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))));
+ i++;
}
oid = LookupFuncName(aggname, argcount, argoids, true);
@@ -1247,7 +1245,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
{
if (noError)
return InvalidOid;
- if (argcount == 1 && argoids[0] == ANYOID)
+ if (argcount == 0)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("aggregate %s(*) does not exist",