in pkg/index/inverted/query.go [73:164]
func BuildQuery(criteria *modelv1.Criteria, schema logical.Schema, entityDict map[string]int,
entity []*modelv1.TagValue,
) (index.Query, [][]*modelv1.TagValue, bool, error) {
if criteria == nil {
return nil, [][]*modelv1.TagValue{entity}, false, 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, false, err
}
if parsedEntity != nil {
return nil, parsedEntity, false, nil
}
if ok, indexRule := schema.IndexDefined(cond.Name); ok {
fk := index.FieldKey{IndexRuleID: indexRule.Metadata.Id}
q, err := parseConditionToQuery(cond, indexRule, expr, fk.Marshal())
if err != nil {
return nil, nil, false, err
}
return q, [][]*modelv1.TagValue{entity}, false, nil
}
return nil, nil, false, errors.Wrapf(logical.ErrUnsupportedConditionOp, "mandatory index rule conf:%s", cond)
case *modelv1.Criteria_Le:
le := criteria.GetLe()
if le.GetLeft() == nil && le.GetRight() == nil {
return nil, nil, false, errors.WithMessagef(logical.ErrInvalidLogicalExpression, "both sides(left and right) of [%v] are empty", criteria)
}
if le.GetLeft() == nil {
return BuildQuery(le.Right, schema, entityDict, entity)
}
if le.GetRight() == nil {
return BuildQuery(le.Left, schema, entityDict, entity)
}
left, leftEntities, leftIsMatchAllQuery, err := BuildQuery(le.Left, schema, entityDict, entity)
if err != nil {
return nil, nil, false, err
}
right, rightEntities, rightIsMatchAllQuery, err := BuildQuery(le.Right, schema, entityDict, entity)
if err != nil {
return nil, nil, false, err
}
entities := logical.ParseEntities(le.Op, entity, leftEntities, rightEntities)
if entities == nil {
return nil, nil, false, nil
}
if left == nil && right == nil {
return nil, entities, false, nil
}
if leftIsMatchAllQuery && rightIsMatchAllQuery {
return &queryNode{
query: bluge.NewMatchAllQuery(),
node: newMatchAllNode(),
}, entities, true, nil
}
switch le.Op {
case modelv1.LogicalExpression_LOGICAL_OP_AND:
query, node := bluge.NewBooleanQuery(), newMustNode()
if left != nil {
query.AddMust(left.(*queryNode).query)
node.Append(left.(*queryNode).node)
}
if right != nil {
query.AddMust(right.(*queryNode).query)
node.Append(right.(*queryNode).node)
}
return &queryNode{query, node}, entities, false, nil
case modelv1.LogicalExpression_LOGICAL_OP_OR:
if leftIsMatchAllQuery || rightIsMatchAllQuery {
return &queryNode{
query: bluge.NewMatchAllQuery(),
node: newMatchAllNode(),
}, entities, true, nil
}
query, node := bluge.NewBooleanQuery(), newShouldNode()
query.SetMinShould(1)
if left != nil {
query.AddShould(left.(*queryNode).query)
node.Append(left.(*queryNode).node)
}
if right != nil {
query.AddShould(right.(*queryNode).query)
node.Append(right.(*queryNode).node)
}
return &queryNode{query, node}, entities, false, nil
}
return nil, nil, false, logical.ErrInvalidCriteriaType
}
return nil, nil, false, logical.ErrInvalidCriteriaType
}