88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.78 2000/04/12 17:15:26 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.79 2000/05/26 03:56:40 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -271,6 +271,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
271271Node * retval ;
272272bool retset ;
273273bool must_be_agg = agg_star || agg_distinct ;
274+ bool could_be_agg ;
274275bool attisset = false;
275276Oid toid = InvalidOid ;
276277Expr * expr ;
@@ -291,7 +292,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
291292if (nargs == 1 && !must_be_agg )
292293{
293294/* Is it a plain Relation name from the parser? */
294- if (IsA (first_arg ,Ident )&& ((Ident * )first_arg )-> isRel )
295+ if (IsA (first_arg ,Ident )&& ((Ident * )first_arg )-> isRel )
295296{
296297Ident * ident = (Ident * )first_arg ;
297298RangeTblEntry * rte ;
@@ -413,28 +414,31 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
413414}
414415}
415416
416- if (nargs == 1 || must_be_agg )
417+ /*
418+ * See if it's an aggregate.
419+ */
420+ if (must_be_agg )
417421{
418-
419- /*
420- * See if it's an aggregate.
421- */
422- Oid basetype ;
423- int ncandidates ;
424- CandidateList candidates ;
425-
426422/* We don't presently cope with, eg, foo(DISTINCT x,y) */
427423if (nargs != 1 )
428424elog (ERROR ,"Aggregate functions may only have one parameter" );
425+ /* Agg's argument can't be a relation name, either */
426+ if (IsA (first_arg ,Ident )&& ((Ident * )first_arg )-> isRel )
427+ elog (ERROR ,"Aggregate functions cannot be applied to relation names" );
428+ could_be_agg = true;
429+ }
430+ else
431+ {
432+ /* Try to parse as an aggregate if above-mentioned checks are OK */
433+ could_be_agg = (nargs == 1 )&&
434+ !(IsA (first_arg ,Ident )&& ((Ident * )first_arg )-> isRel );
435+ }
429436
430- /*
431- * the aggregate COUNT is a special case, ignore its base type.
432- * Treat it as zero. XXX mighty ugly --- FIXME
433- */
434- if (strcmp (funcname ,"count" )== 0 )
435- basetype = 0 ;
436- else
437- basetype = exprType (lfirst (fargs ));
437+ if (could_be_agg )
438+ {
439+ Oid basetype = exprType (lfirst (fargs ));
440+ int ncandidates ;
441+ CandidateList candidates ;
438442
439443/* try for exact match first... */
440444if (SearchSysCacheTuple (AGGNAME ,
@@ -445,9 +449,18 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
445449fargs ,agg_star ,agg_distinct ,
446450precedence );
447451
452+ /* check for aggregate-that-accepts-any-type (eg, COUNT) */
453+ if (SearchSysCacheTuple (AGGNAME ,
454+ PointerGetDatum (funcname ),
455+ ObjectIdGetDatum (0 ),
456+ 0 ,0 ))
457+ return (Node * )ParseAgg (pstate ,funcname ,0 ,
458+ fargs ,agg_star ,agg_distinct ,
459+ precedence );
460+
448461/*
449462 * No exact match yet, so see if there is another entry in the
450- * aggregate tablewhich is compatible. - thomas 1998-12-05
463+ * aggregate tablethat is compatible. - thomas 1998-12-05
451464 */
452465ncandidates = agg_get_candidates (funcname ,basetype ,& candidates );
453466if (ncandidates > 0 )
@@ -497,7 +510,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
497510{
498511Node * arg = lfirst (i );
499512
500- if (IsA (arg ,Ident )&& ((Ident * )arg )-> isRel )
513+ if (IsA (arg ,Ident )&& ((Ident * )arg )-> isRel )
501514{
502515RangeTblEntry * rte ;
503516int vnum ;