in pkg/query/logical/stream/index_filter.go [35:99]
func buildLocalFilter(criteria *modelv1.Criteria, schema logical.Schema,
entityDict map[string]int, entity []*modelv1.TagValue,
) (index.Filter, [][]*modelv1.TagValue, error) {
if criteria == nil {
return nil, [][]*modelv1.TagValue{entity}, nil
}
switch criteria.GetExp().(type) {
case *modelv1.Criteria_Condition:
cond := criteria.GetCondition()
expr, parsedEntity, err := logical.ParseExprOrEntity(entityDict, entity, cond)
if err != nil {
return nil, nil, err
}
if parsedEntity != nil {
return nil, parsedEntity, nil
}
if ok, indexRule := schema.IndexDefined(cond.Name); ok {
return parseConditionToFilter(cond, indexRule, expr, entity)
}
return ENode, [][]*modelv1.TagValue{entity}, nil
case *modelv1.Criteria_Le:
le := criteria.GetLe()
if le.GetLeft() == nil && le.GetRight() == nil {
return nil, nil, errors.WithMessagef(logical.ErrInvalidLogicalExpression, "both sides(left and right) of [%v] are empty", criteria)
}
if le.GetLeft() == nil {
return buildLocalFilter(le.Right, schema, entityDict, entity)
}
if le.GetRight() == nil {
return buildLocalFilter(le.Left, schema, entityDict, entity)
}
left, leftEntities, err := buildLocalFilter(le.Left, schema, entityDict, entity)
if err != nil {
return nil, nil, err
}
right, rightEntities, err := buildLocalFilter(le.Right, schema, entityDict, entity)
if err != nil {
return nil, nil, err
}
entities := logical.ParseEntities(le.Op, entity, leftEntities, rightEntities)
if entities == nil {
return nil, nil, nil
}
if left == nil && right == nil {
return nil, entities, nil
}
if left == ENode && right == ENode {
return ENode, entities, nil
}
switch le.Op {
case modelv1.LogicalExpression_LOGICAL_OP_AND:
and := newAnd(2)
and.append(left).append(right)
return and, entities, nil
case modelv1.LogicalExpression_LOGICAL_OP_OR:
if left == ENode || right == ENode {
return ENode, entities, nil
}
or := newOr(2)
or.append(left).append(right)
return or, entities, nil
}
}
return nil, nil, logical.ErrInvalidCriteriaType
}