db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rick Hillegas <Richard.Hille...@Sun.COM>
Subject Re: Upgrade work when a new column is added to an existing system table...
Date Mon, 22 Mar 2010 15:54:39 GMT
Hi Mamta,

This is a very interesting problem. I am not aware that we have added a 
column to a system table since Derby was open-sourced. Whole tables have 
been added and the contents of individual columns have been changed. But 
I can't remember our adding a column to an existing table.

I do think your problem is solvable--albeit in a tricky way. First let 
me describe a possible user experience for your proposal:

1) In soft-upgraded databases, triggers behave as they did in 10.5.

2) In addition, even in hard-upgraded databases, old triggers behave as 
they did in 10.5.

3) However, in new 10.6 databases and in hard-upgraded databases, new 
triggers on LOB-bearing tables may perform significantly better.

4) So, in order to enjoy the advantages of your work on DERBY-1482, 
legacy databases must be hard-upgraded to 10.6 and triggers on 
LOB-bearing tables must be dropped and recreated.

If that's the contract, I think that the following solution will work:

A) We change the meaning of SYSTRIGGERS.REFERENCEDCOLUMNS. This column 
will carry additional metadata for new triggers created in databases 
which are at level 10.6.

B) We do this by changing the implementation of 
ReferencedColumnsDescriptorImpl, the object stored in that column. This 
object will now carry both the old list of columns in the trigger's 
update list as well as a new, optional list of columns mentioned in the 
trigger action. Let us call these two lists UpdateColumnList and 
TriggerActionColumnList. Note that it is OK to change the implementation 
of this class because the Reference Guide explicitly states that 
REFERENCEDCOLUMNS is not part of Derby's public api.

C) When creating a new trigger, if the database is at level 10.5 or 
earlier, then ReferencedColumnsDescriptorImpl is created only with an 
UpdateColumnList, and TriggerActionColumnList is left null. However, if 
the database level is 10.6 or later, then the new 
ReferencedColumnsDescriptorImpl is created with both an UpdateColumnList 
and a TriggerActionColumnList.

D) Now for the tricky part. When serializing/deserializing a 
ReferencedColumnsDescriptorImpl, we overload the meaning of the first 
integer written/read by the writeExternal()/readExternal() methods. Let 
us call this integer VersionNumber.

i) If ReferencedColumnsDescriptorImpl was created with a null 
TriggerActionColumnList, then VersionNumber continues to be what it was 
in 10.5 and earlier, viz., the length of the UpdateColumnList array. 
(De)serialization is the same as it was in 10.5.

ii) However, if ReferencedColumnsDescriptorImpl was created with a 
non-null TriggerActionColumnList, then VersionNumber is -1. In this 
case, we (de)serialize both UpdateColumnList and TriggerActionColumnList.

E) At query execution time, if TriggerActionColumnList is null, then the 
user sees the 10.5 behavior. However, if TriggerActionColumnList is not 
null, then the user sees the performance improvement you are introducing.

Hope this makes sense and seems useful,

Mamta Satoor wrote:
> Hi,
> I was looking for some guidence regarding upgrade work involved when a
> new column needs to be added to an existing system table and that
> column needs to be initialized to different value depending on the row
> in the table.
> As part of DERBY-1482, I need to add a new column to SYSTRIGGERS. That
> column is going to be of the type
> org.apache.derby.catalog.ReferencedColumns. The purpose of this column
> is to keep track of all the columns (from the trigger table) which are
> referenced in the trigger action through the REFERENCE clause of
> create trigger tr1 after update of id on t1 referencing old as oldt
> 	for each row insert into t2(id2) values (oldt.j);
> For the trigger above, we will note in SYSTRIGGERS that column j from
> the trigger table t1 is getting referenced in the trigger action. We
> will use this information to decide which columns need to be read in
> when the user executes an UPDATE t1(updating column id) SQL which will
> fire the trigger tr1. This will be especially useful if the table t1
> has LOB columns.
> My question is did we need to add a new column to an existing system
> table in the past? If yes, I would love to reuse that code if possible
> rather than reinventing the wheel. I do see following method in
> DataDictionaryImpl but do not see it getting called from anywhere
> 	/**
> 	  * Upgrade an existing catalog by adding columns.
> 	  *
> 	  * @param	rowFactory				Associated with this catalog.
> 	  * @param	newColumnIDs			Array of 1-based column ids.
> 	  * @param	tc						Transaction controller
> 	  *
> 	  * @exception StandardException Standard Derby error policy
> 	  */
> 	public void	upgrade_addColumns( CatalogRowFactory rowFactory, int[]
> newColumnIDs,TransactionController tc)
> 					throws StandardException
> If we do not have an existing infrastructure for adding a new column,
> I will explore the work needed. If anyone has any pointers/thoughts,
> would greatly appreciate that.
> Another needed step for upgrade for my specific situation is to
> initialize the new column correctly so the existing triggers don't
> break.
> thanks,
> Mamta

View raw message