aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_func.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_func.c')
-rw-r--r--src/backend/parser/parse_func.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index e585e6df716..88132bdbd58 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.180 2005/05/31 01:03:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.181 2005/06/22 15:19:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -64,9 +64,9 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
Oid rettype;
Oid funcid;
ListCell *l;
+ ListCell *nextl;
Node *first_arg = NULL;
- int nargs = list_length(fargs);
- int argn;
+ int nargs;
Oid actual_arg_types[FUNC_MAX_ARGS];
Oid *declared_arg_types;
Node *retval;
@@ -79,12 +79,38 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
* protect against array overruns, etc. Of course, this may not be a
* function, but the test doesn't hurt.
*/
- if (nargs > FUNC_MAX_ARGS)
+ if (list_length(fargs) > FUNC_MAX_ARGS)
ereport(ERROR,
(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
errmsg("cannot pass more than %d arguments to a function",
FUNC_MAX_ARGS)));
+ /*
+ * Extract arg type info in preparation for function lookup.
+ *
+ * If any arguments are Param markers of type VOID, we discard them
+ * from the parameter list. This is a hack to allow the JDBC driver
+ * to not have to distinguish "input" and "output" parameter symbols
+ * while parsing function-call constructs. We can't use foreach()
+ * because we may modify the list ...
+ */
+ nargs = 0;
+ for (l = list_head(fargs); l != NULL; l = nextl)
+ {
+ Node *arg = lfirst(l);
+ Oid argtype = exprType(arg);
+
+ nextl = lnext(l);
+
+ if (argtype == VOIDOID && IsA(arg, Param) && !is_column)
+ {
+ fargs = list_delete_ptr(fargs, arg);
+ continue;
+ }
+
+ actual_arg_types[nargs++] = argtype;
+ }
+
if (fargs)
{
first_arg = linitial(fargs);
@@ -99,7 +125,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
*/
if (nargs == 1 && !agg_star && !agg_distinct && list_length(funcname) == 1)
{
- Oid argtype = exprType(first_arg);
+ Oid argtype = actual_arg_types[0];
if (argtype == RECORDOID || ISCOMPLEX(argtype))
{
@@ -117,18 +143,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
}
/*
- * Okay, it's not a column projection, so it must really be a
- * function. Extract arg type info in preparation for function lookup.
- */
- argn = 0;
- foreach(l, fargs)
- {
- Node *arg = lfirst(l);
-
- actual_arg_types[argn++] = exprType(arg);
- }
-
- /*
+ * Okay, it's not a column projection, so it must really be a function.
* func_get_detail looks up the function in the catalogs, does
* disambiguation for polymorphic functions, handles inheritance, and
* returns the funcid and type and set or singleton status of the