Skip to content

Commit 1bf2518

Browse files
committed
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
1 parent df3640e commit 1bf2518

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

src/pl/plpgsql/src/expected/plpgsql_control.out

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,17 @@ begin
413413
raise notice 'should get here';
414414
end$$;
415415
NOTICE: should get here
416+
-- check exit out of outermost block
417+
do $$
418+
<<outerblock>>
419+
begin
420+
<<innerblock>>
421+
begin
422+
exit outerblock;
423+
raise notice 'should not get here';
424+
end;
425+
raise notice 'should not get here, either';
426+
end$$;
416427
-- unlabeled exit does match a while loop
417428
do $$
418429
begin

src/pl/plpgsql/src/pl_comp.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,9 +1038,11 @@ add_dummy_return(PLpgSQL_function *function)
10381038
/*
10391039
* If the outer block has an EXCEPTION clause, we need to make a new outer
10401040
* block, since the added RETURN shouldn't act like it is inside the
1041-
* EXCEPTION clause.
1041+
* EXCEPTION clause. Likewise, if it has a label, wrap it in a new outer
1042+
* block so that EXIT doesn't skip the RETURN.
10421043
*/
1043-
if (function->action->exceptions != NULL)
1044+
if (function->action->exceptions != NULL ||
1045+
function->action->label != NULL)
10441046
{
10451047
PLpgSQL_stmt_block *new;
10461048

src/pl/plpgsql/src/sql/plpgsql_control.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,18 @@ begin
311311
raise notice 'should get here';
312312
end$$;
313313

314+
-- check exit out of outermost block
315+
do $$
316+
<<outerblock>>
317+
begin
318+
<<innerblock>>
319+
begin
320+
exit outerblock;
321+
raise notice 'should not get here';
322+
end;
323+
raise notice 'should not get here, either';
324+
end$$;
325+
314326
-- unlabeled exit does match a while loop
315327
do $$
316328
begin

0 commit comments

Comments
 (0)