Yes. No. Sort of.
It's (not all that) complicated.
This question hit my Twitter feed yesterday:
OK, OK, calm down. Everything is just fine.
Here's the explanation:
As you can see, the warnings feedback ("PLW" stands for PL/SQL Warning) tells the story: procedures are removed after inlining.
Though I suppose we could be a little more explicit - and reassuring - and say:
It's (not all that) complicated.
This question hit my Twitter feed yesterday:
When you enable all warnings, have you ever seen a "PLW-06006-- uncalled procedure removed" (lots of them), when they surely are called?Now that, I must admit, has to be a little bit concerning. You write code, you know it is going to, or should be, executed, and yet the PL/SQL compiler tells you it's been removed?
OK, OK, calm down. Everything is just fine.
Here's the explanation:
- The optimizer performed an inlining optimization, so all the code for that procedure (or function) was moved to where it is invoked.
- The "original" nested or private subprogram that you wrote (and, don't worry, is still and always will be in the source code of your program unit) is, truth be told, never going to be called.
- So then the compiler removed it (did not include it in the compiled code - which is not PL/SQL code any longer).
ALTER SESSION SET plsql_optimize_level = 3
/
Statement processed
ALTER SESSION SET plsql_warnings='enable:all'
/
Statement processed
CREATE OR REPLACE PROCEDURE show_inlining
AUTHID DEFINER
IS
FUNCTION f1 (p NUMBER)
RETURN PLS_INTEGER
IS
BEGIN
RETURN p * 10;
END;
FUNCTION f2 (p BOOLEAN)
RETURN PLS_INTEGER
IS
BEGIN
RETURN CASE WHEN p THEN 10 ELSE 100 END;
END;
FUNCTION f3 (p PLS_INTEGER)
RETURN PLS_INTEGER
IS
BEGIN
RETURN p * 10;
END;
BEGIN
DBMS_OUTPUT.put_line ('f1 called: ' || f1 (1));
PRAGMA INLINE (f2, 'YES');
DBMS_OUTPUT.put_line ('f2 called: ' || TO_CHAR (f2 (TRUE) + f2 (FALSE)));
PRAGMA INLINE (f3, 'NO');
DBMS_OUTPUT.put_line ('f3 called: ' || f3 (55));
END;
/
Warning: PROCEDURE SHOW_INLINING
Warning: PROCEDURE SHOW_INLINING
Line/Col: 4/4 PLW-06027: procedure "F1" is removed after inlining
Line/Col: 10/4 PLW-06027: procedure "F2" is removed after inlining
Line/Col: 22/4 PLW-06005: inlining of call of procedure 'F1' was done
Line/Col: 25/4 PLW-06005: inlining of call of procedure 'F2' was done
Line/Col: 25/4 PLW-06004: inlining of call of procedure 'F2' requested
Line/Col: 25/4 PLW-06005: inlining of call of procedure 'F2' was done
Line/Col: 25/52 PLW-06004: inlining of call of procedure 'F2' requested
Line/Col: 28/4 PLW-06008: call of procedure 'F3' will not be inlined
BEGIN
show_inlining;
END;
/
f1 called: 10
f2 called: 110
f3 called: 550
Please note: all the functions (f1 - f3) were executed!
As you can see, the warnings feedback ("PLW" stands for PL/SQL Warning) tells the story: procedures are removed after inlining.
Though I suppose we could be a little more explicit - and reassuring - and say:
PLW-06027: procedure "F1" is removed after inlining....
but just from the compiled code, not the source code of your program unit!
Comments
Post a Comment