@@ -370,3 +370,38 @@ func TestBackfillBatchTxn_ConflictsWhenReadDocIsModified(t *testing.T) {
370370 require .True (t , errors .Is (commitErr , corekv .ErrTxnConflict ),
371371 "expected ErrTxnConflict but got: %v" , commitErr )
372372}
373+
374+ // A unique violation names the document that lost. Naming the one that already holds the
375+ // value is what lets the two be compared, which is the only way to tell a genuine duplicate
376+ // from two documents that disagree on a field they do not share an index on.
377+ func TestSaveUniqueKey_ErrorNamesTheDocumentHoldingTheValue (t * testing.T ) {
378+ ctx := context .Background ()
379+
380+ db , err := newBadgerDB (ctx )
381+ require .NoError (t , err )
382+ t .Cleanup (func () { db .Close () })
383+
384+ _ , err = db .AddCollection (ctx , userSchema )
385+ require .NoError (t , err )
386+ col , err := db .GetCollectionByName (ctx , "User" )
387+ require .NoError (t , err )
388+
389+ _ , err = col .NewIndex (ctx , client.NewIndexRequest {
390+ Fields : []client.IndexedFieldDescription {{Name : "name" }},
391+ Unique : true ,
392+ })
393+ require .NoError (t , err )
394+
395+ incumbent , err := client .NewDocFromJSON (ctx , []byte (`{"name":"alice","age":1}` ), col .Version ())
396+ require .NoError (t , err )
397+ require .NoError (t , col .AddDocument (ctx , incumbent ))
398+
399+ // Same indexed value, different age, so a different document that cannot have the slot.
400+ duplicate , err := client .NewDocFromJSON (ctx , []byte (`{"name":"alice","age":2}` ), col .Version ())
401+ require .NoError (t , err )
402+ require .NotEqual (t , incumbent .ID ().String (), duplicate .ID ().String ())
403+
404+ err = col .AddDocument (ctx , duplicate )
405+ require .ErrorContains (t , err , "violates unique index" )
406+ require .ErrorContains (t , err , incumbent .ID ().String ())
407+ }
0 commit comments