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

Commit 23436bd

Browse files
committed
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.
1 parent 645ebc0 commit 23436bd

File tree

1 file changed

+54
-22
lines changed

1 file changed

+54
-22
lines changed

src/backend/parser/parse_func.c

Lines changed: 54 additions & 22 deletions
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.101 2001/03/22 03:59:41 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.102 2001/04/18 22:25:31 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -250,6 +250,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
250250
char *refname;
251251
Relation rd;
252252
int nargs = length(fargs);
253+
int argn;
253254
Func *funcnode;
254255
Oid oid_array[FUNC_MAX_ARGS];
255256
Oid *true_oid_array;
@@ -261,6 +262,15 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
261262
Oid toid = InvalidOid;
262263
Expr *expr;
263264

265+
/*
266+
* Most of the rest of the parser just assumes that functions do
267+
* not have more than FUNC_MAX_ARGS parameters. We have to test
268+
* here to protect against array overruns, etc.
269+
*/
270+
if (nargs > FUNC_MAX_ARGS)
271+
elog(ERROR, "Cannot pass more than %d arguments to a function",
272+
FUNC_MAX_ARGS);
273+
264274
if (fargs)
265275
{
266276
first_arg = lfirst(fargs);
@@ -419,7 +429,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
419429
*/
420430
MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
421431

422-
nargs = 0;
432+
argn = 0;
423433
foreach(i, fargs)
424434
{
425435
Node *arg = lfirst(i);
@@ -447,14 +457,31 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
447457
{
448458

449459
/*
450-
* We have f(x) or more likely x.f where x is a join and f
451-
* is not one of the attribute names of the join (else
452-
* we'd have recognized it above). We don't support
460+
* The relation name refers to a join. We can't support
453461
* functions on join tuples (since we don't have a named
454462
* type for the join tuples), so error out.
455463
*/
456-
elog(ERROR, "No such attribute or function %s.%s",
457-
refname, funcname);
464+
if (nargs == 1)
465+
{
466+
/*
467+
* We have f(x) or more likely x.f where x is a join
468+
* and f is not one of the attribute names of the join
469+
* (else we'd have recognized it above). Give an
470+
* appropriately vague error message. Would be nicer
471+
* to know which syntax was used...
472+
*/
473+
elog(ERROR, "No such attribute or function %s.%s",
474+
refname, funcname);
475+
}
476+
else
477+
{
478+
/*
479+
* There are multiple arguments, so it must be a function
480+
* call.
481+
*/
482+
elog(ERROR, "Cannot pass result of join %s to a function",
483+
refname);
484+
}
458485
rte = NULL; /* keep compiler quiet */
459486
}
460487
else
@@ -467,8 +494,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
467494
vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
468495

469496
/*
470-
* for func(relname), the param to the function is the tuple
471-
* under consideration. We build a special VarNode to reflect
497+
* The parameter to be passed to the function is the whole tuple
498+
* from the relation. We build a special VarNode to reflect
472499
* this -- it has varno set to the correct range table entry,
473500
* but has varattno == 0 to signal that the whole tuple is the
474501
* argument. Also, it has typmod set to sizeof(Pointer) to
@@ -477,9 +504,23 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
477504
*/
478505
if (rte->relname == NULL)
479506
{
480-
/* Here, we have an unrecognized attribute of a sub-select */
481-
elog(ERROR, "No such attribute or function %s.%s",
482-
refname, funcname);
507+
/*
508+
* RTE is a subselect; must fail for lack of a specific type
509+
*/
510+
if (nargs == 1)
511+
{
512+
/*
513+
* Here, we probably have an unrecognized attribute of a
514+
* sub-select; again can't tell if it was x.f or f(x)
515+
*/
516+
elog(ERROR, "No such attribute or function %s.%s",
517+
refname, funcname);
518+
}
519+
else
520+
{
521+
elog(ERROR, "Cannot pass result of sub-select %s to a function",
522+
refname);
523+
}
483524
}
484525

485526
toid = typenameTypeId(rte->relname);
@@ -498,16 +539,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
498539
/* if attisset is true, we already set toid for the single arg */
499540
}
500541

501-
/*
502-
* Most of the rest of the parser just assumes that functions do
503-
* not have more than FUNC_MAX_ARGS parameters. We have to test
504-
* here to protect against array overruns, etc.
505-
*/
506-
if (nargs >= FUNC_MAX_ARGS)
507-
elog(ERROR, "Cannot pass more than %d arguments to a function",
508-
FUNC_MAX_ARGS);
509-
510-
oid_array[nargs++] = toid;
542+
oid_array[argn++] = toid;
511543
}
512544

513545
/*

0 commit comments

Comments
 (0)