search: WIP notes on RelationConstraint. Not implemented yet.

Change-Id: Ic179a046da146706b57d7e6e031e1665deedd036
This commit is contained in:
Brad Fitzpatrick 2013-12-11 13:46:19 +04:00
parent aef2fba3e1
commit bbaf755995
2 changed files with 84 additions and 0 deletions

View File

@ -345,11 +345,39 @@ type PermanodeConstraint struct {
// (which must be a blobref) must be a part of.
ValueInSet *Constraint `json:"valueInSet"`
// Relation optionally specifies a constraint based on relations
// to other permanodes (e.g. camliMember or camliPath sets).
// You can use it to test the properties of a parent, ancestor,
// child, or progeny.
Relation *RelationConstraint
// TODO:
// NumClaims *IntConstraint // by owner
// Owner blob.Ref // search for permanodes by an owner
}
type RelationConstraint struct {
// Relation must be one of:
//
// * "child"
// * "progeny" (any level down)
// * "parent" (immediate parent only)
// * "ancestor" (any level up)
Relation string
// EdgeType optionally specifies an edge type.
// By default it matches "camliMember" and "camliPath:*".
EdgeType string
// After finding all the nodes matching the Relation and
// EdgeType, either one or all (depending on whether Any or
// All is set) must then match for the RelationConstraint
// itself to match.
//
// It is an error to set both.
Any, All *Constraint
}
// search is the state of an in-progress search
type search struct {
h *Handler

View File

@ -612,6 +612,62 @@ func TestQueryPermanodeValueAll(t *testing.T) {
})
}
// permanodes tagged "foo" or those in sets where the parent
// permanode set itself is tagged "foo".
func TestQueryPermanodeTaggedViaParent(t *testing.T) {
t.Skip("TODO: finish implementing")
testQuery(t, func(qt *queryTest) {
id := qt.id
ptagged := id.NewPlannedPermanode("tagged_photo")
pindirect := id.NewPlannedPermanode("via_parent")
pset := id.NewPlannedPermanode("set")
pboth := id.NewPlannedPermanode("both") // funny directly and via its parent
pnotfunny := id.NewPlannedPermanode("not_funny")
id.SetAttribute(ptagged, "tag", "funny")
id.SetAttribute(pset, "tag", "funny")
id.SetAttribute(pboth, "tag", "funny")
id.AddAttribute(pset, "camliMember", pindirect.String())
id.AddAttribute(pset, "camliMember", pboth.String())
id.SetAttribute(pnotfunny, "tag", "boring")
sq := &SearchQuery{
Constraint: &Constraint{
Logical: &LogicalConstraint{
Op: "or",
// Those tagged funny directly:
A: &Constraint{
Permanode: &PermanodeConstraint{
Attr: "tag",
Value: "funny",
},
},
// Those tagged funny indirectly:
B: &Constraint{
Permanode: &PermanodeConstraint{
Relation: &RelationConstraint{
Relation: "ancestor", // "parent", "child", "progeny"
// Counter-part to "Any" is "All". Only one may be set.
Any: &Constraint{
Permanode: &PermanodeConstraint{
Attr: "tag",
Value: "funny",
},
},
},
},
},
},
},
}
qt.wantRes(sq, ptagged, pset, pboth, pindirect)
})
}
func TestLimitDoesntDeadlock(t *testing.T) {
// TODO: care about classic (allIndexTypes) too?
testQueryTypes(t, memIndexTypes, func(qt *queryTest) {