in pkg/query/logical/index_filter.go [235:301]
func parseEntities(op modelv1.LogicalExpression_LogicalOp, input tsdb.Entity, left, right []tsdb.Entity) []tsdb.Entity {
count := len(input)
result := make(tsdb.Entity, count)
anyEntity := func(entities []tsdb.Entity) bool {
for _, entity := range entities {
for _, entry := range entity {
if !bytes.Equal(entry, tsdb.AnyEntry) {
return false
}
}
}
return true
}
leftAny := anyEntity(left)
rightAny := anyEntity(right)
mergedEntities := make([]tsdb.Entity, 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 := tsdb.AnyEntry
for j := 0; j < len(mergedEntities); j++ {
e := mergedEntities[j][i]
if bytes.Equal(e, tsdb.AnyEntry) {
continue
}
if bytes.Equal(entry, tsdb.AnyEntry) {
entry = e
} else if !bytes.Equal(entry, e) {
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 := tsdb.AnyEntry
for j := 0; j < len(mergedEntities); j++ {
e := mergedEntities[j][i]
if bytes.Equal(entry, tsdb.AnyEntry) {
entry = e
} else if !bytes.Equal(entry, e) {
return mergedEntities
}
}
result[i] = entry
}
}
return []tsdb.Entity{result}
}