From 690fbbe05386a1234cb4b67807767651aa07ecac Mon Sep 17 00:00:00 2001 From: Naman Jain Date: Wed, 28 Apr 2021 16:27:15 +0530 Subject: [PATCH] opt(GraphQL): filter existence queries on GraphQL side instead of using @filter(type) (#7757) For the existence queries we used to do: query {\n Cuisine_1(func: eq(Cuisine.name, \"yaMqnmHeov\")) @filter(type(Cuisine)) {\n uid \n } \n} The filter operation can be very heavy on dgraph.type as it may store millions of nodes. A better query could be like this: query {\n Cuisine_1(func: eq(Cuisine.name, \"yaMqnmHeov\")) {\n uid dgraph.type \n } \n} This PR removes the above @filter operation from the existence query and uses the suggested alternate query which is lightweight. The existence check operation is path critical and this fix is expected to add some performance improvement along with preventing OOM. --- graphql/admin/add_group.go | 2 +- graphql/admin/update_group.go | 4 +- graphql/e2e/common/mutation.go | 4 +- graphql/resolve/add_mutation_test.yaml | 533 ++++++++++++++-------- graphql/resolve/auth_add_test.yaml | 66 ++- graphql/resolve/auth_delete_test.yaml | 3 +- graphql/resolve/auth_test.go | 6 +- graphql/resolve/auth_update_test.yaml | 18 +- graphql/resolve/extensions_test.go | 4 +- graphql/resolve/mutation.go | 56 ++- graphql/resolve/mutation_rewriter.go | 95 ++-- graphql/resolve/mutation_test.go | 6 +- graphql/resolve/resolver_error_test.go | 2 +- graphql/resolve/update_mutation_test.yaml | 117 +++-- 14 files changed, 590 insertions(+), 326 deletions(-) diff --git a/graphql/admin/add_group.go b/graphql/admin/add_group.go index 4245e0744e6..23ec400be8e 100644 --- a/graphql/admin/add_group.go +++ b/graphql/admin/add_group.go @@ -23,7 +23,7 @@ func NewAddGroupRewriter() resolve.MutationRewriter { // AddRewriter. func (mrw *addGroupRewriter) RewriteQueries( ctx context.Context, - m schema.Mutation) ([]*gql.GraphQuery, error) { + m schema.Mutation) ([]*gql.GraphQuery, []string, error) { return ((*resolve.AddRewriter)(mrw)).RewriteQueries(ctx, m) } diff --git a/graphql/admin/update_group.go b/graphql/admin/update_group.go index 1e2c17dd7f5..77f7db5b7cf 100644 --- a/graphql/admin/update_group.go +++ b/graphql/admin/update_group.go @@ -22,12 +22,12 @@ func NewUpdateGroupRewriter() resolve.MutationRewriter { // nodes. It does not rewrite any queries. func (urw *updateGroupRewriter) RewriteQueries( ctx context.Context, - m schema.Mutation) ([]*gql.GraphQuery, error) { + m schema.Mutation) ([]*gql.GraphQuery, []string, error) { urw.VarGen = resolve.NewVariableGenerator() urw.XidMetadata = resolve.NewXidMetadata() - return []*gql.GraphQuery{}, nil + return []*gql.GraphQuery{}, []string{}, nil } // Rewrite rewrites set and remove update patches into dql upsert mutations diff --git a/graphql/e2e/common/mutation.go b/graphql/e2e/common/mutation.go index 06ce5847b24..8c34acc15f4 100644 --- a/graphql/e2e/common/mutation.go +++ b/graphql/e2e/common/mutation.go @@ -2933,7 +2933,7 @@ func addMultipleMutationWithOneError(t *testing.T) { newAuth := addAuthor(t, newCountry.ID, postExecutor) badAuth := &author{ - ID: "0x0", + ID: "0x1234321", // A random non-existing ID } goodPost := &post{ @@ -3003,7 +3003,7 @@ func addMultipleMutationWithOneError(t *testing.T) { require.NoError(t, err) require.Contains(t, gqlResponse.Errors[0].Error(), - `because ID "0x0" isn't a Author`) + `because ID "0x1234321" isn't a Author`) cleanUp(t, []*country{newCountry}, []*author{newAuth}, result.AddPost.Post) } diff --git a/graphql/resolve/add_mutation_test.yaml b/graphql/resolve/add_mutation_test.yaml index 37ac2fcd760..42135b978b4 100644 --- a/graphql/resolve/add_mutation_test.yaml +++ b/graphql/resolve/add_mutation_test.yaml @@ -253,29 +253,37 @@ underlying Dgraph edge names. Some PostSecrets are present and are not created." dgquery: |- query { - PostSecret_1(func: eq(PostSecret.title, "ps1")) @filter(type(PostSecret)) { + PostSecret_1(func: eq(PostSecret.title, "ps1")) { uid + dgraph.type } - PostSecret_2(func: eq(PostSecret.title, "ps2")) @filter(type(PostSecret)) { + PostSecret_2(func: eq(PostSecret.title, "ps2")) { uid + dgraph.type } - PostSecret_3(func: eq(PostSecret.title, "ps3")) @filter(type(PostSecret)) { + PostSecret_3(func: eq(PostSecret.title, "ps3")) { uid + dgraph.type } - PostSecret_4(func: eq(PostSecret.title, "ps4")) @filter(type(PostSecret)) { + PostSecret_4(func: eq(PostSecret.title, "ps4")) { uid + dgraph.type } - PostSecret_5(func: eq(PostSecret.title, "ps5")) @filter(type(PostSecret)) { + PostSecret_5(func: eq(PostSecret.title, "ps5")) { uid + dgraph.type } - PostSecret_6(func: eq(PostSecret.title, "ps6")) @filter(type(PostSecret)) { + PostSecret_6(func: eq(PostSecret.title, "ps6")) { uid + dgraph.type } - PostSecret_7(func: eq(PostSecret.title, "ps7")) @filter(type(PostSecret)) { + PostSecret_7(func: eq(PostSecret.title, "ps7")) { uid + dgraph.type } - PostSecret_8(func: eq(PostSecret.title, "ps8")) @filter(type(PostSecret)) { + PostSecret_8(func: eq(PostSecret.title, "ps8")) { uid + dgraph.type } } qnametouid: | @@ -518,8 +526,9 @@ getting injected and all data transformed to underlying Dgraph edge names" dgquery: |- query { - User_1(func: eq(User.name, "A.N. Author")) @filter(type(User)) { + User_1(func: eq(User.name, "A.N. Author")) { uid + dgraph.type } } dgmutations: @@ -581,8 +590,9 @@ Dgraph JSON mutation" dgquery: |- query { - Country_1(func: uid(0x123)) @filter(type(Country)) { + Country_1(func: uid(0x123)) { uid + dgraph.type } } qnametouid: |- @@ -622,8 +632,9 @@ explanation: "This should throw an error as 0x123 is not a valid Country node" dgquery: |- query { - Country_1(func: uid(0x123)) @filter(type(Country)) { + Country_1(func: uid(0x123)) { uid + dgraph.type } } error2: @@ -674,8 +685,9 @@ a new 'posts' edge." dgquery: |- query { - Author_1(func: uid(0x2)) @filter(type(Author)) { + Author_1(func: uid(0x2)) { uid + dgraph.type } } qnametouid: |- @@ -746,11 +758,13 @@ explanation: "The add mutation should get rewritten into a Dgraph upsert mutation" dgquery: |- query { - State_1(func: eq(State.code, "nsw")) @filter(type(State)) { + State_1(func: eq(State.code, "nsw")) { uid + dgraph.type } - Country_2(func: uid(0x12)) @filter(type(Country)) { + Country_2(func: uid(0x12)) { uid + dgraph.type } } qnametouid: |- @@ -790,11 +804,13 @@ } dgquery: |- query { - State_1(func: eq(State.code, "nsw")) @filter(type(State)) { + State_1(func: eq(State.code, "nsw")) { uid + dgraph.type } - Country_2(func: uid(0x12)) @filter(type(Country)) { + Country_2(func: uid(0x12)) { uid + dgraph.type } } qnametouid: |- @@ -835,17 +851,21 @@ } dgquery: |- query { - State_1(func: eq(State.code, "nsw")) @filter(type(State)) { + State_1(func: eq(State.code, "nsw")) { uid + dgraph.type } - Country_2(func: uid(0x12)) @filter(type(Country)) { + Country_2(func: uid(0x12)) { uid + dgraph.type } - State_3(func: eq(State.code, "mh")) @filter(type(State)) { + State_3(func: eq(State.code, "mh")) { uid + dgraph.type } - Country_4(func: uid(0x14)) @filter(type(Country)) { + Country_4(func: uid(0x14)) { uid + dgraph.type } } qnametouid: |- @@ -939,11 +959,13 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "NSW")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "NSW")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "Sapiens")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "Sapiens")) { uid + dgraph.type } } qnametouid: |- @@ -991,11 +1013,13 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "NSW")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "NSW")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "Sapiens")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "Sapiens")) { uid + dgraph.type } } qnametouid: |- @@ -1047,14 +1071,17 @@ } dgquery: |- query { - State_1(func: eq(State.code, "nsw")) @filter(type(State)) { + State_1(func: eq(State.code, "nsw")) { uid + dgraph.type } - Country_2(func: uid(0x12)) @filter(type(Country)) { + Country_2(func: uid(0x12)) { uid + dgraph.type } - State_3(func: eq(State.code, "mh")) @filter(type(State)) { + State_3(func: eq(State.code, "mh")) { uid + dgraph.type } } qnametouid: |- @@ -1133,14 +1160,17 @@ } dgquery: |- query { - LibraryMember_1(func: eq(Member.name, "Alice")) @filter(type(LibraryMember)) { + LibraryMember_1(func: eq(Member.name, "Alice")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.refID, "101")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.refID, "101")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "101")) @filter(type(Member)) { + LibraryMember_3(func: eq(Member.refID, "101")) { uid + dgraph.type } } dgmutations: @@ -1186,14 +1216,17 @@ } dgquery: |- query { - LibraryMember_1(func: eq(Member.name, "Alice")) @filter(type(LibraryMember)) { + LibraryMember_1(func: eq(Member.name, "Alice")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.refID, "101")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.refID, "101")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "101")) @filter(type(Member)) { + LibraryMember_3(func: eq(Member.refID, "101")) { uid + dgraph.type } } qnametouid: |- @@ -1231,14 +1264,17 @@ } dgquery: |- query { - LibraryMember_1(func: eq(Member.name, "Alice")) @filter(type(LibraryMember)) { + LibraryMember_1(func: eq(Member.name, "Alice")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.refID, "101")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.refID, "101")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "101")) @filter(type(Member)) { + LibraryMember_3(func: eq(Member.refID, "101")) { uid + dgraph.type } } qnametouid: |- @@ -1276,14 +1312,17 @@ } dgquery: |- query { - LibraryMember_1(func: eq(Member.name, "Alice")) @filter(type(LibraryMember)) { + LibraryMember_1(func: eq(Member.name, "Alice")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.refID, "101")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.refID, "101")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "101")) @filter(type(Member)) { + LibraryMember_3(func: eq(Member.refID, "101")) { uid + dgraph.type } } qnametouid: |- @@ -1334,14 +1373,17 @@ } dgquery: |- query { - LibraryMember_1(func: eq(Member.name, "Alice")) @filter(type(LibraryMember)) { + LibraryMember_1(func: eq(Member.name, "Alice")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.refID, "101")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.refID, "101")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "101")) @filter(type(Member)) { + LibraryMember_3(func: eq(Member.refID, "101")) { uid + dgraph.type } } qnametouid: |- @@ -1385,17 +1427,21 @@ } dgquery: |- query { - LibraryManager_1(func: eq(LibraryManager.name, "Alice")) @filter(type(LibraryManager)) { + LibraryManager_1(func: eq(LibraryManager.name, "Alice")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.name, "Bob")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.name, "Bob")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "101")) @filter(type(LibraryMember)) { + LibraryMember_3(func: eq(Member.refID, "101")) { uid + dgraph.type } - LibraryMember_4(func: eq(Member.refID, "101")) @filter(type(Member)) { + LibraryMember_4(func: eq(Member.refID, "101")) { uid + dgraph.type } } dgmutations: @@ -1454,17 +1500,21 @@ } dgquery: |- query { - LibraryManager_1(func: eq(LibraryManager.name, "Alice")) @filter(type(LibraryManager)) { + LibraryManager_1(func: eq(LibraryManager.name, "Alice")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.name, "Bob")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.name, "Bob")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "101")) @filter(type(LibraryMember)) { + LibraryMember_3(func: eq(Member.refID, "101")) { uid + dgraph.type } - LibraryMember_4(func: eq(Member.refID, "101")) @filter(type(Member)) { + LibraryMember_4(func: eq(Member.refID, "101")) { uid + dgraph.type } } qnametouid: |- @@ -1507,17 +1557,21 @@ } dgquery: |- query { - LibraryManager_1(func: eq(LibraryManager.name, "Alice")) @filter(type(LibraryManager)) { + LibraryManager_1(func: eq(LibraryManager.name, "Alice")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.name, "Bob")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.name, "Bob")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "101")) @filter(type(LibraryMember)) { + LibraryMember_3(func: eq(Member.refID, "101")) { uid + dgraph.type } - LibraryMember_4(func: eq(Member.refID, "101")) @filter(type(Member)) { + LibraryMember_4(func: eq(Member.refID, "101")) { uid + dgraph.type } } qnametouid: |- @@ -1568,23 +1622,29 @@ } dgquery: |- query { - SportsMember_1(func: eq(Member.name, "Alice")) @filter(type(SportsMember)) { + SportsMember_1(func: eq(Member.name, "Alice")) { uid + dgraph.type } - SportsMember_2(func: eq(Member.refID, "101")) @filter(type(SportsMember)) { + SportsMember_2(func: eq(Member.refID, "101")) { uid + dgraph.type } - SportsMember_3(func: eq(Member.refID, "101")) @filter(type(Member)) { + SportsMember_3(func: eq(Member.refID, "101")) { uid + dgraph.type } - SportsMember_4(func: eq(Team.teamID, "T01")) @filter(type(SportsMember)) { + SportsMember_4(func: eq(Team.teamID, "T01")) { uid + dgraph.type } - SportsMember_5(func: eq(Team.teamID, "T01")) @filter(type(Team)) { + SportsMember_5(func: eq(Team.teamID, "T01")) { uid + dgraph.type } - SportsMember_6(func: eq(Team.teamName, "GraphQL")) @filter(type(SportsMember)) { + SportsMember_6(func: eq(Team.teamName, "GraphQL")) { uid + dgraph.type } } dgmutations: @@ -1627,8 +1687,9 @@ explanation: "The add mutation should get rewritten into a Dgraph upsert mutation" dgquery: |- query { - Editor_1(func: eq(Editor.code, "editor")) @filter(type(Editor)) { + Editor_1(func: eq(Editor.code, "editor")) { uid + dgraph.type } } dgmutations: @@ -1777,8 +1838,9 @@ } dgquery: |- query { - Post_1(func: uid(0x123)) @filter(type(Post)) { + Post_1(func: uid(0x123)) { uid + dgraph.type } } qnametouid: |- @@ -1867,11 +1929,13 @@ } dgquery: |- query { - Post_1(func: uid(0x123)) @filter(type(Post)) { + Post_1(func: uid(0x123)) { uid + dgraph.type } - Post_2(func: uid(0x124)) @filter(type(Post)) { + Post_2(func: uid(0x124)) { uid + dgraph.type } } qnametouid: |- @@ -1987,11 +2051,13 @@ } dgquery: |- query { - Post_1(func: uid(0x123)) @filter(type(Post)) { + Post_1(func: uid(0x123)) { uid + dgraph.type } - Post_2(func: uid(0x456)) @filter(type(Post)) { + Post_2(func: uid(0x456)) { uid + dgraph.type } } qnametouid: |- @@ -2158,8 +2224,9 @@ explanation: "No nodes exist. Both nodes are created." dgquery: |- query { - State_1(func: eq(State.code, "dg")) @filter(type(State)) { + State_1(func: eq(State.code, "dg")) { uid + dgraph.type } } dgmutations: @@ -2206,8 +2273,9 @@ explanation: "The state exists. It is linked to the new Country. Its link to old country is deleted." dgquery: |- query { - State_1(func: eq(State.code, "dg")) @filter(type(State)) { + State_1(func: eq(State.code, "dg")) { uid + dgraph.type } } qnametouid: |- @@ -2273,8 +2341,9 @@ because it's missing required field name" dgquery: |- query { - State_1(func: eq(State.code, "dg")) @filter(type(State)) { + State_1(func: eq(State.code, "dg")) { uid + dgraph.type } } qnametouid: |- @@ -2334,8 +2403,9 @@ explanation: "Error is thrown as State with code dg does not exist" dgquery: |- query { - State_1(func: eq(State.code, "dg")) @filter(type(State)) { + State_1(func: eq(State.code, "dg")) { uid + dgraph.type } } error2: @@ -2388,8 +2458,9 @@ explanation: "Movie node exists and is not created" dgquery: |- query { - Movie_1(func: uid(0x2)) @filter(type(Movie)) { + Movie_1(func: uid(0x2)) { uid + dgraph.type } } qnametouid: |- @@ -2484,8 +2555,9 @@ is same or contains just xid, it should not return error." dgquery: |- query { - District_1(func: eq(District.code, "D1")) @filter(type(District)) { + District_1(func: eq(District.code, "D1")) { uid + dgraph.type } } dgmutations: @@ -2750,8 +2822,9 @@ } dgquery: |- query { - Post_1(func: uid(0x456)) @filter(type(Post)) { + Post_1(func: uid(0x456)) { uid + dgraph.type } } qnametouid: |- @@ -2813,11 +2886,13 @@ } dgquery: |- query { - State_1(func: eq(State.code, "abc")) @filter(type(State)) { + State_1(func: eq(State.code, "abc")) { uid + dgraph.type } - State_2(func: eq(State.code, "def")) @filter(type(State)) { + State_2(func: eq(State.code, "def")) { uid + dgraph.type } } qnametouid: |- @@ -2899,17 +2974,21 @@ } dgquery: |- query { - Student_1(func: eq(People.xid, "S0")) @filter(type(Student)) { + Student_1(func: eq(People.xid, "S0")) { uid + dgraph.type } - Teacher_2(func: eq(People.xid, "T0")) @filter(type(Teacher)) { + Teacher_2(func: eq(People.xid, "T0")) { uid + dgraph.type } - Student_3(func: eq(People.xid, "S1")) @filter(type(Student)) { + Student_3(func: eq(People.xid, "S1")) { uid + dgraph.type } - Teacher_4(func: eq(People.xid, "T1")) @filter(type(Teacher)) { + Teacher_4(func: eq(People.xid, "T1")) { uid + dgraph.type } } dgmutations: @@ -2994,17 +3073,21 @@ } dgquery: |- query { - Student_1(func: eq(People.xid, "S0")) @filter(type(Student)) { + Student_1(func: eq(People.xid, "S0")) { uid + dgraph.type } - Teacher_2(func: eq(People.xid, "T0")) @filter(type(Teacher)) { + Teacher_2(func: eq(People.xid, "T0")) { uid + dgraph.type } - Student_3(func: eq(People.xid, "S1")) @filter(type(Student)) { + Student_3(func: eq(People.xid, "S1")) { uid + dgraph.type } - Teacher_4(func: eq(People.xid, "T1")) @filter(type(Teacher)) { + Teacher_4(func: eq(People.xid, "T1")) { uid + dgraph.type } } dgmutations: @@ -3091,14 +3174,17 @@ } dgquery: |- query { - Student_1(func: eq(People.xid, "S0")) @filter(type(Student)) { + Student_1(func: eq(People.xid, "S0")) { uid + dgraph.type } - Teacher_2(func: eq(People.xid, "T0")) @filter(type(Teacher)) { + Teacher_2(func: eq(People.xid, "T0")) { uid + dgraph.type } - Student_3(func: eq(People.xid, "S1")) @filter(type(Student)) { + Student_3(func: eq(People.xid, "S1")) { uid + dgraph.type } } @@ -3165,14 +3251,17 @@ } dgquery: |- query { - Student_1(func: eq(People.xid, "S0")) @filter(type(Student)) { + Student_1(func: eq(People.xid, "S0")) { uid + dgraph.type } - Teacher_2(func: eq(People.xid, "T0")) @filter(type(Teacher)) { + Teacher_2(func: eq(People.xid, "T0")) { uid + dgraph.type } - Student_3(func: eq(People.xid, "S1")) @filter(type(Student)) { + Student_3(func: eq(People.xid, "S1")) { uid + dgraph.type } } qnametouid: | @@ -3227,14 +3316,17 @@ } dgquery: |- query { - Student_1(func: eq(People.xid, "S0")) @filter(type(Student)) { + Student_1(func: eq(People.xid, "S0")) { uid + dgraph.type } - Teacher_2(func: eq(People.xid, "T0")) @filter(type(Teacher)) { + Teacher_2(func: eq(People.xid, "T0")) { uid + dgraph.type } - Student_3(func: eq(People.xid, "S1")) @filter(type(Student)) { + Student_3(func: eq(People.xid, "S1")) { uid + dgraph.type } } qnametouid: | @@ -3299,14 +3391,17 @@ } dgquery: |- query { - Lab_1(func: eq(Lab.name, "Lab1")) @filter(type(Lab)) { + Lab_1(func: eq(Lab.name, "Lab1")) { uid + dgraph.type } - Computer_2(func: eq(Computer.name, "computer1")) @filter(type(Computer)) { + Computer_2(func: eq(Computer.name, "computer1")) { uid + dgraph.type } - ComputerOwner_3(func: eq(ComputerOwner.name, "owner1")) @filter(type(ComputerOwner)) { + ComputerOwner_3(func: eq(ComputerOwner.name, "owner1")) { uid + dgraph.type } } dgmutations: @@ -3361,14 +3456,17 @@ } dgquery: |- query { - Lab_1(func: eq(Lab.name, "Lab1")) @filter(type(Lab)) { + Lab_1(func: eq(Lab.name, "Lab1")) { uid + dgraph.type } - Computer_2(func: eq(Computer.name, "computer1")) @filter(type(Computer)) { + Computer_2(func: eq(Computer.name, "computer1")) { uid + dgraph.type } - ComputerOwner_3(func: eq(ComputerOwner.name, "owner1")) @filter(type(ComputerOwner)) { + ComputerOwner_3(func: eq(ComputerOwner.name, "owner1")) { uid + dgraph.type } } qnametouid: | @@ -3413,14 +3511,17 @@ } dgquery: |- query { - Lab_1(func: eq(Lab.name, "Lab1")) @filter(type(Lab)) { + Lab_1(func: eq(Lab.name, "Lab1")) { uid + dgraph.type } - Computer_2(func: eq(Computer.name, "computer1")) @filter(type(Computer)) { + Computer_2(func: eq(Computer.name, "computer1")) { uid + dgraph.type } - ComputerOwner_3(func: eq(ComputerOwner.name, "owner1")) @filter(type(ComputerOwner)) { + ComputerOwner_3(func: eq(ComputerOwner.name, "owner1")) { uid + dgraph.type } } qnametouid: | @@ -3501,8 +3602,9 @@ } dgquery: |- query { - District_1(func: eq(District.code, "d1")) @filter(type(District)) { + District_1(func: eq(District.code, "d1")) { uid + dgraph.type } } dgmutations: @@ -3568,8 +3670,9 @@ } dgquery: |- query { - District_1(func: eq(District.code, "d1")) @filter(type(District)) { + District_1(func: eq(District.code, "d1")) { uid + dgraph.type } } qnametouid: |- @@ -3616,8 +3719,9 @@ } dgquery: |- query { - State_1(func: eq(State.code, "abc")) @filter(type(State)) { + State_1(func: eq(State.code, "abc")) { uid + dgraph.type } } dgmutations: @@ -3683,20 +3787,25 @@ } dgquery: |- query { - Post1_1(func: eq(Post1.id, "post1")) @filter(type(Post1)) { + Post1_1(func: eq(Post1.id, "post1")) { uid + dgraph.type } - Comment1_2(func: eq(Comment1.id, "comment1")) @filter(type(Comment1)) { + Comment1_2(func: eq(Comment1.id, "comment1")) { uid + dgraph.type } - Comment1_3(func: eq(Comment1.id, "reply1")) @filter(type(Comment1)) { + Comment1_3(func: eq(Comment1.id, "reply1")) { uid + dgraph.type } - Post1_4(func: eq(Post1.id, "post2")) @filter(type(Post1)) { + Post1_4(func: eq(Post1.id, "post2")) { uid + dgraph.type } - Comment1_5(func: eq(Comment1.id, "comment2")) @filter(type(Comment1)) { + Comment1_5(func: eq(Comment1.id, "comment2")) { uid + dgraph.type } } dgmutations: @@ -3783,20 +3892,25 @@ } dgquery: |- query { - Post1_1(func: eq(Post1.id, "post1")) @filter(type(Post1)) { + Post1_1(func: eq(Post1.id, "post1")) { uid + dgraph.type } - Comment1_2(func: eq(Comment1.id, "comment1")) @filter(type(Comment1)) { + Comment1_2(func: eq(Comment1.id, "comment1")) { uid + dgraph.type } - Comment1_3(func: eq(Comment1.id, "reply1")) @filter(type(Comment1)) { + Comment1_3(func: eq(Comment1.id, "reply1")) { uid + dgraph.type } - Post1_4(func: eq(Post1.id, "post2")) @filter(type(Post1)) { + Post1_4(func: eq(Post1.id, "post2")) { uid + dgraph.type } - Comment1_5(func: eq(Comment1.id, "comment2")) @filter(type(Comment1)) { + Comment1_5(func: eq(Comment1.id, "comment2")) { uid + dgraph.type } } qnametouid: | @@ -3878,20 +3992,25 @@ } dgquery: |- query { - Post1_1(func: eq(Post1.id, "post1")) @filter(type(Post1)) { + Post1_1(func: eq(Post1.id, "post1")) { uid + dgraph.type } - Comment1_2(func: eq(Comment1.id, "comment1")) @filter(type(Comment1)) { + Comment1_2(func: eq(Comment1.id, "comment1")) { uid + dgraph.type } - Comment1_3(func: eq(Comment1.id, "reply1")) @filter(type(Comment1)) { + Comment1_3(func: eq(Comment1.id, "reply1")) { uid + dgraph.type } - Post1_4(func: eq(Post1.id, "post2")) @filter(type(Post1)) { + Post1_4(func: eq(Post1.id, "post2")) { uid + dgraph.type } - Comment1_5(func: eq(Comment1.id, "comment2")) @filter(type(Comment1)) { + Comment1_5(func: eq(Comment1.id, "comment2")) { uid + dgraph.type } } qnametouid: | @@ -4059,8 +4178,9 @@ } dgquery: |- query { - Parrot_1(func: uid(0x123)) @filter(type(Parrot)) { + Parrot_1(func: uid(0x123)) { uid + dgraph.type } } qnametouid: |- @@ -4158,11 +4278,13 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "2312SB")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "2312SB")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "Sapiens")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "Sapiens")) { uid + dgraph.type } } dgmutations: @@ -4211,11 +4333,13 @@ } dgquery: |- query { - ABC_1(func: eq(ABC.ab, "cd")) @filter(type(ABC)) { + ABC_1(func: eq(ABC.ab, "cd")) { uid + dgraph.type } - ABC_2(func: eq(ABC.abc, "d")) @filter(type(ABC)) { + ABC_2(func: eq(ABC.abc, "d")) { uid + dgraph.type } } explanation: "We should generate different variables as ABC_1 and ABC_2 if xidName+xidValue is same as in above case @@ -4258,17 +4382,21 @@ } dgquery: |- query { - ABC_1(func: eq(ABC.ab, "cd")) @filter(type(ABC)) { + ABC_1(func: eq(ABC.ab, "cd")) { uid + dgraph.type } - ABC_2(func: eq(ABC.abc, "de")) @filter(type(ABC)) { + ABC_2(func: eq(ABC.abc, "de")) { uid + dgraph.type } - ABC_3(func: eq(ABC.ab, "ef")) @filter(type(ABC)) { + ABC_3(func: eq(ABC.ab, "ef")) { uid + dgraph.type } - ABC_4(func: eq(ABC.abc, "d")) @filter(type(ABC)) { + ABC_4(func: eq(ABC.abc, "d")) { uid + dgraph.type } } explanation: "We should generate different variables as ABC_1 and ABC_4 if xidName+xidValue is same in two different objects as in above case @@ -4324,17 +4452,21 @@ } dgquery: |- query { - ABC_1(func: eq(ABC.ab, "cd")) @filter(type(ABC)) { + ABC_1(func: eq(ABC.ab, "cd")) { uid + dgraph.type } - ABC_2(func: eq(ABC.abc, "de")) @filter(type(ABC)) { + ABC_2(func: eq(ABC.abc, "de")) { uid + dgraph.type } - AB_3(func: eq(AB.Cab, "cde")) @filter(type(AB)) { + AB_3(func: eq(AB.Cab, "cde")) { uid + dgraph.type } - AB_4(func: eq(AB.Cabc, "d")) @filter(type(AB)) { + AB_4(func: eq(AB.Cabc, "d")) { uid + dgraph.type } } explanation: "We should generate different variables as ABC_1 and AB_3, or ABC_2 and AB_4 if typename+xidName+xidValue is same in two different types as in above case @@ -4384,11 +4516,13 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "2312SB")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "2312SB")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "Sapiens")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "Sapiens")) { uid + dgraph.type } } dgmutations: @@ -4453,17 +4587,21 @@ } dgquery: |- query { - Person1_1(func: eq(Person1.id, "1")) @filter(type(Person1)) { + Person1_1(func: eq(Person1.id, "1")) { uid + dgraph.type } - Person1_2(func: eq(Person1.name, "First Person")) @filter(type(Person1)) { + Person1_2(func: eq(Person1.name, "First Person")) { uid + dgraph.type } - Person1_3(func: eq(Person1.id, "2")) @filter(type(Person1)) { + Person1_3(func: eq(Person1.id, "2")) { uid + dgraph.type } - Person1_4(func: eq(Person1.name, "Second Person")) @filter(type(Person1)) { + Person1_4(func: eq(Person1.name, "Second Person")) { uid + dgraph.type } } dgmutations: @@ -4531,11 +4669,13 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "2312SB")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "2312SB")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "Sapiens")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "Sapiens")) { uid + dgraph.type } } qnametouid: | @@ -4577,11 +4717,13 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "2312SB")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "2312SB")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "Sapiens")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "Sapiens")) { uid + dgraph.type } } qnametouid: | @@ -4662,17 +4804,21 @@ } dgquery: |- query { - Person1_1(func: eq(Person1.id, "1")) @filter(type(Person1)) { + Person1_1(func: eq(Person1.id, "1")) { uid + dgraph.type } - Person1_2(func: eq(Person1.name, "First Person")) @filter(type(Person1)) { + Person1_2(func: eq(Person1.name, "First Person")) { uid + dgraph.type } - Person1_3(func: eq(Person1.id, "2")) @filter(type(Person1)) { + Person1_3(func: eq(Person1.id, "2")) { uid + dgraph.type } - Person1_4(func: eq(Person1.name, "Second Person")) @filter(type(Person1)) { + Person1_4(func: eq(Person1.name, "Second Person")) { uid + dgraph.type } } dgmutations: @@ -4744,11 +4890,13 @@ district with code non-existing is ignored. Not even its existence query is generated." dgquery: |- query { - District_1(func: eq(District.code, "D1")) @filter(type(District)) { + District_1(func: eq(District.code, "D1")) { uid + dgraph.type } - District_2(func: eq(District.code, "D2")) @filter(type(District)) { + District_2(func: eq(District.code, "D2")) { uid + dgraph.type } } dgmutations: @@ -4818,17 +4966,21 @@ foo. In case it is supplied, it is simply ignored." dgquery: |- query { - Foo_1(func: eq(Foo.id, "123")) @filter(type(Foo)) { + Foo_1(func: eq(Foo.id, "123")) { uid + dgraph.type } - Bar_2(func: eq(Bar.id, "1234")) @filter(type(Bar)) { + Bar_2(func: eq(Bar.id, "1234")) { uid + dgraph.type } - Foo_3(func: eq(Foo.id, "1")) @filter(type(Foo)) { + Foo_3(func: eq(Foo.id, "1")) { uid + dgraph.type } - Bar_4(func: eq(Bar.id, "2")) @filter(type(Bar)) { + Bar_4(func: eq(Bar.id, "2")) { uid + dgraph.type } } dgmutations: @@ -4896,41 +5048,53 @@ } dgquery: |- query { - Friend1_1(func: eq(Friend1.id, "Main Friend")) @filter(type(Friend1)) { + Friend1_1(func: eq(Friend1.id, "Main Friend")) { uid + dgraph.type } - Friend_2(func: eq(Friend.id, "Friend1")) @filter(type(Friend)) { + Friend_2(func: eq(Friend.id, "Friend1")) { uid + dgraph.type } - Friend_3(func: eq(Friend.id, "Friend2")) @filter(type(Friend)) { + Friend_3(func: eq(Friend.id, "Friend2")) { uid + dgraph.type } - Friend_4(func: eq(Friend.id, "Friend3")) @filter(type(Friend)) { + Friend_4(func: eq(Friend.id, "Friend3")) { uid + dgraph.type } - Friend_5(func: eq(Friend.id, "Friend4")) @filter(type(Friend)) { + Friend_5(func: eq(Friend.id, "Friend4")) { uid + dgraph.type } - Friend_6(func: eq(Friend.id, "Friend5")) @filter(type(Friend)) { + Friend_6(func: eq(Friend.id, "Friend5")) { uid + dgraph.type } - Friend_7(func: eq(Friend.id, "Friend6")) @filter(type(Friend)) { + Friend_7(func: eq(Friend.id, "Friend6")) { uid + dgraph.type } - Friend_8(func: eq(Friend.id, "Friend7")) @filter(type(Friend)) { + Friend_8(func: eq(Friend.id, "Friend7")) { uid + dgraph.type } - Friend_9(func: eq(Friend.id, "Friend8")) @filter(type(Friend)) { + Friend_9(func: eq(Friend.id, "Friend8")) { uid + dgraph.type } - Friend_10(func: eq(Friend.id, "Friend9")) @filter(type(Friend)) { + Friend_10(func: eq(Friend.id, "Friend9")) { uid + dgraph.type } - Friend_11(func: eq(Friend.id, "Friend10")) @filter(type(Friend)) { + Friend_11(func: eq(Friend.id, "Friend10")) { uid + dgraph.type } - Friend_12(func: eq(Friend.id, "Friend11")) @filter(type(Friend)) { + Friend_12(func: eq(Friend.id, "Friend11")) { uid + dgraph.type } } dgmutations: @@ -5049,14 +5213,17 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "B02")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "B02")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "Sapiens")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "Sapiens")) { uid + dgraph.type } - author_3(func: eq(author.authorId, "A02")) @filter(type(author)) { + author_3(func: eq(author.authorId, "A02")) { uid + dgraph.type } } dgmutations: @@ -5114,14 +5281,17 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "B01")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "B01")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "Sapiens")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "Sapiens")) { uid + dgraph.type } - author_3(func: eq(author.authorId, "A01")) @filter(type(author)) { + author_3(func: eq(author.authorId, "A01")) { uid + dgraph.type } } qnametouid: | @@ -5188,11 +5358,13 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "B01")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "B01")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "Sapiens")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "Sapiens")) { uid + dgraph.type } } qnametouid: | @@ -5235,17 +5407,21 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "B01")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "B01")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "Sapiens")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "Sapiens")) { uid + dgraph.type } - author_3(func: eq(author.authorId, "A01")) @filter(type(author)) { + author_3(func: eq(author.authorId, "A01")) { uid + dgraph.type } - author_4(func: eq(author.penName, "Alice")) @filter(type(author)) { + author_4(func: eq(author.penName, "Alice")) { uid + dgraph.type } } qnametouid: | @@ -5315,11 +5491,12 @@ } dgquery: |- query { - Post1_1(func: eq(Post1.id, "P01")) @filter(type(Post1)) { + Post1_1(func: eq(Post1.id, "P01")) { uid + dgraph.type } } error2: { "message": "failed to rewrite mutation payload because field id cannot be empty" - } \ No newline at end of file + } diff --git a/graphql/resolve/auth_add_test.yaml b/graphql/resolve/auth_add_test.yaml index 71e2d1fd731..77008cfbf74 100644 --- a/graphql/resolve/auth_add_test.yaml +++ b/graphql/resolve/auth_add_test.yaml @@ -162,8 +162,9 @@ } dgquery: |- query { - Project_1(func: uid(0x123)) @filter(type(Project)) { + Project_1(func: uid(0x123)) { uid + dgraph.type } } queryjson: | @@ -229,13 +230,14 @@ } dgquery: |- query { - Project_1(func: uid(0x123)) @filter(type(Project)) { + Project_1(func: uid(0x123)) { uid + dgraph.type } } queryjson: | { - "Project_1": [ { "uid": "0x123" } ] + "Project_1": [ { "uid": "0x123", "dgraph.type": ["Project"]} ] } uids: | { @@ -301,13 +303,14 @@ } dgquery: |- query { - Project_1(func: uid(0x123)) @filter(type(Project)) { + Project_1(func: uid(0x123)) { uid + dgraph.type } } queryjson: | { - "Project_1": [ { "uid": "0x123" } ] + "Project_1": [ { "uid": "0x123", "dgraph.type":["Project"] } ] } uids: | { @@ -374,13 +377,14 @@ } dgquery: |- query { - Project_1(func: uid(0x123)) @filter(type(Project)) { + Project_1(func: uid(0x123)) { uid + dgraph.type } } queryjson: | { - "Project_1": [ { "uid": "0x123" } ] + "Project_1": [ { "uid": "0x123", "dgraph.type":["Project"]} ] } uids: | { @@ -449,11 +453,13 @@ } dgquery: |- query { - Project_1(func: uid(0x123)) @filter(type(Project)) { + Project_1(func: uid(0x123)) { uid + dgraph.type } - Ticket_2(func: uid(0x789)) @filter(type(Ticket)) { + Ticket_2(func: uid(0x789)) { uid + dgraph.type } } queryjson: | @@ -528,17 +534,19 @@ } dgquery: |- query { - Project_1(func: uid(0x123)) @filter(type(Project)) { + Project_1(func: uid(0x123)) { uid + dgraph.type } - Ticket_2(func: uid(0x789)) @filter(type(Ticket)) { + Ticket_2(func: uid(0x789)) { uid + dgraph.type } } queryjson: | { - "Project_1": [ { "uid": "0x123" } ], - "Ticket_2": [ { "uid": "0x789" } ] + "Project_1": [ { "uid": "0x123", "dgraph.type":["Project"] } ], + "Ticket_2": [ { "uid": "0x789", "dgraph.type":["Ticket"]} ] } dgquerysec: |- query { @@ -612,8 +620,9 @@ } dgquery: |- query { - Ticket_1(func: uid(0x789)) @filter(type(Ticket)) { + Ticket_1(func: uid(0x789)) { uid + dgraph.type } } queryjson: | @@ -702,13 +711,14 @@ } dgquery: |- query { - Ticket_1(func: uid(0x789)) @filter(type(Ticket)) { + Ticket_1(func: uid(0x789)) { uid + dgraph.type } } queryjson: | { - "Ticket_1": [ { "uid": "0x789" } ] + "Ticket_1": [ { "uid": "0x789", "dgraph.type":["Ticket"] } ] } dgquerysec: |- query { @@ -908,8 +918,9 @@ } dgquery: |- query { - User_1(func: eq(User.username, "user1")) @filter(type(User)) { + User_1(func: eq(User.username, "user1")) { uid + dgraph.type } } queryjson: | @@ -958,8 +969,9 @@ } dgquery: |- query { - User_1(func: eq(User.username, "user1")) @filter(type(User)) { + User_1(func: eq(User.username, "user1")) { uid + dgraph.type } } queryjson: | @@ -1241,13 +1253,14 @@ } dgquery: |- query { - Tweets_1(func: eq(Tweets.id, "existing ID")) @filter(type(Tweets)) { + Tweets_1(func: eq(Tweets.id, "existing ID")) { uid + dgraph.type } } queryjson: | { - "Tweets_1": [ { "uid": "0x123" } ] + "Tweets_1": [ { "uid": "0x123", "dgraph.type":["Tweets"] } ] } dgquerysec: |- query { @@ -1278,13 +1291,14 @@ } dgquery: |- query { - Tweets_1(func: eq(Tweets.id, "existing ID")) @filter(type(Tweets)) { + Tweets_1(func: eq(Tweets.id, "existing ID")) { uid + dgraph.type } } queryjson: | { - "Tweets_1": [ { "uid": "0x123" } ] + "Tweets_1": [ { "uid": "0x123", "dgraph.type":["Tweets"] } ] } dgquerysec: |- query { @@ -1320,16 +1334,18 @@ } dgquery: |- query { - State_1(func: eq(State.code, "mh")) @filter(type(State)) { + State_1(func: eq(State.code, "mh")) { uid + dgraph.type } - Country_2(func: eq(Country.id, "in")) @filter(type(Country)) { + Country_2(func: eq(Country.id, "in")) { uid + dgraph.type } } queryjson: | { - "State_1": [ { "uid": "0x123" } ] + "State_1": [ { "uid": "0x123", "dgraph.type":["State"] } ] } dgquerysec: |- query { diff --git a/graphql/resolve/auth_delete_test.yaml b/graphql/resolve/auth_delete_test.yaml index 97422c5d0dc..66d7b97f361 100644 --- a/graphql/resolve/auth_delete_test.yaml +++ b/graphql/resolve/auth_delete_test.yaml @@ -878,4 +878,5 @@ Author.name : Author.name } } - } \ No newline at end of file + } + diff --git a/graphql/resolve/auth_test.go b/graphql/resolve/auth_test.go index 6ec4f093e81..8817c31d0e0 100644 --- a/graphql/resolve/auth_test.go +++ b/graphql/resolve/auth_test.go @@ -585,7 +585,7 @@ func mutationQueryRewriting(t *testing.T, sch string, authMeta *testutil.AuthMet ctx, err := authMeta.AddClaimsToContext(context.Background()) require.NoError(t, err) - _, _ = rewriter.RewriteQueries(context.Background(), gqlMutation) + _, _, _ = rewriter.RewriteQueries(context.Background(), gqlMutation) _, err = rewriter.Rewrite(ctx, gqlMutation, tt.idExistence) require.Nil(t, err) @@ -660,7 +660,7 @@ func deleteQueryRewriting(t *testing.T, sch string, authMeta *testutil.AuthMeta, } // -- Act -- - _, _ = rewriterToTest.RewriteQueries(context.Background(), mut) + _, _, _ = rewriterToTest.RewriteQueries(context.Background(), mut) idExistence := make(map[string]string) upsert, err := rewriterToTest.Rewrite(ctx, mut, idExistence) @@ -822,10 +822,12 @@ func TestAuthQueryRewriting(t *testing.T) { t.Run("Mutation Query Rewriting "+algo, func(t *testing.T) { mutationQueryRewriting(t, strSchema, metaInfo) }) + b = read(t, "auth_add_test.yaml") t.Run("Add Mutation "+algo, func(t *testing.T) { mutationAdd(t, strSchema, metaInfo, b) }) + b = read(t, "auth_update_test.yaml") t.Run("Update Mutation "+algo, func(t *testing.T) { mutationUpdate(t, strSchema, metaInfo, b) diff --git a/graphql/resolve/auth_update_test.yaml b/graphql/resolve/auth_update_test.yaml index 725444bdf3b..7601e0ef9a9 100644 --- a/graphql/resolve/auth_update_test.yaml +++ b/graphql/resolve/auth_update_test.yaml @@ -177,8 +177,9 @@ } dgquery: |- query { - Ticket_1(func: uid(0x789)) @filter(type(Ticket)) { + Ticket_1(func: uid(0x789)) { uid + dgraph.type } } queryjson: | @@ -247,13 +248,14 @@ } dgquery: |- query { - Ticket_1(func: uid(0x789)) @filter(type(Ticket)) { + Ticket_1(func: uid(0x789)) { uid + dgraph.type } } queryjson: | { - "Ticket_1": [ { "uid": "0x789" } ] + "Ticket_1": [ { "uid": "0x789", "dgraph.type":["Ticket"] } ] } dgquerysec: |- query { @@ -323,13 +325,14 @@ } dgquery: |- query { - Column_1(func: uid(0x456)) @filter(type(Column)) { + Column_1(func: uid(0x456)) { uid + dgraph.type } } queryjson: | { - "Column_1": [ { "uid": "0x456" } ] + "Column_1": [ { "uid": "0x456", "dgraph.type": ["Column"]} ] } dgquerysec: |- query { @@ -394,13 +397,14 @@ } dgquery: |- query { - Column_1(func: uid(0x456)) @filter(type(Column)) { + Column_1(func: uid(0x456)) { uid + dgraph.type } } queryjson: | { - "Column_1": [ { "uid": "0x456" } ] + "Column_1": [ { "uid": "0x456", "dgraph.type":["Column"] } ] } dgquerysec: |- query { diff --git a/graphql/resolve/extensions_test.go b/graphql/resolve/extensions_test.go index a371d85c94a..c53b2dcf1dd 100644 --- a/graphql/resolve/extensions_test.go +++ b/graphql/resolve/extensions_test.go @@ -134,7 +134,7 @@ func TestMutationsPropagateExtensions(t *testing.T) { resp := resolveWithClient(gqlSchema, mutation, nil, &executor{ assigned: map[string]string{"Post_2": "0x2"}, - existenceQueriesResp: `{ "Author_1": [{"uid":"0x1"}]}`, + existenceQueriesResp: `{ "Author_1": [{"uid":"0x1", "dgraph.type": ["Author"]}]}`, queryTouched: 2, mutationTouched: 5, }) @@ -190,7 +190,7 @@ func TestMultipleMutationsPropagateExtensionsCorrectly(t *testing.T) { resp := resolveWithClient(gqlSchema, mutation, nil, &executor{ assigned: map[string]string{"Post_2": "0x2"}, - existenceQueriesResp: `{ "Author_1": [{"uid":"0x1"}]}`, + existenceQueriesResp: `{ "Author_1": [{"uid":"0x1", "dgraph.type": ["Author"]}]}`, queryTouched: 2, mutationTouched: 5, }) diff --git a/graphql/resolve/mutation.go b/graphql/resolve/mutation.go index 699917ddf51..2f7b3637e78 100644 --- a/graphql/resolve/mutation.go +++ b/graphql/resolve/mutation.go @@ -89,16 +89,20 @@ type MutationResolver interface { type MutationRewriter interface { // RewriteQueries generates and rewrites GraphQL mutation m into DQL queries which // check if any referenced node by XID or ID exist or not. + // Instead of filtering on dgraph.type like @filter(type(Parrot)), we query `dgraph.type` and + // filter it on GraphQL side. @filter(type(Parrot)) is costly in terms of memory and cpu. // Example existence queries: - // 1. Parrot1(func: uid(0x127)) @filter(type: Parrot) { + // 1. Parrot1(func: uid(0x127)) { // uid + // dgraph.type // } - // 2. Computer2(func: eq(Computer.name, "computer1")) @filter(type(Computer)) { + // 2. Computer2(func: eq(Computer.name, "computer1")) { // uid + // dgraph.type // } // These query will be created in case of Add or Update Mutation which references node // 0x127 or Computer of name "computer1" - RewriteQueries(ctx context.Context, m schema.Mutation) ([]*gql.GraphQuery, error) + RewriteQueries(ctx context.Context, m schema.Mutation) ([]*gql.GraphQuery, []string, error) // Rewrite rewrites GraphQL mutation m into a Dgraph mutation - that could // be as simple as a single DelNquads, or could be a Dgraph upsert mutation // with a query and multiple mutations guarded by conditions. @@ -266,7 +270,8 @@ func (mr *dgraphResolver) rewriteAndExecute( // queries stores rewritten []*gql.GraphQuery by RewriteQueries function. These queries // are then executed and the results are processed var queries []*gql.GraphQuery - queries, err = mr.mutationRewriter.RewriteQueries(ctx, mutation) + var filterTypes []string + queries, filterTypes, err = mr.mutationRewriter.RewriteQueries(ctx, mutation) if err != nil { return emptyResult(schema.GQLWrapf(err, "couldn't rewrite mutation %s", mutation.Name())), resolverFailed @@ -295,22 +300,29 @@ func (mr *dgraphResolver) rewriteAndExecute( // Parse the result of query. // mutResp.Json will contain response to the query. // The response is parsed to existenceQueriesResult + // dgraph.type is a list that contains types and interfaces the type implements. // Example Response: // { - // Project1 : + // Project_1 : // [ // { - // "uid" : "0x123" + // "uid" : "0x123", + // "dgraph.type" : ["Project", "Work"] // } // ], - // Column2 : + // Column_2 : // [ // { - // "uid": "0x234" + // "uid": "0x234", + // "dgraph.type" : ["Column"] // } // ] // } - queryResultMap := make(map[string][]map[string]string) + type res struct { + Uid string `json:"uid"` + Types []string `json:"dgraph.type"` + } + queryResultMap := make(map[string][]res) if mutResp != nil { err = json.Unmarshal(mutResp.Json, &queryResultMap) } @@ -320,22 +332,34 @@ func (mr *dgraphResolver) rewriteAndExecute( return emptyResult(gqlErr), resolverFailed } + x.AssertTrue(len(filterTypes) == len(queries)) + // qNameToType map contains the mapping from the query name to type/interface the query response + // has to be filtered upon. + qNameToType := make(map[string]string) + for i, typ := range filterTypes { + qNameToType[queries[i].Attr] = typ + } // The above response is parsed into map[string]string as follows: // { - // "Project1" : "0x123", - // "Column2" : "0x234" + // "Project_1" : "0x123", + // "Column_2" : "0x234" // } // As only Add and Update mutations generate queries using RewriteQueries, // qNameToUID map will be non-empty only in case of Add or Update Mutation. qNameToUID := make(map[string]string) for key, result := range queryResultMap { - if len(result) == 1 { - // Found exactly one UID / XID corresponding to given condition - qNameToUID[key] = result[0]["uid"] - } else if len(result) > 1 { + count := 0 + typ := qNameToType[key] + for _, res := range result { + if x.HasString(res.Types, typ) { + qNameToUID[key] = res.Uid + count++ + } + } + if count > 1 { // Found multiple UIDs for query. This should ideally not happen. // This indicates that there are multiple nodes with same XIDs / UIDs. Throw an error. - err = errors.New(fmt.Sprintf("Found multiple nodes with ID: %s", result[0]["uid"])) + err = errors.New(fmt.Sprintf("Found multiple nodes with ID: %s", qNameToUID[key])) gqlErr := schema.GQLWrapLocationf( err, mutation.Location(), "mutation %s failed", mutation.Name()) return emptyResult(gqlErr), resolverFailed diff --git a/graphql/resolve/mutation_rewriter.go b/graphql/resolve/mutation_rewriter.go index a3809f2a156..7375b391ff9 100644 --- a/graphql/resolve/mutation_rewriter.go +++ b/graphql/resolve/mutation_rewriter.go @@ -275,7 +275,7 @@ func (xidMetadata *xidMetadata) isDuplicateXid(atTopLevel bool, xidVar string, // mutation will fail. func (arw *AddRewriter) RewriteQueries( ctx context.Context, - m schema.Mutation) ([]*gql.GraphQuery, error) { + m schema.Mutation) ([]*gql.GraphQuery, []string, error) { arw.VarGen = NewVariableGenerator() arw.XidMetadata = NewXidMetadata() @@ -284,11 +284,12 @@ func (arw *AddRewriter) RewriteQueries( val, _ := m.ArgValue(schema.InputArgName).([]interface{}) var ret []*gql.GraphQuery + var retTypes []string var retErrors error for _, i := range val { obj := i.(map[string]interface{}) - queries, errs := existenceQueries(ctx, mutatedType, nil, arw.VarGen, obj, arw.XidMetadata) + queries, typs, errs := existenceQueries(ctx, mutatedType, nil, arw.VarGen, obj, arw.XidMetadata) if len(errs) > 0 { var gqlErrors x.GqlErrorList for _, err := range errs { @@ -298,8 +299,9 @@ func (arw *AddRewriter) RewriteQueries( "failed to rewrite mutation payload")) } ret = append(ret, queries...) + retTypes = append(retTypes, typs...) } - return ret, retErrors + return ret, retTypes, retErrors } // RewriteQueries creates and rewrites set and remove update patches queries. @@ -323,7 +325,7 @@ func (arw *AddRewriter) RewriteQueries( // See AddRewriter for how the rewritten queries look like. func (urw *UpdateRewriter) RewriteQueries( ctx context.Context, - m schema.Mutation) ([]*gql.GraphQuery, error) { + m schema.Mutation) ([]*gql.GraphQuery, []string, error) { mutatedType := m.MutatedType() urw.VarGen = NewVariableGenerator() @@ -334,13 +336,14 @@ func (urw *UpdateRewriter) RewriteQueries( delArg := inp["remove"] var ret []*gql.GraphQuery + var retTypes []string var retErrors error // Write existence queries for set if setArg != nil { obj := setArg.(map[string]interface{}) if len(obj) != 0 { - queries, errs := existenceQueries(ctx, mutatedType, nil, urw.VarGen, obj, urw.XidMetadata) + queries, typs, errs := existenceQueries(ctx, mutatedType, nil, urw.VarGen, obj, urw.XidMetadata) if len(errs) > 0 { var gqlErrors x.GqlErrorList for _, err := range errs { @@ -350,6 +353,7 @@ func (urw *UpdateRewriter) RewriteQueries( "failed to rewrite mutation payload")) } ret = append(ret, queries...) + retTypes = append(retTypes, typs...) } } @@ -357,7 +361,7 @@ func (urw *UpdateRewriter) RewriteQueries( if delArg != nil { obj := delArg.(map[string]interface{}) if len(obj) != 0 { - queries, errs := existenceQueries(ctx, mutatedType, nil, urw.VarGen, obj, urw.XidMetadata) + queries, typs, errs := existenceQueries(ctx, mutatedType, nil, urw.VarGen, obj, urw.XidMetadata) if len(errs) > 0 { var gqlErrors x.GqlErrorList for _, err := range errs { @@ -367,9 +371,10 @@ func (urw *UpdateRewriter) RewriteQueries( "failed to rewrite mutation payload")) } ret = append(ret, queries...) + retTypes = append(retTypes, typs...) } } - return ret, retErrors + return ret, retTypes, retErrors } // Rewrite takes a GraphQL schema.Mutation add and builds a Dgraph upsert mutation. @@ -683,7 +688,6 @@ func (urw *UpdateRewriter) Rewrite( mutations = append(mutations, mutSet) } retErrors = schema.AppendGQLErrs(retErrors, errSet) - queries = append(queries, urw.setFrag.queries...) } @@ -702,7 +706,6 @@ func (urw *UpdateRewriter) Rewrite( mutations = append(mutations, mutDel) } retErrors = schema.AppendGQLErrs(retErrors, errDel) - queries = append(queries, urw.delFrag.queries...) } @@ -720,7 +723,6 @@ func (urw *UpdateRewriter) Rewrite( NewNodes: newNodes, }) } - return ret, retErrors } @@ -1131,11 +1133,11 @@ func (drw *deleteRewriter) MutatedRootUIDs( // The function generates VarGen and XidMetadata which are used in Rewrite function. func (drw *deleteRewriter) RewriteQueries( ctx context.Context, - m schema.Mutation) ([]*gql.GraphQuery, error) { + m schema.Mutation) ([]*gql.GraphQuery, []string, error) { drw.VarGen = NewVariableGenerator() - return []*gql.GraphQuery{}, nil + return []*gql.GraphQuery{}, []string{}, nil } func asUID(val interface{}) (uint64, error) { @@ -1211,8 +1213,8 @@ func mutationFromFragment( } -func checkXIDExistsQuery(xidVariable, xidString, xidPredicate string, typ schema.Type, - interfaceType schema.Type) *gql.GraphQuery { +func checkXIDExistsQuery( + xidVariable, xidString, xidPredicate string, typ schema.Type) *gql.GraphQuery { qry := &gql.GraphQuery{ Attr: xidVariable, Func: &gql.Function{ @@ -1222,24 +1224,13 @@ func checkXIDExistsQuery(xidVariable, xidString, xidPredicate string, typ schema {Value: maybeQuoteArg("eq", xidString)}, }, }, - Children: []*gql.GraphQuery{{Attr: "uid"}}, + Children: []*gql.GraphQuery{{Attr: "uid"}, {Attr: "dgraph.type"}}, } - // Below filter is added to generate existence query for interface - // If given xid field is inherited from interface and - // have interface arg set then we add interface type in filter - if interfaceType != nil { - typ = interfaceType - } - addTypeFilter(qry, typ) return qry } -func checkUIDExistsQuery( - val interface{}, - srcField schema.FieldDefinition, - variable string) (*gql.GraphQuery, error) { - +func checkUIDExistsQuery(val interface{}, variable string) (*gql.GraphQuery, error) { uid, err := asUID(val) if err != nil { return nil, err @@ -1248,9 +1239,8 @@ func checkUIDExistsQuery( query := &gql.GraphQuery{ Attr: variable, UID: []uint64{uid}, - Children: []*gql.GraphQuery{{Attr: "uid"}}, + Children: []*gql.GraphQuery{{Attr: "uid"}, {Attr: "dgraph.type"}}, } - addTypeFilter(query, srcField.Type()) addUIDFunc(query, []uint64{uid}) return query, nil } @@ -1745,10 +1735,11 @@ func existenceQueries( srcField schema.FieldDefinition, varGen *VariableGenerator, obj map[string]interface{}, - xidMetadata *xidMetadata) ([]*gql.GraphQuery, []error) { + xidMetadata *xidMetadata) ([]*gql.GraphQuery, []string, []error) { atTopLevel := srcField == nil var ret []*gql.GraphQuery + var retTypes []string var retErrors []error // Inverse Object field is deleted. This is to ensure that we don't refer any conflicting @@ -1766,19 +1757,19 @@ func existenceQueries( if idVal != nil { // No need to add query if the UID is already been seen. if xidMetadata.seenUIDs[idVal.(string)] == true { - return ret, retErrors + return ret, retTypes, retErrors } // Mark this UID as seen. xidMetadata.seenUIDs[idVal.(string)] = true variable := varGen.Next(typ, id.Name(), idVal.(string), false) - query, err := checkUIDExistsQuery(idVal, srcField, variable) - + query, err := checkUIDExistsQuery(idVal, variable) if err != nil { retErrors = append(retErrors, err) } ret = append(ret, query) - return ret, retErrors + retTypes = append(retTypes, srcField.Type().DgraphName()) + return ret, retTypes, retErrors // Add check UID query and return it. // There is no need to move forward. If reference ID field is given, // it has to exist. @@ -1797,7 +1788,7 @@ func existenceQueries( if xidVal, ok := obj[xid.Name()]; ok && xidVal != nil { xidString, err = extractVal(xidVal, xid.Name(), xid.Type().Name()) if err != nil { - return nil, append(retErrors, err) + return nil, nil, append(retErrors, err) } variable := varGen.Next(typ, xid.Name(), xidString, false) // There are two cases: @@ -1820,7 +1811,7 @@ func existenceQueries( // but are in different implementing type, we currently treat that as reference. err := errors.Errorf("duplicate XID found: %s", xidString) retErrors = append(retErrors, err) - return nil, retErrors + return nil, nil, retErrors } // In the other case it is not duplicate, we update variableObjMap in case the new // occurrence of XID is its description and the old occurrence was a reference. @@ -1837,7 +1828,7 @@ func existenceQueries( xidMetadata.variableObjMap[variable] = obj } else { // This is just a node reference. No need to proceed further. - return ret, retErrors + return ret, retTypes, retErrors } } else { @@ -1849,8 +1840,9 @@ func existenceQueries( // Add the corresponding existence query. As this is the first time we have // encountered this variable, the query is added only once per variable. - query := checkXIDExistsQuery(variable, xidString, xid.Name(), typ, nil) + query := checkXIDExistsQuery(variable, xidString, xid.Name(), typ) ret = append(ret, query) + retTypes = append(retTypes, typ.DgraphName()) // Add one more existence query if given xid field is inherited from interface and has // interface argument set. This is added to ensure that this xid is unique across all the @@ -1859,8 +1851,9 @@ func existenceQueries( xid.Name(), xidString) if interfaceTyp != nil { queryInterface := checkXIDExistsQuery(varInterface, xidString, xid.Name(), - typ, interfaceTyp) + typ) ret = append(ret, queryInterface) + retTypes = append(retTypes, interfaceTyp.DgraphName()) } // Don't return just over here as there maybe more nodes in the children tree. } @@ -1890,27 +1883,35 @@ func existenceQueries( switch val := val.(type) { case map[string]interface{}: if fieldDef.Type().IsUnion() { - fieldQueries, err := existenceQueriesUnion(ctx, typ, fieldDef, varGen, val, xidMetadata, -1) + fieldQueries, fieldTypes, err := existenceQueriesUnion( + ctx, typ, fieldDef, varGen, val, xidMetadata, -1) retErrors = append(retErrors, err...) ret = append(ret, fieldQueries...) + retTypes = append(retTypes, fieldTypes...) } else { - fieldQueries, err := existenceQueries(ctx, fieldDef.Type(), fieldDef, varGen, val, xidMetadata) + fieldQueries, fieldTypes, err := existenceQueries(ctx, + fieldDef.Type(), fieldDef, varGen, val, xidMetadata) retErrors = append(retErrors, err...) ret = append(ret, fieldQueries...) + retTypes = append(retTypes, fieldTypes...) } case []interface{}: for i, object := range val { switch object := object.(type) { case map[string]interface{}: var fieldQueries []*gql.GraphQuery + var fieldTypes []string var err []error if fieldDef.Type().IsUnion() { - fieldQueries, err = existenceQueriesUnion(ctx, typ, fieldDef, varGen, object, xidMetadata, i) + fieldQueries, fieldTypes, err = existenceQueriesUnion( + ctx, typ, fieldDef, varGen, object, xidMetadata, i) } else { - fieldQueries, err = existenceQueries(ctx, fieldDef.Type(), fieldDef, varGen, object, xidMetadata) + fieldQueries, fieldTypes, err = existenceQueries( + ctx, fieldDef.Type(), fieldDef, varGen, object, xidMetadata) } retErrors = append(retErrors, err...) ret = append(ret, fieldQueries...) + retTypes = append(retTypes, fieldTypes...) default: // This is a scalar list. So, it won't contain any XID. // Don't do anything. @@ -1923,12 +1924,12 @@ func existenceQueries( if fieldDef.HasIDDirective() && val == "" { err := fmt.Errorf("encountered an empty value for @id field `%s`", fieldName) retErrors = append(retErrors, err) - return nil, retErrors + return nil, nil, retErrors } } } - return ret, retErrors + return ret, retTypes, retErrors } func existenceQueriesUnion( @@ -1938,7 +1939,7 @@ func existenceQueriesUnion( varGen *VariableGenerator, obj map[string]interface{}, xidMetadata *xidMetadata, - listIndex int) ([]*gql.GraphQuery, []error) { + listIndex int) ([]*gql.GraphQuery, []string, []error) { var retError []error if len(obj) != 1 { @@ -1955,7 +1956,7 @@ func existenceQueriesUnion( srcField.Name(), parentTyp.Name(), len(obj)) } retError = append(retError, err) - return nil, retError + return nil, nil, retError } var newtyp schema.Type diff --git a/graphql/resolve/mutation_test.go b/graphql/resolve/mutation_test.go index 4e4581d58d8..be5a32821bf 100644 --- a/graphql/resolve/mutation_test.go +++ b/graphql/resolve/mutation_test.go @@ -210,7 +210,7 @@ func deleteMutationRewriting(t *testing.T, file string, rewriterFactory func() M rewriterToTest := rewriterFactory() // -- Act -- - _, _ = rewriterToTest.RewriteQueries(context.Background(), mut) + _, _, _ = rewriterToTest.RewriteQueries(context.Background(), mut) idExistence := make(map[string]string) upsert, err := rewriterToTest.Rewrite(context.Background(), mut, idExistence) // -- Assert -- @@ -282,7 +282,7 @@ func mutationRewriting(t *testing.T, file string, rewriterFactory func() Mutatio rewriterToTest := rewriterFactory() // -- Query -- - queries, err := rewriterToTest.RewriteQueries(context.Background(), mut) + queries, _, err := rewriterToTest.RewriteQueries(context.Background(), mut) // -- Assert -- if tcase.Error != nil || err != nil { require.NotNil(t, err) @@ -381,7 +381,7 @@ func TestMutationQueryRewriting(t *testing.T) { require.NoError(t, err) gqlMutation := test.GetMutation(t, op) - _, _ = rewriter.RewriteQueries(context.Background(), gqlMutation) + _, _, _ = rewriter.RewriteQueries(context.Background(), gqlMutation) _, err = rewriter.Rewrite(context.Background(), gqlMutation, tt.idExistence) require.Nil(t, err) diff --git a/graphql/resolve/resolver_error_test.go b/graphql/resolve/resolver_error_test.go index 7a4cdc1657a..dd58040dc21 100644 --- a/graphql/resolve/resolver_error_test.go +++ b/graphql/resolve/resolver_error_test.go @@ -431,7 +431,7 @@ func TestManyMutationsWithError(t *testing.T) { multiMutation, map[string]interface{}{"id": tcase.idValue}, &executor{ - existenceQueriesResp: `{ "Author_1": [{"uid":"0x1"}]}`, + existenceQueriesResp: `{ "Author_1": [{"uid":"0x1", "dgraph.type":["Author"]}]}`, resp: tcase.queryResponse, assigned: tcase.mutResponse, failMutation: 2}) diff --git a/graphql/resolve/update_mutation_test.yaml b/graphql/resolve/update_mutation_test.yaml index bb4914200f1..054b915e091 100644 --- a/graphql/resolve/update_mutation_test.yaml +++ b/graphql/resolve/update_mutation_test.yaml @@ -531,8 +531,9 @@ } dgquery: |- query { - Post_1(func: uid(0x456)) @filter(type(Post)) { + Post_1(func: uid(0x456)) { uid + dgraph.type } } qnametouid: | @@ -619,8 +620,9 @@ } dgquery: |- query { - ComputerOwner_1(func: eq(ComputerOwner.name, "computerOwnerName")) @filter(type(ComputerOwner)) { + ComputerOwner_1(func: eq(ComputerOwner.name, "computerOwnerName")) { uid + dgraph.type } } qnametouid: | @@ -668,8 +670,9 @@ } dgquery: |- query { - Post_1(func: uid(0x124)) @filter(type(Post)) { + Post_1(func: uid(0x124)) { uid + dgraph.type } } qnametouid: | @@ -717,8 +720,9 @@ } dgquery: |- query { - Post_1(func: uid(0x456)) @filter(type(Post)) { + Post_1(func: uid(0x456)) { uid + dgraph.type } } qnametouid: | @@ -795,11 +799,13 @@ } dgquery: |- query { - Post_1(func: uid(0x456)) @filter(type(Post)) { + Post_1(func: uid(0x456)) { uid + dgraph.type } - Post_2(func: uid(0x789)) @filter(type(Post)) { + Post_2(func: uid(0x789)) { uid + dgraph.type } } qnametouid: | @@ -872,8 +878,9 @@ explanation: "updateAuthor doesn't update posts except where references are removed" dgquery: |- query { - Post_1(func: uid(0x456)) @filter(type(Post)) { + Post_1(func: uid(0x456)) { uid + dgraph.type } } qnametouid: | @@ -977,8 +984,9 @@ explanation: "The update creates a new state" dgquery: |- query { - State_1(func: eq(State.code, "dg")) @filter(type(State)) { + State_1(func: eq(State.code, "dg")) { uid + dgraph.type } } dgquerysec: |- @@ -1038,8 +1046,9 @@ explanation: "The update links to existing state" dgquery: |- query { - State_1(func: eq(State.code, "dg")) @filter(type(State)) { + State_1(func: eq(State.code, "dg")) { uid + dgraph.type } } qnametouid: | @@ -1108,8 +1117,9 @@ explanation: "The update must link to the existing state" dgquery: |- query { - State_1(func: eq(State.code, "dg")) @filter(type(State)) { + State_1(func: eq(State.code, "dg")) { uid + dgraph.type } } qnametouid: | @@ -1174,8 +1184,9 @@ explanation: " Owner 0x123" dgquery: |- query { - House_1(func: uid(0x456)) @filter(type(House)) { + House_1(func: uid(0x456)) { uid + dgraph.type } } qnametouid: | @@ -1237,8 +1248,9 @@ } dgquery: |- query { - Movie_1(func: uid(0x456)) @filter(type(Movie)) { + Movie_1(func: uid(0x456)) { uid + dgraph.type } } qnametouid: | @@ -1284,8 +1296,9 @@ } dgquery: |- query { - Movie_1(func: uid(0x456)) @filter(type(Movie)) { + Movie_1(func: uid(0x456)) { uid + dgraph.type } } qnametouid: | @@ -1342,8 +1355,9 @@ is same, it should not return error." dgquery: |- query { - Teacher_1(func: eq(People.xid, "T1")) @filter(type(Teacher)) { + Teacher_1(func: eq(People.xid, "T1")) { uid + dgraph.type } } dgquerysec: |- @@ -1546,8 +1560,9 @@ } dgquery: |- query { - Post_1(func: uid(0x456)) @filter(type(Post)) { + Post_1(func: uid(0x456)) { uid + dgraph.type } } qnametouid: | @@ -1605,8 +1620,9 @@ } dgquery: |- query { - Author_1(func: uid(0x456)) @filter(type(Author)) { + Author_1(func: uid(0x456)) { uid + dgraph.type } } qnametouid: | @@ -1662,8 +1678,9 @@ } dgquery: |- query { - State_1(func: eq(State.code, "abc")) @filter(type(State)) { + State_1(func: eq(State.code, "abc")) { uid + dgraph.type } } dgquerysec: |- @@ -1731,8 +1748,9 @@ } dgquery: |- query { - Computer_1(func: eq(Computer.name, "Comp")) @filter(type(Computer)) { + Computer_1(func: eq(Computer.name, "Comp")) { uid + dgraph.type } } dgquerysec: |- @@ -1790,11 +1808,13 @@ } dgquery: |- query { - Parrot_1(func: uid(0x124)) @filter(type(Parrot)) { + Parrot_1(func: uid(0x124)) { uid + dgraph.type } - Parrot_2(func: uid(0x125)) @filter(type(Parrot)) { + Parrot_2(func: uid(0x125)) { uid + dgraph.type } } qnametouid: | @@ -2001,11 +2021,13 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "I001")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "I001")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "History of Humans")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "History of Humans")) { uid + dgraph.type } } dgquerysec: |- @@ -2063,11 +2085,13 @@ } dgquery: |- query { - Book_1(func: eq(Book.ISBN, "I001")) @filter(type(Book)) { + Book_1(func: eq(Book.ISBN, "I001")) { uid + dgraph.type } - Book_2(func: eq(Book.title, "History of Humans")) @filter(type(Book)) { + Book_2(func: eq(Book.title, "History of Humans")) { uid + dgraph.type } } qnametouid: |- @@ -2113,11 +2137,13 @@ } dgquery: |- query { - Post1_1(func: eq(Post1.id, "P01")) @filter(type(Post1)) { + Post1_1(func: eq(Post1.id, "P01")) { uid + dgraph.type } - Comment1_2(func: eq(Comment1.id, "C01")) @filter(type(Comment1)) { + Comment1_2(func: eq(Comment1.id, "C01")) { uid + dgraph.type } } dgquerysec: |- @@ -2178,8 +2204,9 @@ } dgquery: |- query { - Post1_1(func: eq(Post1.id, "P01")) @filter(type(Post1)) { + Post1_1(func: eq(Post1.id, "P01")) { uid + dgraph.type } } error2: @@ -2218,14 +2245,17 @@ dgquery: |- query { - LibraryMember_1(func: eq(Member.name, "Alice")) @filter(type(LibraryMember)) { + LibraryMember_1(func: eq(Member.name, "Alice")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.refID, "102")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.refID, "102")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "102")) @filter(type(Member)) { + LibraryMember_3(func: eq(Member.refID, "102")) { uid + dgraph.type } } dgquerysec: |- @@ -2273,14 +2303,17 @@ } dgquery: |- query { - LibraryMember_1(func: eq(Member.name, "Alice")) @filter(type(LibraryMember)) { + LibraryMember_1(func: eq(Member.name, "Alice")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.refID, "102")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.refID, "102")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "102")) @filter(type(Member)) { + LibraryMember_3(func: eq(Member.refID, "102")) { uid + dgraph.type } } qnametouid: |- @@ -2325,14 +2358,17 @@ } dgquery: |- query { - LibraryManager_1(func: eq(LibraryManager.name, "Bob")) @filter(type(LibraryManager)) { + LibraryManager_1(func: eq(LibraryManager.name, "Bob")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.refID, "101")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.refID, "101")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "101")) @filter(type(Member)) { + LibraryMember_3(func: eq(Member.refID, "101")) { uid + dgraph.type } } qnametouid: |- @@ -2375,14 +2411,17 @@ } dgquery: |- query { - LibraryManager_1(func: eq(LibraryManager.name, "Bob")) @filter(type(LibraryManager)) { + LibraryManager_1(func: eq(LibraryManager.name, "Bob")) { uid + dgraph.type } - LibraryMember_2(func: eq(Member.refID, "101")) @filter(type(LibraryMember)) { + LibraryMember_2(func: eq(Member.refID, "101")) { uid + dgraph.type } - LibraryMember_3(func: eq(Member.refID, "101")) @filter(type(Member)) { + LibraryMember_3(func: eq(Member.refID, "101")) { uid + dgraph.type } } qnametouid: |-