"A block containing an EXCEPTION clause is significantly more expensive to enter and exit than a block without one"

From: Bryn Llewellyn <bryn(at)yugabyte(dot)com>
To: pgsql-general list <pgsql-general(at)lists(dot)postgresql(dot)org>
Cc: Tom Lane PostgreSQL <tgl(at)sss(dot)pgh(dot)pa(dot)us>, "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>
Subject: "A block containing an EXCEPTION clause is significantly more expensive to enter and exit than a block without one"
Date: 2022-06-13 05:43:16
Message-ID: 24CD0FA6-F58C-44B5-B3D5-FE704A63E5CA@yugabyte.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Does the “Tip” call-out box, from which the “Subject” here is copied, and the larger story that I copied below, apply even when the executable section of the block statement in question does nothing at all that could be rolled back?

This is my block:

begin
year_as_int := year_as_text;
exception
when invalid_text_representation then
bad_integer := true;
end;

The typecast to integer will cause an error if the input text does not represent an integer. I need to detect this, when I get such a text value, and then go on to do something appropriate after the block. My tests show that I get exactly the behavior that I want. It would be tedious to program the test (presumably by typecasting to a numeric value and comparing that with the result of rounding it) to avoid the "significant" performance penalty that the doc describes.

It seems to me that the PG implementation has, in a block that has an exception section, an opportunity to wait to start a subtraction until it first hits a statement whose effect could be rolled back—and, of course, not do this if it doesn't hit such a statement. I see that this would require first preparing the statement and only then, if it needs it, starting its subtransaction. But this sounds doable.
________________________________________________________________________________

The current PL/pgSQL doc, in this section:

43.6.8. Trapping Errors
https://www.postgresql.org/docs/current/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING <https://www.postgresql.org/docs/current/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING>
says this:

> When an error is caught by an EXCEPTION clause, the local variables of the PL/pgSQL function remain as they were when the error occurred, but all changes to persistent database state within the block are rolled back.
> …
> A block containing an EXCEPTION clause is significantly more expensive to enter and exit than a block without one. Therefore, don't use EXCEPTION without need.

and then on Stack Overflow, here
https://stackoverflow.com/questions/46409856/why-is-catching-errors-inside-a-loop-causing-performance-issues <https://stackoverflow.com/questions/46409856/why-is-catching-errors-inside-a-loop-causing-performance-issues>

Tom Lane said:

> Yeah, it's about the overhead of setting up and ending a subtransaction. That's a fairly expensive mechanism, but we don't have anything cheaper that is able to recover from arbitrary errors.

and David G. Johnston said:

> Setting up the pl/pgsql execution layer to trap "arbitrary SQL-layer exceptions"​ is fairly expensive. Even if the user specifies specific errors the error handling mechanism in pl/pgsql is code for generic (arbitrary) errors being given to it.

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Pavel Stehule 2022-06-13 06:07:01 Re: "A block containing an EXCEPTION clause is significantly more expensive to enter and exit than a block without one"
Previous Message Noah Misch 2022-06-13 03:45:51 Re: Extension pg_trgm, permissions and pg_dump order