Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
946 views
in Technique[技术] by (71.8m points)

plsql - PL/SQL: Confused about type coercion in function calls (stack frames)

Consider the following example:

create or replace function f(n integer) return integer as
begin
  return n;
end;
/

begin
  dbms_output.put_line(f(3.8));
end;
/

3.8


PL/SQL procedure successfully completed.

This makes no sense to me. Obviously, PL/SQL simply ignores the integer specification, both on entering the function and on exiting it. Is this simply a bug? Is it a design choice, made deliberately by the language developers?

Here is why I find this confusing. Compare to the following example:

declare
  x integer;
begin
  x := 3.8;
  dbms_output.put_line(x);
end;
/

4


PL/SQL procedure successfully completed.

In this example, the data type specification is complied with. PL/SQL doesn't throw an error, but at least it performs an implicit coercion and it does not violate the data type declared for x - the variable stores the value 4, an integer, not 3.8.

So, how does PL/SQL do the function call thing in the first example? As far as I understand (never having been trained formally in computing), whenever the compiler or interpreter finds a function call it creates a stack frame, with variables for the arguments passed to the function and for the return value to come back from the function. Aren't these variables, when the stack frame is created, supposed to be the same data type as specified in the function declaration? If the stack frame has a field of integer data type for the argument 3.8, how come that is not coerced to 4 before it is even stored in the corresponding variable? And the same thing for the return value: if the function returns 3.8 but the caller expects an integer (and therefore the corresponding variable in the stack frame should be integer), how is it able to accept the return value 3.8?

And, most disturbing - why is this behavior different from the behavior when explicitly declared variables are involved (as in my second example)?

Thank you for sharing your thoughts!

question from:https://stackoverflow.com/questions/65861777/pl-sql-confused-about-type-coercion-in-function-calls-stack-frames

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The answer is found in the documentation for Oracle Database (to which your question has absolutely no relation whatsoever).

Firstly, INTEGER in the said database is a synonym for NUMBER(38). Upon assignment to a NUMBER(38) variable x, as in your second example, according to the assignment rules the NUMBER (with arbitrary precision) literal 3.8 is rounded.

In your first example though no assignment happens because IN parameters to PL/SQL subprograms are passed by reference and the same reference (to the NUMBER value 3.8) is returned.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...