1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-31 22:04:40 +03:00

PL/pgSQL: Nested CALL with transactions

So far, a nested CALL or DO in PL/pgSQL would not establish a context
where transaction control statements were allowed.  This fixes that by
handling CALL and DO specially in PL/pgSQL, passing the atomic/nonatomic
execution context through and doing the required management around
transaction boundaries.

Reviewed-by: Tomas Vondra <tomas.vondra@2ndquadrant.com>
This commit is contained in:
Peter Eisentraut
2018-03-24 10:05:06 -04:00
parent c2d4eb1b1f
commit d92bc83c48
13 changed files with 235 additions and 59 deletions

View File

@ -3463,9 +3463,9 @@ END LOOP <optional> <replaceable>label</replaceable> </optional>;
<title>Transaction Management</title>
<para>
In procedures invoked by the <command>CALL</command> command from the top
level as well as in anonymous code blocks (<command>DO</command> command)
called from the top level, it is possible to end transactions using the
In procedures invoked by the <command>CALL</command> command
as well as in anonymous code blocks (<command>DO</command> command),
it is possible to end transactions using the
commands <command>COMMIT</command> and <command>ROLLBACK</command>. A new
transaction is started automatically after a transaction is ended using
these commands, so there is no separate <command>START
@ -3495,6 +3495,20 @@ CALL transaction_test1();
</programlisting>
</para>
<para>
Transaction control is only possible in <command>CALL</command> or
<command>DO</command> invocations from the top level or nested
<command>CALL</command> or <command>DO</command> invocations without any
other intervening command. For example, if the call stack is
<command>CALL proc1()</command> &rarr; <command>CALL proc2()</command>
&rarr; <command>CALL proc3()</command>, then the second and third
procedures can perform transaction control actions. But if the call stack
is <command>CALL proc1()</command> &rarr; <command>SELECT
func2()</command> &rarr; <command>CALL proc3()</command>, then the last
procedure cannot do transaction control, because of the
<command>SELECT</command> in between.
</para>
<para>
A transaction cannot be ended inside a loop over a query result, nor
inside a block with exception handlers.