From 1704d5b45d6f9cf8382f86c2e062b183c4556139 Mon Sep 17 00:00:00 2001 From: vmrajas Date: Thu, 15 Apr 2021 11:49:51 +0530 Subject: [PATCH] Fix(GraphQL): Fix GraphQL encoding in case of empty list (#7726) * Fix output node rewriting in case of null list * Fix lint (cherry picked from commit 9e8ab992b2c38e18f89f40bdb698e272a9c402ce) --- graphql/e2e/common/common.go | 3 ++- graphql/e2e/common/mutation.go | 6 +++++- graphql/e2e/directives/schema.graphql | 1 + graphql/e2e/directives/schema_response.json | 8 ++++++++ graphql/e2e/normal/schema.graphql | 1 + graphql/e2e/normal/schema_response.json | 8 ++++++++ query/outputnode_graphql.go | 11 ++++++++++- 7 files changed, 35 insertions(+), 3 deletions(-) diff --git a/graphql/e2e/common/common.go b/graphql/e2e/common/common.go index 64e1e12e7db..5433b9451b5 100644 --- a/graphql/e2e/common/common.go +++ b/graphql/e2e/common/common.go @@ -861,7 +861,8 @@ func RunAll(t *testing.T) { t.Run("add multiple mutations", testMultipleMutations) t.Run("deep XID mutations", deepXIDMutations) t.Run("three level xid", testThreeLevelXID) - t.Run("nested add mutation with @hasInverse", nestedAddMutationWithHasInverse) + t.Run("nested add mutation with multiple linked lists and @hasInverse", + nestedAddMutationWithMultipleLinkedListsAndHasInverse) t.Run("add mutation with @hasInverse overrides correctly", addMutationWithHasInverseOverridesCorrectly) t.Run("error in multiple mutations", addMultipleMutationWithOneError) t.Run("dgraph directive with reverse edge adds data correctly", diff --git a/graphql/e2e/common/mutation.go b/graphql/e2e/common/mutation.go index c3386341c57..004d0451277 100644 --- a/graphql/e2e/common/mutation.go +++ b/graphql/e2e/common/mutation.go @@ -4143,7 +4143,7 @@ func intWithList(t *testing.T) { } -func nestedAddMutationWithHasInverse(t *testing.T) { +func nestedAddMutationWithMultipleLinkedListsAndHasInverse(t *testing.T) { params := &GraphQLParams{ Query: `mutation addPerson1($input: [AddPerson1Input!]!) { addPerson1(input: $input) { @@ -4151,6 +4151,9 @@ func nestedAddMutationWithHasInverse(t *testing.T) { name friends { name + closeFriends { + name + } friends { name } @@ -4186,6 +4189,7 @@ func nestedAddMutationWithHasInverse(t *testing.T) { { "friends": [ { + "closeFriends": [], "friends": [ { "name": "Or" diff --git a/graphql/e2e/directives/schema.graphql b/graphql/e2e/directives/schema.graphql index cfc4b4f26cf..64af79b7c9a 100644 --- a/graphql/e2e/directives/schema.graphql +++ b/graphql/e2e/directives/schema.graphql @@ -207,6 +207,7 @@ type post1{ type Person1 { id: ID! name: String! + closeFriends: [Person1] @hasInverse(field: closeFriends) friends: [Person1] @hasInverse(field: friends) } diff --git a/graphql/e2e/directives/schema_response.json b/graphql/e2e/directives/schema_response.json index c8d1cdfd891..b1377b73c3f 100644 --- a/graphql/e2e/directives/schema_response.json +++ b/graphql/e2e/directives/schema_response.json @@ -336,6 +336,11 @@ "type": "uid", "list": true }, + { + "predicate": "Person1.closeFriends", + "type": "uid", + "list": true + }, { "predicate": "Person1.name", "type": "string" @@ -1061,6 +1066,9 @@ }, { "name": "Person1.friends" + }, + { + "name": "Person1.closeFriends" } ], "name": "Person1" diff --git a/graphql/e2e/normal/schema.graphql b/graphql/e2e/normal/schema.graphql index f456ab96653..347a282c4f4 100644 --- a/graphql/e2e/normal/schema.graphql +++ b/graphql/e2e/normal/schema.graphql @@ -213,6 +213,7 @@ type post1{ type Person1 { id: ID! name: String! + closeFriends: [Person1] @hasInverse(field: closeFriends) friends: [Person1] @hasInverse(field: friends) } diff --git a/graphql/e2e/normal/schema_response.json b/graphql/e2e/normal/schema_response.json index 4a4de22504a..5d6b0c5708b 100644 --- a/graphql/e2e/normal/schema_response.json +++ b/graphql/e2e/normal/schema_response.json @@ -422,6 +422,11 @@ "type": "uid", "list": true }, + { + "predicate": "Person1.closeFriends", + "type": "uid", + "list": true + }, { "predicate": "Person1.name", "type": "string" @@ -1117,6 +1122,9 @@ }, { "name": "Person1.friends" + }, + { + "name": "Person1.closeFriends" } ], "name": "Person1" diff --git a/query/outputnode_graphql.go b/query/outputnode_graphql.go index 26501e45418..e051705d664 100644 --- a/query/outputnode_graphql.go +++ b/query/outputnode_graphql.go @@ -444,7 +444,16 @@ func (genc *graphQLEncoder) encode(encInp encodeInput) bool { } // Step-3: Update counters and Write closing ] for JSON arrays - if !curSelectionIsDgList || next == nil || genc.getAttr(cur) != genc.getAttr(next) { + // We perform this step in any of the 4 conditions is satisfied. + // 1. The current selection is not a Dgraph List (It's of custom type or a single JSON object) + // 2. We are at the end of json encoding process and there is no fastjson node ahead (next == nil) + // 3. We are at the end of list writing and the type of next fastJSON node is not equal to + // type of curr fastJSON node. + // 4. The current selection set which we are encoding is not equal to the type of + // current fastJSON node. + if !curSelectionIsDgList || next == nil || + genc.getAttr(cur) != genc.getAttr(next) || + curSelection.DgraphAlias() != genc.attrForID(genc.getAttr(cur)) { if curSelectionIsDgList && !nullWritten { x.Check2(genc.buf.WriteRune(']')) }