Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8bba4b4

Browse files
committed
Generate a reasonable error message when an aggregate function is applied
to an undecorated relation name (cf. example from Ed Loehr, 5/25/00).
1 parent cf169e0 commit 8bba4b4

File tree

1 file changed

+34
-21
lines changed

1 file changed

+34
-21
lines changed

src/backend/parser/parse_func.c

+34-21
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
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,
271271
Node *retval;
272272
bool retset;
273273
bool must_be_agg = agg_star || agg_distinct;
274+
bool could_be_agg;
274275
bool attisset = false;
275276
Oid toid = InvalidOid;
276277
Expr *expr;
@@ -291,7 +292,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
291292
if (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
{
296297
Ident *ident = (Ident *) first_arg;
297298
RangeTblEntry *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) */
427423
if (nargs != 1)
428424
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+
}
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... */
440444
if (SearchSysCacheTuple(AGGNAME,
@@ -445,9 +449,18 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
445449
fargs, agg_star, agg_distinct,
446450
precedence);
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 table which is compatible. - thomas 1998-12-05
463+
* aggregate table that is compatible. - thomas 1998-12-05
451464
*/
452465
ncandidates = agg_get_candidates(funcname, basetype, &candidates);
453466
if (ncandidates > 0)
@@ -497,7 +510,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
497510
{
498511
Node *arg = lfirst(i);
499512

500-
if (IsA(arg, Ident) &&((Ident *) arg)->isRel)
513+
if (IsA(arg, Ident) && ((Ident *) arg)->isRel)
501514
{
502515
RangeTblEntry *rte;
503516
int vnum;

0 commit comments

Comments
 (0)