Skip to content

Commit

Permalink
fix (graphql): disallowing field names with as (#6645)
Browse files Browse the repository at this point in the history
This is related to GRAPHQL-564. as is Dgraph reserved keyword. It's being used by DQL to identify variables. This PR is to restrict the naming for fields with the name as.
  • Loading branch information
aman-bansal authored Oct 5, 2020
1 parent f079c7f commit 6ae69b4
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
41 changes: 41 additions & 0 deletions graphql/schema/gqlschema_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2398,6 +2398,47 @@ invalid_schemas:
{"message": "Subscription is a reserved word, so you can't declare a type with this name. Pick a different name for the type.", "locations": [{"line":1, "column":6}]},
]

-
name: "as is reserved keyword - type Name"
input: |
type As {
id: ID!
name: String
}
errlist: [
{ "message": "As is a reserved word, so you can't declare a type with this name. Pick a different name for the type.", "locations": [ { "line": 1, "column": 6 } ] },
]

- name: "as is reserved keyword - field name"
input: |
type X {
as: ID!
name: String
}
errlist: [
{ "message": "Type X; Field as: as is a reserved keyword and you cannot declare a field with this name.", "locations": [ { "line": 2, "column": 3 } ] },
]

- name: "as is reserved keyword - type name using @dgraph directive"
input: |
type X @dgraph(type:"as") {
id: ID!
name: String
}
errlist: [
{ "message": "Type X; type argument 'as' for @dgraph directive is a reserved keyword.", "locations": [ { "line": 1, "column": 9 } ] },
]

- name: "as is reserved keyword - field name using @dgraph directive"
input: |
type X {
id: ID!
name: String @dgraph(pred:"as")
}
errlist: [
{ "message": "Type X; Field name: pred argument 'as' for @dgraph directive is a reserved keyword.", "locations": [ { "line": 3, "column": 17 } ] },
]


valid_schemas:
- name: "@auth on interface implementation"
Expand Down
24 changes: 23 additions & 1 deletion graphql/schema/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,11 +547,19 @@ func dgraphDirectiveTypeValidation(schema *ast.Schema, typ *ast.Definition) gqle
dir.Position,
"Type %s; type argument for @dgraph directive should not be empty.", typ.Name)}
}

if typeArg.Value.Kind != ast.StringValue {
return []*gqlerror.Error{gqlerror.ErrorPosf(
dir.Position,
"Type %s; type argument for @dgraph directive should of type String.", typ.Name)}
}

if isReservedKeyWord(typeArg.Value.Raw) {
return []*gqlerror.Error{gqlerror.ErrorPosf(
dir.Position,
"Type %s; type argument '%s' for @dgraph directive is a reserved keyword.", typ.Name, typeArg.Value.Raw)}
}

return nil
}

Expand Down Expand Up @@ -1048,13 +1056,23 @@ func dgraphDirectiveValidation(sch *ast.Schema, typ *ast.Definition, field *ast.
typ.Name, field.Name))
return errs
}

if predArg.Value.Kind != ast.StringValue {
errs = append(errs, gqlerror.ErrorPosf(
dir.Position,
"Type %s; Field %s: pred argument for @dgraph directive should of type String.",
typ.Name, field.Name))
return errs
}

if isReservedKeyWord(predArg.Value.Raw) {
errs = append(errs, gqlerror.ErrorPosf(
dir.Position,
"Type %s; Field %s: pred argument '%s' for @dgraph directive is a reserved keyword.",
typ.Name, field.Name, predArg.Value.Raw))
return errs
}

if strings.HasPrefix(predArg.Value.Raw, "~") || strings.HasPrefix(predArg.Value.Raw, "<~") {
if sch.Types[typ.Name].Kind == ast.Interface {
// We don't want to consider the field of an interface but only the fields with
Expand Down Expand Up @@ -1808,7 +1826,11 @@ func isReservedKeyWord(name string) bool {
"Subscription": true,
}

if isScalar(name) || isQueryOrMutation(name) || reservedTypeNames[name] {
caseInsensitiveKeywords := map[string]bool{
"as": true, // this is reserved keyword because DQL uses this for variables
}

if isScalar(name) || isQueryOrMutation(name) || reservedTypeNames[name] || caseInsensitiveKeywords[strings.ToLower(name)] {
return true
}

Expand Down
13 changes: 12 additions & 1 deletion wiki/content/graphql/schema/reserved.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@ title = "Reserved Names"
parent = "schema"
weight = 1
+++
The following names are reserved and can't be used to define any other identifiers:

Names `Int`, `Float`, `Boolean`, `String`, `DateTime` and `ID` are reserved and cannot be used to define any other identifiers.
- `Int`
- `Float`
- `Boolean`
- `String`
- `DateTime`
- `ID`
- `uid`
- `Subscription`
- `as` (case-insensitive)
- `Query`
- `Mutation`

For each type, Dgraph generates a number of GraphQL types needed to operate the GraphQL API, these generated type names also can't be present in the input schema. For example, for a type `Author`, Dgraph generates `AuthorFilter`, `AuthorOrderable`, `AuthorOrder`, `AuthorRef`, `AddAuthorInput`, `UpdateAuthorInput`, `AuthorPatch`, `AddAuthorPayload`, `DeleteAuthorPayload` and `UpdateAuthorPayload`. Thus if `Author` is present in the input schema, all of those become reserved type names.

0 comments on commit 6ae69b4

Please sign in to comment.