Skip to content

Commit 291fc12

Browse files
gooohgbLi
authored andcommitted
fix(core): fix reverse edge loss when set and delete occur together (#9403)
This PR fixes a bug where a reverse edge (`@reverse` predicate) with a count index (`@count`) may lose values when the same predicate is set and deleted multiple times within a single DQL mutation. --------- Co-authored-by: Li <[email protected]>
1 parent 3145f88 commit 291fc12

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

posting/list.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ func (mm *MutableLayer) insertPosting(mpost *pb.Posting, hasCountIndex bool) {
376376
}
377377
res := mm.currentEntries.Postings[:postIndex]
378378
if postIndex+1 <= len(mm.currentEntries.Postings) {
379-
mm.currentEntries.Postings = append(res,
379+
res = append(res,
380380
mm.currentEntries.Postings[(postIndex+1):]...)
381381
}
382382
mm.currentUids = nil

worker/mutation_unit_test.go

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,67 @@ func TestReverseEdge(t *testing.T) {
6666
pl.RLock()
6767
c := pl.GetLength(5)
6868
pl.RUnlock()
69-
require.Equal(t, c, 0)
69+
require.Equal(t, 0, c)
70+
}
71+
72+
func TestReverseEdgeSetDel(t *testing.T) {
73+
dir, err := os.MkdirTemp("", "storetest_")
74+
x.Check(err)
75+
defer os.RemoveAll(dir)
76+
77+
opt := badger.DefaultOptions(dir)
78+
ps, err := badger.OpenManaged(opt)
79+
x.Check(err)
80+
pstore = ps
81+
// Not using posting list cache
82+
posting.Init(ps, 0, false)
83+
Init(ps)
84+
err = schema.ParseBytes([]byte("revc: [uid] @reverse @count ."), 1)
85+
require.NoError(t, err)
86+
87+
ctx := context.Background()
88+
txn := posting.Oracle().RegisterStartTs(5)
89+
attr := x.GalaxyAttr("revc")
90+
91+
edgeDel := &pb.DirectedEdge{
92+
ValueId: 2,
93+
Attr: attr,
94+
Entity: 3,
95+
Op: pb.DirectedEdge_DEL,
96+
}
97+
98+
edgeSet1 := &pb.DirectedEdge{
99+
ValueId: 2,
100+
Attr: attr,
101+
Entity: 1,
102+
Op: pb.DirectedEdge_SET,
103+
}
104+
105+
edgeSet2 := &pb.DirectedEdge{
106+
ValueId: 2,
107+
Attr: attr,
108+
Entity: 3,
109+
Op: pb.DirectedEdge_SET,
110+
}
111+
112+
edgeSet3 := &pb.DirectedEdge{
113+
ValueId: 2,
114+
Attr: attr,
115+
Entity: 4,
116+
Op: pb.DirectedEdge_SET,
117+
}
118+
119+
x.Check(runMutation(ctx, edgeSet1, txn))
120+
x.Check(runMutation(ctx, edgeSet2, txn))
121+
x.Check(runMutation(ctx, edgeSet3, txn))
122+
x.Check(runMutation(ctx, edgeDel, txn))
123+
124+
pl, err := txn.Get(x.ReverseKey(attr, 2))
125+
require.NoError(t, err)
126+
pl.RLock()
127+
c := pl.GetLength(5)
128+
pl.RUnlock()
129+
require.Equal(t, 2, c)
70130
}
71131

72132
func TestConvertEdgeType(t *testing.T) {

0 commit comments

Comments
 (0)