From 3c6c3ac0a2ceb97115487baf586b3692550384f0 Mon Sep 17 00:00:00 2001 From: Pavel Borzenkov Date: Wed, 8 Feb 2017 18:24:56 +0300 Subject: [PATCH 1/2] Add a test for deletion of non-existing key As of now the test fails and tries to delete the next key returned by the cursor, which happens to be a nested bucket. That's why Delete is fails. Signed-off-by: Pavel Borzenkov --- bucket_test.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/bucket_test.go b/bucket_test.go index c75f71ff..6d96e662 100644 --- a/bucket_test.go +++ b/bucket_test.go @@ -441,6 +441,39 @@ func TestBucket_Delete_FreelistOverflow(t *testing.T) { } } +// Ensure that deleting of non-existing key is a no-op. +func TestBucket_Delete_NonExisting(t *testing.T) { + db := MustOpenDB() + defer db.MustClose() + + if err := db.Update(func(tx *bolt.Tx) error { + b, err := tx.CreateBucket([]byte("widgets")) + if err != nil { + t.Fatal(err) + } + + if _, err = b.CreateBucket([]byte("nested")); err != nil { + t.Fatal(err) + } + return nil + }); err != nil { + t.Fatal(err) + } + + if err := db.Update(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte("widgets")) + if err := b.Delete([]byte("foo")); err != nil { + t.Fatal(err) + } + if b.Bucket([]byte("nested")) == nil { + t.Fatal("nested bucket has been deleted") + } + return nil + }); err != nil { + t.Fatal(err) + } +} + // Ensure that accessing and updating nested buckets is ok across transactions. func TestBucket_Nested(t *testing.T) { db := MustOpenDB() From 6336a429d168668797fbcb4d1f9e3895ae8aa8e2 Mon Sep 17 00:00:00 2001 From: Pavel Borzenkov Date: Wed, 8 Feb 2017 18:25:52 +0300 Subject: [PATCH 2/2] Fix deletion of non-existing keys Doc for Bucket.Delete says that a Delete() on non-existing key is a no-op. Right now it tries to delete the next key returned by the cursor. Fix this by checking for key equivalence before deletion. Fixes #349 Signed-off-by: Pavel Borzenkov --- bucket.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bucket.go b/bucket.go index 0c5bf274..93f9d951 100644 --- a/bucket.go +++ b/bucket.go @@ -323,7 +323,12 @@ func (b *Bucket) Delete(key []byte) error { // Move cursor to correct position. c := b.Cursor() - _, _, flags := c.seek(key) + k, _, flags := c.seek(key) + + // Return nil if the key doesn't exist. + if !bytes.Equal(key, k) { + return nil + } // Return an error if there is already existing bucket value. if (flags & bucketLeafFlag) != 0 {