Skip to Main Content
  • Questions
  • Dependant package not invalidated and recompiled thus providing bad results

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Petr.

Asked: May 09, 2024 - 8:31 am UTC

Last updated: May 16, 2024 - 6:37 am UTC

Version: 19c

Viewed 100+ times

You Asked

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.


with LiveSQL Test Case:

and Connor said...

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.

Rating

  (1 rating)

Comments

A reader, May 13, 2024 - 8:48 am UTC

Thanks Connor for your time reproducing the issue and categorising this as a bug. I've created SR but ran into "this is a feature" mindset, your opinion will surely help!
Connor McDonald
May 16, 2024 - 6:37 am UTC

Keep us posted on drop the SR# to asktom_us@oracle.com

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library