func BuildQuery()

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
}