@ -277,6 +277,25 @@ extern PGDLLIMPORT ErrorContextCallback *error_context_stack;
* ( sub ) transaction abort . Failure to do so may leave the system in an
* ( sub ) transaction abort . Failure to do so may leave the system in an
* inconsistent state for further processing .
* inconsistent state for further processing .
*
*
* For the common case that the error recovery code and the cleanup in the
* normal code path are identical , the following can be used instead :
*
* PG_TRY ( ) ;
* {
* . . . code that might throw ereport ( ERROR ) . . .
* }
* PG_FINALLY ( ) ;
* {
* . . . cleanup code . . .
* }
* PG_END_TRY ( ) ;
*
* The cleanup code will be run in either case , and any error will be rethrown
* afterwards .
*
* You cannot use both PG_CATCH ( ) and PG_FINALLY ( ) in the same
* PG_TRY ( ) / PG_END_TRY ( ) block .
*
* Note : while the system will correctly propagate any new ereport ( ERROR )
* Note : while the system will correctly propagate any new ereport ( ERROR )
* occurring in the recovery section , there is a small limit on the number
* occurring in the recovery section , there is a small limit on the number
* of levels this will work for . It ' s best to keep the error recovery
* of levels this will work for . It ' s best to keep the error recovery
@ -300,24 +319,33 @@ extern PGDLLIMPORT ErrorContextCallback *error_context_stack;
*/
*/
# define PG_TRY() \
# define PG_TRY() \
do { \
do { \
sigjmp_buf * save_exception_stack = PG_exception_stack ; \
sigjmp_buf * _save_exception_stack = PG_exception_stack ; \
ErrorContextCallback * save_context_stack = error_context_stack ; \
ErrorContextCallback * _save_context_stack = error_context_stack ; \
sigjmp_buf local_sigjmp_buf ; \
sigjmp_buf _local_sigjmp_buf ; \
if ( sigsetjmp ( local_sigjmp_buf , 0 ) = = 0 ) \
bool _do_rethrow = false ; \
if ( sigsetjmp ( _local_sigjmp_buf , 0 ) = = 0 ) \
{ \
{ \
PG_exception_stack = & local_sigjmp_buf
PG_exception_stack = & _ local_sigjmp_buf
# define PG_CATCH() \
# define PG_CATCH() \
} \
} \
else \
else \
{ \
{ \
PG_exception_stack = save_exception_stack ; \
PG_exception_stack = _save_exception_stack ; \
error_context_stack = save_context_stack
error_context_stack = _save_context_stack
# define PG_FINALLY() \
} \
else \
_do_rethrow = true ; \
{
# define PG_END_TRY() \
# define PG_END_TRY() \
} \
} \
PG_exception_stack = save_exception_stack ; \
PG_exception_stack = _save_exception_stack ; \
error_context_stack = save_context_stack ; \
error_context_stack = _save_context_stack ; \
if ( _do_rethrow ) \
PG_RE_THROW ( ) ; \
} while ( 0 )
} while ( 0 )
/*
/*