Re: "A transaction cannot be ended inside a block with exception handlers."

From: "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>
To: Bryn Llewellyn <bryn(at)yugabyte(dot)com>
Cc: Tom Lane PostgreSQL <tgl(at)sss(dot)pgh(dot)pa(dot)us>, pgsql-general list <pgsql-general(at)lists(dot)postgresql(dot)org>
Subject: Re: "A transaction cannot be ended inside a block with exception handlers."
Date: 2022-05-07 04:46:34
Message-ID: CAKFQuwYPOAZPs9Kzsm-EBn-DBC3Ep-6LRkkQLJj+k9-GQRgXvw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

I do understand better now and indeed the current limitation has no
workaround that I can come up with. I was hoping maybe subblocks would
work but its pretty clear cut that to catch an error at the commit command
you must catch it within a block and the commit error will be raised first.

On Fri, May 6, 2022 at 9:23 PM Bryn Llewellyn <bryn(at)yugabyte(dot)com> wrote:

>
> I'll take this to mean that there is no plan for PG ever to allow txn
> control in a PL/pgSQL block that has an exception handler. Please tell me
> if I misunderstood.
>

You misunderstand how the development of PostgreSQL works generally. But,
I suppose as a practical matter if you aren't going to spearhead the change
you might as well assume it will not be possible until it is.

> Is there really no sympathy for what I want to achieve?
>

I personally have sympathy, and if you submitted a patch to improve matters
here I don't see anyone saying that it would be unwanted.
As for the circular dependency breaking use of deferred constraints (or
your explicitly deferred triggers), you have the SET CONSTRAINTS ALL
IMMEDIATE command:

postgres=# call do_insert(false);
ERROR: tigger trg caused exception
CONTEXT: PL/pgSQL function trg_fn() line 9 at ASSERT
SQL statement "SET CONSTRAINTS ALL IMMEDIATE"
PL/pgSQL function do_insert(boolean) line 12 at SQL statement
postgres=# create or replace procedure do_insert(good in boolean)
language plpgsql
as $body$
begin
begin
case good
when true then
for j in 10..20 loop
insert into t(k) values(j);
end loop;
when false then
insert into t(k) values(42);
end case;
SET CONSTRAINTS ALL IMMEDIATE;
commit;
end;
exception
when invalid_transaction_termination then
raise exception 'caught invalid';
when OTHERS then
raise notice 'others - ok';
commit;
end;

David J.

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Guillaume Lelarge 2022-05-07 07:36:17 Re: pg_dump: VACUUM and REINDEXING
Previous Message Bryn Llewellyn 2022-05-07 04:23:13 Re: "A transaction cannot be ended inside a block with exception handlers."