-
-
Notifications
You must be signed in to change notification settings - Fork 0
Question mark sn #3
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
base: semantic-non-null
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -1224,6 +1224,8 @@ that variable, that operation is invalid (see | |||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
## Type References | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
### In traditional nullability mode | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
Type : | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- NamedType | ||||||||||||||||||||||||||||||||||
|
@@ -1239,10 +1241,49 @@ NonNullType : | |||||||||||||||||||||||||||||||||
- NamedType ! | ||||||||||||||||||||||||||||||||||
- ListType ! | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
**Semantics** | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
Type : Name | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Let {name} be the string value of {Name} | ||||||||||||||||||||||||||||||||||
- Let {type} be the type defined in the Schema named {name} | ||||||||||||||||||||||||||||||||||
- {type} must not be {null} | ||||||||||||||||||||||||||||||||||
- Return {type} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
Type : [ Type ] | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Let {itemType} be the result of evaluating {Type} | ||||||||||||||||||||||||||||||||||
- Let {type} be a List type where {itemType} is the contained type. | ||||||||||||||||||||||||||||||||||
- Return {type} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
Type : Type ! | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Let {nullableType} be the result of evaluating {Type} | ||||||||||||||||||||||||||||||||||
- Let {type} be a Non-Null type where {nullableType} is the contained type. | ||||||||||||||||||||||||||||||||||
- Return {type} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
### In semantic nullability mode | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
Type : | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- NamedType | ||||||||||||||||||||||||||||||||||
- ListType | ||||||||||||||||||||||||||||||||||
- NonNullType | ||||||||||||||||||||||||||||||||||
- SemanticNonNullType | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
NamedType : Name ? | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
ListType : [ Type ] | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
NonNullType : | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Name ! | ||||||||||||||||||||||||||||||||||
- ListType ! | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
SemanticNonNullType : | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- ! NamedType | ||||||||||||||||||||||||||||||||||
- ! ListType | ||||||||||||||||||||||||||||||||||
- Name [lookahead != `?`] [lookahead != `!`] | ||||||||||||||||||||||||||||||||||
- ListType [lookahead != `?`] [lookahead != `!`] | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
GraphQL describes the types of data expected by arguments and variables. Input | ||||||||||||||||||||||||||||||||||
types may be lists of another input type, or a non-null variant of any other | ||||||||||||||||||||||||||||||||||
|
@@ -1257,6 +1298,17 @@ Type : Name | |||||||||||||||||||||||||||||||||
- {type} must not be {null} | ||||||||||||||||||||||||||||||||||
- Return {type} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
Type : Type ? | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Let {nullableType} be the result of evaluating {Type} | ||||||||||||||||||||||||||||||||||
- Return {nullableType} | ||||||||||||||||||||||||||||||||||
Comment on lines
+1301
to
+1304
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is really confusing; I think delete the
Suggested change
|
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
Type : Type [lookahead != `?`] [lookahead != `!`] | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Let {nullableType} be the result of evaluating {Type} | ||||||||||||||||||||||||||||||||||
- Let {type} be a Semantically-Non-Null type where {nullableType} is the contained type. | ||||||||||||||||||||||||||||||||||
- Return {type} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
Type : [ Type ] | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
- Let {itemType} be the result of evaluating {Type} | ||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -1905,18 +1905,17 @@ Following are examples of result coercion with various types and values: | |||||||||
The GraphQL Semantic-Non-Null type is an alternative to the GraphQL Non-Null | ||||||||||
type to disallow null unless accompanied by a field error. This type wraps an | ||||||||||
underlying type, and this type acts identically to that wrapped type, with the | ||||||||||
exception that {null} will result in a field error being raised. A leading | ||||||||||
exclamation mark is used to denote a field that uses a Semantic-Non-Null type | ||||||||||
like this: `name: !String`. | ||||||||||
|
||||||||||
exception that {null} will result in a field error being raised. Semantic-Non-Null | ||||||||||
types are only valid in a document that also contains a `@SemanticNullability` | ||||||||||
document-level directive. In such a document, Semantic-Non-Null fields have no | ||||||||||
adornment, much like nullable fields in documents without that directive. | ||||||||||
Comment on lines
+1908
to
+1911
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The type system should be valid without reference to documents; support for SDL is optional. |
||||||||||
For example: `name: String`. | ||||||||||
|
||||||||||
In docuements with a `@SemanticNullability` directive, input types are unaltered in | ||||||||||
terms of syntax. Unadorned types still represent nullable input types. | ||||||||||
Comment on lines
+1914
to
+1915
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wait so unadorned is nullable on input but non-null on output? What about if we add something like struct in future that allows the same composite type to be represented on both input and output - you're saying that the input field is allowed to be null, but when it's presented through output it would cause a non-null error to be raised? @semanticNullability
struct Struct {
nullable: Int?
semanticNonNull: Int
strictNonNull: Int!
}
type Query {
identity(struct: Struct): Struct
}
query {
# Valid input since unadorned is nullable on input?
identity(struct: { nullable: null, semanticNonNull: null, strictNonNull: 0 }) {
nullable
# Identity produces error here?
semanticNonNull
strictNonNull
}
} |
||||||||||
Semantic-Non-Null types are only valid for use as an _output type_; they must | ||||||||||
not be used as an _input type_. | ||||||||||
|
||||||||||
**Nullable vs. Optional** | ||||||||||
|
||||||||||
Fields that return Semantic-Non-Null types will never return the value {null} if | ||||||||||
queried _unless_ an error has been logged for that field. | ||||||||||
|
||||||||||
**Result Coercion** | ||||||||||
|
||||||||||
To coerce the result of a Semantic-Non-Null type, the coercion of the wrapped | ||||||||||
|
@@ -1947,35 +1946,35 @@ complex types. The rules for result coercion of Lists and Semantic-Non-Null | |||||||||
types apply in a recursive fashion. | ||||||||||
|
||||||||||
For example if the inner item type of a List is Semantic-Non-Null (e.g. `[!T]`), | ||||||||||
then that List may not contain any {null} items unless associated field errors | ||||||||||
were raised. However if the inner type of a Semantic-Non-Null is a List (e.g. | ||||||||||
then if that list contains any nulls without associated errors, then field errors will be raised. | ||||||||||
However if the inner type of a Semantic-Non-Null is a List (e.g. | ||||||||||
`![T]`), then {null} is not accepted without an accompanying field error being | ||||||||||
raised, however an empty list is accepted. | ||||||||||
|
||||||||||
Following are examples of result coercion with various types and values: | ||||||||||
|
||||||||||
| Expected Type | Internal Value | Coerced Result | | ||||||||||
| ------------- | --------------- | ------------------------------------------- | | ||||||||||
| `![Int]` | `[1, 2, 3]` | `[1, 2, 3]` | | ||||||||||
| `![Int]` | `null` | `null` (With logged coercion error) | | ||||||||||
| `![Int]` | `[1, 2, null]` | `[1, 2, null]` | | ||||||||||
| `![Int]` | `[1, 2, Error]` | `[1, 2, null]` (With logged error) | | ||||||||||
| `![Int!]` | `[1, 2, 3]` | `[1, 2, 3]` | | ||||||||||
| `![Int!]` | `null` | `null` (With logged coercion error) | | ||||||||||
| `![Int!]` | `[1, 2, null]` | `null` (With logged coercion error) | | ||||||||||
| `![Int!]` | `[1, 2, Error]` | `null` (With logged error) | | ||||||||||
| `[!Int]` | `[1, 2, 3]` | `[1, 2, 3]` | | ||||||||||
| `[!Int]` | `null` | `null` | | ||||||||||
| `[!Int]` | `[1, 2, null]` | `[1, 2, null]` (With logged coercion error) | | ||||||||||
| `[!Int]` | `[1, 2, Error]` | `[1, 2, null]` (With logged error) | | ||||||||||
| `[!Int]!` | `[1, 2, 3]` | `[1, 2, 3]` | | ||||||||||
| `[!Int]!` | `null` | Error: Value cannot be null | | ||||||||||
| `[!Int]!` | `[1, 2, null]` | `[1, 2, null]` (With logged coercion error) | | ||||||||||
| `[!Int]!` | `[1, 2, Error]` | `[1, 2, null]` (With logged error) | | ||||||||||
| `![!Int]` | `[1, 2, 3]` | `[1, 2, 3]` | | ||||||||||
| `![!Int]` | `null` | `null` (With logged coercion error) | | ||||||||||
| `![!Int]` | `[1, 2, null]` | `[1, 2, null]` (With logged coercion error) | | ||||||||||
| `![!Int]` | `[1, 2, Error]` | `[1, 2, null]` (With logged error) | | ||||||||||
| `[Int]` | `[1, 2, 3]` | `[1, 2, 3]` | | ||||||||||
| `[Int]` | `null` | `null` (With logged coercion error) | | ||||||||||
| `[Int]` | `[1, 2, null]` | `[1, 2, null]` | | ||||||||||
| `[Int]` | `[1, 2, Error]` | `[1, 2, null]` (With logged error) | | ||||||||||
| `[Int!]` | `[1, 2, 3]` | `[1, 2, 3]` | | ||||||||||
| `[Int!]` | `null` | `null` (With logged coercion error) | | ||||||||||
| `[Int!]` | `[1, 2, null]` | `null` (With logged coercion error) | | ||||||||||
| `[Int!]` | `[1, 2, Error]` | `null` (With logged error) | | ||||||||||
| `[Int]` | `[1, 2, 3]` | `[1, 2, 3]` | | ||||||||||
| `[Int]` | `null` | `null` | | ||||||||||
| `[Int]` | `[1, 2, null]` | `[1, 2, null]` (With logged coercion error) | | ||||||||||
| `[Int]` | `[1, 2, Error]` | `[1, 2, null]` (With logged error) | | ||||||||||
| `[Int]!` | `[1, 2, 3]` | `[1, 2, 3]` | | ||||||||||
| `[Int]!` | `null` | Error: Value cannot be null | | ||||||||||
| `[Int]!` | `[1, 2, null]` | `[1, 2, null]` (With logged coercion error) | | ||||||||||
| `[Int]!` | `[1, 2, Error]` | `[1, 2, null]` (With logged error) | | ||||||||||
| `[Int]` | `[1, 2, 3]` | `[1, 2, 3]` | | ||||||||||
| `[Int]` | `null` | `null` (With logged coercion error) | | ||||||||||
| `[Int]` | `[1, 2, null]` | `[1, 2, null]` (With logged coercion error) | | ||||||||||
| `[Int]` | `[1, 2, Error]` | `[1, 2, null]` (With logged error) | | ||||||||||
|
||||||||||
## Directives | ||||||||||
|
||||||||||
|
@@ -2016,6 +2015,7 @@ TypeSystemDirectiveLocation : one of | |||||||||
- `ENUM_VALUE` | ||||||||||
- `INPUT_OBJECT` | ||||||||||
- `INPUT_FIELD_DEFINITION` | ||||||||||
- `DOCUMENT` | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we extract document level directives to a separate spec PR, it seems to be lumped in here but sounds like a meaningful addition in the grander scheme either way There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah truthfully we could also do no null propagation mode as it's own PR as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These should indeed be separate PRs 👍 |
||||||||||
|
||||||||||
A GraphQL schema describes directives which are used to annotate various parts | ||||||||||
of a GraphQL document as an indicator that they should be evaluated differently | ||||||||||
|
@@ -2025,7 +2025,8 @@ by a validator, executor, or client tool such as a code generator. | |||||||||
|
||||||||||
:: A _built-in directive_ is any directive defined within this specification. | ||||||||||
|
||||||||||
GraphQL implementations should provide the `@skip` and `@include` directives. | ||||||||||
GraphQL implementations should provide the `@skip`, `@include`, and | ||||||||||
`@semanticNullability` directives. | ||||||||||
|
||||||||||
GraphQL implementations that support the type system definition language must | ||||||||||
provide the `@deprecated` directive if representing deprecated portions of the | ||||||||||
|
@@ -2180,6 +2181,20 @@ the `@include` condition is true. Stated conversely, the field or fragment must | |||||||||
_not_ be queried if either the `@skip` condition is true _or_ the `@include` | ||||||||||
condition is false. | ||||||||||
|
||||||||||
### @semanticNullability | ||||||||||
|
||||||||||
```graphql | ||||||||||
directive @semanticNullability on DOCUMENT | ||||||||||
``` | ||||||||||
|
||||||||||
The `@semanticNullability` _built-in directive_ may be provided for documents, | ||||||||||
and causes GraphQL to interpret nullability in that document based on the rules | ||||||||||
for Semantic Nullability. In that document an unadorned named type will be treated | ||||||||||
as if it is wrapped with the Semantic-Non-Null type. Any fields adorned with a question | ||||||||||
mark ie `name: Type?` will be treated as a named nullable type. | ||||||||||
|
||||||||||
An unadorned input type will be treated as a nullable type. | ||||||||||
|
||||||||||
### @deprecated | ||||||||||
|
||||||||||
```graphql | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you want to delete this semantic block