8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -271,6 +271,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
271
271
Node * retval ;
272
272
bool retset ;
273
273
bool must_be_agg = agg_star || agg_distinct ;
274
+ bool could_be_agg ;
274
275
bool attisset = false;
275
276
Oid toid = InvalidOid ;
276
277
Expr * expr ;
@@ -291,7 +292,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
291
292
if (nargs == 1 && !must_be_agg )
292
293
{
293
294
/* 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 )
295
296
{
296
297
Ident * ident = (Ident * ) first_arg ;
297
298
RangeTblEntry * rte ;
@@ -413,28 +414,31 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
413
414
}
414
415
}
415
416
416
- if (nargs == 1 || must_be_agg )
417
+ /*
418
+ * See if it's an aggregate.
419
+ */
420
+ if (must_be_agg )
417
421
{
418
-
419
- /*
420
- * See if it's an aggregate.
421
- */
422
- Oid basetype ;
423
- int ncandidates ;
424
- CandidateList candidates ;
425
-
426
422
/* We don't presently cope with, eg, foo(DISTINCT x,y) */
427
423
if (nargs != 1 )
428
424
elog (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
+ }
429
436
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 ;
438
442
439
443
/* try for exact match first... */
440
444
if (SearchSysCacheTuple (AGGNAME ,
@@ -445,9 +449,18 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
445
449
fargs , agg_star , agg_distinct ,
446
450
precedence );
447
451
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
+
448
461
/*
449
462
* No exact match yet, so see if there is another entry in the
450
- * aggregate table which is compatible. - thomas 1998-12-05
463
+ * aggregate table that is compatible. - thomas 1998-12-05
451
464
*/
452
465
ncandidates = agg_get_candidates (funcname , basetype , & candidates );
453
466
if (ncandidates > 0 )
@@ -497,7 +510,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
497
510
{
498
511
Node * arg = lfirst (i );
499
512
500
- if (IsA (arg , Ident ) && ((Ident * ) arg )-> isRel )
513
+ if (IsA (arg , Ident ) && ((Ident * ) arg )-> isRel )
501
514
{
502
515
RangeTblEntry * rte ;
503
516
int vnum ;
0 commit comments