Hi hackers,

   The current usage PG_TRY() looks something like this:

   ... normal code ...

   PG_TRY();
   {
       ... code that might throw ereport(ERROR) ...
   }
   PG_CATCH();
   {
       ... error recovery code ...
       ... plus anything that you wish to do even if an error wasn't thrown
...
           (because of a PG_RE_THROW possibility)
   }
   PG_END_TRY();

   ... do the same thing over again; since either no ERROR or no RE_THROW()
...

   ... normal code ...

I propose a new constuct, PG_FINALLY. This will help in eliminating code
duplication (hence lesser possibility of errors), and better modularity. It
will also help if someone wishes to call a non-idempotent function in the
now-repeating code.

#define PG_TRY()                                                        \
   do {                                                                \
       sigjmp_buf *save_exception_stack = PG_exception_stack;          \
       ErrorContextCallback *save_context_stack = error_context_stack; \
       bool do_re_throw = false;                                       \
       sigjmp_buf local_sigjmp_buf;                                    \
       if (sigsetjmp(local_sigjmp_buf, 0) == 0)                        \
       {                                                               \
           PG_exception_stack = &local_sigjmp_buf

#define PG_CATCH()                                                      \
       }                                                               \
       else                                                            \
       {                                                               \

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

#define PG_END_TRY()                                                    \
       }                                                               \
       if (do_re_throw)                                                \
           siglongjmp(*PG_exception_stack, 1)                          \
   } while (0)

#define PG_RE_THROW()   do_re_throw = true

This would change the semantics to:

   ... normal code ...

   PG_TRY();
   {
       ... code that might throw ereport(ERROR) ...
   }
   PG_CATCH();
   {
       ... (optional) error recovery code only *and/or* RE_THROW...
   }
   PG_FINALLY();
   {
       ... do something that you wanted done in any case; ERROR or not ...
   }
   PG_END_TRY();

   ... normal code ...

Hope to find buyers.

Best regards,

--
[EMAIL PROTECTED]
[EMAIL PROTECTED] gmail | hotmail | yahoo }.com

Reply via email to