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