A suggestion on PG_TRY() exception handling code. - Mailing list pgsql-hackers
From | Gurjeet Singh |
---|---|
Subject | A suggestion on PG_TRY() exception handling code. |
Date | |
Msg-id | 65937bea0611161350n5b55dcc6w18d0210e490817e8@mail.gmail.com Whole thread Raw |
Responses |
Re: A suggestion on PG_TRY() exception handling code.
|
List | pgsql-hackers |
Hi hackers,<br /><br /> The current usage PG_TRY() looks something like this:<br /><br /><span style="font-family: couriernew,monospace;"> ... normal code ...<br /><br /> PG_TRY();</span><br style="font-family: courier new,monospace;"/><span style="font-family: courier new,monospace;"> {</span><br style="font-family: courier new,monospace;"/><span style="font-family: courier new,monospace;"> ... code that might throw ereport(ERROR) ...</span><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> }</span><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> PG_CATCH();</span><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> {</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> ... error recovery code ...</span><br style="font-family: courier new,monospace;" /><span style="font-family:courier new,monospace;"> ... plus anything that you wish to do even if an error wasn't thrown ...</span><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> (because of a PG_RE_THROW possibility)</span><br style="font-family: courier new,monospace;" /><span style="font-family:courier new,monospace;"> }</span><br style="font-family: courier new,monospace;" /><span style="font-family:courier new,monospace;"> PG_END_TRY();<br /><br /> ... do the same thing over again; since eitherno ERROR or no RE_THROW() ...<br /></span><br clear="all" /><span style="font-family: courier new,monospace;"> ...normal code ...<br /><br /></span>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-idempotentfunction in the now-repeating code. <br /><br /><span style="font-family: courier new,monospace;">#define PG_TRY() \</span><br style="font-family: courier new,monospace;" /><spanstyle="font-family: courier new,monospace;"> do { \</span><br style="font-family: courier new,monospace;" /><spanstyle="font-family: courier new,monospace;"> sigjmp_buf *save_exception_stack = PG_exception_stack; \ </span><br style="font-family: courier new,monospace;" /><span style="font-family: couriernew,monospace;"> ErrorContextCallback *save_context_stack = error_context_stack; \</span><br style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;"> bool do_re_throw =false; \</span><br style="font-family: courier new,monospace;" /><span style="font-family:courier new,monospace;"> sigjmp_buf local_sigjmp_buf; \</span><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> if (sigsetjmp(local_sigjmp_buf,0) == 0) \ </span><br style="font-family: courier new,monospace;" /><spanstyle="font-family: courier new,monospace;"> { \</span><br style="font-family: courier new,monospace;" /><spanstyle="font-family: courier new,monospace;"> PG_exception_stack = &local_sigjmp_buf</span><br style="font-family:courier new,monospace;" /><br style="font-family: courier new,monospace;" /><span style="font-family:courier new,monospace;"> #define PG_CATCH() \</span><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> } \ </span><br style="font-family: courier new,monospace;" /><spanstyle="font-family: courier new,monospace;"> else \</span><br style="font-family: courier new,monospace;" /><spanstyle="font-family: courier new,monospace;"> { \</span><br style="font-family: courier new,monospace;" /><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;">#define PG_FINALLY() \</span><br style="font-family: courier new,monospace;" /><spanstyle="font-family: courier new,monospace;"> } \</span><br style="font-family: courier new,monospace;" /><spanstyle="font-family: courier new,monospace;"> { \ </span><br style="font-family: courier new,monospace;" /><spanstyle="font-family: courier new,monospace;"> PG_exception_stack = save_exception_stack; \</span><br style="font-family: courier new,monospace;" /><span style="font-family:courier new,monospace;"> error_context_stack = save_context_stack</span><br style="font-family:courier new,monospace;" /><br style="font-family: courier new,monospace;" /><span style="font-family:courier new,monospace;"> #define PG_END_TRY() \</span><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> } \ </span><br style="font-family: courier new,monospace;" /><spanstyle="font-family: courier new,monospace;"> if (do_re_throw) \</span><br style="font-family: courier new,monospace;" /><spanstyle="font-family: courier new,monospace;"> siglongjmp(*PG_exception_stack, 1) \</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> } while (0)</span><br style="font-family: courier new,monospace;" /><br style="font-family: courier new,monospace;"/><span style="font-family: courier new,monospace;">#define PG_RE_THROW() do_re_throw = true</span><br style="font-family:courier new,monospace;" /><br />This would change the semantics to:<br /><br /><span style="font-family:courier new,monospace;"> ... normal code ...<br /><br /> PG_TRY();</span><br style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;"> {</span><br style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;"> ... code that mightthrow ereport(ERROR) ...</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> }</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> PG_CATCH();</span><br style="font-family: courier new,monospace;" /><span style="font-family: couriernew,monospace;"> {</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> ... (optional) error recovery code only *and/or* RE_THROW...</span><br style="font-family: couriernew,monospace;" /><span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;"> }</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> PG_FINALLY();</span><br style="font-family: courier new,monospace;" /><span style="font-family: couriernew,monospace;"> {</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;"> ... do something that you wanted done in any case; ERROR or not ...</span><br style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;"></span><span style="font-family:courier new,monospace;"> }</span><br style="font-family: courier new,monospace;" /><span style="font-family:courier new,monospace;"></span><span style="font-family: courier new,monospace;"> PG_END_TRY();<br/><br /></span><span style="font-family: courier new,monospace;"> ... normal code ...<br /></span><br/>Hope to find buyers.<br /><br />Best regards,<br /><br />-- <br />gurjeet[.singh]@EnterpriseDB.com<br />singh.gurjeet@{gmail | hotmail | yahoo }.com
pgsql-hackers by date: