8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -250,6 +250,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
250
250
char * refname ;
251
251
Relation rd ;
252
252
int nargs = length (fargs );
253
+ int argn ;
253
254
Func * funcnode ;
254
255
Oid oid_array [FUNC_MAX_ARGS ];
255
256
Oid * true_oid_array ;
@@ -261,6 +262,15 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
261
262
Oid toid = InvalidOid ;
262
263
Expr * expr ;
263
264
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
+
264
274
if (fargs )
265
275
{
266
276
first_arg = lfirst (fargs );
@@ -419,7 +429,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
419
429
*/
420
430
MemSet (oid_array , 0 , FUNC_MAX_ARGS * sizeof (Oid ));
421
431
422
- nargs = 0 ;
432
+ argn = 0 ;
423
433
foreach (i , fargs )
424
434
{
425
435
Node * arg = lfirst (i );
@@ -447,14 +457,31 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
447
457
{
448
458
449
459
/*
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
453
461
* functions on join tuples (since we don't have a named
454
462
* type for the join tuples), so error out.
455
463
*/
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
+ }
458
485
rte = NULL ; /* keep compiler quiet */
459
486
}
460
487
else
@@ -467,8 +494,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
467
494
vnum = RTERangeTablePosn (pstate , rte , & sublevels_up );
468
495
469
496
/*
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
472
499
* this -- it has varno set to the correct range table entry,
473
500
* but has varattno == 0 to signal that the whole tuple is the
474
501
* argument. Also, it has typmod set to sizeof(Pointer) to
@@ -477,9 +504,23 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
477
504
*/
478
505
if (rte -> relname == NULL )
479
506
{
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
+ }
483
524
}
484
525
485
526
toid = typenameTypeId (rte -> relname );
@@ -498,16 +539,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
498
539
/* if attisset is true, we already set toid for the single arg */
499
540
}
500
541
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 ;
511
543
}
512
544
513
545
/*
0 commit comments