Make Delete() remove all values for DupSort tables (#565)

* panic in MemoryMutation.Reset

* Make Delete remove all values for DupSort tables
This commit is contained in:
Andrew Ashikhmin 2022-08-03 15:36:49 +02:00 committed by GitHub
parent 0c9ada1ab0
commit 1d6c297797
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 14 deletions

View File

@ -1127,7 +1127,7 @@ func (c *MdbxCursor) prevDup() ([]byte, []byte, error) { return c.c.Get(nil,
func (c *MdbxCursor) prevNoDup() ([]byte, []byte, error) { return c.c.Get(nil, nil, mdbx.PrevNoDup) } func (c *MdbxCursor) prevNoDup() ([]byte, []byte, error) { return c.c.Get(nil, nil, mdbx.PrevNoDup) }
func (c *MdbxCursor) last() ([]byte, []byte, error) { return c.c.Get(nil, nil, mdbx.Last) } func (c *MdbxCursor) last() ([]byte, []byte, error) { return c.c.Get(nil, nil, mdbx.Last) }
func (c *MdbxCursor) delCurrent() error { return c.c.Del(mdbx.Current) } func (c *MdbxCursor) delCurrent() error { return c.c.Del(mdbx.Current) }
func (c *MdbxCursor) delNoDupData() error { return c.c.Del(mdbx.NoDupData) } func (c *MdbxCursor) delAllDupData() error { return c.c.Del(mdbx.AllDups) }
func (c *MdbxCursor) put(k, v []byte) error { return c.c.Put(k, v, 0) } func (c *MdbxCursor) put(k, v []byte) error { return c.c.Put(k, v, 0) }
func (c *MdbxCursor) putCurrent(k, v []byte) error { return c.c.Put(k, v, mdbx.Current) } func (c *MdbxCursor) putCurrent(k, v []byte) error { return c.c.Put(k, v, mdbx.Current) }
func (c *MdbxCursor) putNoOverwrite(k, v []byte) error { return c.c.Put(k, v, mdbx.NoOverwrite) } func (c *MdbxCursor) putNoOverwrite(k, v []byte) error { return c.c.Put(k, v, mdbx.NoOverwrite) }
@ -1330,17 +1330,6 @@ func (c *MdbxCursor) Delete(k []byte) error {
return c.deleteDupSort(k) return c.deleteDupSort(k)
} }
if c.bucketCfg.Flags&mdbx.DupSort != 0 {
_, err := c.getBoth(k, nil)
if err != nil {
if mdbx.IsNotFound(err) {
return nil
}
return err
}
return c.delCurrent()
}
_, _, err := c.set(k) _, _, err := c.set(k)
if err != nil { if err != nil {
if mdbx.IsNotFound(err) { if mdbx.IsNotFound(err) {
@ -1349,6 +1338,9 @@ func (c *MdbxCursor) Delete(k []byte) error {
return err return err
} }
if c.bucketCfg.Flags&mdbx.DupSort != 0 {
return c.delAllDupData()
}
return c.delCurrent() return c.delCurrent()
} }
@ -1664,7 +1656,7 @@ func (c *MdbxDupSortCursor) PutNoDupData(key, value []byte) error {
// DeleteCurrentDuplicates - delete all of the data items for the current key. // DeleteCurrentDuplicates - delete all of the data items for the current key.
func (c *MdbxDupSortCursor) DeleteCurrentDuplicates() error { func (c *MdbxDupSortCursor) DeleteCurrentDuplicates() error {
if err := c.delNoDupData(); err != nil { if err := c.delAllDupData(); err != nil {
return fmt.Errorf("in DeleteCurrentDuplicates: %w", err) return fmt.Errorf("in DeleteCurrentDuplicates: %w", err)
} }
return nil return nil

View File

@ -22,6 +22,7 @@ import (
"github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/log/v3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -529,3 +530,24 @@ func TestCurrentDup(t *testing.T) {
require.Equal(t, []string{"key1", "key1"}, keys) require.Equal(t, []string{"key1", "key1"}, keys)
require.Equal(t, []string{"value1.1", "value1.3"}, values) require.Equal(t, []string{"value1.1", "value1.3"}, values)
} }
func TestDupDelete(t *testing.T) {
db, tx, c := BaseCase(t)
defer db.Close()
defer tx.Rollback()
defer c.Close()
k, _, err := c.Current()
require.Nil(t, err)
require.Equal(t, []byte("key3"), k)
err = c.DeleteCurrentDuplicates()
require.Nil(t, err)
err = c.Delete([]byte("key1"))
require.Nil(t, err)
count, err := c.Count()
require.Nil(t, err)
assert.Zero(t, count)
}

View File

@ -379,5 +379,5 @@ func (m *MemoryMutation) ViewID() uint64 {
} }
func (m *MemoryMutation) Reset() error { func (m *MemoryMutation) Reset() error {
return nil panic("MemoryMutation.Reset not implemented")
} }