-<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.140 2009/04/19 18:52:56 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.141 2009/05/02 17:27:57 tgl Exp $ -->
<chapter id="plpgsql">
<title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title>
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>
<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>
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>
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
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;