Re: alternative to PG_CATCH - Mailing list pgsql-hackers

From Kyotaro HORIGUCHI
Subject Re: alternative to PG_CATCH
Date
Msg-id 20181213.212622.115101304.horiguchi.kyotaro@lab.ntt.co.jp
Whole thread Raw
In response to alternative to PG_CATCH  (Peter Eisentraut <peter.eisentraut@2ndquadrant.com>)
Responses Re: alternative to PG_CATCH  (David Steele <david@pgmasters.net>)
Re: alternative to PG_CATCH  (Peter Eisentraut <peter.eisentraut@2ndquadrant.com>)
List pgsql-hackers
At Thu, 13 Dec 2018 11:33:39 +0100, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote in
<c170919d-c78b-3dac-5ff6-9bd12f7a38bc@2ndquadrant.com>
> This is a common pattern:
> 
>     PG_TRY();
>     {
>         ... code that might throw ereport(ERROR) ...
>     }
>     PG_CATCH();
>     {
>         cleanup();
>         PG_RE_THROW();
>     }
>     PG_END_TRY();
>     cleanup();  /* the same as above */
> 
> I've played with a way to express this more compactly:
> 
>     PG_TRY();
>     {
>         ... code that might throw ereport(ERROR) ...
>     }
>     PG_FINALLY({
>         cleanup();
>     });
> 
> See attached patch for how this works out in practice.
> 
> Thoughts?  Other ideas?
> 
> One problem is that this currently makes pgindent crash.  That's
> probably worth fixing anyway.  Or perhaps find a way to write this
> differently.

Though I didn't look into individual change, this kind of
refactoring looks good to me. But the syntax looks
somewhat.. uh..

I'm not sure it is actually workable, but I suspect that what we
need here is just a shortcut of 'PG_CATCH();{PG_RE_THROW();}'.
Something like this:

#define PG_FINALLY()    \
        } \
        else \
        { \
            PG_exception_stack = save_exception_stack; \
            error_context_stack = save_context_stack; \
            PG_RE_THROW();        \
        } \
        PG_exception_stack = save_exception_stack;    \
        error_context_stack = save_context_stack; \
        {

Which can be used as:

PG_TRY();
{
    ... code that might throw ereport(ERROR) ...
}
PG_FINALLY();
{
    cleanup();
}
PG_TRY_END();


Or


#define PG_END_TRY_CATCHING_ALL()  \
        PG_FINALLY(); \
        PG_END_TRY();

PG_TRY();
{
    ... code that might throw ereport(ERROR) ...
}
PG_END_TRY_CATCHING_ALL();

cleanup();



regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center



pgsql-hackers by date:

Previous
From: Alexander Korotkov
Date:
Subject: Re: Connections hang indefinitely while taking a gin index's LWLockbuffer_content lock
Next
From: Andreas Karlsson
Date:
Subject: Re: Introducing SNI in TLS handshake for SSL connections