Fix unique constraint crash when remapping recipients in name collision table.

This commit is contained in:
Cody Henthorne
2026-04-28 16:20:18 -04:00
committed by Greyson Parrelli
parent 9c2825f202
commit 9d1714d452
2 changed files with 17 additions and 8 deletions
@@ -280,13 +280,11 @@ class NameCollisionTables(
}
override fun remapRecipient(fromId: RecipientId, toId: RecipientId) {
val count = writableDatabase
.update(NameCollisionMembershipTable.TABLE_NAME)
.values(NameCollisionMembershipTable.RECIPIENT_ID to toId.serialize())
.where("${NameCollisionMembershipTable.RECIPIENT_ID} = ?", fromId)
.run()
Log.d(TAG, "Remapped $fromId to $toId. count: $count")
writableDatabase.execSQL(
"UPDATE OR REPLACE ${NameCollisionMembershipTable.TABLE_NAME} SET ${NameCollisionMembershipTable.RECIPIENT_ID} = ? WHERE ${NameCollisionMembershipTable.RECIPIENT_ID} = ?",
arrayOf(toId.serialize(), fromId.serialize())
)
Log.d(TAG, "Remapped $fromId to $toId")
}
private fun handleNameCollisions(
@@ -469,7 +467,7 @@ class NameCollisionTables(
SELECT ${NameCollisionMembershipTable.COLLISION_ID}
FROM ${NameCollisionMembershipTable.TABLE_NAME}
GROUP BY ${NameCollisionMembershipTable.COLLISION_ID}
HAVING COUNT($ID) >= 2
HAVING COUNT(*) >= 2
)
""".trimIndent()
)
@@ -186,6 +186,17 @@ class NameCollisionTablesTest {
assertThat(collisions).hasSize(0)
}
@Test
fun givenTwoUsersInTheSameNameCollision_whenIRemapOneToTheOther_thenIExpectNoConstraintViolation() {
setProfileNameAndCheckCollision(alice, ProfileName.fromParts("Bob", "Android"))
setProfileNameAndCheckCollision(bob, ProfileName.fromParts("Bob", "Android"))
SignalDatabase.nameCollisions.remapRecipient(alice, bob)
assertThat(SignalDatabase.nameCollisions.getCollisionsForThreadRecipientId(alice)).hasSize(0)
assertThat(SignalDatabase.nameCollisions.getCollisionsForThreadRecipientId(bob)).hasSize(0)
}
private fun setProfileNameAndCheckCollision(recipientId: RecipientId, name: ProfileName) {
recipients.setProfileName(recipientId, name)
SignalDatabase.nameCollisions.handleIndividualNameCollision(recipientId)