From 722e428c44cbb3ba4dd21f39c4798da9c5e5e4e1 Mon Sep 17 00:00:00 2001 From: Pawan Rawal Date: Thu, 6 Aug 2020 17:50:07 +0530 Subject: [PATCH] fix(GraphQL): Fix getType queries when id was used as a name for types other than ID (#6130) For the schema type Tweets { id: String! @id score: Int } getTweets query was not being properly re-written. This is because we were using the name id to signify that a field is of type ID instead of the type ID itself. That has been fixed now. So getTweets would work if the field was named anything. query MyQuery { getTweets(id: "1286891968727982081") { score id } } (cherry picked from commit bb8e4b9d5456cc05a1abd15933b95881ca8e156b) --- graphql/resolve/query_test.yaml | 20 ++++++++++++++++++-- graphql/resolve/schema.graphql | 5 +++++ graphql/schema/wrappers.go | 16 ++++++++++++---- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/graphql/resolve/query_test.yaml b/graphql/resolve/query_test.yaml index 001198bc580..1912632b74b 100644 --- a/graphql/resolve/query_test.yaml +++ b/graphql/resolve/query_test.yaml @@ -1326,7 +1326,7 @@ } } } - dgquery: | + dgquery: |- query { getPost(func: uid(0x1)) @filter(type(Post)) { postID : uid @@ -1338,4 +1338,20 @@ url : Comment.url } } - } \ No newline at end of file + } +- name: "getType by id should work" + gqlquery: |- + query { + getTweets(id: "1286891968727982081") { + score + id + } + } + dgquery: |- + query { + getTweets(func: eq(Tweets.id, "1286891968727982081")) @filter(type(Tweets)) { + score : Tweets.score + id : Tweets.id + dgraph.uid : uid + } + } diff --git a/graphql/resolve/schema.graphql b/graphql/resolve/schema.graphql index 806b2cf47bc..c3e0797565f 100644 --- a/graphql/resolve/schema.graphql +++ b/graphql/resolve/schema.graphql @@ -239,3 +239,8 @@ type Y implements X @auth( ){ userRole: String @search(by: [hash]) } + +type Tweets { + id: String! @id + score: Int +} \ No newline at end of file diff --git a/graphql/schema/wrappers.go b/graphql/schema/wrappers.go index eb590e5e39a..7ed9c2502ab 100644 --- a/graphql/schema/wrappers.go +++ b/graphql/schema/wrappers.go @@ -87,7 +87,6 @@ const ( HTTPMutation MutationType = "http" NotSupportedMutation MutationType = "notsupported" IDType = "ID" - IDArgName = "id" InputArgName = "input" FilterArgName = "filter" ) @@ -731,8 +730,17 @@ func (f *field) HasCustomDirective() (bool, map[string]bool) { func (f *field) XIDArg() string { xidArgName := "" passwordField := f.Type().PasswordField() - for _, arg := range f.field.Arguments { - if arg.Name != IDArgName && (passwordField == nil || + + args := f.field.Definition.Arguments + if len(f.field.Definition.Arguments) == 0 { + // For acl endpoints like getCurrentUser which redirects to getUser resolver, the field + // definition doesn't change and hence we can't find the arguments for getUser. As a + // fallback, we get the args from the query field arguments in that case. + args = f.op.inSchema.schema.Query.Fields.ForName(f.Name()).Arguments + } + + for _, arg := range args { + if arg.Type.Name() != IDType && (passwordField == nil || arg.Name != passwordField.Name()) { xidArgName = arg.Name } @@ -1608,7 +1616,7 @@ func (t *astType) Interfaces() []string { // satisfy a valid post. func (t *astType) EnsureNonNulls(obj map[string]interface{}, exclusion string) error { for _, fld := range t.inSchema.schema.Types[t.Name()].Fields { - if fld.Type.NonNull && !isID(fld) && !(fld.Name == exclusion) { + if fld.Type.NonNull && !isID(fld) && fld.Name != exclusion { if val, ok := obj[fld.Name]; !ok || val == nil { return errors.Errorf( "type %s requires a value for field %s, but no value present",