8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.261 2010/07/06 19:19:01 momjian Exp $
11
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.262 2010/08/09 02:25:05 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -327,10 +327,6 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo)
327
327
ereport (ERROR ,
328
328
(errcode (ERRCODE_SYNTAX_ERROR ),
329
329
errmsg ("CONTINUE cannot be used outside a loop" )));
330
- else if (rc == PLPGSQL_RC_RERAISE )
331
- ereport (ERROR ,
332
- (errcode (ERRCODE_SYNTAX_ERROR ),
333
- errmsg ("RAISE without parameters cannot be used outside an exception handler" )));
334
330
else
335
331
ereport (ERROR ,
336
332
(errcode (ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT ),
@@ -695,10 +691,6 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
695
691
ereport (ERROR ,
696
692
(errcode (ERRCODE_SYNTAX_ERROR ),
697
693
errmsg ("CONTINUE cannot be used outside a loop" )));
698
- else if (rc == PLPGSQL_RC_RERAISE )
699
- ereport (ERROR ,
700
- (errcode (ERRCODE_SYNTAX_ERROR ),
701
- errmsg ("RAISE without parameters cannot be used outside an exception handler" )));
702
694
else
703
695
ereport (ERROR ,
704
696
(errcode (ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT ),
@@ -1019,6 +1011,7 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
1019
1011
MemoryContext oldcontext = CurrentMemoryContext ;
1020
1012
ResourceOwner oldowner = CurrentResourceOwner ;
1021
1013
ExprContext * old_eval_econtext = estate -> eval_econtext ;
1014
+ ErrorData * save_cur_error = estate -> cur_error ;
1022
1015
1023
1016
estate -> err_text = gettext_noop ("during statement block entry" );
1024
1017
@@ -1130,6 +1123,12 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
1130
1123
unpack_sql_state (edata -> sqlerrcode ));
1131
1124
assign_text_var (errm_var , edata -> message );
1132
1125
1126
+ /*
1127
+ * Also set up cur_error so the error data is accessible
1128
+ * inside the handler.
1129
+ */
1130
+ estate -> cur_error = edata ;
1131
+
1133
1132
estate -> err_text = NULL ;
1134
1133
1135
1134
rc = exec_stmts (estate , exception -> action );
@@ -1141,21 +1140,26 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
1141
1140
errm_var -> value = (Datum ) 0 ;
1142
1141
errm_var -> isnull = true;
1143
1142
1144
- /* re-throw error if requested by handler */
1145
- if (rc == PLPGSQL_RC_RERAISE )
1146
- ReThrowError (edata );
1147
-
1148
1143
break ;
1149
1144
}
1150
1145
}
1151
1146
1147
+ /*
1148
+ * Restore previous state of cur_error, whether or not we executed
1149
+ * a handler. This is needed in case an error got thrown from
1150
+ * some inner block's exception handler.
1151
+ */
1152
+ estate -> cur_error = save_cur_error ;
1153
+
1152
1154
/* If no match found, re-throw the error */
1153
1155
if (e == NULL )
1154
1156
ReThrowError (edata );
1155
1157
else
1156
1158
FreeErrorData (edata );
1157
1159
}
1158
1160
PG_END_TRY ();
1161
+
1162
+ Assert (save_cur_error == estate -> cur_error );
1159
1163
}
1160
1164
else
1161
1165
{
@@ -1177,7 +1181,6 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
1177
1181
case PLPGSQL_RC_OK :
1178
1182
case PLPGSQL_RC_RETURN :
1179
1183
case PLPGSQL_RC_CONTINUE :
1180
- case PLPGSQL_RC_RERAISE :
1181
1184
return rc ;
1182
1185
1183
1186
case PLPGSQL_RC_EXIT :
@@ -1599,7 +1602,6 @@ exec_stmt_loop(PLpgSQL_execstate *estate, PLpgSQL_stmt_loop *stmt)
1599
1602
break ;
1600
1603
1601
1604
case PLPGSQL_RC_RETURN :
1602
- case PLPGSQL_RC_RERAISE :
1603
1605
return rc ;
1604
1606
1605
1607
default :
@@ -1663,7 +1665,6 @@ exec_stmt_while(PLpgSQL_execstate *estate, PLpgSQL_stmt_while *stmt)
1663
1665
break ;
1664
1666
1665
1667
case PLPGSQL_RC_RETURN :
1666
- case PLPGSQL_RC_RERAISE :
1667
1668
return rc ;
1668
1669
1669
1670
default :
@@ -1782,8 +1783,7 @@ exec_stmt_fori(PLpgSQL_execstate *estate, PLpgSQL_stmt_fori *stmt)
1782
1783
*/
1783
1784
rc = exec_stmts (estate , stmt -> body );
1784
1785
1785
- if (rc == PLPGSQL_RC_RETURN ||
1786
- rc == PLPGSQL_RC_RERAISE )
1786
+ if (rc == PLPGSQL_RC_RETURN )
1787
1787
break ; /* break out of the loop */
1788
1788
else if (rc == PLPGSQL_RC_EXIT )
1789
1789
{
@@ -2437,7 +2437,14 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
2437
2437
/* RAISE with no parameters: re-throw current exception */
2438
2438
if (stmt -> condname == NULL && stmt -> message == NULL &&
2439
2439
stmt -> options == NIL )
2440
- return PLPGSQL_RC_RERAISE ;
2440
+ {
2441
+ if (estate -> cur_error != NULL )
2442
+ ReThrowError (estate -> cur_error );
2443
+ /* oops, we're not inside a handler */
2444
+ ereport (ERROR ,
2445
+ (errcode (ERRCODE_SYNTAX_ERROR ),
2446
+ errmsg ("RAISE without parameters cannot be used outside an exception handler" )));
2447
+ }
2441
2448
2442
2449
if (stmt -> condname )
2443
2450
{
@@ -2637,6 +2644,7 @@ plpgsql_estate_setup(PLpgSQL_execstate *estate,
2637
2644
2638
2645
estate -> rettupdesc = NULL ;
2639
2646
estate -> exitlabel = NULL ;
2647
+ estate -> cur_error = NULL ;
2640
2648
2641
2649
estate -> tuple_store = NULL ;
2642
2650
if (rsi )
0 commit comments