fix(storage): fixes panic when building predicates

Fixes #15916.

If a predicate was passed in with multiple key/value matches for the
same tag key, then the value index would be incorrect. This ensures that
each tag key can only be added to the location map once.
pull/15933/head
Edd Robinson 2019-11-15 15:07:36 +00:00
parent d3381c4cc0
commit 2471c2468c
2 changed files with 19 additions and 1 deletions

View File

@ -75,9 +75,17 @@ func NewProtobufPredicate(pred *datatypes.Predicate) (Predicate, error) {
if node.GetNodeType() == datatypes.NodeTypeTagRef {
switch value := node.GetValue().(type) {
case *datatypes.Node_TagRefValue:
// Only add to the matcher locations the first time we encounter
// the tag key reference. This prevents problems with redundant
// predicates like:
//
// foo = a AND foo = b
// foo = c AND foo = d
if _, ok := locs[value.TagRefValue]; !ok {
locs[value.TagRefValue] = len(locs)
}
}
}
})
// Construct the shared state and root predicate node.

View File

@ -85,6 +85,16 @@ func TestPredicate_Matches(t *testing.T) {
Matches: true,
},
{
Name: "Logical And Matching Reduce (Simplify)",
Predicate: predicate(
andNode(
comparisonNode(datatypes.ComparisonEqual, tagNode("foo"), stringNode("bar")),
comparisonNode(datatypes.ComparisonNotEqual, tagNode("foo"), stringNode("bif")))),
Key: "bucketorg,baz=bif,foo=bar,tag3=val3",
Matches: true,
},
{
Name: "Regex Matching",
Predicate: predicate(