Hi Connor/Chris,
I am struggling to reason about the case attached in the liveSQL session.
P1 spec ('get_field_value' just returns the value of 'field' from the record given)
CREATE OR REPLACE PACKAGE p1 AS
field_default CONSTANT varchar2(4) := '0000';
TYPE typ_rec IS RECORD (
field varchar2(4) default field_default
);
function get_field_value(p_rec typ_rec) return varchar2;
end;
P2 body
CREATE OR REPLACE PACKAGE BODY p2 AS
function get_field_value return varchar2
as
l_rec p1.typ_rec;
begin
return p1.get_field_value(l_rec);
end;
end;
/
Now we should get '0000' no matter how we get to the record.field value
DECLARE
l_rec p1.typ_rec;
BEGIN
dbms_output.put_line(p1.get_field_value(l_rec));
dbms_output.put_line(p2.get_field_value());
END;
/
However, now if we prepend a new constant to P1
CREATE OR REPLACE PACKAGE p1 AS
dummy CONSTANT varchar2(4) := 'XXXX';
field_default CONSTANT varchar2(4) := '0000';
TYPE typ_rec IS RECORD (
field varchar2(4) default field_default
);
function get_field_value(p_rec typ_rec) return varchar2;
end;
P2 is not invalidated and starts to return 'XXXX' as a value for the field. It looks like it stored the index of the constant from P1 to be used and now it happily returns the incorrect value.
If one recompiles P2 manually, it starts to return correct result of '0000' again.
You can image the fun one has when a values of 200 constants are suddenly offset.
I tried to find in the docs some explanation of this behaviour but to no avail.
I think that's a bug. I've replicated the results
SQL> CREATE OR REPLACE PACKAGE p1 AS
2
3 field_default CONSTANT varchar2(4) := '0000';
4
5 TYPE typ_rec IS RECORD (
6 field varchar2(4) default field_default
7 );
8
9 function get_field_value(p_rec typ_rec) return varchar2;
10
11 end;
12 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY p1 AS
2
3 function get_field_value(p_rec typ_rec) return varchar2
4 AS
5 begin
6 return p_rec.field;
7 end;
8
9 end;
10 /
Package body created.
SQL> CREATE OR REPLACE PACKAGE p2 AS
2
3 function get_field_value return varchar2;
4
5 end;
6 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY p2 AS
2
3 function get_field_value return varchar2
4 as
5 l_rec p1.typ_rec;
6 begin
7 return p1.get_field_value(l_rec);
8 end;
9
10 end;
11 /
Package body created.
SQL>
SQL> set serverout on
SQL> DECLARE
2 l_rec p1.typ_rec;
3 BEGIN
4 dbms_output.put_line(p1.get_field_value(l_rec));
5 dbms_output.put_line(p2.get_field_value());
6 END;
7 /
0000
0000
PL/SQL procedure successfully completed.
SQL> CREATE OR REPLACE PACKAGE p1 AS
2
3 dummy CONSTANT varchar2(4) := 'XXXX';
4 field_default CONSTANT varchar2(4) := '0000';
5
6 TYPE typ_rec IS RECORD (
7 field varchar2(4) default field_default
8 );
9
10 function get_field_value(p_rec typ_rec) return varchar2;
11
12 end;
13 /
Package created.
SQL> set serverout on
SQL> DECLARE
2 l_rec p1.typ_rec;
3 BEGIN
4 dbms_output.put_line(p1.get_field_value(l_rec));
5 dbms_output.put_line(p2.get_field_value());
6 END;
7 /
0000
XXXX
PL/SQL procedure successfully completed.
SQL> alter package p2 compile body;
Package body altered.
SQL> DECLARE
2 l_rec p1.typ_rec;
3 BEGIN
4 dbms_output.put_line(p1.get_field_value(l_rec));
5 dbms_output.put_line(p2.get_field_value());
6 END;
7 /
0000
0000
PL/SQL procedure successfully completed.
Please log an SR with the test case (or just cut-paste my output above). Bugs get more weighted when logged by customers.