[ http://issues.apache.org/jira/browse/DERBY-359?page=all ]
     
Mamta A. Satoor resolved DERBY-359:
-----------------------------------

    Resolution: Won't Fix

The sql script provided for this JIRA entry was run with autocommit off, 
meaning the DDL and DML were in one single transaction. The DDL to create a 
unique index on the generated column puts shared row locks on SYSCOLUMNS rows 
involving the generated column. After the index creation, the next insert 
statement has the system generate values for the identity column (system 
generates values 1 and 2). (Note - As per SQL standards, the new value 
generation for identity columns should happen in a transaction of its own. 
Based on this SQL specification, Derby attempts to generate values in a 
transaction of its own but since the parent user transaction has shared row 
locks on SYSCOLUMNS, the nested transaction can't get locks on those rows and 
hence Derby has to discard the nested transaction and Derby asks the parent 
user transaction to generate the values. If the DDL to create unique index was 
not in the same user transaction, nested transaction would have succedded). 
After this, user inserts manual value 4 into the generated column. Next insert 
has the system generate the value (3 is generated) for identity column. But the 
subsequent attempt to generate value 4 for identity column will fail because 
user has manually inserted value 4 into the identity column which has been 
defined to have a unique index on it. The unique index failure causes the 
insert statement to rollback which in turn causes the the code related to 
generated 
value 4 to rollback too. And hence, when next time, system tries to generate 
value, it will try to generate 4 again which will again run into unique index 
failure and so on and so forth. 

So, in short, the issue here is that the parent user transaction has shared 
locks on some of the SYSCOLUMNS's rows which prevents a nested transaction to 
get shared locks on those rows to generate the next value. If the DDL to 
generate unique index can be moved out of the transaction, there will not be 
locking issues for nested transaction. 

I am going to mark this JIRA entry as Won't fix (don't if invalid is more 
appropriate Resolution). If anyone disagrees with marking this issue as not a 
bug, we can come back to it to discuss it further.

> GENERATED BY DEFAULT identity option should consume identity values even if 
> the transaction aborts. This would allow skipping over user inserted values 
> during system generation.
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>          Key: DERBY-359
>          URL: http://issues.apache.org/jira/browse/DERBY-359
>      Project: Derby
>         Type: Improvement
>   Components: SQL
>     Versions: 10.1.1.0
>  Environment: Generic
>     Reporter: Satheesh Bandaram
>     Assignee: Mamta A. Satoor

>
> Using GENERATED BY DEFAULT identity column, user can specify a value to be 
> inserted into identity column. When the system generated value and this user 
> specified value match, if an unique index is present, an error is correctly 
> generated. However, it is desirable to skip this value for next identity 
> generation, so that next INSERT would pass. Currently, all subsequent insert 
> statements fail.
> ij(CONNECTION0)> create table tauto(i int generated by default as identity, k 
> int);
> 0 rows inserted/updated/deleted
> ij(CONNECTION0)> create unique index tautoInd on tauto(i);
> 0 rows inserted/updated/deleted
> ij(CONNECTION0)> insert into tauto(k) values 1,2;
> 2 rows inserted/updated/deleted
> ij(CONNECTION0)> select * from tauto;
> I          |K
> -----------------------
> 1          |1
> 2          |2
> 2 rows selected
> ij(CONNECTION0)> insert into tauto values (4,4);
> 1 row inserted/updated/deleted
> ij(CONNECTION0)> insert into tauto(k) values 3;
> 1 row inserted/updated/deleted
> ij(CONNECTION0)> insert into tauto(k) values 4;             <=== Expected 
> error.
> ERROR 23505: The statement was aborted because it would have caused a 
> duplicate
> key value in a unique or primary key constraint or unique index identified by 
> 'T
> AUTOIND' defined on 'TAUTO'.
> ij(CONNECTION0)> insert into tauto(k) values 5;             <=== Would be 
> preferable to skip over identity value of '4' and use '5'
> ERROR 23505: The statement was aborted because it would have caused a 
> duplicate
> key value in a unique or primary key constraint or unique index identified by 
> 'T
> AUTOIND' defined on 'TAUTO'.
> ij(CONNECTION0)> insert into tauto(k) values 6;
> ERROR 23505: The statement was aborted because it would have caused a 
> duplicate
> key value in a unique or primary key constraint or unique index identified by 
> 'T
> AUTOIND' defined on 'TAUTO'.
> ij(CONNECTION0)>
> At this point, all system generated identity value based inserts would 
> continue to fail.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to