Thread: plpgsql's EXIT versus block and loop nesting

plpgsql's EXIT versus block and loop nesting

From
Tom Lane
Date:
Whilst fooling with some plpgsql code translated from Oracle, I found
out that we interpret this construct differently than they do:
       while true loop           begin               -- some code that might throw unique_violation
               exit;           exception when unique_violation then               -- take a recovery action (then go
'roundthe loop again)           end;       end loop;
 

The code author obviously expects that the EXIT will exit the WHILE
loop, so I assume that's what Oracle does with it.  What plpgsql is
doing is matching the EXIT to the BEGIN block, which means this is
an infinite loop.

Aside from the question of Oracle compatibility, ISTM this behavior
is at variance with what our manual says about EXIT:
If no label is given, the innermost loop is terminated and thestatement following END LOOP is executed next.

I'm not sure we should change this in the back branches, but I propose
that for 8.4, we fix it so that EXIT will only match to a begin-block
if the block has a label and it matches the EXIT's.  Unlabeled EXITs
should match to the innermost loop, like the manual says.  (This looks
to be about a one-line code change.)

Comments?
        regards, tom lane


Re: plpgsql's EXIT versus block and loop nesting

From
Pavel Stehule
Date:
2009/4/30 Tom Lane <tgl@sss.pgh.pa.us>:
> Whilst fooling with some plpgsql code translated from Oracle, I found
> out that we interpret this construct differently than they do:
>
>        while true loop
>            begin
>                -- some code that might throw unique_violation
>
>                exit;
>            exception when unique_violation then
>                -- take a recovery action (then go 'round the loop again)
>            end;
>        end loop;
>
> The code author obviously expects that the EXIT will exit the WHILE
> loop, so I assume that's what Oracle does with it.  What plpgsql is
> doing is matching the EXIT to the BEGIN block, which means this is
> an infinite loop.
>
> Aside from the question of Oracle compatibility, ISTM this behavior
> is at variance with what our manual says about EXIT:
>
>        If no label is given, the innermost loop is terminated and the
>        statement following END LOOP is executed next.
>
> I'm not sure we should change this in the back branches, but I propose
> that for 8.4, we fix it so that EXIT will only match to a begin-block
> if the block has a label and it matches the EXIT's.  Unlabeled EXITs
> should match to the innermost loop, like the manual says.  (This looks
> to be about a one-line code change.)

₊1

regards
Pavel Stehule

>
> Comments?
>
>                        regards, tom lane
>
> --
> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers
>


Re: plpgsql's EXIT versus block and loop nesting

From
Andrew Dunstan
Date:

Tom Lane wrote:
> Whilst fooling with some plpgsql code translated from Oracle, I found
> out that we interpret this construct differently than they do:
>
>         while true loop
>             begin
>                 -- some code that might throw unique_violation
>
>                 exit;
>             exception when unique_violation then
>                 -- take a recovery action (then go 'round the loop again)
>             end;
>         end loop;
>
> The code author obviously expects that the EXIT will exit the WHILE
> loop, so I assume that's what Oracle does with it.  What plpgsql is
> doing is matching the EXIT to the BEGIN block, which means this is
> an infinite loop.
>
> Aside from the question of Oracle compatibility, ISTM this behavior
> is at variance with what our manual says about EXIT:
>
>     If no label is given, the innermost loop is terminated and the
>     statement following END LOOP is executed next.
>
> I'm not sure we should change this in the back branches, but I propose
> that for 8.4, we fix it so that EXIT will only match to a begin-block
> if the block has a label and it matches the EXIT's.  Unlabeled EXITs
> should match to the innermost loop, like the manual says.  (This looks
> to be about a one-line code change.)
>
> Comments?
>
>             
>   

It's certainly a bug and should be fixed.  Given what the docs say I'd 
say there's a good case for backpatching it. OTOH, nobody has complained 
about it all these years.

cheers

andrew


Re: plpgsql's EXIT versus block and loop nesting

From
Heikki Linnakangas
Date:
Tom Lane wrote:
> Whilst fooling with some plpgsql code translated from Oracle, I found
> out that we interpret this construct differently than they do:
> 
>         while true loop
>             begin
>                 -- some code that might throw unique_violation
> 
>                 exit;
>             exception when unique_violation then
>                 -- take a recovery action (then go 'round the loop again)
>             end;
>         end loop;
> 
> The code author obviously expects that the EXIT will exit the WHILE
> loop, so I assume that's what Oracle does with it.  What plpgsql is
> doing is matching the EXIT to the BEGIN block, which means this is
> an infinite loop.
> 
> Aside from the question of Oracle compatibility, ISTM this behavior
> is at variance with what our manual says about EXIT:
> 
>     If no label is given, the innermost loop is terminated and the
>     statement following END LOOP is executed next.

later in that paragraph:
   EXIT can be used with all types of loops; it is not limited to use   with unconditional loops. *When used with a
BEGINblock, EXIT passes   control to the next statement after the end of the block.*
 
   Examples:   ...   BEGIN       -- some computations       IF stocks > 100000 THEN           EXIT;  -- causes exit
fromthe BEGIN block       END IF;   END;
 


That quite clearly describes the current behavior.

I'm not opposed to changing that, though. I've bumped into the same 
incompatibility with Oracle. Is it appropriate for 8.4 given that we're 
in beta already?

--   Heikki Linnakangas  EnterpriseDB   http://www.enterprisedb.com


Re: plpgsql's EXIT versus block and loop nesting

From
Tom Lane
Date:
Heikki Linnakangas <heikki.linnakangas@enterprisedb.com> writes:
> Tom Lane wrote:
>> Aside from the question of Oracle compatibility, ISTM this behavior
>> is at variance with what our manual says about EXIT:
>> 
>> If no label is given, the innermost loop is terminated and the
>> statement following END LOOP is executed next.

> later in that paragraph:

>     EXIT can be used with all types of loops; it is not limited to use
>     with unconditional loops. *When used with a BEGIN block, EXIT passes
>     control to the next statement after the end of the block.*

Right, but it fails to define what "used with" means.  I think we'd
clarify that to say that you must use a label.

> I'm not opposed to changing that, though. I've bumped into the same 
> incompatibility with Oracle. Is it appropriate for 8.4 given that we're 
> in beta already?

I think so, since it's only beta1.  We have other user-visible changes
in the pipeline already, eg fixing Unicode literals to not be a security
hazard.
        regards, tom lane