|
Possible duplicate of
They are definitely closely related. Same symptom, different version of Derby. 1495 was logged against 10.1.3, 1645 was logged against 10.2. Derby 10.2 introduced the "ALTER TABLE WITH RESTART X" clause, and 10.1.3 did not have this. That is the only real difference.
Disclaimer: I'm not familiar with the code base, but I'm guessing that one fix may solve both issues. I further investigated on this and following is the summary for that :
- when alter table is executed, ColumnDefinitionNode.validateDefault(DataDictionary dd, TableDescriptor td) get called.void - - - - - - - - - - - validateDefault(DataDictionary dd, TableDescriptor td) throws StandardException { if (defaultNode == null ) // <--- See here return; //Examin whether default value is autoincrement. if (isAutoincrement){ defaultInfo = createDefaultInfoOfAutoInc(); return; } ........................ ........................ - - - - - - - - - - While the alter table statement does not support 'GENERATED BY' clause, the ModifiedColumnNode which gets created by the alter statement has defaultNode=null. Whereas for the original tree (before alter table), the defaultNode is not null and its value is available to ColumnDefinitionNode.validateDefault(DataDictionary dd, TableDescriptor td) in 'td' but is not used in the current code. Thus leaving defaultInfo unset and hence throws exception in ResultColumnList.checkAutoincrement() while checking for cd.isAutoincAlways() I tried to populate the defaultInfo for the alter table case as follows : void validateDefault(DataDictionary dd, TableDescriptor td) throws StandardException { //Check for defalutInfo from the exisiting TableData td //and set defaultInfo if (defaultNode == null ) { ColumnDescriptorList cdl = td.getColumnDescriptorList(); ColumnDescriptor cd = cdl.getColumnDescriptor(td.getUUID(), this.getColumnName()); // Get the defaultInfo for the particular column from the exixiting values itself // and set it for the modified column. if (cd != null) defaultInfo = (DefaultInfoImpl)cd.getDefaultInfo(); return; } //Examin whether default value is autoincrement. if (isAutoincrement){ defaultInfo = createDefaultInfoOfAutoInc(); return; } ................ ................ This works fine for the following : (For the same table MYTABLE) - ALTER TABLE MyTable ALTER TableId SET INCREMENT BY 50 - INSERT INTO MYTABLE (TableId, StringValue) VALUES (123, 'NewTest') Well I could not provide a patch as derbyall was failing for lang/autoincrement.sql , it seems some where else it breaks the regression. I am not too clear with the sceniro. Correct me if I am wrong or if I am missing anything ?? Comments / Suggestions please. - Saurabh
Kristian Waagan made changes - 19/Oct/06 09:54 AM
Saurabh, your analysis seem to be identical to what
I reported in In my case, Derby failed when clearing dependencies for the table when I dropped it.
Bryan Pendleton made changes - 09/Nov/06 10:48 PM
I have attached a proposed patch to
The proposed patch is slightly different from that suggested by Saurabh; I modified the bindAndValidateDefault method in ModifyColumnNode to populate the defaultInfo as needed.
I've committed the patch attached to
as revision 474502. precisely speaking duplicates, but as was noted in the comments above, a single fix resolves both problems. The patch changes the ALTER TABLE handling so that the parts of the identify column that you aren't altering are preserved and not incorrectly reset.
Bryan Pendleton made changes - 13/Nov/06 08:41 PM
Since
Thanks Alan for catching this. Yes, this fix is now in the 10.2 branch as well. Updated Fix Version to reflect this.
Bryan Pendleton made changes - 15/Nov/06 03:20 PM
Yes, since the patch is a fix for both issues, you should not see the bug with the head of the 10.2 branch anymore (or with trunk).
I assume the Fix Version field will be updated properly. Note that to obtain the fix, you will have to build Derby yourself until a new release is out. If you try it out, we would appreciate a confirmation that the patch fixes the problem you saw. This issue has been resolved for over a year with no further movement. Closing.
Andrew McIntyre made changes - 13/Dec/07 09:05 AM
Dag H. Wanvik made changes - 30/Jun/09 04:12 PM
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- ALTER TABLE MyTable ALTER TableId SET INCREMENT BY 50
we override the value for 'columnDefaultInfo' and set it to 'null'. as 'GENERATED BY DEFAULT....' clause is not allowed here. Now when we try to insert a row with specifying value of 'TableId' as :
- INSERT INTO MYTABLE (TableId, StringValue) VALUES (-999, 'test3')
the ResultColumnList.checkAutoincrement() throws an exception
if ((sourceRC != null) &&
(sourceRC.isAutoincrementGenerated()))
{
sourceRC.setColumnDescriptor(cd.getTableDescriptor(), cd);
}else{
if(cd.isAutoincAlways()) // <----- SEE HERE !!
throw StandardException.newException(SQLState.LANG_AI_CANNOT_MODIFY_AI,
rc.getName());
}
Here, isAutoincAlways() is called for the ColumnDescriptor 'cd' for TableId :
public boolean isAutoincAlways(){
return (columnDefaultInfo == null) && isAutoincrement();
}
it returns true as 'columnDefaultInfo' is now 'null' and hence the exception.
For this case to work correctly, ALTER TABLE should change the INCREMENT BY clause without setting the 'columnDefaultInfo' to 'null'. Correct me if I am wrong or if I am missing anything ??
Comments / Suggestions please.
Thanks in advance,
Saurabh