diff --git a/graphql/e2e/common/common.go b/graphql/e2e/common/common.go index 9975f094e44..8b4285e4bf8 100644 --- a/graphql/e2e/common/common.go +++ b/graphql/e2e/common/common.go @@ -342,6 +342,7 @@ func RunAll(t *testing.T) { t.Run("alias works for mutations", mutationsWithAlias) t.Run("three level deep", threeLevelDeepMutation) t.Run("update mutation without set & remove", updateMutationWithoutSetRemove) + t.Run("Input coercing for int64 type", int64BoundaryTesting) t.Run("Check cascade with mutation without ID field", checkCascadeWithMutationWithoutIDField) // error tests diff --git a/graphql/e2e/common/error_test.yaml b/graphql/e2e/common/error_test.yaml index 2ea01476a65..ae682466844 100644 --- a/graphql/e2e/common/error_test.yaml +++ b/graphql/e2e/common/error_test.yaml @@ -115,6 +115,46 @@ [ { "message": "Field `title` is not present in type `Author`. You can only use fields which are in type `Author`", } ] +- + name: "Out of range error for int32 type" + gqlrequest: | + mutation { + addPost(input:[{title:"Dgraph",author:{name:"Bob"},numLikes:2147483648}]){ + post{ + title + numLikes + author{ + name + } + } + } + } + gqlvariables: + { } + errors: + [ { "message": "Out of range value '2147483648', for type `Int`", + "locations": [ { "line": 2, "column": 63 } ] } ] + +- + name: "Out of range error for int64 type" + gqlrequest: | + mutation { + addPost(input:[{title:"Dgraph",author:{name:"Bob"},numViews:9223372036854775808}]){ + post{ + title + numViews + author{ + name + } + } + } + } + gqlvariables: + { } + errors: + [ { "message": "Out of range value '9223372036854775808', for type `Int64`", + "locations": [ { "line": 2, "column": 63 } ] } ] + - name: "@cascade only accepts numUids or given type name as arguments for add or update payload " gqlrequest: | @@ -129,4 +169,44 @@ { } errors: [ { "message": "Field `name` is not present in type `AddAuthorPayload`. You can only use fields which are in type `AddAuthorPayload`", - } ] \ No newline at end of file + } ] + +- + name: "String value is Incompatible with Int64 type" + gqlrequest: | + mutation { + addPost(input:[{title:"Dgraph",author:{name:"Bob"},numViews:"180143985094"}]){ + post{ + title + numLikes + author{ + name + } + } + } + } + gqlvariables: + { } + errors: + [ { "message": "Type mismatched for Value `180143985094`, expected: Int64, got: 'String'", + "locations": [ { "line": 2, "column": 64 } ] } ] + +- + name: "Float value is Incompatible with Int64 type" + gqlrequest: | + mutation { + addPost(input:[{title:"Dgraph",author:{name:"Bob"},numViews:180143985094.0}]){ + post{ + title + numLikes + author{ + name + } + } + } + } + gqlvariables: + { } + errors: + [ { "message": "Type mismatched for Value `180143985094.0`, expected: Int64, got: 'Float'", + "locations": [ { "line": 2, "column": 63 } ] } ] \ No newline at end of file diff --git a/graphql/e2e/common/mutation.go b/graphql/e2e/common/mutation.go index 2c69eccc260..76d21af86dd 100644 --- a/graphql/e2e/common/mutation.go +++ b/graphql/e2e/common/mutation.go @@ -2784,10 +2784,8 @@ func deleteGqlType( require.Equal(t, "Deleted", deleteType["msg"], "while deleting %s (filter: %v)", typeName, filter) } - } else { - if diff := cmp.Diff(expectedErrors, gqlResponse.Errors); diff != "" { - t.Errorf("errors mismatch (-want +got):\n%s", diff) - } + } else if diff := cmp.Diff(expectedErrors, gqlResponse.Errors); diff != "" { + t.Errorf("errors mismatch (-want +got):\n%s", diff) } } @@ -3649,3 +3647,37 @@ func checkCascadeWithMutationWithoutIDField(t *testing.T) { filter := map[string]interface{}{"xcode": map[string]interface{}{"eq": "S2"}} deleteState(t, filter, 1, nil) } + +func int64BoundaryTesting(t *testing.T) { + //This test checks the range of Int64 + //(2^63)=9223372036854775808 + addPost1Params := &GraphQLParams{ + Query: `mutation { + addpost1(input: [{title: "Dgraph", numLikes: 9223372036854775807 },{title: "Dgraph1", numLikes: -9223372036854775808 }]) { + post1 { + title + numLikes + } + } + }`, + } + + gqlResponse := addPost1Params.ExecuteAsPost(t, GraphqlURL) + RequireNoGQLErrors(t, gqlResponse) + + addPost1Expected := `{ + "addpost1": { + "post1": [{ + "title": "Dgraph", + "numLikes": 9223372036854775807 + + },{ + "title": "Dgraph1", + "numLikes": -9223372036854775808 + }] + } + }` + testutil.CompareJSON(t, addPost1Expected, string(gqlResponse.Data)) + filter := map[string]interface{}{"title": map[string]interface{}{"regexp": "/Dgraph.*/"}} + deleteGqlType(t, "post1", filter, 2, nil) +} diff --git a/graphql/e2e/directives/schema.graphql b/graphql/e2e/directives/schema.graphql index 3aecf8c7a45..d0f381401ad 100644 --- a/graphql/e2e/directives/schema.graphql +++ b/graphql/e2e/directives/schema.graphql @@ -172,4 +172,9 @@ type Post1 { type Comment1 { id: String! @id replies: [Comment1] +} +type post1{ + id: ID + title: String! @id @search(by: [regexp]) + numLikes: Int64 } \ No newline at end of file diff --git a/graphql/e2e/directives/schema_response.json b/graphql/e2e/directives/schema_response.json index 06442d0df1d..ab1dc660641 100644 --- a/graphql/e2e/directives/schema_response.json +++ b/graphql/e2e/directives/schema_response.json @@ -82,6 +82,17 @@ ], "upsert": true }, + { + "predicate": "post1.title", + "type": "string", + "index": true, + "tokenizer": ["trigram", "hash"], + "upsert": true + }, + { + "predicate": "post1.numLikes", + "type": "int" + }, { "predicate": "State.capital", "type": "string" @@ -449,6 +460,17 @@ ], "name": "Post1" }, + { + "fields": [ + { + "name": "post1.title" + }, + { + "name": "post1.numLikes" + } + ], + "name": "post1" + }, { "fields": [ { diff --git a/graphql/e2e/normal/schema.graphql b/graphql/e2e/normal/schema.graphql index 345e55753a8..2e101d54227 100644 --- a/graphql/e2e/normal/schema.graphql +++ b/graphql/e2e/normal/schema.graphql @@ -172,4 +172,10 @@ type Post1 { type Comment1 { id: String! @id replies: [Comment1] +} + +type post1{ + id: ID + title: String! @id @search(by: [regexp]) + numLikes: Int64 } \ No newline at end of file diff --git a/graphql/e2e/normal/schema_response.json b/graphql/e2e/normal/schema_response.json index 69d8cedf25a..aae7b9d46cb 100644 --- a/graphql/e2e/normal/schema_response.json +++ b/graphql/e2e/normal/schema_response.json @@ -239,6 +239,17 @@ ], "upsert": true }, + { + "predicate": "post1.title", + "type": "string", + "index": true, + "tokenizer": ["trigram", "hash"], + "upsert": true + }, + { + "predicate": "post1.numLikes", + "type": "int" + }, { "predicate": "Starship.length", "type": "float" @@ -537,6 +548,17 @@ ], "name": "Post1" }, + { + "fields": [ + { + "name": "post1.title" + }, + { + "name": "post1.numLikes" + } + ], + "name": "post1" + }, { "fields": [ { diff --git a/graphql/e2e/schema/generatedSchema.graphql b/graphql/e2e/schema/generatedSchema.graphql index f010dc0096b..1b4e05cccb4 100644 --- a/graphql/e2e/schema/generatedSchema.graphql +++ b/graphql/e2e/schema/generatedSchema.graphql @@ -13,8 +13,7 @@ type Author { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/resolve/resolver.go b/graphql/resolve/resolver.go index 121680a9626..3a3d561e776 100644 --- a/graphql/resolve/resolver.go +++ b/graphql/resolve/resolver.go @@ -689,7 +689,9 @@ func completeDgraphResult( // https://graphql.github.io/graphql-spec/June2018/#sec-Query // So we are only building object results. var valToComplete map[string]interface{} - err := json.Unmarshal(dgResult, &valToComplete) + d := json.NewDecoder(bytes.NewBuffer(dgResult)) + d.UseNumber() + err := d.Decode(&valToComplete) if err != nil { glog.Errorf("%+v \n Dgraph result :\n%s\n", errors.Wrap(err, "failed to unmarshal Dgraph query result"), @@ -1460,18 +1462,19 @@ func coerceScalar(val interface{}, field schema.Field, path []interface{}) (inte case bool: val = strconv.FormatBool(v) case string: + case json.Number: + val = v.String() default: return nil, valueCoercionError(v) } case "Boolean": switch v := val.(type) { - case float64: - val = v != 0 - case int64: - val = v != 0 case string: val = len(v) > 0 case bool: + case json.Number: + valFloat, _ := v.Float64() + val = valFloat != 0 default: return nil, valueCoercionError(v) } @@ -1499,12 +1502,12 @@ func coerceScalar(val interface{}, field schema.Field, path []interface{}) (inte case string: i, err := strconv.ParseFloat(v, 64) // An error can be encountered if we had a value that can't be fit into - // a 64 bit floating point number. + // a 64 bit floating point number.. + // Lets try to see if this number could be converted to int32 without losing + // information, otherwise return error. if err != nil { return nil, valueCoercionError(v) } - // Lets try to see if this number could be converted to int32 without losing - // information, otherwise return error. i32Val := int32(i) if i == float64(i32Val) { val = i32Val @@ -1516,32 +1519,28 @@ func coerceScalar(val interface{}, field schema.Field, path []interface{}) (inte return nil, valueCoercionError(v) } case int: - // numUids are added as int, so we need special handling for that. Other number values - // in a JSON object are automatically unmarshalled as float so they are handle above. + // numUids are added as int, so we need special handling for that. if v > math.MaxInt32 || v < math.MinInt32 { return nil, valueCoercionError(v) } + case json.Number: + // We have already checked range for int32 at input validation time. + // So now just parse and check errors. + i, err := strconv.ParseFloat(v.String(), 64) + if err != nil { + return nil, valueCoercionError(v) + } + i32Val := int32(i) + if i == float64(i32Val) { + val = i32Val + } else { + return nil, valueCoercionError(v) + } default: return nil, valueCoercionError(v) } case "Int64": switch v := val.(type) { - case float64: - // The spec says that we can coerce a Float value to Int, if we don't lose information. - // See: https: //spec.graphql.org/June2018/#sec-Float - // See: JSON RFC https://tools.ietf.org/html/rfc8259#section-6, to understand how the - // number type guarantees the correctness of integers only between the range - // [-(2**53)+1, (2**53)-1] and not the range [-(2**63), (2**63)-1]. - // Lets try to see if this number could be converted to int64 without losing - // information, otherwise return error. - // See: https://github.com/golang/go/issues/19405 to understand why the comparison - // should be done after double conversion. - i64Val := int64(v) - if v == float64(i64Val) { - val = i64Val - } else { - return nil, valueCoercionError(v) - } case bool: if v { val = 1 @@ -1549,20 +1548,21 @@ func coerceScalar(val interface{}, field schema.Field, path []interface{}) (inte val = 0 } case string: - i, err := strconv.ParseFloat(v, 64) + i, err := strconv.ParseInt(v, 10, 64) // An error can be encountered if we had a value that can't be fit into - // a 64 bit floating point number. + // a 64 bit int or because of other parsing issues. if err != nil { return nil, valueCoercionError(v) } - // Lets try to see if this number could be converted to int64 without losing - // information, otherwise return error. - i64Val := int64(i) - if i == float64(i64Val) { - val = i64Val - } else { + val = i + case json.Number: + // To use whole 64-bit range for int64 without any coercing, + // We pass int64 values as string to dgraph and parse it as integer here + i, err := strconv.ParseInt(v.String(), 10, 64) + if err != nil { return nil, valueCoercionError(v) } + val = i default: return nil, valueCoercionError(v) } @@ -1576,12 +1576,18 @@ func coerceScalar(val interface{}, field schema.Field, path []interface{}) (inte } case string: i, err := strconv.ParseFloat(v, 64) + // An error can be encountered if we had a value that can't be fit into + // a 64 bit floating point number or because of other parsing issues. + if err != nil { + return nil, valueCoercionError(v) + } + val = i + case json.Number: + i, err := strconv.ParseFloat(v.String(), 64) if err != nil { return nil, valueCoercionError(v) } val = i - case int64: - val = float64(v) case float64: default: return nil, valueCoercionError(v) @@ -1592,18 +1598,16 @@ func coerceScalar(val interface{}, field schema.Field, path []interface{}) (inte if _, err := types.ParseTime(v); err != nil { return nil, valueCoercionError(v) } - case float64: - truncated := math.Trunc(v) - if truncated == v { + case json.Number: + valFloat, _ := v.Float64() + truncated := math.Trunc(valFloat) + if truncated == valFloat { // Lets interpret int values as unix timestamp. t := time.Unix(int64(truncated), 0).UTC() val = t.Format(time.RFC3339) } else { return nil, valueCoercionError(v) } - case int64: - t := time.Unix(v, 0).UTC() - val = t.Format(time.RFC3339) default: return nil, valueCoercionError(v) } diff --git a/graphql/resolve/resolver_test.go b/graphql/resolve/resolver_test.go index 4baf02d6fe7..9b2e5412a89 100644 --- a/graphql/resolve/resolver_test.go +++ b/graphql/resolve/resolver_test.go @@ -209,7 +209,7 @@ func TestValueCoercion(t *testing.T) { GQLQuery: `query { getPost(postID: "0x1") { numLikes } }`, Response: `{ "getPost": { "numLikes": 2147483648 }}`, Errors: x.GqlErrorList{{ - Message: "Error coercing value '2.147483648e+09' for field 'numLikes' to type" + + Message: "Error coercing value '2147483648' for field 'numLikes' to type" + " Int.", Locations: []x.Location{x.Location{Line: 1, Column: 34}}, Path: []interface{}{"getPost", "numLikes"}, diff --git a/graphql/schema/gqlschema.go b/graphql/schema/gqlschema.go index c2924bad1fa..8283b3a80b6 100644 --- a/graphql/schema/gqlschema.go +++ b/graphql/schema/gqlschema.go @@ -64,8 +64,7 @@ const ( schemaExtras = ` """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/rules.go b/graphql/schema/rules.go index b205a8b01db..598dd47af64 100644 --- a/graphql/schema/rules.go +++ b/graphql/schema/rules.go @@ -46,6 +46,7 @@ func init() { validator.AddRule("Check variable type is correct", variableTypeCheck) validator.AddRule("Check for list type value", listTypeCheck) validator.AddRule("Check arguments of cascade directive", directiveArgumentsCheck) + validator.AddRule("Check range for Int type", intRangeCheck) } diff --git a/graphql/schema/testdata/schemagen/output/authorization.graphql b/graphql/schema/testdata/schemagen/output/authorization.graphql index 929b96dbd22..40d883ec06c 100644 --- a/graphql/schema/testdata/schemagen/output/authorization.graphql +++ b/graphql/schema/testdata/schemagen/output/authorization.graphql @@ -24,8 +24,7 @@ type User @auth(update: {rule:"query($X_MyApp_User: String!) { \n queryUser(f """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/comments-and-descriptions.graphql b/graphql/schema/testdata/schemagen/output/comments-and-descriptions.graphql index 16f7417427a..5c9e9ac5d74 100755 --- a/graphql/schema/testdata/schemagen/output/comments-and-descriptions.graphql +++ b/graphql/schema/testdata/schemagen/output/comments-and-descriptions.graphql @@ -29,8 +29,7 @@ enum AnEnum { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/custom-mutation.graphql b/graphql/schema/testdata/schemagen/output/custom-mutation.graphql index 395fdb6d48d..0cef4773bdf 100644 --- a/graphql/schema/testdata/schemagen/output/custom-mutation.graphql +++ b/graphql/schema/testdata/schemagen/output/custom-mutation.graphql @@ -17,8 +17,7 @@ input UserInput { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/custom-nested-types.graphql b/graphql/schema/testdata/schemagen/output/custom-nested-types.graphql index b4f31629419..a5dc6d5a353 100755 --- a/graphql/schema/testdata/schemagen/output/custom-nested-types.graphql +++ b/graphql/schema/testdata/schemagen/output/custom-nested-types.graphql @@ -34,8 +34,7 @@ input CarInput { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/custom-query-mixed-types.graphql b/graphql/schema/testdata/schemagen/output/custom-query-mixed-types.graphql index 78cd24f579d..717d552f506 100644 --- a/graphql/schema/testdata/schemagen/output/custom-query-mixed-types.graphql +++ b/graphql/schema/testdata/schemagen/output/custom-query-mixed-types.graphql @@ -18,8 +18,7 @@ type Car { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/custom-query-not-dgraph-type.graphql b/graphql/schema/testdata/schemagen/output/custom-query-not-dgraph-type.graphql index 8241904cd06..ff36fc162f2 100755 --- a/graphql/schema/testdata/schemagen/output/custom-query-not-dgraph-type.graphql +++ b/graphql/schema/testdata/schemagen/output/custom-query-not-dgraph-type.graphql @@ -17,8 +17,7 @@ input UserInput { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/custom-query-with-dgraph-type.graphql b/graphql/schema/testdata/schemagen/output/custom-query-with-dgraph-type.graphql index 9cf8ce9074b..4ad8c0a7e63 100755 --- a/graphql/schema/testdata/schemagen/output/custom-query-with-dgraph-type.graphql +++ b/graphql/schema/testdata/schemagen/output/custom-query-with-dgraph-type.graphql @@ -13,8 +13,7 @@ type User { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/deprecated.graphql b/graphql/schema/testdata/schemagen/output/deprecated.graphql index b185e731632..bca0475b22a 100755 --- a/graphql/schema/testdata/schemagen/output/deprecated.graphql +++ b/graphql/schema/testdata/schemagen/output/deprecated.graphql @@ -13,8 +13,7 @@ type Atype { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-on-concrete-type-with-interfaces.graphql b/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-on-concrete-type-with-interfaces.graphql index 422fccc2893..e8d3e32dfb4 100755 --- a/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-on-concrete-type-with-interfaces.graphql +++ b/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-on-concrete-type-with-interfaces.graphql @@ -27,8 +27,7 @@ type Director { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-with-interfaces.graphql b/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-with-interfaces.graphql index 0574588e28c..25cdd776ee6 100755 --- a/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-with-interfaces.graphql +++ b/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-with-interfaces.graphql @@ -27,8 +27,7 @@ type Director { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql b/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql index 036b703cfea..68156857f75 100755 --- a/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql @@ -26,8 +26,7 @@ type Genre { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/field-with-reverse-predicate-in-dgraph-directive.graphql b/graphql/schema/testdata/schemagen/output/field-with-reverse-predicate-in-dgraph-directive.graphql index f83d5f14cc3..2281b3549a1 100755 --- a/graphql/schema/testdata/schemagen/output/field-with-reverse-predicate-in-dgraph-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/field-with-reverse-predicate-in-dgraph-directive.graphql @@ -20,8 +20,7 @@ type MovieDirector { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/hasInverse-with-interface-having-directive.graphql b/graphql/schema/testdata/schemagen/output/hasInverse-with-interface-having-directive.graphql index ddf86bd1d19..c09d5eb2942 100755 --- a/graphql/schema/testdata/schemagen/output/hasInverse-with-interface-having-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/hasInverse-with-interface-having-directive.graphql @@ -37,8 +37,7 @@ type Answer implements Post { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/hasInverse-with-interface.graphql b/graphql/schema/testdata/schemagen/output/hasInverse-with-interface.graphql index 2e1d9b1543d..e37c930dfb2 100755 --- a/graphql/schema/testdata/schemagen/output/hasInverse-with-interface.graphql +++ b/graphql/schema/testdata/schemagen/output/hasInverse-with-interface.graphql @@ -38,8 +38,7 @@ type Answer implements Post { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/hasInverse-with-type-having-directive.graphql b/graphql/schema/testdata/schemagen/output/hasInverse-with-type-having-directive.graphql index ddf86bd1d19..c09d5eb2942 100755 --- a/graphql/schema/testdata/schemagen/output/hasInverse-with-type-having-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/hasInverse-with-type-having-directive.graphql @@ -37,8 +37,7 @@ type Answer implements Post { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/hasInverse.graphql b/graphql/schema/testdata/schemagen/output/hasInverse.graphql index e5e2e177320..83c52389c95 100755 --- a/graphql/schema/testdata/schemagen/output/hasInverse.graphql +++ b/graphql/schema/testdata/schemagen/output/hasInverse.graphql @@ -18,8 +18,7 @@ type Author { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/hasInverse_withSubscription.graphql b/graphql/schema/testdata/schemagen/output/hasInverse_withSubscription.graphql index 8989a9e9cdf..d1a73396829 100755 --- a/graphql/schema/testdata/schemagen/output/hasInverse_withSubscription.graphql +++ b/graphql/schema/testdata/schemagen/output/hasInverse_withSubscription.graphql @@ -18,8 +18,7 @@ type Author @withSubscription { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/hasfilter.graphql b/graphql/schema/testdata/schemagen/output/hasfilter.graphql index 59ab0611ec9..2b9ba7ce4f6 100644 --- a/graphql/schema/testdata/schemagen/output/hasfilter.graphql +++ b/graphql/schema/testdata/schemagen/output/hasfilter.graphql @@ -21,8 +21,7 @@ type B { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/ignore-unsupported-directive.graphql b/graphql/schema/testdata/schemagen/output/ignore-unsupported-directive.graphql index 3d60edc73be..d0ffc6ebba4 100755 --- a/graphql/schema/testdata/schemagen/output/ignore-unsupported-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/ignore-unsupported-directive.graphql @@ -20,8 +20,7 @@ type Product { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/interface-with-dgraph-pred.graphql b/graphql/schema/testdata/schemagen/output/interface-with-dgraph-pred.graphql index d8f39daaa5a..c8e94f675d9 100644 --- a/graphql/schema/testdata/schemagen/output/interface-with-dgraph-pred.graphql +++ b/graphql/schema/testdata/schemagen/output/interface-with-dgraph-pred.graphql @@ -27,8 +27,7 @@ interface Person { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/interface-with-id-directive.graphql b/graphql/schema/testdata/schemagen/output/interface-with-id-directive.graphql index c5b731711bf..911ee3c60b4 100755 --- a/graphql/schema/testdata/schemagen/output/interface-with-id-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/interface-with-id-directive.graphql @@ -22,8 +22,7 @@ type Library { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/interface-with-no-ids.graphql b/graphql/schema/testdata/schemagen/output/interface-with-no-ids.graphql index adf90c6c3ba..3b5d2236280 100755 --- a/graphql/schema/testdata/schemagen/output/interface-with-no-ids.graphql +++ b/graphql/schema/testdata/schemagen/output/interface-with-no-ids.graphql @@ -22,8 +22,7 @@ type User { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/interfaces-with-types-and-password.graphql b/graphql/schema/testdata/schemagen/output/interfaces-with-types-and-password.graphql index 23f82803a3b..feafd2d0744 100755 --- a/graphql/schema/testdata/schemagen/output/interfaces-with-types-and-password.graphql +++ b/graphql/schema/testdata/schemagen/output/interfaces-with-types-and-password.graphql @@ -44,8 +44,7 @@ type Starship { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/interfaces-with-types.graphql b/graphql/schema/testdata/schemagen/output/interfaces-with-types.graphql index 03f4eed9588..12d86c414ff 100755 --- a/graphql/schema/testdata/schemagen/output/interfaces-with-types.graphql +++ b/graphql/schema/testdata/schemagen/output/interfaces-with-types.graphql @@ -44,8 +44,7 @@ type Starship { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/no-id-field-with-searchables.graphql b/graphql/schema/testdata/schemagen/output/no-id-field-with-searchables.graphql index 81b5b5e039a..ef815f9fe85 100755 --- a/graphql/schema/testdata/schemagen/output/no-id-field-with-searchables.graphql +++ b/graphql/schema/testdata/schemagen/output/no-id-field-with-searchables.graphql @@ -12,8 +12,7 @@ type Post { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/no-id-field.graphql b/graphql/schema/testdata/schemagen/output/no-id-field.graphql index b2f51d77cc0..12f92532ae5 100755 --- a/graphql/schema/testdata/schemagen/output/no-id-field.graphql +++ b/graphql/schema/testdata/schemagen/output/no-id-field.graphql @@ -24,8 +24,7 @@ type Genre { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/password-type.graphql b/graphql/schema/testdata/schemagen/output/password-type.graphql index ec6427775b5..d996f729f77 100755 --- a/graphql/schema/testdata/schemagen/output/password-type.graphql +++ b/graphql/schema/testdata/schemagen/output/password-type.graphql @@ -13,8 +13,7 @@ type Author @secret(field: "pwd") { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/searchables-references.graphql b/graphql/schema/testdata/schemagen/output/searchables-references.graphql index 0dc75761d55..856db1ba81a 100755 --- a/graphql/schema/testdata/schemagen/output/searchables-references.graphql +++ b/graphql/schema/testdata/schemagen/output/searchables-references.graphql @@ -22,8 +22,7 @@ type Post { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/searchables.graphql b/graphql/schema/testdata/schemagen/output/searchables.graphql index 4a383312264..457d8313dcd 100755 --- a/graphql/schema/testdata/schemagen/output/searchables.graphql +++ b/graphql/schema/testdata/schemagen/output/searchables.graphql @@ -41,8 +41,7 @@ enum PostType { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/single-type-with-enum.graphql b/graphql/schema/testdata/schemagen/output/single-type-with-enum.graphql index 895e0e33fe3..8ef0203bc74 100755 --- a/graphql/schema/testdata/schemagen/output/single-type-with-enum.graphql +++ b/graphql/schema/testdata/schemagen/output/single-type-with-enum.graphql @@ -21,8 +21,7 @@ enum PostType { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/single-type.graphql b/graphql/schema/testdata/schemagen/output/single-type.graphql index 5d0ba3c880b..4b7f1fd8f65 100755 --- a/graphql/schema/testdata/schemagen/output/single-type.graphql +++ b/graphql/schema/testdata/schemagen/output/single-type.graphql @@ -16,8 +16,7 @@ type Message { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/type-implements-multiple-interfaces.graphql b/graphql/schema/testdata/schemagen/output/type-implements-multiple-interfaces.graphql index d0e1c6f79ae..1ba3370981e 100755 --- a/graphql/schema/testdata/schemagen/output/type-implements-multiple-interfaces.graphql +++ b/graphql/schema/testdata/schemagen/output/type-implements-multiple-interfaces.graphql @@ -28,8 +28,7 @@ type Human implements Character & Employee { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/type-reference.graphql b/graphql/schema/testdata/schemagen/output/type-reference.graphql index 0439a5351d2..21ebb8fe84e 100755 --- a/graphql/schema/testdata/schemagen/output/type-reference.graphql +++ b/graphql/schema/testdata/schemagen/output/type-reference.graphql @@ -20,8 +20,7 @@ type Author { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/type-with-arguments-on-field.graphql b/graphql/schema/testdata/schemagen/output/type-with-arguments-on-field.graphql index b9059e12a79..6df90c8e45e 100644 --- a/graphql/schema/testdata/schemagen/output/type-with-arguments-on-field.graphql +++ b/graphql/schema/testdata/schemagen/output/type-with-arguments-on-field.graphql @@ -21,8 +21,7 @@ type Message implements Abstract { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/type-with-custom-field-on-dgraph-type.graphql b/graphql/schema/testdata/schemagen/output/type-with-custom-field-on-dgraph-type.graphql index 2ec4b00a33e..8dcf28d0e01 100644 --- a/graphql/schema/testdata/schemagen/output/type-with-custom-field-on-dgraph-type.graphql +++ b/graphql/schema/testdata/schemagen/output/type-with-custom-field-on-dgraph-type.graphql @@ -20,8 +20,7 @@ type User { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/testdata/schemagen/output/type-with-custom-fields-on-remote-type.graphql b/graphql/schema/testdata/schemagen/output/type-with-custom-fields-on-remote-type.graphql index 89738e406fb..52edccb256d 100644 --- a/graphql/schema/testdata/schemagen/output/type-with-custom-fields-on-remote-type.graphql +++ b/graphql/schema/testdata/schemagen/output/type-with-custom-fields-on-remote-type.graphql @@ -20,8 +20,7 @@ type User { """ The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. -Int64 can currently represent values in range [-(2^53)+1, (2^53)-1] without any error. -Values out of this range but representable by a signed 64-bit integer, may get coercion error. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. """ scalar Int64 diff --git a/graphql/schema/validation_rules.go b/graphql/schema/validation_rules.go index 6ab52337ddc..8e913f59b6b 100644 --- a/graphql/schema/validation_rules.go +++ b/graphql/schema/validation_rules.go @@ -17,6 +17,9 @@ package schema import ( + "errors" + "strconv" + "github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/validator" ) @@ -53,7 +56,6 @@ func variableTypeCheck(observers *validator.Events, addError validator.AddErrFun if value.Kind != ast.Variable { return } - if value.VariableDefinition.Type.IsCompatible(value.ExpectedType) { return } @@ -89,3 +91,69 @@ func directiveArgumentsCheck(observers *validator.Events, addError validator.Add }) } + +func intRangeCheck(observers *validator.Events, addError validator.AddErrFunc) { + observers.OnValue(func(walker *validator.Walker, value *ast.Value) { + if value.Definition == nil || value.ExpectedType == nil || value.Kind == ast.Variable { + return + } + + switch value.Definition.Name { + case "Int": + if value.Kind == ast.NullValue { + return + } + _, err := strconv.ParseInt(value.Raw, 10, 32) + if err != nil { + if errors.Is(err, strconv.ErrRange) { + addError(validator.Message("Out of range value '%s', for type `%s`", + value.Raw, value.Definition.Name), validator.At(value.Position)) + } else { + addError(validator.Message("%s", err), validator.At(value.Position)) + } + } + case "Int64": + if value.Kind == ast.IntValue { + _, err := strconv.ParseInt(value.Raw, 10, 64) + if err != nil { + if errors.Is(err, strconv.ErrRange) { + addError(validator.Message("Out of range value '%s', for type `%s`", + value.Raw, value.Definition.Name), validator.At(value.Position)) + } else { + addError(validator.Message("%s", err), validator.At(value.Position)) + } + } + value.Kind = ast.StringValue + } else { + addError(validator.Message("Type mismatched for Value `%s`, expected: Int64, got: '%s'", value.Raw, + valueKindToString(value.Kind)), validator.At(value.Position)) + } + } + }) +} + +func valueKindToString(valKind ast.ValueKind) string { + switch valKind { + case ast.Variable: + return "Variable" + case ast.StringValue: + return "String" + case ast.IntValue: + return "Int" + case ast.FloatValue: + return "Float" + case ast.BlockValue: + return "Block" + case ast.BooleanValue: + return "Boolean" + case ast.NullValue: + return "Null" + case ast.EnumValue: + return "Enum" + case ast.ListValue: + return "List" + case ast.ObjectValue: + return "Object" + } + return "" +} \ No newline at end of file