I wanted to see what error(s) would be reported if "exit" or "continue" is 
used, in PL/pgSQL, outside of a loop—and in particular if these were reported 
as syntax errors or runtime errors. There were no surprises with "continue". 
But I was surprised by this:

create procedure p()
  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

"unless it has a label"? Eh?

I Googled this for that message and found this:

https://postgrespro.com/list/thread-id/2364409 
<https://postgrespro.com/list/thread-id/2364409>
“Thread: Better testing coverage and unified coding for plpgsql loops”, Tom 
Lane, 31 December 2017

The message is mentioned. But I couldn't find any opinion about the intention. 
I tried this (using Version 15.3):

create function f(n in int)
  returns text
  language plpgsql
as $body$
declare
  v text not null := 'a';
begin
  <<b1>>begin
    v := v||'1';
    exit b1 when length(v) > n;
    v := v||'2';
    exit b1 when length(v) > n;
    v := v||'3';
  end b1;
  return v;
end;
$body$;

It completed without error. I tried "select f(1)" and then with the actuals "2" 
and "99"—and I got the outcomes that the code asks for. In other words, "exit" 
can, in at least some scenarios, be used to emulate "goto". (Rather like a 
premature "return" in the middle of a procedure.)

What is the rationale for supporting what seems to be on its face this strange 
functionality?

As it happens, Oracle's PL/SQL has a "goto" statement. But PL/pgSQL does not. 
(I assume that this is because "goto" is considered a bad thing.) But PL/SQL 
programmers do use it. However, the doc section:

https://www.postgresql.org/docs/current/plpgsql-porting.html 
<https://www.postgresql.org/docs/current/plpgsql-porting.html>
"Porting from Oracle PL/SQL"

doesn't mention "goto". But "exit <label>" might help.

Reply via email to