diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index 319547ec001..3788b8004b0 100644 --- a/doc/src/sgml/plpgsql.sgml +++ b/doc/src/sgml/plpgsql.sgml @@ -1,4 +1,4 @@ - + <application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language @@ -1904,8 +1904,8 @@ END LOOP label ; indefinitely until terminated by an EXIT or RETURN statement. The optional label can be used by EXIT - and CONTINUE statements in nested loops to - specify which loop the statement should be applied to. + and CONTINUE statements within nested loops to + specify which loop those statements refer to. @@ -1939,9 +1939,19 @@ EXIT label WHEN EXIT can be used with all types of loops; it is - not limited to use with unconditional loops. When used with a + not limited to use with unconditional loops. + + + + When used with a BEGIN block, EXIT passes control to the next statement after the end of the block. + Note that a label must be used for this purpose; an unlabelled + EXIT is never considered to match a + BEGIN block. (This is a change from + pre-8.4 releases of PostgreSQL, which + would allow an unlabelled EXIT to match + a BEGIN block.) @@ -1959,11 +1969,13 @@ LOOP EXIT WHEN count > 0; -- same result as previous example END LOOP; +<<ablock>> BEGIN -- some computations IF stocks > 100000 THEN - EXIT; -- causes exit from the BEGIN block + EXIT ablock; -- causes exit from the BEGIN block END IF; + -- computations here will be skipped when stocks > 100000 END; diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index d440d38e567..e436e053b1b 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.240 2009/04/09 02:57:53 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.241 2009/05/02 17:27:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1145,11 +1145,15 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) return rc; case PLPGSQL_RC_EXIT: + /* + * This is intentionally different from the handling of RC_EXIT + * for loops: to match a block, we require a match by label. + */ if (estate->exitlabel == NULL) - return PLPGSQL_RC_OK; + return PLPGSQL_RC_EXIT; if (block->label == NULL) return PLPGSQL_RC_EXIT; - if (strcmp(block->label, estate->exitlabel)) + if (strcmp(block->label, estate->exitlabel) != 0) return PLPGSQL_RC_EXIT; estate->exitlabel = NULL; return PLPGSQL_RC_OK; @@ -1604,7 +1608,7 @@ exec_stmt_while(PLpgSQL_execstate *estate, PLpgSQL_stmt_while *stmt) return PLPGSQL_RC_OK; if (stmt->label == NULL) return PLPGSQL_RC_EXIT; - if (strcmp(stmt->label, estate->exitlabel)) + if (strcmp(stmt->label, estate->exitlabel) != 0) return PLPGSQL_RC_EXIT; estate->exitlabel = NULL; return PLPGSQL_RC_OK;