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:
parent
645ebc0403
commit
23436bd530
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user