Re: try/catch macros for Postgres backend

Поиск
Список
Период
Сортировка
От Gavin Sherry
Тема Re: try/catch macros for Postgres backend
Дата
Msg-id Pine.LNX.4.58.0407291326260.625@linuxworld.com.au
обсуждение исходный текст
Ответ на try/catch macros for Postgres backend  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-hackers
On Wed, 28 Jul 2004, Tom Lane wrote:

> In service of the refactoring of error handling that I was talking about
> a few days ago, I'm finding that there are several places that really
> ought to catch longjmps and clean up after themselves, instead of
> expecting that whatever mess they've made will be cleaned up for them
> when control gets back to PostgresMain().  If we have functions that can
> catch errors, control might *not* go right back to PostgresMain(), and
> so throwing random cleanup actions into the sigsetjmp branch there is
> No Good.
>
> This is no big deal since pltcl and plpython already do much the same
> thing, but I'm starting to think that instead of directly hacking on
> Warn_restart, it would be good to have some macros hiding the details.
> The syntax I'm toying with is
>
>     PG_TRY();
>     {
>         ... code that might elog ...
>     }
>     PG_CATCH();
>     {
>         ... recovery code here ...
>         PG_RE_THROW();        // optional
>     }
>     PG_END_CATCH();

Cool.

[snip]

> Also, the memcpy technique for saving/restoring Warn_restart is what
> pltcl and plpython currently use, and it works, but it seems
> unnecessarily inefficient.  A further improvement would be to replace
> Warn_restart by a pointer defined like
>     extern sigjmp_buf *exception_stack_top;
>
> and then the macro expansion would be something more like
>
>     do {
>         sigjmp_buf *save_exception_stack = exception_stack_top;
>         sigjmp_buf local_sigjmp_buf;
>
>         if (sigsetjmp(local_sigjmp_buf) == 0)
>         {
>             exception_stack_top = &local_sigjmp_buf;
>             ... code that might elog ...
>             exception_stack_top = save_exception_stack;
>         }
>         else
>         {
>             exception_stack_top = save_exception_stack;
>             ... recovery code here ...
>         }
>
>     } while(0)

I've been thinking about is allow users to trigger named exceptions in
PL/PgSQL. This would work something like this:

CREATE FUNCTION ....
DECLAREinvalid EXCEPTION;count INT;
BEGINSELECT INTO count COUNT(*) FROM ...IF count < 10 -- we shouldn't have been called    RAISE EXCEPTION invalid;

...

EXCEPTIONWHEN invalid THEN    ....ELSE    RAISE NOTICE 'Unknown exception raised';
END...

Another thing I've been thinking about is if an error is generated in
PL/PgSQL, what state is the system in when control is handed to the
excecption handler? That is, should we roll back to the state at the start
of the function? most recent save point?

Another thing I like about exceptions in some languages is the ability for
a subroutine to generate an exception, hand control back to the caller and
have the caller raise the exception. I'm wondering how hard that would be
in PL/PgSQL?

These are specific to PL/PgSQL and we may need something specific to that
code but I thought I'd raise these thoughts now as I intend to work on
them for 7.6.

Thanks,

Gavin


В списке pgsql-hackers по дате отправления:

Предыдущее
От: Tom Lane
Дата:
Сообщение: try/catch macros for Postgres backend
Следующее
От: Alvaro Herrera Munoz
Дата:
Сообщение: Re: try/catch macros for Postgres backend