diff --git a/graphql/e2e/common/common.go b/graphql/e2e/common/common.go index a019c8e6fee..ee6b5bcf64c 100644 --- a/graphql/e2e/common/common.go +++ b/graphql/e2e/common/common.go @@ -911,6 +911,7 @@ func RunAll(t *testing.T) { t.Run("lambda on interface field", lambdaOnInterfaceField) t.Run("lambda on query using dql", lambdaOnQueryUsingDql) t.Run("lambda on mutation using graphql", lambdaOnMutationUsingGraphQL) + t.Run("lambda on query with no unique parents", lambdaOnQueryWithNoUniqueParents) t.Run("query lambda field in a mutation with duplicate @id", lambdaInMutationWithDuplicateId) t.Run("lambda with apollo federation", lambdaWithApolloFederation) } diff --git a/graphql/e2e/common/lambda.go b/graphql/e2e/common/lambda.go index 1acd33842b5..8d863309c78 100644 --- a/graphql/e2e/common/lambda.go +++ b/graphql/e2e/common/lambda.go @@ -193,6 +193,24 @@ func lambdaOnMutationUsingGraphQL(t *testing.T) { deleteAuthors(t, []string{addResp.AuthorID}, nil) } +func lambdaOnQueryWithNoUniqueParents(t *testing.T) { + queryBookParams := &GraphQLParams{Query: ` + query{ + getBook(bookId: 1){ + name + desc + summary + } + } + `} + + resp := queryBookParams.ExecuteAsPost(t, GraphqlURL) + RequireNoGQLErrors(t, resp) + testutil.CompareJSON(t, `{ + "getBook": null + }`, string(resp.Data)) +} + // See: https://discuss.dgraph.io/t/slash-graphql-lambda-bug/12233 func lambdaInMutationWithDuplicateId(t *testing.T) { addStudentParams := &GraphQLParams{Query: ` diff --git a/query/outputnode_graphql.go b/query/outputnode_graphql.go index 807fde30bfd..26501e45418 100644 --- a/query/outputnode_graphql.go +++ b/query/outputnode_graphql.go @@ -638,7 +638,7 @@ func (genc *graphQLEncoder) processCustomFields(field gqlSchema.Field, n fastJso // * a linear search to find the correct fastJson node for a custom field, or // * first fix the order of custom fastJson nodes and then continue the encoding, or // * create a map from custom fastJson node attr to the custom fastJson node, - // so that whenever a custom field in encountered in the selection set, + // so that whenever a custom field is encountered in the selection set, // just use the map to find out the fastJson node for that field. // The last option seems better. @@ -836,6 +836,10 @@ func (genc *graphQLEncoder) resolveCustomField(childField gqlSchema.Field, } } + if len(uniqueParents) == 0 { + return + } + switch fconf.Mode { case gqlSchema.SINGLE: // In SINGLE mode, we can consider steps 2-5 as a single isolated unit of computation,