Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

graphql: Coerce value for scalar types correctly. #5487

Merged
merged 11 commits into from
May 28, 2020

Conversation

pawanrawal
Copy link
Contributor

@pawanrawal pawanrawal commented May 20, 2020

Fixes GRAPHQL-382


This change is Reviewable

@github-actions github-actions bot added the area/graphql Issues related to GraphQL support on Dgraph. label May 20, 2020
@pawanrawal pawanrawal marked this pull request as ready for review May 21, 2020 12:43
Copy link
Contributor

@abhimanyusinghgaur abhimanyusinghgaur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 7 of 7 files at r1.
Reviewable status: all files reviewed, 9 unresolved discussions (waiting on @harshil-goel, @MichaelJCompton, and @pawanrawal)


graphql/resolve/resolver.go, line 1341 at r1 (raw file):

Quoted 4 lines of code…
			case float64:
				val = v > 0
			case int64:
				val = v > 0

It will give false for negative numbers too.
For Boolean, the example GraphQL spec proposes is: returning true for non‐zero numbers, although its not mandatory to follow.
So, should we change the condition to: v != 0?


graphql/resolve/resolver.go, line 1362 at r1 (raw file):

				}
			case bool:
				if !v {

A simplification:

if v {
   val = 1
} else {
   val = 0
}

graphql/resolve/resolver.go, line 1398 at r1 (raw file):

			switch v := val.(type) {
			case bool:
				if !v {

Simplification possible.


graphql/resolve/resolver.go, line 1415 at r1 (raw file):

				return nil, valueCoercionError(v)
			}
		case "DateTime":

can we consider int64 as time since Epoch and parse it as DateTime instead of giving coercion error?


graphql/resolve/resolver.go, line 1449 at r1 (raw file):

		}

		// val is a scalar

We should move this comment at the top of this newly inserted code block.


graphql/resolve/resolver.go, line 1453 at r1 (raw file):

		// Can this ever error?  We can't have an unsupported type or value because
		// we just unmarshaled this val.
		json, err := json.Marshal(val)

Unrelated, but my IDE gives me this warning:
Variable 'json' collides with imported package name

We should rename it to something like b.


graphql/resolve/resolver_test.go, line 143 at r1 (raw file):

			}},
			Expected: `{"getPost": {"numLikes": null}}`,
		},

Also, a test case for when we can't coerce an int value which is out of range of int32 to Int.


graphql/resolve/resolver_test.go, line 175 at r1 (raw file):

		// test bool/int/string/datetime can be coerced to Datetime
		{Name: "int value should raise an error when tried to be coerced to datetime",

this will change if we interpret int as time since Epoch.


graphql/resolve/resolver_test.go, line 204 at r1 (raw file):

		{Name: "invalid string value should raise an error when tried to be coerced to datetime",
			GQLQuery: `query { getAuthor(id: "0x1") { dob } }`,
			Response: `{ "getAuthor": { "dob": "123" }}`,

If we are interpreting int as time since Epoch, then I guess this should also change, and should have a different case to show the error.

Copy link
Contributor

@abhimanyusinghgaur abhimanyusinghgaur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing is, while validating remote schema for @custom graphql, currently we mandate exact type match. We should create a task for that too, to respect coercion once this is merged.

Reviewable status: all files reviewed, 9 unresolved discussions (waiting on @harshil-goel, @MichaelJCompton, and @pawanrawal)

Copy link
Contributor Author

@pawanrawal pawanrawal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will do once I understand it better.

Reviewable status: all files reviewed, 9 unresolved discussions (waiting on @abhimanyusinghgaur, @harshil-goel, and @MichaelJCompton)


graphql/resolve/resolver.go, line 1341 at r1 (raw file):

Previously, abhimanyusinghgaur (Abhimanyu Singh Gaur) wrote…
			case float64:
				val = v > 0
			case int64:
				val = v > 0

It will give false for negative numbers too.
For Boolean, the example GraphQL spec proposes is: returning true for non‐zero numbers, although its not mandatory to follow.
So, should we change the condition to: v != 0?

yeah good one


graphql/resolve/resolver.go, line 1362 at r1 (raw file):

Previously, abhimanyusinghgaur (Abhimanyu Singh Gaur) wrote…

A simplification:

if v {
   val = 1
} else {
   val = 0
}

Done.


graphql/resolve/resolver.go, line 1398 at r1 (raw file):

Previously, abhimanyusinghgaur (Abhimanyu Singh Gaur) wrote…

Simplification possible.

Done.


graphql/resolve/resolver.go, line 1415 at r1 (raw file):

Previously, abhimanyusinghgaur (Abhimanyu Singh Gaur) wrote…

can we consider int64 as time since Epoch and parse it as DateTime instead of giving coercion error?

Done.


graphql/resolve/resolver.go, line 1449 at r1 (raw file):

Previously, abhimanyusinghgaur (Abhimanyu Singh Gaur) wrote…

We should move this comment at the top of this newly inserted code block.

Done.


graphql/resolve/resolver.go, line 1453 at r1 (raw file):

Previously, abhimanyusinghgaur (Abhimanyu Singh Gaur) wrote…

Unrelated, but my IDE gives me this warning:
Variable 'json' collides with imported package name

We should rename it to something like b.

Done.


graphql/resolve/resolver_test.go, line 143 at r1 (raw file):

Previously, abhimanyusinghgaur (Abhimanyu Singh Gaur) wrote…

Also, a test case for when we can't coerce an int value which is out of range of int32 to Int.

good idea, done


graphql/resolve/resolver_test.go, line 175 at r1 (raw file):

Previously, abhimanyusinghgaur (Abhimanyu Singh Gaur) wrote…

this will change if we interpret int as time since Epoch.

Done.


graphql/resolve/resolver_test.go, line 204 at r1 (raw file):

Previously, abhimanyusinghgaur (Abhimanyu Singh Gaur) wrote…

If we are interpreting int as time since Epoch, then I guess this should also change, and should have a different case to show the error.

I think we should continue parsing string values as datetime and don't need to support multiple formats. I have support the format of unix timestamp for int/float values.

Copy link
Contributor

@abhimanyusinghgaur abhimanyusinghgaur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewed 2 of 2 files at r2.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @harshil-goel and @MichaelJCompton)

Copy link
Contributor

@MichaelJCompton MichaelJCompton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewable status: 5 of 7 files reviewed, 4 unresolved discussions (waiting on @abhimanyusinghgaur, @harshil-goel, and @pawanrawal)


graphql/resolve/resolver.go, line 1317 at r3 (raw file):

		// val is a scalar

Is it possible to put this all in a function coerceScalar ?


graphql/resolve/resolver.go, line 1356 at r3 (raw file):

			case float64:
				// Lets try to see if this a whole number, otherwise return error because we
				// might be losing informating by truncating it.

Is this how the spec asks for it to be done? That's a general question - maybe just add a link to the spot in the spec at the top of these changes.


graphql/resolve/resolver.go, line 1393 at r3 (raw file):

				}
			case int:
				// numUids are added as int, so we need special handling for that.

should we be adding them as something else?


graphql/resolve/resolver_test.go, line 186 at r3 (raw file):

			Expected: `{ "getAuthor": { "reputation": 0.0}}`},

		// test bool/int/string/datetime can be coerced to Datetime

these are cool - ints as timestamps

Copy link
Contributor Author

@pawanrawal pawanrawal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 5 of 7 files reviewed, 4 unresolved discussions (waiting on @abhimanyusinghgaur, @harshil-goel, and @MichaelJCompton)


graphql/resolve/resolver.go, line 1317 at r3 (raw file):

Previously, MichaelJCompton (Michael Compton) wrote…

Is it possible to put this all in a function coerceScalar ?

Done.


graphql/resolve/resolver.go, line 1356 at r3 (raw file):

Previously, MichaelJCompton (Michael Compton) wrote…

Is this how the spec asks for it to be done? That's a general question - maybe just add a link to the spot in the spec at the top of these changes.

Yes, Done.


graphql/resolve/resolver.go, line 1393 at r3 (raw file):

Previously, MichaelJCompton (Michael Compton) wrote…

should we be adding them as something else?

Nope, its ok. We don't need this case for other values coming from Dgraph result or from an external endpoint as a JSON number is unmarshaled to float.


graphql/resolve/resolver_test.go, line 186 at r3 (raw file):

Previously, MichaelJCompton (Michael Compton) wrote…

these are cool - ints as timestamps

yeah

@pawanrawal pawanrawal merged commit 1444f00 into master May 28, 2020
@pawanrawal pawanrawal deleted the pawanrawal/graphql-382 branch May 28, 2020 05:47
dna2github pushed a commit to dna2fork/dgraph that referenced this pull request Jul 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/graphql Issues related to GraphQL support on Dgraph.
Development

Successfully merging this pull request may close these issues.

3 participants