veyron2/query/parse: Replace "{foo as bar}" syntax with "{bar: foo}".
Some people found the old alias syntax difficult to parse visually,
so this changes it to be more like a struct literal. This is
helpful when the sub-query is really long-- it can be difficult
to find the name of the result when it is all the way at the end
of the subquery.
This change adds the requirement that all subqueries have an explicit
name. This makes it obvious what to name a subquery of '.' (i.e. the
whole object). The old code named it "" which is kind of a weird
key to have in a map. Now, the developer will choose.
The downside of required alias names is redundancy (e.g. "{Name: Name}").
We'll see if it is a problem and possibly make it optional in
the future (e.g. "{Name, myloc: Location}").
Change-Id: Icd6e82a848aa88ba87ac08adae6642a819c97d80
diff --git a/services/store/memstore/query/eval_test.go b/services/store/memstore/query/eval_test.go
index 65359b2..6c28c11 100644
--- a/services/store/memstore/query/eval_test.go
+++ b/services/store/memstore/query/eval_test.go
@@ -309,31 +309,31 @@
tests := []testCase{
{
- "", "'teams/cardinals' | {Name}",
+ "", "'teams/cardinals' | {Name: Name}",
[]*store.QueryResult{
&store.QueryResult{0, "teams/cardinals", map[string]vdlutil.Any{"Name": "cardinals"}, nil},
},
},
{
- "teams", "'cardinals' | {Name}",
+ "teams", "'cardinals' | {Name: Name}",
[]*store.QueryResult{
&store.QueryResult{0, "cardinals", map[string]vdlutil.Any{"Name": "cardinals"}, nil},
},
},
{
- "teams/cardinals", ". | {Name}",
+ "teams/cardinals", ". | {Name: Name}",
[]*store.QueryResult{
&store.QueryResult{0, "", map[string]vdlutil.Any{"Name": "cardinals"}, nil},
},
},
{
- "", "'teams/cardinals' | {Name as Name}",
+ "", "'teams/cardinals' | {Name: Name}",
[]*store.QueryResult{
&store.QueryResult{0, "teams/cardinals", map[string]vdlutil.Any{"Name": "cardinals"}, nil},
},
},
{
- "", "'teams/cardinals' | {Name as myname, Location as myloc}",
+ "", "'teams/cardinals' | {myname: Name, myloc: Location}",
[]*store.QueryResult{
&store.QueryResult{
0,
@@ -347,7 +347,7 @@
},
},
{
- "", "'teams/cardinals' | {Name as myname, Location as myloc} | ? myname == 'cardinals'",
+ "", "'teams/cardinals' | {myname: Name, myloc: Location} | ? myname == 'cardinals'",
[]*store.QueryResult{
&store.QueryResult{
0,
@@ -361,7 +361,7 @@
},
},
{
- "", "'teams/cardinals' | {Name as myname hidden, Location as myloc} | ? myname == 'cardinals'",
+ "", "'teams/cardinals' | {myname hidden: Name, myloc: Location} | ? myname == 'cardinals'",
[]*store.QueryResult{
&store.QueryResult{
0,
@@ -374,11 +374,25 @@
},
},
{
+ "", "'teams/cardinals' | {self: ., myname: Name} | ? myname == 'cardinals'",
+ []*store.QueryResult{
+ &store.QueryResult{
+ 0,
+ "teams/cardinals",
+ map[string]vdlutil.Any{
+ "self": team{"cardinals", "CA"},
+ "myname": "cardinals",
+ },
+ nil,
+ },
+ },
+ },
+ {
"",
"'teams/*' | type team | {" +
- " Name as myname," +
- " players/* | type player | ?Age >=21 | sort() as drinkers," +
- " players/* | type player | ?Age < 21 | sort() as nondrinkers" +
+ " myname: Name," +
+ " drinkers: players/* | type player | ?Age >=21 | sort()," +
+ " nondrinkers: players/* | type player | ?Age < 21 | sort()" +
"} | sort(myname)",
[]*store.QueryResult{
&store.QueryResult{
@@ -440,14 +454,14 @@
// 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()",
+ "", "'players/*' | type player | {Name: Name, hometown: 'bio/hometown'} | ? Name == 'alfred' || Name == 'betty' | sort()",
[]*store.QueryResult{
&store.QueryResult{
0,
"players/alfred",
map[string]vdlutil.Any{
- "Name": "alfred",
- "bio/hometown": nil,
+ "Name": "alfred",
+ "hometown": nil,
},
nil,
},
@@ -455,8 +469,8 @@
0,
"players/betty",
map[string]vdlutil.Any{
- "Name": "betty",
- "bio/hometown": "Tampa",
+ "Name": "betty",
+ "hometown": "Tampa",
},
nil,
},
@@ -508,7 +522,7 @@
// TODO(kash): We probably want an error message that says that you must
// use a type filter.
{"teams/* | ?Name > 'foo'", "could not look up name 'Name' relative to 'teams': not found"},
- {"'teams/cardinals' | {Name as myname, Location as myloc} | ? Name == 'foo'", "name 'Name' was not selected from 'teams/cardinals', found: [myloc, myname]"},
+ {"'teams/cardinals' | {myname: Name, myloc: Location} | ? Name == 'foo'", "name 'Name' was not selected from 'teams/cardinals', found: [myloc, myname]"},
{"teams/* | type team | sort(Name) | ?-Name > 'foo'", "cannot negate value of type string for teams/bears"},
// TODO(kash): Selection with conflicting names.