(ctx context.Context, q *pb.Query, out *pb.Result, srcFn *functionContext)
| 2677 | } |
| 2678 | |
| 2679 | func (qs *queryState) handleHasFunction(ctx context.Context, q *pb.Query, out *pb.Result, |
| 2680 | srcFn *functionContext) error { |
| 2681 | span := trace.SpanFromContext(ctx) |
| 2682 | stop := x.SpanTimer(span, "handleHasFunction") |
| 2683 | defer stop() |
| 2684 | if glog.V(3) { |
| 2685 | glog.Infof("handleHasFunction query: %+v\n", q) |
| 2686 | } |
| 2687 | |
| 2688 | hasOrders := q.Order != nil && len(q.Order.Order) > 0 |
| 2689 | |
| 2690 | sch, ok := schema.State().Get(ctx, q.Attr) |
| 2691 | isSortablePred := false |
| 2692 | if ok { |
| 2693 | isSortablePred = (sch.ValueType == pb.Posting_INT || sch.ValueType == pb.Posting_FLOAT || sch.ValueType == pb.Posting_DATETIME) |
| 2694 | } |
| 2695 | |
| 2696 | isIndexed := schema.State().IsIndexed(ctx, q.Attr) |
| 2697 | if isIndexed && ok && isSortablePred && hasOrders { |
| 2698 | var order *pb.Order |
| 2699 | for _, i := range q.Order.Order { |
| 2700 | if i.Attr == q.Attr { |
| 2701 | order = i |
| 2702 | break |
| 2703 | } |
| 2704 | } |
| 2705 | if order != nil { |
| 2706 | return qs.handleHasWithOrderFunction(ctx, q, out, order.Desc, int(q.Order.Offset), int(q.Order.Count), srcFn) |
| 2707 | } |
| 2708 | } |
| 2709 | |
| 2710 | initKey := x.ParsedKey{ |
| 2711 | Attr: q.Attr, |
| 2712 | } |
| 2713 | startKey := x.DataKey(q.Attr, q.AfterUid+1) |
| 2714 | prefix := initKey.DataPrefix() |
| 2715 | if q.Reverse { |
| 2716 | // Reverse does not mean reverse iteration. It means we're looking for |
| 2717 | // the reverse index. |
| 2718 | startKey = x.ReverseKey(q.Attr, q.AfterUid+1) |
| 2719 | prefix = initKey.ReversePrefix() |
| 2720 | } |
| 2721 | |
| 2722 | result := &pb.List{} |
| 2723 | |
| 2724 | lang := langForFunc(q.Langs) |
| 2725 | needFiltering := needsStringFiltering(srcFn, q.Langs, q.Attr) |
| 2726 | |
| 2727 | // This function checks if we should include uid in result or not when has is queried with |
| 2728 | // @lang(eg: has(name@en)). We need to do this inside this function to return correct result |
| 2729 | // for first. |
| 2730 | checkInclusion := func(uid uint64) error { |
| 2731 | if !needFiltering { |
| 2732 | return nil |
| 2733 | } |
| 2734 | |
| 2735 | _, err := qs.getValsForUID(q.Attr, lang, uid, q.ReadTs) |
| 2736 | return err |
no test coverage detected