From 44547fe45b0720d62ed567a7d687647d95f3dd2a Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Fri, 24 Nov 2023 10:53:51 +0000 Subject: [PATCH] Change name to 'SemanticNonNull' and syntax to bang prefix --- spec/Section 2 -- Language.md | 6 +- spec/Section 3 -- Type System.md | 92 +++++++++++++++--------------- spec/Section 4 -- Introspection.md | 44 +++++++------- spec/Section 6 -- Execution.md | 6 +- 4 files changed, 73 insertions(+), 75 deletions(-) diff --git a/spec/Section 2 -- Language.md b/spec/Section 2 -- Language.md index 1a8088906..f5e245ab3 100644 --- a/spec/Section 2 -- Language.md +++ b/spec/Section 2 -- Language.md @@ -1239,10 +1239,10 @@ NonNullType : - NamedType ! - ListType ! -NullOnlyOnErrorType : +SemanticNonNullType : -- NamedType \* -- ListType \* +- ! NamedType +- ! ListType 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 diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index beee413ae..967e806a5 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -1859,7 +1859,7 @@ non-null input type as invalid. **Type Validation** 1. A Non-Null type must not wrap another Non-Null type. -1. A Non-Null type must not wrap a Null-Only-On-Error type. +1. A Non-Null type must not wrap a Semantic-Non-Null type. ### Combining List and Non-Null @@ -1893,31 +1893,31 @@ Following are examples of result coercion with various types and values: | `[Int!]!` | `[1, 2, null]` | Error: Item cannot be null | | `[Int!]!` | `[1, 2, Error]` | Error: Error occurred in item | -## Null-Only-On-Error +## Semantic-Non-Null -The GraphQL Null-Only-On-Error type is an alternative to the GraphQL Non-Null +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 trailing -asterisk is used to denote a field that uses a Null-Only-On-Error type like -this: `name: String*`. +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`. -Null-Only-On-Error types are only valid for use as an _output type_; they must +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 Null-Only-On-Error types will never return the value {null} -if queried _unless_ an error has been logged for that field. +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 Null-Only-On-Error type, the coercion of the wrapped -type should be performed. If that result was not {null}, then the result of -coercing the Null-Only-On-Error type is that result. If that result was {null}, -then a _field error_ must be raised. +To coerce the result of a Null-Semantic-Non-Null type, the coercion of the +wrapped type should be performed. If that result was not {null}, then the result +of coercing the Semantic-Non-Null type is that result. If that result was +{null}, then a _field error_ must be raised. -Note: When a _field error_ is raised on a Null-Only-On-Error value, the error +Note: When a _field error_ is raised on a Semantic-Non-Null value, the error does not propagate to the parent field, instead {null} is used for the value. For more information on this process, see [Handling Field Errors](#sec-Handling-Field-Errors) within the Execution @@ -1925,50 +1925,50 @@ section. **Input Coercion** -Null-Only-On-Error types are never valid inputs. +Semantic-Non-Null types are never valid inputs. **Type Validation** -1. A Null-Only-On-Error type must wrap an _output type_. -1. A Null-Only-On-Error type must not wrap another Null-Only-On-Error type. -1. A Null-Only-On-Error type must not wrap a Non-Null type. +1. A Semantic-Non-Null type must wrap an _output type_. +1. A Semantic-Non-Null type must not wrap another Semantic-Non-Null type. +1. A Semantic-Non-Null type must not wrap a Non-Null type. -### Combining List and Null-Only-On-Error +### Combining List and Semantic-Non-Null -The List and Null-Only-On-Error wrapping types can compose, representing more -complex types. The rules for result coercion of Lists and Null-Only-On-Error +The List and Semantic-Non-Null wrapping types can compose, representing more +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 Null-Only-On-Error (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 Null-Only-On-Error is a List -(e.g. `[T]*`), then {null} is not accepted without an accompanying field error -being raised, however an empty list is accepted. +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. +`![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 diff --git a/spec/Section 4 -- Introspection.md b/spec/Section 4 -- Introspection.md index 1d82a1b08..d1bc07aff 100644 --- a/spec/Section 4 -- Introspection.md +++ b/spec/Section 4 -- Introspection.md @@ -162,14 +162,14 @@ enum __TypeKind { INPUT_OBJECT LIST NON_NULL - NULL_ONLY_ON_ERROR + SEMANTIC_NON_NULL } type __Field { name: String! description: String args(includeDeprecated: Boolean = false): [__InputValue!]! - type(includeNullOnlyOnError: Boolean! = false): __Type! + type(includeSemanticNonNull: Boolean! = false): __Type! isDeprecated: Boolean! deprecationReason: String } @@ -264,7 +264,7 @@ possible value of the `__TypeKind` enum: - {"INPUT_OBJECT"} - {"LIST"} - {"NON_NULL"} -- {"NULL_ONLY_ON_ERROR"} +- {"SEMANTIC_NON_NULL"} **Scalar** @@ -403,34 +403,32 @@ required inputs for arguments and input object fields. The modified type in the `ofType` field may itself be a modified List type, allowing the representation of Non-Null of Lists. However it must not be a modified Non-Null type to avoid a redundant Non-Null of Non-Null; nor may it be -a modified Null-Only-On-Error type since these types are mutually exclusive. +a modified Semantic-Non-Null type since these types are mutually exclusive. Fields\: - `kind` must return `__TypeKind.NON_NULL`. -- `ofType` must return a type of any kind except Non-Null and - Null-Only-On-Error. +- `ofType` must return a type of any kind except Non-Null and Semantic-Non-Null. - All other fields must return {null}. -**Null-Only-On-Error** +**Semantic-Non-Null** GraphQL types are nullable. The value {null} is a valid response for field type. -A Null-Only-On-Error type is a type modifier: it wraps another _output type_ -instance in the `ofType` field. Null-Only-On-Error types do not allow {null} as -a response _unless_ an associated _field error_ has been raised. +A Semantic-Non-Null type is a type modifier: it wraps another _output type_ +instance in the `ofType` field. Semantic-Non-Null types do not allow {null} as a +response _unless_ an associated _field error_ has been raised. The modified type in the `ofType` field may itself be a modified List type, -allowing the representation of Null-Only-On-Error of Lists. However it must not -be a modified Null-Only-On-Error type to avoid a redundant Null-Only-On-Error of -Null-Only-On-Error; nor may it be a modified Non-Null type since these types are +allowing the representation of Semantic-Non-Null of Lists. However it must not +be a modified Semantic-Non-Null type to avoid a redundant Null-Only-On-Error of +Semantic-Non-Null; nor may it be a modified Non-Null type since these types are mutually exclusive. Fields\: -- `kind` must return `__TypeKind.NULL_ONLY_ON_ERROR`. -- `ofType` must return a type of any kind except Non-Null and - Null-Only-On-Error. +- `kind` must return `__TypeKind.SEMANTIC_NON_NULL`. +- `ofType` must return a type of any kind except Non-Null and Semantic-Non-Null. - All other fields must return {null}. ### The \_\_Field Type @@ -447,24 +445,24 @@ Fields\: {true}, deprecated arguments are also returned. - `type` must return a `__Type` that represents the type of value returned by this field. - - Accepts the argument `includeNullOnlyOnError` which defaults to {false}. If + - Accepts the argument `includeSemanticNonNull` which defaults to {false}. If {false}, let {fieldType} be the type of value returned by this field and instead return a `__Type` that represents - {RecursivelyStripNullOnlyOnErrorTypes(fieldType)}. + {RecursivelyStripSemanticNonNullTypes(fieldType)}. - `isDeprecated` returns {true} if this field should no longer be used, otherwise {false}. - `deprecationReason` optionally provides a reason why this field is deprecated. -RecursivelyStripNullOnlyOnErrorTypes(type): +RecursivelyStripSemanticNonNullTypes(type): -- If {type} is a Null-Only-On-Error type: +- If {type} is a Semantic-Non-Null type: - Let {innerType} be the inner type of {type}. - - Return {RecursivelyStripNullOnlyOnErrorTypes(innerType)}. + - Return {RecursivelyStripSemanticNonNullTypes(innerType)}. - Otherwise, return {type}. -Note: This algorithm recursively removes all Null-Only-On-Error type wrappers +Note: This algorithm recursively removes all Semantic-Non-Null type wrappers (e.g. `[[Int*]!]*` would become `[[Int]!]`). This is to support legacy clients: -they can safely treat a Null-Only-On-Error type as the underlying nullable type. +they can safely treat a Semantic-Non-Null type as the underlying nullable type. ### The \_\_InputValue Type diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index f0d06c1d8..4e7bd0571 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -670,7 +670,7 @@ field execution process continues recursively. CompleteValue(fieldType, fields, result, variableValues): -- If the {fieldType} is a Non-Null or a Null-Only-On-Error type: +- If the {fieldType} is a Non-Null or a Semantic-Non-Null type: - Let {innerType} be the inner type of {fieldType}. - Let {completedResult} be the result of calling {CompleteValue(innerType, fields, result, variableValues)}. @@ -806,5 +806,5 @@ If all fields from the root of the request to the source of the field error return `Non-Null` types, then the {"data"} entry in the response should be {null}. -Note: By the above, field errors that happen in `Null-Only-On-Error` types do -not propagate. +Note: By the above, field errors that happen in `Semantic-Non-Null` types do not +propagate.