(ctx context.Context, q *pb.Query, gid uint32)
| 1071 | } |
| 1072 | |
| 1073 | func (qs *queryState) helpProcessTask(ctx context.Context, q *pb.Query, gid uint32) ( |
| 1074 | *pb.Result, error) { |
| 1075 | |
| 1076 | span := trace.SpanFromContext(ctx) |
| 1077 | out := new(pb.Result) |
| 1078 | attr := q.Attr |
| 1079 | |
| 1080 | srcFn, err := parseSrcFn(ctx, q) |
| 1081 | if err != nil { |
| 1082 | return nil, err |
| 1083 | } |
| 1084 | |
| 1085 | if q.Reverse && !schema.State().IsReversed(ctx, attr) { |
| 1086 | return nil, errors.Errorf("Predicate %s doesn't have reverse edge", x.ParseAttr(attr)) |
| 1087 | } |
| 1088 | |
| 1089 | if needsIndex(srcFn.fnType, q.UidList) && !schema.State().IsIndexed(ctx, q.Attr) { |
| 1090 | return nil, errors.Errorf("Predicate %s is not indexed", x.ParseAttr(q.Attr)) |
| 1091 | } |
| 1092 | |
| 1093 | if len(q.Langs) > 0 && !schema.State().HasLang(attr) { |
| 1094 | return nil, errors.Errorf("Language tags can only be used with predicates of string type"+ |
| 1095 | " having @lang directive in schema. Got: [%v]", x.ParseAttr(attr)) |
| 1096 | } |
| 1097 | if len(q.Langs) == 1 && q.Langs[0] == "*" { |
| 1098 | // Reset the Langs fields. The ExpandAll field is set to true already so there's no |
| 1099 | // more need to store the star value in this field. |
| 1100 | q.Langs = nil |
| 1101 | } |
| 1102 | |
| 1103 | typ, err := schema.State().TypeOf(attr) |
| 1104 | if err != nil { |
| 1105 | // All schema checks are done before this, this type is only used to |
| 1106 | // convert it to schema type before returning. |
| 1107 | // Schema type won't be present only if there is no data for that predicate |
| 1108 | // or if we load through bulk loader. |
| 1109 | typ = types.DefaultID |
| 1110 | } |
| 1111 | out.List = schema.State().IsList(attr) |
| 1112 | srcFn.atype = typ |
| 1113 | |
| 1114 | // Reverse attributes might have more than 1 results even if the original attribute |
| 1115 | // is not a list. |
| 1116 | if q.Reverse { |
| 1117 | out.List = true |
| 1118 | } |
| 1119 | |
| 1120 | opts := posting.ListOptions{ |
| 1121 | ReadTs: q.ReadTs, |
| 1122 | AfterUid: q.AfterUid, |
| 1123 | First: int(q.First + q.Offset), |
| 1124 | } |
| 1125 | // If we have srcFunc and Uids, it means its a filter. So we intersect. |
| 1126 | if srcFn.fnType != notAFunction && q.UidList != nil && len(q.UidList.Uids) > 0 { |
| 1127 | opts.Intersect = q.UidList |
| 1128 | } |
| 1129 | |
| 1130 | args := funcArgs{q, gid, srcFn, out} |
no test coverage detected