diff --git a/pkg/local_object_storage/metabase/select.go b/pkg/local_object_storage/metabase/select.go index b42461790..af5614ecc 100644 --- a/pkg/local_object_storage/metabase/select.go +++ b/pkg/local_object_storage/metabase/select.go @@ -45,8 +45,8 @@ func (db *DB) Select(fs object.SearchFilters) ([]*object.Address, error) { }) } - // keep processed addresses - mAddr := make(map[string]struct{}) + // keep processed addresses (false if address was added and excluded later) + mAddr := make(map[string]bool) for _, f := range fs { matchFunc, ok := db.matchers[f.Operation()] @@ -76,9 +76,11 @@ func (db *DB) Select(fs object.SearchFilters) ([]*object.Address, error) { for i := range strs { if include { - mAddr[strs[i]] = struct{}{} + if _, ok := mAddr[strs[i]]; !ok { + mAddr[strs[i]] = true + } } else { - delete(mAddr, strs[i]) + mAddr[strs[i]] = false } } @@ -88,7 +90,11 @@ func (db *DB) Select(fs object.SearchFilters) ([]*object.Address, error) { } } - for a := range mAddr { + for a, inc := range mAddr { + if !inc { + continue + } + // check if object marked as deleted if objectRemoved(tx, []byte(a)) { return nil diff --git a/pkg/local_object_storage/metabase/select_test.go b/pkg/local_object_storage/metabase/select_test.go index 73ab600a8..94dbdf185 100644 --- a/pkg/local_object_storage/metabase/select_test.go +++ b/pkg/local_object_storage/metabase/select_test.go @@ -88,3 +88,26 @@ func BenchmarkDB_Select(b *testing.B) { }) } } + +func TestMismatchAfterMatch(t *testing.T) { + db := newDB(t) + defer releaseDB(db) + + obj := generateObject(t, testPrm{ + attrNum: 1, + }) + + require.NoError(t, db.Put(obj)) + + a := obj.GetAttributes()[0] + + fs := objectSDK.SearchFilters{} + + // 1st - mismatching filter + fs.AddFilter(a.GetKey(), a.GetValue()+"1", objectSDK.MatchStringEqual) + + // 2nd - matching filter + fs.AddFilter(a.GetKey(), a.GetValue(), objectSDK.MatchStringEqual) + + testSelect(t, db, fs) +}