Further tweaking of error messages for cases involving attributes &

functions of join or subselect aliases.  It'd be awfully nice if this
code knew for sure whether it was dealing with 'x.f' or 'f(x)' syntax;
maybe we can fix that in a future cycle.
This commit is contained in:
Tom Lane 2001-04-18 22:25:31 +00:00
parent 645ebc0403
commit 23436bd530

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.101 2001/03/22 03:59:41 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.102 2001/04/18 22:25:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -250,6 +250,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
char *refname; char *refname;
Relation rd; Relation rd;
int nargs = length(fargs); int nargs = length(fargs);
int argn;
Func *funcnode; Func *funcnode;
Oid oid_array[FUNC_MAX_ARGS]; Oid oid_array[FUNC_MAX_ARGS];
Oid *true_oid_array; Oid *true_oid_array;
@ -261,6 +262,15 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
Oid toid = InvalidOid; Oid toid = InvalidOid;
Expr *expr; Expr *expr;
/*
* Most of the rest of the parser just assumes that functions do
* not have more than FUNC_MAX_ARGS parameters. We have to test
* here to protect against array overruns, etc.
*/
if (nargs > FUNC_MAX_ARGS)
elog(ERROR, "Cannot pass more than %d arguments to a function",
FUNC_MAX_ARGS);
if (fargs) if (fargs)
{ {
first_arg = lfirst(fargs); first_arg = lfirst(fargs);
@ -419,7 +429,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
*/ */
MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
nargs = 0; argn = 0;
foreach(i, fargs) foreach(i, fargs)
{ {
Node *arg = lfirst(i); Node *arg = lfirst(i);
@ -447,14 +457,31 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
{ {
/* /*
* We have f(x) or more likely x.f where x is a join and f * The relation name refers to a join. We can't support
* is not one of the attribute names of the join (else
* we'd have recognized it above). We don't support
* functions on join tuples (since we don't have a named * functions on join tuples (since we don't have a named
* type for the join tuples), so error out. * type for the join tuples), so error out.
*/ */
elog(ERROR, "No such attribute or function %s.%s", if (nargs == 1)
refname, funcname); {
/*
* We have f(x) or more likely x.f where x is a join
* and f is not one of the attribute names of the join
* (else we'd have recognized it above). Give an
* appropriately vague error message. Would be nicer
* to know which syntax was used...
*/
elog(ERROR, "No such attribute or function %s.%s",
refname, funcname);
}
else
{
/*
* There are multiple arguments, so it must be a function
* call.
*/
elog(ERROR, "Cannot pass result of join %s to a function",
refname);
}
rte = NULL; /* keep compiler quiet */ rte = NULL; /* keep compiler quiet */
} }
else else
@ -467,8 +494,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
vnum = RTERangeTablePosn(pstate, rte, &sublevels_up); vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
/* /*
* for func(relname), the param to the function is the tuple * The parameter to be passed to the function is the whole tuple
* under consideration. We build a special VarNode to reflect * from the relation. We build a special VarNode to reflect
* this -- it has varno set to the correct range table entry, * this -- it has varno set to the correct range table entry,
* but has varattno == 0 to signal that the whole tuple is the * but has varattno == 0 to signal that the whole tuple is the
* argument. Also, it has typmod set to sizeof(Pointer) to * argument. Also, it has typmod set to sizeof(Pointer) to
@ -477,9 +504,23 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
*/ */
if (rte->relname == NULL) if (rte->relname == NULL)
{ {
/* Here, we have an unrecognized attribute of a sub-select */ /*
elog(ERROR, "No such attribute or function %s.%s", * RTE is a subselect; must fail for lack of a specific type
refname, funcname); */
if (nargs == 1)
{
/*
* Here, we probably have an unrecognized attribute of a
* sub-select; again can't tell if it was x.f or f(x)
*/
elog(ERROR, "No such attribute or function %s.%s",
refname, funcname);
}
else
{
elog(ERROR, "Cannot pass result of sub-select %s to a function",
refname);
}
} }
toid = typenameTypeId(rte->relname); toid = typenameTypeId(rte->relname);
@ -498,16 +539,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
/* if attisset is true, we already set toid for the single arg */ /* if attisset is true, we already set toid for the single arg */
} }
/* oid_array[argn++] = toid;
* Most of the rest of the parser just assumes that functions do
* not have more than FUNC_MAX_ARGS parameters. We have to test
* here to protect against array overruns, etc.
*/
if (nargs >= FUNC_MAX_ARGS)
elog(ERROR, "Cannot pass more than %d arguments to a function",
FUNC_MAX_ARGS);
oid_array[nargs++] = toid;
} }
/* /*