]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix EXIT out of outermost block in plpgsql.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 13 Sep 2021 16:42:03 +0000 (12:42 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 13 Sep 2021 16:42:03 +0000 (12:42 -0400)
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

src/pl/plpgsql/src/expected/plpgsql_control.out
src/pl/plpgsql/src/pl_comp.c
src/pl/plpgsql/src/sql/plpgsql_control.sql

index 73b23a35e56976a472eca0cd41ed98f2b6370b65..e09a7aa98aa43561d896bc4a11f829ec67c3df3e 100644 (file)
@@ -413,6 +413,17 @@ begin
   raise notice 'should get here';
 end$$;
 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
 do $$
 begin
index 871195a70cd4cbc46c4aa16211f968c8fdc003ef..7e49d59a2d0dbd41951c1625d44d760c45c746ef 100644 (file)
@@ -1029,9 +1029,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;
 
index 61d6ca645134785e8a0ed79e51aacd44b20aadd8..ed7231134f4df0c7df0c8c04652e8b45e7223d1a 100644 (file)
@@ -311,6 +311,18 @@ begin
   raise notice 'should get here';
 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
 do $$
 begin