diff --git a/spectator-reg-atlas/src/main/java/com/netflix/spectator/atlas/impl/QueryIndex.java b/spectator-reg-atlas/src/main/java/com/netflix/spectator/atlas/impl/QueryIndex.java index 5ece1d4e3..f4a2ff743 100644 --- a/spectator-reg-atlas/src/main/java/com/netflix/spectator/atlas/impl/QueryIndex.java +++ b/spectator-reg-atlas/src/main/java/com/netflix/spectator/atlas/impl/QueryIndex.java @@ -20,6 +20,7 @@ import com.netflix.spectator.impl.Cache; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -175,8 +176,9 @@ private void add(List queries, int i, T value) { otherChecksCache.clear(); // Not queries should match if the key is missing from the id, so they need to - // be included in the other keys sub-tree as well - if (kq instanceof Query.InvertedKeyQuery) { + // be included in the other keys sub-tree as well. Check this by seeing if it will + // match an empty map as there could be a variety of inverted types. + if (kq.matches(Collections.emptyMap())) { if (missingKeysIdx == null) { missingKeysIdx = QueryIndex.empty(registry); } @@ -267,8 +269,9 @@ private boolean remove(List queries, int i, T value) { } // Not queries should match if the key is missing from the id, so they need to - // be included in the other keys sub-tree as well - if (kq instanceof Query.InvertedKeyQuery && missingKeysIdx != null) { + // be included in the other keys sub-tree as well. Check this by seeing if it will + // match an empty map as there could be a variety of inverted types. + if (kq.matches(Collections.emptyMap()) && missingKeysIdx != null) { result |= missingKeysIdx.remove(queries, j, value); if (missingKeysIdx.isEmpty()) missingKeysIdx = null; diff --git a/spectator-reg-atlas/src/test/java/com/netflix/spectator/atlas/impl/QueryIndexTest.java b/spectator-reg-atlas/src/test/java/com/netflix/spectator/atlas/impl/QueryIndexTest.java index 750008408..55f3906c3 100644 --- a/spectator-reg-atlas/src/test/java/com/netflix/spectator/atlas/impl/QueryIndexTest.java +++ b/spectator-reg-atlas/src/test/java/com/netflix/spectator/atlas/impl/QueryIndexTest.java @@ -372,6 +372,16 @@ public void multiNotInClause() { Assertions.assertTrue(idx.findMatches(id("cpu", "id", "iowait")).isEmpty()); } + @Test + public void doubleNotsSameKey() { + Query q = Parser.parseQuery("a,1,:eq,b,2,:eq,:and,c,3,:eq,:not,:and,c,4,:eq,:not,:and"); + QueryIndex idx = QueryIndex.newInstance(registry).add(q, q); + Assertions.assertFalse(idx.findMatches(id("cpu", "a", "1", "b", "2", "c", "5")).isEmpty()); + Assertions.assertTrue(idx.findMatches(id("cpu", "a", "1", "b", "2", "c", "3")).isEmpty()); + Assertions.assertTrue(idx.findMatches(id("cpu", "a", "1", "b", "2", "c", "4")).isEmpty()); + Assertions.assertFalse(idx.findMatches(id("cpu", "a", "1", "b", "2")).isEmpty()); + } + @Test public void removalOfNotQuery() { Query q = Parser.parseQuery("name,cpu,:eq,id,user,:eq,:not,:and");