Mamta Satoor wrote:
Hi,
I have researched quite a bit on Derby-655 : getImportedKeys returning duplicate rows in some cases. Here are my findings and 3 possible solutions to the problem. After reading the mail, if someone can think of any other way of solving this problem, then please share it.
  ====  SNIP ==


In the above sql snippet, when the join is made on SYSCONSTRAINTS, SYSKEYS, and SYSCONGLOMERATES for primary key on table t2, the query finds 2 rows in SYSCONGLOMERATES with the conglomerateid and it picks both those rows. This is wrong and we need to somehow return only one row from SYSCONGLOMERATES, eventhough there might be duplicate rows in there for a given conglomerateid. I have thought of following 3 solutions 1)Even if a foreign key's backing index qualifies as a duplicate index, have foreign key backing index create its own conglomerate rather than share an existing conglomerate. But this would mean that system would have to maintain 2 identical conglomerates. This can impact Derby's performance negatively, although I don't know how badly because it might be rare that a user creates a primary key and foreign key on identical columns. 2)Write a system function which will return just one row for all the duplicate conglomerateids for a given constraintid and use that row in the outermost select statement of metadata query for getImportedKeys. Not sure how easy this would be to implement but I am leaning towards this solution. 3)Do not create duplicate rows in sysconglomerates for duplicate indexes. Instead have just one row in sysconglomerate to represent all the duplicate indexes in sysconstraints. But that seems like more of an enhancement rather than a bug fix to me. Current Derby code heavily relies on having a row in SYSCONGLOMERATE for each of the indexes. Thanks if you have made it this far :) I hope this mail is clear in explaining the problem and the possible solutions. If anything is not clear, then let me know and I can provide more information. If anyone has any ideas about some other possible fix for the problem, please let me know that too. thanks,
Mamta
The table needs a primary key - besides making conglomerateid unique it might be less invasive to add a system generated primary key to this table. I personally avoid using tables without primary keys because you can run into odd-ball situations like this where multiple records can be identical and so it is not possible to get just one record. With a primary key you can get a single record by adding a correlated subquery to the query conditions that specify using the record with the record with max or min value of the unique column. Say the unique key column is conglomeratePK - the conditional would be:

select * from sys.sysconglomerates c1 where c1.conglomeratePK = ( select max(c2.conglomeratePK ) from sys.sysconglomerates c2 where c2.conglomerateid = c1.conglomerateid);

Reply via email to