Re: PL/SQL Interpreter oddity - bug or "expected"?

  • From: Stefan Knecht <knecht.stefan@xxxxxxxxx>
  • To: Toon Koppelaars <toon@xxxxxxxxxxx>
  • Date: Mon, 19 Mar 2018 14:57:10 +0700

Ah, that's why this list rocks :)

My email wasn't written to be taken apart word by word, though. What may
feel like natural language to the product manager of PL/SQL himself, the
intrepid developer using that language to write code, may not weigh such
understanding so tremendously. While it's certainly important to
distinguish between reserved words and keywords and flow control statements
and whatever else there may be - it's also important to be able to take a
step back and just ask oneself: "does this make sense when I look at this
code?". Alas, I don't think that I'm doomed for not mentioning "reserved
words" in my OP. What I fear dooms me more is that code that shouldn't
compile, does compile :)

Makes me wonder how much code is out there, where someone forgot to
uncomment a "loop" statement, but accidentally left the "end loop" in,
found the code compiled and left it like that.

It seems that the primary criticism was my somewhat relaxed use of the term
"keyword". Perhaps had I used "language element" instead, it would have
been received differently. However, I do believe that it doesn't matter for
this particular case. The language element "loop" has a similarly strong
effect in controlling what code does when executed, as does the language
element "if". It therefore doesn't matter whether it's categorized as a
reserved word, a keyword or something else, if you just break it down to
how the naked code looks.

Having said that, however, when it comes to understanding the effect of
said code, it of course matters whether the language element used is a
keyword or a reserved word. As Bryn has shown, PL/SQL does recognize that
something is off by showing a warning, if warnings are enabled. I however
think that this should be an error and not a warning; because warnings
still allow the code to compile. I don't know, it just feels wrong to me.

Bryn pointing out my (ab-)use of null; is also interesting. I'm sure that
the compiler optimizing this out of existence could cause some unexpected
effects when using null; but I don't think it changes the presented case.
Also, the code snippet shown is just a stripped-down version - as small as
I could get it - to show what I'm trying to point out. Of course, using
"null;" isn't ideal - but this isn't production code. I did run into this
while working on a 5000-line production code package which I obviously am
not gonna paste here. It compiled and misbehaved during testing, where I
feel it shouldn't have. I saw the warning Bryn pointed out, but I didn't
see any errors, which after seeing why the code misbehaved, I would have
expected to see. Hence my question to the community, if they felt the same
way about this. And it seems that some of you indeed do.

Anyway, it looks like we're stuck with getting a warning only due to
backward compatibility issues and we have to pay close attention to that. I
wish the compiler could be a tad more pedantic and not allow "language
elements" to be used in places they really shouldn't be allowed. Perhaps a
neat way of handling these things (and I'm sure there are other cases that
Oracle would like to change within the PL/SQL language but can't due to the
same circumstances with handling older version code) would be a parameter
similar to "compatible" - but for PL/SQL. Newer versions could have tighter
restrictions.

So to summarize, I still feel that the behavior isn't what I'd expect.
Regardless of what "loop" is underneath the covers, it has a special
meaning, and that meaning is entirely obliterated by the compiler treating
it as a mere label.

Stefan


On Mon, Mar 19, 2018 at 4:27 AM, Toon Koppelaars <toon@xxxxxxxxxxx> wrote:

From "the man" himself:


blogs.oracle.com/plsql-and-ebr/reserved-words%2c-keywords%
2c-and-the-ends-of-labeled-blocks


On Sat, Mar 17, 2018 at 6:13 AM, Stefan Knecht <knecht.stefan@xxxxxxxxx>
wrote:

Ran into this recently, and personally I feel that this should not
compile. What do you guys think?

Simple case in point:

create or replace package foo as
procedure bar;
end;
/

Package created.


create or replace package body foo as
procedure bar
is
begin
  begin
    null;
  end loop;
end;
end;
/

Package body created.

show errors

No errors.

SQL> exec foo.bar

PL/SQL procedure successfully completed.


What is happening is that Oracle interprets the "end loop" as being "end
anonymous_block_name". And in my opinion, with a keyword like "loop" that
should not be happening. In essence, the above is interpreted as:

create or replace package body foo as
procedure bar
is
begin
  begin
    null;
  end anon_block_name;
end;
end;
/


If we switch the "end loop" to an "end if" (which is a similar flow
control keyword) it reacts (in my opinion) correctly:

create or replace package body foo as
procedure bar
is
begin
  begin
    null;
  end if;
end;
end;
/

Warning: Package Body created with compilation errors.

SQL> show errors
Errors for PACKAGE BODY FOO:

LINE/COL ERROR
-------- ------------------------------------------------------------
-----
7/7      PLS-00103: Encountered the symbol "IF" when expecting one of the
         following:
         ; <an identifier> <a double-quoted delimited-identifier>
         The symbol "IF" was ignored.

SQL>


Would you agree that that should not compile in the first place?



Stefan





--
//
zztat - The Next-Gen Oracle Performance Monitoring and Reaction Framework!
Visit us at zztat.net | Support our Indiegogo campaign at igg.me/at/zztat
| @zztat_oracle




--
Toon Koppelaars
RuleGen BV
Toon.Koppelaars@xxxxxxxxxxx
www.RuleGen.com
TheHelsinkiDeclaration.blogspot.com

(co)Author: "Applied Mathematics for Database Professionals"
www.RuleGen.com/pls/apex/f?p=14265:13




-- 
//
zztat - The Next-Gen Oracle Performance Monitoring and Reaction Framework!
Visit us at zztat.net | Support our Indiegogo campaign at igg.me/at/zztat |
@zztat_oracle

Other related posts: