]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Further tweaking of error messages for cases involving attributes &
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 18 Apr 2001 22:25:31 +0000 (22:25 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 18 Apr 2001 22:25:31 +0000 (22:25 +0000)
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.

src/backend/parser/parse_func.c

index 8d2f632f33acb48041e1ea9563070cb28870012f..947dcdcee581f3777a85b062317bab46e2f875c7 100644 (file)
@@ -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;
        }
 
        /*