EBR – Part 9: Adding a New Column

This is part 9 of a post series about Oracle Edition-Based Redefinition.

Visit the index page for all the parts of the series

Introduction

In part 7 (“Editioning Views”) I introduced our third development use case – adding a new column that represents a new business logic.

I emphasize the fact it’s a new business logic, because sometimes we add new columns that come instead of existing columns, for replacing an existing business logic. As we’ll see in future posts, such cases require some additional handling in online upgrades.

Now, after part 8 (“The Last Planned Downtime”), in which we converted our schema to use editioning views and made it fully ready for online upgrades, we can implement the requirement in an online way.

The Task

We want to add a new attribute – Eye Color – to the Person entity.
For that we need to add a new column – EYE_COLOR – to the PEOPLE table, add make the corresponding changes in the PEOPLE_DL and APP_MGR packages (adding an input parameter – i_eye_color – to the people_dl.add procedure and changing the implementation of people_dl.add and app_mgr.do_something accordingly).

The Current State

At this point, V2 is our latest edition and it is exposed to the production clients. When connected to V2, we see the following objects:

V2> break on object_type on object_name on status on edition_name skip 1
V2>
V2>   select o.object_type,
  2          o.object_name,
  3          o.status,
  4          o.edition_name
  5   from   user_objects      o
  6   order by nvl2(o.edition_name, 2, 1),
  7            o.object_type,
  8            o.object_name;

OBJECT_TYPE  OBJECT_NAME  STATUS  EDITION_NAME
------------ ------------ ------- ------------
INDEX        PEOPLE_PK    VALID

TABLE        PEOPLE$0     VALID

PACKAGE      APP_MGR      VALID   ORA$BASE

             PEOPLE_DL    VALID   V2

PACKAGE BODY APP_MGR      VALID   V2

             PEOPLE_DL    VALID   V2

VIEW         PEOPLE       VALID   V2

7 rows selected.

The PEOPLE editioning view projects all the columns of the PEOPLE$0 table:

V2> desc people$0
 Name                    Null?    Type
 ----------------------- -------- ----------------
 ID                      NOT NULL NUMBER(9)
 FIRST_NAME              NOT NULL VARCHAR2(15)
 LAST_NAME               NOT NULL VARCHAR2(20)
 PHONE_NUMBER                     VARCHAR2(20)

V2> desc people
 Name                    Null?    Type
 ----------------------- -------- ----------------
 ID                      NOT NULL NUMBER(9)
 FIRST_NAME              NOT NULL VARCHAR2(15)
 LAST_NAME               NOT NULL VARCHAR2(20)
 PHONE_NUMBER                     VARCHAR2(20)

Performing the Upgrade

Creating a New Edition

As in any online upgrade, we start by creating a new edition.
Let’s create edition V3 and grant use on it to DEMO_EBR:

-- connected as system
ORA$BASE> create edition v3;

Edition created.

ORA$BASE> grant use on edition v3 to demo_ebr;

Grant succeeded.

In the developer session, let’s change the session edition to V3:


-- the developer session
V2> @set_edition v3

Session altered.

V3>

Adding the Column to the Table

Let’s add the new column to the table. This is an online operation, and, as explained in part 7, since no object depends on the table except for the editioning view, no object is invalidated.


V3> alter table people$0 add (eye_color varchar2(20));

Table altered.

Adding the Column to the Editioning View

Now we can add the new column to the editioning view. We do it in the privacy of the new (and unexposed) edition, and, as a result, a new actual object of PEOPLE is instantiated.


V3> create or replace editioning view people as
  2    select * from people$0;

V3> desc people
 Name                    Null?    Type
 ----------------------- -------- ----------------
 ID                      NOT NULL NUMBER(9)
 FIRST_NAME              NOT NULL VARCHAR2(15)
 LAST_NAME               NOT NULL VARCHAR2(20)
 PHONE_NUMBER                     VARCHAR2(20)
 EYE_COLOR                        VARCHAR2(20)

The clients, that are connected to the V2 edition, still see the pre-upgrade version of PEOPLE:


-- the client session
V2> desc people
 Name                    Null?    Type
 ----------------------- -------- ----------------
 ID                      NOT NULL NUMBER(9)
 FIRST_NAME              NOT NULL VARCHAR2(15)
 LAST_NAME               NOT NULL VARCHAR2(20)
 PHONE_NUMBER                     VARCHAR2(20)

So although tables are non-editionable and we have only one instance with one structure of the table, the view allows us to get the feeling that the table has different structures in different editions.

Changing the Code

In the privacy of V3 we make all the necessary changes in the packages:


V3> create or replace package people_dl as
  2    procedure add
  3    (
  4      i_id           in people.id%type,
  5      i_first_name   in people.first_name%type,
  6      i_last_name    in people.last_name%type,
  7      i_phone_number in people.phone_number%type,
  8      i_eye_color    in people.eye_color%type
  9    );
 10    procedure remove
 11    (
 12      i_id           in people.id%type
 13    );
 14  end people_dl;
 15  /

Package created.

V3> create or replace package body people_dl as
  2    procedure add
  3    (
  4      i_id           in people.id%type,
  5      i_first_name   in people.first_name%type,
  6      i_last_name    in people.last_name%type,
  7      i_phone_number in people.phone_number%type,
  8      i_eye_color    in people.eye_color%type
  9    ) is
 10    begin
 11      insert into people (id,first_name,last_name,phone_number,eye_color)
 12      values (i_id,i_first_name,i_last_name,i_phone_number,i_eye_color);
 13      --
 14      dbms_output.new_line;
 15      dbms_output.put_line('this is the version that introduced eye colors');
 16      --
 17    end add;
 18
 19    procedure remove(i_id in people.id%type) is
 20    begin
 21      delete people where id = i_id;
 22    end remove;
 23  end people_dl;
 24  /

Package body created.

V3> create or replace package body app_mgr as
  2    procedure do_something is
  3    begin
  4      people_dl.add(123, 'John', 'Doe', NULL, 'Brown');
  5      people_dl.remove(123);
  6      commit;
  7    end do_something;
  8  end app_mgr;
  9  /

Package body created.

Revalidation

And finally, before exposing the new edition to the clients, we make sure all the objects are valid and we explicitly actualize dependent objects if needed, as explained in part 5 (“Explicit Actualization of Dependent Objects”):


V3> @revalidate

PL/SQL procedure successfully completed.

V3>   select o.object_type,
  2          o.object_name,
  3          o.status,
  4          o.edition_name,
  5          nullif(
  6            d.referenced_name || ' [' || lower(d.referenced_type) || ']',
  7            ' []'
  8          ) depends_on
  9   from   user_objects      o,
 10          user_dependencies d
 11   where  d.name(+) = o.object_name
 12   and    d.type(+) = o.object_type
 13   and    d.referenced_owner(+) = user
 14   order by nvl2(o.edition_name, 2, 1),
 15            o.object_type,
 16            o.object_name,
 17            d.referenced_name;

OBJECT_TYPE  OBJECT_NAME  STATUS  EDITION_NAME DEPENDS_ON
------------ ------------ ------- ------------ --------------------
INDEX        PEOPLE_PK    VALID

TABLE        PEOPLE$0     VALID

PACKAGE      APP_MGR      VALID   ORA$BASE

             PEOPLE_DL    VALID   V3           PEOPLE [view]

PACKAGE BODY APP_MGR      VALID   V3           APP_MGR [package]
                                               PEOPLE_DL [package]

             PEOPLE_DL    VALID   V3           PEOPLE [view]
                                               PEOPLE_DL [package]

VIEW         PEOPLE       VALID   V3           PEOPLE$0 [table]


9 rows selected. 

Exposing the New Edition

And now let’s simulate exposing of the post-upgrade version to the client, simply by setting its session edition to V3, and let it use the people_dl.add procedure for inserting our first person into the table:


-- the client session
V2> @set_edition v3

Session altered.

V3> exec people_dl.add(1,'John','Lennon',null,'Brown')

this is the version that introduced eye colors

PL/SQL procedure successfully completed.

V3> commit;

Commit complete.

V3> select * from people;

        ID FIRST_NAME LAST_NAME  PHONE_NUMBER EYE_COLOR
---------- ---------- ---------- ------------ --------------------
         1 John       Lennon                  Brown

For other parts of the EBR series, please visit the index page.

Leave a Reply

Your email address will not be published. Required fields are marked *