aboutsummaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-11-04 13:25:39 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2018-11-04 13:25:39 -0500
commit15c7293477a6de03234f58898da7fb29f3ab5b94 (patch)
tree5905c47b65a619b546b19382013f19d7bec0ce5c /doc/src
parent3e0b05a75673f0ad73d5487efe814485a9fcf68f (diff)
downloadpostgresql-15c7293477a6de03234f58898da7fb29f3ab5b94.tar.gz
postgresql-15c7293477a6de03234f58898da7fb29f3ab5b94.zip
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
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/sgml/plpgsql.sgml34
-rw-r--r--doc/src/sgml/ref/call.sgml11
2 files changed, 36 insertions, 9 deletions
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
index 4344ceadbe4..beb7e03bbcf 100644
--- a/doc/src/sgml/plpgsql.sgml
+++ b/doc/src/sgml/plpgsql.sgml
@@ -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>
diff --git a/doc/src/sgml/ref/call.sgml b/doc/src/sgml/ref/call.sgml
index 7418e19eeba..abaa81c78b9 100644
--- a/doc/src/sgml/ref/call.sgml
+++ b/doc/src/sgml/ref/call.sgml
@@ -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>