Index: src/pl/plpgsql/src/pl_exec.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/pl/plpgsql/src/pl_exec.c,v
retrieving revision 1.257
diff -c -p -r1.257 pl_exec.c
*** src/pl/plpgsql/src/pl_exec.c	14 Apr 2010 23:52:10 -0000	1.257
--- src/pl/plpgsql/src/pl_exec.c	23 Apr 2010 09:51:08 -0000
*************** plpgsql_exec_function(PLpgSQL_function *
*** 327,336 ****
  			ereport(ERROR,
  					(errcode(ERRCODE_SYNTAX_ERROR),
  					 errmsg("CONTINUE cannot be used outside a loop")));
- 		else if (rc == PLPGSQL_RC_RERAISE)
- 			ereport(ERROR,
- 					(errcode(ERRCODE_SYNTAX_ERROR),
- 					 errmsg("RAISE without parameters cannot be used outside an exception handler")));
  		else
  			ereport(ERROR,
  			   (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
--- 327,332 ----
*************** plpgsql_exec_trigger(PLpgSQL_function *f
*** 695,704 ****
  			ereport(ERROR,
  					(errcode(ERRCODE_SYNTAX_ERROR),
  					 errmsg("CONTINUE cannot be used outside a loop")));
- 		else if (rc == PLPGSQL_RC_RERAISE)
- 			ereport(ERROR,
- 					(errcode(ERRCODE_SYNTAX_ERROR),
- 					 errmsg("RAISE without parameters cannot be used outside an exception handler")));
  		else
  			ereport(ERROR,
  			   (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
--- 691,696 ----
*************** exec_stmt_block(PLpgSQL_execstate *estat
*** 1132,1138 ****
--- 1124,1136 ----
  
  					estate->err_text = NULL;
  
+ 					/*
+ 					 * Set last_caught_error for the duration of the
+ 					 * exception handler, so that "RAISE;" can rethrow it.
+ 					 */
+ 					estate->last_caught_error = edata;
  					rc = exec_stmts(estate, exception->action);
+ 					estate->last_caught_error = NULL;
  
  					free_var(state_var);
  					state_var->value = (Datum) 0;
*************** exec_stmt_block(PLpgSQL_execstate *estat
*** 1141,1150 ****
  					errm_var->value = (Datum) 0;
  					errm_var->isnull = true;
  
- 					/* re-throw error if requested by handler */
- 					if (rc == PLPGSQL_RC_RERAISE)
- 						ReThrowError(edata);
- 
  					break;
  				}
  			}
--- 1139,1144 ----
*************** exec_stmt_block(PLpgSQL_execstate *estat
*** 1177,1183 ****
  		case PLPGSQL_RC_OK:
  		case PLPGSQL_RC_RETURN:
  		case PLPGSQL_RC_CONTINUE:
- 		case PLPGSQL_RC_RERAISE:
  			return rc;
  
  		case PLPGSQL_RC_EXIT:
--- 1171,1176 ----
*************** exec_stmt_loop(PLpgSQL_execstate *estate
*** 1599,1605 ****
  				break;
  
  			case PLPGSQL_RC_RETURN:
- 			case PLPGSQL_RC_RERAISE:
  				return rc;
  
  			default:
--- 1592,1597 ----
*************** exec_stmt_while(PLpgSQL_execstate *estat
*** 1663,1669 ****
  				break;
  
  			case PLPGSQL_RC_RETURN:
- 			case PLPGSQL_RC_RERAISE:
  				return rc;
  
  			default:
--- 1655,1660 ----
*************** exec_stmt_fori(PLpgSQL_execstate *estate
*** 1782,1789 ****
  		 */
  		rc = exec_stmts(estate, stmt->body);
  
! 		if (rc == PLPGSQL_RC_RETURN ||
! 			rc == PLPGSQL_RC_RERAISE)
  			break;				/* break out of the loop */
  		else if (rc == PLPGSQL_RC_EXIT)
  		{
--- 1773,1779 ----
  		 */
  		rc = exec_stmts(estate, stmt->body);
  
! 		if (rc == PLPGSQL_RC_RETURN)
  			break;				/* break out of the loop */
  		else if (rc == PLPGSQL_RC_EXIT)
  		{
*************** exec_stmt_raise(PLpgSQL_execstate *estat
*** 2435,2441 ****
  	/* RAISE with no parameters: re-throw current exception */
  	if (stmt->condname == NULL && stmt->message == NULL &&
  		stmt->options == NIL)
! 		return PLPGSQL_RC_RERAISE;
  
  	if (stmt->condname)
  	{
--- 2425,2438 ----
  	/* RAISE with no parameters: re-throw current exception */
  	if (stmt->condname == NULL && stmt->message == NULL &&
  		stmt->options == NIL)
! 	{
! 		if (estate->last_caught_error == NULL)
! 			ereport(ERROR,
! 				(errcode(ERRCODE_SYNTAX_ERROR),
! 				 errmsg("RAISE without parameters cannot be used outside an exception handler")));
! 
! 		ReThrowError(estate->last_caught_error);
! 	}
  
  	if (stmt->condname)
  	{
*************** plpgsql_estate_setup(PLpgSQL_execstate *
*** 2664,2669 ****
--- 2661,2667 ----
  	estate->err_text = NULL;
  
  	estate->plugin_info = NULL;
+ 	estate->last_caught_error = NULL;
  
  	/*
  	 * Create an EState and ExprContext for evaluation of simple expressions.
Index: src/pl/plpgsql/src/plpgsql.h
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/pl/plpgsql/src/plpgsql.h,v
retrieving revision 1.130
diff -c -p -r1.130 plpgsql.h
*** src/pl/plpgsql/src/plpgsql.h	26 Feb 2010 02:01:35 -0000	1.130
--- src/pl/plpgsql/src/plpgsql.h	23 Apr 2010 09:51:08 -0000
*************** enum
*** 115,122 ****
  	PLPGSQL_RC_OK,
  	PLPGSQL_RC_EXIT,
  	PLPGSQL_RC_RETURN,
! 	PLPGSQL_RC_CONTINUE,
! 	PLPGSQL_RC_RERAISE
  };
  
  /* ----------
--- 115,121 ----
  	PLPGSQL_RC_OK,
  	PLPGSQL_RC_EXIT,
  	PLPGSQL_RC_RETURN,
! 	PLPGSQL_RC_CONTINUE
  };
  
  /* ----------
*************** typedef struct PLpgSQL_execstate
*** 721,726 ****
--- 720,726 ----
  	const char *err_text;		/* additional state info */
  
  	void	   *plugin_info;	/* reserved for use by optional plugin */
+ 	ErrorData	*last_caught_error;
  } PLpgSQL_execstate;
  
  
