Example #1
0
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)))
	}
}
Example #2
0
// 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
}
Example #3
0
// 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
}
Example #4
0
// 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
}
Example #5
0
// 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
}
Example #6
0
// 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
}
Example #7
0
// 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
}