a composite unique index on (STRING, INTEGER) properties is correctly updated when an UPDATE statement is executed to modify the value of one of the indexed properties.
If the value of one of the indexed properties is updated (preserving the uniqueness), a DuplicatedKeyException is thrown, showing that the indexed value of the other property was null, instead of the correct value. The value of the other property guaranteed the uniqueness, so by replacing the correct value with null, the engine has created the conditions for a duplicate key.
The attached testCompositeIndex method demonstrates steps 1 - 8 and produces the following result:
INSERT INTO Order SET id = ?, status = ?, processor = ?; parameters: 1, SIR1LRM-7.1, PENDING
result = {"id":"1","status":"PENDING","processor":"SIR1LRM-7.1","@cat":"d","@type":"Order","@rid":"#1:0"}
INSERT INTO Order SET id = ?, status = ?, processor = ?; parameters: 2, SIR1LRM-7.1, PENDING
result = {"id":"2","status":"PENDING","processor":"SIR1LRM-7.1","@cat":"d","@type":"Order","@rid":"#2:0"}
UPDATE Order SET status = ? RETURN AFTER WHERE id = ?, parameters: [ERROR, 1]
result = {"id":"1","status":"ERROR","processor":"SIR1LRM-7.1","@cat":"d","@type":"Order","@rid":"#1:0"}
UPDATE Order SET status = ? RETURN AFTER WHERE id = ?, parameters: [ERROR, 2]
result = {"id":"2","status":"ERROR","processor":"SIR1LRM-7.1","@cat":"d","@type":"Order","@rid":"#2:0"}
Exception in thread "main" com.arcadedb.exception.DuplicatedKeyException: Duplicated key [ERROR, null] found on index 'Order[status,id]' already assigned to record #1:0
at com.arcadedb.database.TransactionIndexContext.checkUniqueIndexKeys(TransactionIndexContext.java:338)
at com.arcadedb.database.TransactionIndexContext.checkUniqueIndexKeys(TransactionIndexContext.java:373)
at com.arcadedb.database.TransactionIndexContext.commit(TransactionIndexContext.java:162)
at com.arcadedb.database.TransactionContext.commit1stPhase(TransactionContext.java:479)
at com.arcadedb.database.TransactionContext.commit(TransactionContext.java:114)
at com.arcadedb.database.EmbeddedDatabase.lambda$commit$2(EmbeddedDatabase.java:366)
at com.arcadedb.database.EmbeddedDatabase.executeInReadLock(EmbeddedDatabase.java:1326)
at com.arcadedb.database.EmbeddedDatabase.commit(EmbeddedDatabase.java:361)
at com.arcadedb.database.EmbeddedDatabase.transaction(EmbeddedDatabase.java:1000)
at com.arcadedb.database.EmbeddedDatabase.transaction(EmbeddedDatabase.java:965)
at com.arcadedb.server.ServerDatabase.transaction(ServerDatabase.java:301)
at eu.serco.csrs.persistence.ArcadeDBTest.testCompositeIndex(ArcadeDBTest.java:153)
at eu.serco.csrs.persistence.ArcadeDBTest.main(ArcadeDBTest.java:67)
ArcadeDB Version: v23.1.2-SNAPSHOT (build 75a9319/1674650185130/main)
JDK Version: openjdk version "11.0.12" 2021-07-20 LTS
OS: Windows 10 Enterprise 22H2
Expected behavior
a composite unique index on (STRING, INTEGER) properties is correctly updated when an UPDATE statement is executed to modify the value of one of the indexed properties.
Actual behavior
If the value of one of the indexed properties is updated (preserving the uniqueness), a DuplicatedKeyException is thrown, showing that the indexed value of the other property was null, instead of the correct value. The value of the other property guaranteed the uniqueness, so by replacing the correct value with null, the engine has created the conditions for a duplicate key.
Steps to reproduce
com.arcadedb.exception.DuplicatedKeyException: Duplicated key [ERROR, null] found on index 'Order[status,id]' already assigned to record #1:0and that the second update has been rolled backThe attached testCompositeIndex method demonstrates steps 1 - 8 and produces the following result:
testCompositeIndex.zip