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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy