func parseEntities()

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}
}