in pkg/query/logical/parser.go [110:176]
func ParseEntities(op modelv1.LogicalExpression_LogicalOp, input []*modelv1.TagValue, left, right [][]*modelv1.TagValue) [][]*modelv1.TagValue {
count := len(input)
result := make([]*modelv1.TagValue, count)
anyEntity := func(entities [][]*modelv1.TagValue) bool {
for _, entity := range entities {
for _, entry := range entity {
if entry != pbv1.AnyTagValue {
return false
}
}
}
return true
}
leftAny := anyEntity(left)
rightAny := anyEntity(right)
mergedEntities := make([][]*modelv1.TagValue, 0, len(left)+len(right))
switch op {
case modelv1.LogicalExpression_LOGICAL_OP_AND:
if leftAny && !rightAny {
return right
}
if !leftAny && rightAny {
return left
}
mergedEntities = append(mergedEntities, left...)
mergedEntities = append(mergedEntities, right...)
for i := 0; i < count; i++ {
entry := pbv1.AnyTagValue
for j := 0; j < len(mergedEntities); j++ {
e := mergedEntities[j][i]
if e == pbv1.AnyTagValue {
continue
}
if entry == pbv1.AnyTagValue {
entry = e
} else if pbv1.MustCompareTagValue(entry, e) != 0 {
return nil
}
}
result[i] = entry
}
case modelv1.LogicalExpression_LOGICAL_OP_OR:
if leftAny {
return left
}
if rightAny {
return right
}
mergedEntities = append(mergedEntities, left...)
mergedEntities = append(mergedEntities, right...)
for i := 0; i < count; i++ {
entry := pbv1.AnyTagValue
for j := 0; j < len(mergedEntities); j++ {
e := mergedEntities[j][i]
if entry == pbv1.AnyTagValue {
entry = e
} else if pbv1.MustCompareTagValue(entry, e) != 0 {
return mergedEntities
}
}
result[i] = entry
}
}
return [][]*modelv1.TagValue{result}
}