aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_func.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2001-04-18 22:25:31 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2001-04-18 22:25:31 +0000
commit23436bd530b296f8c56b8b73853b3f010898165f (patch)
treef81983cd64a3e055909969a2618788a009cbf4bc /src/backend/parser/parse_func.c
parent645ebc0403936e97ab62e5302280aa8cf99aee08 (diff)
downloadpostgresql-23436bd530b296f8c56b8b73853b3f010898165f.tar.gz
postgresql-23436bd530b296f8c56b8b73853b3f010898165f.zip
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.
Diffstat (limited to 'src/backend/parser/parse_func.c')
-rw-r--r--src/backend/parser/parse_func.c76
1 files changed, 54 insertions, 22 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 8d2f632f33a..947dcdcee58 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
*
*
* 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;
Relation rd;
int nargs = length(fargs);
+ int argn;
Func *funcnode;
Oid oid_array[FUNC_MAX_ARGS];
Oid *true_oid_array;
@@ -261,6 +262,15 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
Oid toid = InvalidOid;
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)
{
first_arg = lfirst(fargs);
@@ -419,7 +429,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
*/
MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
- nargs = 0;
+ argn = 0;
foreach(i, fargs)
{
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
- * is not one of the attribute names of the join (else
- * we'd have recognized it above). We don't support
+ * The relation name refers to a join. We can't support
* functions on join tuples (since we don't have a named
* type for the join tuples), so error out.
*/
- elog(ERROR, "No such attribute or function %s.%s",
- refname, funcname);
+ if (nargs == 1)
+ {
+ /*
+ * 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 */
}
else
@@ -467,8 +494,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
/*
- * for func(relname), the param to the function is the tuple
- * under consideration. We build a special VarNode to reflect
+ * The parameter to be passed to the function is the whole tuple
+ * from the relation. We build a special VarNode to reflect
* this -- it has varno set to the correct range table entry,
* but has varattno == 0 to signal that the whole tuple is the
* 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)
{
- /* Here, we have an unrecognized attribute of a sub-select */
- elog(ERROR, "No such attribute or function %s.%s",
- refname, funcname);
+ /*
+ * RTE is a subselect; must fail for lack of a specific type
+ */
+ 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);
@@ -498,16 +539,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
/* if attisset is true, we already set toid for the single arg */
}
- /*
- * 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;
+ oid_array[argn++] = toid;
}
/*