Add a hack requested by the JDBC driver writers: when a function's
authorTom Lane
Wed, 22 Jun 2005 15:19:43 +0000 (15:19 +0000)
committerTom Lane
Wed, 22 Jun 2005 15:19:43 +0000 (15:19 +0000)
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.

doc/src/sgml/protocol.sgml
src/backend/parser/parse_func.c

index a3d445e43668783ef9a58944f741c6a4d4ca456e..cd6fa0e94f0e6fccec0af3cb6ecb062bec0e8255 100644 (file)
@@ -1,4 +1,4 @@
-
+
 
 
  Frontend/Backend Protocol
       
        
         The frontend must now send a PasswordMessage containing the
-   password in clear-text form.  If
+        password in clear-text form.  If
         this is the correct password, the server responds with an
         AuthenticationOk, otherwise it responds with an ErrorResponse.
        
       
        
         The frontend must now send a PasswordMessage containing the
-   password encrypted via crypt(3), using the 2-character salt
-   specified in the AuthenticationCryptPassword message.  If
+        password encrypted via crypt(3), using the 2-character salt
+        specified in the AuthenticationCryptPassword message.  If
         this is the correct password, the server responds with an
         AuthenticationOk, otherwise it responds with an ErrorResponse.
        
       
        
         The frontend must now send a PasswordMessage containing the
-   password encrypted via MD5, using the 4-character salt
-   specified in the AuthenticationMD5Password message.  If
+        password encrypted via MD5, using the 4-character salt
+        specified in the AuthenticationMD5Password message.  If
         this is the correct password, the server responds with an
         AuthenticationOk, otherwise it responds with an ErrorResponse.
        
       
        
         This response is only possible for local Unix-domain connections
-   on platforms that support SCM credential messages.  The frontend
-   must issue an SCM credential message and then send a single data
-   byte.  (The contents of the data byte are uninteresting; it's
-   only used to ensure that the server waits long enough to receive
-   the credential message.)  If the credential is acceptable,
-   the server responds with an
+        on platforms that support SCM credential messages.  The frontend
+        must issue an SCM credential message and then send a single data
+        byte.  (The contents of the data byte are uninteresting; it's
+        only used to ensure that the server waits long enough to receive
+        the credential message.)  If the credential is acceptable,
+        the server responds with an
         AuthenticationOk, otherwise it responds with an ErrorResponse.
        
       
       
        
         Indicates that rows are about to be returned in response to
-   a SELECTFETCH, etc query.
-   The contents of this message describe the column layout of the rows.
-   This will be followed by a DataRow message for each row being returned
+        SELECTFETCH, etc query.
+        The contents of this message describe the column layout of the rows.
+        This will be followed by a DataRow message for each row being returned
         to the frontend.
        
       
       
        
         One of the set of rows returned by
-   a SELECTFETCH, etc query.
+        SELECTFETCH, etc query.
        
       
      
     constants.
    
 
+   
+    
+     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 ($n)
+     used in the query string.  Another special case is that a parameter's
+     type can be specified as void (that is, the OID of the
+     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 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 foo($1,$2,$3,$4) could match a function with
+     two IN and two OUT arguments, if $3 and $4
+     are specified as having type void.
+    
+   
+
    
     
      The query string contained in a Parse message cannot include more
     the values to use for any parameter placeholders present in the prepared
     statement.  The
     supplied parameter set must match those needed by the prepared statement.
+    (If you declared any 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
     by the query; the format can be specified overall, or per-column.
     The response is either BindComplete or ErrorResponse.
       
        
         The function call was completed and returned the result given
-   in the message.
-   (Note that the Function Call protocol can only handle a single
-   scalar result, not a row type or set of results.)
+        in the message.
+        (Note that the Function Call protocol can only handle a single
+        scalar result, not a row type or set of results.)
        
       
      
@@ -1259,10 +1279,10 @@ This section describes the base data types used in messages.
 
 
                 An n-bit integer in network byte
-       order (most significant byte first).
+                order (most significant byte first).
                 If i is specified it
                 is the exact value that will appear, otherwise the value
-       is variable.  Eg. Int16, Int32(42).
+                is variable.  Eg. Int16, Int32(42).
 
 
 
@@ -1273,11 +1293,11 @@ This section describes the base data types used in messages.
 
 
 
-       An array of k
+                An array of k
                 n-bit integers, each in network
-       byte order.  The array length k
-       is always determined by an earlier field in the message.
-       Eg. Int16[M].
+                byte order.  The array length k
+                is always determined by an earlier field in the message.
+                Eg. Int16[M].
 
 
 
@@ -1289,9 +1309,9 @@ This section describes the base data types used in messages.
 
 
                 A null-terminated string (C-style string).  There is no
-       specific length limitation on strings.
+                specific length limitation on strings.
                 If s is specified it is the exact
-       value that will appear, otherwise the value is variable.
+                value that will appear, otherwise the value is variable.
                 Eg. String, String("user").
 
                 
@@ -1314,8 +1334,8 @@ characters that don't fit into your fixed-size buffer.
 
 
                 Exactly n bytes.  If the field
-       width n is not a constant, it is
-       always determinable from an earlier field in the message.
+                width n is not a constant, it is
+                always determinable from an earlier field in the message.
                 If c is specified it is the exact
                 value.  Eg. Byte2, Byte1('\n').
 
@@ -1767,7 +1787,7 @@ Bind (F)
 
 
                 The name of the destination portal
-       (an empty string selects the unnamed portal).
+                (an empty string selects the unnamed portal).
 
 
 
@@ -1778,7 +1798,7 @@ Bind (F)
 
 
                 The name of the source prepared statement
-       (an empty string selects the unnamed prepared statement).
+                (an empty string selects the unnamed prepared statement).
 
 
 
@@ -1788,13 +1808,13 @@ Bind (F)
 
 
 
-       The number of parameter format codes that follow
-       (denoted C below).
-       This can be zero to indicate that there are no parameters
-       or that the parameters all use the default format (text);
-       or one, in which case the specified format code is applied
-       to all parameters; or it can equal the actual number of
-       parameters.
+                The number of parameter format codes that follow
+                (denoted C below).
+                This can be zero to indicate that there are no parameters
+                or that the parameters all use the default format (text);
+                or one, in which case the specified format code is applied
+                to all parameters; or it can equal the actual number of
+                parameters.
 
 
 
@@ -1805,7 +1825,7 @@ Bind (F)
 
 
                 The parameter format codes.  Each must presently be
-       zero (text) or one (binary).
+                zero (text) or one (binary).
 
 
 
@@ -1816,7 +1836,7 @@ Bind (F)
 
 
                 The number of parameter values that follow (possibly zero).
-       This must match the number of parameters needed by the query.
+                This must match the number of parameters needed by the query.
 
 
 
@@ -1830,9 +1850,9 @@ Bind (F)
 
 
                 The length of the parameter value, in bytes (this count
-       does not include itself).  Can be zero.
-       As a special case, -1 indicates a NULL parameter value.
-       No value bytes follow in the NULL case.
+                does not include itself).  Can be zero.
+                As a special case, -1 indicates a NULL parameter value.
+                No value bytes follow in the NULL case.
 
 
 
@@ -1843,7 +1863,7 @@ Bind (F)
 
 
                 The value of the parameter, in the format indicated by the
-       associated format code.
+                associated format code.
                 n is the above length.
 
 
@@ -1857,14 +1877,14 @@ Bind (F)
 
 
 
-       The number of result-column format codes that follow
-       (denoted R below).
-       This can be zero to indicate that there are no result columns
-       or that the result columns should all use the default format
-       (text); 
-       or one, in which case the specified format code is applied
-       to all result columns (if any); or it can equal the actual
-       number of result columns of the query.
+                The number of result-column format codes that follow
+                (denoted R below).
+                This can be zero to indicate that there are no result columns
+                or that the result columns should all use the default format
+                (text); 
+                or one, in which case the specified format code is applied
+                to all result columns (if any); or it can equal the actual
+                number of result columns of the query.
 
 
 
@@ -1875,7 +1895,7 @@ Bind (F)
 
 
                 The result-column format codes.  Each must presently be
-       zero (text) or one (binary).
+                zero (text) or one (binary).
 
 
 
@@ -2024,8 +2044,8 @@ Close (F)
 
 
                 The name of the prepared statement or portal to close
-       (an empty string selects the unnamed prepared statement
-       or portal).
+                (an empty string selects the unnamed prepared statement
+                or portal).
 
 
 
@@ -2115,19 +2135,19 @@ CommandComplete (B)
         rows is the number of rows
         inserted. oid is the object ID
         of the inserted row if rows is 1
-   and the target table has OIDs;
-   otherwise oid is 0.
+        and the target table has OIDs;
+        otherwise oid is 0.
        
 
        
         For a DELETE command, the tag is
-   DELETE rows where
+        DELETE rows where
         rows is the number of rows deleted.
        
 
        
         For an UPDATE command, the tag is
-   UPDATE rows where
+        UPDATE rows where
         rows is the number of rows updated.
        
 
@@ -2187,9 +2207,9 @@ CopyData (F & B)
 
 
                 Data that forms part of a COPY data stream.  Messages sent
-       from the backend will always correspond to single data rows,
-       but messages sent by frontends may divide the data stream
-       arbitrarily.
+                from the backend will always correspond to single data rows,
+                but messages sent by frontends may divide the data stream
+                arbitrarily.
 
 
 
@@ -2295,7 +2315,7 @@ CopyInResponse (B)
 
                 Identifies the message as a Start Copy In response.
                 The frontend must now send copy-in data (if not
-       prepared to do so, send a CopyFail message).
+                prepared to do so, send a CopyFail message).
 
 
 
@@ -2316,12 +2336,12 @@ CopyInResponse (B)
 
 
                 0 indicates the overall COPY format is textual (rows
-       separated by newlines, columns separated by separator
-       characters, etc).
-       1 indicates the overall copy format is binary (similar
-       to DataRow format).
-       See 
-       for more information.
+                separated by newlines, columns separated by separator
+                characters, etc).
+                1 indicates the overall copy format is binary (similar
+                to DataRow format).
+                See 
+                for more information.
 
 
 
@@ -2331,8 +2351,8 @@ CopyInResponse (B)
 
 
 
-       The number of columns in the data to be copied
-       (denoted N below).
+                The number of columns in the data to be copied
+                (denoted N below).
 
 
 
@@ -2343,8 +2363,8 @@ CopyInResponse (B)
 
 
                 The format codes to be used for each column.
-       Each must presently be zero (text) or one (binary).
-       All must be zero if the overall copy format is textual.
+                Each must presently be zero (text) or one (binary).
+                All must be zero if the overall copy format is textual.
 
 
 
@@ -2405,8 +2425,8 @@ CopyOutResponse (B)
 
 
 
-       The number of columns in the data to be copied
-       (denoted N below).
+                The number of columns in the data to be copied
+                (denoted N below).
 
 
 
@@ -2417,8 +2437,8 @@ CopyOutResponse (B)
 
 
                 The format codes to be used for each column.
-       Each must presently be zero (text) or one (binary).
-       All must be zero if the overall copy format is textual.
+                Each must presently be zero (text) or one (binary).
+                All must be zero if the overall copy format is textual.
 
 
 
@@ -2476,9 +2496,9 @@ DataRow (B)
 
 
                 The length of the column value, in bytes (this count
-       does not include itself).  Can be zero.
-       As a special case, -1 indicates a NULL column value.
-       No value bytes follow in the NULL case.
+                does not include itself).  Can be zero.
+                As a special case, -1 indicates a NULL column value.
+                No value bytes follow in the NULL case.
 
 
 
@@ -2489,7 +2509,7 @@ DataRow (B)
 
 
                 The value of the column, in the format indicated by the
-       associated format code.
+                associated format code.
                 n is the above length.
 
 
@@ -2547,8 +2567,8 @@ Describe (F)
 
 
                 The name of the prepared statement or portal to describe
-       (an empty string selects the unnamed prepared statement
-       or portal).
+                (an empty string selects the unnamed prepared statement
+                or portal).
 
 
 
@@ -2573,7 +2593,7 @@ EmptyQueryResponse (B)
 
 
                 Identifies the message as a response to an empty query string.
-       (This substitutes for CommandComplete.)
+                (This substitutes for CommandComplete.)
 
 
 
@@ -2624,8 +2644,8 @@ ErrorResponse (B)
 
 
         The message body consists of one or more identified fields,
-   followed by a zero byte as a terminator.  Fields may appear in
-   any order.  For each field there is the following:
+        followed by a zero byte as a terminator.  Fields may appear in
+        any order.  For each field there is the following:
 
 
 
@@ -2634,12 +2654,12 @@ ErrorResponse (B)
 
 
                 A code identifying the field type; if zero, this is
-       the message terminator and no string follows.
-       The presently defined field types are listed in
-       .
-       Since more field types may be added in future,
-       frontends should silently ignore fields of unrecognized
-       type.
+                the message terminator and no string follows.
+                The presently defined field types are listed in
+                .
+                Since more field types may be added in future,
+                frontends should silently ignore fields of unrecognized
+                type.
 
 
 
@@ -2695,7 +2715,7 @@ Execute (F)
 
 
                 The name of the portal to execute
-       (an empty string selects the unnamed portal).
+                (an empty string selects the unnamed portal).
 
 
 
@@ -2706,8 +2726,8 @@ Execute (F)
 
 
                 Maximum number of rows to return, if portal contains
-       a query that returns rows (ignored otherwise).  Zero
-       denotes no limit.
+                a query that returns rows (ignored otherwise).  Zero
+                denotes no limit.
 
 
 
@@ -2796,13 +2816,13 @@ FunctionCall (F)
 
 
 
-       The number of argument format codes that follow
-       (denoted C below).
-       This can be zero to indicate that there are no arguments
-       or that the arguments all use the default format (text);
-       or one, in which case the specified format code is applied
-       to all arguments; or it can equal the actual number of
-       arguments.
+                The number of argument format codes that follow
+                (denoted C below).
+                This can be zero to indicate that there are no arguments
+                or that the arguments all use the default format (text);
+                or one, in which case the specified format code is applied
+                to all arguments; or it can equal the actual number of
+                arguments.
 
 
 
@@ -2813,7 +2833,7 @@ FunctionCall (F)
 
 
                 The argument format codes.  Each must presently be
-       zero (text) or one (binary).
+                zero (text) or one (binary).
 
 
 
@@ -2838,9 +2858,9 @@ FunctionCall (F)
 
 
                 The length of the argument value, in bytes (this count
-       does not include itself).  Can be zero.
-       As a special case, -1 indicates a NULL argument value.
-       No value bytes follow in the NULL case.
+                does not include itself).  Can be zero.
+                As a special case, -1 indicates a NULL argument value.
+                No value bytes follow in the NULL case.
 
 
 
@@ -2851,7 +2871,7 @@ FunctionCall (F)
 
 
                 The value of the argument, in the format indicated by the
-       associated format code.
+                associated format code.
                 n is the above length.
 
 
@@ -2866,7 +2886,7 @@ FunctionCall (F)
 
 
                 The format code for the function result. Must presently be
-       zero (text) or one (binary).
+                zero (text) or one (binary).
 
 
 
@@ -2912,9 +2932,9 @@ FunctionCallResponse (B)
 
 
                 The length of the function result value, in bytes (this count
-       does not include itself).  Can be zero.
-       As a special case, -1 indicates a NULL function result.
-       No value bytes follow in the NULL case.
+                does not include itself).  Can be zero.
+                As a special case, -1 indicates a NULL function result.
+                No value bytes follow in the NULL case.
 
 
 
@@ -2925,7 +2945,7 @@ FunctionCallResponse (B)
 
 
                 The value of the function result, in the format indicated by
-       the associated format code.
+                the associated format code.
                 n is the above length.
 
 
@@ -3002,8 +3022,8 @@ NoticeResponse (B)
 
 
         The message body consists of one or more identified fields,
-   followed by a zero byte as a terminator.  Fields may appear in
-   any order.  For each field there is the following:
+        followed by a zero byte as a terminator.  Fields may appear in
+        any order.  For each field there is the following:
 
 
 
@@ -3012,12 +3032,12 @@ NoticeResponse (B)
 
 
                 A code identifying the field type; if zero, this is
-       the message terminator and no string follows.
-       The presently defined field types are listed in
-       .
-       Since more field types may be added in future,
-       frontends should silently ignore fields of unrecognized
-       type.
+                the message terminator and no string follows.
+                The presently defined field types are listed in
+                .
+                Since more field types may be added in future,
+                frontends should silently ignore fields of unrecognized
+                type.
 
 
 
@@ -3093,8 +3113,8 @@ NotificationResponse (B)
 
 
                 Additional information passed from the notifying process.
-       (Currently, this feature is unimplemented so the field
-       is always an empty string.)
+                (Currently, this feature is unimplemented so the field
+                is always an empty string.)
 
 
 
@@ -3140,7 +3160,7 @@ ParameterDescription (B)
 
 
                 The number of parameters used by the statement
-       (may be zero).
+                (may be zero).
 
 
 
@@ -3252,7 +3272,7 @@ Parse (F)
 
 
                 The name of the destination prepared statement
-       (an empty string selects the unnamed prepared statement).
+                (an empty string selects the unnamed prepared statement).
 
 
 
@@ -3273,10 +3293,10 @@ Parse (F)
 
 
                 The number of parameter data types specified
-       (may be zero).  Note that this is not an indication of
-       the number of parameters that might appear in the
-       query string, only the number that the frontend wants to
-       prespecify types for.
+                (may be zero).  Note that this is not an indication of
+                the number of parameters that might appear in the
+                query string, only the number that the frontend wants to
+                prespecify types for.
 
 
 
@@ -3290,8 +3310,8 @@ Parse (F)
 
 
                 Specifies the object ID of the parameter data type.
-       Placing a zero here is equivalent to leaving the type
-       unspecified.
+                Placing a zero here is equivalent to leaving the type
+                unspecified.
 
 
 
@@ -3395,8 +3415,8 @@ PortalSuspended (B)
 
 
                 Identifies the message as a portal-suspended indicator.
-       Note this only appears if an Execute message's row-count limit
-       was reached.
+                Note this only appears if an Execute message's row-count limit
+                was reached.
 
 
 
@@ -3498,10 +3518,10 @@ ReadyForQuery (B)
 
 
                 Current backend transaction status indicator.
-       Possible values are 'I' if idle (not in
-       a transaction block); 'T' if in a transaction
-       block; or 'E' if in a failed transaction
-       block (queries will be rejected until block is ended).
+                Possible values are 'I' if idle (not in
+                a transaction block); 'T' if in a transaction
+                block; or 'E' if in a failed transaction
+                block (queries will be rejected until block is ended).
 
 
 
@@ -3570,7 +3590,7 @@ RowDescription (B)
 
 
                 If the field can be identified as a column of a specific
-       table, the object ID of the table; otherwise zero.
+                table, the object ID of the table; otherwise zero.
 
 
 
@@ -3581,7 +3601,7 @@ RowDescription (B)
 
 
                 If the field can be identified as a column of a specific
-       table, the attribute number of the column; otherwise zero.
+                table, the attribute number of the column; otherwise zero.
 
 
 
@@ -3602,7 +3622,7 @@ RowDescription (B)
 
 
                 The data type size (see pg_type.typlen).
-       Note that negative values denote variable-width types.
+                Note that negative values denote variable-width types.
 
 
 
@@ -3613,7 +3633,7 @@ RowDescription (B)
 
 
                 The type modifier (see pg_attribute.atttypmod).
-       The meaning of the modifier is type-specific.
+                The meaning of the modifier is type-specific.
 
 
 
@@ -3624,9 +3644,9 @@ RowDescription (B)
 
 
                 The format code being used for the field.  Currently will
-       be zero (text) or one (binary).  In a RowDescription
-       returned from the statement variant of Describe, the
-       format code is not yet known and will always be zero.
+                be zero (text) or one (binary).  In a RowDescription
+                returned from the statement variant of Describe, the
+                format code is not yet known and will always be zero.
 
 
 
@@ -3701,18 +3721,18 @@ StartupMessage (F)
 
                 The protocol version number.  The most significant 16 bits are
                 the major version number (3 for the protocol described here).
-       The least significant 16 bits are the minor version number
-       (0 for the protocol described here).
+                The least significant 16 bits are the minor version number
+                (0 for the protocol described here).
 
 
 
 
         The protocol version number is followed by one or more pairs of
-   parameter name and value strings.  A zero byte is required as a
-   terminator after the last name/value pair.
-   Parameters can appear in any
-   order.  user is required, others are optional.
-   Each parameter is specified as:
+        parameter name and value strings.  A zero byte is required as a
+        terminator after the last name/value pair.
+        Parameters can appear in any
+        order.  user is required, others are optional.
+        Each parameter is specified as:
 
 
 
@@ -3730,7 +3750,7 @@ StartupMessage (F)
 
 
                         The database user name to connect as.  Required;
-           there is no default.
+                        there is no default.
 
 
 
@@ -3751,18 +3771,18 @@ StartupMessage (F)
 
 
                         Command-line arguments for the backend.  (This is
-           deprecated in favor of setting individual run-time
-           parameters.)
+                        deprecated in favor of setting individual run-time
+                        parameters.)
 
 
 
 
 
                 In addition to the above, any run-time parameter that can be
-       set at backend start time may be listed.  Such settings
-       will be applied during backend start (after parsing the
-       command-line options if any).  The values will act as
-       session defaults.
+                set at backend start time may be listed.  Such settings
+                will be applied during backend start (after parsing the
+                command-line options if any).  The values will act as
+                session defaults.
 
 
 
@@ -3879,9 +3899,9 @@ message.
         Severity: the field contents are
         ERROR, FATAL, or
         PANIC (in an error message), or
-   WARNING, NOTICE, DEBUG,
-   INFO, or LOG (in a notice message),
-   or a localized translation of one of these.  Always present.
+        WARNING, NOTICE, DEBUG,
+        INFO, or LOG (in a notice message),
+        or a localized translation of one of these.  Always present.
 
 
 
@@ -3893,7 +3913,7 @@ message.
 
 
         Code: the SQLSTATE code for the error (see 
-   linkend="errcodes-appendix">).  Not localizable.  Always present.
+        linkend="errcodes-appendix">).  Not localizable.  Always present.
 
 
 
@@ -3930,9 +3950,9 @@ message.
 
 
         Hint: an optional suggestion what to do about the problem.
-   This is intended to differ from Detail in that it offers advice
-   (potentially inappropriate) rather than hard facts.
-   May run to multiple lines.
+        This is intended to differ from Detail in that it offers advice
+        (potentially inappropriate) rather than hard facts.
+        May run to multiple lines.
 
 
 
@@ -3944,9 +3964,9 @@ message.
 
 
         Position: the field value is a decimal ASCII integer, indicating
-   an error cursor position as an index into the original query string.
-   The first character has index 1, and positions are measured in
-   characters not bytes.
+        an error cursor position as an index into the original query string.
+        The first character has index 1, and positions are measured in
+        characters not bytes.
 
 
 
@@ -3998,7 +4018,7 @@ message.
 
 
         File: the file name of the source-code location where the error
-   was reported.
+        was reported.
 
 
 
@@ -4010,7 +4030,7 @@ message.
 
 
         Line: the line number of the source-code location where the error
-   was reported.
+        was reported.
 
 
 
index e585e6df716b31a89595a58ec1c8ff01a51ca07b..88132bdbd58323cc44e88a818843b025dc738d56 100644 (file)
@@ -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