Using the "exit" statement to jump out of a block statement
The exit statement is legal, and has well-defined semantics, within a simple block statement, even when it isn't inside a loop statement. This means that you can use it anywhere in the PL/pgSQL text that defines the implementation of a do statement or a language plpgsql subprogram. If you label the top-level block statement that defines the implementation with, for example, top level block, then use can use this:
exit top_level_block when <boolean expresssion>:
as a more compact alternative to the bare return statement within an if statement:
if <boolean expresssion> then
return;
end if;
(The bare return statement is legal, and has well-defined semantics, in a do statement's implementation and in a language plpgsql procedure. The other forms of the return statement are legal only in a language plpgsql function.)
Try this:
\c :db :u
drop schema if exists s cascade;
create schema s;
create function s.f(n in int)
returns text
language plpgsql
as $body$
declare
v text not null := 'a';
begin
<<b1>>begin
exit b1 when length(v) >= n;
v := v||'b';
exit b1 when length(v) >= n;
v := v||'c';
exit b1 when length(v) >= n;
v := v||'-impossible';
end b1;
return v;
end;
$body$;
This finishes without error. Now test it. First like this:
select s.f(1);
This is the result:
a
Next like this:
select s.f(2);
This is the result:
ab
And finally like this:
select s.f(3);
This is the result:
abc
Now try this counter example:
create procedure s.bad()
language plpgsql
as $body$
begin
exit;
end;
$body$;
It causes the 42601 syntax error:
EXIT cannot be used outside a loop, unless it has a label
Finally try this counter example:
create procedure s.bad()
language plpgsql
as $body$
<<b1>>begin
loop
continue b1;
end loop;
end b1;
$body$;
It, too, causes the 42601 syntax error, but now with this wording:
block label "b1" cannot be used in CONTINUE
This is the meaning:
- Neither the continue statement (without a label) nor the continue <label> statement can be used outside a loop.
- When the continue <label> statement is used, as it must be, within a loop, the label must match that of an enclosing loop statement.
There's an example of the legal use of the continue <label> statement, where the label matches that of an enclosing loop statement, in the function s.vowels_from_lines() on the page «Two case studies: Using the "for" loop, the "foreach" loop, the "infinite" loop, the "exit" statement, and the "continue" statement» in Case study #2.
Look for this:
continue lines when c = prev;