Commit 4ffd3fe4 authored by Tom Lane's avatar Tom Lane

Fix EXIT out of outermost block in plpgsql.

Ordinarily, using EXIT this way would draw "control reached end of
function without RETURN".  However, if the function is one where we
don't require an explicit RETURN (such as a DO block), that should
not happen.  It did anyway, because add_dummy_return() neglected to
account for the case.

Per report from Herwig Goemans.  Back-patch to all supported branches.

Discussion: https://postgr.es/m/868ae948-e3ca-c7ec-95a6-83cfc08ef750@gmail.com
parent 10faeb7e
...@@ -413,6 +413,17 @@ begin ...@@ -413,6 +413,17 @@ begin
raise notice 'should get here'; raise notice 'should get here';
end$$; end$$;
NOTICE: should get here NOTICE: should get here
-- check exit out of outermost block
do $$
<<outerblock>>
begin
<<innerblock>>
begin
exit outerblock;
raise notice 'should not get here';
end;
raise notice 'should not get here, either';
end$$;
-- unlabeled exit does match a while loop -- unlabeled exit does match a while loop
do $$ do $$
begin begin
......
...@@ -1038,9 +1038,11 @@ add_dummy_return(PLpgSQL_function *function) ...@@ -1038,9 +1038,11 @@ add_dummy_return(PLpgSQL_function *function)
/* /*
* If the outer block has an EXCEPTION clause, we need to make a new outer * If the outer block has an EXCEPTION clause, we need to make a new outer
* block, since the added RETURN shouldn't act like it is inside the * block, since the added RETURN shouldn't act like it is inside the
* EXCEPTION clause. * EXCEPTION clause. Likewise, if it has a label, wrap it in a new outer
* block so that EXIT doesn't skip the RETURN.
*/ */
if (function->action->exceptions != NULL) if (function->action->exceptions != NULL ||
function->action->label != NULL)
{ {
PLpgSQL_stmt_block *new; PLpgSQL_stmt_block *new;
......
...@@ -311,6 +311,18 @@ begin ...@@ -311,6 +311,18 @@ begin
raise notice 'should get here'; raise notice 'should get here';
end$$; end$$;
-- check exit out of outermost block
do $$
<<outerblock>>
begin
<<innerblock>>
begin
exit outerblock;
raise notice 'should not get here';
end;
raise notice 'should not get here, either';
end$$;
-- unlabeled exit does match a while loop -- unlabeled exit does match a while loop
do $$ do $$
begin begin
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment