mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Add a hack requested by the JDBC driver writers: when a function's
argument list contains parameter symbols ($n) declared as type VOID, discard these arguments. This allows the driver to avoid renumbering mixed IN and OUT argument placeholders (the JDBC syntax involves writing ? for both IN and OUT parameters, but on the server side we don't think that OUT parameters are arguments). This doesn't break any currently- useful cases since VOID is not used as an input argument type.
This commit is contained in:
parent
738df437b2
commit
676bb1ab06
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/protocol.sgml,v 1.58 2005/01/23 00:30:18 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/protocol.sgml,v 1.59 2005/06/22 15:19:43 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="protocol">
|
<chapter id="protocol">
|
||||||
<title>Frontend/Backend Protocol</title>
|
<title>Frontend/Backend Protocol</title>
|
||||||
@ -639,6 +639,24 @@
|
|||||||
constants.
|
constants.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
A parameter data type can be left unspecified by setting it to zero,
|
||||||
|
or by making the array of parameter type OIDs shorter than the
|
||||||
|
number of parameter symbols (<literal>$</><replaceable>n</>)
|
||||||
|
used in the query string. Another special case is that a parameter's
|
||||||
|
type can be specified as <type>void</> (that is, the OID of the
|
||||||
|
<type>void</> pseudotype). This is meant to allow parameter symbols
|
||||||
|
to be used for function parameters that are actually OUT parameters.
|
||||||
|
Ordinarily there is no context in which a <type>void</> parameter
|
||||||
|
could be used, but if such a parameter symbol appears in a function's
|
||||||
|
parameter list, it is effectively ignored. For example, a function
|
||||||
|
call such as <literal>foo($1,$2,$3,$4)</> could match a function with
|
||||||
|
two IN and two OUT arguments, if <literal>$3</> and <literal>$4</>
|
||||||
|
are specified as having type <type>void</>.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
The query string contained in a Parse message cannot include more
|
The query string contained in a Parse message cannot include more
|
||||||
@ -670,6 +688,8 @@
|
|||||||
the values to use for any parameter placeholders present in the prepared
|
the values to use for any parameter placeholders present in the prepared
|
||||||
statement. The
|
statement. The
|
||||||
supplied parameter set must match those needed by the prepared statement.
|
supplied parameter set must match those needed by the prepared statement.
|
||||||
|
(If you declared any <type>void</> parameters in the Parse message,
|
||||||
|
pass NULL values for them in the Bind message.)
|
||||||
Bind also specifies the format to use for any data returned
|
Bind also specifies the format to use for any data returned
|
||||||
by the query; the format can be specified overall, or per-column.
|
by the query; the format can be specified overall, or per-column.
|
||||||
The response is either BindComplete or ErrorResponse.
|
The response is either BindComplete or ErrorResponse.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 rettype;
|
||||||
Oid funcid;
|
Oid funcid;
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
|
ListCell *nextl;
|
||||||
Node *first_arg = NULL;
|
Node *first_arg = NULL;
|
||||||
int nargs = list_length(fargs);
|
int nargs;
|
||||||
int argn;
|
|
||||||
Oid actual_arg_types[FUNC_MAX_ARGS];
|
Oid actual_arg_types[FUNC_MAX_ARGS];
|
||||||
Oid *declared_arg_types;
|
Oid *declared_arg_types;
|
||||||
Node *retval;
|
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
|
* protect against array overruns, etc. Of course, this may not be a
|
||||||
* function, but the test doesn't hurt.
|
* function, but the test doesn't hurt.
|
||||||
*/
|
*/
|
||||||
if (nargs > FUNC_MAX_ARGS)
|
if (list_length(fargs) > FUNC_MAX_ARGS)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
|
(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
|
||||||
errmsg("cannot pass more than %d arguments to a function",
|
errmsg("cannot pass more than %d arguments to a function",
|
||||||
FUNC_MAX_ARGS)));
|
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)
|
if (fargs)
|
||||||
{
|
{
|
||||||
first_arg = linitial(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)
|
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))
|
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
|
* Okay, it's not a column projection, so it must really be a function.
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* func_get_detail looks up the function in the catalogs, does
|
* func_get_detail looks up the function in the catalogs, does
|
||||||
* disambiguation for polymorphic functions, handles inheritance, and
|
* disambiguation for polymorphic functions, handles inheritance, and
|
||||||
* returns the funcid and type and set or singleton status of the
|
* returns the funcid and type and set or singleton status of the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user