Обсуждение: BUG #2108: Function with OUT parameters not recognized, using plpgsql

Поиск
Список
Период
Сортировка

BUG #2108: Function with OUT parameters not recognized, using plpgsql

От
"Tony"
Дата:
The following bug has been logged online:

Bug reference:      2108
Logged by:          Tony
Email address:      tony@vectorsalad.com
PostgreSQL version: 8.1.0
Operating system:   Debian 1:3.3.5-8ubuntu2, 2.6.10-5-k7, i686
Description:        Function with OUT parameters not recognized, using
plpgsql
Details:

Defined a function with OUT paramter.  Attempts to call it fail as the
function can not be found.

Example:

<code>

CREATE OR REPLACE FUNCTION f_multiparam (
  i1 integer,
  i2 varchar,
  OUT o1 varchar
) AS
$$
BEGIN
  o1 := 'i2 was ' || i2;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION f_showperformstatus () RETURNS varchar AS
$$
DECLARE
  outparameter varchar;
BEGIN
  PERFORM f_multiparam(1, 'hello', outparameter);
  RETURN 'successfully run';
END;
$$
LANGUAGE plpgsql;

select f_showperformstatus();

</code>

Output:

CREATE FUNCTION
CREATE FUNCTION
psql:bug2.sql:24: ERROR:  function f_multiparam(integer, "unknown",
character varying) does not exist
HINT:  No function matches the given name and argument types. You may need
to add explicit type casts.
CONTEXT:  SQL statement "SELECT  f_multiparam(1, 'hello',  $1 )"
PL/pgSQL function "f_showperformstatus" line 4 at perform

It appears that the function is not defined properly in the system, with
only 2 parameters instead of 3:

\df f_multiparam
                           List of functions
 Schema |     Name     | Result data type  |    Argument data types
--------+--------------+-------------------+----------------------------
 apps   | f_multiparam | character varying | integer, character varying


Explicitly casting the value 'hello' as suggested does not help.  Changing
the function definition from OUT to INOUT parameter is a successful
workaround.

Re: BUG #2108: Function with OUT parameters not recognized, using plpgsql

От
Tom Lane
Дата:
"Tony" <tony@vectorsalad.com> writes:
> Defined a function with OUT paramter.  Attempts to call it fail as the
> function can not be found.

Apparently, you don't understand how OUT parameters work either :-(
Perhaps the examples here will help:
http://www.postgresql.org/docs/8.1/static/xfunc-sql.html#XFUNC-OUTPUT-PARAMETERS

            regards, tom lane

Re: BUG #2108: Function with OUT parameters not recognized, using plpgsql

От
Alvaro Herrera
Дата:
Tony wrote:

> CREATE OR REPLACE FUNCTION f_multiparam (
>   i1 integer,
>   i2 varchar,
>   OUT o1 varchar
> ) AS
> $$
> BEGIN
>   o1 := 'i2 was ' || i2;
> END;
> $$
> LANGUAGE plpgsql;
>
> CREATE OR REPLACE FUNCTION f_showperformstatus () RETURNS varchar AS
> $$
> DECLARE
>   outparameter varchar;
> BEGIN
>   PERFORM f_multiparam(1, 'hello', outparameter);
>   RETURN 'successfully run';
> END;
> $$
> LANGUAGE plpgsql;

You are misunderstanding how are functions with OUT params supposed to
be called, I think.  Try this:

 CREATE OR REPLACE FUNCTION f_multiparam (
   i1 integer,
   i2 varchar,
   OUT o1 varchar
 ) AS
 $$
 BEGIN
   o1 := 'i2 was ' || i2;
 END;
 $$
 LANGUAGE plpgsql;

 CREATE OR REPLACE FUNCTION f_showperformstatus () RETURNS varchar AS
 $$
 DECLARE
   outparameter varchar;
 BEGIN
   SELECT INTO outparameter f_multiparam(1, 'hello');
   RAISE NOTICE 'the out param is %', outparameter;
   RETURN 'successfully run';
 END;
 $$
 LANGUAGE plpgsql;


The output I get is what I'd expect:

alvherre=# select f_showperformstatus();
NOTICE:  the out param is i2 was hello
 f_showperformstatus
---------------------
 successfully run
(1 fila)



I think this also applies to your INOUT report, but I haven't checked.

--
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

Re: BUG #2108: Function with OUT parameters not recognized,

От
Tony S
Дата:
Alvaro Herrera wrote:
> Stallone wrote:
>
> Please keep replies on the list.
>
>
>>What you have done is run a SELECT which evaluates the function
>>f_multiparam() passing it two parameters, and then takes the result and
>>puts it INTO a local parameter.  This is not the same.  An OUT parameter
>>is actually passed to the function and is part of the function
>>specification, in this case it is defined as the third parameter.  It's
>>like a placeholder within the definition of the function itself, and it
>>should show up on the list of parameters for that function.  You can, in
>>fact, have many OUT parameters in one function.  This is an advantage of
>>out parameters over just a plain function with a single RETURN element.
>>
>>At least this is how it has always worked for me.
>
>
> Has always worked where?  In Postgres?  It's strange that you mention
> "always" because OUT parameters are new in Postgres 8.1.  Behavior in
> other database systems is not directly applicable to Postgres.
>
> Keep in mind that in Postgres we don't have host variables, which is
> what is needed to make OUT params work the way you are assuming they do.
> This could be improved in the future but currently that's the way it is.
>

I have seriously mistaken the nature of IN/OUT parameters in Postgres.

This misunderstanding all leaked over from Oracle and is not applicable
at all here.  Maybe this might make a good bullet point to add in Sec
36.11 "Porting from Oracle PL/SQL".  I will post a note separately there.