aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_func.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-05-26 03:56:40 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-05-26 03:56:40 +0000
commit8bba4b4e0eaa16fbbddbf0631ea295a6953eec85 (patch)
tree06adbf9e372f7f729a8a84ea44bf18bb60ad3bc5 /src/backend/parser/parse_func.c
parentcf169e00882609c0b3b9e0a0085df4b6d82d8041 (diff)
downloadpostgresql-8bba4b4e0eaa16fbbddbf0631ea295a6953eec85.tar.gz
postgresql-8bba4b4e0eaa16fbbddbf0631ea295a6953eec85.zip
Generate a reasonable error message when an aggregate function is applied
to an undecorated relation name (cf. example from Ed Loehr, 5/25/00).
Diffstat (limited to 'src/backend/parser/parse_func.c')
-rw-r--r--src/backend/parser/parse_func.c55
1 files changed, 34 insertions, 21 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 3b543c3d613..ed6a910f273 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.78 2000/04/12 17:15:26 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.79 2000/05/26 03:56:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -271,6 +271,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
Node *retval;
bool retset;
bool must_be_agg = agg_star || agg_distinct;
+ bool could_be_agg;
bool attisset = false;
Oid toid = InvalidOid;
Expr *expr;
@@ -291,7 +292,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
if (nargs == 1 && !must_be_agg)
{
/* Is it a plain Relation name from the parser? */
- if (IsA(first_arg, Ident) &&((Ident *) first_arg)->isRel)
+ if (IsA(first_arg, Ident) && ((Ident *) first_arg)->isRel)
{
Ident *ident = (Ident *) first_arg;
RangeTblEntry *rte;
@@ -413,28 +414,31 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
}
}
- if (nargs == 1 || must_be_agg)
+ /*
+ * See if it's an aggregate.
+ */
+ if (must_be_agg)
{
-
- /*
- * See if it's an aggregate.
- */
- Oid basetype;
- int ncandidates;
- CandidateList candidates;
-
/* We don't presently cope with, eg, foo(DISTINCT x,y) */
if (nargs != 1)
elog(ERROR, "Aggregate functions may only have one parameter");
+ /* Agg's argument can't be a relation name, either */
+ if (IsA(first_arg, Ident) && ((Ident *) first_arg)->isRel)
+ elog(ERROR, "Aggregate functions cannot be applied to relation names");
+ could_be_agg = true;
+ }
+ else
+ {
+ /* Try to parse as an aggregate if above-mentioned checks are OK */
+ could_be_agg = (nargs == 1) &&
+ !(IsA(first_arg, Ident) && ((Ident *) first_arg)->isRel);
+ }
- /*
- * the aggregate COUNT is a special case, ignore its base type.
- * Treat it as zero. XXX mighty ugly --- FIXME
- */
- if (strcmp(funcname, "count") == 0)
- basetype = 0;
- else
- basetype = exprType(lfirst(fargs));
+ if (could_be_agg)
+ {
+ Oid basetype = exprType(lfirst(fargs));
+ int ncandidates;
+ CandidateList candidates;
/* try for exact match first... */
if (SearchSysCacheTuple(AGGNAME,
@@ -445,9 +449,18 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
fargs, agg_star, agg_distinct,
precedence);
+ /* check for aggregate-that-accepts-any-type (eg, COUNT) */
+ if (SearchSysCacheTuple(AGGNAME,
+ PointerGetDatum(funcname),
+ ObjectIdGetDatum(0),
+ 0, 0))
+ return (Node *) ParseAgg(pstate, funcname, 0,
+ fargs, agg_star, agg_distinct,
+ precedence);
+
/*
* No exact match yet, so see if there is another entry in the
- * aggregate table which is compatible. - thomas 1998-12-05
+ * aggregate table that is compatible. - thomas 1998-12-05
*/
ncandidates = agg_get_candidates(funcname, basetype, &candidates);
if (ncandidates > 0)
@@ -497,7 +510,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
{
Node *arg = lfirst(i);
- if (IsA(arg, Ident) &&((Ident *) arg)->isRel)
+ if (IsA(arg, Ident) && ((Ident *) arg)->isRel)
{
RangeTblEntry *rte;
int vnum;