Quantcast
Channel: Oracle
Viewing all articles
Browse latest Browse all 1814

Blog Post: Wait, did the PL/SQL compiler just REMOVE my code?

$
0
0
The PL/SQL compiler does more than compile - it also: automatically optimizes your code to run faster offers advice in the form of compile-time warnings to improve the quality and/or performance of your code allows you to conditionally include or exclude portions of your code for compilation That's just fantastic - but it can now and then result in some confusing moments for the Oracle Database developer (well, at least this developer). Recently, I was looking over the warnings I had gotten for a new package I'd written and saw this: Wait - my "procedure" user_goals_cur was removed ? I could tell by the name that it was not a procedure - it was a cursor. So clearly the warning message hasn't been customized to the type of code removed. OK, that's no big deal - I can deal with that. But when I see the PLW-06006 warning, it has meant that I'd written a nested subprogram in a procedure or function but it was no longer used. It was superfluous code that should have been removed - so the compiler removed it for me (from the compiled code, not my source code). But a cursor? Did I declare a cursor and then not use it? Entirely possible. So I opened up the package body and saw this: As I expect you can see, the cursor is used. OK, now I was worried. It was removing code that I was using? How could that make any sense? Well, you know what they say: Trust The Compiler. And trust people you know are way smarter than you - in this case, the PL/SQL development team. So rather than panicking about the removal of essential code, I went back and took a closer look at the warnings report. And this time I noticed the second warning that referenced the same "USER_GOALS_CUR": The cursor was inlined ! Now this was interesting news for two reasons: I hadn't even realized that the compiler performed the inlining operation on cursors . It made me think that perhaps the inlining was somehow related to the removal of the cursor. But first for those who are unfamiliar with the inlining feature, I will take a moment to explain. Suppose I have a procedure defined as follows: PROCEDURE p IS FUNCTION f RETURN NUMBER IS BEGIN ... END; BEGIN IF f() THEN ... END; When f is executed at runtime, PL/SQL spends a small amount of time finding the code for f . If you'd like to avoid this overhead, you can ask the compiler to inline the function. This means that when you compile your program, the invocation of a subprogram is replaced by the code itself. Your compiled code size increases, but the runtime performance is faster. We recommend that you set your PL/SQL optimization level to 3 (default is 2) to take full advantage of this feature. You an also selectively request to inline or disable inlining with the PRAGMA INLINE statement. Check the doc for lots more information on inlining. So when you see the PLW-06006 warning , you know that inlining optimization is enabled and has been put into effect. And that's when the light bulb goes off in my head and I realize: A cursor really is no different than a function. You "pass in" bind variables and "return" one or more values via the SELECT list. So the compiler doesn't just inline procedures and functions. It inlines cursors, too! How cool is that? Once the cursor (or procedure or function) has been inlined, there is no reason to keep it defined as a cursor or subprogram in the declaration section. So the compiler removes it. That all makes perfect sense, but, gee, that's also kind of confusing. False alarm, and all that. The bottom line is that the PL/SQL compiler will "remove" code (leave it "behind" in the source code and not move it to the compiled code) only when it is truly not used or not needed to execute your code. So remember: Trust your compiler. But verify your understanding of what it is doing.

Viewing all articles
Browse latest Browse all 1814

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>