From c95c46460473e23c3340514ad9457cdb0be7095d Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Wed, 13 Jan 2021 18:30:14 +0530 Subject: [PATCH] perf(GraphQL): JSON Part-5: Change query rewriting for scalar/object fields asked multiple times at same level (GRAPHQL-938) (#7283) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, for a GraphQL query like this: ``` query { queryThing { i1: id i2: id name n: name n1: name } } ``` GraphQL layer used to generate following DQL query: ``` query { queryThing(func: type(Thing)) { id : uid name : Thing.name } } ``` This can’t work with the new way of JSON encoding for GraphQL because it expects that everything asked for in GraphQL query is present in DQL response. So, Now, the GraphQL layer generates the following DQL to make it work: ``` query { queryThing(func: type(Thing)) { Thing.i1 : uid Thing.i2: uid Thing.name : Thing.name Thing.n : Thing.name Thing.n1 : Thing.name } } ``` Basically, the `DgraphAlias()` is now generated using the `TypeCondition.GraphqlAlias` format. That works even with fragments as they have their specific type conditions. Here are related thoughts: ``` query { queryHuman { name n: name } # DQL: use field.name as DgAlias() # queryHuman(func: type(Human)) { # name: Human.name # name: Human.name # } # => just using field.name doesn't work => use field.alias # queryHuman(func: type(Human)) { # name: Human.name # n: Human.name # } # but there are interfaces and fragments queryCharacter { ... on Human { n: name } ... on Droid { n: bio } } # DQL: use field.alias as DgAlias() # queryCharacter(func: type(Character)) { # n: Character.name # n: Character.bio # } # => just using field.alias doesn't work => use field.name + field.alias # queryCharacter(func: type(Character)) { # name.n: Character.name # bio.n: Character.bio # } # but the implementing types may have fields with same name not inherited from the interface queryThing { ... on ThingOne { c: color } ... on ThingTwo { c: color } } # DQL: use field.name + field.alias as DgAlias() # queryThing(func: type(Thing)) { # color.c: ThingOne.color # color.c: ThingTwo.color # } # => even that doesn't work => use Typename + field.name + field.alias # queryThing(func: type(Thing)) { # ThingOne.color.c: ThingOne.color # ThingTwo.color.c: ThingTwo.color # } # nice! but then different frags explicitly ask for an inherited field with same name & alias queryCharacter { ... on Human { n: name } ... on Droid { n: name } } # DQL: use Typename + field.name + field.alias as DgAlias() # queryCharacter(func: type(Character)) { # Character.name.n: Character.name # Character.name.n: Character.name # } # => doesn't work => use typeCond + Typename + field.name + field.alias # queryCharacter(func: type(Character)) { # Human.Character.name.n: Character.name # Droid.Character.name.n: Character.name # } # but wait, wouldn't just typeCond + field.alias work? # queryCharacter(func: type(Character)) { # Human.n: Character.name # Droid.n: Character.name # } # yeah! that works even for all the above cases. # # OR # # just appending the count when encountering duplicate alias at the same level also works. # But, we need to maintain the count map every time we need DgAlias(). # Also, this requires query pre-processing and the generated aliases are non-deterministic. # # So, we are going with the typeCond + field.alias approach. That will work with @custom(dql:...) too. } ``` --- graphql/e2e/auth/auth_test.go | 16 +- graphql/e2e/common/common.go | 36 + graphql/e2e/common/fragment.go | 184 +++-- graphql/e2e/common/lambda.go | 2 + graphql/e2e/common/query.go | 23 +- graphql/resolve/auth_add_test.yaml | 136 ++-- .../auth_closed_by_default_query_test.yaml | 16 - graphql/resolve/auth_delete_test.yaml | 96 +-- graphql/resolve/auth_query_test.yaml | 464 ++++++------- graphql/resolve/auth_test.go | 52 +- graphql/resolve/auth_update_test.yaml | 118 ++-- graphql/resolve/delete_mutation_test.yaml | 22 +- graphql/resolve/mutation_query_test.yaml | 152 ++-- graphql/resolve/mutation_rewriter.go | 22 +- graphql/resolve/mutation_test.go | 21 +- graphql/resolve/query_rewriter.go | 114 ++- graphql/resolve/query_test.yaml | 654 +++++++++--------- graphql/resolve/resolver.go | 2 +- graphql/schema/wrappers.go | 103 +-- query/outputnode_graphql.go | 181 +++-- testutil/graphql.go | 4 +- 21 files changed, 1214 insertions(+), 1204 deletions(-) diff --git a/graphql/e2e/auth/auth_test.go b/graphql/e2e/auth/auth_test.go index 2fba3b9027f..7f1d9f7274a 100644 --- a/graphql/e2e/auth/auth_test.go +++ b/graphql/e2e/auth/auth_test.go @@ -1622,7 +1622,11 @@ func TestChildAggregateQueryWithDeepRBAC(t *testing.T) { [ { "username": "user1", - "issuesAggregate": null + "issuesAggregate": { + "count": null, + "msgMax": null, + "msgMin": null + } } ] }`}, @@ -1668,7 +1672,7 @@ func TestChildAggregateQueryWithDeepRBAC(t *testing.T) { gqlResponse := getUserParams.ExecuteAsPost(t, common.GraphqlURL) common.RequireNoGQLErrors(t, gqlResponse) - require.JSONEq(t, string(gqlResponse.Data), tcase.result) + require.JSONEq(t, tcase.result, string(gqlResponse.Data)) }) } } @@ -1684,7 +1688,11 @@ func TestChildAggregateQueryWithOtherFields(t *testing.T) { { "username": "user1", "issues":[], - "issuesAggregate": null + "issuesAggregate": { + "count": null, + "msgMin": null, + "msgMax": null + } } ] }`}, @@ -1739,7 +1747,7 @@ func TestChildAggregateQueryWithOtherFields(t *testing.T) { gqlResponse := getUserParams.ExecuteAsPost(t, common.GraphqlURL) common.RequireNoGQLErrors(t, gqlResponse) - require.JSONEq(t, string(gqlResponse.Data), tcase.result) + require.JSONEq(t, tcase.result, string(gqlResponse.Data)) }) } } diff --git a/graphql/e2e/common/common.go b/graphql/e2e/common/common.go index d5ff69e3084..08b64c2666a 100644 --- a/graphql/e2e/common/common.go +++ b/graphql/e2e/common/common.go @@ -463,6 +463,42 @@ func assertUpdateGqlSchemaUsingAdminSchemaEndpt(t *testing.T, authority, schema AssertSchemaUpdateCounterIncrement(t, authority, oldCounter) } +// JSONEqGraphQL compares two JSON strings obtained from a /graphql response. +// To avoid issues, don't use space for indentation in expected input. +// +// The comparison requirements for JSON reported by /graphql are following: +// * The key order matters in object comparison, i.e. +// {"hello": "world", "foo": "bar"} +// is not same as: +// {"foo": "bar", "hello": "world"} +// * A key missing in an object is not same as that key present with value null, i.e. +// {"hello": "world"} +// is not same as: +// {"hello": "world", "foo": null} +// * Integers that are out of the [-(2^53)+1, (2^53)-1] precision range supported by JSON RFC, +// should still be encoded with full precision. i.e., the number 9007199254740993 ( = 2^53 + 1) +// should not get encoded as 9007199254740992 ( = 2^53). This happens in Go's standard JSON +// parser due to IEEE754 precision loss for floating point numbers. +// +// The above requirements are not satisfied by the standard require.JSONEq or testutil.CompareJSON +// methods. +// In order to satisfy all these requirements, this implementation just requires that the input +// strings be equal after removing `\r`, `\n`, `\t` whitespace characters from the inputs. +// TODO: +// Find a better way to do this such that order isn't mandated in list comparison. +// So that it is actually usable at places it is not used at present. +func JSONEqGraphQL(t *testing.T, expected, actual string) { + expected = strings.ReplaceAll(expected, "\r", "") + expected = strings.ReplaceAll(expected, "\n", "") + expected = strings.ReplaceAll(expected, "\t", "") + + actual = strings.ReplaceAll(actual, "\r", "") + actual = strings.ReplaceAll(actual, "\n", "") + actual = strings.ReplaceAll(actual, "\t", "") + + require.Equal(t, expected, actual) +} + func (twt *Tweets) DeleteByID(t *testing.T, user string, metaInfo *testutil.AuthMeta) { getParams := &GraphQLParams{ Headers: GetJWT(t, user, "", metaInfo), diff --git a/graphql/e2e/common/fragment.go b/graphql/e2e/common/fragment.go index 31a7a4e6497..035ca93943d 100644 --- a/graphql/e2e/common/fragment.go +++ b/graphql/e2e/common/fragment.go @@ -108,23 +108,15 @@ func fragmentInQuery(t *testing.T) { queryStarshipExpected := fmt.Sprintf(` { "queryStarship":[{ - "id": "%s", + "id":"%s", "name":"Millennium Falcon", - "length":2 + "length":2.000000 }] }`, newStarship.ID) - var expected, result struct { - QueryStarship []*starship - } - err := json.Unmarshal([]byte(queryStarshipExpected), &expected) - require.NoError(t, err) - err = json.Unmarshal(gqlResponse.Data, &result) - require.NoError(t, err) + JSONEqGraphQL(t, queryStarshipExpected, string(gqlResponse.Data)) - require.Equal(t, expected, result) - - cleanupStarwars(t, result.QueryStarship[0].ID, "", "") + cleanupStarwars(t, newStarship.ID, "", "") } func fragmentInQueryOnInterface(t *testing.T) { @@ -281,51 +273,51 @@ func fragmentInQueryOnInterface(t *testing.T) { { "queryCharacter":[ { - "__typename": "Human", - "id": "%s", - "name": "Han", - "appearsIn": ["EMPIRE"], - "starships": [{ - "__typename": "Starship", - "id": "%s", - "name": "Millennium Falcon", - "length": 2 + "__typename":"Human", + "id":"%s", + "name":"Han", + "appearsIn":["EMPIRE"], + "starships":[{ + "__typename":"Starship", + "id":"%s", + "name":"Millennium Falcon", + "length":2.000000 }], - "totalCredits": 10, - "ename": "Han_employee" + "totalCredits":10.000000, + "ename":"Han_employee" }, { - "__typename": "Droid", - "id": "%s", - "name": "R2-D2", - "appearsIn": ["EMPIRE"], - "primaryFunction": "Robot" + "__typename":"Droid", + "id":"%s", + "name":"R2-D2", + "appearsIn":["EMPIRE"], + "primaryFunction":"Robot" } ], "qc":[ { - "__typename": "Human", - "id": "%s", - "name": "Han" + "__typename":"Human", + "id":"%s", + "name":"Han" }, { - "__typename": "Droid", - "appearsIn": ["EMPIRE"] + "__typename":"Droid", + "appearsIn":["EMPIRE"] } ], "qc1":[ { - "__typename": "Human", - "id": "%s" + "__typename":"Human", + "id":"%s" }, { - "id": "%s" + "id":"%s" } ], "qc2":[ { - "name": "Han", - "n": "Han" + "name":"Han", + "n":"Han" }, { } @@ -341,69 +333,63 @@ func fragmentInQueryOnInterface(t *testing.T) { "primaryFunction":"Robot" } ], - "qcRep1": [ - { - "name": "Han", - "totalCredits": 10 - }, - { - "name": "R2-D2", - "primaryFunction": "Robot" - } + "qcRep1":[ + { + "name":"Han", + "totalCredits":10.000000 + }, + { + "name":"R2-D2", + "primaryFunction":"Robot" + } ], - "qcRep2": [ - { - "totalCredits": 10, - "name": "Han" - }, - { - "name": "R2-D2", - "primaryFunction": "Robot" - } + "qcRep2":[ + { + "totalCredits":10.000000, + "name":"Han" + }, + { + "name":"R2-D2", + "primaryFunction":"Robot" + } ], - "qcRep3": [ - { - "name": "Han" - }, - { - "name": "R2-D2" - } + "qcRep3":[ + { + "name":"Han" + }, + { + "name":"R2-D2" + } ], "queryThing":[ { - "__typename": "ThingOne", - "id": "%s", - "name": "Thing-1", - "color": "White", - "usedBy": "me" + "__typename":"ThingOne", + "id":"%s", + "name":"Thing-1", + "color":"White", + "usedBy":"me" }, { - "__typename": "ThingTwo", - "id": "%s", - "name": "Thing-2", - "color": "Black", - "owner": "someone" + "__typename":"ThingTwo", + "id":"%s", + "name":"Thing-2", + "color":"Black", + "owner":"someone" } ], "qt":[ { - "__typename": "ThingOne", - "id": "%s" + "__typename":"ThingOne", + "id":"%s" }, { - "__typename": "ThingTwo" + "__typename":"ThingTwo" } ] }`, humanID, newStarship.ID, droidID, humanID, humanID, droidID, thingOneId, thingTwoId, thingOneId) - var expected, result map[string]interface{} - err := json.Unmarshal([]byte(queryCharacterExpected), &expected) - require.NoError(t, err) - err = json.Unmarshal(gqlResponse.Data, &result) - require.NoError(t, err) - - require.Equal(t, expected, result) + JSONEqGraphQL(t, queryCharacterExpected, string(gqlResponse.Data)) cleanupStarwars(t, newStarship.ID, humanID, droidID) deleteThingOne(t, thingOneId) @@ -564,31 +550,23 @@ func fragmentInQueryOnObject(t *testing.T) { { "queryHuman":[ { - "__typename": "Human", - "id": "%s", - "name": "Han", - "appearsIn": ["EMPIRE"], - "starships": [{ - "__typename": "Starship", - "id": "%s", - "name": "Millennium Falcon", - "length": 2 + "__typename":"Human", + "id":"%s", + "name":"Han", + "appearsIn":["EMPIRE"], + "starships":[{ + "__typename":"Starship", + "id":"%s", + "name":"Millennium Falcon", + "length":2.000000 }], - "totalCredits": 10, - "ename": "Han_employee" + "totalCredits":10.000000, + "ename":"Han_employee" } ] }`, humanID, newStarship.ID) - var expected, result struct { - QueryHuman []map[string]interface{} - } - err := json.Unmarshal([]byte(queryCharacterExpected), &expected) - require.NoError(t, err) - err = json.Unmarshal(gqlResponse.Data, &result) - require.NoError(t, err) - - require.Equal(t, expected, result) + JSONEqGraphQL(t, queryCharacterExpected, string(gqlResponse.Data)) cleanupStarwars(t, newStarship.ID, humanID, "") } diff --git a/graphql/e2e/common/lambda.go b/graphql/e2e/common/lambda.go index ee9f1d3210a..880f65eb384 100644 --- a/graphql/e2e/common/lambda.go +++ b/graphql/e2e/common/lambda.go @@ -26,6 +26,7 @@ import ( ) func lambdaOnTypeField(t *testing.T) { + t.Skipf("enable after porting JSON for @custom") query := ` query { queryAuthor { @@ -61,6 +62,7 @@ func lambdaOnTypeField(t *testing.T) { } func lambdaOnInterfaceField(t *testing.T) { + t.Skipf("enable after porting JSON for @custom") starship := addStarship(t) humanID := addHuman(t, starship.ID) droidID := addDroid(t) diff --git a/graphql/e2e/common/query.go b/graphql/e2e/common/query.go index 18f1bbf3ed4..8fd7b4a3d30 100644 --- a/graphql/e2e/common/query.go +++ b/graphql/e2e/common/query.go @@ -2842,6 +2842,7 @@ func queryAggregateOnEmptyData(t *testing.T) { aggregatePost (filter: {title : { anyofterms : "Nothing" }} ) { count numLikesMax + type: __typename titleMin } }`, @@ -2849,10 +2850,15 @@ func queryAggregateOnEmptyData(t *testing.T) { gqlResponse := queryPostParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) - testutil.CompareJSON(t, + require.JSONEq(t, `{ - "aggregatePost": null - }`, + "aggregatePost": { + "count": 0, + "numLikesMax": null, + "type": "PostAggregateResult", + "titleMin": null + } + }`, string(gqlResponse.Data)) } @@ -3021,6 +3027,7 @@ func queryAggregateAtChildLevel(t *testing.T) { name ag : statesAggregate { count + __typename nameMin } } @@ -3035,6 +3042,7 @@ func queryAggregateAtChildLevel(t *testing.T) { "name": "India", "ag": { "count" : 3, + "__typename": "StateAggregateResult", "nameMin": "Gujarat" } }] @@ -3079,8 +3087,10 @@ func queryAggregateAtChildLevelWithEmptyData(t *testing.T) { name ag : statesAggregate(filter: {xcode: {in: ["nothing"]}}) { count + __typename nameMin } + n: name } }`, } @@ -3091,7 +3101,12 @@ func queryAggregateAtChildLevelWithEmptyData(t *testing.T) { { "queryCountry": [{ "name": "India", - "ag": null + "ag": { + "count": 0, + "__typename": "StateAggregateResult", + "nameMin": null + }, + "n": "India" }] }`, string(gqlResponse.Data)) diff --git a/graphql/resolve/auth_add_test.yaml b/graphql/resolve/auth_add_test.yaml index c952b33b8c9..0d52d49cb44 100644 --- a/graphql/resolve/auth_add_test.yaml +++ b/graphql/resolve/auth_add_test.yaml @@ -159,9 +159,9 @@ } Column1 as var(func: uid(0x456)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -170,10 +170,10 @@ } Ticket3 as var(func: uid(0x789)) TicketAuth4 as var(func: uid(Ticket3)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -221,9 +221,9 @@ } Column1 as var(func: uid(0x456)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -232,10 +232,10 @@ } Ticket3 as var(func: uid(0x789)) TicketAuth4 as var(func: uid(Ticket3)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -292,9 +292,9 @@ } Column1 as var(func: uid(0x456, 0x459)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -303,10 +303,10 @@ } Ticket3 as var(func: uid(0x789, 0x799)) TicketAuth4 as var(func: uid(Ticket3)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -364,9 +364,9 @@ } Column1 as var(func: uid(0x456, 0x459)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -375,10 +375,10 @@ } Ticket3 as var(func: uid(0x789, 0x799)) TicketAuth4 as var(func: uid(Ticket3)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -433,9 +433,9 @@ uid } ColumnAuth5 as var(func: uid(Column4)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -456,9 +456,9 @@ } Column1 as var(func: uid(0x456)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -504,9 +504,9 @@ uid } ColumnAuth5 as var(func: uid(Column4)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -526,9 +526,9 @@ } Column1 as var(func: uid(0x456)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -577,9 +577,9 @@ uid } ColumnAuth5 as var(func: uid(Column4)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -602,9 +602,9 @@ } Column1 as var(func: uid(0x456)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -613,8 +613,8 @@ } Project3 as var(func: uid(0x123)) ProjectAuth4 as var(func: uid(Project3)) @cascade { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -661,9 +661,9 @@ uid } ColumnAuth5 as var(func: uid(Column4)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -685,9 +685,9 @@ } Column1 as var(func: uid(0x456)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -696,8 +696,8 @@ } Project3 as var(func: uid(0x123)) ProjectAuth4 as var(func: uid(Project3)) @cascade { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -813,8 +813,8 @@ } Project1 as var(func: uid(0x123)) ProjectAuth2 as var(func: uid(Project1)) @cascade { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -868,7 +868,7 @@ } Issue1 as var(func: uid(0x789)) IssueAuth2 as var(func: uid(Issue1)) @cascade { - owner : Issue.owner @filter(eq(User.username, "user1")) + Issue.owner : Issue.owner @filter(eq(User.username, "user1")) } } authjson: | @@ -919,7 +919,7 @@ } Issue1 as var(func: uid(0x789)) Issue2 as var(func: uid(Issue1)) @cascade { - owner : Issue.owner @filter(eq(User.username, "user1")) + Issue.owner : Issue.owner @filter(eq(User.username, "user1")) } } error: @@ -1006,12 +1006,12 @@ } Question1 as var(func: uid(0x123)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid + Question.id : uid } QuestionAuth3 as var(func: uid(Question1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } } @@ -1053,12 +1053,12 @@ } Question1 as var(func: uid(0x123)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid + Question.id : uid } QuestionAuth3 as var(func: uid(Question1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } } @@ -1102,8 +1102,8 @@ FbPost1 as var(func: uid(0x123)) FbPostAuth2 as var(func: uid(FbPost1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } } diff --git a/graphql/resolve/auth_closed_by_default_query_test.yaml b/graphql/resolve/auth_closed_by_default_query_test.yaml index 56f3958e3b4..c0a6fc02b97 100644 --- a/graphql/resolve/auth_closed_by_default_query_test.yaml +++ b/graphql/resolve/auth_closed_by_default_query_test.yaml @@ -7,14 +7,6 @@ text } } - dgquery: |- - query { - queryRTodo(func: type(Todo)) { - owner : Todo.comment - text : Todo.text - dgraph.uid : uid - } - } error: { "message": "a valid JWT is required but was not provided"} @@ -27,13 +19,5 @@ text } } - dgquery: |- - query { - queryRTodo(func: type(Todo)) { - owner : Todo.comment - text : Todo.text - dgraph.uid : uid - } - } error: { "message": "a valid JWT is required but was not provided" } diff --git a/graphql/resolve/auth_delete_test.yaml b/graphql/resolve/auth_delete_test.yaml index 9c3b9ce6bac..8c820eced1e 100644 --- a/graphql/resolve/auth_delete_test.yaml +++ b/graphql/resolve/auth_delete_test.yaml @@ -62,8 +62,8 @@ x as var(func: uid(TweetsRoot)) TweetsRoot as var(func: uid(Tweets1)) Tweets1 as var(func: type(Tweets)) @filter(anyoftext(Tweets.text, "abc")) - tweets(func: uid(Tweets3)) { - text : Tweets.text + DeleteTweetsPayload.tweets(func: uid(Tweets3)) { + Tweets.text : Tweets.text dgraph.uid : uid } Tweets3 as var(func: uid(Tweets4)) @@ -96,8 +96,8 @@ dgquerysec: |- query { x as var() - tweets(func: uid(Tweets1)) { - text : Tweets.text + DeleteTweetsPayload.tweets(func: uid(Tweets1)) { + Tweets.text : Tweets.text dgraph.uid : uid } Tweets1 as var(func: uid(Tweets2)) @@ -138,10 +138,10 @@ TicketRoot as var(func: uid(Ticket1)) @filter(uid(TicketAuth2)) Ticket1 as var(func: type(Ticket)) @filter(anyofterms(Ticket.title, "auth is applied")) TicketAuth2 as var(func: uid(Ticket1)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -197,10 +197,10 @@ TicketRoot as var(func: uid(Ticket1)) @filter(uid(TicketAuth2)) Ticket1 as var(func: type(Ticket)) @filter(anyofterms(Ticket.title, "auth is applied")) TicketAuth2 as var(func: uid(Ticket1)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -212,22 +212,22 @@ TicketRoot as var(func: uid(Ticket1)) @filter(uid(TicketAuth2)) Ticket1 as var(func: type(Ticket)) @filter(anyofterms(Ticket.title, "auth is applied")) TicketAuth2 as var(func: uid(Ticket1)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } } - ticket(func: uid(Ticket5)) { - title : Ticket.title - onColumn : Ticket.onColumn @filter(uid(Column6)) { - inProject : Column.inProject @filter(uid(Project8)) { - roles : Project.roles @filter(uid(Role10)) { - assignedTo : Role.assignedTo @filter(uid(User12)) { - username : User.username - age : User.age + DeleteTicketPayload.ticket(func: uid(Ticket5)) { + Ticket.title : Ticket.title + Ticket.onColumn : Ticket.onColumn @filter(uid(Column6)) { + Column.inProject : Column.inProject @filter(uid(Project8)) { + Project.roles : Project.roles @filter(uid(Role10)) { + Role.assignedTo : Role.assignedTo @filter(uid(User12)) { + User.username : User.username + User.age : User.age dgraph.uid : uid } dgraph.uid : uid @@ -241,10 +241,10 @@ Ticket5 as var(func: uid(Ticket16)) @filter(uid(TicketAuth17)) Ticket16 as var(func: uid(x)) TicketAuth17 as var(func: uid(Ticket16)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -266,14 +266,14 @@ } User12 as var(func: uid(User13)) ProjectAuth14 as var(func: uid(Project9)) @cascade { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } ColumnAuth15 as var(func: uid(Column7)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -345,7 +345,7 @@ dgquerysec: |- query { x as var() - log() + DeleteLogPayload.log() } - name: "multiple rule in delete mutation" @@ -483,9 +483,9 @@ x as var(func: uid(LogRoot)) LogRoot as var(func: uid(Log1)) Log1 as var(func: uid(0x1, 0x2)) @filter(type(Log)) - log(func: uid(Log2), orderasc: Log.logs) { - logs : Log.logs - random : Log.random + DeleteLogPayload.log(func: uid(Log2), orderasc: Log.logs) { + Log.logs : Log.logs + Log.random : Log.random dgraph.uid : uid } Log2 as var(func: uid(Log3), orderasc: Log.logs) @@ -571,7 +571,7 @@ IssueRoot as var(func: uid(Issue1)) @filter(uid(IssueAuth2)) Issue1 as var(func: uid(0x1, 0x2)) @filter(type(Issue)) IssueAuth2 as var(func: uid(Issue1)) @cascade { - owner : Issue.owner @filter(eq(User.username, "user1")) + Issue.owner : Issue.owner @filter(eq(User.username, "user1")) } } @@ -683,19 +683,19 @@ Post1 as var(func: uid(0x1, 0x2)) @filter(type(Post)) Question1 as var(func: type(Question)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid + Question.id : uid } QuestionAuth3 as var(func: uid(Question1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } Answer1 as var(func: type(Answer)) AnswerAuth4 as var(func: uid(Answer1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } } @@ -783,12 +783,12 @@ QuestionRoot as var(func: uid(Question1)) @filter((uid(QuestionAuth2) AND uid(QuestionAuth3))) Question1 as var(func: uid(0x1, 0x2)) @filter(type(Question)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid + Question.id : uid } QuestionAuth3 as var(func: uid(Question1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } } @@ -874,8 +874,8 @@ FbPost1 as var(func: uid(0x1, 0x2)) @filter(type(FbPost)) FbPostAuth2 as var(func: uid(FbPost1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } } \ No newline at end of file diff --git a/graphql/resolve/auth_query_test.yaml b/graphql/resolve/auth_query_test.yaml index 07173d8df3e..1839b86dc43 100644 --- a/graphql/resolve/auth_query_test.yaml +++ b/graphql/resolve/auth_query_test.yaml @@ -21,14 +21,14 @@ dgquery: |- query { queryContact(func: uid(ContactRoot)) { - id : uid - nickName : Contact.nickName - adminTasks : Contact.adminTasks @filter(uid(AdminTask1)) { - id : uid - name : AdminTask.name - occurrences : AdminTask.occurrences @filter(uid(TaskOccurrence3)) { - due : TaskOccurrence.due - comp : TaskOccurrence.comp + Contact.id : uid + Contact.nickName : Contact.nickName + Contact.adminTasks : Contact.adminTasks @filter(uid(AdminTask1)) { + AdminTask.id : uid + AdminTask.name : AdminTask.name + AdminTask.occurrences : AdminTask.occurrences @filter(uid(TaskOccurrence3)) { + TaskOccurrence.due : TaskOccurrence.due + TaskOccurrence.comp : TaskOccurrence.comp dgraph.uid : uid } } @@ -94,8 +94,8 @@ dgquery: |- query { queryContact(func: uid(ContactRoot)) { - id : uid - nickName : Contact.nickName + Contact.id : uid + Contact.nickName : Contact.nickName } ContactRoot as var(func: uid(Contact6)) Contact6 as var(func: type(Contact)) @@ -124,14 +124,14 @@ dgquery: |- query { queryContact(func: uid(ContactRoot)) @cascade { - id : uid - nickName : Contact.nickName - adminTasks : Contact.adminTasks @filter(uid(AdminTask1)) { - id : uid - name : AdminTask.name - occurrences : AdminTask.occurrences @filter(uid(TaskOccurrence3)) { - due : TaskOccurrence.due - comp : TaskOccurrence.comp + Contact.id : uid + Contact.nickName : Contact.nickName + Contact.adminTasks : Contact.adminTasks @filter(uid(AdminTask1)) { + AdminTask.id : uid + AdminTask.name : AdminTask.name + AdminTask.occurrences : AdminTask.occurrences @filter(uid(TaskOccurrence3)) { + TaskOccurrence.due : TaskOccurrence.due + TaskOccurrence.comp : TaskOccurrence.comp dgraph.uid : uid } } @@ -173,11 +173,11 @@ dgquery: |- query { queryContact(func: uid(ContactRoot)) { - id : uid - nickName : Contact.nickName - adminTasks : Contact.adminTasks @filter(uid(AdminTask1)) { - id : uid - name : AdminTask.name + Contact.id : uid + Contact.nickName : Contact.nickName + Contact.adminTasks : Contact.adminTasks @filter(uid(AdminTask1)) { + AdminTask.id : uid + AdminTask.name : AdminTask.name } } ContactRoot as var(func: uid(Contact5)) @@ -211,14 +211,14 @@ dgquery: |- query { queryContact(func: uid(ContactRoot)) { - id : uid - nickName : Contact.nickName - tasks : Contact.tasks @filter(uid(Task1)) { - id : uid - name : Task.name - occurrences : Task.occurrences @filter(uid(TaskOccurrence3)) { - due : TaskOccurrence.due - comp : TaskOccurrence.comp + Contact.id : uid + Contact.nickName : Contact.nickName + Contact.tasks : Contact.tasks @filter(uid(Task1)) { + Task.id : uid + Task.name : Task.name + Task.occurrences : Task.occurrences @filter(uid(TaskOccurrence3)) { + TaskOccurrence.due : TaskOccurrence.due + TaskOccurrence.comp : TaskOccurrence.comp dgraph.uid : uid } } @@ -249,7 +249,7 @@ dgquery: |- query { queryStudent(func: uid(StudentRoot)) { - email : IOw80vnV + Student.email : IOw80vnV dgraph.uid : uid } StudentRoot as var(func: uid(Student1)) @filter(uid(StudentAuth2)) @@ -288,17 +288,17 @@ dgquery: |- query { getProject(func: uid(ProjectRoot)) @filter(type(Project)) { - projID : uid - columns : Project.columns @filter(uid(Column1)) { - name : Column.name - colID : uid + Project.projID : uid + Project.columns : Project.columns @filter(uid(Column1)) { + Column.name : Column.name + Column.colID : uid } } ProjectRoot as var(func: uid(Project4)) @filter(uid(ProjectAuth5)) Project4 as var(func: uid(0x123)) ProjectAuth5 as var(func: uid(Project4)) @cascade { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } var(func: uid(ProjectRoot)) { @@ -306,9 +306,9 @@ } Column1 as var(func: uid(Column2)) @filter(uid(ColumnAuth3)) ColumnAuth3 as var(func: uid(Column2)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -327,8 +327,8 @@ dgquery: |- query { queryUserSecret(func: uid(UserSecretRoot)) { - id : uid - ownedBy : UserSecret.ownedBy + UserSecret.id : uid + UserSecret.ownedBy : UserSecret.ownedBy } UserSecretRoot as var(func: uid(UserSecret1)) @filter(uid(UserSecretAuth2)) UserSecret1 as var(func: type(UserSecret)) @@ -349,9 +349,9 @@ dgquery: |- query { aggregateUserSecret() { - count : max(val(countVar)) - aSecretMax : max(val(aSecretVar)) - aSecretMin : min(val(aSecretVar)) + UserSecretAggregateResult.count : max(val(countVar)) + UserSecretAggregateResult.aSecretMax : max(val(aSecretVar)) + UserSecretAggregateResult.aSecretMin : min(val(aSecretVar)) } var(func: uid(UserSecretRoot)) { countVar as count(uid) @@ -375,8 +375,8 @@ dgquery: |- query { getUserSecret(func: uid(UserSecretRoot)) @filter(type(UserSecret)) { - id : uid - ownedBy : UserSecret.ownedBy + UserSecret.id : uid + UserSecret.ownedBy : UserSecret.ownedBy } UserSecretRoot as var(func: uid(UserSecret1)) @filter(uid(UserSecretAuth2)) UserSecret1 as var(func: uid(0x123)) @@ -396,8 +396,8 @@ dgquery: |- query { queryUserSecret(func: uid(UserSecretRoot)) { - id : uid - ownedBy : UserSecret.ownedBy + UserSecret.id : uid + UserSecret.ownedBy : UserSecret.ownedBy } UserSecretRoot as var(func: uid(UserSecret1)) @filter(uid(UserSecretAuth2)) UserSecret1 as var(func: type(UserSecret)) @filter(eq(UserSecret.ownedBy, "user2")) @@ -419,8 +419,8 @@ dgquery: |- query { queryUser(func: uid(UserRoot)) { - issues : User.issues @filter(uid(Issue1)) { - id : uid + User.issues : User.issues @filter(uid(Issue1)) { + Issue.id : uid } dgraph.uid : uid } @@ -431,7 +431,7 @@ } Issue1 as var(func: uid(Issue2)) @filter(uid(IssueAuth3)) IssueAuth3 as var(func: uid(Issue2)) @cascade { - owner : Issue.owner @filter(eq(User.username, "user1")) + Issue.owner : Issue.owner @filter(eq(User.username, "user1")) } } @@ -451,7 +451,7 @@ dgquery: |- query { queryUser(func: uid(UserRoot)) { - username : User.username + User.username : User.username dgraph.uid : uid } UserRoot as var(func: uid(User3)) @@ -471,13 +471,13 @@ dgquery: |- query { queryIssue(func: uid(IssueRoot)) { - msg : Issue.msg + Issue.msg : Issue.msg dgraph.uid : uid } IssueRoot as var(func: uid(Issue1)) @filter(uid(IssueAuth2)) Issue1 as var(func: type(Issue)) IssueAuth2 as var(func: uid(Issue1)) @cascade { - owner : Issue.owner @filter(eq(User.username, "user1")) + Issue.owner : Issue.owner @filter(eq(User.username, "user1")) } } @@ -494,7 +494,7 @@ dgquery: |- query { queryComplexLog(func: uid(ComplexLogRoot)) { - logs : ComplexLog.logs + ComplexLog.logs : ComplexLog.logs dgraph.uid : uid } ComplexLogRoot as var(func: uid(ComplexLog1)) @@ -529,7 +529,7 @@ dgquery: |- query { queryLog(func: uid(LogRoot)) { - logs : Log.logs + Log.logs : Log.logs dgraph.uid : uid } LogRoot as var(func: uid(Log1)) @@ -595,7 +595,7 @@ dgquery: |- query { queryProject(func: uid(ProjectRoot)) { - name : Project.name + Project.name : Project.name dgraph.uid : uid } ProjectRoot as var(func: uid(Project1)) @@ -617,9 +617,9 @@ dgquery: |- query { aggregateProject() { - nameMin : min(val(nameVar)) - count : max(val(countVar)) - randomMin : min(val(randomVar)) + ProjectAggregateResult.nameMin : min(val(nameVar)) + ProjectAggregateResult.count : max(val(countVar)) + ProjectAggregateResult.randomMin : min(val(randomVar)) } var(func: uid(ProjectRoot)) { nameVar as Project.name @@ -642,15 +642,15 @@ dgquery: |- query { queryGroup(func: uid(GroupRoot)) { - id : uid + Group.id : uid } GroupRoot as var(func: uid(Group1)) @filter((uid(GroupAuth2) OR uid(GroupAuth3))) Group1 as var(func: type(Group)) GroupAuth2 as var(func: uid(Group1)) @cascade { - users : Group.users @filter(eq(User.username, "user1")) + Group.users : Group.users @filter(eq(User.username, "user1")) } GroupAuth3 as var(func: uid(Group1)) @cascade { - createdBy : Group.createdBy @filter(eq(User.username, "user1")) + Group.createdBy : Group.createdBy @filter(eq(User.username, "user1")) } } @@ -667,14 +667,14 @@ dgquery: |- query { queryProject(func: uid(ProjectRoot)) { - name : Project.name + Project.name : Project.name dgraph.uid : uid } ProjectRoot as var(func: uid(Project1)) @filter(uid(ProjectAuth2)) Project1 as var(func: type(Project)) ProjectAuth2 as var(func: uid(Project1)) @cascade { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -692,8 +692,8 @@ dgquery: |- query { queryUserSecret(func: uid(UserSecretRoot), orderasc: UserSecret.aSecret) { - id : uid - ownedBy : UserSecret.ownedBy + UserSecret.id : uid + UserSecret.ownedBy : UserSecret.ownedBy } UserSecretRoot as var(func: uid(UserSecret1), orderasc: UserSecret.aSecret, first: 1) @filter(uid(UserSecretAuth2)) UserSecret1 as var(func: type(UserSecret)) @filter(eq(UserSecret.ownedBy, "user2")) @@ -713,16 +713,16 @@ dgquery: |- query { queryTicket(func: uid(TicketRoot)) { - id : uid - title : Ticket.title + Ticket.id : uid + Ticket.title : Ticket.title } TicketRoot as var(func: uid(Ticket1)) @filter(uid(TicketAuth2)) Ticket1 as var(func: type(Ticket)) TicketAuth2 as var(func: uid(Ticket1)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -745,10 +745,10 @@ dgquery: |- query { queryUser(func: uid(UserRoot)) { - username : User.username - tickets : User.tickets @filter(uid(Ticket1)) { - id : uid - title : Ticket.title + User.username : User.username + User.tickets : User.tickets @filter(uid(Ticket1)) { + Ticket.id : uid + Ticket.title : Ticket.title } dgraph.uid : uid } @@ -759,10 +759,10 @@ } Ticket1 as var(func: uid(Ticket2)) @filter(uid(TicketAuth3)) TicketAuth3 as var(func: uid(Ticket2)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -785,10 +785,10 @@ dgquery: |- query { queryUser(func: uid(UserRoot)) { - username : User.username - tickets : User.tickets @filter(uid(Ticket1)) { - id : uid - title : Ticket.title + User.username : User.username + User.tickets : User.tickets @filter(uid(Ticket1)) { + Ticket.id : uid + Ticket.title : Ticket.title } dgraph.uid : uid } @@ -799,10 +799,10 @@ } Ticket1 as var(func: uid(Ticket2)) @filter(uid(TicketAuth3)) TicketAuth3 as var(func: uid(Ticket2)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -821,19 +821,19 @@ dgquery: |- query { queryMovie(func: uid(MovieRoot), orderasc: Movie.content) { - content : Movie.content + Movie.content : Movie.content dgraph.uid : uid } MovieRoot as var(func: uid(Movie1), orderasc: Movie.content, first: 10, offset: 10) @filter((NOT (uid(MovieAuth2)) AND (uid(MovieAuth3) OR uid(MovieAuth4)))) Movie1 as var(func: type(Movie)) @filter(eq(Movie.content, "A. N. Author")) MovieAuth2 as var(func: uid(Movie1)) @filter(eq(Movie.hidden, true)) @cascade MovieAuth3 as var(func: uid(Movie1)) @cascade { - regionsAvailable : Movie.regionsAvailable { - users : Region.users @filter(eq(User.username, "user1")) + Movie.regionsAvailable : Movie.regionsAvailable { + Region.users : Region.users @filter(eq(User.username, "user1")) } } MovieAuth4 as var(func: uid(Movie1)) @cascade { - regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) + Movie.regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) } } @@ -853,10 +853,10 @@ dgquery: |- query { queryMovie(func: uid(MovieRoot), orderasc: Movie.content) @cascade { - content : Movie.content - regionsAvailable : Movie.regionsAvailable @filter(uid(Region1)) (orderasc: Region.name, first: 10, offset: 10) { - name : Region.name - global : Region.global + Movie.content : Movie.content + Movie.regionsAvailable : Movie.regionsAvailable @filter(uid(Region1)) (orderasc: Region.name, first: 10, offset: 10) { + Region.name : Region.name + Region.global : Region.global dgraph.uid : uid } dgraph.uid : uid @@ -865,12 +865,12 @@ Movie3 as var(func: type(Movie)) @filter(eq(Movie.content, "MovieXYZ")) MovieAuth4 as var(func: uid(Movie3)) @filter(eq(Movie.hidden, true)) @cascade MovieAuth5 as var(func: uid(Movie3)) @cascade { - regionsAvailable : Movie.regionsAvailable { - users : Region.users @filter(eq(User.username, "user1")) + Movie.regionsAvailable : Movie.regionsAvailable { + Region.users : Region.users @filter(eq(User.username, "user1")) } } MovieAuth6 as var(func: uid(Movie3)) @cascade { - regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) + Movie.regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) } var(func: uid(MovieRoot)) { Region2 as Movie.regionsAvailable @filter(eq(Region.name, "Region123")) @@ -903,17 +903,17 @@ dgquery: |- query { queryMovie(func: uid(MovieRoot), orderasc: Movie.content) { - content : Movie.content - regionsAvailable : Movie.regionsAvailable @filter(uid(Region1)) (orderasc: Region.name, first: 10, offset: 10) @cascade { - name : Region.name - global : Region.global - users : Region.users @filter(uid(User3)) (orderasc: User.username, first: 10, offset: 10) { - username : User.username - age : User.age - isPublic : User.isPublic - secrets : User.secrets @filter(uid(UserSecret5)) (orderasc: UserSecret.aSecret, first: 10, offset: 10) { - aSecret : UserSecret.aSecret - ownedBy : UserSecret.ownedBy + Movie.content : Movie.content + Movie.regionsAvailable : Movie.regionsAvailable @filter(uid(Region1)) (orderasc: Region.name, first: 10, offset: 10) @cascade { + Region.name : Region.name + Region.global : Region.global + Region.users : Region.users @filter(uid(User3)) (orderasc: User.username, first: 10, offset: 10) { + User.username : User.username + User.age : User.age + User.isPublic : User.isPublic + User.secrets : User.secrets @filter(uid(UserSecret5)) (orderasc: UserSecret.aSecret, first: 10, offset: 10) { + UserSecret.aSecret : UserSecret.aSecret + UserSecret.ownedBy : UserSecret.ownedBy dgraph.uid : uid } dgraph.uid : uid @@ -926,12 +926,12 @@ Movie8 as var(func: type(Movie)) @filter(eq(Movie.content, "MovieXYZ")) MovieAuth9 as var(func: uid(Movie8)) @filter(eq(Movie.hidden, true)) @cascade MovieAuth10 as var(func: uid(Movie8)) @cascade { - regionsAvailable : Movie.regionsAvailable { - users : Region.users @filter(eq(User.username, "user1")) + Movie.regionsAvailable : Movie.regionsAvailable { + Region.users : Region.users @filter(eq(User.username, "user1")) } } MovieAuth11 as var(func: uid(Movie8)) @cascade { - regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) + Movie.regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) } var(func: uid(MovieRoot)) { Region2 as Movie.regionsAvailable @filter(eq(Region.name, "Region123")) @@ -960,19 +960,19 @@ dgquery: |- query { queryMovie(func: uid(MovieRoot)) { - content : Movie.content + Movie.content : Movie.content dgraph.uid : uid } MovieRoot as var(func: uid(Movie1)) @filter((NOT (uid(MovieAuth2)) AND (uid(MovieAuth3) OR uid(MovieAuth4)))) Movie1 as var(func: type(Movie)) MovieAuth2 as var(func: uid(Movie1)) @filter(eq(Movie.hidden, true)) @cascade MovieAuth3 as var(func: uid(Movie1)) @cascade { - regionsAvailable : Movie.regionsAvailable { - users : Region.users @filter(eq(User.username, "user1")) + Movie.regionsAvailable : Movie.regionsAvailable { + Region.users : Region.users @filter(eq(User.username, "user1")) } } MovieAuth4 as var(func: uid(Movie1)) @cascade { - regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) + Movie.regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) } } @@ -989,8 +989,8 @@ dgquery: |- query { aggregateMovie() { - count : max(val(countVar)) - contentMin : min(val(contentVar)) + MovieAggregateResult.count : max(val(countVar)) + MovieAggregateResult.contentMin : min(val(contentVar)) } var(func: uid(MovieRoot)) { countVar as count(uid) @@ -1000,12 +1000,12 @@ Movie1 as var(func: type(Movie)) MovieAuth2 as var(func: uid(Movie1)) @filter(eq(Movie.hidden, true)) @cascade MovieAuth3 as var(func: uid(Movie1)) @cascade { - regionsAvailable : Movie.regionsAvailable { - users : Region.users @filter(eq(User.username, "user1")) + Movie.regionsAvailable : Movie.regionsAvailable { + Region.users : Region.users @filter(eq(User.username, "user1")) } } MovieAuth4 as var(func: uid(Movie1)) @cascade { - regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) + Movie.regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) } } @@ -1049,7 +1049,7 @@ dgquery: |- query { queryUser(func: uid(UserRoot)) { - username : User.username + User.username : User.username dgraph.uid : uid } UserRoot as var(func: uid(User3)) @@ -1068,7 +1068,7 @@ dgquery: |- query { queryProject(func: uid(ProjectRoot)) { - name : Project.name + Project.name : Project.name dgraph.uid : uid } ProjectRoot as var(func: uid(Project1)) @@ -1085,7 +1085,7 @@ dgquery: |- query { queryRole(func: type(Role)) { - permission : Role.permission + Role.permission : Role.permission dgraph.uid : uid } } @@ -1100,14 +1100,14 @@ dgquery: |- query { queryMovie(func: uid(MovieRoot)) { - content : Movie.content + Movie.content : Movie.content dgraph.uid : uid } MovieRoot as var(func: uid(Movie1)) @filter((NOT (uid(MovieAuth2)) AND uid(MovieAuth3))) Movie1 as var(func: type(Movie)) MovieAuth2 as var(func: uid(Movie1)) @filter(eq(Movie.hidden, true)) @cascade MovieAuth3 as var(func: uid(Movie1)) @cascade { - regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) + Movie.regionsAvailable : Movie.regionsAvailable @filter(eq(Region.global, true)) } } @@ -1121,7 +1121,7 @@ dgquery: |- query { queryReview(func: type(Review)) { - comment : Review.comment + Review.comment : Review.comment dgraph.uid : uid } } @@ -1142,13 +1142,13 @@ dgquery: |- query { queryUser(func: uid(UserRoot)) { - ticketsAggregate : User.tickets @filter(uid(TicketAggregateResult1)) { - ticketsAggregate_titleVar as Ticket.title + User.ticketsAggregate : User.tickets @filter(uid(TicketAggregateResult1)) { + User.ticketsAggregate_titleVar as Ticket.title dgraph.uid : uid } - count_ticketsAggregate : count(User.tickets) @filter(uid(TicketAggregateResult1)) - titleMin_ticketsAggregate : min(val(ticketsAggregate_titleVar)) - titleMax_ticketsAggregate : max(val(ticketsAggregate_titleVar)) + TicketAggregateResult.count_User.ticketsAggregate : count(User.tickets) @filter(uid(TicketAggregateResult1)) + TicketAggregateResult.titleMin_User.ticketsAggregate : min(val(User.ticketsAggregate_titleVar)) + TicketAggregateResult.titleMax_User.ticketsAggregate : max(val(User.ticketsAggregate_titleVar)) dgraph.uid : uid } UserRoot as var(func: uid(User4)) @@ -1158,10 +1158,10 @@ } TicketAggregateResult1 as var(func: uid(TicketAggregateResult2)) @filter(uid(TicketAuth3)) TicketAuth3 as var(func: uid(TicketAggregateResult2)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -1190,19 +1190,19 @@ dgquery: |- query { queryUser(func: uid(UserRoot)) { - ticketsAggregate : User.tickets @filter(uid(TicketAggregateResult1)) { - ticketsAggregate_titleVar as Ticket.title + User.ticketsAggregate : User.tickets @filter(uid(TicketAggregateResult1)) { + User.ticketsAggregate_titleVar as Ticket.title dgraph.uid : uid } - titleMin_ticketsAggregate : min(val(ticketsAggregate_titleVar)) - issuesAggregate : User.issues @filter(uid(IssueAggregateResult4)) { - issuesAggregate_msgVar as Issue.msg + TicketAggregateResult.titleMin_User.ticketsAggregate : min(val(User.ticketsAggregate_titleVar)) + User.issuesAggregate : User.issues @filter(uid(IssueAggregateResult4)) { + User.issuesAggregate_msgVar as Issue.msg dgraph.uid : uid } - count_issuesAggregate : count(User.issues) @filter(uid(IssueAggregateResult4)) - msgMax_issuesAggregate : max(val(issuesAggregate_msgVar)) - tickets : User.tickets @filter(uid(Ticket7)) { - title : Ticket.title + IssueAggregateResult.count_User.issuesAggregate : count(User.issues) @filter(uid(IssueAggregateResult4)) + IssueAggregateResult.msgMax_User.issuesAggregate : max(val(User.issuesAggregate_msgVar)) + User.tickets : User.tickets @filter(uid(Ticket7)) { + Ticket.title : Ticket.title dgraph.uid : uid } dgraph.uid : uid @@ -1214,10 +1214,10 @@ } TicketAggregateResult1 as var(func: uid(TicketAggregateResult2)) @filter(uid(TicketAuth3)) TicketAuth3 as var(func: uid(TicketAggregateResult2)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -1227,17 +1227,17 @@ } IssueAggregateResult4 as var(func: uid(IssueAggregateResult5)) @filter(uid(IssueAuth6)) IssueAuth6 as var(func: uid(IssueAggregateResult5)) @cascade { - owner : Issue.owner @filter(eq(User.username, "user1")) + Issue.owner : Issue.owner @filter(eq(User.username, "user1")) } var(func: uid(UserRoot)) { Ticket8 as User.tickets @filter(anyofterms(Ticket.title, "graphql2")) } Ticket7 as var(func: uid(Ticket8)) @filter(uid(TicketAuth9)) TicketAuth9 as var(func: uid(Ticket8)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -1260,12 +1260,12 @@ dgquery: |- query { queryUser(func: uid(UserRoot)) { - issuesAggregate : User.issues @filter(uid(IssueAggregateResult1)) { - issuesAggregate_msgVar as Issue.msg + User.issuesAggregate : User.issues @filter(uid(IssueAggregateResult1)) { + User.issuesAggregate_msgVar as Issue.msg dgraph.uid : uid } - count_issuesAggregate : count(User.issues) @filter(uid(IssueAggregateResult1)) - msgMin_issuesAggregate : min(val(issuesAggregate_msgVar)) + IssueAggregateResult.count_User.issuesAggregate : count(User.issues) @filter(uid(IssueAggregateResult1)) + IssueAggregateResult.msgMin_User.issuesAggregate : min(val(User.issuesAggregate_msgVar)) dgraph.uid : uid } UserRoot as var(func: uid(User4)) @@ -1275,7 +1275,7 @@ } IssueAggregateResult1 as var(func: uid(IssueAggregateResult2)) @filter(uid(IssueAuth3)) IssueAuth3 as var(func: uid(IssueAggregateResult2)) @cascade { - owner : Issue.owner @filter(eq(User.username, "user1")) + Issue.owner : Issue.owner @filter(eq(User.username, "user1")) } } @@ -1296,7 +1296,7 @@ dgquery: |- query { queryUser(func: uid(UserRoot)) { - username : User.username + User.username : User.username dgraph.uid : uid } UserRoot as var(func: uid(User1)) @@ -1317,18 +1317,18 @@ dgquery: |- query { queryQuestion(func: uid(QuestionRoot)) { - id : uid - text : Post.text + Question.id : uid + Question.text : Post.text } QuestionRoot as var(func: uid(Question1)) @filter((uid(QuestionAuth2) AND uid(QuestionAuth3))) Question1 as var(func: type(Question)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid + Question.id : uid } QuestionAuth3 as var(func: uid(Question1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } } @@ -1346,15 +1346,15 @@ dgquery: |- query { queryAnswer(func: uid(AnswerRoot)) { - id : uid - text : Post.text + Answer.id : uid + Answer.text : Post.text } AnswerRoot as var(func: uid(Answer1)) @filter(uid(AnswerAuth2)) Answer1 as var(func: type(Answer)) AnswerAuth2 as var(func: uid(Answer1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } } @@ -1373,15 +1373,15 @@ dgquery: |- query { queryFbPost(func: uid(FbPostRoot)) { - id : uid - postCount : FbPost.postCount + FbPost.id : uid + FbPost.postCount : FbPost.postCount } FbPostRoot as var(func: uid(FbPost1)) @filter(uid(FbPostAuth2)) FbPost1 as var(func: type(FbPost)) FbPostAuth2 as var(func: uid(FbPost1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } } @@ -1417,33 +1417,33 @@ query { queryPost(func: uid(PostRoot)) { dgraph.type - text : Post.text + Post.text : Post.text dgraph.uid : uid } PostRoot as var(func: uid(Post1)) @filter(((uid(QuestionAuth2) AND uid(QuestionAuth3)) OR uid(FbPostAuth4) OR uid(AnswerAuth5))) Post1 as var(func: type(Post)) Question1 as var(func: type(Question)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid + Question.id : uid } QuestionAuth3 as var(func: uid(Question1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } FbPost1 as var(func: type(FbPost)) FbPostAuth4 as var(func: uid(FbPost1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } Answer1 as var(func: type(Answer)) AnswerAuth5 as var(func: uid(Answer1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } } @@ -1463,33 +1463,33 @@ query { queryPost(func: uid(PostRoot), orderdesc: Post.text) { dgraph.type - text : Post.text + Post.text : Post.text dgraph.uid : uid } PostRoot as var(func: uid(Post1), orderdesc: Post.text, first: 10, offset: 5) @filter(((uid(QuestionAuth2) AND uid(QuestionAuth3)) OR uid(FbPostAuth4) OR uid(AnswerAuth5))) Post1 as var(func: type(Post)) @filter(eq(Post.text, "A Post")) Question1 as var(func: type(Question)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid + Question.id : uid } QuestionAuth3 as var(func: uid(Question1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } FbPost1 as var(func: type(FbPost)) FbPostAuth4 as var(func: uid(FbPost1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } Answer1 as var(func: type(Answer)) AnswerAuth5 as var(func: uid(Answer1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } } @@ -1523,26 +1523,26 @@ query { queryPost(func: uid(PostRoot)) { dgraph.type - text : Post.text + Post.text : Post.text dgraph.uid : uid } PostRoot as var(func: uid(Post1)) @filter(((uid(QuestionAuth2) AND uid(QuestionAuth3)) OR uid(AnswerAuth4))) Post1 as var(func: type(Post)) Question1 as var(func: type(Question)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid + Question.id : uid } QuestionAuth3 as var(func: uid(Question1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } Answer1 as var(func: type(Answer)) AnswerAuth4 as var(func: uid(Answer1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } } @@ -1561,26 +1561,26 @@ query { getPost(func: uid(PostRoot)) @filter(type(Post)) { dgraph.type - text : Post.text + Post.text : Post.text dgraph.uid : uid } PostRoot as var(func: uid(Post1)) @filter(((uid(QuestionAuth2) AND uid(QuestionAuth3)) OR uid(AnswerAuth4))) Post1 as var(func: uid(0x1)) Question1 as var(func: type(Question)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid + Question.id : uid } QuestionAuth3 as var(func: uid(Question1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } Answer1 as var(func: type(Answer)) AnswerAuth4 as var(func: uid(Answer1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "Random")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "Random")) { + Author.name : Author.name } } } @@ -1611,7 +1611,7 @@ query { queryA(func: uid(ARoot)) { dgraph.type - fieldA : A.fieldA + A.fieldA : A.fieldA dgraph.uid : uid } ARoot as var(func: uid(A1)) @filter((uid(B1) OR uid(CAuth2))) @@ -1619,7 +1619,7 @@ B1 as var(func: type(B)) C1 as var(func: type(C)) CAuth2 as var(func: uid(C1)) @filter(eq(C.fieldC, true)) @cascade { - id : uid + C.id : uid } } @@ -1635,7 +1635,7 @@ query { queryA(func: uid(ARoot)) { dgraph.type - fieldA : A.fieldA + A.fieldA : A.fieldA dgraph.uid : uid } ARoot as var(func: uid(A1)) @filter((uid(B1))) @@ -1654,7 +1654,7 @@ dgquery: |- query { checkUserPassword(func: eq(User.username, "user")) @filter((eq(val(pwd), 1) AND type(User))) { - username : User.username + User.username : User.username dgraph.uid : uid } checkPwd(func: eq(User.username, "user")) @filter(type(User)) { @@ -1677,9 +1677,9 @@ dgquery: |- query { checkLogPassword(func: uid(LogRoot)) @filter((eq(val(pwd), 1) AND type(Log))) { - id : uid - logs : Log.logs - random : Log.random + Log.id : uid + Log.logs : Log.logs + Log.random : Log.random } LogRoot as var(func: uid(Log1)) Log1 as var(func: uid(0x123)) @@ -1722,18 +1722,18 @@ dgquery: |- query { checkProjectPassword(func: uid(ProjectRoot)) @filter((eq(val(pwd), 1) AND type(Project))) { - name : Project.name - projID : uid - columns : Project.columns @filter(uid(Column1)) { - name : Column.name - colID : uid + Project.name : Project.name + Project.projID : uid + Project.columns : Project.columns @filter(uid(Column1)) { + Column.name : Column.name + Column.colID : uid } } ProjectRoot as var(func: uid(Project4)) @filter(uid(ProjectAuth5)) Project4 as var(func: uid(0x123)) ProjectAuth5 as var(func: uid(Project4)) @cascade { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } var(func: uid(ProjectRoot)) { @@ -1741,9 +1741,9 @@ } Column1 as var(func: uid(Column2)) @filter(uid(ColumnAuth3)) ColumnAuth3 as var(func: uid(Column2)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -1767,14 +1767,14 @@ dgquery: |- query { checkQuestionPassword(func: uid(QuestionRoot)) @filter((eq(val(pwd), 1) AND type(Question))) { - id : uid - text : Post.text + Question.id : uid + Question.text : Post.text } QuestionRoot as var(func: uid(Question1)) @filter(uid(QuestionAuth2)) Question1 as var(func: uid(0x123)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid - text : Post.text + Question.id : uid + Question.text : Post.text } checkPwd(func: uid(QuestionRoot)) @filter(type(Question)) { pwd as checkpwd(Question.pwd, "something") @@ -1813,20 +1813,20 @@ query { checkPostPassword(func: uid(PostRoot)) @filter((eq(val(pwd), 1) AND type(Post))) { dgraph.type - text : Post.text + Post.text : Post.text dgraph.uid : uid } PostRoot as var(func: uid(Post1)) @filter((uid(QuestionAuth2) OR uid(FbPostAuth3) OR uid(Answer1))) Post1 as var(func: uid(0x123)) Question1 as var(func: type(Question)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid - text : Post.text + Question.id : uid + Question.text : Post.text } FbPost1 as var(func: type(FbPost)) FbPostAuth3 as var(func: uid(FbPost1)) @cascade { - author : Post.author @filter(eq(Author.name, "ADMIN")) { - name : Author.name + FbPost.author : Post.author @filter(eq(Author.name, "ADMIN")) { + Author.name : Author.name } } Answer1 as var(func: type(Answer)) diff --git a/graphql/resolve/auth_test.go b/graphql/resolve/auth_test.go index 84ee4c6880c..dde8c93eccc 100644 --- a/graphql/resolve/auth_test.go +++ b/graphql/resolve/auth_test.go @@ -433,21 +433,21 @@ func mutationQueryRewriting(t *testing.T, sch string, authMeta *testutil.AuthMet rewriter: NewAddRewriter, assigned: map[string]string{"Ticket1": "0x4"}, dgQuery: `query { - ticket(func: uid(TicketRoot)) { - id : uid - title : Ticket.title - onColumn : Ticket.onColumn @filter(uid(Column1)) { - colID : uid - name : Column.name + AddTicketPayload.ticket(func: uid(TicketRoot)) { + Ticket.id : uid + Ticket.title : Ticket.title + Ticket.onColumn : Ticket.onColumn @filter(uid(Column1)) { + Column.colID : uid + Column.name : Column.name } } TicketRoot as var(func: uid(Ticket4)) @filter(uid(TicketAuth5)) Ticket4 as var(func: uid(0x4)) TicketAuth5 as var(func: uid(Ticket4)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -457,9 +457,9 @@ func mutationQueryRewriting(t *testing.T, sch string, authMeta *testutil.AuthMet } Column1 as var(func: uid(Column2)) @filter(uid(ColumnAuth3)) ColumnAuth3 as var(func: uid(Column2)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -482,21 +482,21 @@ func mutationQueryRewriting(t *testing.T, sch string, authMeta *testutil.AuthMet result: map[string]interface{}{ "updateTicket": []interface{}{map[string]interface{}{"uid": "0x4"}}}, dgQuery: `query { - ticket(func: uid(TicketRoot)) { - id : uid - title : Ticket.title - onColumn : Ticket.onColumn @filter(uid(Column1)) { - colID : uid - name : Column.name + UpdateTicketPayload.ticket(func: uid(TicketRoot)) { + Ticket.id : uid + Ticket.title : Ticket.title + Ticket.onColumn : Ticket.onColumn @filter(uid(Column1)) { + Column.colID : uid + Column.name : Column.name } } TicketRoot as var(func: uid(Ticket4)) @filter(uid(TicketAuth5)) Ticket4 as var(func: uid(0x4)) TicketAuth5 as var(func: uid(Ticket4)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -506,9 +506,9 @@ func mutationQueryRewriting(t *testing.T, sch string, authMeta *testutil.AuthMet } Column1 as var(func: uid(Column2)) @filter(uid(ColumnAuth3)) ColumnAuth3 as var(func: uid(Column2)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "VIEW")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "VIEW")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } diff --git a/graphql/resolve/auth_update_test.yaml b/graphql/resolve/auth_update_test.yaml index ef44dc320ae..7269e826557 100644 --- a/graphql/resolve/auth_update_test.yaml +++ b/graphql/resolve/auth_update_test.yaml @@ -56,9 +56,9 @@ ColumnRoot as var(func: uid(Column1)) @filter(uid(ColumnAuth2)) Column1 as var(func: uid(0x123)) @filter(type(Column)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -74,10 +74,10 @@ } Ticket1 as var(func: uid(0x789)) TicketAuth2 as var(func: uid(Ticket1)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -118,9 +118,9 @@ ColumnRoot as var(func: uid(Column1)) @filter(uid(ColumnAuth2)) Column1 as var(func: uid(0x123)) @filter(type(Column)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -136,10 +136,10 @@ } Ticket1 as var(func: uid(0x789)) TicketAuth2 as var(func: uid(Ticket1)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -183,9 +183,9 @@ ColumnRoot as var(func: uid(Column1)) @filter(uid(ColumnAuth2)) Column1 as var(func: uid(0x123)) @filter(type(Column)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -202,9 +202,9 @@ uid } ColumnAuth6 as var(func: uid(Column5)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -246,9 +246,9 @@ ColumnRoot as var(func: uid(Column1)) @filter(uid(ColumnAuth2)) Column1 as var(func: uid(0x123)) @filter(type(Column)) ColumnAuth2 as var(func: uid(Column1)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -265,9 +265,9 @@ uid } ColumnAuth6 as var(func: uid(Column5)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -310,10 +310,10 @@ TicketRoot as var(func: uid(Ticket1)) @filter(uid(TicketAuth2)) Ticket1 as var(func: uid(0x123)) @filter(type(Ticket)) TicketAuth2 as var(func: uid(Ticket1)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -331,9 +331,9 @@ uid } ColumnAuth6 as var(func: uid(Column5)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -374,10 +374,10 @@ TicketRoot as var(func: uid(Ticket1)) @filter(uid(TicketAuth2)) Ticket1 as var(func: uid(0x123)) @filter(type(Ticket)) TicketAuth2 as var(func: uid(Ticket1)) @cascade { - onColumn : Ticket.onColumn { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "EDIT")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Ticket.onColumn : Ticket.onColumn { + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "EDIT")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -395,9 +395,9 @@ uid } ColumnAuth6 as var(func: uid(Column5)) @cascade { - inProject : Column.inProject { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Column.inProject : Column.inProject { + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -497,8 +497,8 @@ ProjectRoot as var(func: uid(Project1)) @filter(uid(ProjectAuth2)) Project1 as var(func: uid(0x123)) @filter(type(Project)) ProjectAuth2 as var(func: uid(Project1)) @cascade { - roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { - assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) + Project.roles : Project.roles @filter(eq(Role.permission, "ADMIN")) { + Role.assignedTo : Role.assignedTo @filter(eq(User.username, "user1")) } } } @@ -562,7 +562,7 @@ IssueRoot as var(func: uid(Issue1)) @filter(uid(IssueAuth2)) Issue1 as var(func: uid(0x123)) @filter(type(Issue)) IssueAuth2 as var(func: uid(Issue1)) @cascade { - owner : Issue.owner @filter(eq(User.username, "user1")) + Issue.owner : Issue.owner @filter(eq(User.username, "user1")) } } @@ -678,12 +678,12 @@ QuestionRoot as var(func: uid(Question1)) @filter((uid(QuestionAuth2) AND uid(QuestionAuth3))) Question1 as var(func: uid(0x123)) @filter(type(Question)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid + Question.id : uid } QuestionAuth3 as var(func: uid(Question1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } } @@ -743,8 +743,8 @@ FbPost1 as var(func: uid(0x123)) @filter(type(FbPost)) FbPostAuth2 as var(func: uid(FbPost1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } } @@ -808,26 +808,26 @@ Post1 as var(func: uid(0x123, 0x456)) @filter(type(Post)) Question1 as var(func: type(Question)) QuestionAuth2 as var(func: uid(Question1)) @filter(eq(Question.answered, true)) @cascade { - id : uid + Question.id : uid } QuestionAuth3 as var(func: uid(Question1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } FbPost1 as var(func: type(FbPost)) FbPostAuth4 as var(func: uid(FbPost1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } Answer1 as var(func: type(Answer)) AnswerAuth5 as var(func: uid(Answer1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } } @@ -864,15 +864,15 @@ FbPost1 as var(func: type(FbPost)) FbPostAuth2 as var(func: uid(FbPost1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } Answer1 as var(func: type(Answer)) AnswerAuth3 as var(func: uid(Answer1)) @cascade { dgraph.type - author : Post.author @filter(eq(Author.name, "user1")) { - name : Author.name + Post.author : Post.author @filter(eq(Author.name, "user1")) { + Author.name : Author.name } } } diff --git a/graphql/resolve/delete_mutation_test.yaml b/graphql/resolve/delete_mutation_test.yaml index 1a81dc32d49..7893ff279c8 100644 --- a/graphql/resolve/delete_mutation_test.yaml +++ b/graphql/resolve/delete_mutation_test.yaml @@ -73,15 +73,15 @@ dgquerysec: |- query { x as var(func: uid(0x1, 0x2)) @filter(type(Author)) - author(func: uid(x), orderasc: Author.name, first: 10, offset: 10) @filter(eq(Author.name, "GraphQL")) { - id : uid - name : Author.name - country : Author.country { - name : Country.name - states : Country.states @filter(eq(State.code, "GraphQL")) (orderasc: State.name, first: 10, offset: 10) { - code : State.code - name : State.name - capital : State.capital + DeleteAuthorPayload.author(func: uid(x), orderasc: Author.name, first: 10, offset: 10) @filter(eq(Author.name, "GraphQL")) { + Author.id : uid + Author.name : Author.name + Author.country : Author.country { + Country.name : Country.name + Country.states : Country.states @filter(eq(State.code, "GraphQL")) (orderasc: State.name, first: 10, offset: 10) { + State.code : State.code + State.name : State.name + State.capital : State.capital dgraph.uid : uid } dgraph.uid : uid @@ -268,9 +268,9 @@ dgquerysec: |- query { x as var(func: type(A)) @filter(eq(A.name, "xyz")) - a(func: uid(x)) { + DeleteAPayload.a(func: uid(x)) { dgraph.type - name : A.name + A.name : A.name dgraph.uid : uid } } diff --git a/graphql/resolve/mutation_query_test.yaml b/graphql/resolve/mutation_query_test.yaml index 3db8af9df84..43a76a43e67 100644 --- a/graphql/resolve/mutation_query_test.yaml +++ b/graphql/resolve/mutation_query_test.yaml @@ -12,9 +12,9 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) { - postID : uid - title : Post.title + PAYLOAD_TYPE.post(func: uid(0x4)) { + Post.postID : uid + Post.title : Post.title } } @@ -34,11 +34,11 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) { - postID : uid - title : Post.title - author : Post.author { - name : Author.name + PAYLOAD_TYPE.result(func: uid(0x4)) { + Post.postID : uid + Post.titleAlias : Post.title + Post.theAuthor : Post.author { + Author.nameAlias : Author.name dgraph.uid : uid } } @@ -57,9 +57,9 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4), orderasc: Post.title, first: 0, offset: 10) @filter(anyofterms(Post.title, "GraphQL")) { - postID : uid - title : Post.title + PAYLOAD_TYPE.post(func: uid(0x4), orderasc: Post.title, first: 0, offset: 10) @filter(anyofterms(Post.title, "GraphQL")) { + Post.postID : uid + Post.title : Post.title } } @@ -79,11 +79,11 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) { - postID : uid - title : Post.title - author : Post.author { - name : Author.name + PAYLOAD_TYPE.post(func: uid(0x4)) { + Post.postID : uid + Post.title : Post.title + Post.author : Post.author { + Author.name : Author.name dgraph.uid : uid } } @@ -108,13 +108,13 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) { - postID : uid - title : Post.title - author : Post.author { - name : Author.name - posts : Author.posts @filter(anyofterms(Post.title, "GraphQL")) { - title : Post.title + PAYLOAD_TYPE.post(func: uid(0x4)) { + Post.postID : uid + Post.title : Post.title + Post.author : Post.author { + Author.name : Author.name + Author.posts : Author.posts @filter(anyofterms(Post.title, "GraphQL")) { + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -144,8 +144,8 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) { - title : Post.title + PAYLOAD_TYPE.post(func: uid(0x4)) { + Post.title : Post.title dgraph.uid : uid } } @@ -167,12 +167,12 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) @cascade { - title : Post.title - text : Post.text - author : Post.author { - name : Author.name - dob : Author.dob + PAYLOAD_TYPE.post(func: uid(0x4)) @cascade { + Post.title : Post.title + Post.text : Post.text + Post.author : Post.author { + Author.name : Author.name + Author.dob : Author.dob dgraph.uid : uid } dgraph.uid : uid @@ -196,12 +196,12 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) @cascade { - title : Post.title - text : Post.text - author : Post.author { - name : Author.name - dob : Author.dob + PAYLOAD_TYPE.post(func: uid(0x4)) @cascade { + Post.title : Post.title + Post.text : Post.text + Post.author : Post.author { + Author.name : Author.name + Author.dob : Author.dob dgraph.uid : uid } dgraph.uid : uid @@ -225,12 +225,12 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) { - title : Post.title - text : Post.text - author : Post.author @cascade { - name : Author.name - dob : Author.dob + PAYLOAD_TYPE.post(func: uid(0x4)) { + Post.title : Post.title + Post.text : Post.text + Post.author : Post.author @cascade { + Author.name : Author.name + Author.dob : Author.dob dgraph.uid : uid } dgraph.uid : uid @@ -254,12 +254,12 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) @cascade { - title : Post.title - text : Post.text - author : Post.author { - name : Author.name - dob : Author.dob + PAYLOAD_TYPE.post(func: uid(0x4)) @cascade { + Post.title : Post.title + Post.text : Post.text + Post.author : Post.author { + Author.name : Author.name + Author.dob : Author.dob dgraph.uid : uid } dgraph.uid : uid @@ -283,12 +283,12 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) @cascade(Post.title, Post.text) { - title : Post.title - text : Post.text - author : Post.author { - name : Author.name - dob : Author.dob + PAYLOAD_TYPE.post(func: uid(0x4)) @cascade(Post.title, Post.text) { + Post.title : Post.title + Post.text : Post.text + Post.author : Post.author { + Author.name : Author.name + Author.dob : Author.dob dgraph.uid : uid } dgraph.uid : uid @@ -312,12 +312,12 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) { - title : Post.title - text : Post.text - author : Post.author @cascade(Author.name, Author.dob, uid) { - name : Author.name - dob : Author.dob + PAYLOAD_TYPE.post(func: uid(0x4)) { + Post.title : Post.title + Post.text : Post.text + Post.author : Post.author @cascade(Author.name, Author.dob, uid) { + Author.name : Author.name + Author.dob : Author.dob dgraph.uid : uid } dgraph.uid : uid @@ -341,12 +341,12 @@ ADD_UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) @cascade { - title : Post.title - text : Post.text - author : Post.author @cascade(Author.name, Author.dob) { - name : Author.name - dob : Author.dob + PAYLOAD_TYPE.post(func: uid(0x4)) @cascade { + Post.title : Post.title + Post.text : Post.text + Post.author : Post.author @cascade(Author.name, Author.dob) { + Author.name : Author.name + Author.dob : Author.dob dgraph.uid : uid } dgraph.uid : uid @@ -366,9 +366,9 @@ UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4)) @filter(anyofterms(Post.title, "GraphQL")) { - postID : uid - title : Post.title + PAYLOAD_TYPE.post(func: uid(0x4)) @filter(anyofterms(Post.title, "GraphQL")) { + Post.postID : uid + Post.title : Post.title } } - @@ -384,9 +384,9 @@ UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4), orderasc: Post.title) { - postID : uid - title : Post.title + PAYLOAD_TYPE.post(func: uid(0x4), orderasc: Post.title) { + Post.postID : uid + Post.title : Post.title } } @@ -403,8 +403,8 @@ UPDATE_MUTATION: } dgquery: |- query { - post(func: uid(0x4), orderasc: Post.title, first: 0, offset: 10) { - postID : uid - title : Post.title + PAYLOAD_TYPE.post(func: uid(0x4), orderasc: Post.title, first: 0, offset: 10) { + Post.postID : uid + Post.title : Post.title } } diff --git a/graphql/resolve/mutation_rewriter.go b/graphql/resolve/mutation_rewriter.go index 39c0c7c5bc8..ff66e4248a1 100644 --- a/graphql/resolve/mutation_rewriter.go +++ b/graphql/resolve/mutation_rewriter.go @@ -802,13 +802,13 @@ func (drw *deleteRewriter) Rewrite( varGen: varGen, selector: queryAuthSelector, filterByUid: true, + parentVarName: varGen.Next(queryField.Type(), "", "", false), + varName: MutationQueryVar, + hasAuthRules: hasAuthRules(queryField, authRw), } - queryAuthRw.parentVarName = queryAuthRw.varGen.Next(queryField.Type(), "", "", - queryAuthRw.isWritingAuth) - queryAuthRw.varName = MutationQueryVar - queryAuthRw.hasAuthRules = hasAuthRules(queryField, authRw) - queryDel := rewriteAsQuery(queryField, queryAuthRw) + // these queries are responsible for querying the queryField + queryFieldQry := rewriteAsQuery(queryField, queryAuthRw) // we don't want the `x` query to show up in GraphQL JSON response while querying the query // field. So, need to make it `var` query and remove any children from it as there can be @@ -821,11 +821,19 @@ func (drw *deleteRewriter) Rewrite( Children: nil, // no need to copy children Filter: qry.Filter, } + // if there wasn't any root func because auth RBAC processing may have filtered out + // everything, then need to append () to attr so that a valid DQL is formed. if qryCopy.Func == nil { qryCopy.Attr = qryCopy.Attr + "()" } - queryDel = append(append([]*gql.GraphQuery{qryCopy}, dgQry[1:]...), queryDel...) - upserts = append(upserts, &UpsertMutation{Query: queryDel}) + // if the queryFieldQry didn't use the variable `x`, then need to make qryCopy not use that + // variable name, so that a valid DQL is formed. This happens when RBAC processing returns + // false. + if queryFieldQry[0].Attr == queryField.DgraphAlias()+"()" { + qryCopy.Var = "" + } + queryFieldQry = append(append([]*gql.GraphQuery{qryCopy}, dgQry[1:]...), queryFieldQry...) + upserts = append(upserts, &UpsertMutation{Query: queryFieldQry}) } return upserts, err diff --git a/graphql/resolve/mutation_test.go b/graphql/resolve/mutation_test.go index 25aa27c6ef7..d0ea8d7e0eb 100644 --- a/graphql/resolve/mutation_test.go +++ b/graphql/resolve/mutation_test.go @@ -227,20 +227,23 @@ func mutationRewriting(t *testing.T, file string, rewriterFactory func() Mutatio func TestMutationQueryRewriting(t *testing.T) { testTypes := map[string]struct { - mut string - rewriter func() MutationRewriter - assigned map[string]string - result map[string]interface{} + mut string + payloadType string + rewriter func() MutationRewriter + assigned map[string]string + result map[string]interface{} }{ "Add Post ": { - mut: `addPost(input: [{title: "A Post", author: {id: "0x1"}}])`, - rewriter: NewAddRewriter, - assigned: map[string]string{"Post1": "0x4"}, + mut: `addPost(input: [{title: "A Post", author: {id: "0x1"}}])`, + payloadType: "AddPostPayload", + rewriter: NewAddRewriter, + assigned: map[string]string{"Post1": "0x4"}, }, "Update Post ": { mut: `updatePost(input: {filter: {postID : ["0x4"]}, set: {text: "Updated text"} }) `, - rewriter: NewUpdateRewriter, + payloadType: "UpdatePostPayload", + rewriter: NewUpdateRewriter, result: map[string]interface{}{ "updatePost": []interface{}{map[string]interface{}{"uid": "0x4"}}}, }, @@ -268,6 +271,8 @@ func TestMutationQueryRewriting(t *testing.T) { rewriter := tt.rewriter() // -- Arrange -- gqlMutationStr := strings.Replace(tcase.GQLQuery, testType, tt.mut, 1) + tcase.DGQuery = strings.Replace(tcase.DGQuery, "PAYLOAD_TYPE", + tt.payloadType, 1) op, err := gqlSchema.Operation( &schema.Request{ Query: gqlMutationStr, diff --git a/graphql/resolve/query_rewriter.go b/graphql/resolve/query_rewriter.go index af0975cf563..17d9e7ecddd 100644 --- a/graphql/resolve/query_rewriter.go +++ b/graphql/resolve/query_rewriter.go @@ -188,31 +188,28 @@ func aggregateQuery(query schema.Query, authRw *authRewriter) []*gql.GraphQuery mainQuery.Attr = "var" finalMainQuery := &gql.GraphQuery{ - Attr: query.Name() + "()", + Attr: query.DgraphAlias() + "()", } // Add selection set to mainQuery and finalMainQuery. - isAggregateFieldVisited := make(map[string]bool) - // isAggregateFunctionVisited stores if the aggregate function for a field has been added or not. - // So the map entries would contain keys as nameMin, ageMin, nameName, etc. - isAggregateFunctionVisited := make(map[string]bool) + isAggregateVarAdded := make(map[string]bool) + isCountVarAdded := false for _, f := range query.SelectionSet() { // fldName stores Name of the field f. fldName := f.Name() - if _, visited := isAggregateFunctionVisited[fldName]; visited { - continue - } - isAggregateFunctionVisited[fldName] = true if fldName == "count" { - child := &gql.GraphQuery{ - Var: "countVar", - Attr: "count(uid)", + if !isCountVarAdded { + child := &gql.GraphQuery{ + Var: "countVar", + Attr: "count(uid)", + } + mainQuery.Children = append(mainQuery.Children, child) + isCountVarAdded = true } finalQueryChild := &gql.GraphQuery{ - Alias: fldName, + Alias: f.DgraphAlias(), Attr: "max(val(countVar))", } - mainQuery.Children = append(mainQuery.Children, child) finalMainQuery.Children = append(finalMainQuery.Children, finalQueryChild) continue } @@ -220,7 +217,6 @@ func aggregateQuery(query schema.Query, authRw *authRewriter) []*gql.GraphQuery // Handle other aggregate functions than count aggregateFunctions := []string{"Max", "Min", "Sum", "Avg"} - // TODO(GRAPHQL-887) :Fix Maximum and Minimum Aggregate DQL functions in case of no data for _, function := range aggregateFunctions { // A field can have at maximum one of the aggregation functions as suffix if strings.HasSuffix(fldName, function) { @@ -229,11 +225,11 @@ func aggregateQuery(query schema.Query, authRw *authRewriter) []*gql.GraphQuery // constructedForField contains the field for which aggregate function has been queried. // As all aggregate functions have length 3, removing last 3 characters from fldName. constructedForField := fldName[:len(fldName)-3] - // isAggregateFieldVisited ensures that a field is added to Var query at maximum once. + // isAggregateVarAdded ensures that a field is added to Var query at maximum once. // If a field has already been added to the var query, don't add it again. // Eg. Even if scoreMax and scoreMin are queried, the query will contain only one expression // of the from, "scoreVar as Tweets.score" - if !isAggregateFieldVisited[constructedForField] { + if !isAggregateVarAdded[constructedForField] { child := &gql.GraphQuery{ Var: constructedForField + "Var", Attr: constructedForDgraphPredicate, @@ -243,15 +239,15 @@ func aggregateQuery(query schema.Query, authRw *authRewriter) []*gql.GraphQuery // scoreVar as Tweets.score // } mainQuery.Children = append(mainQuery.Children, child) - isAggregateFieldVisited[constructedForField] = true + isAggregateVarAdded[constructedForField] = true } finalQueryChild := &gql.GraphQuery{ - Alias: fldName, + Alias: f.DgraphAlias(), Attr: strings.ToLower(function) + "(val(" + constructedForField + "Var))", } // This adds the following DQL query // aggregateTweets() { - // scoreMin : min(val(scoreVar)) + // TweetsAggregateResult.scoreMin : min(val(scoreVar)) // } finalMainQuery.Children = append(finalMainQuery.Children, finalQueryChild) break @@ -380,7 +376,7 @@ func rewriteAsQueryByIds( rbac := authRw.evaluateStaticRules(field.Type()) dgQuery := []*gql.GraphQuery{{ - Attr: field.Name(), + Attr: field.DgraphAlias(), }} if rbac == schema.Negative { @@ -447,7 +443,7 @@ func rewriteAsGet( // caught here but in case of interface, we need to check validity on each // implementing type as Rules for the interface are made empty. if rbac == schema.Negative { - return []*gql.GraphQuery{{Attr: query.Name() + "()"}} + return []*gql.GraphQuery{{Attr: query.DgraphAlias() + "()"}} } // For interface, empty query should be returned if Auth rules are @@ -487,7 +483,7 @@ func rewriteAsGet( if uid > 0 { dgQuery = []*gql.GraphQuery{{ - Attr: query.Name(), + Attr: query.DgraphAlias(), Func: &gql.Function{ Name: "uid", UID: []uint64{uid}, @@ -499,7 +495,7 @@ func rewriteAsGet( } else { dgQuery = []*gql.GraphQuery{{ - Attr: query.Name(), + Attr: query.DgraphAlias(), Func: eqXidFunc, }} } @@ -531,7 +527,7 @@ func addCommonRules( authRw *authRewriter) ([]*gql.GraphQuery, schema.RuleResult) { rbac := authRw.evaluateStaticRules(fieldType) dgQuery := &gql.GraphQuery{ - Attr: field.Name(), + Attr: field.DgraphAlias(), } if rbac == schema.Negative { @@ -1005,11 +1001,8 @@ func buildCommonAuthQueries( // buildAggregateFields builds DQL queries for aggregate fields like count, avg, max etc. // It returns related DQL fields and Auth Queries which are then added to the final DQL query // by the caller. -// fieldAlias is being passed along with the field as it depends on the number of times we have -// encountered that field till now. func buildAggregateFields( f schema.Field, - fieldAlias string, auth *authRewriter) ([]*gql.GraphQuery, []*gql.GraphQuery) { constructedForType := f.ConstructedFor() constructedForDgraphPredicate := f.ConstructedForDgraphPredicate() @@ -1026,12 +1019,12 @@ func buildAggregateFields( // titleMin // } // is - // postsAggregate : Author.posts { - // postsAggregate_titleVar as Post.title + // Author.postsAggregate : Author.posts { + // Author.postsAggregate_titleVar as Post.title // ... other queried aggregate fields // } mainField := &gql.GraphQuery{ - Alias: fieldAlias, + Alias: f.DgraphAlias(), Attr: constructedForDgraphPredicate, } @@ -1040,26 +1033,19 @@ func buildAggregateFields( fieldFilter, _ := f.ArgValue("filter").(map[string]interface{}) _ = addFilter(mainField, constructedForType, fieldFilter) - // addedAggregateFields is a map from aggregate field name to boolean - addedAggregateField := make(map[string]bool) - // isAggregateFieldVisited is a map from field name to boolean. It is used to + // isAggregateVarAdded is a map from field name to boolean. It is used to // ensure that a field is added to Var query at maximum once. // Eg. Even if scoreMax and scoreMin are queried, the corresponding field will // contain "scoreVar as Tweets.score" only once. - isAggregateFieldVisited := make(map[string]bool) + isAggregateVarAdded := make(map[string]bool) // Iterate over fields queried inside aggregate. for _, aggregateField := range f.SelectionSet() { - // Don't add the same field twice - if _, isAddedAggregateField := addedAggregateField[aggregateField.DgraphAlias()]; isAddedAggregateField { - continue - } - addedAggregateField[aggregateField.DgraphAlias()] = true // Handle count fields inside aggregate fields. - if aggregateField.DgraphAlias() == "count" { + if aggregateField.Name() == "count" { aggregateChild := &gql.GraphQuery{ - Alias: "count_" + fieldAlias, + Alias: aggregateField.DgraphAlias() + "_" + f.DgraphAlias(), Attr: "count(" + constructedForDgraphPredicate + ")", } // Add filter to count aggregation field. @@ -1080,26 +1066,26 @@ func buildAggregateFields( // constructedForDgraphPredicate stores the Dgraph predicate for which aggregate function // has been queried. Eg. Post.name for nameMin constructedForDgraphPredicateField := aggregateField.DgraphPredicateForAggregateField() - // Adding the corresponding var field if it has not been added before. isAggregateFieldVisited + // Adding the corresponding var field if it has not been added before. isAggregateVarAdded // ensures that a var queried is added at maximum once. - if !isAggregateFieldVisited[constructedForField] { + if !isAggregateVarAdded[constructedForField] { child := &gql.GraphQuery{ - Var: fieldAlias + "_" + constructedForField + "Var", + Var: f.DgraphAlias() + "_" + constructedForField + "Var", Attr: constructedForDgraphPredicateField, } // The var field is added to mainQuery. This adds the following DQL query. - // postsAggregate : Author.posts { - // postsAggregate_nameVar as Post.name + // Author.postsAggregate : Author.posts { + // Author.postsAggregate_nameVar as Post.name // } mainField.Children = append(mainField.Children, child) - isAggregateFieldVisited[constructedForField] = true + isAggregateVarAdded[constructedForField] = true } aggregateChild := &gql.GraphQuery{ - Alias: aggregateFldName + "_" + fieldAlias, - Attr: strings.ToLower(function) + "(val(" + fieldAlias + "_" + constructedForField + "Var))", + Alias: aggregateField.DgraphAlias() + "_" + f.DgraphAlias(), + Attr: strings.ToLower(function) + "(val(" + "" + f.DgraphAlias() + "_" + constructedForField + "Var))", } // This adds the following DQL query - // nameMin_postsAggregate : min(val(postsAggregate_nameVar)) + // PostAggregateResult.nameMin_Author.postsAggregate : min(val(Author.postsAggregate_nameVar)) otherAggregateChildren = append(otherAggregateChildren, aggregateChild) break } @@ -1211,13 +1197,12 @@ func addSelectionSetFrom( } // These fields might not have been requested by the user directly as part of the query but - // are required in the body template for other fields requested within the query. We must - // fetch them from Dgraph. + // are required in the body template for other @custom fields requested within the query. + // We must fetch them from Dgraph. requiredFields := make(map[string]schema.FieldDefinition) - // fieldSeenCount is a map from field's dgraph alias to integer. - // It stores the number of times a field was encountered - // in the query till now. - fieldSeenCount := make(map[string]int) + // fieldAdded is a map from field's dgraph alias to bool. + // It tells whether a field with that dgraph alias has been added to DQL query or not. + fieldAdded := make(map[string]bool) for _, f := range field.SelectionSet() { hasCustom, rf := f.HasCustomDirective() @@ -1238,18 +1223,17 @@ func addSelectionSetFrom( // Handle aggregation queries if f.IsAggregateField() { - fieldAlias := generateUniqueDgraphAlias(f, fieldSeenCount) - aggregateChildren, aggregateAuthQueries := buildAggregateFields(f, fieldAlias, auth) + aggregateChildren, aggregateAuthQueries := buildAggregateFields(f, auth) authQueries = append(authQueries, aggregateAuthQueries...) q.Children = append(q.Children, aggregateChildren...) // As all child fields inside aggregate have been looked at. We can continue - fieldSeenCount[f.DgraphAlias()]++ + fieldAdded[f.DgraphAlias()] = true continue } child := &gql.GraphQuery{ - Alias: generateUniqueDgraphAlias(f, fieldSeenCount), + Alias: f.DgraphAlias(), } if f.Type().Name() == schema.IDType { @@ -1291,11 +1275,7 @@ func addSelectionSetFrom( } } - if f.Type().IsInbuiltOrEnumType() && (fieldSeenCount[f.DgraphAlias()] > 0) { - restoreAuthState() - continue - } - fieldSeenCount[f.DgraphAlias()]++ + fieldAdded[f.DgraphAlias()] = true if rbac == schema.Positive || rbac == schema.Uncertain { q.Children = append(q.Children, child) @@ -1365,7 +1345,7 @@ func addSelectionSetFrom( // Add fields required by other custom fields which haven't already been added as a // child to be fetched from Dgraph. for _, dgAlias := range rfset { - if fieldSeenCount[dgAlias] == 0 { + if !fieldAdded[dgAlias] { f := requiredFields[dgAlias] child := &gql.GraphQuery{ Alias: f.DgraphAlias(), diff --git a/graphql/resolve/query_test.yaml b/graphql/resolve/query_test.yaml index 0cd3a3dae35..3aacf400d89 100644 --- a/graphql/resolve/query_test.yaml +++ b/graphql/resolve/query_test.yaml @@ -10,8 +10,8 @@ dgquery: |- query { queryState(func: type(State)) @filter(eq(State.code, "abc", "def", "ghi")) { - code : State.code - name : State.name + State.code : State.code + State.name : State.name dgraph.uid : uid } } @@ -28,8 +28,8 @@ dgquery: |- query { queryVerification(func: type(Verification)) @filter(eq(Verification.prevStatus, "ACTIVE", "DEACTIVATED")) { - name : Verification.name - prevStatus : Verification.prevStatus + Verification.name : Verification.name + Verification.prevStatus : Verification.prevStatus dgraph.uid : uid } } @@ -46,8 +46,8 @@ dgquery: |- query { queryVerification(func: type(Verification)) @filter(eq(Verification.status, "ACTIVE", "DEACTIVATED")) { - name : Verification.name - status : Verification.status + Verification.name : Verification.name + Verification.status : Verification.status dgraph.uid : uid } } @@ -63,8 +63,8 @@ dgquery: |- query { queryVerification(func: type(Verification)) @filter(eq(Verification.status, "ACTIVE")) { - name : Verification.name - status : Verification.status + Verification.name : Verification.name + Verification.status : Verification.status dgraph.uid : uid } } @@ -80,8 +80,8 @@ dgquery: |- query { queryVerification(func: type(Verification)) @filter(le(Verification.status, "INACTIVE")) { - name : Verification.name - status : Verification.status + Verification.name : Verification.name + Verification.status : Verification.status dgraph.uid : uid } } @@ -100,8 +100,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(near(Hotel.location, [22.22,11.11], 33.33)) { - name : Hotel.name - location : Hotel.location + Hotel.name : Hotel.name + Hotel.location : Hotel.location dgraph.uid : uid } } @@ -121,8 +121,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(within(Hotel.location, [[[22.22,11.11],[16.16,15.15],[21.21,20.2]],[[22.28,11.18],[16.18,15.18],[21.28,20.28]]])) { - name : Hotel.name - location : Hotel.location + Hotel.name : Hotel.name + Hotel.location : Hotel.location dgraph.uid : uid } } @@ -146,8 +146,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(near(Hotel.area, [22.22,11.11], 33.33)) { - name : Hotel.name - area : Hotel.area + Hotel.name : Hotel.name + Hotel.area : Hotel.area dgraph.uid : uid } } @@ -171,8 +171,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(within(Hotel.area, [[[22.22,11.11],[16.16,15.15],[21.21,20.2]],[[22.28,11.18],[16.18,15.18],[21.28,20.28]]])) { - name : Hotel.name - area : Hotel.area + Hotel.name : Hotel.name + Hotel.area : Hotel.area dgraph.uid : uid } } @@ -196,8 +196,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(contains(Hotel.area, [[[22.22,11.11],[16.16,15.15],[21.21,20.2]],[[22.28,11.18],[16.18,15.18],[21.28,20.28]]])) { - name : Hotel.name - area : Hotel.area + Hotel.name : Hotel.name + Hotel.area : Hotel.area dgraph.uid : uid } } @@ -221,8 +221,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(contains(Hotel.area, [22.22,11.11])) { - name : Hotel.name - area : Hotel.area + Hotel.name : Hotel.name + Hotel.area : Hotel.area dgraph.uid : uid } } @@ -276,8 +276,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(intersects(Hotel.area, [[[22.22,11.11],[16.16,15.15],[21.21,20.2]],[[22.28,11.18],[16.18,15.18],[21.28,20.28]]])) { - name : Hotel.name - area : Hotel.area + Hotel.name : Hotel.name + Hotel.area : Hotel.area dgraph.uid : uid } } @@ -357,8 +357,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(intersects(Hotel.area, [[[[22.22,11.11],[16.16,15.15],[21.21,20.2]],[[22.28,11.18],[16.18,15.18],[21.28,20.28]]],[[[92.22,91.11],[16.16,15.15],[21.21,20.2]],[[22.28,11.18],[16.18,15.18],[21.28,20.28]]]])) { - name : Hotel.name - area : Hotel.area + Hotel.name : Hotel.name + Hotel.area : Hotel.area dgraph.uid : uid } } @@ -384,8 +384,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(near(Hotel.branches, [22.22,11.11], 33.33)) { - name : Hotel.name - branches : Hotel.branches + Hotel.name : Hotel.name + Hotel.branches : Hotel.branches dgraph.uid : uid } } @@ -411,8 +411,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(within(Hotel.branches, [[[22.22,11.11],[16.16,15.15],[21.21,20.2]],[[22.28,11.18],[16.18,15.18],[21.28,20.28]]])) { - name : Hotel.name - branches : Hotel.branches + Hotel.name : Hotel.name + Hotel.branches : Hotel.branches dgraph.uid : uid } } @@ -438,8 +438,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(contains(Hotel.branches, [[[22.22,11.11],[16.16,15.15],[21.21,20.2]],[[22.28,11.18],[16.18,15.18],[21.28,20.28]]])) { - name : Hotel.name - branches : Hotel.branches + Hotel.name : Hotel.name + Hotel.branches : Hotel.branches dgraph.uid : uid } } @@ -465,8 +465,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(contains(Hotel.branches, [22.22,11.11])) { - name : Hotel.name - branches : Hotel.branches + Hotel.name : Hotel.name + Hotel.branches : Hotel.branches dgraph.uid : uid } } @@ -522,8 +522,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(intersects(Hotel.branches, [[[22.22,11.11],[16.16,15.15],[21.21,20.2]],[[22.28,11.18],[16.18,15.18],[21.28,20.28]]])) { - name : Hotel.name - branches : Hotel.branches + Hotel.name : Hotel.name + Hotel.branches : Hotel.branches dgraph.uid : uid } } @@ -605,8 +605,8 @@ dgquery: |- query { queryHotel(func: type(Hotel)) @filter(intersects(Hotel.branches, [[[[22.22,11.11],[16.16,15.15],[21.21,20.2]],[[22.28,11.18],[16.18,15.18],[21.28,20.28]]],[[[92.22,91.11],[16.16,15.15],[21.21,20.2]],[[22.28,11.18],[16.18,15.18],[21.28,20.28]]]])) { - name : Hotel.name - branches : Hotel.branches + Hotel.name : Hotel.name + Hotel.branches : Hotel.branches dgraph.uid : uid } } @@ -622,13 +622,13 @@ dgquery: |- query { getAuthor(func: uid(0x1)) @filter(type(Author)) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } - - name: "Alias is ignored in query rewriting - get" + name: "Alias isn't ignored in query rewriting - get" gqlquery: | query { author : getAuthor(id: "0x1") { @@ -641,9 +641,9 @@ dgquery: |- query { getAuthor(func: uid(0x1)) @filter(type(Author)) { - name : Author.name - posts : Author.posts { - title : Post.title + Author.anAlias : Author.name + Author.postAlias : Author.posts { + Post.titleAlias : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -651,7 +651,7 @@ } - - name: "Alias is ignored in query rewriting - query" + name: "Alias isn't ignored in query rewriting - query" gqlquery: | query { author : queryAuthor { @@ -664,9 +664,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name - posts : Author.posts { - title : Post.title + Author.anAlias : Author.name + Author.postAlias : Author.posts { + Post.titleAlias : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -685,8 +685,8 @@ dgquery: |- query { getAuthor(func: uid(0x1)) @filter(type(Author)) { - id : uid - name : Author.name + Author.id : uid + Author.name : Author.name } } @@ -705,10 +705,10 @@ dgquery: |- query { getAuthor(func: uid(0x1)) @filter(type(Author)) { - name : Author.name - posts : Author.posts { - title : Post.title - text : Post.text + Author.name : Author.name + Author.posts : Author.posts { + Post.title : Post.title + Post.text : Post.text dgraph.uid : uid } dgraph.uid : uid @@ -734,13 +734,13 @@ dgquery: |- query { getAuthor(func: uid(0x1)) @filter(type(Author)) { - name : Author.name - posts : Author.posts { - title : Post.title - text : Post.text - author : Post.author { - id : uid - name : Author.name + Author.name : Author.name + Author.posts : Author.posts { + Post.title : Post.title + Post.text : Post.text + Post.author : Post.author { + Author.id : uid + Author.name : Author.name } dgraph.uid : uid } @@ -759,7 +759,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -775,7 +775,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter(eq(Author.name, "A. N. Author")) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -791,7 +791,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter(eq(Author.name, "A. N. Author")) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -807,7 +807,7 @@ dgquery: |- query { queryTeacher(func: type(Teacher)) @filter(has(Teacher.subject)) { - name : People.name + Teacher.name : People.name dgraph.uid : uid } } @@ -823,7 +823,7 @@ dgquery: |- query { queryTeacher(func: type(Teacher)) @filter(NOT (has(Teacher.subject))) { - name : People.name + Teacher.name : People.name dgraph.uid : uid } } @@ -839,7 +839,7 @@ dgquery: |- query { queryTeacher(func: type(Teacher)) @filter((has(Teacher.teaches) AND has(Teacher.subject))) { - name : People.name + Teacher.name : People.name dgraph.uid : uid } } @@ -854,7 +854,7 @@ dgquery: |- query { queryNode(func: type(Node)) @filter(has(Node.name)) { - name : Node.name + Node.name : Node.name dgraph.uid : uid } } @@ -869,7 +869,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter((le(Author.dob, "2001-01-01") AND eq(Author.name, "A. N. Author") AND gt(Author.reputation, "2.5"))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -885,7 +885,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter(((gt(Author.reputation, "2.5") AND le(Author.dob, "2001-01-01")) AND eq(Author.name, "A. N. Author"))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -901,7 +901,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter(((has(Author.country) AND le(Author.dob, "2001-01-01")) AND eq(Author.name, "A. N. Author"))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -917,7 +917,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter((eq(Author.name, "A. N. Author") OR (le(Author.dob, "2001-01-01")))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -933,7 +933,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter((eq(Author.name, "A. N. Author") OR le(Author.dob, "2001-01-01"))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -949,7 +949,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter((eq(Author.name, "A. N. Author"))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -966,7 +966,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter(((eq(Author.name, "A. N. Author") AND gt(Author.reputation, "2.5")) OR (le(Author.dob, "2001-01-01")))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -982,7 +982,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter((eq(Author.name, "A. N. Author") OR ((le(Author.dob, "2001-01-01") AND gt(Author.reputation, "2.5"))))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -998,7 +998,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter((eq(Author.name, "A. N. Author") OR ((gt(Author.reputation, "2.5") OR (le(Author.dob, "2001-01-01")))))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1014,7 +1014,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter(NOT (gt(Author.reputation, "2.5"))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1030,7 +1030,7 @@ dgquery: |- query { queryAuthor(func: type(Author), first: 10) @filter(eq(Author.name, "A. N. Author")) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1046,7 +1046,7 @@ dgquery: |- query { queryAuthor(func: type(Author), first: 10, offset: 10) @filter(eq(Author.name, "A. N. Author")) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1062,7 +1062,7 @@ dgquery: |- query { queryAuthor(func: type(Author), orderasc: Author.reputation) @filter(eq(Author.name, "A. N. Author")) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1078,7 +1078,7 @@ dgquery: |- query { queryAuthor(func: type(Author), orderdesc: Author.reputation) @filter(eq(Author.name, "A. N. Author")) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1095,7 +1095,7 @@ dgquery: |- query { queryAuthor(func: type(Author), orderdesc: Author.reputation, orderasc: Author.dob) @filter(eq(Author.name, "A. N. Author")) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1111,7 +1111,7 @@ dgquery: |- query { queryAuthor(func: type(Author), orderdesc: Author.reputation, first: 10, offset: 10) @filter(eq(Author.name, "A. N. Author")) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1130,9 +1130,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name - posts : Author.posts @filter(anyofterms(Post.title, "GraphQL")) { - title : Post.title + Author.name : Author.name + Author.posts : Author.posts @filter(anyofterms(Post.title, "GraphQL")) { + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -1154,9 +1154,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name - posts : Author.posts @filter(has(Post.tags)) { - title : Post.title + Author.name : Author.name + Author.posts : Author.posts @filter(has(Post.tags)) { + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -1177,9 +1177,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name - posts : Author.posts @filter((has(Post.tags) AND anyofterms(Post.title, "GRAPHQL"))) { - title : Post.title + Author.name : Author.name + Author.posts : Author.posts @filter((has(Post.tags) AND anyofterms(Post.title, "GRAPHQL"))) { + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -1199,9 +1199,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name - posts : Author.posts @filter(anyofterms(Post.title, "GraphQL")) (first: 10) { - title : Post.title + Author.name : Author.name + Author.posts : Author.posts @filter(anyofterms(Post.title, "GraphQL")) (first: 10) { + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -1222,9 +1222,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name - posts : Author.posts @filter(anyofterms(Post.title, "GraphQL")) (orderasc: Post.numLikes, first: 10, offset: 10) { - title : Post.title + Author.name : Author.name + Author.posts : Author.posts @filter(anyofterms(Post.title, "GraphQL")) (orderasc: Post.numLikes, first: 10, offset: 10) { + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -1242,7 +1242,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter(gt(Author.reputation, "1.23456789113e+08")) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1258,7 +1258,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter((gt(Author.reputation, "1.1") OR ((ge(Author.reputation, "1.1") OR ((lt(Author.reputation, "1.1") OR ((le(Author.reputation, "1.1") OR (eq(Author.reputation, "1.1")))))))))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1274,7 +1274,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter((gt(Author.dob, "2000-01-01") OR ((ge(Author.dob, "2000-01-01") OR ((lt(Author.dob, "2000-01-01") OR ((le(Author.dob, "2000-01-01") OR (eq(Author.dob, "2000-01-01")))))))))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1290,7 +1290,7 @@ dgquery: |- query { queryPost(func: type(Post)) @filter((gt(Post.numLikes, 10) OR ((ge(Post.numLikes, 10) OR ((lt(Post.numLikes, 10) OR ((le(Post.numLikes, 10) OR (eq(Post.numLikes, 10)))))))))) { - title : Post.title + Post.title : Post.title dgraph.uid : uid } } @@ -1306,7 +1306,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter(eq(Author.name, "A. N. Author")) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1322,7 +1322,7 @@ dgquery: |- query { queryCountry(func: type(Country)) @filter((gt(Country.name, "AAA") OR ((ge(Country.name, "AAA") OR ((lt(Country.name, "AAA") OR ((le(Country.name, "AAA") OR (eq(Country.name, "AAA")))))))))) { - name : Country.name + Country.name : Country.name dgraph.uid : uid } } @@ -1338,7 +1338,7 @@ dgquery: |- query { queryCountry(func: type(Country)) @filter((gt(Country.name, "AAA") OR (ge(Country.name, "AAA") OR lt(Country.name, "AAA") OR le(Country.name, "AAA") OR eq(Country.name, "AAA")))) { - name : Country.name + Country.name : Country.name dgraph.uid : uid } } @@ -1354,7 +1354,7 @@ dgquery: |- query { queryCountry(func: type(Country)) @filter((ge(Country.name, "AAA") AND lt(Country.name, "AAA") AND le(Country.name, "AAA") AND eq(Country.name, "AAA") AND gt(Country.name, "AAA"))) { - name : Country.name + Country.name : Country.name dgraph.uid : uid } } @@ -1371,7 +1371,7 @@ dgquery: |- query { queryCountry(func: type(Country)) @filter(((gt(Country.name, "AAA") OR (lt(Country.name, "XXX"))) AND (gt(Country.name, "CCC") OR (lt(Country.name, "MMM"))))) { - name : Country.name + Country.name : Country.name dgraph.uid : uid } } @@ -1387,7 +1387,7 @@ dgquery: |- query { queryPost(func: type(Post)) @filter((anyofterms(Post.title, "GraphQL") OR (allofterms(Post.title, "GraphQL")))) { - title : Post.title + Post.title : Post.title dgraph.uid : uid } } @@ -1404,7 +1404,7 @@ dgquery: |- query { queryPost(func: type(Post)) @filter((anyoftext(Post.text, "GraphQL") OR (alloftext(Post.text, "GraphQL")))) { - title : Post.title + Post.title : Post.title dgraph.uid : uid } } @@ -1420,7 +1420,7 @@ dgquery: |- query { queryCountry(func: type(Country)) @filter(regexp(Country.name, /.*ust.*/)) { - name : Country.name + Country.name : Country.name dgraph.uid : uid } } @@ -1440,9 +1440,11 @@ dgquery: |- query { aggregateCountry() { - count : max(val(countVar)) - nameMin : min(val(nameVar)) - nameMax : max(val(nameVar)) + CountryAggregateResult.count : max(val(countVar)) + CountryAggregateResult.cnt : max(val(countVar)) + CountryAggregateResult.nameMin : min(val(nameVar)) + CountryAggregateResult.nm : min(val(nameVar)) + CountryAggregateResult.nameMax : max(val(nameVar)) } var(func: type(Country)) @filter(regexp(Country.name, /.*ust.*/)) { countVar as count(uid) @@ -1468,7 +1470,7 @@ dgquery: |- query { getAuthor(func: uid(0x1)) @filter(type(Author)) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1490,7 +1492,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1519,7 +1521,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -1538,9 +1540,9 @@ dgquery: |- query { getAuthor(func: uid(0x1)) @filter(type(Author)) @cascade { - dob : Author.dob - posts : Author.posts { - text : Post.text + Author.dob : Author.dob + Author.posts : Author.posts { + Post.text : Post.text dgraph.uid : uid } dgraph.uid : uid @@ -1561,9 +1563,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) @cascade { - dob : Author.dob - posts : Author.posts { - text : Post.text + Author.dob : Author.dob + Author.posts : Author.posts { + Post.text : Post.text dgraph.uid : uid } dgraph.uid : uid @@ -1584,9 +1586,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - dob : Author.dob - posts : Author.posts @cascade { - text : Post.text + Author.dob : Author.dob + Author.posts : Author.posts @cascade { + Post.text : Post.text dgraph.uid : uid } dgraph.uid : uid @@ -1607,9 +1609,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) @cascade { - dob : Author.dob - posts : Author.posts @cascade { - text : Post.text + Author.dob : Author.dob + Author.posts : Author.posts @cascade { + Post.text : Post.text dgraph.uid : uid } dgraph.uid : uid @@ -1631,10 +1633,10 @@ dgquery: |- query { queryAuthor(func: type(Author)) @cascade(Author.dob) { - dob : Author.dob - name : Author.name - posts : Author.posts { - text : Post.text + Author.dob : Author.dob + Author.name : Author.name + Author.posts : Author.posts { + Post.text : Post.text dgraph.uid : uid } dgraph.uid : uid @@ -1656,10 +1658,10 @@ dgquery: |- query { getAuthor(func: uid(0x1)) @filter(type(Author)) @cascade(Author.dob) { - dob : Author.dob - name : Author.name - posts : Author.posts { - text : Post.text + Author.dob : Author.dob + Author.name : Author.name + Author.posts : Author.posts { + Post.text : Post.text dgraph.uid : uid } dgraph.uid : uid @@ -1681,10 +1683,10 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - dob : Author.dob - posts : Author.posts @cascade(Post.text) { - text : Post.text - title : Post.title + Author.dob : Author.dob + Author.posts : Author.posts @cascade(Post.text) { + Post.text : Post.text + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -1707,11 +1709,11 @@ dgquery: |- query { queryAuthor(func: type(Author)) @cascade(Author.dob) { - dob : Author.dob - reputation : Author.reputation - posts : Author.posts @cascade(Post.text, Post.title, uid) { - text : Post.text - title : Post.title + Author.dob : Author.dob + Author.reputation : Author.reputation + Author.posts : Author.posts @cascade(Post.text, Post.title, uid) { + Post.text : Post.text + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -1734,11 +1736,11 @@ dgquery: |- query { queryAuthor(func: type(Author)) @cascade(Author.dob, Author.reputation, uid) { - dob : Author.dob - reputation : Author.reputation - posts : Author.posts @cascade(Post.text, Post.title) { - text : Post.text - title : Post.title + Author.dob : Author.dob + Author.reputation : Author.reputation + Author.posts : Author.posts @cascade(Post.text, Post.title) { + Post.text : Post.text + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -1761,11 +1763,11 @@ dgquery: |- query { queryAuthor(func: type(Author)) @cascade(Author.dob) { - dob : Author.dob - reputation : Author.reputation - posts : Author.posts { - text : Post.text - title : Post.title + Author.dob : Author.dob + Author.reputation : Author.reputation + Author.posts : Author.posts { + Post.text : Post.text + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -1787,11 +1789,11 @@ dgquery: |- query { queryHuman(func: type(Human)) @cascade(uid, Character.name, Employee.ename, Human.dob) { - id : uid - name : Character.name - ename : Employee.ename - dob : Human.dob - female : Human.female + Human.id : uid + Human.name : Character.name + Human.ename : Employee.ename + Human.dob : Human.dob + Human.female : Human.female } } @@ -1808,8 +1810,8 @@ query { queryCharacter(func: type(Character)) @cascade(uid, Character.name) { dgraph.type - id : uid - name : Character.name + Character.id : uid + Character.name : Character.name } } @@ -1828,11 +1830,11 @@ dgquery: |- query { getHuman(func: uid(0x1)) @filter(type(Human)) { - id : uid - name : Character.name - ename : Employee.ename - dob : Human.dob - female : Human.female + Human.id : uid + Human.name : Character.name + Human.ename : Employee.ename + Human.dob : Human.dob + Human.female : Human.female } } @@ -1851,11 +1853,11 @@ dgquery: |- query { queryHuman(func: type(Human)) { - id : uid - name : Character.name - ename : Employee.ename - dob : Human.dob - female : Human.female + Human.id : uid + Human.name : Character.name + Human.ename : Employee.ename + Human.dob : Human.dob + Human.female : Human.female } } @@ -1901,10 +1903,10 @@ dgquery: |- query { queryHuman(func: type(Human), orderasc: Employee.ename) @filter(anyofterms(Character.name, "GraphQL")) { - id : uid - name : Character.name - ename : Employee.ename - dob : Human.dob + Human.id : uid + Human.name : Character.name + Human.ename : Employee.ename + Human.dob : Human.dob } } @@ -1925,10 +1927,10 @@ query { queryCharacter(func: type(Character)) { dgraph.type - id : uid - name : Character.name - female : Human.female - ename : Employee.ename + Character.id : uid + Character.name : Character.name + Human.female : Human.female + Human.ename : Employee.ename } } @@ -1952,11 +1954,11 @@ query { queryCharacter(func: type(Character)) { dgraph.type - id : uid - name : Character.name - female : Human.female - ename : Employee.ename - movies : Director.movies + Character.id : uid + Character.name : Character.name + Human.female : Human.female + Human.ename : Employee.ename + Director.movies : Director.movies } } @@ -1979,10 +1981,10 @@ query { queryCharacter(func: type(Character)) { dgraph.type - id : uid - name : Character.name - ename : Employee.ename - female : Human.female + Character.id : uid + Character.name : Character.name + Employee.ename : Employee.ename + Human.female : Human.female } } @@ -1997,7 +1999,7 @@ dgquery: |- query { queryAuthor(func: uid(0x1, 0x2)) @filter((eq(Author.name, "A. N. Author") AND type(Author))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -2014,8 +2016,8 @@ dgquery: |- query { queryPost(func: type(Post)) @filter(between(Post.numLikes, 10, 20)) { - title : Post.title - text : Post.text + Post.title : Post.title + Post.text : Post.text dgraph.uid : uid } } @@ -2036,11 +2038,11 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter(between(Author.reputation, "6", "7.2")) { - name : Author.name - reputation : Author.reputation - posts : Author.posts @filter(between(Post.numLikes, 10, 100)) { - title : Post.title - numLikes : Post.numLikes + Author.name : Author.name + Author.reputation : Author.reputation + Author.posts : Author.posts @filter(between(Post.numLikes, 10, 100)) { + Post.title : Post.title + Post.numLikes : Post.numLikes dgraph.uid : uid } dgraph.uid : uid @@ -2058,7 +2060,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter((uid(0x1, 0x2) AND eq(Author.name, "A. N. Author"))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -2074,7 +2076,7 @@ dgquery: |- query { queryAuthor(func: type(Author)) @filter(NOT (uid(0x1, 0x2))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -2093,9 +2095,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name - posts : Author.posts @filter((anyofterms(Post.title, "GraphQL") AND uid(0x1, 0x2))) { - title : Post.title + Author.name : Author.name + Author.posts : Author.posts @filter((anyofterms(Post.title, "GraphQL") AND uid(0x1, 0x2))) { + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -2116,9 +2118,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name - posts : Author.posts @filter((NOT (uid(0x1, 0x2)) AND anyofterms(Post.title, "GraphQL"))) { - title : Post.title + Author.name : Author.name + Author.posts : Author.posts @filter((NOT (uid(0x1, 0x2)) AND anyofterms(Post.title, "GraphQL"))) { + Post.title : Post.title dgraph.uid : uid } dgraph.uid : uid @@ -2136,7 +2138,7 @@ dgquery: |- query { queryAuthor(func: uid(0x1, 0x2), orderasc: Author.name, first: 0, offset: 1) @filter(type(Author)) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -2152,7 +2154,7 @@ dgquery: |- query { queryAuthor(func: uid(0x1, 0x2), orderasc: Author.name) @filter(type(Author)) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -2168,7 +2170,7 @@ dgquery: |- query { queryAuthor(func: type(Author), orderasc: Author.name) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -2184,7 +2186,7 @@ dgquery: |- query { queryAuthor(func: type(Author), orderasc: Author.name, first: 2, offset: 3) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -2201,7 +2203,7 @@ dgquery: |- query { queryAuthor(func: uid()) @filter((eq(Author.name, "A. N. Author") AND type(Author))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -2217,7 +2219,7 @@ dgquery: |- query { queryAuthor(func: uid(0x1)) @filter((eq(Author.name, "A. N. Author") AND type(Author))) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } @@ -2233,7 +2235,7 @@ dgquery: |- query { getEditor(func: uid(0x0)) @filter(type(Editor)) { - name : Editor.name + Editor.name : Editor.name dgraph.uid : uid } } @@ -2249,7 +2251,7 @@ dgquery: |- query { getEditor(func: eq(Editor.code, "tolstoy")) @filter(type(Editor)) { - name : Editor.name + Editor.name : Editor.name dgraph.uid : uid } } @@ -2265,7 +2267,7 @@ dgquery: |- query { getEditor(func: uid(0x1)) @filter((eq(Editor.code, "tolstoy") AND type(Editor))) { - name : Editor.name + Editor.name : Editor.name dgraph.uid : uid } } @@ -2281,7 +2283,7 @@ dgquery: |- query { getState(func: eq(State.code, "NSW")) @filter(type(State)) { - name : State.name + State.name : State.name dgraph.uid : uid } } @@ -2297,7 +2299,7 @@ dgquery: |- query { queryEditor(func: type(Editor)) @filter((eq(Editor.name, "A. N. Editor") AND eq(Editor.code, "editor"))) { - name : Editor.name + Editor.name : Editor.name dgraph.uid : uid } } @@ -2313,7 +2315,7 @@ dgquery: |- query { queryEditor(func: uid(0x1)) @filter((eq(Editor.code, "editor") AND type(Editor))) { - name : Editor.name + Editor.name : Editor.name dgraph.uid : uid } } @@ -2332,9 +2334,9 @@ dgquery: |- query { queryMovie(func: type(Movie)) { - name : Movie.name - director : ~directed.movies { - name : MovieDirector.name + Movie.name : Movie.name + Movie.director : ~directed.movies { + MovieDirector.name : MovieDirector.name dgraph.uid : uid } dgraph.uid : uid @@ -2353,7 +2355,7 @@ dgquery: |- query { queryCategory(func: type(Category)) { - iAmDeprecated : Category.iAmDeprecated + Category.iAmDeprecated : Category.iAmDeprecated dgraph.uid : uid } } @@ -2369,7 +2371,7 @@ dgquery: |- query { checkUserPassword(func: eq(User.name, "user1")) @filter((eq(val(pwd), 1) AND type(User))) { - name : User.name + User.name : User.name dgraph.uid : uid } checkPwd(func: eq(User.name, "user1")) @filter(type(User)) { @@ -2388,7 +2390,7 @@ dgquery: |- query { checkUserPassword(func: eq(User.name, "user1")) @filter((eq(val(pwd), 1) AND type(User))) { - name : User.name + User.name : User.name dgraph.uid : uid } checkPwd(func: eq(User.name, "user1")) @filter(type(User)) { @@ -2413,13 +2415,14 @@ dgquery: |- query { getComment(func: uid(0x1)) @filter(type(Comment)) { - id : uid - author : Comment.author - title : Comment.title - ups : Comment.ups - url : Comment.url + Comment.id : uid + Comment.author : Comment.author + Comment.title : Comment.title + Comment.ups : Comment.ups + Comment.url : Comment.url } } + - name: "Include fields needed by custom directive" gqlquery: | query { @@ -2433,9 +2436,9 @@ dgquery: |- query { getComment(func: uid(0x1)) @filter(type(Comment)) { - author : Comment.author - id : uid - url : Comment.url + Comment.author : Comment.author + Comment.id : uid + Comment.url : Comment.url } } - name: "Rewrite without custom fields deep" @@ -2459,13 +2462,13 @@ dgquery: |- query { getPost(func: uid(0x1)) @filter(type(Post)) { - postID : uid - comments : Post.comments { - id : uid - author : Comment.author - title : Comment.title - ups : Comment.ups - url : Comment.url + Post.postID : uid + Post.comments : Post.comments { + Comment.id : uid + Comment.author : Comment.author + Comment.title : Comment.title + Comment.ups : Comment.ups + Comment.url : Comment.url } } } @@ -2488,13 +2491,13 @@ dgquery: |- query { getPost(func: uid(0x1)) @filter(type(Post)) { - postID : uid - comments : Post.comments { - author : Comment.author - title : Comment.title - ups : Comment.ups - id : uid - url : Comment.url + Post.postID : uid + Post.comments : Post.comments { + Comment.author : Comment.author + Comment.title : Comment.title + Comment.ups : Comment.ups + Comment.id : uid + Comment.url : Comment.url } } } @@ -2509,13 +2512,13 @@ dgquery: |- query { getTweets(func: eq(Tweets.id, "1286891968727982081")) @filter(type(Tweets)) { - score : Tweets.score - id : Tweets.id + Tweets.score : Tweets.score + Tweets.id : Tweets.id dgraph.uid : uid } } -- name: "querying a inbuiltType field multiple times with different aliases adds it only once in rewriting" +- name: "querying a inbuiltType field multiple times with different aliases adds it multiple times in rewriting" gqlquery: |- query { queryThingOne { @@ -2529,12 +2532,15 @@ dgquery: |- query { queryThingOne(func: type(ThingOne)) { - id : uid - name : Thing.name + ThingOne.i1 : uid + ThingOne.i2 : uid + ThingOne.name : Thing.name + ThingOne.n : Thing.name + ThingOne.n1 : Thing.name } } -- name: "querying an Enum type field multiple times with different aliases adds it only once in rewrting" +- name: "querying an Enum type field multiple times with different aliases adds it multiple times in rewriting" gqlquery: |- query { queryPost { @@ -2546,8 +2552,9 @@ dgquery: |- query { queryPost(func: type(Post)) { - title : Post.title - postType : Post.postType + Post.title : Post.title + Post.p1 : Post.postType + Post.p2 : Post.postType dgraph.uid : uid } } @@ -2570,15 +2577,15 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name - posts : Author.posts @filter(eq(Post.isPublished, true)) { - title : Post.title - text : Post.text + Author.name : Author.name + Author.p1 : Author.posts @filter(eq(Post.isPublished, true)) { + Post.title : Post.title + Post.text : Post.text dgraph.uid : uid } - posts.1 : Author.posts @filter(eq(Post.isPublished, false)) { - title : Post.title - text : Post.text + Author.p2 : Author.posts @filter(eq(Post.isPublished, false)) { + Post.title : Post.title + Post.text : Post.text dgraph.uid : uid } dgraph.uid : uid @@ -2604,15 +2611,15 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name - posts : Author.posts @filter(eq(Post.isPublished, true)) { - title : Post.title - text : Post.text + Author.name : Author.name + Author.p1 : Author.posts @filter(eq(Post.isPublished, true)) { + Post.title : Post.title + Post.text : Post.text dgraph.uid : uid } - posts.1 : Author.posts @filter(eq(Post.isPublished, true)) { - title : Post.title - text : Post.text + Author.p2 : Author.posts @filter(eq(Post.isPublished, true)) { + Post.title : Post.title + Post.text : Post.text dgraph.uid : uid } dgraph.uid : uid @@ -2637,10 +2644,10 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - name : Author.name - posts : Author.posts @filter(eq(Post.isPublished, true)) { - title : Post.title - text : Post.text + Author.name : Author.name + Author.p1 : Author.posts @filter(eq(Post.isPublished, true)) { + Post.title : Post.title + Post.text : Post.text dgraph.uid : uid } dgraph.uid : uid @@ -2665,9 +2672,9 @@ dgquery: |- query { queryAuthor(func: type(Author)) { - count_postsAggregate : count(Author.posts) - count_postsAggregate.1 : count(Author.posts) @filter(gt(Post.tags, "abc")) - count_postsAggregate.2 : count(Author.posts) @filter(le(Post.tags, "xyz")) + PostAggregateResult.count_Author.postsAggregate : count(Author.posts) + PostAggregateResult.count_Author.p1 : count(Author.posts) @filter(gt(Post.tags, "abc")) + PostAggregateResult.count_Author.p2 : count(Author.posts) @filter(le(Post.tags, "xyz")) dgraph.uid : uid } } @@ -2698,13 +2705,16 @@ query { queryThing(func: type(Thing)) { dgraph.type - id : uid - name : Thing.name + ThingOne.id : uid + ThingOne.name : Thing.name ThingOne.color : ThingOne.color - prop : prop - usedBy : ThingOne.usedBy + ThingOne.prop : prop + ThingOne.usedBy : ThingOne.usedBy + ThingTwo.id : uid + ThingTwo.name : Thing.name ThingTwo.color : ThingTwo.color - owner : ThingTwo.owner + ThingTwo.prop : prop + ThingTwo.owner : ThingTwo.owner } } @@ -2769,14 +2779,14 @@ dgquery: |- query { queryHome(func: type(Home)) { - address : Home.address - members : Home.members { + Home.address : Home.address + Home.members : Home.members { dgraph.type - category : Animal.category + Animal.category : Animal.category Dog.breed : Dog.breed - repeatsWords : Parrot.repeatsWords - name : Character.name - dob : Human.dob + Parrot.repeatsWords : Parrot.repeatsWords + Human.name : Character.name + Human.dob : Human.dob dgraph.uid : uid } dgraph.uid : uid @@ -2801,9 +2811,9 @@ dgquery: |- query { queryHome(func: type(Home)) { - members : Home.members { + Home.members : Home.members { dgraph.type - category : Animal.category + Dog.category : Animal.category Dog.breed : Dog.breed Plant.breed : Plant.breed dgraph.uid : uid @@ -2837,10 +2847,10 @@ dgquery: |- query { queryHome(func: type(Home)) { - members : Home.members @filter(((type(Dog) AND allofterms(Dog.breed, "German Shepherd")) OR type(Parrot))) (first: 5, offset: 10) { + Home.members : Home.members @filter(((type(Dog) AND allofterms(Dog.breed, "German Shepherd")) OR type(Parrot))) (first: 5, offset: 10) { dgraph.type - id : uid - repeatsWords : Parrot.repeatsWords + Dog.id : uid + Parrot.repeatsWords : Parrot.repeatsWords } dgraph.uid : uid } @@ -2888,9 +2898,9 @@ dgquery: |- query { queryHome(func: type(Home)) { - members : Home.members @filter(((type(Dog) AND allofterms(Dog.breed, "German Shepherd")) OR type(Parrot) OR type(Human) OR type(Plant))) { + Home.members : Home.members @filter(((type(Dog) AND allofterms(Dog.breed, "German Shepherd")) OR type(Parrot) OR type(Human) OR type(Plant))) { dgraph.type - id : uid + Dog.id : uid } dgraph.uid : uid } @@ -2915,9 +2925,9 @@ dgquery: |- query { queryHome(func: type(Home)) { - members : Home.members @filter(((type(Dog) AND allofterms(Dog.breed, "German Shepherd")) OR type(Human) OR type(Parrot) OR type(Plant))) { + Home.members : Home.members @filter(((type(Dog) AND allofterms(Dog.breed, "German Shepherd")) OR type(Human) OR type(Parrot) OR type(Plant))) { dgraph.type - id : uid + Dog.id : uid } dgraph.uid : uid } @@ -2937,8 +2947,8 @@ dgquery: |- query { queryCountry(func: type(Country)) { - name : Country.name - count_statesAggregate : count(Country.states) + Country.nm : Country.name + StateAggregateResult.cnt_Country.ag : count(Country.states) dgraph.uid : uid } } @@ -2966,22 +2976,24 @@ dgquery: |- query { queryCountry(func: type(Country)) { - name : Country.name - statesAggregate : Country.states { - statesAggregate_nameVar as State.name + Country.nm : Country.name + Country.ag : Country.states { + Country.ag_nameVar as State.name dgraph.uid : uid } - nameMin_statesAggregate : min(val(statesAggregate_nameVar)) - nameMax_statesAggregate : max(val(statesAggregate_nameVar)) - statesAggregate.1 : Country.states @filter(eq(State.code, "state code")) { - statesAggregate.1_nameVar as State.name - statesAggregate.1_capitalVar as State.capital + StateAggregateResult.nMin_Country.ag : min(val(Country.ag_nameVar)) + StateAggregateResult.nMax_Country.ag : max(val(Country.ag_nameVar)) + Country.statesAggregate : Country.states @filter(eq(State.code, "state code")) { + Country.statesAggregate_nameVar as State.name + Country.statesAggregate_capitalVar as State.capital dgraph.uid : uid } - count_statesAggregate.1 : count(Country.states) @filter(eq(State.code, "state code")) - nameMin_statesAggregate.1 : min(val(statesAggregate.1_nameVar)) - nameMax_statesAggregate.1 : max(val(statesAggregate.1_nameVar)) - capitalMin_statesAggregate.1 : min(val(statesAggregate.1_capitalVar)) + StateAggregateResult.cnt_Country.statesAggregate : count(Country.states) @filter(eq(State.code, "state code")) + StateAggregateResult.cnt2_Country.statesAggregate : count(Country.states) @filter(eq(State.code, "state code")) + StateAggregateResult.nMin_Country.statesAggregate : min(val(Country.statesAggregate_nameVar)) + StateAggregateResult.nameMin_Country.statesAggregate : min(val(Country.statesAggregate_nameVar)) + StateAggregateResult.nMax_Country.statesAggregate : max(val(Country.statesAggregate_nameVar)) + StateAggregateResult.cMin_Country.statesAggregate : min(val(Country.statesAggregate_capitalVar)) dgraph.uid : uid } } @@ -3003,10 +3015,10 @@ dgquery: |- query { queryCountry(func: type(Country)) { - name : Country.name - count_statesAggregate : count(Country.states) @filter(eq(State.code, "state code")) - states : Country.states { - capital : State.capital + Country.nm : Country.name + StateAggregateResult.cnt_Country.ag : count(Country.states) @filter(eq(State.code, "state code")) + Country.st : Country.states { + State.capital : State.capital dgraph.uid : uid } dgraph.uid : uid @@ -3029,9 +3041,9 @@ dgquery: |- query { getAuthor(func: uid(0x1)) @filter(type(Author)) { - name : Author.name - country : Author.country { - count_statesAggregate : count(Country.states) @filter(eq(State.code, "state code")) + Author.nm : Author.name + Author.country : Author.country { + StateAggregateResult.count_Country.ag : count(Country.states) @filter(eq(State.code, "state code")) dgraph.uid : uid } dgraph.uid : uid @@ -3053,11 +3065,11 @@ dgquery: |- query { aggregateTweets() { - count : max(val(countVar)) - scoreMin : min(val(scoreVar)) - scoreMax : max(val(scoreVar)) - scoreAvg : avg(val(scoreVar)) - scoreSum : sum(val(scoreVar)) + TweetsAggregateResult.count : max(val(countVar)) + TweetsAggregateResult.scoreMin : min(val(scoreVar)) + TweetsAggregateResult.scoreMax : max(val(scoreVar)) + TweetsAggregateResult.scoreAvg : avg(val(scoreVar)) + TweetsAggregateResult.scoreSum : sum(val(scoreVar)) } var(func: type(Tweets)) { countVar as count(uid) @@ -3076,7 +3088,7 @@ dgquery: |- query { queryAuthor(func: uid(0x1)) @filter(type(Author)) { - name : Author.name + Author.name : Author.name dgraph.uid : uid } } \ No newline at end of file diff --git a/graphql/resolve/resolver.go b/graphql/resolve/resolver.go index 378f59aced5..ccb959bbc5d 100644 --- a/graphql/resolve/resolver.go +++ b/graphql/resolve/resolver.go @@ -1381,7 +1381,7 @@ func completeObject( } else { uniqueDgraphAlias = generateUniqueDgraphAlias(f, fieldSeenCount) } - val := res[uniqueDgraphAlias] + val := res[f.Name()] // temp change just for making admin work // Handle aggregate queries: // Aggregate Fields in DQL response don't follow the same response as other queries. // Create a map aggregateVal and store response of aggregate fields in a way which diff --git a/graphql/schema/wrappers.go b/graphql/schema/wrappers.go index ac96aec4839..ce5a7841c0f 100644 --- a/graphql/schema/wrappers.go +++ b/graphql/schema/wrappers.go @@ -232,9 +232,6 @@ type schema struct { mutatedType map[string]*astType // Map from typename to ast.Definition typeNameAst map[string][]*ast.Definition - // map from field name to bool, indicating if a field name was repeated across different types - // implementing the same interface - repeatedFieldNames map[string]bool // customDirectives stores the mapping of typeName -> fieldName -> @custom definition. // It is read-only. // The outer map will contain typeName key only if one of the fields on that type has @custom. @@ -581,54 +578,6 @@ func typeMappings(s *ast.Schema) map[string][]*ast.Definition { return typeNameAst } -func repeatedFieldMappings(s *ast.Schema, dgPreds map[string]map[string]string) map[string]bool { - repeatedFieldNames := make(map[string]bool) - - for _, typ := range s.Types { - if !isAbstractKind(typ.Kind) { - continue - } - - type fieldInfo struct { - dgPred string - repeated bool - } - - repeatedFieldsInTypesWithCommonAncestor := make(map[string]*fieldInfo) - for _, typ := range s.PossibleTypes[typ.Name] { - typPreds := dgPreds[typ.Name] - for _, field := range typ.Fields { - // ignore this field if it was inherited from the common interface or is of ID type. - // We ignore ID type fields too, because they map only to uid in dgraph and can't - // map to two different predicates. - if field.Type.Name() == IDType { - continue - } - // if we find a field with same name from types implementing a common interface - // and its DgraphPredicate is different than what was previously encountered, then - // we mark it as repeated field, so that queries will rewrite it with correct alias. - // For fields, which these types have implemented from a common interface, their - // DgraphPredicate will be same, so they won't be marked as repeated. - dgPred := typPreds[field.Name] - if fInfo, ok := repeatedFieldsInTypesWithCommonAncestor[field.Name]; ok && fInfo. - dgPred != dgPred { - repeatedFieldsInTypesWithCommonAncestor[field.Name].repeated = true - } else { - repeatedFieldsInTypesWithCommonAncestor[field.Name] = &fieldInfo{dgPred: dgPred} - } - } - } - - for fName, info := range repeatedFieldsInTypesWithCommonAncestor { - if info.repeated { - repeatedFieldNames[fName] = true - } - } - } - - return repeatedFieldNames -} - // customAndLambdaMappings does following things: // * If there is @custom on any field, it removes the directive from the list of directives on // that field. Instead, it puts it in a map of typeName->fieldName->custom directive definition. @@ -804,13 +753,12 @@ func AsSchema(s *ast.Schema) (Schema, error) { customDirs, lambdaDirs := customAndLambdaMappings(s) dgraphPredicate := dgraphMapping(s) sch := &schema{ - schema: s, - dgraphPredicate: dgraphPredicate, - typeNameAst: typeMappings(s), - repeatedFieldNames: repeatedFieldMappings(s, dgraphPredicate), - customDirectives: customDirs, - lambdaDirectives: lambdaDirs, - authRules: authRules, + schema: s, + dgraphPredicate: dgraphPredicate, + typeNameAst: typeMappings(s), + customDirectives: customDirs, + lambdaDirectives: lambdaDirs, + authRules: authRules, } sch.mutatedType = mutatedTypeMapping(sch, dgraphPredicate) @@ -833,25 +781,7 @@ func (f *field) Alias() string { } func (f *field) DgraphAlias() string { - // if this field is repeated, then it should be aliased using its dgraph predicate which will be - // unique across repeated fields - if f.op.inSchema.repeatedFieldNames[f.Name()] { - dgraphPredicate := f.DgraphPredicate() - // There won't be any dgraph predicate for fields in introspection queries, as they are not - // stored in dgraph. So we identify those fields using this condition, and just let the - // field name get returned for introspection query fields, because the raw data response is - // prepared for them using only the field name, so that is what should be used to pick them - // back up from that raw data response before completion is performed. - // Now, the reason to not combine this if check with the outer one is because this - // function is performance critical. If there are a million fields in the output, - // it would be called a million times. So, better to perform this check and allocate memory - // for the variable only when necessary to do so. - if dgraphPredicate != "" { - return dgraphPredicate - } - } - // if not repeated, alias it using its name - return f.Name() + return f.field.ObjectDefinition.Name + "." + f.field.Alias } func (f *field) ResponseName() string { @@ -877,7 +807,7 @@ func (f *field) IsAuthQuery() bool { } func (f *field) IsAggregateField() bool { - return strings.HasSuffix(f.DgraphAlias(), "Aggregate") && f.Type().IsAggregateResult() + return strings.HasSuffix(f.Name(), "Aggregate") && f.Type().IsAggregateResult() } func (f *field) GqlErrorf(path []interface{}, message string, args ...interface{}) *x.GqlError { @@ -1115,9 +1045,17 @@ func (f *field) IDArgValue() (xid *string, uid uint64, err error) { func (f *field) Type() Type { var t *ast.Type if f.field != nil && f.field.Definition != nil { - // This is strange. There was a case with a parsed schema and query where the field - // had a nil Definition ... how ??? t = f.field.Definition.Type + } else { + // If f is a field that isn't defined in the schema, then it would have nil definition. + // This can happen in case if the incoming request contains a query/mutation that isn't + // defined in the schema being served. Resolving such a query would report that no + // suitable resolver was found. + // In this case we are returning a nullable type named "__Undefined__" from here, instead + // of returning nil, so that the rest of the code can continue to work. The type is + // nullable so that if the request contained other valid queries, they should still get a + // data response. + t = &ast.Type{NamedType: "__Undefined__", NonNull: false} } return &astType{ @@ -1831,10 +1769,7 @@ func (fd *fieldDefinition) Name() string { } func (fd *fieldDefinition) DgraphAlias() string { - if fd.inSchema.repeatedFieldNames[fd.Name()] { - return fd.DgraphPredicate() - } - return fd.Name() + return fd.parentType.Name() + "." + fd.fieldDef.Name } func (fd *fieldDefinition) DgraphPredicate() string { diff --git a/query/outputnode_graphql.go b/query/outputnode_graphql.go index 533692e0053..fbc38a434b4 100644 --- a/query/outputnode_graphql.go +++ b/query/outputnode_graphql.go @@ -53,15 +53,12 @@ func writeKeyGraphQL(field gqlSchema.Field, out *bytes.Buffer) { } // TODO: -// * change query rewriting for scalar fields asked multiple times (DgraphAlias() thing). -// We may also need to pay attention to aggregate field rewriting as they just use fieldName -// and not DgraphAlias(). // * Scalar coercion // * Enums -// * Null writing for root Aggregate queries // * Password queries -// * Cleanup code from resolve pkg -// * make args like *bytes.Buffer the first arg in funcs as a best practice +// * (cleanup) Cleanup code from resolve pkg +// * (cleanup) make const args like *bytes.Buffer the first arg in funcs as a best practice. +// * (cleanup) refactor this func as `func (ctx *graphQLEncodingCtx) encode(enc *encoder, ...)`. func (enc *encoder) encodeGraphQL(ctx *graphQLEncodingCtx, fj fastJsonNode, fjIsRoot bool, childSelectionSet []gqlSchema.Field, parentField gqlSchema.Field, parentPath []interface{}) bool { @@ -152,6 +149,8 @@ func (enc *encoder) encodeGraphQL(ctx *graphQLEncodingCtx, fj fastJsonNode, fjIs // correctly write value as null, if need be. nullWritten := false // indicates whether null has been written as value for the current // selection or not. Used to figure out whether to write the closing ] for JSON arrays. + seenField := make(map[string]bool) // seenField map keeps track of fields which have been seen + // as part of interface to avoid double entry in the resulting response var curSelection gqlSchema.Field // used to store the current selection in the childSelectionSet var curSelectionIsList bool // indicates whether the type of curSelection is list or not @@ -179,29 +178,32 @@ func (enc *encoder) encodeGraphQL(ctx *graphQLEncodingCtx, fj fastJsonNode, fjIs cur = child next = cur.next - if skipField(curSelection, dgraphTypes) { - cnt = 0 // Reset the count, - // indicating that we need to write the JSON key in next iteration. - i++ - // if this is the last field and shouldn't be included, - // then need to remove comma from the buffer if one was present. - if i == len(childSelectionSet) { - checkAndStripComma(ctx.buf) - } - // also if there was any data for this field, need to skip that - // there may not be data in case this field was added from a fragment. - attrId := enc.idForAttr(curSelection.DgraphAlias()) - if enc.getAttr(cur) == attrId { - for next != nil && enc.getAttr(next) == attrId { - next = next.next + // Step-1: Skip the field OR Write JSON key and opening [ for JSON arrays + if cnt == 1 { + // we need to check if the field should be skipped only when it is encountered for + // the first time + if skipField(curSelection, dgraphTypes, seenField) { + cnt = 0 // Reset the count, + // indicating that we need to write the JSON key in next iteration. + i++ + // if this is the last field and shouldn't be included, + // then need to remove comma from the buffer if one was present. + if i == len(childSelectionSet) { + checkAndStripComma(ctx.buf) } - child = next + // also if there was any data for this field, need to skip that. There may not be + // data in case this field was added from a fragment on another type. + attrId := enc.idForAttr(curSelection.DgraphAlias()) + if enc.getAttr(cur) == attrId { + for next != nil && enc.getAttr(next) == attrId { + next = next.next + } + child = next + } + continue } - continue - } - // Step-1: Write JSON key and opening [ for JSON arrays - if cnt == 1 { + // Write JSON key and opening [ for JSON arrays writeKeyGraphQL(curSelection, ctx.buf) keyEndPos = ctx.buf.Len() curSelectionIsList = curSelection.Type().ListType() != nil @@ -214,32 +216,45 @@ func (enc *encoder) encodeGraphQL(ctx *graphQLEncodingCtx, fj fastJsonNode, fjIs if curSelection.Name() == gqlSchema.Typename { // If the current selection is __typename then we find out the typename using the // dgraphTypes slice saved earlier. - x.Check2(ctx.buf.Write([]byte(`"` + curSelection.TypeName(dgraphTypes) + `"`))) + x.Check2(ctx.buf.Write(getTypename(curSelection, dgraphTypes))) // We don't need to iterate to next fastJson node in this case, // as the current node will have data for the next field in the selection set. } else if curSelection.DgraphAlias() != enc.attrForID(enc.getAttr(cur)) { - // TODO: use the correct alias everywhere // if the current fastJson node doesn't hold data for the current GraphQL selection, // then there can be two cases: // 1. The current fastJson node holds data for a next selection and there was no data // present for the current GraphQL selection, so need to write null for the current // GraphQL selection with appropriate errors. - // 2. The current fastJson node holds data which wasn't requested by any GraphQL + // 2. The current fastJson node holds data for count(pred), the current GraphQL + // selection is an aggregate field at child level and there was no data present for + // it. So, need to write null for the children of current GraphQL selection but also + // need to skip all the count(pred) fastJson nodes which were requested from within + // the current GraphQL selection. + // 3. The current fastJson node holds data which wasn't requested by any GraphQL // selection, but instead by a DQL selection added by GraphQL layer; and the data // for current selection may be present in an upcoming fastJson node. // Point to note is that this case doesn't happen as the GraphQL layer adds such // DQL selections only at the beginning (dgraph.type) or end (dgraph.uid: uid) of a // DQL selection set, but not in middle. The beginning case we have already handled, // and the end case would either be ignored by this for loop or handled as case 1. - // So, we don't have a need to handle case 2, and need to always write null with + // So, we don't have a need to handle case 3, and need to always write null with // appropriate errors. - if nullWritten = writeGraphQLNull(curSelection, ctx.buf, keyEndPos); !nullWritten { - ctx.gqlErrs = append(ctx.gqlErrs, curSelection.GqlErrorf(append(parentPath, - curSelection.ResponseName()), gqlSchema.ErrExpectedNonNull, curSelection.Name(), - curSelection.Type())) - return false + // TODO: check if case 3 can happen for @custom(dql: "") + + if !fjIsRoot && curSelection.IsAggregateField() { + // handles null writing for case 2 + child = completeAggregateChildren(enc, ctx, cur, curSelection, + append(parentPath, curSelection.ResponseName()), true) + } else { + // handles null writing for case 1 + if nullWritten = writeGraphQLNull(curSelection, ctx.buf, keyEndPos); !nullWritten { + ctx.gqlErrs = append(ctx.gqlErrs, curSelection.GqlErrorf(append(parentPath, + curSelection.ResponseName()), gqlSchema.ErrExpectedNonNull, + curSelection.Name(), curSelection.Type())) + return false + } + // we don't need to iterate to next fastJson node here. } - // we don't need to iterate to next fastJson node here. } else { // This is the case where the current fastJson node holds data for the current // GraphQL selection. There are following possible sub-cases: @@ -342,7 +357,7 @@ func (enc *encoder) encodeGraphQL(ctx *graphQLEncodingCtx, fj fastJsonNode, fjIs } else { // this case is of deep aggregate fields next = completeAggregateChildren(enc, ctx, cur, curSelection, - append(parentPath, curSelection.ResponseName())) + append(parentPath, curSelection.ResponseName()), false) } child = next } else if !curSelectionIsList { @@ -370,8 +385,8 @@ func (enc *encoder) encodeGraphQL(ctx *graphQLEncodingCtx, fj fastJsonNode, fjIs } } - // Step-3: Write closing ] for JSON arrays - if next == nil || enc.getAttr(cur) != enc.getAttr(next) { + // Step-3: Update counters and Write closing ] for JSON arrays + if !curSelectionIsList || next == nil || enc.getAttr(cur) != enc.getAttr(next) { if curSelectionIsList && !nullWritten { x.Check2(ctx.buf.WriteRune(']')) } @@ -393,7 +408,7 @@ func (enc *encoder) encodeGraphQL(ctx *graphQLEncodingCtx, fj fastJsonNode, fjIs for i < len(childSelectionSet) { curSelection = childSelectionSet[i] - if skipField(curSelection, dgraphTypes) { + if skipField(curSelection, dgraphTypes, seenField) { i++ // if this is the last field and shouldn't be included, // then need to remove comma from the buffer if one was present. @@ -408,7 +423,7 @@ func (enc *encoder) encodeGraphQL(ctx *graphQLEncodingCtx, fj fastJsonNode, fjIs // Step-2: Write JSON value if curSelection.Name() == gqlSchema.Typename { - x.Check2(ctx.buf.Write([]byte(`"` + curSelection.TypeName(dgraphTypes) + `"`))) + x.Check2(ctx.buf.Write(getTypename(curSelection, dgraphTypes))) } else { if !writeGraphQLNull(curSelection, ctx.buf, ctx.buf.Len()) { ctx.gqlErrs = append(ctx.gqlErrs, curSelection.GqlErrorf(append(parentPath, @@ -433,8 +448,7 @@ func (enc *encoder) encodeGraphQL(ctx *graphQLEncodingCtx, fj fastJsonNode, fjIs return true } -// TODO: add seenField logic -func skipField(f gqlSchema.Field, dgraphTypes []interface{}) bool { +func skipField(f gqlSchema.Field, dgraphTypes []interface{}, seenField map[string]bool) bool { if f.Skip() || !f.Include() { return true } @@ -447,6 +461,12 @@ func skipField(f gqlSchema.Field, dgraphTypes []interface{}) bool { if len(dgraphTypes) > 0 && !f.IncludeInterfaceField(dgraphTypes) { return true } + // if the field has already been seen at the current level, then we need to skip it. + // Otherwise, mark it seen. + if seenField[f.ResponseName()] { + return true + } + seenField[f.ResponseName()] = true return false } @@ -457,6 +477,11 @@ func checkAndStripComma(buf *bytes.Buffer) { } } +func getTypename(f gqlSchema.Field, dgraphTypes []interface{}) []byte { + // TODO (cleanup): refactor the TypeName method to accept []string + return []byte(`"` + f.TypeName(dgraphTypes) + `"`) +} + func writeGraphQLNull(f gqlSchema.Field, buf *bytes.Buffer, keyEndPos int) bool { buf.Truncate(keyEndPos) // truncate to make sure we write null correctly if f.Type().ListType() != nil { @@ -489,11 +514,11 @@ func writeGraphQLNull(f gqlSchema.Field, buf *bytes.Buffer, keyEndPos int) bool // { // "aggregateCountry": [ // { -// "count": 3 +// "CountryAggregateResult.count": 3 // }, { -// "nameMin": "US1" +// "CountryAggregateResult.nameMin": "US1" // }, { -// "nameMax": "US2" +// "CountryAggregateResult.nameMax": "US2" // } // ] // } @@ -508,25 +533,40 @@ func writeGraphQLNull(f gqlSchema.Field, buf *bytes.Buffer, keyEndPos int) bool // Note that there can't be the case when an aggregate property was requested in DQL and not // returned by Dgraph because aggregate properties are calculated using math functions which // always give some result. -// TODO: -// * check if above note is still valid after Rajas's PR is merged and handle null writing for -// the whole query appropriately. +// But, auth queries may lead to generation of following DQL: +// query { +// aggregateCountry() +// } +// which doesn't request any aggregate properties. In this case the fastJson node won't have any +// children and we just need to write null as the value of the query. func completeRootAggregateQuery(enc *encoder, ctx *graphQLEncodingCtx, fj fastJsonNode, query gqlSchema.Field, qryPath []interface{}) fastJsonNode { + if enc.children(fj) == nil { + x.Check2(ctx.buf.Write(jsonNull)) + return fj.next + } + + var val []byte + var err error comma := "" x.Check2(ctx.buf.WriteString("{")) for _, f := range query.SelectionSet() { x.Check2(ctx.buf.WriteString(comma)) writeKeyGraphQL(f, ctx.buf) - val, err := enc.getScalarVal(enc.children(fj)) - if err != nil { - ctx.gqlErrs = append(ctx.gqlErrs, f.GqlErrorf(append(qryPath, f.ResponseName()), - err.Error())) - // all aggregate properties are nullable, so no special checks are required - val = jsonNull + + if f.Name() == gqlSchema.Typename { + val = getTypename(f, nil) + } else { + val, err = enc.getScalarVal(enc.children(fj)) + if err != nil { + ctx.gqlErrs = append(ctx.gqlErrs, f.GqlErrorf(append(qryPath, f.ResponseName()), + err.Error())) + // all aggregate properties are nullable, so no special checks are required + val = jsonNull + } + fj = fj.next } - fj = fj.next x.Check2(ctx.buf.Write(val)) comma = "," } @@ -538,15 +578,15 @@ func completeRootAggregateQuery(enc *encoder, ctx *graphQLEncodingCtx, fj fastJs // completeAggregateChildren build GraphQL JSON for aggregate fields at child levels. // Dgraph result: // { -// "statesAggregate": [ +// "Country.statesAggregate": [ // { // "State.name": "Calgary", // "dgraph.uid": "0x2712" // } // ], -// "count_statesAggregate": 1, -// "nameMin_statesAggregate": "Calgary", -// "nameMax_statesAggregate": "Calgary" +// "StateAggregateResult.count_Country.statesAggregate": 1, +// "StateAggregateResult.nameMin_Country.statesAggregate": "Calgary", +// "StateAggregateResult.nameMax_Country.statesAggregate": "Calgary" // } // GraphQL result: // { @@ -557,12 +597,16 @@ func completeRootAggregateQuery(enc *encoder, ctx *graphQLEncodingCtx, fj fastJs // } // } func completeAggregateChildren(enc *encoder, ctx *graphQLEncodingCtx, fj fastJsonNode, - field gqlSchema.Field, fieldPath []interface{}) fastJsonNode { - // first we need to skip all the nodes returned with the attr of field as they are not needed - // in GraphQL. - attrId := enc.getAttr(fj) - for fj = fj.next; attrId == enc.getAttr(fj); fj = fj.next { - // do nothing + field gqlSchema.Field, fieldPath []interface{}, respIsNull bool) fastJsonNode { + if !respIsNull { + // first we need to skip all the nodes returned with the attr of field as they are not + // needed in GraphQL. + attrId := enc.getAttr(fj) + for fj = fj.next; attrId == enc.getAttr(fj); fj = fj.next { + // do nothing + } + // there would always be some other fastJson node after the nodes for field are skipped + // corresponding to a selection inside field that. So, no need to check above if fj != nil. } // now fj points to a node containing data for a child of field @@ -574,7 +618,10 @@ func completeAggregateChildren(enc *encoder, ctx *graphQLEncodingCtx, fj fastJso for _, f := range field.SelectionSet() { x.Check2(ctx.buf.WriteString(comma)) writeKeyGraphQL(f, ctx.buf) - if f.Name()+suffix == enc.attrForID(enc.getAttr(fj)) { + + if f.Name() == gqlSchema.Typename { + val = getTypename(f, nil) + } else if fj != nil && f.DgraphAlias()+suffix == enc.attrForID(enc.getAttr(fj)) { val, err = enc.getScalarVal(fj) if err != nil { ctx.gqlErrs = append(ctx.gqlErrs, f.GqlErrorf(append(fieldPath, f.ResponseName()), diff --git a/testutil/graphql.go b/testutil/graphql.go index 152583a281f..35b99457fcd 100644 --- a/testutil/graphql.go +++ b/testutil/graphql.go @@ -225,7 +225,7 @@ func (a *AuthMeta) AddClaimsToContext(ctx context.Context) (context.Context, err } func AppendAuthInfo(schema []byte, algo, publicKeyFile string, closedByDefault bool) ([]byte, error) { - authInfo := `# Dgraph.Authorization {"VerificationKey":"%s","Header":"X-Test-Auth","Namespace":"https://xyz.io/jwt/claims","Algo":"HS256","Audience":["aud1","63do0q16n6ebjgkumu05kkeian","aud5"],"ClosedByDefault":%s}` + authInfo := `# Dgraph.Authorization {"VerificationKey":"%s","Header":"X-Test-Auth","Namespace":"https://xyz.io/jwt/claims","Algo":"%s","Audience":["aud1","63do0q16n6ebjgkumu05kkeian","aud5"],"ClosedByDefault":%s}` closedByDefaultStr := "false" if closedByDefault { @@ -246,7 +246,7 @@ func AppendAuthInfo(schema []byte, algo, publicKeyFile string, closedByDefault b verificationKey = string(bytes.ReplaceAll(keyData, []byte{10}, []byte{92, 110})) } - authInfo = fmt.Sprintf(authInfo, verificationKey, closedByDefaultStr) + authInfo = fmt.Sprintf(authInfo, verificationKey, algo, closedByDefaultStr) return append(schema, []byte(authInfo)...), nil }