veyron/services/store/memstore/query: Better handling of slashes in selection.
Ensure that selection of sub-sub-fields works. Also, allow for aliases to
contain slashes. I don't see any reason why they can't, and it matches the
behavior of selection of sub-sub-fields.
Fix a bug in selection: if an intermediate result does not have a value
for one of the sub pipelines, use nil as the value instead of aborting
the query (without an error message).
Change-Id: I631f7f80b562096f725ef566b648fe711534b94a
diff --git a/services/store/memstore/query/eval.go b/services/store/memstore/query/eval.go
index 73fa455..783fbd8 100644
--- a/services/store/memstore/query/eval.go
+++ b/services/store/memstore/query/eval.go
@@ -501,7 +501,6 @@
pos: p.Pos,
}
for i, a := range p.SubPipelines {
- // TODO(kash): Protect against aliases that have slashes in them?
e.subpipelines[i] = alias{convertPipeline(a.Pipeline), a.Alias, a.Hidden}
}
return e
@@ -580,10 +579,9 @@
case <-c.abort:
return false
case sub, ok := <-out:
- if !ok {
- return false
+ if ok {
+ value = sub.Value
}
- value = sub.Value
}
} else {
value = out
diff --git a/services/store/memstore/query/eval_test.go b/services/store/memstore/query/eval_test.go
index 6367a9f..65359b2 100644
--- a/services/store/memstore/query/eval_test.go
+++ b/services/store/memstore/query/eval_test.go
@@ -40,6 +40,9 @@
bettyID := put(t, sn, "/players/betty", player{"betty", 23})
bobID := put(t, sn, "/players/bob", player{"bob", 21})
+ put(t, sn, "/players/betty/bio", "")
+ put(t, sn, "/players/betty/bio/hometown", "Tampa")
+
put(t, sn, "/teams", "")
put(t, sn, "/teams/cardinals", team{"cardinals", "CA"})
put(t, sn, "/teams/sharks", team{"sharks", "NY"})
@@ -434,6 +437,31 @@
},
},
},
+ // Test for selection of a nested name ('bio/hometown'). Only betty has this
+ // nested name, so other players should get a nil value.
+ {
+ "", "'players/*' | type player | {Name, 'bio/hometown'} | ? Name == 'alfred' || Name == 'betty' | sort()",
+ []*store.QueryResult{
+ &store.QueryResult{
+ 0,
+ "players/alfred",
+ map[string]vdlutil.Any{
+ "Name": "alfred",
+ "bio/hometown": nil,
+ },
+ nil,
+ },
+ &store.QueryResult{
+ 0,
+ "players/betty",
+ map[string]vdlutil.Any{
+ "Name": "betty",
+ "bio/hometown": "Tampa",
+ },
+ nil,
+ },
+ },
+ },
}
for _, test := range tests {
vlog.VI(1).Infof("Testing %s\n", test.query)