Exemple #1
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
}
Exemple #2
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)))
	}
}
Exemple #3
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
}
Exemple #4
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
}
Exemple #5
0
func getValue(attr, data string) (types.Value, error) {
	// Parse given value and get token. There should be only one token.
	t := schema.TypeOf(attr)
	if t == nil || !t.IsScalar() {
		return nil, x.Errorf("Attribute %s is not valid scalar type", attr)
	}

	schemaType := t.(types.Scalar)
	v := types.ValueForType(schemaType.ID())
	err := v.UnmarshalText([]byte(data))
	if err != nil {
		return nil, err
	}
	return v, nil
}
Exemple #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
}
Exemple #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
}
Exemple #8
0
// Parse parses a mutation string and returns the NQuad representation for it.
func Parse(line string) (rnq NQuad, rerr error) {
	l := &lex.Lexer{}
	l.Init(line)

	go run(l)
	var oval string
	var vend bool
	// We read items from the l.Items channel to which the lexer sends items.
	for item := range l.Items {
		switch item.Typ {
		case itemSubject:
			rnq.Subject = stripBracketsAndTrim(item.Val)

		case itemPredicate:
			rnq.Predicate = stripBracketsAndTrim(item.Val)

		case itemObject:
			rnq.ObjectId = stripBracketsAndTrim(item.Val)

		case itemLiteral:
			oval = item.Val

		case itemLanguage:
			rnq.Predicate += "." + item.Val

		case itemObjectType:
			if len(oval) == 0 {
				log.Fatalf(
					"itemObject should be emitted before itemObjectType. Input: [%s]",
					line)
			}
			val := stripBracketsAndTrim(item.Val)
			if strings.Trim(val, " ") == "*" {
				return rnq, fmt.Errorf("itemObject can't be *")
			}
			if t, ok := typeMap[val]; ok {
				p := types.ValueForType(t)
				err := p.UnmarshalText([]byte(oval))
				if err != nil {
					return rnq, err
				}
				rnq.ObjectValue, err = p.MarshalBinary()
				if err != nil {
					return rnq, err
				}
				rnq.ObjectType = byte(t)
				oval = ""
			} else {
				oval += "@@" + val
			}

		case lex.ItemError:
			return rnq, fmt.Errorf(item.Val)

		case itemValidEnd:
			vend = true

		case itemLabel:
			rnq.Label = stripBracketsAndTrim(item.Val)
		}
	}

	if !vend {
		return rnq, fmt.Errorf("Invalid end of input. Input: [%s]", line)
	}
	if len(oval) > 0 {
		rnq.ObjectValue = []byte(oval)
		// If no type is specified, we default to string.
		rnq.ObjectType = 0
	}
	if len(rnq.Subject) == 0 || len(rnq.Predicate) == 0 {
		return rnq, fmt.Errorf("Empty required fields in NQuad. Input: [%s]", line)
	}
	if len(rnq.ObjectId) == 0 && rnq.ObjectValue == nil {
		return rnq, fmt.Errorf("No Object in NQuad. Input: [%s]", line)
	}
	if !sane(rnq.Subject) || !sane(rnq.Predicate) || !sane(rnq.ObjectId) ||
		!sane(rnq.Label) {
		return rnq, fmt.Errorf("NQuad failed sanity check:%+v", rnq)
	}

	return rnq, nil
}