mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Fix bugs in plpgsql's handling of CALL argument lists.
exec_stmt_call() tried to extract information out of a CALL statement's argument list without using expand_function_arguments(), apparently in the hope of saving a few nanoseconds by not processing defaulted arguments. It got that quite wrong though, leading to crashes with named arguments, as well as failure to enforce writability of the argument for a defaulted INOUT parameter. Fix and simplify the logic by using expand_function_arguments() before examining the list. Also, move the argument-examination to just after producing the CALL command's plan, before invoking the called procedure. This ensures that we'll track possible changes in the procedure's argument list correctly, and avoids a hazard of the plan cache being flushed while the procedure executes. Also fix assorted falsehoods and omissions in associated documentation. Per bug #15477 from Alexey Stepanov. Patch by me, with some help from Pavel Stehule. Back-patch to v11. Discussion: https://postgr.es/m/15477-86075b1d1d319e0a@postgresql.org Discussion: https://postgr.es/m/CAFj8pRA6UsujpTs9Sdwmk-R6yQykPx46wgjj+YZ7zxm4onrDyw@mail.gmail.com
This commit is contained in:
@ -1864,15 +1864,29 @@ SELECT * FROM get_available_flightid(CURRENT_DATE);
|
||||
|
||||
<para>
|
||||
A procedure does not have a return value. A procedure can therefore end
|
||||
without a <command>RETURN</command> statement. If
|
||||
a <command>RETURN</command> statement is desired to exit the code early,
|
||||
then <symbol>NULL</symbol> must be returned. Returning any other value
|
||||
will result in an error.
|
||||
without a <command>RETURN</command> statement. If you wish to use
|
||||
a <command>RETURN</command> statement to exit the code early, write
|
||||
just <command>RETURN</command> with no expression.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If a procedure has output parameters, then the output values can be
|
||||
assigned to the parameters as if they were variables. For example:
|
||||
If the procedure has output parameters, the final values of the output
|
||||
parameter variables will be returned to the caller.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="plpgsql-statements-calling-procedure">
|
||||
<title>Calling a Procedure</title>
|
||||
|
||||
<para>
|
||||
A <application>PL/pgSQL</application> function, procedure,
|
||||
or <command>DO</command> block can call a procedure
|
||||
using <command>CALL</command>. Output parameters are handled
|
||||
differently from the way that <command>CALL</command> works in plain
|
||||
SQL. Each <literal>INOUT</literal> parameter of the procedure must
|
||||
correspond to a variable in the <command>CALL</command> statement, and
|
||||
whatever the procedure returns is assigned back to that variable after
|
||||
it returns. For example:
|
||||
<programlisting>
|
||||
CREATE PROCEDURE triple(INOUT x int)
|
||||
LANGUAGE plpgsql
|
||||
@ -1882,7 +1896,13 @@ BEGIN
|
||||
END;
|
||||
$$;
|
||||
|
||||
CALL triple(5);
|
||||
DO $$
|
||||
DECLARE myvar int := 5;
|
||||
BEGIN
|
||||
CALL triple(myvar);
|
||||
RAISE NOTICE 'myvar = %', myvar; -- prints 15
|
||||
END
|
||||
$$;
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect2>
|
||||
|
@ -33,7 +33,8 @@ CALL <replaceable class="parameter">name</replaceable> ( [ <replaceable class="p
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the procedure has output arguments, then a result row will be returned.
|
||||
If the procedure has any output parameters, then a result row will be
|
||||
returned, containing the values of those parameters.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
@ -54,7 +55,7 @@ CALL <replaceable class="parameter">name</replaceable> ( [ <replaceable class="p
|
||||
<term><replaceable class="parameter">argument</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
An argument for the procedure call.
|
||||
An input argument for the procedure call.
|
||||
See <xref linkend="sql-syntax-calling-funcs"/> for the full details on
|
||||
function and procedure call syntax, including use of named parameters.
|
||||
</para>
|
||||
@ -81,6 +82,12 @@ CALL <replaceable class="parameter">name</replaceable> ( [ <replaceable class="p
|
||||
Transaction control statements are only allowed if <command>CALL</command>
|
||||
is executed in its own transaction.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<application>PL/pgSQL</application> handles output parameters
|
||||
in <command>CALL</command> commands differently;
|
||||
see <xref linkend="plpgsql-statements-calling-procedure"/>.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
Reference in New Issue
Block a user