diff options
-rw-r--r-- | doc/src/sgml/plpgsql.sgml | 20 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 10 |
2 files changed, 23 insertions, 7 deletions
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index 30d1c64af5..80dbf45327 100644 --- a/doc/src/sgml/plpgsql.sgml +++ b/doc/src/sgml/plpgsql.sgml @@ -1904,8 +1904,8 @@ END LOOP <optional> <replaceable>label</replaceable> </optional>; indefinitely until terminated by an <literal>EXIT</> or <command>RETURN</command> statement. The optional <replaceable>label</replaceable> can be used by <literal>EXIT</> - and <literal>CONTINUE</literal> statements in nested loops to - specify which loop the statement should be applied to. + and <literal>CONTINUE</literal> statements within nested loops to + specify which loop those statements refer to. </para> </sect3> @@ -1939,9 +1939,19 @@ EXIT <optional> <replaceable>label</replaceable> </optional> <optional> WHEN <re <para> <literal>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. + </para> + + <para> + When used with a <literal>BEGIN</literal> block, <literal>EXIT</literal> passes control to the next statement after the end of the block. + Note that a label must be used for this purpose; an unlabelled + <literal>EXIT</literal> is never considered to match a + <literal>BEGIN</literal> block. (This is a change from + pre-8.4 releases of <productname>PostgreSQL</productname>, which + would allow an unlabelled <literal>EXIT</literal> to match + a <literal>BEGIN</literal> block.) </para> <para> @@ -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; </programlisting> </para> diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 1ba342f20d..77d0e8fad4 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -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; |