diff --git a/src/pl/plpgsql/src/expected/plpgsql_control.out b/src/pl/plpgsql/src/expected/plpgsql_control.out index fbfc939eae..328bd48586 100644 --- a/src/pl/plpgsql/src/expected/plpgsql_control.out +++ b/src/pl/plpgsql/src/expected/plpgsql_control.out @@ -413,6 +413,17 @@ begin raise notice 'should get here'; end$$; NOTICE: should get here +-- check exit out of outermost block +do $$ +<> +begin + <> + 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 do $$ begin diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index a68a2077c3..f5b1d5c4fa 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -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 * 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; diff --git a/src/pl/plpgsql/src/sql/plpgsql_control.sql b/src/pl/plpgsql/src/sql/plpgsql_control.sql index 61d6ca6451..ed7231134f 100644 --- a/src/pl/plpgsql/src/sql/plpgsql_control.sql +++ b/src/pl/plpgsql/src/sql/plpgsql_control.sql @@ -311,6 +311,18 @@ begin raise notice 'should get here'; end$$; +-- check exit out of outermost block +do $$ +<> +begin + <> + 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 do $$ begin