From 025ae345bce8c210a4aa1ada67d308d4ef91e010 Mon Sep 17 00:00:00 2001 From: Martin Martinez Rivera Date: Mon, 21 Jan 2019 16:58:09 -0800 Subject: [PATCH] Output non-list uid predicates as a map. (#2921) Currently these predicates are outputted as a list, despite the fact that only one value is ever allowed. This PR changes the query code so that these predicates are outputted to json as a map. --- contrib/integration/testtxn/main_test.go | 4 ++-- query/common_test.go | 3 +++ query/query.go | 6 +++++- query/query0_test.go | 17 +++++++++++++++++ query/query3_test.go | 18 +++++++++--------- systest/mutations_test.go | 2 +- systest/queries_test.go | 2 +- 7 files changed, 38 insertions(+), 14 deletions(-) diff --git a/contrib/integration/testtxn/main_test.go b/contrib/integration/testtxn/main_test.go index 5b8691a2313..586cafe79b3 100644 --- a/contrib/integration/testtxn/main_test.go +++ b/contrib/integration/testtxn/main_test.go @@ -572,7 +572,7 @@ func TestSPStar(t *testing.T) { require.NoError(t, s.dg.Alter(context.Background(), op)) op = &api.Operation{} - op.Schema = `friend: uid .` + op.Schema = `friend: [uid] .` require.NoError(t, s.dg.Alter(context.Background(), op)) txn := s.dg.NewTxn() @@ -620,7 +620,7 @@ func TestSPStar2(t *testing.T) { require.NoError(t, s.dg.Alter(context.Background(), op)) op = &api.Operation{} - op.Schema = `friend: uid .` + op.Schema = `friend: [uid] .` require.NoError(t, s.dg.Alter(context.Background(), op)) // Add edge diff --git a/query/common_test.go b/query/common_test.go index eea4eab7495..a89a842aa71 100644 --- a/query/common_test.go +++ b/query/common_test.go @@ -331,6 +331,7 @@ password : password . symbol : string @index(exact) . room : string @index(term) . office.room : [uid] . +best_friend : uid . ` err := schema.ParseBytes([]byte(schemaStr), 1) @@ -359,6 +360,8 @@ office.room : [uid] . addEdgeToUID(t, "friend", 31, 24, nil) addEdgeToUID(t, "friend", 23, 1, nil) + addEdgeToUID(t, "best_friend", 2, 64, nil) + addEdgeToUID(t, "school", 1, 5000, nil) addEdgeToUID(t, "school", 23, 5001, nil) addEdgeToUID(t, "school", 24, 5000, nil) diff --git a/query/query.go b/query/query.go index 914b48215d1..1a6f5e7e79b 100644 --- a/query/query.go +++ b/query/query.go @@ -466,7 +466,11 @@ func (sg *SubGraph) preTraverse(uid uint64, dst outputNode) error { if sg.Params.GetUid { uc.SetUID(childUID, "uid") } - dst.AddListChild(fieldName, uc) + if pc.List { + dst.AddListChild(fieldName, uc) + } else { + dst.AddMapChild(fieldName, uc, false) + } } } if pc.Params.uidCount && !(pc.Params.uidCountAlias == "" && pc.Params.Normalize) { diff --git a/query/query0_test.go b/query/query0_test.go index 2ecbc130a41..2aa8fd4c797 100644 --- a/query/query0_test.go +++ b/query/query0_test.go @@ -214,6 +214,23 @@ func TestFindFriendsWhoAreBetween15And19(t *testing.T) { js) } +func TestGetNonListUidPredicate(t *testing.T) { + query := ` + { + me(func: uid(0x02)) { + uid + best_friend { + uid + } + } + } + ` + js := processToFastJsonNoErr(t, query) + require.JSONEq(t, + `{"data": {"me":[{"uid":"0x2", "best_friend": {"uid": "0x40"}}]}}`, + js) +} + func TestGeAge(t *testing.T) { query := `{ senior_citizens(func: ge(age, 75)) { diff --git a/query/query3_test.go b/query/query3_test.go index 53625a1b4bf..f8c8284b35b 100644 --- a/query/query3_test.go +++ b/query/query3_test.go @@ -305,7 +305,7 @@ func TestKShortestPathWeighted(t *testing.T) { // We only get one path in this case as the facet is present only in one path. js := processToFastJsonNoErr(t, query) require.JSONEq(t, - `{"data":{"_path_":[{"uid":"0x1","path":[{"uid":"0x1f","path":[{"uid":"0x3e8","path":[{"uid":"0x3e9","path|weight":0.100000}],"path|weight":0.100000}],"path|weight":0.100000}]}]}}`, + `{"data":{"_path_":[{"uid":"0x1","path":{"uid":"0x1f","path":{"uid":"0x3e8","path":{"uid":"0x3e9","path|weight":0.100000},"path|weight":0.100000},"path|weight":0.100000}}]}}`, js) } @@ -334,7 +334,7 @@ func TestKShortestPathWeighted1(t *testing.T) { }` js := processToFastJsonNoErr(t, query) require.JSONEq(t, - `{"data":{"_path_":[{"uid":"0x1","path":[{"uid":"0x1f","path":[{"uid":"0x3e8","path":[{"uid":"0x3e9","path":[{"uid":"0x3ea","path":[{"uid":"0x3eb","path|weight":0.600000}],"path|weight":0.100000}],"path|weight":0.100000}],"path|weight":0.100000}],"path|weight":0.100000}]},{"uid":"0x1","path":[{"uid":"0x1f","path":[{"uid":"0x3e8","path":[{"uid":"0x3ea","path":[{"uid":"0x3eb","path|weight":0.600000}],"path|weight":0.700000}],"path|weight":0.100000}],"path|weight":0.100000}]},{"uid":"0x1","path":[{"uid":"0x1f","path":[{"uid":"0x3e8","path":[{"uid":"0x3e9","path":[{"uid":"0x3eb","path|weight":1.500000}],"path|weight":0.100000}],"path|weight":0.100000}],"path|weight":0.100000}]}]}}`, + `{"data":{"_path_":[{"uid":"0x1","path":{"uid":"0x1f","path":{"uid":"0x3e8","path":{"uid":"0x3e9","path":{"uid":"0x3ea","path":{"uid":"0x3eb","path|weight":0.600000},"path|weight":0.100000},"path|weight":0.100000},"path|weight":0.100000},"path|weight":0.100000}},{"uid":"0x1","path":{"uid":"0x1f","path":{"uid":"0x3e8","path":{"uid":"0x3ea","path":{"uid":"0x3eb","path|weight":0.600000},"path|weight":0.700000},"path|weight":0.100000},"path|weight":0.100000}},{"uid":"0x1","path":{"uid":"0x1f","path":{"uid":"0x3e8","path":{"uid":"0x3e9","path":{"uid":"0x3eb","path|weight":1.500000},"path|weight":0.100000},"path|weight":0.100000},"path|weight":0.100000}}]}}`, js) } @@ -352,7 +352,7 @@ func TestTwoShortestPath(t *testing.T) { }` js := processToFastJsonNoErr(t, query) require.JSONEq(t, - `{"data": {"_path_":[{"uid":"0x1","path":[{"uid":"0x1f","path":[{"uid":"0x3e8","path":[{"uid":"0x3ea"}]}]}]},{"uid":"0x1","path":[{"uid":"0x1f","path":[{"uid":"0x3e8","path":[{"uid":"0x3e9","path":[{"uid":"0x3ea"}]}]}]}]}],"me":[{"name":"Michonne"},{"name":"Andrea"},{"name":"Alice"},{"name":"Matt"}]}}`, + `{"data": {"_path_":[{"uid":"0x1","path":{"uid":"0x1f","path":{"uid":"0x3e8","path":{"uid":"0x3ea"}}}},{"uid":"0x1","path":{"uid":"0x1f","path":{"uid":"0x3e8","path":{"uid":"0x3e9","path":{"uid":"0x3ea"}}}}}],"me":[{"name":"Michonne"},{"name":"Andrea"},{"name":"Alice"},{"name":"Matt"}]}}`, js) } @@ -370,7 +370,7 @@ func TestShortestPath(t *testing.T) { }` js := processToFastJsonNoErr(t, query) require.JSONEq(t, - `{"data": {"_path_":[{"uid":"0x1","friend":[{"uid":"0x1f"}]}],"me":[{"name":"Michonne"},{"name":"Andrea"}]}}`, + `{"data": {"_path_":[{"uid":"0x1","friend":{"uid":"0x1f"}}],"me":[{"name":"Michonne"},{"name":"Andrea"}]}}`, js) } @@ -388,7 +388,7 @@ func TestShortestPathRev(t *testing.T) { }` js := processToFastJsonNoErr(t, query) require.JSONEq(t, - `{"data": {"_path_":[{"uid":"0x17","friend":[{"uid":"0x1"}]}],"me":[{"name":"Rick Grimes"},{"name":"Michonne"}]}}`, + `{"data": {"_path_":[{"uid":"0x17","friend":{"uid":"0x1"}}],"me":[{"name":"Rick Grimes"},{"name":"Michonne"}]}}`, js) } @@ -461,7 +461,7 @@ func TestShortestPathWeights(t *testing.T) { }` js := processToFastJsonNoErr(t, query) require.JSONEq(t, - `{"data":{"me":[{"name":"Michonne"},{"name":"Andrea"},{"name":"Alice"},{"name":"Bob"},{"name":"Matt"}],"_path_":[{"uid":"0x1","path":[{"uid":"0x1f","path":[{"uid":"0x3e8","path":[{"uid":"0x3e9","path":[{"uid":"0x3ea","path|weight":0.100000}],"path|weight":0.100000}],"path|weight":0.100000}],"path|weight":0.100000}]}]}}`, + `{"data":{"me":[{"name":"Michonne"},{"name":"Andrea"},{"name":"Alice"},{"name":"Bob"},{"name":"Matt"}],"_path_":[{"uid":"0x1","path":{"uid":"0x1f","path":{"uid":"0x3e8","path":{"uid":"0x3e9","path":{"uid":"0x3ea","path|weight":0.100000},"path|weight":0.100000},"path|weight":0.100000},"path|weight":0.100000}}]}}`, js) } @@ -479,7 +479,7 @@ func TestShortestPath2(t *testing.T) { }` js := processToFastJsonNoErr(t, query) require.JSONEq(t, - `{"data": {"_path_":[{"uid":"0x1","path":[{"uid":"0x1f","path":[{"uid":"0x3e8"}]}]}],"me":[{"name":"Michonne"},{"name":"Andrea"},{"name":"Alice"}]}} + `{"data": {"_path_":[{"uid":"0x1","path":{"uid":"0x1f","path":{"uid":"0x3e8"}}}],"me":[{"name":"Michonne"},{"name":"Andrea"},{"name":"Alice"}]}} `, js) } @@ -499,7 +499,7 @@ func TestShortestPath4(t *testing.T) { }` js := processToFastJsonNoErr(t, query) require.JSONEq(t, - `{"data": {"_path_":[{"uid":"0x1","follow":[{"uid":"0x1f","follow":[{"uid":"0x3e9","follow":[{"uid":"0x3eb"}]}]}]}],"me":[{"name":"Michonne"},{"name":"Andrea"},{"name":"Bob"},{"name":"John"}]}}`, + `{"data": {"_path_":[{"uid":"0x1","follow":{"uid":"0x1f","follow":{"uid":"0x3e9","follow":{"uid":"0x3eb"}}}}],"me":[{"name":"Michonne"},{"name":"Andrea"},{"name":"Bob"},{"name":"John"}]}}`, js) } @@ -518,7 +518,7 @@ func TestShortestPath_filter(t *testing.T) { }` js := processToFastJsonNoErr(t, query) require.JSONEq(t, - `{"data": {"_path_":[{"uid":"0x1","follow":[{"uid":"0x1f","follow":[{"uid":"0x3e9","path":[{"uid":"0x3ea"}]}]}]}],"me":[{"name":"Michonne"},{"name":"Andrea"},{"name":"Bob"},{"name":"Matt"}]}}`, + `{"data": {"_path_":[{"uid":"0x1","follow":{"uid":"0x1f","follow":{"uid":"0x3e9","path":{"uid":"0x3ea"}}}}],"me":[{"name":"Michonne"},{"name":"Andrea"},{"name":"Bob"},{"name":"Matt"}]}}`, js) } diff --git a/systest/mutations_test.go b/systest/mutations_test.go index d5ac4a738ba..44cddea7e61 100644 --- a/systest/mutations_test.go +++ b/systest/mutations_test.go @@ -233,7 +233,7 @@ func NQuadMutationTest(t *testing.T, c *dgo.Dgraph) { func DeleteAllReverseIndex(t *testing.T, c *dgo.Dgraph) { ctx := context.Background() - require.NoError(t, c.Alter(ctx, &api.Operation{Schema: "link: uid @reverse ."})) + require.NoError(t, c.Alter(ctx, &api.Operation{Schema: "link: [uid] @reverse ."})) assignedIds, err := c.NewTxn().Mutate(ctx, &api.Mutation{ CommitNow: true, SetNquads: []byte("_:a _:b ."), diff --git a/systest/queries_test.go b/systest/queries_test.go index 5f33358e4d2..0ab7dbef319 100644 --- a/systest/queries_test.go +++ b/systest/queries_test.go @@ -63,7 +63,7 @@ func MultipleBlockEval(t *testing.T, c *dgo.Dgraph) { require.NoError(t, c.Alter(ctx, &api.Operation{ Schema: ` entity: string @index(exact) . - stock: uid @reverse . + stock: [uid] @reverse . `, }))