func toRDF(buf *bytes.Buffer, item kv) { pl := item.list for _, p := range pl.Postings { x.Check2(buf.WriteString(item.prefix)) if p.Uid == math.MaxUint64 && !bytes.Equal(p.Value, nil) { // Value posting // Convert to appropriate type typ := stype.ValueForType(stype.TypeID(p.ValType)) x.Check(typ.UnmarshalBinary(p.Value)) str, err := typ.MarshalText() x.Check(err) x.Check2(buf.WriteString(fmt.Sprintf("\"%s\"", str))) if p.ValType == uint32(stype.GeoID) { x.Check2(buf.WriteString(fmt.Sprintf("^^<geo:geojson> "))) } else if p.ValType != uint32(stype.BytesID) { x.Check2(buf.WriteString(fmt.Sprintf("^^<xs:%s> ", typ.Type().Name))) } x.Check2(buf.WriteString(" .\n")) return } x.Check2(buf.WriteString(fmt.Sprintf("<_uid_:%#x> .\n", p.Uid))) } }
// validateTypes checks for predicate types present in the schema and validates if the // input value is of the correct type func validateTypes(nquads []rdf.NQuad) error { for i := range nquads { nquad := &nquads[i] if t := schema.TypeOf(nquad.Predicate); t != nil && t.IsScalar() { schemaType := t.(types.Scalar) typeID := types.TypeID(nquad.ObjectType) if typeID == types.BytesID { // Storage type was unspecified in the RDF, so we convert the data to the schema // type. v := types.ValueForType(schemaType.ID()) err := v.UnmarshalText(nquad.ObjectValue) if err != nil { return err } nquad.ObjectValue, err = v.MarshalBinary() if err != nil { return err } nquad.ObjectType = byte(schemaType.ID()) } else if typeID != schemaType.ID() { v := types.ValueForType(typeID) err := v.UnmarshalBinary(nquad.ObjectValue) if err != nil { return err } if _, err := schemaType.Convert(v); err != nil { return err } } } } return nil }
// FilterUids filters the uids based on the corresponding values and QueryData. func FilterUids(uids *task.List, values []*task.Value, q *QueryData) *task.List { x.AssertTruef(len(values) == len(uids.Uids), "lengths not matching") rv := &task.List{} for i := 0; i < len(values); i++ { valBytes := values[i].Val if bytes.Equal(valBytes, nil) { continue } vType := values[i].ValType if types.TypeID(vType) != types.GeoID { continue } var g types.Geo if err := g.UnmarshalBinary(valBytes); err != nil { continue } if !q.MatchesFilter(g) { continue } // we matched the geo filter, add the uid to the list rv.Uids = append(rv.Uids, uids.Uids[i]) } return rv }
// AddMutationWithIndex is AddMutation with support for indexing. func (l *List) AddMutationWithIndex(ctx context.Context, t *task.DirectedEdge, op uint32) error { x.AssertTruef(len(t.Attr) > 0, "[%s] [%d] [%v] %d %d\n", t.Attr, t.Entity, t.Value, t.ValueId, op) var vbytes []byte var vtype byte var verr error doUpdateIndex := pstore != nil && (t.Value != nil) && schema.IsIndexed(t.Attr) if doUpdateIndex { // Check last posting for original value BEFORE any mutation actually happens. vbytes, vtype, verr = l.Value() } hasMutated, err := l.AddMutation(ctx, t, op) if err != nil { return err } if !hasMutated || !doUpdateIndex { return nil } // Exact matches. if verr == nil && len(vbytes) > 0 { delTerm := vbytes delType := vtype p := types.ValueForType(types.TypeID(delType)) if err := p.UnmarshalBinary(delTerm); err != nil { return err } addIndexMutations(ctx, t.Attr, t.Entity, p, true) } if op == Set { p := types.ValueForType(types.TypeID(t.ValueType)) if err := p.UnmarshalBinary(t.Value); err != nil { return err } addIndexMutations(ctx, t.Attr, t.Entity, p, false) } return nil }
// getValue gets the value from the task. func getValue(tv *task.Value) (types.Value, error) { vType := tv.ValType valBytes := tv.Val val := types.ValueForType(types.TypeID(vType)) if val == nil { return nil, x.Errorf("Invalid type: %v", vType) } if err := val.UnmarshalBinary(valBytes); err != nil { return nil, err } return val, nil }
// getPostingValue looks up key, gets the value, converts it. If any error is // encountered, we return nil. This is used in some filtering where we do not // want to waste time creating errors. func getPostingValue(key []byte, scalarType types.Scalar) *types.Value { pl, decr := posting.GetOrCreate(key) defer decr() valBytes, vType, err := pl.Value() if bytes.Equal(valBytes, nil) { return nil } val := types.ValueForType(types.TypeID(vType)) if val == nil { return nil } if err := val.UnmarshalBinary(valBytes); err != nil { return nil } // Convert to schema type. sv, err := scalarType.Convert(val) if err != nil { return nil } return &sv }
// fetchValue gets the value for a given UID. func fetchValue(uid uint64, attr string, scalar types.Scalar) (types.Value, error) { pl, decr := posting.GetOrCreate(x.DataKey(attr, uid)) defer decr() valBytes, vType, err := pl.Value() if err != nil { return nil, err } val := types.ValueForType(types.TypeID(vType)) if val == nil { return nil, x.Errorf("Invalid type: %v", vType) } err = val.UnmarshalBinary(valBytes) if err != nil { return nil, err } schemaVal, err := scalar.Convert(val) if err != nil { return nil, err } return schemaVal, nil }