From 6e49337e9f1927163c19060cb5985fb08b2379f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Mon, 27 Nov 2023 13:36:21 +0100 Subject: [PATCH 01/22] `$Apply` and `$Function` in Appendix B (#216) --- docs/odata-csdl-json/odata-csdl-json.html | 33 +++++++++++----------- docs/odata-csdl-json/odata-csdl-json.md | 31 ++++++++++---------- odata-csdl/14 Vocabulary and Annotation.md | 3 +- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html index cba9575d1..ad3eaa72b 100644 --- a/docs/odata-csdl-json/odata-csdl-json.html +++ b/docs/odata-csdl-json/odata-csdl-json.html @@ -2979,8 +2979,8 @@

14.4.4 Apply Client-Side Functions

The apply expression enables a value to be obtained by applying a client-side function. The apply expression MAY have operand expressions. The operand expressions are used as parameters to the client-side function.

-
-

$Apply

+
+

$Apply and $Function

Apply expressions are represented as an object with a member $Apply whose value is an array of annotation expressions, and a member $Function whose value is a string containing the qualified name of the client-side function to be applied.

It MAY contain annotations.

@@ -3073,7 +3073,7 @@

14.4.5 Cast

The cast expression casts the value obtained from its single child expression to the specified type. The cast expression follows the same rules as the cast canonical function defined in OData-URL.

-

$Cast

+

$Cast

Cast expressions are represented as an object with a member $Cast whose value is an annotation expression, a member $Type whose value is a string containing the qualified type name, and optionally a member $Collection with a value of true.

It MAY contain annotations.

If the specified type is a primitive type or a collection of primitive types, the facet members $MaxLength, $Unicode, $Precision, $Scale, and $SRID MAY be specified if applicable to the specified primitive type. If the facet members are not specified, their values are considered unspecified.

@@ -3106,7 +3106,7 @@

14.4.7 If-The

The second and third child expressions are evaluated conditionally. The result MUST be type compatible with the type expected by the surrounding expression.

If the first expression evaluates to true, the second expression MUST be evaluated and its value MUST be returned as the result of the if-then-else expression. If the first expression evaluates to false and a third child element is present, it MUST be evaluated and its value MUST be returned as the result of the if-then-else expression. If no third expression is present, nothing is added to the surrounding collection.

-

$If

+

$If

Conditional expressions are represented as an object with a member $If whose value is an array of two or three annotation expressions.

It MAY contain annotations.

@@ -3125,7 +3125,7 @@

$If

14.4.8 Is-Of

The is-of expression checks whether the value obtained from its single child expression is compatible with the specified type. It returns true if the child expression returns a type that is compatible with the specified type, and false otherwise.

-

$IsOf

+

$IsOf

Is-of expressions are represented as an object with a member $IsOf whose value is an annotation expression, a member $Type whose value is a string containing an qualified type name, and optionally a member $Collection with a value of true.

It MAY contain annotations.

If the specified type is a primitive type or a collection of primitive types, the facet members $MaxLength, $Unicode, $Precision, $Scale, and $SRID MAY be specified if applicable to the specified primitive type. If the facet members are not specified, their values are considered unspecified.

@@ -3144,7 +3144,7 @@

14

A labeled element expression MUST contain exactly one child expression. The value of the child expression is also the value of the labeled element expression.

A labeled element expression MUST provide a simple identifier value as its name that MUST be unique within the schema containing the expression.

-

$LabeledElement

+

$LabeledElement

Labeled element expressions are represented as an object with a member $LabeledElement whose value is an annotation expression, and a member $Name whose value is a string containing the labeled element’s name.

It MAY contain annotations.

@@ -3160,7 +3160,7 @@

$LabeledEle

14.4.10 Labeled Element Reference

The labeled element reference expression MUST specify the qualified name of a labeled element expression in scope and returns the value of the identified labeled element expression as its value.

-

$LabeledElementReference

+

$LabeledElementReference

Labeled element reference expressions are represented as an object with a member $LabeledElementReference whose value is a string containing an qualified name.

@@ -3179,7 +3179,7 @@

14.4.11 Null

"@UI.DisplayName": null,
-

$Null

+

$Null

Null expression containing annotations are represented as an object with a member $Null whose value is the literal null.

diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md index 4ff23c496..71e397f61 100644 --- a/docs/odata-csdl-json/odata-csdl-json.md +++ b/docs/odata-csdl-json/odata-csdl-json.md @@ -4909,7 +4909,7 @@ The operand expressions are used as parameters to the client-side function. ::: {.varjson .rep} -### `$Apply` +### `$Apply` and `$Function` Apply expressions are represented as an object with a member `$Apply` whose value is an array of annotation expressions, and a member @@ -5090,7 +5090,7 @@ rules as the `cast` canonical function defined in [OData-URL](#ODataURL). ::: {.varjson .rep} -### `$Cast` +### `$Cast` Cast expressions are represented as an object with a member `$Cast` whose value is an annotation expression, a member `$Type` whose value is @@ -5173,7 +5173,7 @@ third expression is present, nothing is added to the surrounding collection. ::: {.varjson .rep} -### `$If` +### `$If` Conditional expressions are represented as an object with a member `$If` whose value is an array of two or three annotation expressions. @@ -5208,7 +5208,7 @@ child expression is compatible with the specified type. It returns the specified type, and `false` otherwise. ::: {.varjson .rep} -### `$IsOf` +### `$IsOf` Is-of expressions are represented as an object with a member `$IsOf` whose value is an annotation expression, a member `$Type` whose value is @@ -5255,7 +5255,7 @@ identifier](#SimpleIdentifier) value as its name that MUST be unique within the schema containing the expression. ::: {.varjson .rep} -### `$LabeledElement` +### `$LabeledElement` Labeled element expressions are represented as an object with a member `$LabeledElement` whose value is an annotation expression, and a member @@ -5286,7 +5286,7 @@ in scope and returns the value of the identified labeled element expression as its value. ::: {.varjson .rep} -### `$LabeledElementReference` +### `$LabeledElementReference` Labeled element reference expressions are represented as an object with a member `$LabeledElementReference` whose value is a string containing @@ -5322,7 +5322,7 @@ Example 85: ::: ::: {.varjson .rep} -### `$Null` +### `$Null` Null expression containing [annotations](#Annotations) are represented as an object with a member `$Null` whose value is the literal `null`. @@ -5433,7 +5433,7 @@ expression MUST be type compatible with the type expected by the surrounding expression. ::: {.varjson .rep} -### `$UrlRef` +### `$UrlRef` URL reference expressions are represented as an object with a single member `$UrlRef` whose value is an annotation expression. @@ -6072,13 +6072,14 @@ https://openui5.hana.ondemand.com/1.40.10/#docs/guide/87aac894a40640f89920d7b2a4 - [`$DivBy`](#DivBy21.18) - [`$Mod`](#Mod21.19) - [`$Apply`](#Apply21.20) - - [`$Cast`](#Cast21.21) - - [`$If`](#If21.22) - - [`$IsOf`](#IsOf21.23) - - [`$LabeledElement`](#LabeledElement21.24) - - [`$LabeledElementReference`](#LabeledElementReference21.25) - - [`$Null`](#Null21.26) - - [`$UrlRef`](#UrlRef21.27) + - [`$Function`](#Function21.21) + - [`$Cast`](#Cast21.22) + - [`$If`](#If21.23) + - [`$IsOf`](#IsOf21.24) + - [`$LabeledElement`](#LabeledElement21.25) + - [`$LabeledElementReference`](#LabeledElementReference21.26) + - [`$Null`](#Null21.27) + - [`$UrlRef`](#UrlRef21.28) ::: ------- diff --git a/odata-csdl/14 Vocabulary and Annotation.md b/odata-csdl/14 Vocabulary and Annotation.md index eac9586f6..c90f0429a 100644 --- a/odata-csdl/14 Vocabulary and Annotation.md +++ b/odata-csdl/14 Vocabulary and Annotation.md @@ -2278,7 +2278,8 @@ The operand expressions are used as parameters to the client-side function. ::: {.varjson .rep} -### ##subisec `$Apply` +### ##subisec `$Apply` +and ##subisec `$Function` Apply expressions are represented as an object with a member `$Apply` whose value is an array of annotation expressions, and a member From b232264803cc84a9946baba6c7e22ff400f34168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Wed, 29 Nov 2023 17:21:22 +0100 Subject: [PATCH 02/22] ODATA-1397 (#61) --- docs/odata-csdl-json/odata-csdl-json.html | 60 +++++++------- docs/odata-csdl-json/odata-csdl-json.md | 52 ++++++------ docs/odata-csdl-xml/odata-csdl-xml.html | 40 +++++----- docs/odata-csdl-xml/odata-csdl-xml.md | 40 +++++----- odata-csdl/14 Vocabulary and Annotation.md | 92 ++++++++++++---------- 5 files changed, 151 insertions(+), 133 deletions(-) diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html index ad3eaa72b..38ced93c3 100644 --- a/docs/odata-csdl-json/odata-csdl-json.html +++ b/docs/odata-csdl-json/odata-csdl-json.html @@ -3201,34 +3201,38 @@

14.4.12 Record

Example 87: this annotation “morphs” the entity type from example 13 into a structured type with two structural properties GivenName and Surname and two navigation properties DirectSupervisor and CostCenter. The first three properties simply rename properties of the annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service

-
"@person.Employee": {
-  "@type": "https://example.org/vocabs/person#org.example.person.Manager",
-  "@Core.Description": "Annotation on record",
-  "GivenName": {
-    "$Path": "FirstName"
-  },
-  "GivenName@Core.Description": "Annotation on record member",
-  "Surname": {
-    "$Path": "LastName"
-  },
-  "DirectSupervisor": {
-    "$Path": "Manager"
-  },
-  "CostCenter": {
-    "$UrlRef": {
-      "$Apply": [
-        "http://host/anotherservice/CostCenters('{ccid}')",
-        {
-          "$LabeledElement": {
-            "$Path": "CostCenterID"
-          },
-          "$Name": "ccid"
-        }
-      ],
-      "$Function": "odata.fillUriTemplate"
-    }
-  }
-}
+
"$Annotations": {
+  "org.example.Person": {
+    "@org.example.hcm.Employee": {
+      "@type": "https://example.org/vocabs/person#org.example.person.Manager",
+      "@Core.Description": "Annotation on record",
+      "GivenName": {
+        "$Path": "FirstName"
+      },
+      "GivenName@Core.Description": "Annotation on record member",
+      "Surname": {
+        "$Path": "LastName"
+      },
+      "DirectSupervisor": {
+        "$Path": "Manager"
+      },
+      "CostCenter": {
+        "$UrlRef": {
+          "$Apply": [
+            "http://host/anotherservice/CostCenters('{ccid}')",
+            {
+              "$LabeledElement": {
+                "$Path": "CostCenterID"
+              },
+              "$Name": "ccid"
+            }
+          ],
+          "$Function": "odata.fillUriTemplate"
+        }
+      }
+    }
+  }
+}

14.4.13 URL Reference

The URL reference expression enables a value to be obtained by sending a GET request.

diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md index 71e397f61..0b4ed90d2 100644 --- a/docs/odata-csdl-json/odata-csdl-json.md +++ b/docs/odata-csdl-json/odata-csdl-json.md @@ -5383,31 +5383,35 @@ a structured type with two structural properties `GivenName` and annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service ```json -"@person.Employee": { - "@type": "https://example.org/vocabs/person#org.example.person.Manager", - "@Core.Description": "Annotation on record", - "GivenName": { - "$Path": "FirstName" - }, - "GivenName@Core.Description": "Annotation on record member", - "Surname": { - "$Path": "LastName" - }, - "DirectSupervisor": { - "$Path": "Manager" - }, - "CostCenter": { - "$UrlRef": { - "$Apply": [ - "http://host/anotherservice/CostCenters('{ccid}')", - { - "$LabeledElement": { - "$Path": "CostCenterID" - }, - "$Name": "ccid" +"$Annotations": { + "org.example.Person": { + "@org.example.hcm.Employee": { + "@type": "https://example.org/vocabs/person#org.example.person.Manager", + "@Core.Description": "Annotation on record", + "GivenName": { + "$Path": "FirstName" + }, + "GivenName@Core.Description": "Annotation on record member", + "Surname": { + "$Path": "LastName" + }, + "DirectSupervisor": { + "$Path": "Manager" + }, + "CostCenter": { + "$UrlRef": { + "$Apply": [ + "http://host/anotherservice/CostCenters('{ccid}')", + { + "$LabeledElement": { + "$Path": "CostCenterID" + }, + "$Name": "ccid" + } + ], + "$Function": "odata.fillUriTemplate" } - ], - "$Function": "odata.fillUriTemplate" + } } } } diff --git a/docs/odata-csdl-xml/odata-csdl-xml.html b/docs/odata-csdl-xml/odata-csdl-xml.html index 4efcaa357..7908b1256 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.html +++ b/docs/odata-csdl-xml/odata-csdl-xml.html @@ -2984,25 +2984,27 @@

Example 87: this annotation “morphs” the entity type from example 13 into a structured type with two structural properties GivenName and Surname and two navigation properties DirectSupervisor and CostCenter. The first three properties simply rename properties of the annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service

-
<Annotation Term="org.example.person.Employee">
-  <Record>
-    <Annotation Term="Core.Description" String="Annotation on record" />
-    <PropertyValue Property="GivenName" Path="FirstName">
-      <Annotation Term="Core.Description"
-                  String="Annotation on record member" />
-    </PropertyValue>
-    <PropertyValue Property="Surname" Path="LastName" />
-    <PropertyValue Property="DirectSupervisor" Path="Manager" />
-    <PropertyValue Property="CostCenter">
-      <UrlRef>
-        <Apply Function="odata.fillUriTemplate">
-          <String>http://host/anotherservice/CostCenters('{ccid}')</String>
-          <LabeledElement Name="ccid" Path="CostCenterID" />
-        </Apply>
-      </UrlRef>
-    </PropertyValue>
-  </Record>
-</Annotation>
+
<Annotations Target="org.example.Person">
+  <Annotation Term="org.example.hcm.Employee">
+    <Record Type="org.example.hcm.Manager">
+      <Annotation Term="Core.Description" String="Annotation on record" />
+      <PropertyValue Property="GivenName" Path="FirstName">
+        <Annotation Term="Core.Description"
+                    String="Annotation on record member" />
+      </PropertyValue>
+      <PropertyValue Property="Surname" Path="LastName" />
+      <PropertyValue Property="DirectSupervisor" Path="Manager" />
+      <PropertyValue Property="CostCenter">
+        <UrlRef>
+          <Apply Function="odata.fillUriTemplate">
+            <String>http://host/anotherservice/CostCenters('{ccid}')</String>
+            <LabeledElement Name="ccid" Path="CostCenterID" />
+          </Apply>
+        </UrlRef>
+      </PropertyValue>
+    </Record>
+  </Annotation>
+</Annotations>

14.4.13 URL Reference

The URL reference expression enables a value to be obtained by sending a GET request.

diff --git a/docs/odata-csdl-xml/odata-csdl-xml.md b/docs/odata-csdl-xml/odata-csdl-xml.md index 50714c646..8fe7faf7c 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.md +++ b/docs/odata-csdl-xml/odata-csdl-xml.md @@ -5212,25 +5212,27 @@ a structured type with two structural properties `GivenName` and annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service ```xml - - - - - - - - - - - - http://host/anotherservice/CostCenters('{ccid}') - - - - - - + + + + + + + + + + + + + http://host/anotherservice/CostCenters('{ccid}') + + + + + + + ``` ::: diff --git a/odata-csdl/14 Vocabulary and Annotation.md b/odata-csdl/14 Vocabulary and Annotation.md index c90f0429a..02ef3e82d 100644 --- a/odata-csdl/14 Vocabulary and Annotation.md +++ b/odata-csdl/14 Vocabulary and Annotation.md @@ -2973,31 +2973,35 @@ a structured type with two structural properties `GivenName` and annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service ```json -"@person.Employee": { - "@type": "https://example.org/vocabs/person#org.example.person.Manager", - "@Core.Description": "Annotation on record", - "GivenName": { - "$Path": "FirstName" - }, - "GivenName@Core.Description": "Annotation on record member", - "Surname": { - "$Path": "LastName" - }, - "DirectSupervisor": { - "$Path": "Manager" - }, - "CostCenter": { - "$UrlRef": { - "$Apply": [ - "http://host/anotherservice/CostCenters('{ccid}')", - { - "$LabeledElement": { - "$Path": "CostCenterID" - }, - "$Name": "ccid" +"$Annotations": { + "org.example.Person": { + "@org.example.hcm.Employee": { + "@type": "https://example.org/vocabs/person#org.example.person.Manager", + "@Core.Description": "Annotation on record", + "GivenName": { + "$Path": "FirstName" + }, + "GivenName@Core.Description": "Annotation on record member", + "Surname": { + "$Path": "LastName" + }, + "DirectSupervisor": { + "$Path": "Manager" + }, + "CostCenter": { + "$UrlRef": { + "$Apply": [ + "http://host/anotherservice/CostCenters('{ccid}')", + { + "$LabeledElement": { + "$Path": "CostCenterID" + }, + "$Name": "ccid" + } + ], + "$Function": "odata.fillUriTemplate" } - ], - "$Function": "odata.fillUriTemplate" + } } } } @@ -3038,25 +3042,27 @@ a structured type with two structural properties `GivenName` and annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service ```xml - - - - - - - - - - - - http://host/anotherservice/CostCenters('{ccid}') - - - - - - + + + + + + + + + + + + + http://host/anotherservice/CostCenters('{ccid}') + + + + + + + ``` ::: From 7ed8ef663d07bb29914207f4240170654fcc2bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Wed, 29 Nov 2023 17:24:00 +0100 Subject: [PATCH 03/22] ODATA-1475 (#171) --- docs/odata-url-conventions/odata-url-conventions.html | 2 +- docs/odata-url-conventions/odata-url-conventions.md | 1 + odata-url-conventions/5 Query Options.md | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/odata-url-conventions/odata-url-conventions.html b/docs/odata-url-conventions/odata-url-conventions.html index 1c8433ffe..b1c4de110 100644 --- a/docs/odata-url-conventions/odata-url-conventions.html +++ b/docs/odata-url-conventions/odata-url-conventions.html @@ -1901,7 +1901,7 @@

.

The OData-ABNF searchExpr syntax rule defines the formal grammar of the search expression.

5.1.9 System Query Option $format

The $format system query option allows clients to request a response in a particular format and is useful for clients without access to request headers for standard content-type negotiation. Where present $format takes precedence over standard content-type negotiation.

diff --git a/docs/odata-url-conventions/odata-url-conventions.md b/docs/odata-url-conventions/odata-url-conventions.md index 61da0b091..89c0e757b 100644 --- a/docs/odata-url-conventions/odata-url-conventions.md +++ b/docs/odata-url-conventions/odata-url-conventions.md @@ -3745,6 +3745,7 @@ expressions evaluate to true, otherwise false. To support type-ahead use cases, incomplete search expressions can be sent as OData string literals enclosed in single-quotes, and single-quotes within the search expression doubled. +Such an expression can also be used to search for double quotes: `?$search='"'`. The [OData-ABNF](#ODataABNF) `searchExpr` syntax rule defines the formal grammar of the search expression. diff --git a/odata-url-conventions/5 Query Options.md b/odata-url-conventions/5 Query Options.md index 6e03ae306..2275ac6b4 100644 --- a/odata-url-conventions/5 Query Options.md +++ b/odata-url-conventions/5 Query Options.md @@ -2346,6 +2346,7 @@ expressions evaluate to true, otherwise false. To support type-ahead use cases, incomplete search expressions can be sent as OData string literals enclosed in single-quotes, and single-quotes within the search expression doubled. +Such an expression can also be used to search for double quotes: `?$search='"'`. The [OData-ABNF](#ODataABNF) `searchExpr` syntax rule defines the formal grammar of the search expression. From 72ab55cc774b59f88ccc0ac072be77f1c4c23a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Wed, 29 Nov 2023 17:29:56 +0100 Subject: [PATCH 04/22] ODATA-1503 (#178) --- docs/odata-json-format/odata-json-format.html | 2 +- docs/odata-json-format/odata-json-format.md | 6 ++++-- odata-json-format/20 Instance Annotations.md | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/odata-json-format/odata-json-format.html b/docs/odata-json-format/odata-json-format.html index 1f3558790..0b889c779 100644 --- a/docs/odata-json-format/odata-json-format.html +++ b/docs/odata-json-format/odata-json-format.html @@ -1788,7 +1788,7 @@

OData-CSDLJSON or OData-CSDLXML

The annotation identifier odata is reserved for future extensions of the protocol and format. Instance annotations MUST have a namespace or alias that is different from odata.

Annotations can be applied to any name/value pair in a JSON payload that represents a value of any type from the entity data model. Clients should never error due to an unexpected annotation in a JSON payload.

-

Annotations are always expressed as name/value pairs. For entity data model constructs represented as JSON objects the annotation name/value pairs are placed within the object; for constructs represented as JSON arrays or primitives they are placed next to the annotated model construct. When annotating a payload that represents a single primitive or collection value, the annotations for the value appear next to the value property and are not prefixed with a property name.

+

Annotations are always expressed as name/value pairs. For entity data model constructs represented as JSON objects the annotation name/value pairs are placed within the object; for constructs represented as JSON arrays or primitives, including null, they are placed next to the annotated model construct and have the name of the annotated property before the @. An annotation in the latter format can also take the place of an absent property. When annotating a payload that represents a single primitive or collection value, the annotations for the value appear next to the value property and are not prefixed with a property name.

Example 54:

{
diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md
index 8a2f8a204..b5eb8eb96 100644
--- a/docs/odata-json-format/odata-json-format.md
+++ b/docs/odata-json-format/odata-json-format.md
@@ -3390,8 +3390,10 @@ should never error due to an unexpected annotation in a JSON payload.
 Annotations are always expressed as name/value pairs. For entity data
 model constructs represented as JSON objects the annotation name/value
 pairs are placed within the object; for constructs represented as JSON
-arrays or primitives they are placed next to the annotated model
-construct. When annotating a payload that represents a
+arrays or primitives, including null, they are placed next to the annotated model
+construct and have the name of the annotated property before the `@`.
+An annotation in the latter format can also take the place of an absent property.
+When annotating a payload that represents a
 [single primitive or collection value](#IndividualPropertyorOperationResponse),
 the annotations for the value appear next to the `value`
 property and are not prefixed with a property name.
diff --git a/odata-json-format/20 Instance Annotations.md b/odata-json-format/20 Instance Annotations.md
index c80504512..0601e8a6f 100644
--- a/odata-json-format/20 Instance Annotations.md	
+++ b/odata-json-format/20 Instance Annotations.md	
@@ -26,8 +26,10 @@ should never error due to an unexpected annotation in a JSON payload.
 Annotations are always expressed as name/value pairs. For entity data
 model constructs represented as JSON objects the annotation name/value
 pairs are placed within the object; for constructs represented as JSON
-arrays or primitives they are placed next to the annotated model
-construct. When annotating a payload that represents a
+arrays or primitives, including null, they are placed next to the annotated model
+construct and have the name of the annotated property before the `@`.
+An annotation in the latter format can also take the place of an absent property.
+When annotating a payload that represents a
 [single primitive or collection value](#IndividualPropertyorOperationResponse),
 the annotations for the value appear next to the `value`
 property and are not prefixed with a property name.

From af6ad7d404d8516d194b4545a96f4366b93c550f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= 
Date: Wed, 29 Nov 2023 17:35:22 +0100
Subject: [PATCH 05/22] ODATA-1517 (#60)

Co-authored-by: Ralf Handl 
---
 docs/odata-csdl-json/odata-csdl-json.html  | 1303 ++++++++++----------
 docs/odata-csdl-json/odata-csdl-json.md    |    9 +-
 docs/odata-csdl-xml/odata-csdl-xml.html    |  809 ++++++------
 docs/odata-csdl-xml/odata-csdl-xml.md      |    9 +-
 odata-csdl/14 Vocabulary and Annotation.md |    9 +-
 5 files changed, 1078 insertions(+), 1061 deletions(-)

diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html
index 38ced93c3..516403bc1 100644
--- a/docs/odata-csdl-json/odata-csdl-json.html
+++ b/docs/odata-csdl-json/odata-csdl-json.html
@@ -2555,8 +2555,9 @@ 

14.4.1.1 Path

A model path MAY contain path segments starting with a navigation property, then followed by an at (@) character, then followed by the qualified name of a term in scope, and optionally followed by a hash (#) character and a simple identifier which is interpreted as a qualifier for the term. If the navigation property has not been annotated with that term (and if present, with that qualifier), the path segment evaluates to the null value. This allows addressing annotations on the navigation property itself; annotations on the entity type specified by the navigation property are addressed via a term-cast segment.

-

Example 64: model path addressing an annotation on a navigation property

-
.../Items@Capabilities.InsertRestrictions/Insertable
+

Example 64: model path segment addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property

+
.../Items@Core.Description
+
.../Items/@Core.Description

An instance path MAY contain path segments starting with an entity set or a collection-valued navigation property, then followed by a key predicate using parentheses-style convention, see OData-URL. The key values are either primitive literals or instance paths. If the key value is a relative instance path, it is interpreted according to the same rule below as the instance path it is part of, not relative to the instance identified by the preceding path part.

@@ -2588,64 +2589,64 @@

1

Example 67: Annotations hosted by property A2 in various modes

Path evaluation for the annotations in the first block starts at the directly enclosing type self.A of the hosting property A2.

-
"self": {
-  "A": {
-    "$Kind": "EntityType",
-    "A1": {
-      "$Type": "Edm.Boolean"
-    },
-    "A2": {
-      "$Type": "self.B"
-      "@Core.Description@Core.IsLanguageDependent": {
-        "$Path": "A1"
-      },
-      "@Core.Description": "..."
-    }
-  },
-  "B": {
-    "$Kind": "ComplexType",
-    "B1": {
-      "$Type": "Edm.Boolean"
-    }
-  },
+
"self": {
+  "A": {
+    "$Kind": "EntityType",
+    "A1": {
+      "$Type": "Edm.Boolean"
+    },
+    "A2": {
+      "$Type": "self.B"
+      "@Core.Description@Core.IsLanguageDependent": {
+        "$Path": "A1"
+      },
+      "@Core.Description": "..."
+    }
+  },
+  "B": {
+    "$Kind": "ComplexType",
+    "B1": {
+      "$Type": "Edm.Boolean"
+    }
+  },

Path evaluation for the annotations in the next block starts at the declared type self.B of the hosting property A2.

-
  "Container": {
-    "$Kind": "EntityContainer",
-    "SetA": {
-      "$Collection": true,
-      "$Type": "self.A"
-    }
-  },
-  "$Annotations": {
-    "self.Container/SetA/A2": {
-      "@Core.Description#viaset@Core.IsLanguageDependent": {
-        "$Path": "B1"
-      },
-      "@Core.Description#viaset": "..."
-    },
-    "self.Container/SetA/A2/@Core.Description#viaset": {
-      "@Core.IsLanguageDependent": {
-        "$Path": "B1"
-      }
-    },
+
  "Container": {
+    "$Kind": "EntityContainer",
+    "SetA": {
+      "$Collection": true,
+      "$Type": "self.A"
+    }
+  },
+  "$Annotations": {
+    "self.Container/SetA/A2": {
+      "@Core.Description#viaset@Core.IsLanguageDependent": {
+        "$Path": "B1"
+      },
+      "@Core.Description#viaset": "..."
+    },
+    "self.Container/SetA/A2/@Core.Description#viaset": {
+      "@Core.IsLanguageDependent": {
+        "$Path": "B1"
+      }
+    },

Path evaluation for the annotations in the final block starts at the outermost type self.A named in the target path.

-
    "self.A/A2": {
-      "@Core.Description#external@Core.IsLanguageDependent": {
-        "$Path": "A1"
-      },
-      "@Core.Description#external": "..."
-    },
-    "self.A/A2/@Core.Description": {
-      "@Core.IsLanguageDependent": {
-        "$Path": "A1"
-      }
-    }
-  }
-}
+
    "self.A/A2": {
+      "@Core.Description#external@Core.IsLanguageDependent": {
+        "$Path": "A1"
+      },
+      "@Core.Description#external": "..."
+    },
+    "self.A/A2/@Core.Description": {
+      "@Core.IsLanguageDependent": {
+        "$Path": "A1"
+      }
+    }
+  }
+}

14.4.1.3 Annotation Path

@@ -2660,11 +2661,11 @@

1

Example 68:

-
"@UI.ReferenceFacet": "Product/Supplier/@UI.LineItem",
-"@UI.CollectionFacet#Contacts": [
-  "Supplier/@Communication.Contact",
-  "Customer/@Communication.Contact"
-]
+
"@UI.ReferenceFacet": "Product/Supplier/@UI.LineItem",
+"@UI.CollectionFacet#Contacts": [
+  "Supplier/@Communication.Contact",
+  "Customer/@Communication.Contact"
+]

14.4.1.4 Model Element Path

The model element path expression provides a value for terms or term properties that specify the built-in type Edm.ModelElementPath. Its argument is a model path.

@@ -2674,7 +2675,7 @@

Example 69:

-
"@org.example.MyFavoriteModelElement": "/self.someAction"
+
"@org.example.MyFavoriteModelElement": "/self.someAction"

14.4.1.5 Navigation Property Path

The navigation property path expression provides a value for terms or term properties that specify the built-in types Edm.NavigationPropertyPath, Edm.AnyPropertyPath, or Edm.ModelElementPath. Its argument is a model path with the following restriction:

@@ -2687,14 +2688,14 @@

Example 70:

-
"@UI.HyperLink": "Supplier",
-
-"@Capabilities.UpdateRestrictions": {
-  "NonUpdatableNavigationProperties": [
-    "Supplier",
-    "Category"
-  ]
-}
+
"@UI.HyperLink": "Supplier",
+
+"@Capabilities.UpdateRestrictions": {
+  "NonUpdatableNavigationProperties": [
+    "Supplier",
+    "Category"
+  ]
+}

14.4.1.6 Property Path

The property path expression provides a value for terms or term properties that specify one of the built-in types Edm.PropertyPath, Edm.AnyPropertyPath, or Edm.ModelElementPath. Its argument is a model path with the following restriction:

@@ -2707,14 +2708,14 @@

14.4.1.

Example 71:

-
"@UI.RefreshOnChangeOf": "ChangedAt",
-
-"@Capabilities.UpdateRestrictions": {
-  "NonUpdatableProperties": [
-    "CreatedAt",
-    "ChangedAt"
-  ]
-}
+
"@UI.RefreshOnChangeOf": "ChangedAt",
+
+"@Capabilities.UpdateRestrictions": {
+  "NonUpdatableProperties": [
+    "CreatedAt",
+    "ChangedAt"
+  ]
+}

14.4.1.7 Value Path

The value path expression allows assigning a value by traversing an object graph. It can be used in annotations that target entity containers, entity sets, entity types, complex types, navigation properties of structured types, and structural properties of structured types. Its argument is an instance path.

@@ -2725,13 +2726,13 @@

$Path

Example 72:

-
"@UI.DisplayName": {
-  "$Path": "FirstName"
-},
-
-"@UI.DisplayName#second": {
-  "$Path": "@vCard.Address#work/FullName"
-}
+
"@UI.DisplayName": {
+  "$Path": "FirstName"
+},
+
+"@UI.DisplayName#second": {
+  "$Path": "@vCard.Address#work/FullName"
+}

14.4.2 Comparison and Logical Operators

Annotations MAY use the following logical and comparison expressions which evaluate to a Boolean value. These expressions MAY be combined and they MAY be used anywhere instead of a Boolean expression.

@@ -2767,98 +2768,98 @@

<

Example 73:

-
{
-  "$And": [
-    {
-      "$Path": "IsMale"
-    },
-    {
-      "$Path": "IsMarried"
-    }
-  ]
-},
-{
-  "$Or": [
-    {
-      "$Path": "IsMale"
-    },
-    {
-      "$Path": "IsMarried"
-    }
-  ]
-},
-{
-  "$Not": {
-    "$Path": "IsMale"
-  }
-},
-{
-  "$Eq": [
-    null,
-    {
-      "$Path": "IsMale"
-    }
-  ]
-},
-{
-  "$Ne": [
-    null,
-    {
-      "$Path": "IsMale"
-    }
-  ]
-},
-{
-  "$Gt": [
-    {
-      "$Path": "Price"
-    },
-    20
-  ]
-},
-{
-  "$Ge": [
-    {
-      "$Path": "Price"
-    },
-    10
-  ]
-},
-{
-  "$Lt": [
-    {
-      "$Path": "Price"
-    },
-    20
-  ]
-},
-{
-  "$Le": [
-    {
-      "$Path": "Price"
-    },
-    100
-  ]
-},
-{
-  "$Has": [
-    {
-      "$Path": "Fabric"
-    },
-    "Red"
-  ]
-},
-{
-  "$In": [
-    {
-      "$Path": "Size"
-    },
-    [
-      "XS",
-      "S"
-    ]
-  ]
-}
+
{
+  "$And": [
+    {
+      "$Path": "IsMale"
+    },
+    {
+      "$Path": "IsMarried"
+    }
+  ]
+},
+{
+  "$Or": [
+    {
+      "$Path": "IsMale"
+    },
+    {
+      "$Path": "IsMarried"
+    }
+  ]
+},
+{
+  "$Not": {
+    "$Path": "IsMale"
+  }
+},
+{
+  "$Eq": [
+    null,
+    {
+      "$Path": "IsMale"
+    }
+  ]
+},
+{
+  "$Ne": [
+    null,
+    {
+      "$Path": "IsMale"
+    }
+  ]
+},
+{
+  "$Gt": [
+    {
+      "$Path": "Price"
+    },
+    20
+  ]
+},
+{
+  "$Ge": [
+    {
+      "$Path": "Price"
+    },
+    10
+  ]
+},
+{
+  "$Lt": [
+    {
+      "$Path": "Price"
+    },
+    20
+  ]
+},
+{
+  "$Le": [
+    {
+      "$Path": "Price"
+    },
+    100
+  ]
+},
+{
+  "$Has": [
+    {
+      "$Path": "Fabric"
+    },
+    "Red"
+  ]
+},
+{
+  "$In": [
+    {
+      "$Path": "Size"
+    },
+    [
+      "XS",
+      "S"
+    ]
+  ]
+}

14.4.3 Arithmetic Operators

Annotations MAY use the following arithmetic expressions which evaluate to a numeric value. These expressions MAY be combined, and they MAY be used anywhere instead of a numeric expression of the appropriate type. The semantics and evaluation rules for each arithmetic expression is identical to the corresponding arithmetic operator defined in OData-URL.

@@ -2911,71 +2912,71 @@

Example 74:

-
{
-  "$Add": [
-    {
-      "$Path": "StartDate"
-    },
-    {
-      "$Path": "Duration"
-    }
-  ]
-},
-{
-  "$Sub": [
-    {
-      "$Path": "Revenue"
-    },
-    {
-      "$Path": "Cost"
-    }
-  ]
-},
-{
-  "$Neg": {
-    "$Path": "Height"
-  }
-},
-{
-  "$Mul": [
-    {
-      "$Path": "NetPrice"
-    },
-    {
-      "$Path": "TaxRate"
-    }
-  ]
-},
-{
-  "$Div": [
-    {
-      "$Path": "Quantity"
-    },
-    {
-      "$Path": "QuantityPerParcel"
-    }
-  ]
-},
-{
-  "$DivBy": [
-    {
-      "$Path": "Quantity"
-    },
-    {
-      "$Path": "QuantityPerParcel"
-    }
-  ]
-},
-{
-  "$Mod": [
-    {
-      "$Path": "Quantity"
-    },
-    {
-      "$Path": "QuantityPerParcel"
-    }
-  ]
-}
+
{
+  "$Add": [
+    {
+      "$Path": "StartDate"
+    },
+    {
+      "$Path": "Duration"
+    }
+  ]
+},
+{
+  "$Sub": [
+    {
+      "$Path": "Revenue"
+    },
+    {
+      "$Path": "Cost"
+    }
+  ]
+},
+{
+  "$Neg": {
+    "$Path": "Height"
+  }
+},
+{
+  "$Mul": [
+    {
+      "$Path": "NetPrice"
+    },
+    {
+      "$Path": "TaxRate"
+    }
+  ]
+},
+{
+  "$Div": [
+    {
+      "$Path": "Quantity"
+    },
+    {
+      "$Path": "QuantityPerParcel"
+    }
+  ]
+},
+{
+  "$DivBy": [
+    {
+      "$Path": "Quantity"
+    },
+    {
+      "$Path": "QuantityPerParcel"
+    }
+  ]
+},
+{
+  "$Mod": [
+    {
+      "$Path": "Quantity"
+    },
+    {
+      "$Path": "QuantityPerParcel"
+    }
+  ]
+}

14.4.4 Apply Client-Side Functions

The apply expression enables a value to be obtained by applying a client-side function. The apply expression MAY have operand expressions. The operand expressions are used as parameters to the client-side function.

@@ -2990,24 +2991,24 @@

OData-ABNF, i.e. Edm.Binary as binaryValue, Edm.Boolean as booleanValue etc.

Example 75:

-
"@UI.DisplayName": {
-  "$Apply": [
-    "Product: ",
-    {
-      "$Path": "ProductName"
-    },
-    " (",
-    {
-      "$Path": "Available/Quantity"
-    },
-    " ",
-    {
-      "$Path": "Available/Unit"
-    },
-    " available)"
-  ],
-  "$Function": "odata.concat"
-}
+
"@UI.DisplayName": {
+  "$Apply": [
+    "Product: ",
+    {
+      "$Path": "ProductName"
+    },
+    " (",
+    {
+      "$Path": "Available/Quantity"
+    },
+    " ",
+    {
+      "$Path": "Available/Unit"
+    },
+    " available)"
+  ],
+  "$Function": "odata.concat"
+}

ProductName is of type String, Quantity in complex type Available is of type Decimal, and Unit in Available is of type enumeration, so the result of the Path expression is represented as the member name of the enumeration value.

14.4.4.2 Function odata.fillUriTemplate

@@ -3019,56 +3020,56 @@

labeled element expressions that evaluate to a collection of complex types with two properties that are used in lexicographic order. The first property is used as key, the second property as value.

Example 76: assuming there are no special characters in values of the Name property of the Actor entity

-
{
-  "$Apply": [
-    "http://host/someAPI/Actors/{actorName}/CV",
-    {
-      "$LabeledElement": {
-        "$Path": "Actor/Name"
-      },
-      "$Name": "self.actorName"
-    }
-  ],
-  "$Function": "odata.fillUriTemplate"
-}
+
{
+  "$Apply": [
+    "http://host/someAPI/Actors/{actorName}/CV",
+    {
+      "$LabeledElement": {
+        "$Path": "Actor/Name"
+      },
+      "$Name": "self.actorName"
+    }
+  ],
+  "$Function": "odata.fillUriTemplate"
+}

14.4.4.3 Function odata.matchesPattern

The odata.matchesPattern client-side function takes two string expressions as arguments and returns a Boolean value. It is the counterpart of the identically named URL function OData-URL, section 5.1.1.7.1.

The function returns true if the second expression evaluates to an ECMAScript (JavaScript) regular expression and the result of the first argument expression matches that regular expression, using syntax and semantics of ECMAScript regular expressions.

Example 77: all non-empty FirstName values not containing the letters b, c, or d evaluate to true

-
{
-  "$Apply": [
-    {
-      "$Path": "FirstName"
-    },
-    "^[^b-d]+$"
-  ],
-  "$Function": "odata.matchesPattern"
-}
+
{
+  "$Apply": [
+    {
+      "$Path": "FirstName"
+    },
+    "^[^b-d]+$"
+  ],
+  "$Function": "odata.matchesPattern"
+}

14.4.4.4 Function odata.uriEncode

The odata.uriEncode client-side function takes one argument of primitive type and returns the URL-encoded OData literal that can be used as a key value in OData URLs or in the query part of OData URLs.

Note: string literals are surrounded by single quotes as required by the paren-style key syntax.

Example 78:

-
{
-  "$Apply": [
-    "http://host/service/Genres({genreName})",
-    {
-      "$LabeledElement": {
-        "$Apply": [
-          {
-            "$Path": "NameOfMovieGenre"
-          }
-        ],
-        "$Function": "odata.uriEncode"
-      },
-      "$Name": "self.genreName"
-    }
-  ],
-  "$Function": "odata.fillUriTemplate"
-}
+
{
+  "$Apply": [
+    "http://host/service/Genres({genreName})",
+    {
+      "$LabeledElement": {
+        "$Apply": [
+          {
+            "$Path": "NameOfMovieGenre"
+          }
+        ],
+        "$Function": "odata.uriEncode"
+      },
+      "$Name": "self.genreName"
+    }
+  ],
+  "$Function": "odata.fillUriTemplate"
+}

14.4.5 Cast

The cast expression casts the value obtained from its single child expression to the specified type. The cast expression follows the same rules as the cast canonical function defined in OData-URL.

@@ -3080,12 +3081,12 @@

$Cast

Example 79:

-
"@UI.Threshold": {
-  "$Cast": {
-    "$Path": "Average"
-  },
-  "$Type": "Edm.Decimal"
-}
+
"@UI.Threshold": {
+  "$Cast": {
+    "$Path": "Average"
+  },
+  "$Type": "Edm.Decimal"
+}

14.4.6 Collection

The collection expression enables a value to be obtained from zero or more item expressions. The value calculated by the collection expression is the collection of the values calculated by each of the item expressions. The values of the child expressions MUST all be type compatible.

@@ -3094,11 +3095,11 @@

14.4.6 Collecti

Example 80:

-
"@seo.SeoTerms": [
-  "Product",
-  "Supplier",
-  "Customer"
-]
+
"@seo.SeoTerms": [
+  "Product",
+  "Supplier",
+  "Customer"
+]

14.4.7 If-Then-Else

The if-then-else expression enables a value to be obtained by evaluating a condition expression. It MUST contain exactly three child expressions. There is one exception to this rule: if and only if the if-then-else expression is an item of a collection expression, the third child expression MAY be omitted, reducing it to an if-then expression. This can be used to conditionally add an element to a collection.

@@ -3112,15 +3113,15 @@

$If

Example 81: the condition is a value path expression referencing the Boolean property IsFemale, whose value then determines the value of the $If expression (or so it was long ago)

-
"@person.Gender": {
-  "$If": [
-    {
-      "$Path": "IsFemale"
-    },
-    "Female",
-    "Male"
-  ]
-}
+
"@person.Gender": {
+  "$If": [
+    {
+      "$Path": "IsFemale"
+    },
+    "Female",
+    "Male"
+  ]
+}

14.4.8 Is-Of

The is-of expression checks whether the value obtained from its single child expression is compatible with the specified type. It returns true if the child expression returns a type that is compatible with the specified type, and false otherwise.

@@ -3132,12 +3133,12 @@

$IsOf

Example 82:

-
"@Self.IsPreferredCustomer": {
-  "$IsOf": {
-    "$Path": "Customer"
-  },
-  "$Type": "self.PreferredCustomer"
-}
+
"@Self.IsPreferredCustomer": {
+  "$IsOf": {
+    "$Path": "Customer"
+  },
+  "$Type": "self.PreferredCustomer"
+}

14.4.9 Labeled Element

The labeled element expression assigns a name to its single child expression. The value of the child expression can then be reused elsewhere with a labeled element reference expression.

@@ -3150,12 +3151,12 @@

$LabeledEle

Example 83:

-
"@UI.DisplayName": {
-  "$LabeledElement": {
-    "$Path": "FirstName"
-  },
-  "$Name": "CustomerFirstName"
-}
+
"@UI.DisplayName": {
+  "$LabeledElement": {
+    "$Path": "FirstName"
+  },
+  "$Name": "CustomerFirstName"
+}

14.4.10 Labeled Element Reference

The labeled element reference expression MUST specify the qualified name of a labeled element expression in scope and returns the value of the identified labeled element expression as its value.

@@ -3165,9 +3166,9 @@

Example 84:

-
"@UI.DisplayName": {
-  "$LabeledElementReference": "self.CustomerFirstName"
-}
+
"@UI.DisplayName": {
+  "$LabeledElementReference": "self.CustomerFirstName"
+}

14.4.11 Null

The null expression indicates the absence of a value. The null expression MAY be annotated.

@@ -3176,7 +3177,7 @@

14.4.11 Null

Example 85:

-
"@UI.DisplayName": null,
+
"@UI.DisplayName": null,

$Null

@@ -3184,10 +3185,10 @@

$Null

Example 86:

-
"@UI.Address": {
-  "$Null": null,
-  "@self.Reason": "Private"
-}
+
"@UI.Address": {
+  "$Null": null,
+  "@self.Reason": "Private"
+}

14.4.12 Record

The record expression enables a new entity type or complex type instance to be constructed.

@@ -3201,38 +3202,38 @@

14.4.12 Record

Example 87: this annotation “morphs” the entity type from example 13 into a structured type with two structural properties GivenName and Surname and two navigation properties DirectSupervisor and CostCenter. The first three properties simply rename properties of the annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service

-
"$Annotations": {
-  "org.example.Person": {
-    "@org.example.hcm.Employee": {
-      "@type": "https://example.org/vocabs/person#org.example.person.Manager",
-      "@Core.Description": "Annotation on record",
-      "GivenName": {
-        "$Path": "FirstName"
-      },
-      "GivenName@Core.Description": "Annotation on record member",
-      "Surname": {
-        "$Path": "LastName"
-      },
-      "DirectSupervisor": {
-        "$Path": "Manager"
-      },
-      "CostCenter": {
-        "$UrlRef": {
-          "$Apply": [
-            "http://host/anotherservice/CostCenters('{ccid}')",
-            {
-              "$LabeledElement": {
-                "$Path": "CostCenterID"
-              },
-              "$Name": "ccid"
-            }
-          ],
-          "$Function": "odata.fillUriTemplate"
-        }
-      }
-    }
-  }
-}
+
"$Annotations": {
+  "org.example.Person": {
+    "@org.example.hcm.Employee": {
+      "@type": "https://example.org/vocabs/person#org.example.person.Manager",
+      "@Core.Description": "Annotation on record",
+      "GivenName": {
+        "$Path": "FirstName"
+      },
+      "GivenName@Core.Description": "Annotation on record member",
+      "Surname": {
+        "$Path": "LastName"
+      },
+      "DirectSupervisor": {
+        "$Path": "Manager"
+      },
+      "CostCenter": {
+        "$UrlRef": {
+          "$Apply": [
+            "http://host/anotherservice/CostCenters('{ccid}')",
+            {
+              "$LabeledElement": {
+                "$Path": "CostCenterID"
+              },
+              "$Name": "ccid"
+            }
+          ],
+          "$Function": "odata.fillUriTemplate"
+        }
+      }
+    }
+  }
+}

14.4.13 URL Reference

The URL reference expression enables a value to be obtained by sending a GET request.

@@ -3245,29 +3246,29 @@

$UrlRef

Example 88:

-
"@org.example.person.Supplier": {
-  "$UrlRef": {
-    "$Apply": [
-      "http://host/service/Suppliers({suppID})",
-      {
-        "$LabeledElement": {
-          "$Apply": [
-            {
-              "$Path": "SupplierId"
-            }
-          ],
-          "$Function": "odata.uriEncode"
-        },
-        "$Name": "suppID"
-      }
-    ],
-    "$Function": "odata.fillUriTemplate"
-  }
-},
- 
-"@Core.LongDescription#element": {
-  "$UrlRef": "http://host/wiki/HowToUse"
-}
+
"@org.example.person.Supplier": {
+  "$UrlRef": {
+    "$Apply": [
+      "http://host/service/Suppliers({suppID})",
+      {
+        "$LabeledElement": {
+          "$Apply": [
+            {
+              "$Path": "SupplierId"
+            }
+          ],
+          "$Function": "odata.uriEncode"
+        },
+        "$Name": "suppID"
+      }
+    ],
+    "$Function": "odata.fillUriTemplate"
+  }
+},
+ 
+"@Core.LongDescription#element": {
+  "$UrlRef": "http://host/wiki/HowToUse"
+}

15 Identifier and Path Values

@@ -3305,270 +3306,270 @@

16 CSDL Ex

16.1 Products and Categories Example

Example 90:

-
{
-  "$Version": "4.0",
-  "$EntityContainer": "ODataDemo.DemoService",
-  "$Reference": {
-    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
-      "$Include": [
-        {
-          "$Namespace": "Org.OData.Core.V1",
-          "$Alias": "Core",
-          "@Core.DefaultNamespace": true
-        }
-      ]
-    },
-    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.json": {
-      "$Include": [
-        {
-          "$Namespace": "Org.OData.Measures.V1",
-          "$Alias": "Measures"
-        }
-      ]
-    }
-  },
-  "ODataDemo": {
-    "$Alias": "self",
-    "@Core.DefaultNamespace": true,
-    "Product": {
-      "$Kind": "EntityType",
-      "$Key": [
-        "ID"
-      ],
-      "ID": {},
-      "Description": {
-        "$Nullable": true,
-        "@Core.IsLanguageDependent": true
-      },
-      "ReleaseDate": {
-        "$Nullable": true,
-        "$Type": "Edm.Date"
-      },
-      "DiscontinuedDate": {
-        "$Nullable": true,
-        "$Type": "Edm.Date"
-      },
-      "Rating": {
-        "$Nullable": true,
-        "$Type": "Edm.Int32"
-      },
-      "Price": {
-        "$Nullable": true,
-        "$Type": "Edm.Decimal",
-        "@Measures.ISOCurrency": {
-          "$Path": "Currency"
-        }
-      },
-      "Currency": {
-        "$Nullable": true,
-        "$MaxLength": 3
-      },
-      "Category": {
-        "$Kind": "NavigationProperty",
-        "$Type": "self.Category",
-        "$Partner": "Products"
-      },
-      "Supplier": {
-        "$Kind": "NavigationProperty",
-        "$Nullable": true,
-        "$Type": "self.Supplier",
-        "$Partner": "Products"
-      }
-    },
-    "Category": {
-      "$Kind": "EntityType",
-      "$Key": [
-        "ID"
-      ],
-      "ID": {
-        "$Type": "Edm.Int32"
-      },
-      "Name": {
-        "@Core.IsLanguageDependent": true
-      },
-      "Products": {
-        "$Kind": "NavigationProperty",
-        "$Partner": "Category",
-        "$Collection": true,
-        "$Type": "self.Product",
-        "$OnDelete": "Cascade"
-      }
-    },
-    "Supplier": {
-      "$Kind": "EntityType",
-      "$Key": [
-        "ID"
-      ],
-      "ID": {},
-      "Name": {
-        "$Nullable": true
-      },
-      "Address": {
-        "$Type": "self.Address"
-      },
-      "Concurrency": {
-        "$Type": "Edm.Int32"
-      },
-      "Products": {
-        "$Kind": "NavigationProperty",
-        "$Partner": "Supplier",
-        "$Collection": true,
-        "$Type": "self.Product"
-      }
-    },
-    "Country": {
-      "$Kind": "EntityType",
-      "$Key": [
-        "Code"
-      ],
-      "Code": {
-        "$MaxLength": 2
-      },
-      "Name": {
-        "$Nullable": true
-      }
-    },
-    "Address": {
-      "$Kind": "ComplexType",
-      "Street": {
-        "$Nullable": true
-      },
-      "City": {
-        "$Nullable": true
-      },
-      "State": {
-        "$Nullable": true
-      },
-      "ZipCode": {
-        "$Nullable": true
-      },
-      "CountryName": {
-        "$Nullable": true
-      },
-      "Country": {
-        "$Kind": "NavigationProperty",
-        "$Nullable": true,
-        "$Type": "self.Country",
-        "$ReferentialConstraint": {
-          "CountryName": "Name"
-        }
-      }
-    },
-    "ProductsByRating": [
-      {
-        "$Kind": "Function",
-        "$Parameter": [
-          {
-            "$Name": "Rating",
-            "$Nullable": true,
-            "$Type": "Edm.Int32"
-          }
-        ],
-        "$ReturnType": {
-          "$Collection": true,
-          "$Type": "self.Product"
-        }
-      }
-    ],
-    "DemoService": {
-      "$Kind": "EntityContainer",
-      "Products": {
-        "$Collection": true,
-        "$Type": "self.Product",
-        "$NavigationPropertyBinding": {
-          "Category": "Categories"
-        }
-      },
-      "Categories": {
-        "$Collection": true,
-        "$Type": "self.Category",
-        "$NavigationPropertyBinding": {
-          "Products": "Products"
-        },
-        "@Core.Description": "Product Categories"
-      },
-      "Suppliers": {
-        "$Collection": true,
-        "$Type": "self.Supplier",
-        "$NavigationPropertyBinding": {
-          "Products": "Products",
-          "Address/Country": "Countries"
-        },
-        "@Core.OptimisticConcurrency": [
-          "Concurrency"
-        ]
-      },
-      "Countries": {
-        "$Collection": true,
-        "$Type": "self.Country"
-      },
-      "MainSupplier": {
-        "$Type": "self.Supplier",
-        "$NavigationPropertyBinding": {
-          "Products": "Products"
-        },
-        "@Core.Description": "Primary Supplier"
-      },
-      "ProductsByRating": {
-        "$EntitySet": "Products",
-        "$Function": "self.ProductsByRating"
-      }
-    }
-  }
-}
+
{
+  "$Version": "4.0",
+  "$EntityContainer": "ODataDemo.DemoService",
+  "$Reference": {
+    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
+      "$Include": [
+        {
+          "$Namespace": "Org.OData.Core.V1",
+          "$Alias": "Core",
+          "@Core.DefaultNamespace": true
+        }
+      ]
+    },
+    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.json": {
+      "$Include": [
+        {
+          "$Namespace": "Org.OData.Measures.V1",
+          "$Alias": "Measures"
+        }
+      ]
+    }
+  },
+  "ODataDemo": {
+    "$Alias": "self",
+    "@Core.DefaultNamespace": true,
+    "Product": {
+      "$Kind": "EntityType",
+      "$Key": [
+        "ID"
+      ],
+      "ID": {},
+      "Description": {
+        "$Nullable": true,
+        "@Core.IsLanguageDependent": true
+      },
+      "ReleaseDate": {
+        "$Nullable": true,
+        "$Type": "Edm.Date"
+      },
+      "DiscontinuedDate": {
+        "$Nullable": true,
+        "$Type": "Edm.Date"
+      },
+      "Rating": {
+        "$Nullable": true,
+        "$Type": "Edm.Int32"
+      },
+      "Price": {
+        "$Nullable": true,
+        "$Type": "Edm.Decimal",
+        "@Measures.ISOCurrency": {
+          "$Path": "Currency"
+        }
+      },
+      "Currency": {
+        "$Nullable": true,
+        "$MaxLength": 3
+      },
+      "Category": {
+        "$Kind": "NavigationProperty",
+        "$Type": "self.Category",
+        "$Partner": "Products"
+      },
+      "Supplier": {
+        "$Kind": "NavigationProperty",
+        "$Nullable": true,
+        "$Type": "self.Supplier",
+        "$Partner": "Products"
+      }
+    },
+    "Category": {
+      "$Kind": "EntityType",
+      "$Key": [
+        "ID"
+      ],
+      "ID": {
+        "$Type": "Edm.Int32"
+      },
+      "Name": {
+        "@Core.IsLanguageDependent": true
+      },
+      "Products": {
+        "$Kind": "NavigationProperty",
+        "$Partner": "Category",
+        "$Collection": true,
+        "$Type": "self.Product",
+        "$OnDelete": "Cascade"
+      }
+    },
+    "Supplier": {
+      "$Kind": "EntityType",
+      "$Key": [
+        "ID"
+      ],
+      "ID": {},
+      "Name": {
+        "$Nullable": true
+      },
+      "Address": {
+        "$Type": "self.Address"
+      },
+      "Concurrency": {
+        "$Type": "Edm.Int32"
+      },
+      "Products": {
+        "$Kind": "NavigationProperty",
+        "$Partner": "Supplier",
+        "$Collection": true,
+        "$Type": "self.Product"
+      }
+    },
+    "Country": {
+      "$Kind": "EntityType",
+      "$Key": [
+        "Code"
+      ],
+      "Code": {
+        "$MaxLength": 2
+      },
+      "Name": {
+        "$Nullable": true
+      }
+    },
+    "Address": {
+      "$Kind": "ComplexType",
+      "Street": {
+        "$Nullable": true
+      },
+      "City": {
+        "$Nullable": true
+      },
+      "State": {
+        "$Nullable": true
+      },
+      "ZipCode": {
+        "$Nullable": true
+      },
+      "CountryName": {
+        "$Nullable": true
+      },
+      "Country": {
+        "$Kind": "NavigationProperty",
+        "$Nullable": true,
+        "$Type": "self.Country",
+        "$ReferentialConstraint": {
+          "CountryName": "Name"
+        }
+      }
+    },
+    "ProductsByRating": [
+      {
+        "$Kind": "Function",
+        "$Parameter": [
+          {
+            "$Name": "Rating",
+            "$Nullable": true,
+            "$Type": "Edm.Int32"
+          }
+        ],
+        "$ReturnType": {
+          "$Collection": true,
+          "$Type": "self.Product"
+        }
+      }
+    ],
+    "DemoService": {
+      "$Kind": "EntityContainer",
+      "Products": {
+        "$Collection": true,
+        "$Type": "self.Product",
+        "$NavigationPropertyBinding": {
+          "Category": "Categories"
+        }
+      },
+      "Categories": {
+        "$Collection": true,
+        "$Type": "self.Category",
+        "$NavigationPropertyBinding": {
+          "Products": "Products"
+        },
+        "@Core.Description": "Product Categories"
+      },
+      "Suppliers": {
+        "$Collection": true,
+        "$Type": "self.Supplier",
+        "$NavigationPropertyBinding": {
+          "Products": "Products",
+          "Address/Country": "Countries"
+        },
+        "@Core.OptimisticConcurrency": [
+          "Concurrency"
+        ]
+      },
+      "Countries": {
+        "$Collection": true,
+        "$Type": "self.Country"
+      },
+      "MainSupplier": {
+        "$Type": "self.Supplier",
+        "$NavigationPropertyBinding": {
+          "Products": "Products"
+        },
+        "@Core.Description": "Primary Supplier"
+      },
+      "ProductsByRating": {
+        "$EntitySet": "Products",
+        "$Function": "self.ProductsByRating"
+      }
+    }
+  }
+}

16.2 Annotations for Products and Categories Example

Example 91:

-
{
-  "$Version": "4.01",
-  "$Reference": {
-    "http://host/service/$metadata": {
-      "$Include": [
-        {
-          "$Namespace": "ODataDemo",
-          "$Alias": "target"
-        }
-      ]
-    },
-    "http://somewhere/Vocabulary/V1": {
-      "$Include": [
-        {
-          "$Namespace": "Some.Vocabulary.V1",
-          "$Alias": "Vocabulary1"
-        }
-      ]
-    }
-  },
-  "External.Annotations": {
-    "$Annotations": {
-      "target.Supplier": {
-        "@Vocabulary1.EMail": null,
-        "@Vocabulary1.AccountID": {
-          "$Path": "ID"
-        },
-        "@Vocabulary1.Title": "Supplier Info",
-        "@Vocabulary1.DisplayName": {
-          "$Apply": [
-            {
-              "$Path": "Name"
-            },
-            " in ",
-            {
-              "$Path": "Address/CountryName"
-            }
-          ],
-          "$Function": "odata.concat"
-        }
-      },
-      "target.Product": {
-        "@Vocabulary1.Tags": [
-          "MasterData"
-        ]
-      }
-    }
-  }
-}
+
{
+  "$Version": "4.01",
+  "$Reference": {
+    "http://host/service/$metadata": {
+      "$Include": [
+        {
+          "$Namespace": "ODataDemo",
+          "$Alias": "target"
+        }
+      ]
+    },
+    "http://somewhere/Vocabulary/V1": {
+      "$Include": [
+        {
+          "$Namespace": "Some.Vocabulary.V1",
+          "$Alias": "Vocabulary1"
+        }
+      ]
+    }
+  },
+  "External.Annotations": {
+    "$Annotations": {
+      "target.Supplier": {
+        "@Vocabulary1.EMail": null,
+        "@Vocabulary1.AccountID": {
+          "$Path": "ID"
+        },
+        "@Vocabulary1.Title": "Supplier Info",
+        "@Vocabulary1.DisplayName": {
+          "$Apply": [
+            {
+              "$Path": "Name"
+            },
+            " in ",
+            {
+              "$Path": "Address/CountryName"
+            }
+          ],
+          "$Function": "odata.concat"
+        }
+      },
+      "target.Product": {
+        "@Vocabulary1.Tags": [
+          "MasterData"
+        ]
+      }
+    }
+  }
+}

17 Conformance

diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md index 0b4ed90d2..b66d706d2 100644 --- a/docs/odata-csdl-json/odata-csdl-json.md +++ b/docs/odata-csdl-json/odata-csdl-json.md @@ -4271,9 +4271,14 @@ type specified by the navigation property are addressed via a [term-cast segment](#TermCast). ::: example -Example 64: model path addressing an annotation on a navigation property +Example 64: model path segment addressing an annotation on a navigation property +vs. term cast addressing an annotation on the resource addressed by the navigation property ``` -.../Items@Capabilities.InsertRestrictions/Insertable +.../Items@Core.Description +``` + +``` +.../Items/@Core.Description ``` ::: diff --git a/docs/odata-csdl-xml/odata-csdl-xml.html b/docs/odata-csdl-xml/odata-csdl-xml.html index 7908b1256..bf05facbe 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.html +++ b/docs/odata-csdl-xml/odata-csdl-xml.html @@ -2436,8 +2436,9 @@

14.4.1.1 Path

A model path MAY contain path segments starting with a navigation property, then followed by an at (@) character, then followed by the qualified name of a term in scope, and optionally followed by a hash (#) character and a simple identifier which is interpreted as a qualifier for the term. If the navigation property has not been annotated with that term (and if present, with that qualifier), the path segment evaluates to the null value. This allows addressing annotations on the navigation property itself; annotations on the entity type specified by the navigation property are addressed via a term-cast segment.

-

Example 64: model path addressing an annotation on a navigation property

-
.../Items@Capabilities.InsertRestrictions/Insertable
+

Example 64: model path segment addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property

+
.../Items@Core.Description
+
.../Items/@Core.Description

An instance path MAY contain path segments starting with an entity set or a collection-valued navigation property, then followed by a key predicate using parentheses-style convention, see OData-URL. The key values are either primitive literals or instance paths. If the key value is a relative instance path, it is interpreted according to the same rule below as the instance path it is part of, not relative to the instance identified by the preceding path part.

@@ -2469,44 +2470,44 @@

1

Example 67: Annotations hosted by property A2 in various modes

Path evaluation for the annotations in the first block starts at the directly enclosing type self.A of the hosting property A2.

-
<Schema Namespace="self">
-  <EntityType Name="A">
-    <Property Name="A1" Type="Edm.Boolean" Nullable="false" />
-    <Property Name="A2" Type="self.B" Nullable="false">
-      <Annotation Term="Core.Description" String="...">
-        <Annotation Term="Core.IsLanguageDependent" Path="A1" />
-      </Annotation>
-    </Property>
-  </EntityType>
-  <ComplexType Name="B">
-    <Property Name="B1" Type="Edm.Boolean" Nullable="false" />
-  </ComplexType>
+
<Schema Namespace="self">
+  <EntityType Name="A">
+    <Property Name="A1" Type="Edm.Boolean" Nullable="false" />
+    <Property Name="A2" Type="self.B" Nullable="false">
+      <Annotation Term="Core.Description" String="...">
+        <Annotation Term="Core.IsLanguageDependent" Path="A1" />
+      </Annotation>
+    </Property>
+  </EntityType>
+  <ComplexType Name="B">
+    <Property Name="B1" Type="Edm.Boolean" Nullable="false" />
+  </ComplexType>

Path evaluation for the annotations in the next block starts at the declared type self.B of the hosting property A2.

-
  <EntityContainer Name="Container">
-    <EntitySet Name="SetA" EntityType="self.A" />
-  </EntityContainer>
-  <Annotations Target="self.Container/SetA/A2">
-    <Annotation Term="Core.Description" Qualifier="viaset" String="...">
-      <Annotation Term="Core.IsLanguageDependent" Path="B1" />
-    </Annotation>
-  </Annotations>
-  <Annotations Target="self.Container/SetA/A2/@Core.Description#viaset">
-    <Annotation Term="Core.IsLanguageDependent" Path="B1" />
-  </Annotations>
+
  <EntityContainer Name="Container">
+    <EntitySet Name="SetA" EntityType="self.A" />
+  </EntityContainer>
+  <Annotations Target="self.Container/SetA/A2">
+    <Annotation Term="Core.Description" Qualifier="viaset" String="...">
+      <Annotation Term="Core.IsLanguageDependent" Path="B1" />
+    </Annotation>
+  </Annotations>
+  <Annotations Target="self.Container/SetA/A2/@Core.Description#viaset">
+    <Annotation Term="Core.IsLanguageDependent" Path="B1" />
+  </Annotations>

Path evaluation for the annotations in the final block starts at the outermost type self.A named in the target path.

-
  <Annotations Target="self.A/A2">
-    <Annotation Term="Core.Description" Qualifier="external" String="...">
-      <Annotation Term="Core.IsLanguageDependent" Path="A1" />
-    </Annotation>
-  </Annotations>
-  <Annotations Target="self.A/A2/@Core.Description">
-    <Annotation Term="Core.IsLanguageDependent" Path="A1" />
-  </Annotations>
-</Schema>
+
  <Annotations Target="self.A/A2">
+    <Annotation Term="Core.Description" Qualifier="external" String="...">
+      <Annotation Term="Core.IsLanguageDependent" Path="A1" />
+    </Annotation>
+  </Annotations>
+  <Annotations Target="self.A/A2/@Core.Description">
+    <Annotation Term="Core.IsLanguageDependent" Path="A1" />
+  </Annotations>
+</Schema>

14.4.1.3 Annotation Path

@@ -2522,15 +2523,15 @@

Example 68:

-
<Annotation Term="UI.ReferenceFacet"
-            AnnotationPath="Product/Supplier/@UI.LineItem" />
-
-<Annotation Term="UI.CollectionFacet" Qualifier="Contacts">
-  <Collection>
-    <AnnotationPath>Supplier/@Communication.Contact</AnnotationPath>
-    <AnnotationPath>Customer/@Communication.Contact</AnnotationPath>
-  </Collection>
-</Annotation>
+
<Annotation Term="UI.ReferenceFacet"
+            AnnotationPath="Product/Supplier/@UI.LineItem" />
+
+<Annotation Term="UI.CollectionFacet" Qualifier="Contacts">
+  <Collection>
+    <AnnotationPath>Supplier/@Communication.Contact</AnnotationPath>
+    <AnnotationPath>Customer/@Communication.Contact</AnnotationPath>
+  </Collection>
+</Annotation>

14.4.1.4 Model Element Path

The model element path expression provides a value for terms or term properties that specify the built-in type Edm.ModelElementPath. Its argument is a model path.

@@ -2541,12 +2542,12 @@

Example 69:

-
<Annotation Term="org.example.MyFavoriteModelElement"
-            ModelElementPath="/org.example.someAction" />
-
-<Annotation Term="org.example.MyFavoriteModelElement">
-  <ModelElementPath>/org.example.someAction</ModelElementPath>
-</Annotation>
+
<Annotation Term="org.example.MyFavoriteModelElement"
+            ModelElementPath="/org.example.someAction" />
+
+<Annotation Term="org.example.MyFavoriteModelElement">
+  <ModelElementPath>/org.example.someAction</ModelElementPath>
+</Annotation>

14.4.1.5 Navigation Property Path

The navigation property path expression provides a value for terms or term properties that specify the built-in types Edm.NavigationPropertyPath, Edm.AnyPropertyPath, or Edm.ModelElementPath. Its argument is a model path with the following restriction:

@@ -2560,18 +2561,18 @@

Example 70:

-
<Annotation Term="UI.HyperLink" NavigationPropertyPath="Supplier" />
-
-<Annotation Term="Capabilities.UpdateRestrictions">
-  <Record>
-    <PropertyValue Property="NonUpdatableNavigationProperties">
-      <Collection>
-        <NavigationPropertyPath>Supplier</NavigationPropertyPath>
-        <NavigationPropertyPath>Category</NavigationPropertyPath>
-      </Collection>
-    </PropertyValue>
-  </Record>
-</Annotation>
+
<Annotation Term="UI.HyperLink" NavigationPropertyPath="Supplier" />
+
+<Annotation Term="Capabilities.UpdateRestrictions">
+  <Record>
+    <PropertyValue Property="NonUpdatableNavigationProperties">
+      <Collection>
+        <NavigationPropertyPath>Supplier</NavigationPropertyPath>
+        <NavigationPropertyPath>Category</NavigationPropertyPath>
+      </Collection>
+    </PropertyValue>
+  </Record>
+</Annotation>

14.4.1.6 Property Path

The property path expression provides a value for terms or term properties that specify one of the built-in types Edm.PropertyPath, Edm.AnyPropertyPath, or Edm.ModelElementPath. Its argument is a model path with the following restriction:

@@ -2585,18 +2586,18 @@

E

Example 71:

-
<Annotation Term="UI.RefreshOnChangeOf" PropertyPath="ChangedAt" />
-
-<Annotation Term="Capabilities.UpdateRestrictions">
-  <Record>
-    <PropertyValue Property="NonUpdatableProperties">
-      <Collection>
-        <PropertyPath>CreatedAt</PropertyPath>
-        <PropertyPath>ChangedAt</PropertyPath>
-      </Collection>
-    </PropertyValue>
-  </Record>
-</Annotation>
+
<Annotation Term="UI.RefreshOnChangeOf" PropertyPath="ChangedAt" />
+
+<Annotation Term="Capabilities.UpdateRestrictions">
+  <Record>
+    <PropertyValue Property="NonUpdatableProperties">
+      <Collection>
+        <PropertyPath>CreatedAt</PropertyPath>
+        <PropertyPath>ChangedAt</PropertyPath>
+      </Collection>
+    </PropertyValue>
+  </Record>
+</Annotation>

14.4.1.7 Value Path

The value path expression allows assigning a value by traversing an object graph. It can be used in annotations that target entity containers, entity sets, entity types, complex types, navigation properties of structured types, and structural properties of structured types. Its argument is an instance path.

@@ -2607,11 +2608,11 @@

Expression

Example 72:

-
<Annotation Term="org.example.display.DisplayName" Path="FirstName" />
-
-<Annotation Term="org.example.display.DisplayName">
-  <Path>@vCard.Address#work/FullName</Path>
-</Annotation>
+
<Annotation Term="org.example.display.DisplayName" Path="FirstName" />
+
+<Annotation Term="org.example.display.DisplayName">
+  <Path>@vCard.Address#work/FullName</Path>
+</Annotation>

14.4.2 Comparison and Logical Operators

Annotations MAY use the following logical and comparison expressions which evaluate to a Boolean value. These expressions MAY be combined and they MAY be used anywhere instead of a Boolean expression.

@@ -2647,52 +2648,52 @@

Example 73:

-
<And>
-  <Path>IsMale</Path>
-  <Path>IsMarried</Path>
-</And>
-<Or>
-  <Path>IsMale</Path>
-  <Path>IsMarried</Path>
-</Or>
-<Not>
-  <Path>IsMale</Path>
-</Not>
-<Eq>
-  <Null />
-  <Path>IsMale</Path>
-</Eq>
-<Ne>
-  <Null />
-  <Path>IsMale</Path>
-</Ne>
-<Gt>
-  <Path>Price</Path>
-  <Int>20</Int>
-</Gt>
-<Ge>
-  <Path>Price</Path>
-  <Int>10</Int>
-</Ge>
-<Lt>
-  <Path>Price</Path>
-  <Int>20</Int>
-</Lt>
-<Le>
-  <Path>Price</Path>
-  <Int>100</Int>
-</Le>
-<Has>
-  <Path>Fabric</Path>
-  <EnumMember>org.example.Pattern/Red</EnumMember>
-</Has>
-<In>
-  <Path>Size</Path>
-  <Collection>
-    <String>XS</String>
-    <String>S</String>
-  </Collection>
-</In>
+
<And>
+  <Path>IsMale</Path>
+  <Path>IsMarried</Path>
+</And>
+<Or>
+  <Path>IsMale</Path>
+  <Path>IsMarried</Path>
+</Or>
+<Not>
+  <Path>IsMale</Path>
+</Not>
+<Eq>
+  <Null />
+  <Path>IsMale</Path>
+</Eq>
+<Ne>
+  <Null />
+  <Path>IsMale</Path>
+</Ne>
+<Gt>
+  <Path>Price</Path>
+  <Int>20</Int>
+</Gt>
+<Ge>
+  <Path>Price</Path>
+  <Int>10</Int>
+</Ge>
+<Lt>
+  <Path>Price</Path>
+  <Int>20</Int>
+</Lt>
+<Le>
+  <Path>Price</Path>
+  <Int>100</Int>
+</Le>
+<Has>
+  <Path>Fabric</Path>
+  <EnumMember>org.example.Pattern/Red</EnumMember>
+</Has>
+<In>
+  <Path>Size</Path>
+  <Collection>
+    <String>XS</String>
+    <String>S</String>
+  </Collection>
+</In>

14.4.3 Arithmetic Operators

Annotations MAY use the following arithmetic expressions which evaluate to a numeric value. These expressions MAY be combined, and they MAY be used anywhere instead of a numeric expression of the appropriate type. The semantics and evaluation rules for each arithmetic expression is identical to the corresponding arithmetic operator defined in OData-URL.

@@ -2745,33 +2746,33 @@

Example 74:

-
<Add>
-  <Path>StartDate</Path>
-  <Path>Duration</Path>
-</Add>
-<Sub>
-  <Path>Revenue</Path>
-  <Path>Cost</Path>
-</Sub>
-<Neg>
-  <Path>Height</Path>
-</Neg>
-<Mul>
-  <Path>NetPrice</Path>
-  <Path>TaxRate</Path>
-</Mul>
-<Div>
-  <Path>Quantity</Path>
-  <Path>QuantityPerParcel</Path>
-</Div>
-<DivBy>
-  <Path>Quantity</Path>
-  <Path>QuantityPerParcel</Path>
-</DivBy>
-<Mod>
-  <Path>Quantity</Path>
-  <Path>QuantityPerParcel</Path>
-</Mod>
+
<Add>
+  <Path>StartDate</Path>
+  <Path>Duration</Path>
+</Add>
+<Sub>
+  <Path>Revenue</Path>
+  <Path>Cost</Path>
+</Sub>
+<Neg>
+  <Path>Height</Path>
+</Neg>
+<Mul>
+  <Path>NetPrice</Path>
+  <Path>TaxRate</Path>
+</Mul>
+<Div>
+  <Path>Quantity</Path>
+  <Path>QuantityPerParcel</Path>
+</Div>
+<DivBy>
+  <Path>Quantity</Path>
+  <Path>QuantityPerParcel</Path>
+</DivBy>
+<Mod>
+  <Path>Quantity</Path>
+  <Path>QuantityPerParcel</Path>
+</Mod>

14.4.4 Apply Client-Side Functions

The apply expression enables a value to be obtained by applying a client-side function. The apply expression MAY have operand expressions. The operand expressions are used as parameters to the client-side function.

@@ -2788,17 +2789,17 @@

OData-ABNF, i.e. Edm.Binary as binaryValue, Edm.Boolean as booleanValue etc.

Example 75:

-
<Annotation Term="org.example.display.DisplayName">
-  <Apply Function="odata.concat">
-    <String>Product: </String>
-    <Path>ProductName</Path>
-    <String> (</String>
-    <Path>Available/Quantity</Path>
-    <String> </String>
-    <Path>Available/Unit</Path>
-    <String> available)</String>
-  </Apply>
-</Annotation>
+
<Annotation Term="org.example.display.DisplayName">
+  <Apply Function="odata.concat">
+    <String>Product: </String>
+    <Path>ProductName</Path>
+    <String> (</String>
+    <Path>Available/Quantity</Path>
+    <String> </String>
+    <Path>Available/Unit</Path>
+    <String> available)</String>
+  </Apply>
+</Annotation>

ProductName is of type String, Quantity in complex type Available is of type Decimal, and Unit in Available is of type enumeration, so the result of the Path expression is represented as the member name of the enumeration value.

14.4.4.2 Function odata.fillUriTemplate

@@ -2810,34 +2811,34 @@

labeled element expressions that evaluate to a collection of complex types with two properties that are used in lexicographic order. The first property is used as key, the second property as value.

Example 76: assuming there are no special characters in values of the Name property of the Actor entity

-
<Apply Function="odata.fillUriTemplate">
-  <String>http://host/someAPI/Actors/{actorName}/CV</String>
-  <LabeledElement Name="actorName" Path="Actor/Name" />
-</Apply>
+
<Apply Function="odata.fillUriTemplate">
+  <String>http://host/someAPI/Actors/{actorName}/CV</String>
+  <LabeledElement Name="actorName" Path="Actor/Name" />
+</Apply>

14.4.4.3 Function odata.matchesPattern

The odata.matchesPattern client-side function takes two string expressions as arguments and returns a Boolean value. It is the counterpart of the identically named URL function OData-URL, section 5.1.1.7.1.

The function returns true if the second expression evaluates to an ECMAScript (JavaScript) regular expression and the result of the first argument expression matches that regular expression, using syntax and semantics of ECMAScript regular expressions.

Example 77: all non-empty FirstName values not containing the letters b, c, or d evaluate to true

-
<Apply Function="odata.matchesPattern">
-  <Path>FirstName</Path>
-  <String>^[^b-d]+$</String>
-</Apply>
+
<Apply Function="odata.matchesPattern">
+  <Path>FirstName</Path>
+  <String>^[^b-d]+$</String>
+</Apply>

14.4.4.4 Function odata.uriEncode

The odata.uriEncode client-side function takes one argument of primitive type and returns the URL-encoded OData literal that can be used as a key value in OData URLs or in the query part of OData URLs.

Note: string literals are surrounded by single quotes as required by the paren-style key syntax.

Example 78:

-
<Apply Function="odata.fillUriTemplate">
-  <String>http://host/service/Genres({genreName})</String>
-  <LabeledElement Name="genreName">
-    <Apply Function="odata.uriEncode" >
-      <Path>NameOfMovieGenre</Path>
-    </Apply>
-  </LabeledElement>
-</Apply>
+
<Apply Function="odata.fillUriTemplate">
+  <String>http://host/service/Genres({genreName})</String>
+  <LabeledElement Name="genreName">
+    <Apply Function="odata.uriEncode" >
+      <Path>NameOfMovieGenre</Path>
+    </Apply>
+  </LabeledElement>
+</Apply>

14.4.5 Cast

The cast expression casts the value obtained from its single child expression to the specified type. The cast expression follows the same rules as the cast canonical function defined in OData-URL.

@@ -2851,11 +2852,11 @@

Example 79:

-
<Annotation Term="org.example.display.Threshold">
-  <Cast Type="Edm.Decimal">
-    <Path>Average</Path>
-  </Cast>
-</Annotation>
+
<Annotation Term="org.example.display.Threshold">
+  <Cast Type="Edm.Decimal">
+    <Path>Average</Path>
+  </Cast>
+</Annotation>

14.4.6 Collection

The collection expression enables a value to be obtained from zero or more item expressions. The value calculated by the collection expression is the collection of the values calculated by each of the item expressions. The values of the child expressions MUST all be type compatible.

@@ -2865,13 +2866,13 @@

Expre

Example 80:

-
<Annotation Term="org.example.seo.SeoTerms">
-  <Collection>
-    <String>Product</String>
-    <String>Supplier</String>
-    <String>Customer</String>
-  </Collection>
-</Annotation>
+
<Annotation Term="org.example.seo.SeoTerms">
+  <Collection>
+    <String>Product</String>
+    <String>Supplier</String>
+    <String>Customer</String>
+  </Collection>
+</Annotation>

14.4.7 If-Then-Else

The if-then-else expression enables a value to be obtained by evaluating a condition expression. It MUST contain exactly three child expressions. There is one exception to this rule: if and only if the if-then-else expression is an item of a collection expression, the third child expression MAY be omitted, reducing it to an if-then expression. This can be used to conditionally add an element to a collection.

@@ -2885,13 +2886,13 @@

Expression edm:

Example 81: the condition is a value path expression referencing the Boolean property IsFemale, whose value then determines the value of the edm:If expression (or so it was long ago)

-
<Annotation Term="org.example.person.Gender">
-  <If>
-    <Path>IsFemale</Path>
-    <String>Female</String>
-    <String>Male</String>
-  </If>
-</Annotation>
+
<Annotation Term="org.example.person.Gender">
+  <If>
+    <Path>IsFemale</Path>
+    <String>Female</String>
+    <String>Male</String>
+  </If>
+</Annotation>

14.4.8 Is-Of

The is-of expression checks whether the value obtained from its single child expression is compatible with the specified type. It returns true if the child expression returns a type that is compatible with the specified type, and false otherwise.

@@ -2903,11 +2904,11 @@

Expression

Example 82:

-
<Annotation Term="self.IsPreferredCustomer">
-  <IsOf Type="self.PreferredCustomer">
-    <Path>Customer</Path>
-  </IsOf>
-</Annotation>
+
<Annotation Term="self.IsPreferredCustomer">
+  <IsOf Type="self.PreferredCustomer">
+    <Path>Customer</Path>
+  </IsOf>
+</Annotation>

14.4.9 Labeled Element

The labeled element expression assigns a name to its single child expression. The value of the child expression can then be reused elsewhere with a labeled element reference expression.

@@ -2923,15 +2924,15 @@

Example 83:

-
<Annotation Term="org.example.display.DisplayName">
-  <LabeledElement Name="CustomerFirstName" Path="FirstName" />
-</Annotation>
-
-<Annotation Term="org.example.display.DisplayName">
-  <LabeledElement Name="CustomerFirstName">
-    <Path>FirstName</Path>
-  </LabeledElement>
-</Annotation>
+
<Annotation Term="org.example.display.DisplayName">
+  <LabeledElement Name="CustomerFirstName" Path="FirstName" />
+</Annotation>
+
+<Annotation Term="org.example.display.DisplayName">
+  <LabeledElement Name="CustomerFirstName">
+    <Path>FirstName</Path>
+  </LabeledElement>
+</Annotation>

14.4.10 Labeled Element Reference

The labeled element reference expression MUST specify the qualified name of a labeled element expression in scope and returns the value of the identified labeled element expression as its value.

@@ -2941,9 +2942,9 @@

Example 84:

-
<Annotation Term="org.example.display.DisplayName">
-  <LabeledElementReference>Model.CustomerFirstName</LabeledElementReference>
-</Annotation>
+
<Annotation Term="org.example.display.DisplayName">
+  <LabeledElementReference>Model.CustomerFirstName</LabeledElementReference>
+</Annotation>

14.4.11 Null

The null expression indicates the absence of a value. The null expression MAY be annotated.

@@ -2953,17 +2954,17 @@

Expression

Example 85:

-
<Annotation Term="org.example.display.DisplayName">
-  <Null/>
-</Annotation>
+
<Annotation Term="org.example.display.DisplayName">
+  <Null/>
+</Annotation>

Example 86:

-
<Annotation Term="@UI.Address">
-  <Null>
-    <Annotation Term="self.Reason" String="Private" />
-  </Null>
-</Annotation>
+
<Annotation Term="@UI.Address">
+  <Null>
+    <Annotation Term="self.Reason" String="Private" />
+  </Null>
+</Annotation>

14.4.12 Record

The record expression enables a new entity type or complex type instance to be constructed.

@@ -2984,27 +2985,27 @@

Example 87: this annotation “morphs” the entity type from example 13 into a structured type with two structural properties GivenName and Surname and two navigation properties DirectSupervisor and CostCenter. The first three properties simply rename properties of the annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service

-
<Annotations Target="org.example.Person">
-  <Annotation Term="org.example.hcm.Employee">
-    <Record Type="org.example.hcm.Manager">
-      <Annotation Term="Core.Description" String="Annotation on record" />
-      <PropertyValue Property="GivenName" Path="FirstName">
-        <Annotation Term="Core.Description"
-                    String="Annotation on record member" />
-      </PropertyValue>
-      <PropertyValue Property="Surname" Path="LastName" />
-      <PropertyValue Property="DirectSupervisor" Path="Manager" />
-      <PropertyValue Property="CostCenter">
-        <UrlRef>
-          <Apply Function="odata.fillUriTemplate">
-            <String>http://host/anotherservice/CostCenters('{ccid}')</String>
-            <LabeledElement Name="ccid" Path="CostCenterID" />
-          </Apply>
-        </UrlRef>
-      </PropertyValue>
-    </Record>
-  </Annotation>
-</Annotations>
+
<Annotations Target="org.example.Person">
+  <Annotation Term="org.example.hcm.Employee">
+    <Record Type="org.example.hcm.Manager">
+      <Annotation Term="Core.Description" String="Annotation on record" />
+      <PropertyValue Property="GivenName" Path="FirstName">
+        <Annotation Term="Core.Description"
+                    String="Annotation on record member" />
+      </PropertyValue>
+      <PropertyValue Property="Surname" Path="LastName" />
+      <PropertyValue Property="DirectSupervisor" Path="Manager" />
+      <PropertyValue Property="CostCenter">
+        <UrlRef>
+          <Apply Function="odata.fillUriTemplate">
+            <String>http://host/anotherservice/CostCenters('{ccid}')</String>
+            <LabeledElement Name="ccid" Path="CostCenterID" />
+          </Apply>
+        </UrlRef>
+      </PropertyValue>
+    </Record>
+  </Annotation>
+</Annotations>

14.4.13 URL Reference

The URL reference expression enables a value to be obtained by sending a GET request.

@@ -3018,24 +3019,24 @@

Expression

Example 88:

-
<Annotation Term="org.example.person.Supplier">
-  <UrlRef>
-    <Apply Function="odata.fillUriTemplate">
-      <String>http://host/service/Suppliers({suppID})</String>
-      <LabeledElement Name="suppID">
-      <Apply Function="odata.uriEncode">
-        <Path>SupplierId</Path>
-      </Apply>
-      </LabeledElement>
-     </Apply>
-  </UrlRef>
-</Annotation>
-
-<Annotation Term="Core.LongDescription">
-  <UrlRef><String>http://host/wiki/HowToUse</String></UrlRef>
-</Annotation>
-
-<Annotation Term="Core.LongDescription" UrlRef="http://host/wiki/HowToUse" />
+
<Annotation Term="org.example.person.Supplier">
+  <UrlRef>
+    <Apply Function="odata.fillUriTemplate">
+      <String>http://host/service/Suppliers({suppID})</String>
+      <LabeledElement Name="suppID">
+      <Apply Function="odata.uriEncode">
+        <Path>SupplierId</Path>
+      </Apply>
+      </LabeledElement>
+     </Apply>
+  </UrlRef>
+</Annotation>
+
+<Annotation Term="Core.LongDescription">
+  <UrlRef><String>http://host/wiki/HowToUse</String></UrlRef>
+</Annotation>
+
+<Annotation Term="Core.LongDescription" UrlRef="http://host/wiki/HowToUse" />

15 Identifier and Path Values

@@ -3073,153 +3074,153 @@

16 CSDL Ex

16.1 Products and Categories Example

Example 90:

-
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
-           xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">
-  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
-    <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
-      <Annotation Term="Core.DefaultNamespace" />
-    </edmx:Include>
-  </edmx:Reference>
-  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.xml">
-    <edmx:Include Alias="Measures" Namespace="Org.OData.Measures.V1" />
-  </edmx:Reference>
-  <edmx:DataServices>
-    <Schema Namespace="ODataDemo">
-      <EntityType Name="Product">
-        <Key>
-          <PropertyRef Name="ID" />
-        </Key>
-        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="Description" Type="Edm.String" >
-          <Annotation Term="Core.IsLanguageDependent" />
-        </Property>
-        <Property Name="ReleaseDate" Type="Edm.Date" />
-        <Property Name="DiscontinuedDate" Type="Edm.Date" />
-        <Property Name="Rating" Type="Edm.Int32" />
-        <Property Name="Price" Type="Edm.Decimal" Scale="variable">
-          <Annotation Term="Measures.ISOCurrency" Path="Currency" />
-        </Property>
-        <Property Name="Currency" Type="Edm.String" MaxLength="3" />
-        <NavigationProperty Name="Category" Type="ODataDemo.Category"
-                            Nullable="false" Partner="Products" />
-        <NavigationProperty Name="Supplier" Type="ODataDemo.Supplier"
-                            Partner="Products" />
-      </EntityType>
-      <EntityType Name="Category">
-        <Key>
-         <PropertyRef Name="ID" />
-        </Key>
-        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="Name" Type="Edm.String" Nullable="false">
-          <Annotation Term="Core.IsLanguageDependent" />
-        </Property>
-        <NavigationProperty Name="Products" Partner="Category"
-                            Type="Collection(ODataDemo.Product)">
-          <OnDelete Action="Cascade" />
-        </NavigationProperty>
-      </EntityType>
-      <EntityType Name="Supplier">
-        <Key>
-          <PropertyRef Name="ID" />
-        </Key>
-        <Property Name="ID" Type="Edm.String" Nullable="false" />
-        <Property Name="Name" Type="Edm.String" />
-        <Property Name="Address" Type="ODataDemo.Address" Nullable="false" />
-        <Property Name="Concurrency" Type="Edm.Int32" Nullable="false" />
-        <NavigationProperty Name="Products" Partner="Supplier"
-                            Type="Collection(ODataDemo.Product)" />
-      </EntityType>
-      <EntityType Name="Country">
-        <Key>
-          <PropertyRef Name="Code" />
-        </Key>
-        <Property Name="Code" Type="Edm.String" MaxLength="2"
-                              Nullable="false" />
-        <Property Name="Name" Type="Edm.String" />
-      </EntityType>
-      <ComplexType Name="Address">
-        <Property Name="Street" Type="Edm.String" />
-        <Property Name="City" Type="Edm.String" />
-        <Property Name="State" Type="Edm.String" />
-        <Property Name="ZipCode" Type="Edm.String" />
-        <Property Name="CountryName" Type="Edm.String" />
-        <NavigationProperty Name="Country" Type="ODataDemo.Country">
-          <ReferentialConstraint Property="CountryName"  
-                                 ReferencedProperty="Name" />
-        </NavigationProperty>
-      </ComplexType>
-      <Function Name="ProductsByRating">
-        <Parameter Name="Rating" Type="Edm.Int32" />
-        <ReturnType Type="Collection(ODataDemo.Product)" />
-      </Function>
-      <EntityContainer Name="DemoService">
-        <EntitySet Name="Products" EntityType="ODataDemo.Product">
-          <NavigationPropertyBinding Path="Category" Target="Categories" />
-        </EntitySet>
-        <EntitySet Name="Categories" EntityType="ODataDemo.Category">
-          <NavigationPropertyBinding Path="Products" Target="Products" />
-          <Annotation Term="Core.Description" String="Product Categories" />
-        </EntitySet>
-        <EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier">
-          <NavigationPropertyBinding Path="Products" Target="Products" />
-          <NavigationPropertyBinding Path="Address/Country"
-                                     Target="Countries" />
-          <Annotation Term="Core.OptimisticConcurrency">
-            <Collection>
-              <PropertyPath>Concurrency</PropertyPath>
-            </Collection>
-          </Annotation>
-        </EntitySet>
-        <Singleton Name="MainSupplier" Type="ODataDemo.Supplier">
-          <NavigationPropertyBinding Path="Products" Target="Products" />
-          <Annotation Term="Core.Description" String="Primary Supplier" />
-        </Singleton>
-        <EntitySet Name="Countries" EntityType="ODataDemo.Country" />
-        <FunctionImport Name="ProductsByRating" EntitySet="Products"
-                        Function="ODataDemo.ProductsByRating" />
-      </EntityContainer>
-    </Schema>
-  </edmx:DataServices>
-</edmx:Edmx>
+
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
+           xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">
+  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
+    <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
+      <Annotation Term="Core.DefaultNamespace" />
+    </edmx:Include>
+  </edmx:Reference>
+  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.xml">
+    <edmx:Include Alias="Measures" Namespace="Org.OData.Measures.V1" />
+  </edmx:Reference>
+  <edmx:DataServices>
+    <Schema Namespace="ODataDemo">
+      <EntityType Name="Product">
+        <Key>
+          <PropertyRef Name="ID" />
+        </Key>
+        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Description" Type="Edm.String" >
+          <Annotation Term="Core.IsLanguageDependent" />
+        </Property>
+        <Property Name="ReleaseDate" Type="Edm.Date" />
+        <Property Name="DiscontinuedDate" Type="Edm.Date" />
+        <Property Name="Rating" Type="Edm.Int32" />
+        <Property Name="Price" Type="Edm.Decimal" Scale="variable">
+          <Annotation Term="Measures.ISOCurrency" Path="Currency" />
+        </Property>
+        <Property Name="Currency" Type="Edm.String" MaxLength="3" />
+        <NavigationProperty Name="Category" Type="ODataDemo.Category"
+                            Nullable="false" Partner="Products" />
+        <NavigationProperty Name="Supplier" Type="ODataDemo.Supplier"
+                            Partner="Products" />
+      </EntityType>
+      <EntityType Name="Category">
+        <Key>
+         <PropertyRef Name="ID" />
+        </Key>
+        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Name" Type="Edm.String" Nullable="false">
+          <Annotation Term="Core.IsLanguageDependent" />
+        </Property>
+        <NavigationProperty Name="Products" Partner="Category"
+                            Type="Collection(ODataDemo.Product)">
+          <OnDelete Action="Cascade" />
+        </NavigationProperty>
+      </EntityType>
+      <EntityType Name="Supplier">
+        <Key>
+          <PropertyRef Name="ID" />
+        </Key>
+        <Property Name="ID" Type="Edm.String" Nullable="false" />
+        <Property Name="Name" Type="Edm.String" />
+        <Property Name="Address" Type="ODataDemo.Address" Nullable="false" />
+        <Property Name="Concurrency" Type="Edm.Int32" Nullable="false" />
+        <NavigationProperty Name="Products" Partner="Supplier"
+                            Type="Collection(ODataDemo.Product)" />
+      </EntityType>
+      <EntityType Name="Country">
+        <Key>
+          <PropertyRef Name="Code" />
+        </Key>
+        <Property Name="Code" Type="Edm.String" MaxLength="2"
+                              Nullable="false" />
+        <Property Name="Name" Type="Edm.String" />
+      </EntityType>
+      <ComplexType Name="Address">
+        <Property Name="Street" Type="Edm.String" />
+        <Property Name="City" Type="Edm.String" />
+        <Property Name="State" Type="Edm.String" />
+        <Property Name="ZipCode" Type="Edm.String" />
+        <Property Name="CountryName" Type="Edm.String" />
+        <NavigationProperty Name="Country" Type="ODataDemo.Country">
+          <ReferentialConstraint Property="CountryName"  
+                                 ReferencedProperty="Name" />
+        </NavigationProperty>
+      </ComplexType>
+      <Function Name="ProductsByRating">
+        <Parameter Name="Rating" Type="Edm.Int32" />
+        <ReturnType Type="Collection(ODataDemo.Product)" />
+      </Function>
+      <EntityContainer Name="DemoService">
+        <EntitySet Name="Products" EntityType="ODataDemo.Product">
+          <NavigationPropertyBinding Path="Category" Target="Categories" />
+        </EntitySet>
+        <EntitySet Name="Categories" EntityType="ODataDemo.Category">
+          <NavigationPropertyBinding Path="Products" Target="Products" />
+          <Annotation Term="Core.Description" String="Product Categories" />
+        </EntitySet>
+        <EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier">
+          <NavigationPropertyBinding Path="Products" Target="Products" />
+          <NavigationPropertyBinding Path="Address/Country"
+                                     Target="Countries" />
+          <Annotation Term="Core.OptimisticConcurrency">
+            <Collection>
+              <PropertyPath>Concurrency</PropertyPath>
+            </Collection>
+          </Annotation>
+        </EntitySet>
+        <Singleton Name="MainSupplier" Type="ODataDemo.Supplier">
+          <NavigationPropertyBinding Path="Products" Target="Products" />
+          <Annotation Term="Core.Description" String="Primary Supplier" />
+        </Singleton>
+        <EntitySet Name="Countries" EntityType="ODataDemo.Country" />
+        <FunctionImport Name="ProductsByRating" EntitySet="Products"
+                        Function="ODataDemo.ProductsByRating" />
+      </EntityContainer>
+    </Schema>
+  </edmx:DataServices>
+</edmx:Edmx>

16.2 Annotations for Products and Categories Example

Example 91:

-
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
-           Version="4.01">
-  <edmx:Reference Uri="http://host/service/$metadata">
-    <edmx:Include Namespace="ODataDemo" Alias="target" />
-  </edmx:Reference>
-  <edmx:Reference Uri="http://somewhere/Vocabulary/V1">
-    <edmx:Include Alias="Vocabulary1" Namespace="Some.Vocabulary.V1" />
-  </edmx:Reference>
-  <edmx:DataServices>
-    <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
-            Namespace="External.Annotations">
-      <Annotations Target="ODataDemo.Supplier">
-        <Annotation Term="Vocabulary1.EMail">
-          <Null />
-        </Annotation>
-        <Annotation Term="Vocabulary1.AccountID" Path="ID" />
-        <Annotation Term="Vocabulary1.Title" String="Supplier Info" />
-        <Annotation Term="Vocabulary1.DisplayName">
-        <Apply Function="odata.concat">
-            <Path>Name</Path>
-            <String> in </String>
-            <Path>Address/CountryName</Path>
-          </Apply>
-        </Annotation>
-      </Annotations>
-      <Annotations Target="ODataDemo.Product">
-        <Annotation Term="Vocabulary1.Tags">
-          <Collection>
-            <String>MasterData</String>
-          </Collection>
-        </Annotation>
-      </Annotations>
-  </Schema>
-  </edmx:DataServices>
-</edmx:Edmx>
+
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
+           Version="4.01">
+  <edmx:Reference Uri="http://host/service/$metadata">
+    <edmx:Include Namespace="ODataDemo" Alias="target" />
+  </edmx:Reference>
+  <edmx:Reference Uri="http://somewhere/Vocabulary/V1">
+    <edmx:Include Alias="Vocabulary1" Namespace="Some.Vocabulary.V1" />
+  </edmx:Reference>
+  <edmx:DataServices>
+    <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
+            Namespace="External.Annotations">
+      <Annotations Target="ODataDemo.Supplier">
+        <Annotation Term="Vocabulary1.EMail">
+          <Null />
+        </Annotation>
+        <Annotation Term="Vocabulary1.AccountID" Path="ID" />
+        <Annotation Term="Vocabulary1.Title" String="Supplier Info" />
+        <Annotation Term="Vocabulary1.DisplayName">
+        <Apply Function="odata.concat">
+            <Path>Name</Path>
+            <String> in </String>
+            <Path>Address/CountryName</Path>
+          </Apply>
+        </Annotation>
+      </Annotations>
+      <Annotations Target="ODataDemo.Product">
+        <Annotation Term="Vocabulary1.Tags">
+          <Collection>
+            <String>MasterData</String>
+          </Collection>
+        </Annotation>
+      </Annotations>
+  </Schema>
+  </edmx:DataServices>
+</edmx:Edmx>

17 Conformance

diff --git a/docs/odata-csdl-xml/odata-csdl-xml.md b/docs/odata-csdl-xml/odata-csdl-xml.md index 8fe7faf7c..754590c04 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.md +++ b/docs/odata-csdl-xml/odata-csdl-xml.md @@ -4191,9 +4191,14 @@ type specified by the navigation property are addressed via a [term-cast segment](#TermCast). ::: example -Example 64: model path addressing an annotation on a navigation property +Example 64: model path segment addressing an annotation on a navigation property +vs. term cast addressing an annotation on the resource addressed by the navigation property ``` -.../Items@Capabilities.InsertRestrictions/Insertable +.../Items@Core.Description +``` + +``` +.../Items/@Core.Description ``` ::: diff --git a/odata-csdl/14 Vocabulary and Annotation.md b/odata-csdl/14 Vocabulary and Annotation.md index 02ef3e82d..11712bf03 100644 --- a/odata-csdl/14 Vocabulary and Annotation.md +++ b/odata-csdl/14 Vocabulary and Annotation.md @@ -1351,9 +1351,14 @@ type specified by the navigation property are addressed via a [term-cast segment](#TermCast). ::: example -Example ##ex: model path addressing an annotation on a navigation property +Example ##ex: model path segment addressing an annotation on a navigation property +vs. term cast addressing an annotation on the resource addressed by the navigation property ``` -.../Items@Capabilities.InsertRestrictions/Insertable +.../Items@Core.Description +``` + +``` +.../Items/@Core.Description ``` ::: From 34410b20de6b8ff5bc111480f1d14cc4d1598e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Wed, 29 Nov 2023 17:39:00 +0100 Subject: [PATCH 06/22] ODATA-1553 (#174) --- docs/odata-url-conventions/odata-url-conventions.html | 2 +- docs/odata-url-conventions/odata-url-conventions.md | 3 +++ odata-url-conventions/5 Query Options.md | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/odata-url-conventions/odata-url-conventions.html b/docs/odata-url-conventions/odata-url-conventions.html index b1c4de110..f345701b0 100644 --- a/docs/odata-url-conventions/odata-url-conventions.html +++ b/docs/odata-url-conventions/odata-url-conventions.html @@ -1910,7 +1910,7 @@

5.1.10 System Query Option $compute

The $compute system query option allows clients to define computed properties that can be used in a $select or within a $filter or $orderby expression.

The $compute system query option is interpreted relative to the entity type or complex type of the resources identified by the resource path section of the URL.

-

The value of $compute is a comma-separated list of compute instructions, each consisting of a common expression followed by the keyword as, followed by the name for the computed dynamic property. This name MUST differ from the names of declared or dynamic properties of the identified resources.

+

The value of $compute is a comma-separated list of compute instructions, each consisting of a common expression followed by the keyword as, followed by the name for the computed dynamic property. This name MUST differ from the names of declared or dynamic properties of the identified resources. Services MAY support compute instructions that address dynamic properties added by other compute instructions within the same $compute system query option, provided that the service can determine an evaluation sequence.

The OData-ABNF compute syntax rule defines the formal grammar of the $compute query option.

Computed properties SHOULD be included as dynamic properties in the result and MUST be included if $select is specified with the computed property name, or star (*).

diff --git a/docs/odata-url-conventions/odata-url-conventions.md b/docs/odata-url-conventions/odata-url-conventions.md index 89c0e757b..b913c1552 100644 --- a/docs/odata-url-conventions/odata-url-conventions.md +++ b/docs/odata-url-conventions/odata-url-conventions.md @@ -3780,6 +3780,9 @@ expression](#CommonExpressionSyntax) followed by the keyword `as`, followed by the name for the computed dynamic property. This name MUST differ from the names of declared or dynamic properties of the identified resources. +Services MAY support compute instructions that address +dynamic properties added by other compute instructions within the same +`$compute` system query option, provided that the service can determine an evaluation sequence. The [OData-ABNF](#ODataABNF) `compute` syntax rule defines the formal grammar of the `$compute` query option. diff --git a/odata-url-conventions/5 Query Options.md b/odata-url-conventions/5 Query Options.md index 2275ac6b4..6bb1854a0 100644 --- a/odata-url-conventions/5 Query Options.md +++ b/odata-url-conventions/5 Query Options.md @@ -2381,6 +2381,9 @@ expression](#CommonExpressionSyntax) followed by the keyword `as`, followed by the name for the computed dynamic property. This name MUST differ from the names of declared or dynamic properties of the identified resources. +Services MAY support compute instructions that address +dynamic properties added by other compute instructions within the same +`$compute` system query option, provided that the service can determine an evaluation sequence. The [OData-ABNF](#ODataABNF) `compute` syntax rule defines the formal grammar of the `$compute` query option. From 00da66623b9ee5696962ed1ba99334011572b85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Wed, 29 Nov 2023 17:49:41 +0100 Subject: [PATCH 07/22] ODATA-1555 (#173) --- docs/odata-protocol/odata-protocol.html | 9 ++++-- docs/odata-protocol/odata-protocol.md | 36 +++++++++++++++------- odata-protocol/11 Data Service Requests.md | 36 +++++++++++++++------- 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html index d948d856f..40cca6ad2 100644 --- a/docs/odata-protocol/odata-protocol.html +++ b/docs/odata-protocol/odata-protocol.html @@ -1531,14 +1531,17 @@

GET http://host/service/Categories?$orderby=Products/$count

11.2.6.3 System Query Option $top

-

The $top system query option specifies a non-negative integer n that limits the number of items returned from a collection. The service returns the number of available items up to but not greater than the specified value n.

+

The $top system query option specifies a non-negative integer \(n\) that limits the number of items returned from a collection.

+

Let \(A\) be a copy of the result set with a total order that extends any existing order of the result set but is otherwise chosen by the service. If no unique ordering is imposed through an $orderby query option, the service MUST choose a stable ordering across requests that include $top or $skip.

+

If \(A\) contains more than \(n\) instances, the result of \({\tt \$top}=n\) consists of the first \(n\) instances in \(A\). Otherwise, the result equals \(A\). The instances in the result are in the same order as they occur in \(A\).

Example 53: return only the first five products of the Products entity set

GET http://host/service/Products?$top=5
-

If no unique ordering is imposed through an $orderby query option, the service MUST impose a stable ordering across requests that include $top.

11.2.6.4 System Query Option $skip

-

The $skip system query option specifies a non-negative integer n that excludes the first n items of the queried collection from the result. The service returns items starting at position n+1.

+

The $skip system query option specifies a non-negative integer \(n\) that excludes the first \(n\) items of the queried collection from the result.

+

Let \(A\) be a copy of the result set with a total order that extends any existing order of the result set but is otherwise chosen by the service. If no unique ordering is imposed through an $orderby query option, the service MUST choose a stable ordering across requests that include $top or $skip.

+

If \(A\) contains \(n\) or fewer instances, the result of \({\tt \$skip}=n\) is empty. Otherwise, the first \(n\) instances in \(A\) are omitted from the result and all remaining instances are kept in the same order as they occur in \(A\).

Example 54: return products starting with the 6th product of the Products entity set

GET http://host/service/Products?$skip=5
diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md index 8158cc6b0..4e4ff2d6d 100644 --- a/docs/odata-protocol/odata-protocol.md +++ b/docs/odata-protocol/odata-protocol.md @@ -3336,10 +3336,18 @@ GET http://host/service/Categories?$orderby=Products/$count #### 11.2.6.3 System Query Option `$top` -The `$top` system query option specifies a non-negative integer n that -limits the number of items returned from a collection. The service -returns the number of available items up to but not greater than the -specified value n. +The `$top` system query option specifies a non-negative integer $n$ that +limits the number of items returned from a collection. + +Let $A$ be a copy of the result set with a total order that extends any +existing order of the result set but is otherwise chosen by the service. If no +unique ordering is imposed through an [`$orderby`](#SystemQueryOptionorderby) +query option, the service MUST choose a stable +ordering across requests that include `$top` or [`$skip`](#SystemQueryOptionskip). + +If $A$ contains more than $n$ instances, the result of ${\tt \$top}=n$ +consists of the first $n$ instances in $A$. Otherwise, the result equals $A$. +The instances in the result are in the same order as they occur in $A$. ::: example Example 53: return only the first five products of the Products entity @@ -3349,15 +3357,21 @@ GET http://host/service/Products?$top=5 ``` ::: -If no unique ordering is imposed through an -[`$orderby`](#SystemQueryOptionorderby) query option, the service MUST -impose a stable ordering across requests that include `$top`. - #### 11.2.6.4 System Query Option `$skip` -The `$skip` system query option specifies a non-negative integer n that -excludes the first n items of the queried collection from the result. -The service returns items starting at position n+1. +The `$skip` system query option specifies a non-negative integer $n$ that +excludes the first $n$ items of the queried collection from the result. + +Let $A$ be a copy of the result set with a total order that extends any +existing order of the result set but is otherwise chosen by the service. If no +unique ordering is imposed through an [`$orderby`](#SystemQueryOptionorderby) +query option, the service MUST choose a stable +ordering across requests that include [`$top`](#SystemQueryOptiontop) or `$skip`. + +If $A$ contains $n$ or fewer instances, the result of ${\tt \$skip}=n$ +is empty. Otherwise, the first $n$ instances in $A$ are omitted +from the result and all remaining instances are kept in the same order as +they occur in $A$. ::: example Example 54: return products starting with the 6th product of the diff --git a/odata-protocol/11 Data Service Requests.md b/odata-protocol/11 Data Service Requests.md index d356be30a..705ab2b59 100644 --- a/odata-protocol/11 Data Service Requests.md +++ b/odata-protocol/11 Data Service Requests.md @@ -802,10 +802,18 @@ GET http://host/service/Categories?$orderby=Products/$count #### ##subsubsubsec System Query Option `$top` -The `$top` system query option specifies a non-negative integer n that -limits the number of items returned from a collection. The service -returns the number of available items up to but not greater than the -specified value n. +The `$top` system query option specifies a non-negative integer $n$ that +limits the number of items returned from a collection. + +Let $A$ be a copy of the result set with a total order that extends any +existing order of the result set but is otherwise chosen by the service. If no +unique ordering is imposed through an [`$orderby`](#SystemQueryOptionorderby) +query option, the service MUST choose a stable +ordering across requests that include `$top` or [`$skip`](#SystemQueryOptionskip). + +If $A$ contains more than $n$ instances, the result of ${\tt \$top}=n$ +consists of the first $n$ instances in $A$. Otherwise, the result equals $A$. +The instances in the result are in the same order as they occur in $A$. ::: example Example ##ex: return only the first five products of the Products entity @@ -815,15 +823,21 @@ GET http://host/service/Products?$top=5 ``` ::: -If no unique ordering is imposed through an -[`$orderby`](#SystemQueryOptionorderby) query option, the service MUST -impose a stable ordering across requests that include `$top`. - #### ##subsubsubsec System Query Option `$skip` -The `$skip` system query option specifies a non-negative integer n that -excludes the first n items of the queried collection from the result. -The service returns items starting at position n+1. +The `$skip` system query option specifies a non-negative integer $n$ that +excludes the first $n$ items of the queried collection from the result. + +Let $A$ be a copy of the result set with a total order that extends any +existing order of the result set but is otherwise chosen by the service. If no +unique ordering is imposed through an [`$orderby`](#SystemQueryOptionorderby) +query option, the service MUST choose a stable +ordering across requests that include [`$top`](#SystemQueryOptiontop) or `$skip`. + +If $A$ contains $n$ or fewer instances, the result of ${\tt \$skip}=n$ +is empty. Otherwise, the first $n$ instances in $A$ are omitted +from the result and all remaining instances are kept in the same order as +they occur in $A$. ::: example Example ##ex: return products starting with the 6th product of the From cac53eb05172c7a3c5ca96d2281e9ba09765a658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Wed, 29 Nov 2023 17:53:42 +0100 Subject: [PATCH 08/22] ODATA-1584 (#177) Co-authored-by: Ralf Handl --- docs/odata-protocol/odata-protocol.html | 2 +- docs/odata-protocol/odata-protocol.md | 3 ++- odata-protocol/11 Data Service Requests.md | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html index 40cca6ad2..4ba419955 100644 --- a/docs/odata-protocol/odata-protocol.html +++ b/docs/odata-protocol/odata-protocol.html @@ -1309,7 +1309,7 @@

$select and $expand system query options enable the client to specify the set of structural properties and navigation properties to include in a response. The service MAY include additional properties not specified in $select and $expand, including properties not defined in the metadata document.

11.2.5.1 System Query Option $select

The $select system query option requests that the service return only the properties, dynamic properties, actions and functions explicitly requested by the client. The service returns the specified content, if available, along with any available expanded navigation or stream properties, and MAY return additional information.

-

The value of the $select query option is a comma-separated list of properties, qualified action names, qualified function names, the star operator (*), or the star operator prefixed with the namespace or alias of the schema in order to specify all operations defined in the schema. Only aliases defined in the metadata document of the service can be used in URLs.

+

The value of the $select query option is a comma-separated list of paths that end with properties, non-entity-valued instance annotations, qualified action names, or qualified function names, as well as of the star operator (*), or the star operator prefixed with the namespace or alias of the schema in order to specify all operations defined in the schema. Only aliases defined in the metadata document of the service can be used in URLs.

Example 33: request only the Rating and ReleaseDate for the matching Products

GET http://host/service/Products?$select=Rating,ReleaseDate
diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md index 4e4ff2d6d..de17ee23c 100644 --- a/docs/odata-protocol/odata-protocol.md +++ b/docs/odata-protocol/odata-protocol.md @@ -2839,7 +2839,8 @@ returns the specified content, if available, along with any available and MAY return additional information. The value of the `$select` query option is a comma-separated list of -properties, qualified action names, qualified function names, the star +paths that end with properties, non-entity-valued instance annotations, +qualified action names, or qualified function names, as well as of the star operator (`*`), or the star operator prefixed with the namespace or alias of the schema in order to specify all operations defined in the schema. Only aliases defined in the metadata document of the service can diff --git a/odata-protocol/11 Data Service Requests.md b/odata-protocol/11 Data Service Requests.md index 705ab2b59..ebfe0e577 100644 --- a/odata-protocol/11 Data Service Requests.md +++ b/odata-protocol/11 Data Service Requests.md @@ -305,7 +305,8 @@ returns the specified content, if available, along with any available and MAY return additional information. The value of the `$select` query option is a comma-separated list of -properties, qualified action names, qualified function names, the star +paths that end with properties, non-entity-valued instance annotations, +qualified action names, or qualified function names, as well as of the star operator (`*`), or the star operator prefixed with the namespace or alias of the schema in order to specify all operations defined in the schema. Only aliases defined in the metadata document of the service can From 4993adbead02d71b4748cc0e4b23e2cc8caad7c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Wed, 29 Nov 2023 17:56:53 +0100 Subject: [PATCH 09/22] ODATA-1591 (#172) --- docs/odata-protocol/odata-protocol.html | 2 +- docs/odata-protocol/odata-protocol.md | 2 +- odata-protocol/11 Data Service Requests.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html index 4ba419955..507bf5dfb 100644 --- a/docs/odata-protocol/odata-protocol.html +++ b/docs/odata-protocol/odata-protocol.html @@ -1611,7 +1611,7 @@

Entities are stably addressable using their canonical URL and are not accessible using an ordinal index.

Example 64: the first address in a list of addresses for MainSupplier

-
GET http://host/service/Suppliers(MainSupplier)/Addresses/0
+
GET http://host/service/MainSupplier/Addresses/0

To request related entities according to a particular relationship, the client issues a GET request to the source entity’s request URL, followed by a forward slash and the name of the navigation property representing the relationship.

diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md index de17ee23c..9cf70d6eb 100644 --- a/docs/odata-protocol/odata-protocol.md +++ b/docs/odata-protocol/odata-protocol.md @@ -3557,7 +3557,7 @@ accessible using an ordinal index. ::: example Example 64: the first address in a list of addresses for `MainSupplier` ``` -GET http://host/service/Suppliers(MainSupplier)/Addresses/0 +GET http://host/service/MainSupplier/Addresses/0 ``` ::: diff --git a/odata-protocol/11 Data Service Requests.md b/odata-protocol/11 Data Service Requests.md index ebfe0e577..20ecf449b 100644 --- a/odata-protocol/11 Data Service Requests.md +++ b/odata-protocol/11 Data Service Requests.md @@ -1023,7 +1023,7 @@ accessible using an ordinal index. ::: example Example ##ex: the first address in a list of addresses for `MainSupplier` ``` -GET http://host/service/Suppliers(MainSupplier)/Addresses/0 +GET http://host/service/MainSupplier/Addresses/0 ``` ::: From 2b014dba5e1a4c5cac1b46fe233fb565f723afca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Wed, 29 Nov 2023 17:59:21 +0100 Subject: [PATCH 10/22] ODATA-1592 (#94) --- docs/odata-csdl-json/odata-csdl-json.html | 8 ++-- docs/odata-csdl-json/odata-csdl-json.md | 8 ++-- docs/odata-csdl-xml/odata-csdl-xml.html | 52 ++++++++++++----------- docs/odata-csdl-xml/odata-csdl-xml.md | 12 ++++-- odata-csdl/4 CSDL Document.md | 20 +++++---- 5 files changed, 56 insertions(+), 44 deletions(-) diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html index 516403bc1..b9c650b22 100644 --- a/docs/odata-csdl-json/odata-csdl-json.html +++ b/docs/odata-csdl-json/odata-csdl-json.html @@ -826,10 +826,10 @@

{
   ...
   "$Reference": {
-    "http://vocabs.odata.org/capabilities/v1": {
+    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
       ...
     },
-    "http://vocabs.odata.org/core/v1": {
+    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
       ...
     },
     "http://example.org/display/v1": {
@@ -863,7 +863,7 @@ 

$Alias

{
   ...
   "$Reference": {
-    "http://vocabs.odata.org/capabilities/v1": {
+    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
       "$Include": [
         {
           "$Namespace": "Org.OData.Capabilities.V1",
@@ -871,7 +871,7 @@ 

$Alias

} ] }, - "http://vocabs.odata.org/core/v1": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { "$Include": [ { "$Namespace": "Org.OData.Core.V1", diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md index b66d706d2..05f9a52e9 100644 --- a/docs/odata-csdl-json/odata-csdl-json.md +++ b/docs/odata-csdl-json/odata-csdl-json.md @@ -985,10 +985,10 @@ Example 8: references to other CSDL documents { ... "$Reference": { - "http://vocabs.odata.org/capabilities/v1": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { ... }, - "http://vocabs.odata.org/core/v1": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { ... }, "http://example.org/display/v1": { @@ -1063,7 +1063,7 @@ vocabulary terms { ... "$Reference": { - "http://vocabs.odata.org/capabilities/v1": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { "$Include": [ { "$Namespace": "Org.OData.Capabilities.V1", @@ -1071,7 +1071,7 @@ vocabulary terms } ] }, - "http://vocabs.odata.org/core/v1": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { "$Include": [ { "$Namespace": "Org.OData.Core.V1", diff --git a/docs/odata-csdl-xml/odata-csdl-xml.html b/docs/odata-csdl-xml/odata-csdl-xml.html index bf05facbe..5bb609002 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.html +++ b/docs/odata-csdl-xml/odata-csdl-xml.html @@ -804,17 +804,19 @@

Attri
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
            Version="4.0">
-  <edmx:Reference Uri="http://vocabs.odata.org/capabilities/v1">
-   ...
-  </edmx:Reference>
-  <edmx:Reference Uri="http://vocabs.odata.org/core/v1">
-    ...
-  </edmx:Reference>
-  <edmx:Reference Uri="http://example.org/display/v1">
-    ...
-  </edmx:Reference>
-  <edmx:DataServices>...</edmx:DataServices>
-</edmx:Edmx>
+ <edmx:Reference + Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml"> + ... + </edmx:Reference> + <edmx:Reference + Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml"> + ... + </edmx:Reference> + <edmx:Reference Uri="http://example.org/display/v1"> + ... + </edmx:Reference> + <edmx:DataServices>...</edmx:DataServices> +</edmx:Edmx>

4.2 Included Schema

A reference MAY include zero or more schemas from the referenced document.

@@ -840,19 +842,21 @@

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
            Version="4.0">
-  <edmx:Reference Uri="http://vocabs.odata.org/capabilities/v1">
-    <edmx:Include Namespace="Org.OData.Capabilities.V1" />
-  </edmx:Reference>
-  <edmx:Reference Uri="http://vocabs.odata.org/core/v1">
-    <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
-      <Annotation Term="Core.DefaultNamespace" />
-    </edmx:Include>
-  </edmx:Reference>
-  <edmx:Reference Uri="http://example.org/display/v1">
-    <edmx:Include Alias="UI" Namespace="org.example.display" />
-  </edmx:Reference>
-  <edmx:DataServices>...</edmx:DataServices>
-</edmx:Edmx>
+ <edmx:Reference + Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml"> + <edmx:Include Namespace="Org.OData.Capabilities.V1" /> + </edmx:Reference> + <edmx:Reference + Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml"> + <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core"> + <Annotation Term="Core.DefaultNamespace" /> + </edmx:Include> + </edmx:Reference> + <edmx:Reference Uri="http://example.org/display/v1"> + <edmx:Include Alias="UI" Namespace="org.example.display" /> + </edmx:Reference> + <edmx:DataServices>...</edmx:DataServices> +</edmx:Edmx>

4.3 Included Annotations

In addition to including whole schemas with all model constructs defined within that schema, a reference may include annotations.

diff --git a/docs/odata-csdl-xml/odata-csdl-xml.md b/docs/odata-csdl-xml/odata-csdl-xml.md index 754590c04..d3587a01e 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.md +++ b/docs/odata-csdl-xml/odata-csdl-xml.md @@ -929,10 +929,12 @@ Example 8: references to other CSDL documents - + ... - + ... @@ -1009,10 +1011,12 @@ vocabulary terms - + - + diff --git a/odata-csdl/4 CSDL Document.md b/odata-csdl/4 CSDL Document.md index c119d00bc..7674fb830 100644 --- a/odata-csdl/4 CSDL Document.md +++ b/odata-csdl/4 CSDL Document.md @@ -125,10 +125,10 @@ Example ##ex: references to other CSDL documents { ... "$Reference": { - "http://vocabs.odata.org/capabilities/v1": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { ... }, - "http://vocabs.odata.org/core/v1": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { ... }, "http://example.org/display/v1": { @@ -169,10 +169,12 @@ Example ##ex: references to other CSDL documents - + ... - + ... @@ -252,7 +254,7 @@ vocabulary terms { ... "$Reference": { - "http://vocabs.odata.org/capabilities/v1": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { "$Include": [ { "$Namespace": "Org.OData.Capabilities.V1", @@ -260,7 +262,7 @@ vocabulary terms } ] }, - "http://vocabs.odata.org/core/v1": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { "$Include": [ { "$Namespace": "Org.OData.Core.V1", @@ -310,10 +312,12 @@ vocabulary terms - + - + From 2abb246d78b3778f833e7a7d6f0f23a66e097bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Wed, 29 Nov 2023 18:02:40 +0100 Subject: [PATCH 11/22] ODATA-1602: Example 39 applies to Term (#186) --- docs/odata-csdl-json/odata-csdl-json.html | 13 +++++++------ docs/odata-csdl-json/odata-csdl-json.md | 3 ++- odata-csdl/14 Vocabulary and Annotation.md | 3 ++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html index b9c650b22..410f6e9cd 100644 --- a/docs/odata-csdl-json/odata-csdl-json.html +++ b/docs/odata-csdl-json/odata-csdl-json.html @@ -2200,12 +2200,13 @@

$AppliesTo "$Type": "Core.Tag", "$DefaultValue": true, "$AppliesTo": [ - "Property" - ], - "@Core.Description": "Properties and terms annotated with this term -MUST contain a valid URL", - "@Core.RequiresType": "Edm.String" -} + "Property", + "Term" + ], + "@Core.Description": "Properties and terms annotated with this term +MUST contain a valid URL", + "@Core.RequiresType": "Edm.String" +}

14.2 Annotation

An annotation applies a term to a model element and defines how to calculate a value for the term application. Both term and model element MUST be in scope. Section 14.1.2 specifies which model elements MAY be annotated with a term.

diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md index 05f9a52e9..1a2219d5d 100644 --- a/docs/odata-csdl-json/odata-csdl-json.md +++ b/docs/odata-csdl-json/odata-csdl-json.md @@ -3700,7 +3700,8 @@ are defined in [OData-VocCore](#ODataVocCore)) "$Type": "Core.Tag", "$DefaultValue": true, "$AppliesTo": [ - "Property" + "Property", + "Term" ], "@Core.Description": "Properties and terms annotated with this term MUST contain a valid URL", diff --git a/odata-csdl/14 Vocabulary and Annotation.md b/odata-csdl/14 Vocabulary and Annotation.md index 11712bf03..af862b3e4 100644 --- a/odata-csdl/14 Vocabulary and Annotation.md +++ b/odata-csdl/14 Vocabulary and Annotation.md @@ -346,7 +346,8 @@ are defined in [OData-VocCore](#ODataVocCore)) "$Type": "Core.Tag", "$DefaultValue": true, "$AppliesTo": [ - "Property" + "Property", + "Term" ], "@Core.Description": "Properties and terms annotated with this term MUST contain a valid URL", From eaf27e931212509a9d79ea1e11fd15343efa5689 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Wed, 29 Nov 2023 18:11:04 +0100 Subject: [PATCH 12/22] ODATA-1398 (#195) --- docs/odata-json-format/odata-json-format.html | 55 ++++++++++--------- docs/odata-json-format/odata-json-format.md | 5 ++ docs/odata-protocol/odata-protocol.html | 16 +++--- docs/odata-protocol/odata-protocol.md | 34 ++++++------ .../19 Batch Requests and Responses.md | 5 ++ odata-protocol/11.7 Batch Requests.md | 34 ++++++------ 6 files changed, 82 insertions(+), 67 deletions(-) diff --git a/docs/odata-json-format/odata-json-format.html b/docs/odata-json-format/odata-json-format.html index 0b889c779..2336c1fb6 100644 --- a/docs/odata-json-format/odata-json-format.html +++ b/docs/odata-json-format/odata-json-format.html @@ -1673,32 +1673,37 @@

19.5 B

Relative URLs in a response object follow the rules for relative URLs based on the request URL of the corresponding request. Especially: URLs in responses MUST NOT contain $-prefixed request identifiers.

Example 51: referencing the batch request example 48 above, assume all the requests except the final query request succeed. In this case the response would be

-
{
-  "responses": [
-    {
-      "id": "0",
-      "status": 200,
-      "body": <JSON representation of the Customer entity with key ALFKI>
-    },
+
HTTP/1.1 200 OK
+OData-Version: 4.01
+Content-Length: ####
+Content-Type: application/json
+
+{
+  "responses": [
     {
-      "id": "1",
-      "status": 204
-    },
-    {
-      "id": "2",
-      "status": 201,
-      "headers": {
-        "location": "http://host/service.svc/Customer('POIUY')"
-      },
-      "body": <JSON representation of the new Customer entity>
-    },
-    {
-      "id": "3",
-      "status": 404,
-      "body": <Error message>
-    }
-  ]
-}
+ "id": "0", + "status": 200, + "body": <JSON representation of the Customer entity with key ALFKI> + }, + { + "id": "1", + "status": 204 + }, + { + "id": "2", + "status": 201, + "headers": { + "location": "http://host/service.svc/Customer('POIUY')" + }, + "body": <JSON representation of the new Customer entity> + }, + { + "id": "3", + "status": 404, + "body": <Error message> + } + ] +}

19.6 Asynchronous Batch Requests

A batch request that specifies the respond-async preference MAY be executed asynchronously. This means that the “outer” batch request is executed asynchronously; this preference does not automatically cascade down to the individual requests within the batch. After successful execution of the batch request the response to the batch request is returned in the body of a response to an interrogation request against the status monitor resource URL, see section “Asynchronous Requests” in OData-Protocol.

diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md index b5eb8eb96..bcf80d345 100644 --- a/docs/odata-json-format/odata-json-format.md +++ b/docs/odata-json-format/odata-json-format.md @@ -3198,6 +3198,11 @@ Example 51: referencing the batch request [example 48](#batchRequest) above, ass the requests except the final query request succeed. In this case the response would be ```json +HTTP/1.1 200 OK +OData-Version: 4.01 +Content-Length: #### +Content-Type: application/json + { "responses": [ { diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html index 507bf5dfb..2e34909dc 100644 --- a/docs/odata-protocol/odata-protocol.html +++ b/docs/odata-protocol/odata-protocol.html @@ -2234,6 +2234,8 @@

11.7 B

Batch requests are submitted as a single HTTP POST request to the batch endpoint of a service, located at the URL $batch relative to the service root.

Individual requests within a batch request are evaluated according to the same semantics used when the request appears outside the context of a batch request.

A batch request is represented using either the multipart batch format defined in this document or the JSON batch format defined in OData-JSON.

+

If the set of request headers of a batch request are valid the service MUST return a 200 OK HTTP response code to indicate that the batch request was accepted for processing, even if the processing is yet to be completed. The individual requests within the body of the batch request may be processed as soon as they are received, this enables clients to stream batch requests, and batch implementations to stream the results.

+

If the service receives a batch request with an invalid set of headers it MUST return a 4xx response code and perform no further processing of the batch request.

11.7.1 Batch Request Headers

A batch request using the multipart batch format MUST contain a Content-Type header specifying a content type of multipart/mixed and a boundary parameter as defined in RFC2046.

@@ -2257,8 +2259,6 @@

Accept header specifying the desired batch response format, either multipart/mixed or application/json. If no Accept header is provided, services SHOULD respond with the content type of the request.

-

If the set of request headers of a batch request are valid the service MUST return a 200 OK HTTP response code to indicate that the batch request was accepted for processing, but the processing is yet to be completed. The individual requests within the body of the batch request may subsequently fail or be malformed; however, this enables batch implementations to stream the results.

-

If the service receives a batch request with an invalid set of headers it MUST return a 4xx response code and perform no further processing of the batch request.

11.7.2 Request Dependencies

Requests within a batch may have dependencies on other requests according to the particular batch format.

In the JSON format, requests may explicitly declare a dependency on other requests that must be successfully processed before the current request. In addition, requests may be specified as part of an atomicity group whose members MUST either all succeed, or all fail. If a request fails, then any dependent requests within the JSON format return 424 Failed Dependency.

@@ -2470,7 +2470,7 @@

Data Service Requests. Relative URLs in each individual response are relative to the request URL of the corresponding individual request. URLs in responses MUST NOT contain $-prefixed request identifiers.

Example 107: referencing the batch request example 101 above, assume all the requests except the final query request succeed. In this case the response would be

-
HTTP/1.1 200 Ok
+
HTTP/1.1 200 OK
 OData-Version: 4.0
 Content-Length: ####
 Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -2478,7 +2478,7 @@ 

When interrogating the monitor URL only the first request in the batch has finished processing and all the remaining requests are still being processed. Note that the actual multipart batch response itself is contained in an application/http wrapper as it is a response to a status monitor resource:

-
HTTP/1.1 200 Ok
+
HTTP/1.1 200 OK
 Content-Type: application/http
 
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 OData-Version: 4.0
 Content-Length: ####
 Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -2539,7 +2539,7 @@ 

After some time the client makes a second request using the returned monitor URL, not explicitly accepting application/http. The batch is completely processed and the response is the final result.

-
HTTP/1.1 200 Ok
+
HTTP/1.1 200 OK
 AsyncResult: 200
 OData-Version: 4.0
 Content-Length: ####
diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md
index 9cf70d6eb..109bb298a 100644
--- a/docs/odata-protocol/odata-protocol.md
+++ b/docs/odata-protocol/odata-protocol.md
@@ -5684,6 +5684,17 @@ A batch request is represented using either the [multipart batch
 format](#MultipartBatchFormat) defined in this document or the JSON
 batch format defined in [OData-JSON](#ODataJSON).
 
+If the set of request headers of a batch request are valid the service
+MUST return a [`200 OK`](#ResponseCode200OK) HTTP response code to
+indicate that the batch request was accepted for processing, even if the
+processing is yet to be completed. The individual requests within the
+body of the batch request may be processed as soon as they are received,
+this enables clients to stream batch requests, and batch implementations to stream the results.
+
+If the service receives a batch request with an invalid set of headers
+it MUST return a [`4xx response code`](#ClientErrorResponses) and
+perform no further processing of the batch request.
+
 ### 11.7.1 Batch Request Headers
 
 A batch request using the [multipart batch
@@ -5726,17 +5737,6 @@ specifying the desired batch response format, either `multipart/mixed`
 or `application/json`. If no `Accept` header is provided, services
 SHOULD respond with the content type of the request.
 
-If the set of request headers of a batch request are valid the service
-MUST return a [`200 OK`](#ResponseCode200OK) HTTP response code to
-indicate that the batch request was accepted for processing, but the
-processing is yet to be completed. The individual requests within the
-body of the batch request may subsequently fail or be malformed;
-however, this enables batch implementations to stream the results.
-
-If the service receives a batch request with an invalid set of headers
-it MUST return a [`4xx response code`](#ClientErrorResponses) and
-perform no further processing of the batch request.
-
 ### 11.7.2 Request Dependencies
 
 Requests within a batch may have dependencies on other requests
@@ -6131,7 +6131,7 @@ Example 107: referencing the batch request example 101 above, assume all
 the requests except the final query request succeed. In this case the
 response would be
 ```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 OData-Version: 4.0
 Content-Length: ####
 Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -6139,7 +6139,7 @@ Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
 --b_243234_25424_ef_892u748
 Content-Type: application/http
 
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 Content-Type: application/json
 Content-Length: ###
 
@@ -6219,10 +6219,10 @@ processed. Note that the actual multipart batch response itself is
 contained in an `application/http` wrapper as it is a response to a
 status monitor resource:
 ```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 Content-Type: application/http
 
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 OData-Version: 4.0
 Content-Length: ####
 Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -6230,7 +6230,7 @@ Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
 --b_243234_25424_ef_892u748
 Content-Type: application/http
 
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 Content-Type: application/json
 Content-Length: ###
 
@@ -6250,7 +6250,7 @@ After some time the client makes a second request using the returned
 monitor URL, not explicitly accepting
 `application/http`. The batch is completely processed and the response is the final result.
 ```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 AsyncResult: 200
 OData-Version: 4.0
 Content-Length: ####
diff --git a/odata-json-format/19 Batch Requests and Responses.md b/odata-json-format/19 Batch Requests and Responses.md
index 960fd1201..fffa230cd 100644
--- a/odata-json-format/19 Batch Requests and Responses.md	
+++ b/odata-json-format/19 Batch Requests and Responses.md	
@@ -360,6 +360,11 @@ Example ##ex: referencing the batch request [example ##batchRequest] above, assu
 the requests except the final query request succeed. In this case the
 response would be
 ```json
+HTTP/1.1 200 OK
+OData-Version: 4.01
+Content-Length: ####
+Content-Type: application/json
+
 {
   "responses": [
     {
diff --git a/odata-protocol/11.7 Batch Requests.md b/odata-protocol/11.7 Batch Requests.md
index cd923e317..0363af910 100644
--- a/odata-protocol/11.7 Batch Requests.md	
+++ b/odata-protocol/11.7 Batch Requests.md	
@@ -19,6 +19,17 @@ A batch request is represented using either the [multipart batch
 format](#MultipartBatchFormat) defined in this document or the JSON
 batch format defined in [OData-JSON](#ODataJSON).
 
+If the set of request headers of a batch request are valid the service
+MUST return a [`200 OK`](#ResponseCode200OK) HTTP response code to
+indicate that the batch request was accepted for processing, even if the
+processing is yet to be completed. The individual requests within the
+body of the batch request may be processed as soon as they are received,
+this enables clients to stream batch requests, and batch implementations to stream the results.
+
+If the service receives a batch request with an invalid set of headers
+it MUST return a [`4xx response code`](#ClientErrorResponses) and
+perform no further processing of the batch request.
+
 ### ##subsubsec Batch Request Headers
 
 A batch request using the [multipart batch
@@ -61,17 +72,6 @@ specifying the desired batch response format, either `multipart/mixed`
 or `application/json`. If no `Accept` header is provided, services
 SHOULD respond with the content type of the request.
 
-If the set of request headers of a batch request are valid the service
-MUST return a [`200 OK`](#ResponseCode200OK) HTTP response code to
-indicate that the batch request was accepted for processing, but the
-processing is yet to be completed. The individual requests within the
-body of the batch request may subsequently fail or be malformed;
-however, this enables batch implementations to stream the results.
-
-If the service receives a batch request with an invalid set of headers
-it MUST return a [`4xx response code`](#ClientErrorResponses) and
-perform no further processing of the batch request.
-
 ### ##subsubsec Request Dependencies
 
 Requests within a batch may have dependencies on other requests
@@ -468,7 +468,7 @@ Example ##ex: referencing the batch request example 101 above, assume all
 the requests except the final query request succeed. In this case the
 response would be
 ```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 OData-Version: 4.0
 Content-Length: ####
 Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -476,7 +476,7 @@ Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
 --b_243234_25424_ef_892u748
 Content-Type: application/http
 
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 Content-Type: application/json
 Content-Length: ###
 
@@ -556,10 +556,10 @@ processed. Note that the actual multipart batch response itself is
 contained in an `application/http` wrapper as it is a response to a
 status monitor resource:
 ```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 Content-Type: application/http
 
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 OData-Version: 4.0
 Content-Length: ####
 Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -567,7 +567,7 @@ Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
 --b_243234_25424_ef_892u748
 Content-Type: application/http
 
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 Content-Type: application/json
 Content-Length: ###
 
@@ -587,7 +587,7 @@ After some time the client makes a second request using the returned
 monitor URL, not explicitly accepting
 `application/http`. The batch is completely processed and the response is the final result.
 ```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
 AsyncResult: 200
 OData-Version: 4.0
 Content-Length: ####

From 971d7f3a4b24f8fffdfeba1abc8715c1dc7589f8 Mon Sep 17 00:00:00 2001
From: Ralf Handl 
Date: Wed, 29 Nov 2023 18:15:25 +0100
Subject: [PATCH 13/22] ODATA-1563 (#192)

---
 docs/odata-url-conventions/odata-url-conventions.html | 2 +-
 docs/odata-url-conventions/odata-url-conventions.md   | 4 ++--
 odata-url-conventions/4 Resource Path.md              | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/docs/odata-url-conventions/odata-url-conventions.html b/docs/odata-url-conventions/odata-url-conventions.html
index f345701b0..c46720cab 100644
--- a/docs/odata-url-conventions/odata-url-conventions.html
+++ b/docs/odata-url-conventions/odata-url-conventions.html
@@ -744,7 +744,7 @@ 

4.11 Addressing Derived Types

Any resource path or path expression identifying a collection of entities or complex type instances can be appended with a type-cast segment, that is a path segment containing the qualified name of a type derived from the declared item type of the collection. The result will be restricted to instances of the derived type and may be empty.

-

Any resource path or path expression identifying a single entity or complex type instance can be appended with a type-cast segment containing the qualified name of a type derived from the declared type of the identified resource. If used in a resource path and the identified resource is not an instance of the derived type, the request will result in a 404 Not Found response. If used in a path expression that is part of a Boolean expression, the type cast will evaluate to null.

+

Any resource path or path expression identifying a single entity or complex type instance can be appended with a type-cast segment containing the qualified name of a type derived from the declared type of the identified resource. If used in a resource path and the identified resource is not an instance of the derived type, the request will result in a 404 Not Found response. If used in a path expression, the type cast will evaluate to null.

Services MAY additionally support the use of the unqualified name of a derived type in a URL by defining one or more default namespaces through the Core.DefaultNamespace term defined in OData-VocCore. For more information on default namespaces, see Default Namespaces in OData-Protocol.

Services MAY also support treating an instance as a type outside of the type hierarchy using the same syntax and semantics as when addressing a derived type. In this case, the set and values of properties of the addressed type may be different than the properties of the source type. The set of such possible target types outside of the type hierarchy SHOULD be called out using the Core.MayImplement annotation term, defined in OData-VocCore.

diff --git a/docs/odata-url-conventions/odata-url-conventions.md b/docs/odata-url-conventions/odata-url-conventions.md index b913c1552..df2a97f34 100644 --- a/docs/odata-url-conventions/odata-url-conventions.md +++ b/docs/odata-url-conventions/odata-url-conventions.md @@ -1118,8 +1118,8 @@ complex type instance can be appended with a type-cast segment containing the qualified name of a type derived from the declared type of the identified resource. If used in a resource path and the identified resource is not an instance of the derived type, the request will result -in a `404 Not Found` response. If used in a path expression that is part -of a Boolean expression, the type cast will evaluate to `null`. +in a `404 Not Found` response. If used in a path expression, +the type cast will evaluate to `null`. Services MAY additionally support the use of the unqualified name of a derived type in a URL by defining one or more default namespaces through diff --git a/odata-url-conventions/4 Resource Path.md b/odata-url-conventions/4 Resource Path.md index f902b38b7..a4620cfe1 100644 --- a/odata-url-conventions/4 Resource Path.md +++ b/odata-url-conventions/4 Resource Path.md @@ -679,8 +679,8 @@ complex type instance can be appended with a type-cast segment containing the qualified name of a type derived from the declared type of the identified resource. If used in a resource path and the identified resource is not an instance of the derived type, the request will result -in a `404 Not Found` response. If used in a path expression that is part -of a Boolean expression, the type cast will evaluate to `null`. +in a `404 Not Found` response. If used in a path expression, +the type cast will evaluate to `null`. Services MAY additionally support the use of the unqualified name of a derived type in a URL by defining one or more default namespaces through From a254a86ed6ac2bfadb873efadd6212844741992f Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Wed, 29 Nov 2023 18:19:26 +0100 Subject: [PATCH 14/22] ODATA-1587: Remove reference to obsolete GeoJSON document (#194) --- docs/odata-json-format/odata-json-format.html | 8 +------- docs/odata-json-format/odata-json-format.md | 14 +------------- odata-json-format/7 Structural Property.md | 10 +--------- odata-json-format/Appendix.md | 4 ---- 4 files changed, 3 insertions(+), 33 deletions(-) diff --git a/docs/odata-json-format/odata-json-format.html b/docs/odata-json-format/odata-json-format.html index 2336c1fb6..9b4381f99 100644 --- a/docs/odata-json-format/odata-json-format.html +++ b/docs/odata-json-format/odata-json-format.html @@ -743,11 +743,7 @@

7.1

Values of type Edm.Binary, Edm.Date, Edm.DateTimeOffset, Edm.Duration, Edm.Guid, and Edm.TimeOfDay are represented as JSON strings whose content satisfies the rules binaryValue, dateValue, dateTimeOffsetValue, durationValue, guidValue, and timeOfDayValue respectively, in OData-ABNF.

Primitive values that cannot be represented, for example due to server conversion issues or IEEE754 limitations on the size of an Edm.Int64 or Edm.Decimal value, are annotated with the Core.ValueException term. In this case, the payload MAY include an approximation of the value and MAY specify a string representation of the exact value in the value property of the annotation.

Enumeration values are represented as JSON strings whose content satisfies the rule enumValue in OData-ABNF. The preferred representation is the enumerationMember. If no enumerationMember (or combination of named enumeration members) is available, the enumMemberValue representation may be used.

-

Geography and geometry values are represented as geometry types as defined in RFC7946, with the following modifications:

-
    -
  • Keys SHOULD be ordered with type first, then coordinates, then any other keys
  • -
  • If the optional CRS object is present, it MUST be of type name, where the value of the name member of the contained properties object is an EPSG SRID legacy identifier, see [GeoJSON-2008].
  • -
+

Geography and geometry values are represented as geometry types as defined in RFC7946.

Geography and geometry types have the same representation in a JSON payload. Whether the value represents a geography type or geometry type is inferred from its usage or specified using the type control information.

Example 12:

@@ -2017,8 +2013,6 @@
[RFC8259]

A.2 Informative References

[ECMAScript]

ECMAScript 2023 Language Specification, 14th Edition, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.

-
[GeoJSON-2008]
-

Butler, H., Daly, M., Doyle, A., Gillies, S., Schaub, T., and C. Schmidt, “The GeoJSON Format Specification”, June 2008 http://geojson.org/geojson-spec.html.


Appendix B. Safety, Security and Privacy Considerations

This specification raises no security issues.

diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md index bcf80d345..e1dd4ebbc 100644 --- a/docs/odata-json-format/odata-json-format.md +++ b/docs/odata-json-format/odata-json-format.md @@ -1388,15 +1388,7 @@ combination of named enumeration members) is available, the `enumMemberValue` representation may be used. Geography and geometry values are represented as geometry types as -defined in [RFC7946](#rfc7946), with the following -modifications: - -- Keys SHOULD be ordered with type first, then coordinates, then any other keys -- If the optional [CRS - object](http://geojson.org/geojson-spec.html#named-crs) is present, it - MUST be of type `name`, where the value of the - `name` member of the contained `properties` object - is an EPSG SRID legacy identifier, see [[GeoJSON-2008](#GeoJSON-2008)]. +defined in [RFC7946](#rfc7946). Geography and geometry types have the same representation in a JSON payload. Whether the value represents a geography type or geometry type @@ -3790,10 +3782,6 @@ https://www.rfc-editor.org/info/rfc8259. ###### [ECMAScript] _ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/. -###### [GeoJSON-2008] -_Butler, H., Daly, M., Doyle, A., Gillies, S., Schaub, T., and C. Schmidt, "The GeoJSON Format Specification", June 2008_ -http://geojson.org/geojson-spec.html. - ------- # Appendix B. Safety, Security and Privacy Considerations diff --git a/odata-json-format/7 Structural Property.md b/odata-json-format/7 Structural Property.md index b98aae8cf..d7b56f083 100644 --- a/odata-json-format/7 Structural Property.md +++ b/odata-json-format/7 Structural Property.md @@ -54,15 +54,7 @@ combination of named enumeration members) is available, the `enumMemberValue` representation may be used. Geography and geometry values are represented as geometry types as -defined in [RFC7946](#rfc7946), with the following -modifications: - -- Keys SHOULD be ordered with type first, then coordinates, then any other keys -- If the optional [CRS - object](http://geojson.org/geojson-spec.html#named-crs) is present, it - MUST be of type `name`, where the value of the - `name` member of the contained `properties` object - is an EPSG SRID legacy identifier, see [[GeoJSON-2008](#GeoJSON-2008)]. +defined in [RFC7946](#rfc7946). Geography and geometry types have the same representation in a JSON payload. Whether the value represents a geography type or geometry type diff --git a/odata-json-format/Appendix.md b/odata-json-format/Appendix.md index 6aea417d2..6d50ee3a9 100644 --- a/odata-json-format/Appendix.md +++ b/odata-json-format/Appendix.md @@ -80,10 +80,6 @@ https://www.rfc-editor.org/info/rfc8259. _ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/. -###### [GeoJSON-2008] -_Butler, H., Daly, M., Doyle, A., Gillies, S., Schaub, T., and C. Schmidt, "The GeoJSON Format Specification", June 2008_ -http://geojson.org/geojson-spec.html. - ------- # Appendix ##asec Safety, Security and Privacy Considerations From 153def271909c3b2b36c093b31cd2bf1c7d87950 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Wed, 29 Nov 2023 18:29:52 +0100 Subject: [PATCH 15/22] ODATA-1593 (#197) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Heiko Theißen --- docs/odata-json-format/odata-json-format.html | 855 ++++++++++-------- docs/odata-json-format/odata-json-format.md | 156 +++- docs/odata-protocol/odata-protocol.html | 8 +- docs/odata-protocol/odata-protocol.md | 12 +- odata-json-format/15 Delta Payload.md | 156 +++- odata-protocol/11.4 Data Modification.md | 8 +- odata-protocol/8 Header Fields.md | 4 +- 7 files changed, 819 insertions(+), 380 deletions(-) diff --git a/docs/odata-json-format/odata-json-format.html b/docs/odata-json-format/odata-json-format.html index 9b4381f99..7fb143ed8 100644 --- a/docs/odata-json-format/odata-json-format.html +++ b/docs/odata-json-format/odata-json-format.html @@ -1301,9 +1301,9 @@

15.6 Update a Collection of Entities

-

The body of a PATCH request to a URL identifying a collection of entities is a JSON object. It MUST contain the context control information with a string value of #$delta, and it MUST contain an array-valued property named value containing all added, changed, or deleted entities, as well as added or deleted links between entities.

+

The body of a PATCH request to a URL identifying a collection of entities is a JSON object. It MUST contain the context control information with a string value of #$delta, and it MUST contain an array-valued property named value containing all added, changed, or deleted entities, as well as added or deleted links between entities.

-

Example 39: 4.01 delta response customers with expanded orders represented inline as a delta

+

Example 39: 4.01 collection-update request for customers with expanded orders represented inline as a delta

  1. Add customer EASTC
  2. Change ContactName of customer AROUT
  3. @@ -1312,69 +1312,212 @@

  4. Create order 11011
  5. Add link to existing order 10692
  6. -
  7. Change ShippedDate of related order 10835
  8. +
  9. Change RequiredDate of related order 10835
  10. Delete link to order 10643
  • Add link between customer ANATR and order 10643
  • Delete link between customer DUMON and order 10311
  • -
    {
    -  "@context": "#$delta",
    -  "value": [
    -    {
    -      "CustomerID": "EASTC",
    -      "CompanyName": "Eastern Connection",
    -      "ContactName": "Ann Devon",
    -      "ContactTitle": "Sales Agent"
    -    },
    +
    PATCH /service/Customers HTTP/1.1
    +Host: host
    +Content-Type: application/json
    +Content-Length: ###
    +Prefer: return=minimal, continue-on-error
    +
    +{
    +  "@context": "#$delta",
    +  "value": [
         {
    -      "CustomerID": "AROUT",
    -      "ContactName": "Thomas Hardy",
    -    },
    -    {
    -      "@removed": {},
    -      "CustomerID":"ANTON"
    -    },
    -    {
    -      "CustomerID": "ALFKI",
    -      "Orders@delta": [
    -        {
    -          "OrderID": 11011,
    -          "CustomerID": "ALFKI",
    -          "EmployeeID": 3,
    -          "OrderDate": "1998-04-09T00:00:00Z",
    -          "RequiredDate": "1998-05-07T00:00:00Z",
    -          "ShippedDate": "1998-04-13T00:00:00Z"
    -        },
    -        {
    -          "@id": "Orders(10692)"
    -        },
    -        {
    -          "@id": "Orders(10835)",
    -          "ShippedDate": "1998-01-23T00:00:00Z",
    -        },
    -        {
    -          "@removed": {
    -            "reason": "changed"
    -          },
    -          "OrderID": 10643
    -        }
    -      ]
    -    },
    -    {
    -      "@context": "#Customers/$link",
    -      "source": "Customers('ANATR')",
    -      "relationship":" Orders",
    -      "target": "Orders(10643)"
    -    },
    -    {
    -      "@context": "#Customers/$deletedLink",
    -      "source": "Customers('DUMON')",
    -      "relationship": "Orders",
    -      "target": "Orders(10311)"
    -    }
    -  ]
    -}
    + "@Org.OData.Core.V1.ContentID": "1", + "CustomerID": "EASTC", + "CompanyName": "Eastern Connection", + "ContactName": "Ann Devon", + "ContactTitle": "Sales Agent" + }, + { + "@Org.OData.Core.V1.ContentID": "2", + "CustomerID": "AROUT", + "ContactName": "Thomas Hardy", + }, + { + "@Org.OData.Core.V1.ContentID": "3", + "@removed": {}, + "CustomerID":"ANTON" + }, + { + "@Org.OData.Core.V1.ContentID": "4", + "CustomerID": "ALFKI", + "Orders@delta": [ + { + "@Org.OData.Core.V1.ContentID": "4.1", + "OrderID": 11011, + "CustomerID": "ALFKI", + "EmployeeID": 3, + "OrderDate": "1998-04-09T00:00:00Z", + "RequiredDate": "1998-05-07T00:00:00Z", + "ShippedDate": "1998-04-13T00:00:00Z" + }, + { + "@Org.OData.Core.V1.ContentID": "4.2", + "@id": "Orders(10692)" + }, + { + "@Org.OData.Core.V1.ContentID": "4.3", + "@id": "Orders(10835)", + "RequiredDate": "1998-01-23T00:00:00Z", + }, + { + "@Org.OData.Core.V1.ContentID": "4.4", + "@removed": { + "reason": "changed" + }, + "OrderID": 10643 + } + ] + }, + { + "@context": "#Customers/$link", + "@Org.OData.Core.V1.ContentID": "5", + "source": "Customers('ANATR')", + "relationship":" Orders", + "target": "Orders(10643)" + }, + { + "@context": "#Customers/$deletedLink", + "@Org.OData.Core.V1.ContentID": "6", + "source": "Customers('DUMON')", + "relationship": "Orders", + "target": "Orders(10311)" + } + ] +}
    +

    Assuming all changes can be applied without errors, the response would be

    +
    HTTP/1.1 204 No Content
    +Preference-Applied: return=minimal, continue-on-error
    +
    +
    +

    Assuming some or all changes cannot be applied, the overall request is still deemed successful due to the continue-on-error preference, and the response details what went wrong

    +
      +
    1. Add customer ‘EASTC’ - failed
    2. +
    3. Change ContactName of customer ‘AROUT’ - failed
    4. +
    5. Delete customer ‘ANTON’ - failed
    6. +
    7. Change customer ‘ALFKI’: +
        +
      1. Create order 11011 - succeeded, not mentioned in response
      2. +
      3. Add link to existing order 10692 - succeeded, not mentioned in response
      4. +
      5. Change RequiredDate of related order 10835 - failed
      6. +
      7. Delete link to order 10643 - succeeded, not mentioned in response
      8. +
    8. +
    9. Add link between customer ‘ANATR’ and order 10643 - failed without further info
    10. +
    11. Delete link between customer ‘DUMON’ and order 10311 - failed without further info
    12. +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +Content-Length: ###
    +Preference-Applied: return=minimal, continue-on-error
    +
    +{
    +  "@context": "#$delta",
    +  "value": [
    +    {
    +      "@Org.OData.Core.V1.ContentID": "1",
    +      "CustomerID": "EASTC",
    +      "@removed": {},
    +      "@Org.OData.Core.V1.DataModificationException": {
    +        "failedOperation": "insert",
    +        "responseCode": 400,
    +        "info": {
    +          "code": "incmplt",
    +          "message": "Required field(s) not provided",
    +          "target": "Address",
    +          "@OtherVocab.additionalTargets": [ "Industry", "VATRegistration" ],
    +          "severity": "error"
    +        }
    +      }
    +    },
    +    {
    +      "@Org.OData.Core.V1.ContentID": "2",
    +      "CustomerID": "AROUT",
    +      "@Org.OData.Core.V1.DataModificationException": {
    +        "failedOperation": "update",
    +        "responseCode": 400,
    +        "info": {
    +          "code": "r-o",
    +          "message": "Customer is archived and cannot be changed",
    +          "severity": "error"
    +        }
    +      }
    +    },
    +    {
    +      "@Org.OData.Core.V1.ContentID": "3",
    +      "CustomerID":"ANTON"
    +      "@Org.OData.Core.V1.DataModificationException": {
    +        "failedOperation": "delete",
    +        "responseCode": 400,
    +        "info": {
    +          "code": "ufo",
    +          "message": "Customer has unfinished orders and cannot be deleted",
    +          "severity": "error"
    +        }
    +      }
    +    },
    +    {
    +      "@Org.OData.Core.V1.ContentID": "4",
    +      "CustomerID": "ALFKI",
    +      "Orders@delta": [
    +        {
    +          "@Org.OData.Core.V1.ContentID": "4.3",
    +          "@id": "Orders(10835)",
    +          "@Org.OData.Core.V1.DataModificationException": {
    +            "failedOperation": "update",
    +            "responseCode": 400,
    +            "info": {
    +              "code": "b/s",
    +              "message": "RequiredDate cannot be changed because Order is already being shipped",
    +              "severity": "error"
    +            }
    +          }
    +        }
    +      ]
    +    },
    +    {
    +      "@context": "#Customers/$deletedLink",
    +      "@Org.OData.Core.V1.ContentID": "5",
    +      "source": "Customers('ANATR')",
    +      "relationship":" Orders",
    +      "target": "Orders(10643)",
    +      "@Org.OData.Core.V1.DataModificationException": {
    +        "failedOperation": "link",
    +        "responseCode": 404,
    +        "info": null
    +      }
    +    },
    +    {
    +      "@context": "#Customers/$link",
    +      "@Org.OData.Core.V1.ContentID": "6",
    +      "source": "Customers('DUMON')",
    +      "relationship": "Orders",
    +      "target": "Orders(10311)",
    +      "@Org.OData.Core.V1.DataModificationException": {
    +        "failedOperation": "unlink",
    +        "responseCode": 400
    +      }
    +    }
    +  ]
    +}
    +

    Without the continue-on-error preference processing would stop on the first error, and the response would be a standard OData error response

    +
    HTTP/1.1 400 Bad Request
    +Content-Type: application/json
    +Content-Length: ###
    +
    +{
    +  "error": {
    +    "code": "incmplt",
    +    "message": "Required field(s) not provided",
    +    "target": "Customers('EASTC')/Address",
    +    "@OtherVocab.additionalTargets": [ "Customers('EASTC')/Industry", "Customers('EASTC')/VATRegistration" ]
    +  }
    +}

    16 Bound Function

    @@ -1388,46 +1531,46 @@

    16 Boun

    If metadata=minimal is requested, the target name/value pair MUST be included if its value differs from the canonical function or action URL.

    Example 40: minimal representation of a function where all overloads are applicable

    -
    {
    -  "@context": "http://host/service/$metadata#Employees/$entity",
    -  "#Model.RemainingVacation": {},
    -  ...
    -}
    +
    {
    +  "@context": "http://host/service/$metadata#Employees/$entity",
    +  "#Model.RemainingVacation": {},
    +  ...
    +}

    Example 41: full representation of a specific overload with parameter alias for the Year parameter

    -
    {
    -  "@context": "http://host/service/$metadata#Employees/$entity",
    -  "#Model.RemainingVacation(Year)": {
    -    "title": "Remaining vacation from year.",
    -    "target": "Employees(2)/RemainingVacation(Year=@Year)"
    -  },
    -  ...
    -}
    +
    {
    +  "@context": "http://host/service/$metadata#Employees/$entity",
    +  "#Model.RemainingVacation(Year)": {
    +    "title": "Remaining vacation from year.",
    +    "target": "Employees(2)/RemainingVacation(Year=@Year)"
    +  },
    +  ...
    +}

    Example 42: full representation in a collection

    -
    {
    -  "@context": "http://host/service/$metadata#Employees",
    -  "#Model.RemainingVacation": {
    -    "title": "Remaining Vacation",
    -    "target": "Managers(22)/Employees/RemainingVacation"
    -  },
    -  "value": [ ... ]
    -}
    +
    {
    +  "@context": "http://host/service/$metadata#Employees",
    +  "#Model.RemainingVacation": {
    +    "title": "Remaining Vacation",
    +    "target": "Managers(22)/Employees/RemainingVacation"
    +  },
    +  "value": [ ... ]
    +}

    Example 43: full representation in a nested collection

    -
    {
    -  "@context": "http://host/service/$metadata#Employees/$entity",
    -  "@type": "Model.Manager",
    -  "ID":22,
    -  ...
    -  "Employees#RemainingVacation": {
    -    "title": "RemainingVacation",
    -    "target": "Managers(22)/Employees/RemainingVacation"
    -  }
    -}
    +
    {
    +  "@context": "http://host/service/$metadata#Employees/$entity",
    +  "@type": "Model.Manager",
    +  "ID":22,
    +  ...
    +  "Employees#RemainingVacation": {
    +    "title": "RemainingVacation",
    +    "target": "Managers(22)/Employees/RemainingVacation"
    +  }
    +}

    17 Bound Action

    @@ -1441,46 +1584,46 @@

    17 Bound Acti

    If metadata=minimal is requested, the target name/value pair MUST be included if its value differs from the canonical function or action URL.

    Example 44: minimal representation in an entity

    -
    {
    -  "@context": "http://host/service/$metadata#LeaveRequests/$entity",
    -  "#Model.Approve": {},
    -  ...
    -}
    +
    {
    +  "@context": "http://host/service/$metadata#LeaveRequests/$entity",
    +  "#Model.Approve": {},
    +  ...
    +}

    Example 45: full representation in an entity:

    -
    {
    -  "@context": "http://host/service/$metadata#LeaveRequests/$entity",
    -  "#Model.Approve": {
    -    "title": "Approve Leave Request",
    -    "target": "LeaveRequests(2)/Approve"
    -  },
    -  ...
    -}
    +
    {
    +  "@context": "http://host/service/$metadata#LeaveRequests/$entity",
    +  "#Model.Approve": {
    +    "title": "Approve Leave Request",
    +    "target": "LeaveRequests(2)/Approve"
    +  },
    +  ...
    +}

    Example 46: full representation in a collection

    -
    {
    -  "@context": "http://host/service/$metadata#LeaveRequests",
    -  "#Model.Approve": {
    -    "title": "Approve All Leave Requests",
    -    "target": "Employees(22)/Model.Manager/LeaveRequests/Approve"
    -  },
    -  "value": [ ... ]
    -}
    +
    {
    +  "@context": "http://host/service/$metadata#LeaveRequests",
    +  "#Model.Approve": {
    +    "title": "Approve All Leave Requests",
    +    "target": "Employees(22)/Model.Manager/LeaveRequests/Approve"
    +  },
    +  "value": [ ... ]
    +}

    Example 47: full representation in a nested collection

    -
    {
    -  "@context": "http://host/service/$metadata#Employees/$entity",
    -  "@type": "Model.Manager",
    -  "ID": 22,
    -  ...
    -  "LeaveRequests#Model.Approve": {
    -    "title": "Approve All Leave Requests",
    -    "target": "Employees(22)/Model.Manager/LeaveRequests/Approve"
    -  }
    -}
    +
    {
    +  "@context": "http://host/service/$metadata#Employees/$entity",
    +  "@type": "Model.Manager",
    +  "ID": 22,
    +  ...
    +  "LeaveRequests#Model.Approve": {
    +    "title": "Approve All Leave Requests",
    +    "target": "Employees(22)/Model.Manager/LeaveRequests/Approve"
    +  }
    +}

    18 Action Invocation

    @@ -1489,15 +1632,15 @@

    Core.OptionalParameter defined in OData-VocCore MAY be omitted from the request body. If an omitted parameter is not annotated (and thus nullable), it MUST be interpreted as having the null value. If it is annotated and the annotation specifies a DefaultValue, the omitted parameter is interpreted as having that default value. If omitted and the annotation does not specify a default value, the service is free on how to interpret the omitted parameter. Note: a nullable non-binding parameter is equivalent to being annotated as optional with a default value of null.

    Example 46:

    -
    {
    -  "param1": 42,
    -  "param2": {
    -    "Street": "One Microsoft Way",
    -    "Zip": 98052
    -  },
    -  "param3": [ 1, 42, 99 ],
    -  "param4": null
    -}
    +
    {
    +  "param1": 42,
    +  "param2": {
    +    "Street": "One Microsoft Way",
    +    "Zip": 98052
    +  },
    +  "param3": [ 1, 42, 99 ],
    +  "param4": null
    +}

    In order to invoke an action with no non-binding parameters, the client passes an empty JSON object in the body of the request. 4.01 Services MUST also support clients passing an empty request body for this case.


    @@ -1541,45 +1684,45 @@

    19.1 Batc
  • A second query request
  • Note: For brevity, in the example, request bodies are excluded in favor of English descriptions inside <> brackets and OData-Version headers are omitted.

    -
    POST /service/$batch HTTP/1.1
    -Host: host
    -OData-Version: 4.01
    -Content-Type: application/json
    -Content-Length: ###
    -
    -{
    -  "requests": [
    -    {
    -      "id": "0",
    -      "method": "get",
    -      "url": "/service/Customers('ALFKI')"
    -    },
    -    {
    -      "id": "1",
    -      "atomicityGroup": "group1",
    -      "dependsOn": [ "0" ],
    -      "method": "patch",
    -      "url": "/service/Customers('ALFKI')",
    -      "headers": {
    -        "Prefer": "return=minimal"
    -      },
    -      "body": <JSON representation of changes to Customer ALFKI>
    -    },
    -    {
    -      "id": "2",
    -      "atomicityGroup": "group1",
    -      "method": "post",
    -      "url": "/service/Customers",
    -      "body": <JSON representation of a new Customer entity>
    -    },
    -    {
    -      "id": "3",
    -      "dependsOn": [ "group1" ],
    -      "method": "get",
    -      "url": "/service/Products"
    -    }
    -  ]
    -}
    +
    POST /service/$batch HTTP/1.1
    +Host: host
    +OData-Version: 4.01
    +Content-Type: application/json
    +Content-Length: ###
    +
    +{
    +  "requests": [
    +    {
    +      "id": "0",
    +      "method": "get",
    +      "url": "/service/Customers('ALFKI')"
    +    },
    +    {
    +      "id": "1",
    +      "atomicityGroup": "group1",
    +      "dependsOn": [ "0" ],
    +      "method": "patch",
    +      "url": "/service/Customers('ALFKI')",
    +      "headers": {
    +        "Prefer": "return=minimal"
    +      },
    +      "body": <JSON representation of changes to Customer ALFKI>
    +    },
    +    {
    +      "id": "2",
    +      "atomicityGroup": "group1",
    +      "method": "post",
    +      "url": "/service/Customers",
    +      "body": <JSON representation of a new Customer entity>
    +    },
    +    {
    +      "id": "3",
    +      "dependsOn": [ "group1" ],
    +      "method": "get",
    +      "url": "/service/Products"
    +    }
    +  ]
    +}

    19.2 Referencing New Entities

    The entity returned by a preceding request can be referenced in the request URL of subsequent requests. If the Location header in the response contains a relative URL, clients MUST be able to resolve it relative to the request’s URL even if that contains such a reference.

    @@ -1589,29 +1732,29 @@

    POST /service/$batch HTTP/1.1
    -Host: host
    -OData-Version: 4.01
    -Content-Type: application/json
    -Content-Length: ###
    -
    -{
    -  "requests": [
    -    {
    -      "id": "1",
    -      "method": "post",
    -      "url": "/service/Customers",
    -      "body": <JSON representation of a new Customer entity>
    -    },
    -    {
    -      "id": "2",
    -      "dependsOn": [ "1" ]
    -      "method": "post",
    -      "url": "$1/Orders",
    -      "body": <JSON representation of a new Order>
    -    }
    -  ]
    -}

    +
    POST /service/$batch HTTP/1.1
    +Host: host
    +OData-Version: 4.01
    +Content-Type: application/json
    +Content-Length: ###
    +
    +{
    +  "requests": [
    +    {
    +      "id": "1",
    +      "method": "post",
    +      "url": "/service/Customers",
    +      "body": <JSON representation of a new Customer entity>
    +    },
    +    {
    +      "id": "2",
    +      "dependsOn": [ "1" ]
    +      "method": "post",
    +      "url": "$1/Orders",
    +      "body": <JSON representation of a new Order>
    +    }
    +  ]
    +}

    19.3 Referencing an ETag

    @@ -1620,36 +1763,36 @@

    POST /service/$batch HTTP/1.1
    -Host: host
    -OData-Version: 4.01
    -Content-Type: application/json
    -Content-Length: ###
    -
    -{
    -  "requests": [
    -    {
    -      "id": "1",
    -      "method": "get",
    -      "url": "/service/Employees(0)",
    -      "headers": {
    -        "accept": "application/json"
    -      }
    -    },
    -    {
    -      "id": "2",
    -      "dependsOn": [ "1" ],
    -      "method": "patch",
    -      "url": "/service/Employees(0)",
    -      "headers": {
    -        "if-match": "$1"
    -      },
    -      "body": {
    -        "Salary": 75000
    -      }
    -    }
    -  ]
    -}

    +
    POST /service/$batch HTTP/1.1
    +Host: host
    +OData-Version: 4.01
    +Content-Type: application/json
    +Content-Length: ###
    +
    +{
    +  "requests": [
    +    {
    +      "id": "1",
    +      "method": "get",
    +      "url": "/service/Employees(0)",
    +      "headers": {
    +        "accept": "application/json"
    +      }
    +    },
    +    {
    +      "id": "2",
    +      "dependsOn": [ "1" ],
    +      "method": "patch",
    +      "url": "/service/Employees(0)",
    +      "headers": {
    +        "if-match": "$1"
    +      },
    +      "body": {
    +        "Salary": 75000
    +      }
    +    }
    +  ]
    +}

    19.4 Processing a Batch Request

    All requests in an atomicity group represent a single change unit. A service MUST successfully process and apply all the requests in the atomicity group or else apply none of them. It is up to the service implementation to define rollback semantics to undo any requests within an atomicity group that may have been applied before another request in that same atomicity group failed.

    @@ -1669,119 +1812,119 @@

    19.5 B

    Relative URLs in a response object follow the rules for relative URLs based on the request URL of the corresponding request. Especially: URLs in responses MUST NOT contain $-prefixed request identifiers.

    Example 51: referencing the batch request example 48 above, assume all the requests except the final query request succeed. In this case the response would be

    -
    HTTP/1.1 200 OK
    -OData-Version: 4.01
    -Content-Length: ####
    -Content-Type: application/json
    -
    -{
    -  "responses": [
    -    {
    -      "id": "0",
    -      "status": 200,
    -      "body": <JSON representation of the Customer entity with key ALFKI>
    -    },
    -    {
    -      "id": "1",
    -      "status": 204
    -    },
    -    {
    -      "id": "2",
    -      "status": 201,
    -      "headers": {
    -        "location": "http://host/service.svc/Customer('POIUY')"
    -      },
    -      "body": <JSON representation of the new Customer entity>
    -    },
    -    {
    -      "id": "3",
    -      "status": 404,
    -      "body": <Error message>
    -    }
    -  ]
    -}
    +
    HTTP/1.1 200 OK
    +OData-Version: 4.01
    +Content-Length: ####
    +Content-Type: application/json
    +
    +{
    +  "responses": [
    +    {
    +      "id": "0",
    +      "status": 200,
    +      "body": <JSON representation of the Customer entity with key ALFKI>
    +    },
    +    {
    +      "id": "1",
    +      "status": 204
    +    },
    +    {
    +      "id": "2",
    +      "status": 201,
    +      "headers": {
    +        "location": "http://host/service.svc/Customer('POIUY')"
    +      },
    +      "body": <JSON representation of the new Customer entity>
    +    },
    +    {
    +      "id": "3",
    +      "status": 404,
    +      "body": <Error message>
    +    }
    +  ]
    +}

    19.6 Asynchronous Batch Requests

    A batch request that specifies the respond-async preference MAY be executed asynchronously. This means that the “outer” batch request is executed asynchronously; this preference does not automatically cascade down to the individual requests within the batch. After successful execution of the batch request the response to the batch request is returned in the body of a response to an interrogation request against the status monitor resource URL, see section “Asynchronous Requests” in OData-Protocol.

    A service MAY return interim results to an asynchronously executing batch. It does this by responding with 200 OK to a GET request to the monitor resource and including a nextLink control information in the JSON batch response, thus signaling that the response is only a partial result. A subsequent GET request to the next link MAY result in a 202 Accepted response with a location header pointing to a new status monitor resource.

    Example 52: referencing the example 47 above again, assume that the request is sent with the respond-async preference. This results in a 202 response pointing to a status monitor resource:

    -
    HTTP/1.1 202 Accepted
    -Location: http://service-root/async-monitor-0
    -Retry-After: ###
    +
    HTTP/1.1 202 Accepted
    +Location: http://service-root/async-monitor-0
    +Retry-After: ###

    When interrogating the monitor URL only the first request in the batch has finished processing and all the remaining requests are still being processed. The service signals that asynchronous processing is “finished” and returns a partial result with the first response and a next link. The client did not explicitly accept application/http, so the response is “unwrapped” and only indicates with the AsyncResult header that it is a response to a status monitor resource:

    -
    HTTP/1.1 200 OK
    -AsyncResult: 200
    -OData-Version: 4.01
    -Content-Length: ###
    -Content-Type: application/json
    -
    -{
    -  "responses": [
    -    {
    -      "id": "0",
    -      "status": 200,
    -      "body": <JSON representation of the Customer entity with key ALFKI>
    -    }
    -  ],
    -  "@nextLink": "...?$skiptoken=YmF0Y2gx"
    -}
    +
    HTTP/1.1 200 OK
    +AsyncResult: 200
    +OData-Version: 4.01
    +Content-Length: ###
    +Content-Type: application/json
    +
    +{
    +  "responses": [
    +    {
    +      "id": "0",
    +      "status": 200,
    +      "body": <JSON representation of the Customer entity with key ALFKI>
    +    }
    +  ],
    +  "@nextLink": "...?$skiptoken=YmF0Y2gx"
    +}

    Client makes a GET request to the next link and receives a 202 response with the location of a new monitor resource.

    -
    HTTP/1.1 202 Accepted
    -Location: http://service-root/async-monitor-1
    -Retry-After: ###
    +
    HTTP/1.1 202 Accepted
    +Location: http://service-root/async-monitor-1
    +Retry-After: ###

    After some time a GET request to the monitor resource returns the remainder of the result.

    -
    HTTP/1.1 200 OK
    -AsyncResult: 200
    -OData-Version: 4.01
    -Content-Length: ###
    -Content-Type: application/json
    -
    -{
    -  "responses": [
    -    {
    -      "id": "1",
    -      "status": 204
    -    },
    -    {
    -      "id": "2",
    -      "status": 201,
    -      "headers": {
    -        "location": "http://host/service.svc/Customer('POIUY')"
    -      },
    -      "body": <JSON representation of the new Customer entity>
    -    },
    -    {
    -      "id": "3",
    -      "status": 404,
    -      "body": <Error message>
    -    }
    -  ]
    -}
    +
    HTTP/1.1 200 OK
    +AsyncResult: 200
    +OData-Version: 4.01
    +Content-Length: ###
    +Content-Type: application/json
    +
    +{
    +  "responses": [
    +    {
    +      "id": "1",
    +      "status": 204
    +    },
    +    {
    +      "id": "2",
    +      "status": 201,
    +      "headers": {
    +        "location": "http://host/service.svc/Customer('POIUY')"
    +      },
    +      "body": <JSON representation of the new Customer entity>
    +    },
    +    {
    +      "id": "3",
    +      "status": 404,
    +      "body": <Error message>
    +    }
    +  ]
    +}

    In addition to the above interaction pattern individual requests within a batch with no other requests depending on it and not part of an atomicity group MAY be executed asynchronously if they specify the respond-async preference and if the service responds with a JSON batch response. In this case the response array contains a response object for each asynchronously executed individual request with a status of 202, a location header pointing to an individual status monitor resource, and optionally a retry-after header.

    Example 53: the first individual request is processed asynchronously, the second synchronously, the batch itself is processed synchronously

    -
    HTTP/1.1 200 OK
    -OData-Version: 4.01
    -Content-Length: ###
    -Content-Type: application/json
    -
    -{
    -  "responses": [
    -    {
    -      "id": "0",
    -      "status": 202,
    -      "headers": {
    -        "location": "http://service-root/async-monitor-0"
    -      }
    -    },
    -    {
    -      "id": "1",
    -      "status": 204
    -    }
    -  ]
    -}
    +
    HTTP/1.1 200 OK
    +OData-Version: 4.01
    +Content-Length: ###
    +Content-Type: application/json
    +
    +{
    +  "responses": [
    +    {
    +      "id": "0",
    +      "status": 202,
    +      "headers": {
    +        "location": "http://service-root/async-monitor-0"
    +      }
    +    },
    +    {
    +      "id": "1",
    +      "status": 204
    +    }
    +  ]
    +}

    20 Instance Annotations

    @@ -1792,19 +1935,19 @@

    single primitive or collection value, the annotations for the value appear next to the value property and are not prefixed with a property name.

    Example 54:

    -
    {
    -  "@context": "http://host/service/$metadata#Customers",
    -  "@com.example.customer.setkind": "VIPs",
    -  "value": [
    -    {
    -      "@com.example.display.highlight": true,
    -      "ID": "ALFKI",
    -      "CompanyName@com.example.display.style": { "title": true, "order": 1 },
    -      "CompanyName": "Alfreds Futterkiste",
    -      "Orders@com.example.display.style#simple": { "order": 2 }
    -    }
    -  ]
    -}
    +
    {
    +  "@context": "http://host/service/$metadata#Customers",
    +  "@com.example.customer.setkind": "VIPs",
    +  "value": [
    +    {
    +      "@com.example.display.highlight": true,
    +      "ID": "ALFKI",
    +      "CompanyName@com.example.display.style": { "title": true, "order": 1 },
    +      "CompanyName": "Alfreds Futterkiste",
    +      "Orders@com.example.display.style#simple": { "order": 2 }
    +    }
    +  ]
    +}

    20.1 Annotate a JSON Object

    When annotating a name/value pair for which the value is represented as a JSON object, each annotation is placed within the object and represented as a single name/value pair.

    @@ -1832,24 +1975,24 @@

    21.1 E

    Error responses MAY contain annotations in any of its JSON objects.

    Example 55:

    -
    {
    -  "error": {
    -    "code": "err123",
    -    "message": "Unsupported functionality",
    -    "target": "query",
    -    "details": [
    -      {
    -      "code": "forty-two",
    -      "target": "$search",
    -      "message": "$search query option not supported"
    -      }
    -    ],
    -    "innererror": {
    -      "trace": [...],
    -      "context": {...}
    -    }
    -  }
    -}
    +
    {
    +  "error": {
    +    "code": "err123",
    +    "message": "Unsupported functionality",
    +    "target": "query",
    +    "details": [
    +      {
    +      "code": "forty-two",
    +      "target": "$search",
    +      "message": "$search query option not supported"
    +      }
    +    ],
    +    "innererror": {
    +      "trace": [...],
    +      "context": {...}
    +    }
    +  }
    +}

    21.2 In-Stream Error

    In the case that a service encounters an error after sending a success status to the client, the service MUST leave the response malformed. This can be achieved by immediately stopping response serialization and thus omitting (among others) the end-object character of the top-level JSON object in the response.

    @@ -1861,9 +2004,9 @@

    21.2

    Example 56: note that this is one HTTP header line without any line breaks or optional whitespace

    -
    OData-error: {"code":"err123","message":"Unsupported
    -functionality","target":"query","details":[{"code":"forty-two","target":"$search","message":"$search
    -query option not supported"}]}
    +
    OData-error: {"code":"err123","message":"Unsupported
    +functionality","target":"query","details":[{"code":"forty-two","target":"$search","message":"$search
    +query option not supported"}]}

    21.3 Error Information in a Success Payload

    Services may return error information within a success payload; for example, if the client has specified the continue-on-error preference.

    diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md index e1dd4ebbc..7ee29c591 100644 --- a/docs/odata-json-format/odata-json-format.md +++ b/docs/odata-json-format/odata-json-format.md @@ -2478,7 +2478,7 @@ the target MAY be omitted for single-valued navigation. ## 15.6 Update a Collection of Entities -The body of a PATCH request to a URL identifying a collection of +The body of a `PATCH` request to a URL identifying a collection of entities is a JSON object. It MUST contain the [`context`](#ControlInformationcontextodatacontext) control information with a string value of `#$delta`, and it @@ -2489,7 +2489,7 @@ entities, as well as [added](#AddedLink) or [deleted](#DeletedLink) links between entities. ::: example -Example 39: 4.01 delta response customers with expanded orders represented +Example 39: 4.01 collection-update request for customers with expanded orders represented inline as a delta 1. Add customer `EASTC` 2. Change `ContactName` of customer `AROUT` @@ -2497,32 +2497,43 @@ inline as a delta 4. Change customer `ALFKI`: 1. Create order 11011 2. Add link to existing order 10692 - 3. Change `ShippedDate` of related order 10835 + 3. Change `RequiredDate` of related order 10835 4. Delete link to order 10643 5. Add link between customer `ANATR` and order 10643 6. Delete link between customer `DUMON` and order 10311 ```json +PATCH /service/Customers HTTP/1.1 +Host: host +Content-Type: application/json +Content-Length: ### +Prefer: return=minimal, continue-on-error + { "@context": "#$delta", "value": [ { + "@Org.OData.Core.V1.ContentID": "1", "CustomerID": "EASTC", "CompanyName": "Eastern Connection", "ContactName": "Ann Devon", "ContactTitle": "Sales Agent" }, { + "@Org.OData.Core.V1.ContentID": "2", "CustomerID": "AROUT", "ContactName": "Thomas Hardy", }, { + "@Org.OData.Core.V1.ContentID": "3", "@removed": {}, "CustomerID":"ANTON" }, { + "@Org.OData.Core.V1.ContentID": "4", "CustomerID": "ALFKI", "Orders@delta": [ { + "@Org.OData.Core.V1.ContentID": "4.1", "OrderID": 11011, "CustomerID": "ALFKI", "EmployeeID": 3, @@ -2531,13 +2542,16 @@ inline as a delta "ShippedDate": "1998-04-13T00:00:00Z" }, { + "@Org.OData.Core.V1.ContentID": "4.2", "@id": "Orders(10692)" }, { + "@Org.OData.Core.V1.ContentID": "4.3", "@id": "Orders(10835)", - "ShippedDate": "1998-01-23T00:00:00Z", + "RequiredDate": "1998-01-23T00:00:00Z", }, { + "@Org.OData.Core.V1.ContentID": "4.4", "@removed": { "reason": "changed" }, @@ -2547,12 +2561,14 @@ inline as a delta }, { "@context": "#Customers/$link", + "@Org.OData.Core.V1.ContentID": "5", "source": "Customers('ANATR')", "relationship":" Orders", "target": "Orders(10643)" }, { "@context": "#Customers/$deletedLink", + "@Org.OData.Core.V1.ContentID": "6", "source": "Customers('DUMON')", "relationship": "Orders", "target": "Orders(10311)" @@ -2560,6 +2576,138 @@ inline as a delta ] } ``` + +Assuming all changes can be applied without errors, the response would be +``` +HTTP/1.1 204 No Content +Preference-Applied: return=minimal, continue-on-error + + +``` + +Assuming some or all changes cannot be applied, the overall request is still deemed successful due to the `continue-on-error` preference, and the response details what went wrong + 1. Add customer 'EASTC' - failed + 2. Change `ContactName` of customer 'AROUT' - failed + 3. Delete customer 'ANTON' - failed + 4. Change customer 'ALFKI': + 1. Create order 11011 - succeeded, not mentioned in response + 2. Add link to existing order 10692 - succeeded, not mentioned in response + 3. Change `RequiredDate` of related order 10835 - failed + 4. Delete link to order 10643 - succeeded, not mentioned in response + 5. Add link between customer 'ANATR' and order 10643 - failed without further info + 6. Delete link between customer 'DUMON' and order 10311 - failed without further info +```json +HTTP/1.1 200 OK +Content-Type: application/json +Content-Length: ### +Preference-Applied: return=minimal, continue-on-error + +{ + "@context": "#$delta", + "value": [ + { + "@Org.OData.Core.V1.ContentID": "1", + "CustomerID": "EASTC", + "@removed": {}, + "@Org.OData.Core.V1.DataModificationException": { + "failedOperation": "insert", + "responseCode": 400, + "info": { + "code": "incmplt", + "message": "Required field(s) not provided", + "target": "Address", + "@OtherVocab.additionalTargets": [ "Industry", "VATRegistration" ], + "severity": "error" + } + } + }, + { + "@Org.OData.Core.V1.ContentID": "2", + "CustomerID": "AROUT", + "@Org.OData.Core.V1.DataModificationException": { + "failedOperation": "update", + "responseCode": 400, + "info": { + "code": "r-o", + "message": "Customer is archived and cannot be changed", + "severity": "error" + } + } + }, + { + "@Org.OData.Core.V1.ContentID": "3", + "CustomerID":"ANTON" + "@Org.OData.Core.V1.DataModificationException": { + "failedOperation": "delete", + "responseCode": 400, + "info": { + "code": "ufo", + "message": "Customer has unfinished orders and cannot be deleted", + "severity": "error" + } + } + }, + { + "@Org.OData.Core.V1.ContentID": "4", + "CustomerID": "ALFKI", + "Orders@delta": [ + { + "@Org.OData.Core.V1.ContentID": "4.3", + "@id": "Orders(10835)", + "@Org.OData.Core.V1.DataModificationException": { + "failedOperation": "update", + "responseCode": 400, + "info": { + "code": "b/s", + "message": "RequiredDate cannot be changed because Order is already being shipped", + "severity": "error" + } + } + } + ] + }, + { + "@context": "#Customers/$deletedLink", + "@Org.OData.Core.V1.ContentID": "5", + "source": "Customers('ANATR')", + "relationship":" Orders", + "target": "Orders(10643)", + "@Org.OData.Core.V1.DataModificationException": { + "failedOperation": "link", + "responseCode": 404, + "info": null + } + }, + { + "@context": "#Customers/$link", + "@Org.OData.Core.V1.ContentID": "6", + "source": "Customers('DUMON')", + "relationship": "Orders", + "target": "Orders(10311)", + "@Org.OData.Core.V1.DataModificationException": { + "failedOperation": "unlink", + "responseCode": 400 + } + } + ] +} +``` + +Without the `continue-on-error` preference processing would stop on the first error, and the response would be a standard OData error response +```json +HTTP/1.1 400 Bad Request +Content-Type: application/json +Content-Length: ### + +{ + "error": { + "code": "incmplt", + "message": "Required field(s) not provided", + "target": "Customers('EASTC')/Address", + "@OtherVocab.additionalTargets": [ "Customers('EASTC')/Industry", "Customers('EASTC')/VATRegistration" ] + } +} +``` ::: diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html index 2e34909dc..031fe1220 100644 --- a/docs/odata-protocol/odata-protocol.html +++ b/docs/odata-protocol/odata-protocol.html @@ -815,7 +815,7 @@

    OData-VocCore.

    Properties with null or default values MUST be included in delta payloads, if modified.

    -

    The response to a POST operation MUST include any properties not set to their default value, and the response to a PUT/PATCH operation MUST include any properties whose values were changed as part of the operation.

    +

    The response to a POST operation MUST include any properties not set to their default value, and the response to a PUT or PATCH operation MUST include any properties whose values were changed as part of the operation.

    The omit-values preference does not affect a request payload.

    8.2.8.7 Preference return=representation and return=minimal

    The return=representation and return=minimal preferences are defined in RFC7240.

    @@ -1844,8 +1844,8 @@

    Example 8: references to other CSDL documents

    {
    -  ...
    +  
       "$Reference": {
         "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
    -      ...
    +      
         },
         "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
    -      ...
    +      
         },
         "http://example.org/display/v1": {
    -      ...
    +      
         }
       },
    -  ...
    +  
     }

    4.2 Included Schema

    @@ -861,7 +861,7 @@

    $Alias

    Example 9: references to entity models containing definitions of vocabulary terms

    {
    -  ...
    +  
       "$Reference": {
         "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
           "$Include": [
    @@ -889,7 +889,7 @@ 

    $Alias

    ] } }, - ... + }

    4.3 Included Annotations

    @@ -912,7 +912,7 @@

    Example 10: reference documents that contain annotations

    {
    -  ...
    +  
       "$Reference": {
         "http://odata.org/ann/b": {
           "$IncludeAnnotations": [
    @@ -935,7 +935,7 @@ 

    ] } }, - ... + }

    @@ -973,13 +973,13 @@

    $Alias

    Example 11: document defining a schema org.example with an alias and a description for the schema

    {
    -  ...
    +  
       "org.example": {
         "$Alias": "self",
         "@Core.Description": "Example schema",
    -    ...
    +    
       },
    -  ...
    +  
     }

    5.2 Annotations with External Targeting

    @@ -994,7 +994,7 @@

    $Annotations "$Annotations": { "self.Person": { "@Core.Description#Tablet": "Dummy", - ... + } } }

    @@ -1263,7 +1263,7 @@

    Navig

    Example 22: the Product entity type has a navigation property to a Category, which has a navigation link back to one or more products

    "Product": {
       "$Kind": "EntityType",
    -  ...
    +  
       "Category": {
         "$Kind": "NavigationProperty",
         "$Type": "self.Category",
    @@ -1279,7 +1279,7 @@ 

    Navig }, "Category": { "$Kind": "EntityType", - ... + "Products": { "$Kind": "NavigationProperty", "$Collection": true, @@ -1351,7 +1351,7 @@

    $

    Example 23: the category must exist for a product in that category to exist. The CategoryID of the product is identical to the ID of the category, and the CategoryKind property of the product is identical to the Kind property of the category.

    "Product": {
       "$Kind": "EntityType",
    -  ...
    +  
       "CategoryID": {},
       "CategoryKind": {},
       "Category": {
    @@ -1374,7 +1374,7 @@ 

    $ "Kind": { "$Nullable": true }, - ... + }

    8.6 On-Delete Action

    @@ -1396,7 +1396,7 @@

    $OnDelete

    Example 24: deletion of a category implies deletion of the related products in that category

    "Category": {
       "$Kind": "EntityType",
    -  ...
    +  
       "Products": {
         "$Kind": "NavigationProperty",
         "$Collection": true,
    @@ -1436,7 +1436,7 @@ 

    Complex Type Object } }, "Product": { - ... + "ProductDimensions": { "$Nullable": true, "$Type": "self.Dimensions" @@ -1447,7 +1447,7 @@

    Complex Type Object } }, "ShipmentBox": { - ... + "Dimensions": { "$Nullable": true, "$Type": "self.Dimensions" @@ -1844,7 +1844,7 @@

    $Extends

    "Extending": {
       "$Kind": "EntityContainer",
       "$Extends": "Some.Other.Schema.Base",
    -   ...
    +   
     }

    13.2 Entity Set

    @@ -2203,10 +2203,9 @@

    $AppliesTo "Property", "Term" ], - "@Core.Description": "Properties and terms annotated with this term -MUST contain a valid URL", - "@Core.RequiresType": "Edm.String" -} + "@Core.Description": "Properties and terms annotated with this term MUST contain a valid URL", + "@Core.RequiresType": "Edm.String" +}

    14.2 Annotation

    An annotation applies a term to a model element and defines how to calculate a value for the term application. Both term and model element MUST be in scope. Section 14.1.2 specifies which model elements MAY be annotated with a term.

    @@ -2528,7 +2527,7 @@

    14.4.1.1 Path

    If a path segment is a qualified name, it represents a type cast, and the segment MUST be the name of a type in scope. If the type or instance identified by the preceding path part cannot be cast to the specified type, the path expression evaluates to the null value.

    Example 60: type-cast segment

    -
    .../self.Manager/...
    +
    …/self.Manager/…

    If a path segment starts with an at (@) character, it represents a term cast. The at (@) character MUST be followed by a qualified name that MAY be followed by a hash (#) character and a simple identifier. The qualified name preceding the hash character MUST resolve to a term that is in scope, the simple identifier following the hash sign is interpreted as a qualifier for the term. If the model element or instance identified by the preceding path part has not been annotated with that term (and if present, with that qualifier), the term cast evaluates to the null value. Four special terms are implicitly “annotated” for media entities and stream properties:

    Example 61: term-cast segments

    -
    .../@Capabilities.SortRestrictions/...
    +
    …/@Capabilities.SortRestrictions/…

    If a path segment is a simple identifier, it MUST be the name of a child model element of the model element identified by the preceding path part, or a structural or navigation property of the instance identified by the preceding path part. A sequence of navigation segments can traverse multiple CSDL documents. The document containing the path expression only needs to reference the next traversed document to bring the navigation target type into scope, and each traversed document in turn needs to reference only its next document.

    A model path MAY contain any number of segments representing collection-valued structural or navigation properties. The result of the expression is the model element reached via this path.

    Example 62: property segments in model path

    -
    .../Orders/Items/Product/...
    +
    …/Orders/Items/Product/…

    An instance path MUST NOT contain more than one segment representing a collection-valued construct, e.g. an entity set or a collection-valued navigation property that is not followed by a key predicate, or a collection-valued structural property that is not followed by an index segment. The result of the expression is the collection of instances resulting from applying any remaining path segments that operate on a single-valued expression to each instance in the collection-valued segment.

    An instance path MAY terminate in a $count segment if the previous segment is collection-valued, in which case the path evaluates to the number of items in the collection identified by the preceding segment.

    Example 63: property segments in instance path

    -
    .../Addresses/Street
    -
    .../Addresses/$count
    +
    …/Addresses/Street
    +
    …/Addresses/$count

    A model path MAY contain path segments starting with a navigation property, then followed by an at (@) character, then followed by the qualified name of a term in scope, and optionally followed by a hash (#) character and a simple identifier which is interpreted as a qualifier for the term. If the navigation property has not been annotated with that term (and if present, with that qualifier), the path segment evaluates to the null value. This allows addressing annotations on the navigation property itself; annotations on the entity type specified by the navigation property are addressed via a term-cast segment.

    Example 64: model path segment addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property

    -
    .../Items@Core.Description
    -
    .../Items/@Core.Description
    +
    …/Items@Core.Description
    +
    …/Items/@Core.Description

    An instance path MAY contain path segments starting with an entity set or a collection-valued navigation property, then followed by a key predicate using parentheses-style convention, see OData-URL. The key values are either primitive literals or instance paths. If the key value is a relative instance path, it is interpreted according to the same rule below as the instance path it is part of, not relative to the instance identified by the preceding path part.

    @@ -2601,7 +2600,7 @@

    1 "@Core.Description@Core.IsLanguageDependent": { "$Path": "A1" }, - "@Core.Description": "..." + "@Core.Description": "…" } }, "B": { @@ -2625,7 +2624,7 @@

    1 "@Core.Description#viaset@Core.IsLanguageDependent": { "$Path": "B1" }, - "@Core.Description#viaset": "..." + "@Core.Description#viaset": "…" }, "self.Container/SetA/A2/@Core.Description#viaset": { "@Core.IsLanguageDependent": { @@ -2639,7 +2638,7 @@

    1 "@Core.Description#external@Core.IsLanguageDependent": { "$Path": "A1" }, - "@Core.Description#external": "..." + "@Core.Description#external": "…" }, "self.A/A2/@Core.Description": { "@Core.IsLanguageDependent": { @@ -2690,13 +2689,12 @@

    Example 70:

    "@UI.HyperLink": "Supplier",
    -
    -"@Capabilities.UpdateRestrictions": {
    -  "NonUpdatableNavigationProperties": [
    -    "Supplier",
    -    "Category"
    -  ]
    -}
    +"@Capabilities.UpdateRestrictions": { + "NonUpdatableNavigationProperties": [ + "Supplier", + "Category" + ] +}

    14.4.1.6 Property Path

    The property path expression provides a value for terms or term properties that specify one of the built-in types Edm.PropertyPath, Edm.AnyPropertyPath, or Edm.ModelElementPath. Its argument is a model path with the following restriction:

    @@ -2710,13 +2708,12 @@

    14.4.1.

    Example 71:

    "@UI.RefreshOnChangeOf": "ChangedAt",
    -
    -"@Capabilities.UpdateRestrictions": {
    -  "NonUpdatableProperties": [
    -    "CreatedAt",
    -    "ChangedAt"
    -  ]
    -}
    +"@Capabilities.UpdateRestrictions": { + "NonUpdatableProperties": [ + "CreatedAt", + "ChangedAt" + ] +}

    14.4.1.7 Value Path

    The value path expression allows assigning a value by traversing an object graph. It can be used in annotations that target entity containers, entity sets, entity types, complex types, navigation properties of structured types, and structural properties of structured types. Its argument is an instance path.

    @@ -2730,10 +2727,9 @@

    $Path

    "@UI.DisplayName": {
       "$Path": "FirstName"
     },
    -
    -"@UI.DisplayName#second": {
    -  "$Path": "@vCard.Address#work/FullName"
    -}
    +"@UI.DisplayName#second": { + "$Path": "@vCard.Address#work/FullName" +}

    14.4.2 Comparison and Logical Operators

    Annotations MAY use the following logical and comparison expressions which evaluate to a Boolean value. These expressions MAY be combined and they MAY be used anywhere instead of a Boolean expression.

    @@ -3295,11 +3291,11 @@

    15.4 Target Pat

    Example 89: Target expressions

    -
    MySchema.MyEntityContainer/MyEntitySet
    -MySchema.MyEntityContainer/MySingleton
    -MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty
    -MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty
    -MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp
    +
    MySchema.MyEntityContainer/MyEntitySet
    +
    MySchema.MyEntityContainer/MySingleton
    +
    MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty
    +
    MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty
    +
    MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp

    16 CSDL Examples

    @@ -3307,270 +3303,270 @@

    16 CSDL Ex

    16.1 Products and Categories Example

    Example 90:

    -
    {
    -  "$Version": "4.0",
    -  "$EntityContainer": "ODataDemo.DemoService",
    -  "$Reference": {
    -    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
    -      "$Include": [
    -        {
    -          "$Namespace": "Org.OData.Core.V1",
    -          "$Alias": "Core",
    -          "@Core.DefaultNamespace": true
    -        }
    -      ]
    -    },
    -    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.json": {
    -      "$Include": [
    -        {
    -          "$Namespace": "Org.OData.Measures.V1",
    -          "$Alias": "Measures"
    -        }
    -      ]
    -    }
    -  },
    -  "ODataDemo": {
    -    "$Alias": "self",
    -    "@Core.DefaultNamespace": true,
    -    "Product": {
    -      "$Kind": "EntityType",
    -      "$Key": [
    -        "ID"
    -      ],
    -      "ID": {},
    -      "Description": {
    -        "$Nullable": true,
    -        "@Core.IsLanguageDependent": true
    -      },
    -      "ReleaseDate": {
    -        "$Nullable": true,
    -        "$Type": "Edm.Date"
    -      },
    -      "DiscontinuedDate": {
    -        "$Nullable": true,
    -        "$Type": "Edm.Date"
    -      },
    -      "Rating": {
    -        "$Nullable": true,
    -        "$Type": "Edm.Int32"
    -      },
    -      "Price": {
    -        "$Nullable": true,
    -        "$Type": "Edm.Decimal",
    -        "@Measures.ISOCurrency": {
    -          "$Path": "Currency"
    -        }
    -      },
    -      "Currency": {
    -        "$Nullable": true,
    -        "$MaxLength": 3
    -      },
    -      "Category": {
    -        "$Kind": "NavigationProperty",
    -        "$Type": "self.Category",
    -        "$Partner": "Products"
    -      },
    -      "Supplier": {
    -        "$Kind": "NavigationProperty",
    -        "$Nullable": true,
    -        "$Type": "self.Supplier",
    -        "$Partner": "Products"
    -      }
    -    },
    -    "Category": {
    -      "$Kind": "EntityType",
    -      "$Key": [
    -        "ID"
    -      ],
    -      "ID": {
    -        "$Type": "Edm.Int32"
    -      },
    -      "Name": {
    -        "@Core.IsLanguageDependent": true
    -      },
    -      "Products": {
    -        "$Kind": "NavigationProperty",
    -        "$Partner": "Category",
    -        "$Collection": true,
    -        "$Type": "self.Product",
    -        "$OnDelete": "Cascade"
    -      }
    -    },
    -    "Supplier": {
    -      "$Kind": "EntityType",
    -      "$Key": [
    -        "ID"
    -      ],
    -      "ID": {},
    -      "Name": {
    -        "$Nullable": true
    -      },
    -      "Address": {
    -        "$Type": "self.Address"
    -      },
    -      "Concurrency": {
    -        "$Type": "Edm.Int32"
    -      },
    -      "Products": {
    -        "$Kind": "NavigationProperty",
    -        "$Partner": "Supplier",
    -        "$Collection": true,
    -        "$Type": "self.Product"
    -      }
    -    },
    -    "Country": {
    -      "$Kind": "EntityType",
    -      "$Key": [
    -        "Code"
    -      ],
    -      "Code": {
    -        "$MaxLength": 2
    -      },
    -      "Name": {
    -        "$Nullable": true
    -      }
    -    },
    -    "Address": {
    -      "$Kind": "ComplexType",
    -      "Street": {
    -        "$Nullable": true
    -      },
    -      "City": {
    -        "$Nullable": true
    -      },
    -      "State": {
    -        "$Nullable": true
    -      },
    -      "ZipCode": {
    -        "$Nullable": true
    -      },
    -      "CountryName": {
    -        "$Nullable": true
    -      },
    -      "Country": {
    -        "$Kind": "NavigationProperty",
    -        "$Nullable": true,
    -        "$Type": "self.Country",
    -        "$ReferentialConstraint": {
    -          "CountryName": "Name"
    -        }
    -      }
    -    },
    -    "ProductsByRating": [
    -      {
    -        "$Kind": "Function",
    -        "$Parameter": [
    -          {
    -            "$Name": "Rating",
    -            "$Nullable": true,
    -            "$Type": "Edm.Int32"
    -          }
    -        ],
    -        "$ReturnType": {
    -          "$Collection": true,
    -          "$Type": "self.Product"
    -        }
    -      }
    -    ],
    -    "DemoService": {
    -      "$Kind": "EntityContainer",
    -      "Products": {
    -        "$Collection": true,
    -        "$Type": "self.Product",
    -        "$NavigationPropertyBinding": {
    -          "Category": "Categories"
    -        }
    -      },
    -      "Categories": {
    -        "$Collection": true,
    -        "$Type": "self.Category",
    -        "$NavigationPropertyBinding": {
    -          "Products": "Products"
    -        },
    -        "@Core.Description": "Product Categories"
    -      },
    -      "Suppliers": {
    -        "$Collection": true,
    -        "$Type": "self.Supplier",
    -        "$NavigationPropertyBinding": {
    -          "Products": "Products",
    -          "Address/Country": "Countries"
    -        },
    -        "@Core.OptimisticConcurrency": [
    -          "Concurrency"
    -        ]
    -      },
    -      "Countries": {
    -        "$Collection": true,
    -        "$Type": "self.Country"
    -      },
    -      "MainSupplier": {
    -        "$Type": "self.Supplier",
    -        "$NavigationPropertyBinding": {
    -          "Products": "Products"
    -        },
    -        "@Core.Description": "Primary Supplier"
    -      },
    -      "ProductsByRating": {
    -        "$EntitySet": "Products",
    -        "$Function": "self.ProductsByRating"
    -      }
    -    }
    -  }
    -}
    +
    {
    +  "$Version": "4.0",
    +  "$EntityContainer": "ODataDemo.DemoService",
    +  "$Reference": {
    +    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
    +      "$Include": [
    +        {
    +          "$Namespace": "Org.OData.Core.V1",
    +          "$Alias": "Core",
    +          "@Core.DefaultNamespace": true
    +        }
    +      ]
    +    },
    +    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.json": {
    +      "$Include": [
    +        {
    +          "$Namespace": "Org.OData.Measures.V1",
    +          "$Alias": "Measures"
    +        }
    +      ]
    +    }
    +  },
    +  "ODataDemo": {
    +    "$Alias": "self",
    +    "@Core.DefaultNamespace": true,
    +    "Product": {
    +      "$Kind": "EntityType",
    +      "$Key": [
    +        "ID"
    +      ],
    +      "ID": {},
    +      "Description": {
    +        "$Nullable": true,
    +        "@Core.IsLanguageDependent": true
    +      },
    +      "ReleaseDate": {
    +        "$Nullable": true,
    +        "$Type": "Edm.Date"
    +      },
    +      "DiscontinuedDate": {
    +        "$Nullable": true,
    +        "$Type": "Edm.Date"
    +      },
    +      "Rating": {
    +        "$Nullable": true,
    +        "$Type": "Edm.Int32"
    +      },
    +      "Price": {
    +        "$Nullable": true,
    +        "$Type": "Edm.Decimal",
    +        "@Measures.ISOCurrency": {
    +          "$Path": "Currency"
    +        }
    +      },
    +      "Currency": {
    +        "$Nullable": true,
    +        "$MaxLength": 3
    +      },
    +      "Category": {
    +        "$Kind": "NavigationProperty",
    +        "$Type": "self.Category",
    +        "$Partner": "Products"
    +      },
    +      "Supplier": {
    +        "$Kind": "NavigationProperty",
    +        "$Nullable": true,
    +        "$Type": "self.Supplier",
    +        "$Partner": "Products"
    +      }
    +    },
    +    "Category": {
    +      "$Kind": "EntityType",
    +      "$Key": [
    +        "ID"
    +      ],
    +      "ID": {
    +        "$Type": "Edm.Int32"
    +      },
    +      "Name": {
    +        "@Core.IsLanguageDependent": true
    +      },
    +      "Products": {
    +        "$Kind": "NavigationProperty",
    +        "$Partner": "Category",
    +        "$Collection": true,
    +        "$Type": "self.Product",
    +        "$OnDelete": "Cascade"
    +      }
    +    },
    +    "Supplier": {
    +      "$Kind": "EntityType",
    +      "$Key": [
    +        "ID"
    +      ],
    +      "ID": {},
    +      "Name": {
    +        "$Nullable": true
    +      },
    +      "Address": {
    +        "$Type": "self.Address"
    +      },
    +      "Concurrency": {
    +        "$Type": "Edm.Int32"
    +      },
    +      "Products": {
    +        "$Kind": "NavigationProperty",
    +        "$Partner": "Supplier",
    +        "$Collection": true,
    +        "$Type": "self.Product"
    +      }
    +    },
    +    "Country": {
    +      "$Kind": "EntityType",
    +      "$Key": [
    +        "Code"
    +      ],
    +      "Code": {
    +        "$MaxLength": 2
    +      },
    +      "Name": {
    +        "$Nullable": true
    +      }
    +    },
    +    "Address": {
    +      "$Kind": "ComplexType",
    +      "Street": {
    +        "$Nullable": true
    +      },
    +      "City": {
    +        "$Nullable": true
    +      },
    +      "State": {
    +        "$Nullable": true
    +      },
    +      "ZipCode": {
    +        "$Nullable": true
    +      },
    +      "CountryName": {
    +        "$Nullable": true
    +      },
    +      "Country": {
    +        "$Kind": "NavigationProperty",
    +        "$Nullable": true,
    +        "$Type": "self.Country",
    +        "$ReferentialConstraint": {
    +          "CountryName": "Name"
    +        }
    +      }
    +    },
    +    "ProductsByRating": [
    +      {
    +        "$Kind": "Function",
    +        "$Parameter": [
    +          {
    +            "$Name": "Rating",
    +            "$Nullable": true,
    +            "$Type": "Edm.Int32"
    +          }
    +        ],
    +        "$ReturnType": {
    +          "$Collection": true,
    +          "$Type": "self.Product"
    +        }
    +      }
    +    ],
    +    "DemoService": {
    +      "$Kind": "EntityContainer",
    +      "Products": {
    +        "$Collection": true,
    +        "$Type": "self.Product",
    +        "$NavigationPropertyBinding": {
    +          "Category": "Categories"
    +        }
    +      },
    +      "Categories": {
    +        "$Collection": true,
    +        "$Type": "self.Category",
    +        "$NavigationPropertyBinding": {
    +          "Products": "Products"
    +        },
    +        "@Core.Description": "Product Categories"
    +      },
    +      "Suppliers": {
    +        "$Collection": true,
    +        "$Type": "self.Supplier",
    +        "$NavigationPropertyBinding": {
    +          "Products": "Products",
    +          "Address/Country": "Countries"
    +        },
    +        "@Core.OptimisticConcurrency": [
    +          "Concurrency"
    +        ]
    +      },
    +      "Countries": {
    +        "$Collection": true,
    +        "$Type": "self.Country"
    +      },
    +      "MainSupplier": {
    +        "$Type": "self.Supplier",
    +        "$NavigationPropertyBinding": {
    +          "Products": "Products"
    +        },
    +        "@Core.Description": "Primary Supplier"
    +      },
    +      "ProductsByRating": {
    +        "$EntitySet": "Products",
    +        "$Function": "self.ProductsByRating"
    +      }
    +    }
    +  }
    +}

    16.2 Annotations for Products and Categories Example

    Example 91:

    -
    {
    -  "$Version": "4.01",
    -  "$Reference": {
    -    "http://host/service/$metadata": {
    -      "$Include": [
    -        {
    -          "$Namespace": "ODataDemo",
    -          "$Alias": "target"
    -        }
    -      ]
    -    },
    -    "http://somewhere/Vocabulary/V1": {
    -      "$Include": [
    -        {
    -          "$Namespace": "Some.Vocabulary.V1",
    -          "$Alias": "Vocabulary1"
    -        }
    -      ]
    -    }
    -  },
    -  "External.Annotations": {
    -    "$Annotations": {
    -      "target.Supplier": {
    -        "@Vocabulary1.EMail": null,
    -        "@Vocabulary1.AccountID": {
    -          "$Path": "ID"
    -        },
    -        "@Vocabulary1.Title": "Supplier Info",
    -        "@Vocabulary1.DisplayName": {
    -          "$Apply": [
    -            {
    -              "$Path": "Name"
    -            },
    -            " in ",
    -            {
    -              "$Path": "Address/CountryName"
    -            }
    -          ],
    -          "$Function": "odata.concat"
    -        }
    -      },
    -      "target.Product": {
    -        "@Vocabulary1.Tags": [
    -          "MasterData"
    -        ]
    -      }
    -    }
    -  }
    -}
    +
    {
    +  "$Version": "4.01",
    +  "$Reference": {
    +    "http://host/service/$metadata": {
    +      "$Include": [
    +        {
    +          "$Namespace": "ODataDemo",
    +          "$Alias": "target"
    +        }
    +      ]
    +    },
    +    "http://somewhere/Vocabulary/V1": {
    +      "$Include": [
    +        {
    +          "$Namespace": "Some.Vocabulary.V1",
    +          "$Alias": "Vocabulary1"
    +        }
    +      ]
    +    }
    +  },
    +  "External.Annotations": {
    +    "$Annotations": {
    +      "target.Supplier": {
    +        "@Vocabulary1.EMail": null,
    +        "@Vocabulary1.AccountID": {
    +          "$Path": "ID"
    +        },
    +        "@Vocabulary1.Title": "Supplier Info",
    +        "@Vocabulary1.DisplayName": {
    +          "$Apply": [
    +            {
    +              "$Path": "Name"
    +            },
    +            " in ",
    +            {
    +              "$Path": "Address/CountryName"
    +            }
    +          ],
    +          "$Function": "odata.concat"
    +        }
    +      },
    +      "target.Product": {
    +        "@Vocabulary1.Tags": [
    +          "MasterData"
    +        ]
    +      }
    +    }
    +  }
    +}

    17 Conformance

    diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md index 1a2219d5d..46dfa0f37 100644 --- a/docs/odata-csdl-json/odata-csdl-json.md +++ b/docs/odata-csdl-json/odata-csdl-json.md @@ -930,7 +930,7 @@ Example 7: { "$Version": "4.01", "$EntityContainer": "org.example.DemoService", - ... + … } ``` ::: @@ -983,19 +983,19 @@ The reference object MAY contain the members Example 8: references to other CSDL documents ```json { - ... + … "$Reference": { "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { - ... + … }, "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { - ... + … }, "http://example.org/display/v1": { - ... + … } }, - ... + … } ``` ::: @@ -1061,7 +1061,7 @@ Example 9: references to entity models containing definitions of vocabulary terms ```json { - ... + … "$Reference": { "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { "$Include": [ @@ -1089,7 +1089,7 @@ vocabulary terms ] } }, - ... + … } ``` ::: @@ -1158,7 +1158,7 @@ The value of `$TargetNamespace` is a namespace. Example 10: reference documents that contain annotations ```json { - ... + … "$Reference": { "http://odata.org/ann/b": { "$IncludeAnnotations": [ @@ -1181,7 +1181,7 @@ Example 10: reference documents that contain annotations ] } }, - ... + … } ``` ::: @@ -1281,13 +1281,13 @@ Example 11: document defining a schema `org.example` with an alias and a description for the schema ```json { - ... + … "org.example": { "$Alias": "self", "@Core.Description": "Example schema", - ... + … }, - ... + … } ``` ::: @@ -1314,7 +1314,7 @@ Example 12: annotations targeting the `Person` type with qualifier "$Annotations": { "self.Person": { "@Core.Description#Tablet": "Dummy", - ... + … } } } @@ -1886,7 +1886,7 @@ Example 22: the `Product` entity type has a navigation property to a ```json "Product": { "$Kind": "EntityType", - ... + … "Category": { "$Kind": "NavigationProperty", "$Type": "self.Category", @@ -1902,7 +1902,7 @@ Example 22: the `Product` entity type has a navigation property to a }, "Category": { "$Kind": "EntityType", - ... + … "Products": { "$Kind": "NavigationProperty", "$Collection": true, @@ -2134,7 +2134,7 @@ the `Kind` property of the category. ```json "Product": { "$Kind": "EntityType", - ... + … "CategoryID": {}, "CategoryKind": {}, "Category": { @@ -2157,7 +2157,7 @@ the `Kind` property of the category. "Kind": { "$Nullable": true }, - ... + … } ``` ::: @@ -2204,7 +2204,7 @@ products in that category ```json "Category": { "$Kind": "EntityType", - ... + … "Products": { "$Kind": "NavigationProperty", "$Collection": true, @@ -2279,7 +2279,7 @@ Example 25: a complex type used by two entity types } }, "Product": { - ... + … "ProductDimensions": { "$Nullable": true, "$Type": "self.Dimensions" @@ -2290,7 +2290,7 @@ Example 25: a complex type used by two entity types } }, "ShipmentBox": { - ... + … "Dimensions": { "$Nullable": true, "$Type": "self.Dimensions" @@ -3139,7 +3139,7 @@ entity container located in `SomeOtherSchema` "Extending": { "$Kind": "EntityContainer", "$Extends": "Some.Other.Schema.Base", - ... + … } ``` ::: @@ -3703,8 +3703,7 @@ are defined in [OData-VocCore](#ODataVocCore)) "Property", "Term" ], - "@Core.Description": "Properties and terms annotated with this term -MUST contain a valid URL", + "@Core.Description": "Properties and terms annotated with this term MUST contain a valid URL", "@Core.RequiresType": "Edm.String" } ``` @@ -4186,7 +4185,7 @@ the null value. ::: example Example 60: type-cast segment ``` -.../self.Manager/... +…/self.Manager/… ``` ::: @@ -4211,7 +4210,7 @@ properties: ::: example Example 61: term-cast segments ``` -.../@Capabilities.SortRestrictions/... +…/@Capabilities.SortRestrictions/… ``` ::: @@ -4231,7 +4230,7 @@ expression is the model element reached via this path. ::: example Example 62: property segments in model path ``` -.../Orders/Items/Product/... +…/Orders/Items/Product/… ``` ::: @@ -4251,11 +4250,11 @@ number of items in the collection identified by the preceding segment. ::: example Example 63: property segments in instance path ``` -.../Addresses/Street +…/Addresses/Street ``` ``` -.../Addresses/$count +…/Addresses/$count ``` ::: @@ -4275,11 +4274,11 @@ segment](#TermCast). Example 64: model path segment addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property ``` -.../Items@Core.Description +…/Items@Core.Description ``` ``` -.../Items/@Core.Description +…/Items/@Core.Description ``` ::: @@ -4408,7 +4407,7 @@ enclosing type `self.A` of the hosting property `A2`. "@Core.Description@Core.IsLanguageDependent": { "$Path": "A1" }, - "@Core.Description": "..." + "@Core.Description": "…" } }, "B": { @@ -4437,7 +4436,7 @@ type `self.B` of the hosting property `A2`. "@Core.Description#viaset@Core.IsLanguageDependent": { "$Path": "B1" }, - "@Core.Description#viaset": "..." + "@Core.Description#viaset": "…" }, "self.Container/SetA/A2/@Core.Description#viaset": { "@Core.IsLanguageDependent": { @@ -4456,7 +4455,7 @@ type `self.A` named in the target path. "@Core.Description#external@Core.IsLanguageDependent": { "$Path": "A1" }, - "@Core.Description#external": "..." + "@Core.Description#external": "…" }, "self.A/A2/@Core.Description": { "@Core.IsLanguageDependent": { @@ -4555,7 +4554,6 @@ containing a path. Example 70: ```json "@UI.HyperLink": "Supplier", - "@Capabilities.UpdateRestrictions": { "NonUpdatableNavigationProperties": [ "Supplier", @@ -4591,7 +4589,6 @@ Property path expressions are represented as a string containing a path. Example 71: ```json "@UI.RefreshOnChangeOf": "ChangedAt", - "@Capabilities.UpdateRestrictions": { "NonUpdatableProperties": [ "CreatedAt", @@ -4627,7 +4624,6 @@ Example 72: "@UI.DisplayName": { "$Path": "FirstName" }, - "@UI.DisplayName#second": { "$Path": "@vCard.Address#work/FullName" } @@ -5539,9 +5535,21 @@ segments Example 89: Target expressions ``` MySchema.MyEntityContainer/MyEntitySet +``` + +``` MySchema.MyEntityContainer/MySingleton +``` + +``` MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty +``` + +``` MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty +``` + +``` MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp ``` ::: diff --git a/docs/odata-csdl-xml/odata-csdl-xml.html b/docs/odata-csdl-xml/odata-csdl-xml.html index 5bb609002..5a99b05d3 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.html +++ b/docs/odata-csdl-xml/odata-csdl-xml.html @@ -782,7 +782,7 @@

    <edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
                Version="4.01">
       <edmx:DataServices>
    -    ...
    +
       </edmx:DataServices>
     </edmx:Edmx>
    @@ -806,16 +806,16 @@

    Attri Version="4.0"> <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml"> - ... + </edmx:Reference> <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml"> - ... + </edmx:Reference> <edmx:Reference Uri="http://example.org/display/v1"> - ... + </edmx:Reference> - <edmx:DataServices>...</edmx:DataServices> + <edmx:DataServices>…</edmx:DataServices> </edmx:Edmx>

    4.2 Included Schema

    @@ -855,7 +855,7 @@

    <edmx:Reference Uri="http://example.org/display/v1"> <edmx:Include Alias="UI" Namespace="org.example.display" /> </edmx:Reference> - <edmx:DataServices>...</edmx:DataServices> + <edmx:DataServices>…</edmx:DataServices> </edmx:Edmx>

    4.3 Included Annotations

    @@ -891,7 +891,7 @@

    Qualifier="Tablet" TargetNamespace="com.example.Person" /> </edmx:Reference> - <edmx:DataServices>...</edmx:DataServices> + <edmx:DataServices>…</edmx:DataServices> </edmx:Edmx>
    @@ -931,7 +931,7 @@

    Attribute Alias

    Example 11: schema org.example with an alias and a description for the schema

    <Schema Namespace="org.example" Alias="self">
       <Annotation Term="Core.Description" String="Example schema" />
    -  ...
    +
     </Schema>

    5.2 Annotations with External Targeting

    @@ -948,7 +948,7 @@

    <Annotations Target="org.example.Person" Qualifier="Tablet">
       <Annotation Term="Core.Description" String="Dummy" />
    -  ...
    +
     </Annotations>

    @@ -1177,14 +1177,14 @@

    Example 22: the Product entity type has a navigation property to a Category, which has a navigation link back to one or more products

    <EntityType Name="Product">
    -  ...
    +
       <NavigationProperty Name="Category" Type="self.Category" Nullable="false"
                           Partner="Products" />
       <NavigationProperty Name="Supplier" Type="self.Supplier" />
     </EntityType>
     
     <EntityType Name="Category">
    -  ...
    +
       <NavigationProperty Name="Products" Type="Collection(self.Product)"
                           Partner="Category" />
     </EntityType>
    @@ -1253,7 +1253,7 @@

    Example 23: the category must exist for a product in that category to exist. The CategoryID of the product is identical to the ID of the category, and the CategoryKind property of the product is identical to the Kind property of the category.

    <EntityType Name="Product">
    -  ...
    +
       <Property Name="CategoryID" Type="Edm.String" Nullable="false"/>
       <Property Name="CategoryKind" Type="Edm.String" Nullable="true" />
       <NavigationProperty Name="Category" Type="self.Category" Nullable="false">
    @@ -1271,7 +1271,7 @@ 

    </Key> <Property Name="ID" Type="Edm.String" Nullable="false" /> <Property Name="Kind" Type="Edm.String" Nullable="true" /> - ... + </EntityType>

    8.6 On-Delete Action

    @@ -1294,7 +1294,7 @@

    Example 24: deletion of a category implies deletion of the related products in that category

    <EntityType Name="Category">
    -  ...
    +
       <NavigationProperty Name="Products" Type="Collection(self.Product)">
         <OnDelete Action="Cascade">
           <Annotation Term="Core.Description"
    @@ -1326,13 +1326,13 @@ 

    </ComplexType> <EntityType Name="Product"> - ... + <Property Name="ProductDimensions" Type="self.Dimensions" /> <Property Name="ShippingDimensions" Type="self.Dimensions" /> </EntityType> <EntityType Name="ShipmentBox"> - ... + <Property Name="Dimensions" Type="self.Dimensions" /> </EntityType>

    @@ -1669,7 +1669,7 @@

    Attribute

    Example 34: the entity container Extending will contain all child elements that it defines itself, plus all child elements of the Base entity container located in SomeOtherSchema

    <EntityContainer Name="Extending" Extends="Some.Other.Schema.Base">
    -  ...
    +
     </EntityContainer>

    13.2 Entity Set

    @@ -1810,7 +1810,7 @@

    <Property Name="ID" Nullable="false" Type="Edm.Int32" /> <Property Name="Name" Type="Edm.String" /> <Property Name="Description" Type="Edm.String" /> - ... + <Annotation Term="UI.DisplayName" Path="Name" /> <Annotation Term="SearchVocabulary.SearchResult"> <Record> @@ -2412,7 +2412,7 @@

    14.4.1.1 Path

    If a path segment is a qualified name, it represents a type cast, and the segment MUST be the name of a type in scope. If the type or instance identified by the preceding path part cannot be cast to the specified type, the path expression evaluates to the null value.

    Example 60: type-cast segment

    -
    .../self.Manager/...
    +
    …/self.Manager/…

    If a path segment starts with an at (@) character, it represents a term cast. The at (@) character MUST be followed by a qualified name that MAY be followed by a hash (#) character and a simple identifier. The qualified name preceding the hash character MUST resolve to a term that is in scope, the simple identifier following the hash sign is interpreted as a qualifier for the term. If the model element or instance identified by the preceding path part has not been annotated with that term (and if present, with that qualifier), the term cast evaluates to the null value. Four special terms are implicitly “annotated” for media entities and stream properties:

    Example 61: term-cast segments

    -
    .../@Capabilities.SortRestrictions/...
    +
    …/@Capabilities.SortRestrictions/…

    If a path segment is a simple identifier, it MUST be the name of a child model element of the model element identified by the preceding path part, or a structural or navigation property of the instance identified by the preceding path part. A sequence of navigation segments can traverse multiple CSDL documents. The document containing the path expression only needs to reference the next traversed document to bring the navigation target type into scope, and each traversed document in turn needs to reference only its next document.

    A model path MAY contain any number of segments representing collection-valued structural or navigation properties. The result of the expression is the model element reached via this path.

    Example 62: property segments in model path

    -
    .../Orders/Items/Product/...
    +
    …/Orders/Items/Product/…

    An instance path MUST NOT contain more than one segment representing a collection-valued construct, e.g. an entity set or a collection-valued navigation property that is not followed by a key predicate, or a collection-valued structural property that is not followed by an index segment. The result of the expression is the collection of instances resulting from applying any remaining path segments that operate on a single-valued expression to each instance in the collection-valued segment.

    An instance path MAY terminate in a $count segment if the previous segment is collection-valued, in which case the path evaluates to the number of items in the collection identified by the preceding segment.

    Example 63: property segments in instance path

    -
    .../Addresses/Street
    -
    .../Addresses/$count
    +
    …/Addresses/Street
    +
    …/Addresses/$count

    A model path MAY contain path segments starting with a navigation property, then followed by an at (@) character, then followed by the qualified name of a term in scope, and optionally followed by a hash (#) character and a simple identifier which is interpreted as a qualifier for the term. If the navigation property has not been annotated with that term (and if present, with that qualifier), the path segment evaluates to the null value. This allows addressing annotations on the navigation property itself; annotations on the entity type specified by the navigation property are addressed via a term-cast segment.

    Example 64: model path segment addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property

    -
    .../Items@Core.Description
    -
    .../Items/@Core.Description
    +
    …/Items@Core.Description
    +
    …/Items/@Core.Description

    An instance path MAY contain path segments starting with an entity set or a collection-valued navigation property, then followed by a key predicate using parentheses-style convention, see OData-URL. The key values are either primitive literals or instance paths. If the key value is a relative instance path, it is interpreted according to the same rule below as the instance path it is part of, not relative to the instance identified by the preceding path part.

    @@ -2478,7 +2478,7 @@

    1 <EntityType Name="A"> <Property Name="A1" Type="Edm.Boolean" Nullable="false" /> <Property Name="A2" Type="self.B" Nullable="false"> - <Annotation Term="Core.Description" String="..."> + <Annotation Term="Core.Description" String="…"> <Annotation Term="Core.IsLanguageDependent" Path="A1" /> </Annotation> </Property> @@ -2493,7 +2493,7 @@

    1 <EntitySet Name="SetA" EntityType="self.A" /> </EntityContainer> <Annotations Target="self.Container/SetA/A2"> - <Annotation Term="Core.Description" Qualifier="viaset" String="..."> + <Annotation Term="Core.Description" Qualifier="viaset" String="…"> <Annotation Term="Core.IsLanguageDependent" Path="B1" /> </Annotation> </Annotations> @@ -2504,7 +2504,7 @@

    1

    Path evaluation for the annotations in the final block starts at the outermost type self.A named in the target path.

      <Annotations Target="self.A/A2">
    -    <Annotation Term="Core.Description" Qualifier="external" String="...">
    +    <Annotation Term="Core.Description" Qualifier="external" String="…">
           <Annotation Term="Core.IsLanguageDependent" Path="A1" />
         </Annotation>
       </Annotations>
    @@ -3066,11 +3066,11 @@ 

    15.4 Target Pat

    Example 89: Target expressions

    -
    MySchema.MyEntityContainer/MyEntitySet
    -MySchema.MyEntityContainer/MySingleton
    -MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty
    -MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty
    -MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp
    +
    MySchema.MyEntityContainer/MyEntitySet
    +
    MySchema.MyEntityContainer/MySingleton
    +
    MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty
    +
    MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty
    +
    MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp

    16 CSDL Examples

    @@ -3078,153 +3078,153 @@

    16 CSDL Ex

    16.1 Products and Categories Example

    Example 90:

    -
    <edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
    -           xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">
    -  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
    -    <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
    -      <Annotation Term="Core.DefaultNamespace" />
    -    </edmx:Include>
    -  </edmx:Reference>
    -  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.xml">
    -    <edmx:Include Alias="Measures" Namespace="Org.OData.Measures.V1" />
    -  </edmx:Reference>
    -  <edmx:DataServices>
    -    <Schema Namespace="ODataDemo">
    -      <EntityType Name="Product">
    -        <Key>
    -          <PropertyRef Name="ID" />
    -        </Key>
    -        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
    -        <Property Name="Description" Type="Edm.String" >
    -          <Annotation Term="Core.IsLanguageDependent" />
    -        </Property>
    -        <Property Name="ReleaseDate" Type="Edm.Date" />
    -        <Property Name="DiscontinuedDate" Type="Edm.Date" />
    -        <Property Name="Rating" Type="Edm.Int32" />
    -        <Property Name="Price" Type="Edm.Decimal" Scale="variable">
    -          <Annotation Term="Measures.ISOCurrency" Path="Currency" />
    -        </Property>
    -        <Property Name="Currency" Type="Edm.String" MaxLength="3" />
    -        <NavigationProperty Name="Category" Type="ODataDemo.Category"
    -                            Nullable="false" Partner="Products" />
    -        <NavigationProperty Name="Supplier" Type="ODataDemo.Supplier"
    -                            Partner="Products" />
    -      </EntityType>
    -      <EntityType Name="Category">
    -        <Key>
    -         <PropertyRef Name="ID" />
    -        </Key>
    -        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
    -        <Property Name="Name" Type="Edm.String" Nullable="false">
    -          <Annotation Term="Core.IsLanguageDependent" />
    -        </Property>
    -        <NavigationProperty Name="Products" Partner="Category"
    -                            Type="Collection(ODataDemo.Product)">
    -          <OnDelete Action="Cascade" />
    -        </NavigationProperty>
    -      </EntityType>
    -      <EntityType Name="Supplier">
    -        <Key>
    -          <PropertyRef Name="ID" />
    -        </Key>
    -        <Property Name="ID" Type="Edm.String" Nullable="false" />
    -        <Property Name="Name" Type="Edm.String" />
    -        <Property Name="Address" Type="ODataDemo.Address" Nullable="false" />
    -        <Property Name="Concurrency" Type="Edm.Int32" Nullable="false" />
    -        <NavigationProperty Name="Products" Partner="Supplier"
    -                            Type="Collection(ODataDemo.Product)" />
    -      </EntityType>
    -      <EntityType Name="Country">
    -        <Key>
    -          <PropertyRef Name="Code" />
    -        </Key>
    -        <Property Name="Code" Type="Edm.String" MaxLength="2"
    -                              Nullable="false" />
    -        <Property Name="Name" Type="Edm.String" />
    -      </EntityType>
    -      <ComplexType Name="Address">
    -        <Property Name="Street" Type="Edm.String" />
    -        <Property Name="City" Type="Edm.String" />
    -        <Property Name="State" Type="Edm.String" />
    -        <Property Name="ZipCode" Type="Edm.String" />
    -        <Property Name="CountryName" Type="Edm.String" />
    -        <NavigationProperty Name="Country" Type="ODataDemo.Country">
    -          <ReferentialConstraint Property="CountryName"  
    -                                 ReferencedProperty="Name" />
    -        </NavigationProperty>
    -      </ComplexType>
    -      <Function Name="ProductsByRating">
    -        <Parameter Name="Rating" Type="Edm.Int32" />
    -        <ReturnType Type="Collection(ODataDemo.Product)" />
    -      </Function>
    -      <EntityContainer Name="DemoService">
    -        <EntitySet Name="Products" EntityType="ODataDemo.Product">
    -          <NavigationPropertyBinding Path="Category" Target="Categories" />
    -        </EntitySet>
    -        <EntitySet Name="Categories" EntityType="ODataDemo.Category">
    -          <NavigationPropertyBinding Path="Products" Target="Products" />
    -          <Annotation Term="Core.Description" String="Product Categories" />
    -        </EntitySet>
    -        <EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier">
    -          <NavigationPropertyBinding Path="Products" Target="Products" />
    -          <NavigationPropertyBinding Path="Address/Country"
    -                                     Target="Countries" />
    -          <Annotation Term="Core.OptimisticConcurrency">
    -            <Collection>
    -              <PropertyPath>Concurrency</PropertyPath>
    -            </Collection>
    -          </Annotation>
    -        </EntitySet>
    -        <Singleton Name="MainSupplier" Type="ODataDemo.Supplier">
    -          <NavigationPropertyBinding Path="Products" Target="Products" />
    -          <Annotation Term="Core.Description" String="Primary Supplier" />
    -        </Singleton>
    -        <EntitySet Name="Countries" EntityType="ODataDemo.Country" />
    -        <FunctionImport Name="ProductsByRating" EntitySet="Products"
    -                        Function="ODataDemo.ProductsByRating" />
    -      </EntityContainer>
    -    </Schema>
    -  </edmx:DataServices>
    -</edmx:Edmx>
    +
    <edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
    +           xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">
    +  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
    +    <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
    +      <Annotation Term="Core.DefaultNamespace" />
    +    </edmx:Include>
    +  </edmx:Reference>
    +  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.xml">
    +    <edmx:Include Alias="Measures" Namespace="Org.OData.Measures.V1" />
    +  </edmx:Reference>
    +  <edmx:DataServices>
    +    <Schema Namespace="ODataDemo">
    +      <EntityType Name="Product">
    +        <Key>
    +          <PropertyRef Name="ID" />
    +        </Key>
    +        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
    +        <Property Name="Description" Type="Edm.String" >
    +          <Annotation Term="Core.IsLanguageDependent" />
    +        </Property>
    +        <Property Name="ReleaseDate" Type="Edm.Date" />
    +        <Property Name="DiscontinuedDate" Type="Edm.Date" />
    +        <Property Name="Rating" Type="Edm.Int32" />
    +        <Property Name="Price" Type="Edm.Decimal" Scale="variable">
    +          <Annotation Term="Measures.ISOCurrency" Path="Currency" />
    +        </Property>
    +        <Property Name="Currency" Type="Edm.String" MaxLength="3" />
    +        <NavigationProperty Name="Category" Type="ODataDemo.Category"
    +                            Nullable="false" Partner="Products" />
    +        <NavigationProperty Name="Supplier" Type="ODataDemo.Supplier"
    +                            Partner="Products" />
    +      </EntityType>
    +      <EntityType Name="Category">
    +        <Key>
    +         <PropertyRef Name="ID" />
    +        </Key>
    +        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
    +        <Property Name="Name" Type="Edm.String" Nullable="false">
    +          <Annotation Term="Core.IsLanguageDependent" />
    +        </Property>
    +        <NavigationProperty Name="Products" Partner="Category"
    +                            Type="Collection(ODataDemo.Product)">
    +          <OnDelete Action="Cascade" />
    +        </NavigationProperty>
    +      </EntityType>
    +      <EntityType Name="Supplier">
    +        <Key>
    +          <PropertyRef Name="ID" />
    +        </Key>
    +        <Property Name="ID" Type="Edm.String" Nullable="false" />
    +        <Property Name="Name" Type="Edm.String" />
    +        <Property Name="Address" Type="ODataDemo.Address" Nullable="false" />
    +        <Property Name="Concurrency" Type="Edm.Int32" Nullable="false" />
    +        <NavigationProperty Name="Products" Partner="Supplier"
    +                            Type="Collection(ODataDemo.Product)" />
    +      </EntityType>
    +      <EntityType Name="Country">
    +        <Key>
    +          <PropertyRef Name="Code" />
    +        </Key>
    +        <Property Name="Code" Type="Edm.String" MaxLength="2"
    +                              Nullable="false" />
    +        <Property Name="Name" Type="Edm.String" />
    +      </EntityType>
    +      <ComplexType Name="Address">
    +        <Property Name="Street" Type="Edm.String" />
    +        <Property Name="City" Type="Edm.String" />
    +        <Property Name="State" Type="Edm.String" />
    +        <Property Name="ZipCode" Type="Edm.String" />
    +        <Property Name="CountryName" Type="Edm.String" />
    +        <NavigationProperty Name="Country" Type="ODataDemo.Country">
    +          <ReferentialConstraint Property="CountryName"  
    +                                 ReferencedProperty="Name" />
    +        </NavigationProperty>
    +      </ComplexType>
    +      <Function Name="ProductsByRating">
    +        <Parameter Name="Rating" Type="Edm.Int32" />
    +        <ReturnType Type="Collection(ODataDemo.Product)" />
    +      </Function>
    +      <EntityContainer Name="DemoService">
    +        <EntitySet Name="Products" EntityType="ODataDemo.Product">
    +          <NavigationPropertyBinding Path="Category" Target="Categories" />
    +        </EntitySet>
    +        <EntitySet Name="Categories" EntityType="ODataDemo.Category">
    +          <NavigationPropertyBinding Path="Products" Target="Products" />
    +          <Annotation Term="Core.Description" String="Product Categories" />
    +        </EntitySet>
    +        <EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier">
    +          <NavigationPropertyBinding Path="Products" Target="Products" />
    +          <NavigationPropertyBinding Path="Address/Country"
    +                                     Target="Countries" />
    +          <Annotation Term="Core.OptimisticConcurrency">
    +            <Collection>
    +              <PropertyPath>Concurrency</PropertyPath>
    +            </Collection>
    +          </Annotation>
    +        </EntitySet>
    +        <Singleton Name="MainSupplier" Type="ODataDemo.Supplier">
    +          <NavigationPropertyBinding Path="Products" Target="Products" />
    +          <Annotation Term="Core.Description" String="Primary Supplier" />
    +        </Singleton>
    +        <EntitySet Name="Countries" EntityType="ODataDemo.Country" />
    +        <FunctionImport Name="ProductsByRating" EntitySet="Products"
    +                        Function="ODataDemo.ProductsByRating" />
    +      </EntityContainer>
    +    </Schema>
    +  </edmx:DataServices>
    +</edmx:Edmx>

    16.2 Annotations for Products and Categories Example

    Example 91:

    -
    <edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
    -           Version="4.01">
    -  <edmx:Reference Uri="http://host/service/$metadata">
    -    <edmx:Include Namespace="ODataDemo" Alias="target" />
    -  </edmx:Reference>
    -  <edmx:Reference Uri="http://somewhere/Vocabulary/V1">
    -    <edmx:Include Alias="Vocabulary1" Namespace="Some.Vocabulary.V1" />
    -  </edmx:Reference>
    -  <edmx:DataServices>
    -    <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
    -            Namespace="External.Annotations">
    -      <Annotations Target="ODataDemo.Supplier">
    -        <Annotation Term="Vocabulary1.EMail">
    -          <Null />
    -        </Annotation>
    -        <Annotation Term="Vocabulary1.AccountID" Path="ID" />
    -        <Annotation Term="Vocabulary1.Title" String="Supplier Info" />
    -        <Annotation Term="Vocabulary1.DisplayName">
    -        <Apply Function="odata.concat">
    -            <Path>Name</Path>
    -            <String> in </String>
    -            <Path>Address/CountryName</Path>
    -          </Apply>
    -        </Annotation>
    -      </Annotations>
    -      <Annotations Target="ODataDemo.Product">
    -        <Annotation Term="Vocabulary1.Tags">
    -          <Collection>
    -            <String>MasterData</String>
    -          </Collection>
    -        </Annotation>
    -      </Annotations>
    -  </Schema>
    -  </edmx:DataServices>
    -</edmx:Edmx>
    +
    <edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
    +           Version="4.01">
    +  <edmx:Reference Uri="http://host/service/$metadata">
    +    <edmx:Include Namespace="ODataDemo" Alias="target" />
    +  </edmx:Reference>
    +  <edmx:Reference Uri="http://somewhere/Vocabulary/V1">
    +    <edmx:Include Alias="Vocabulary1" Namespace="Some.Vocabulary.V1" />
    +  </edmx:Reference>
    +  <edmx:DataServices>
    +    <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
    +            Namespace="External.Annotations">
    +      <Annotations Target="ODataDemo.Supplier">
    +        <Annotation Term="Vocabulary1.EMail">
    +          <Null />
    +        </Annotation>
    +        <Annotation Term="Vocabulary1.AccountID" Path="ID" />
    +        <Annotation Term="Vocabulary1.Title" String="Supplier Info" />
    +        <Annotation Term="Vocabulary1.DisplayName">
    +        <Apply Function="odata.concat">
    +            <Path>Name</Path>
    +            <String> in </String>
    +            <Path>Address/CountryName</Path>
    +          </Apply>
    +        </Annotation>
    +      </Annotations>
    +      <Annotations Target="ODataDemo.Product">
    +        <Annotation Term="Vocabulary1.Tags">
    +          <Collection>
    +            <String>MasterData</String>
    +          </Collection>
    +        </Annotation>
    +      </Annotations>
    +  </Schema>
    +  </edmx:DataServices>
    +</edmx:Edmx>

    17 Conformance

    diff --git a/docs/odata-csdl-xml/odata-csdl-xml.md b/docs/odata-csdl-xml/odata-csdl-xml.md index d3587a01e..dd2ecb0b0 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.md +++ b/docs/odata-csdl-xml/odata-csdl-xml.md @@ -867,7 +867,7 @@ Example 7: - ... + … ``` @@ -931,16 +931,16 @@ Example 8: references to other CSDL documents Version="4.0"> - ... + … - ... + … - ... + … - ... + ``` ::: @@ -1024,7 +1024,7 @@ vocabulary terms - ... + ``` ::: @@ -1111,7 +1111,7 @@ Example 10: reference documents that contain annotations Qualifier="Tablet" TargetNamespace="com.example.Person" /> - ... + ``` ::: @@ -1216,7 +1216,7 @@ schema ```xml - ... + … ``` ::: @@ -1249,7 +1249,7 @@ Example 12: annotations should only be applied to tablet devices ```xml - ... + … ``` ::: @@ -1787,14 +1787,14 @@ Example 22: the Product entity type has a navigation property to a Category, which has a navigation link back to one or more products ```xml - ... + … - ... + … @@ -2033,7 +2033,7 @@ category, and the `CategoryKind` property of the product is identical to the `Kind` property of the category. ```xml - ... + … @@ -2051,7 +2051,7 @@ the `Kind` property of the category. - ... + … ``` ::: @@ -2100,7 +2100,7 @@ Example 24: deletion of a category implies deletion of the related products in that category ```xml - ... + … - ... + … - ... + … ``` @@ -2948,7 +2948,7 @@ elements that it defines itself, plus all child elements of the `Base` entity container located in `SomeOtherSchema` ```xml - ... + … ``` ::: @@ -3329,7 +3329,7 @@ type specified by the term `SearchResult` - ... + … @@ -4109,7 +4109,7 @@ the null value. ::: example Example 60: type-cast segment ``` -.../self.Manager/... +…/self.Manager/… ``` ::: @@ -4134,7 +4134,7 @@ properties: ::: example Example 61: term-cast segments ``` -.../@Capabilities.SortRestrictions/... +…/@Capabilities.SortRestrictions/… ``` ::: @@ -4154,7 +4154,7 @@ expression is the model element reached via this path. ::: example Example 62: property segments in model path ``` -.../Orders/Items/Product/... +…/Orders/Items/Product/… ``` ::: @@ -4174,11 +4174,11 @@ number of items in the collection identified by the preceding segment. ::: example Example 63: property segments in instance path ``` -.../Addresses/Street +…/Addresses/Street ``` ``` -.../Addresses/$count +…/Addresses/$count ``` ::: @@ -4198,11 +4198,11 @@ segment](#TermCast). Example 64: model path segment addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property ``` -.../Items@Core.Description +…/Items@Core.Description ``` ``` -.../Items/@Core.Description +…/Items/@Core.Description ``` ::: @@ -4325,7 +4325,7 @@ enclosing type `self.A` of the hosting property `A2`. - + @@ -4345,7 +4345,7 @@ type `self.B` of the hosting property `A2`. - + @@ -4361,7 +4361,7 @@ type `self.A` named in the target path. :::: varxml ```xml - + @@ -5357,9 +5357,21 @@ segments Example 89: Target expressions ``` MySchema.MyEntityContainer/MyEntitySet +``` + +``` MySchema.MyEntityContainer/MySingleton +``` + +``` MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty +``` + +``` MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty +``` + +``` MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp ``` ::: diff --git a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.html b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.html index 308d7e60b..d9b2b34ef 100644 --- a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.html +++ b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.html @@ -1928,22 +1928,22 @@

    { "Customer": { "Country": "USA", "Name": "Joe" }, "Product": { "Category": { "Name": "Non-Food" }, "Name": "Paper" }, "Total@type": "Decimal", "Total": 1 }, - ...

    +

    plus additional fifteen rollup entities for subtotals: five without customer name

        { "Customer": { "Country": "USA" },
           "Product":  { "Category": { "Name": "Food" }, "Name": "Sugar" },
           "Total@type": "Decimal", "Total":  2 },
    -    ...
    +

    six without product name

        { "Customer": { "Country": "USA", "Name": "Joe" },
           "Product":  { "Category": { "Name": "Food" } },
           "Total@type": "Decimal", "Total":  6 },
    -    ...
    +

    and four with neither customer nor product name

        { "Customer": { "Country": "USA" },
           "Product":  { "Category": { "Name": "Food" } },
           "Total@type": "Decimal", "Total": 14 },
    -    ...
    +    
       ]
     }
    @@ -2396,7 +2396,7 @@

    "value": [ { "Products": { "Name": "Paper" }, "Sales": { "Amount": 1 } }, { "Products": { "Name": "Sugar" }, "Sales": { "Amount": 2 } }, - ... + ] } @@ -2443,14 +2443,14 @@

    <EntityContainer Name="SalesData">
       <Annotation Term="Aggregation.ApplySupportedDefaults" />
    -  ...
    +
     </EntityContainer>

    Example 50: Define aggregation support only for the products of a given category

    <Annotations Target="SalesModel.SalesData/Categories/Products">
       <Annotation Term="Aggregation.ApplySupported">
    -    ...
    +
       </Annotation>
     </Annotations>
    @@ -2657,9 +2657,9 @@

    { "ID": "Sales Netherlands", "Name": "Sales Netherlands" }, { "ID": "Sales Germany", "Name": "Sales Germany" }, { "ID": "EMEA South", "Name": "EMEA South" }, - ... + { "ID": "EMEA North", "Name": "EMEA North" }, - ... + ] } @@ -2678,7 +2678,7 @@

    { "ID": "EMEA Central", "Name": "EMEA Central" }, { "ID": "EMEA South", "Name": "EMEA South" }, { "ID": "EMEA North", "Name": "EMEA North" }, - ... + ] } @@ -2694,7 +2694,7 @@

    "value": [ { "ID": "Sales Office London", "Name": "Sales Office London" }, { "ID": "Sales Office New York", "Name": "Sales Office New York" }, - ... + ] } @@ -2713,7 +2713,7 @@

    "Superordinate": { "ID": "EMEA United Kingdom" } }, { "ID": "Sales Office New York", "Name": "Sales Office New York", "Superordinate": { "ID": "US East" } }, - ... + ] } @@ -2910,21 +2910,21 @@

    {
       "@context": "$metadata#SalesOrganizations",
       "value": [
    -    ...
    +    
         { "ID": "Atlantis", "Name": "Atlantis",
           "@Aggregation.UpPath#MultiParentHierarchy":
             [ "US", "Sales" ] },
         { "ID": "AtlantisChild", "Name": "Child of Atlantis",
           "@Aggregation.UpPath#MultiParentHierarchy":
              [ "Atlantis", "US", "Sales" ] },
    -    ...
    +    
         { "ID": "Atlantis", "Name": "Atlantis",
           "@Aggregation.UpPath#MultiParentHierarchy":
             [ "EMEA", "Sales" ] },
         { "ID": "AtlantisChild", "Name": "Child of Atlantis",
           "@Aggregation.UpPath#MultiParentHierarchy":
             [ "Atlantis", "EMEA", "Sales" ] },
    -    ...
    +    
       ]
     }
    @@ -3073,7 +3073,7 @@

    "TotalAmount": null }, { "SalesOrganization": { "ID": "US", "Name": "US" }, "TotalAmount": null }, - ... + ] } @@ -3463,7 +3463,7 @@

    { "@context": "#SalesOrganizations/$entity", "ID": "US", "SalesRegion": "Corporate Sales" } }, ] - }, ... + }, ] } @@ -3713,16 +3713,16 @@

    {
       "@context": "$metadata#Sales(Customer(Country),Total)",
       "value": [
    -    { "Customer":{ "Country": "USA" },         "Product":{ "Name": "Coffee" },
    +    { "Customer": { "Country": "USA" },         "Product": { "Name": "Coffee" },
           "Total@type": "Decimal", "Total": 12
         },
    -    { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Paper" },
    +    { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Paper" },
           "Total@type": "Decimal", "Total":  3
         },
    -    { "Customer":{ "Country": "USA" },
    +    { "Customer": { "Country": "USA" },
           "Total@type": "Decimal", "Total": 19
         },
    -    { "Customer":{ "Country": "Netherlands" },
    +    { "Customer": { "Country": "Netherlands" },
           "Total@type": "Decimal", "Total":  5
         }
       ]
    @@ -3736,19 +3736,19 @@ 

    {
       "@context": "$metadata#Sales(Customer(Country),Product(Name),Total)",
       "value": [
    -    { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Paper" },
    +    { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Paper" },
           "Total@type": "Decimal", "Total":  3
         },
    -    { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Sugar" },
    +    { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Sugar" },
           "Total@type": "Decimal", "Total":  2
         },
    -    { "Customer":{ "Country": "USA" },         "Product":{ "Name": "Sugar" },
    +    { "Customer": { "Country": "USA" },         "Product": { "Name": "Sugar" },
           "Total@type": "Decimal", "Total":  2
         },
    -    { "Customer":{ "Country": "USA" },         "Product":{ "Name": "Coffee" },
    +    { "Customer": { "Country": "USA" },         "Product": { "Name": "Coffee" },
           "Total@type": "Decimal", "Total": 12
         },
    -    { "Customer":{ "Country": "USA" },         "Product":{ "Name": "Paper" },
    +    { "Customer": { "Country": "USA" },         "Product": { "Name": "Paper" },
           "Total@type": "Decimal", "Total":  5
         }
       ]
    @@ -4312,14 +4312,14 @@ 

    { "SalesOrganization": { "ID": "Atlantis", "Name": "Atlantis", "@Aggregation.UpPath#MultiParentHierarchy": [ "US", "Sales" ] }, "MultiParentWeightedTotal": 6 }, - ... + { "SalesOrganization": { "ID": "EMEA", "Name": "EMEA", "@Aggregation.UpPath#MultiParentHierarchy": [ "Sales" ] }, "MultiParentWeightedTotal": 9 }, { "SalesOrganization": { "ID": "Atlantis", "Name": "Atlantis", "@Aggregation.UpPath#MultiParentHierarchy": [ "EMEA", "Sales" ] }, "MultiParentWeightedTotal": 4 }, - ... + ] }

    @@ -4376,7 +4376,7 @@

    "TotalPopulation@type": "Int32", "TotalPopulation": 1412000000 }, { "Continent": { "Name": "Asia" }, "Country": { "Name": "India" }, "TotalPopulation@type": "Int32", "TotalPopulation": 1408000000 }, - ... + ] }

    diff --git a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md index fc49e8686..b56cf4e2b 100644 --- a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md +++ b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md @@ -885,7 +885,7 @@ Date|Month|Quarter|Year 2022-01-01|2022-01|2022-1|2022 2022-04-01|2022-04|2022-2|2022 2022-04-10|2022-04|2022-2|2022 -...||| +…||| ::::: ::::: {style=top:150px;left:360px} @@ -1580,28 +1580,28 @@ results in seven entities for the finest grouping level { "Customer": { "Country": "USA", "Name": "Joe" }, "Product": { "Category": { "Name": "Non-Food" }, "Name": "Paper" }, "Total@type": "Decimal", "Total": 1 }, - ... + … ``` plus additional fifteen rollup entities for subtotals: five without customer name ```json { "Customer": { "Country": "USA" }, "Product": { "Category": { "Name": "Food" }, "Name": "Sugar" }, "Total@type": "Decimal", "Total": 2 }, - ... + … ``` six without product name ```json { "Customer": { "Country": "USA", "Name": "Joe" }, "Product": { "Category": { "Name": "Food" } }, "Total@type": "Decimal", "Total": 6 }, - ... + … ``` and four with neither customer nor product name ```json { "Customer": { "Country": "USA" }, "Product": { "Category": { "Name": "Food" } }, "Total@type": "Decimal", "Total": 14 }, - ... + … ] } ``` @@ -2235,7 +2235,7 @@ results in "value": [ { "Products": { "Name": "Paper" }, "Sales": { "Amount": 1 } }, { "Products": { "Name": "Sugar" }, "Sales": { "Amount": 2 } }, - ... + … ] } ``` @@ -2295,7 +2295,7 @@ Example 49: an entity container with default support for everything defined in t ```xml - ... + … ``` ::: @@ -2305,7 +2305,7 @@ Example 50: Define aggrega ```xml - ... + … ``` @@ -2555,9 +2555,9 @@ results in { "ID": "Sales Netherlands", "Name": "Sales Netherlands" }, { "ID": "Sales Germany", "Name": "Sales Germany" }, { "ID": "EMEA South", "Name": "EMEA South" }, - ... + … { "ID": "EMEA North", "Name": "EMEA North" }, - ... + … ] } ``` @@ -2581,7 +2581,7 @@ results in { "ID": "EMEA Central", "Name": "EMEA Central" }, { "ID": "EMEA South", "Name": "EMEA South" }, { "ID": "EMEA North", "Name": "EMEA North" }, - ... + … ] } ``` @@ -2602,7 +2602,7 @@ results in "value": [ { "ID": "Sales Office London", "Name": "Sales Office London" }, { "ID": "Sales Office New York", "Name": "Sales Office New York" }, - ... + … ] } ``` @@ -2626,7 +2626,7 @@ results in "Superordinate": { "ID": "EMEA United Kingdom" } }, { "ID": "Sales Office New York", "Name": "Sales Office New York", "Superordinate": { "ID": "US East" } }, - ... + … ] } ``` @@ -2918,21 +2918,21 @@ results in { "@context": "$metadata#SalesOrganizations", "value": [ - ... + … { "ID": "Atlantis", "Name": "Atlantis", "@Aggregation.UpPath#MultiParentHierarchy": [ "US", "Sales" ] }, { "ID": "AtlantisChild", "Name": "Child of Atlantis", "@Aggregation.UpPath#MultiParentHierarchy": [ "Atlantis", "US", "Sales" ] }, - ... + … { "ID": "Atlantis", "Name": "Atlantis", "@Aggregation.UpPath#MultiParentHierarchy": [ "EMEA", "Sales" ] }, { "ID": "AtlantisChild", "Name": "Child of Atlantis", "@Aggregation.UpPath#MultiParentHierarchy": [ "Atlantis", "EMEA", "Sales" ] }, - ... + … ] } ``` @@ -3142,7 +3142,7 @@ results in "TotalAmount": null }, { "SalesOrganization": { "ID": "US", "Name": "US" }, "TotalAmount": null }, - ... + … ] } ``` @@ -3662,7 +3662,7 @@ results in { "@context": "#SalesOrganizations/$entity", "ID": "US", "SalesRegion": "Corporate Sales" } }, ] - }, ... + }, … ] } ``` @@ -3986,16 +3986,16 @@ results in { "@context": "$metadata#Sales(Customer(Country),Total)", "value": [ - { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Coffee" }, + { "Customer": { "Country": "USA" }, "Product": { "Name": "Coffee" }, "Total@type": "Decimal", "Total": 12 }, - { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Paper" }, + { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Paper" }, "Total@type": "Decimal", "Total": 3 }, - { "Customer":{ "Country": "USA" }, + { "Customer": { "Country": "USA" }, "Total@type": "Decimal", "Total": 19 }, - { "Customer":{ "Country": "Netherlands" }, + { "Customer": { "Country": "Netherlands" }, "Total@type": "Decimal", "Total": 5 } ] @@ -4014,19 +4014,19 @@ results in { "@context": "$metadata#Sales(Customer(Country),Product(Name),Total)", "value": [ - { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Paper" }, + { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Paper" }, "Total@type": "Decimal", "Total": 3 }, - { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Sugar" }, + { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Sugar" }, "Total@type": "Decimal", "Total": 2 }, - { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Sugar" }, + { "Customer": { "Country": "USA" }, "Product": { "Name": "Sugar" }, "Total@type": "Decimal", "Total": 2 }, - { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Coffee" }, + { "Customer": { "Country": "USA" }, "Product": { "Name": "Coffee" }, "Total@type": "Decimal", "Total": 12 }, - { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Paper" }, + { "Customer": { "Country": "USA" }, "Product": { "Name": "Paper" }, "Total@type": "Decimal", "Total": 5 } ] @@ -4662,14 +4662,14 @@ Note that `rolluprecursive` must preserve the preorder established by `traverse` { "SalesOrganization": { "ID": "Atlantis", "Name": "Atlantis", "@Aggregation.UpPath#MultiParentHierarchy": [ "US", "Sales" ] }, "MultiParentWeightedTotal": 6 }, - ... + … { "SalesOrganization": { "ID": "EMEA", "Name": "EMEA", "@Aggregation.UpPath#MultiParentHierarchy": [ "Sales" ] }, "MultiParentWeightedTotal": 9 }, { "SalesOrganization": { "ID": "Atlantis", "Name": "Atlantis", "@Aggregation.UpPath#MultiParentHierarchy": [ "EMEA", "Sales" ] }, "MultiParentWeightedTotal": 4 }, - ... + … ] } ``` @@ -4749,7 +4749,7 @@ results in "TotalPopulation@type": "Int32", "TotalPopulation": 1412000000 }, { "Continent": { "Name": "Asia" }, "Country": { "Name": "India" }, "TotalPopulation@type": "Int32", "TotalPopulation": 1408000000 }, - ... + … ] } ``` diff --git a/docs/odata-json-format/odata-json-format.html b/docs/odata-json-format/odata-json-format.html index 7fb143ed8..c529d6b46 100644 --- a/docs/odata-json-format/odata-json-format.html +++ b/docs/odata-json-format/odata-json-format.html @@ -447,11 +447,11 @@

    4.3 Relati

    Example 2:

    {
       "@context": "http://host/service/$metadata#Customers/$entity",
    -  ...
    +  
       "@editLink": "Customers('ALFKI')",
    -  ...
    +  
       "Orders@navigationLink": "Customers('ALFKI')/Orders",
    -  ...
    +  
     }

    The resulting absolute URLs are http://host/service/Customers('ALFKI') and http://host/service/Customers('ALFKI')/Orders.

    @@ -494,7 +494,7 @@

    {
       "@context": "http://host/service/$metadata#Customers/$entity",
       "@metadataEtag": "W/\"A1FF3E230954908F\"",
    -  ...
    +  
     }

    4.5.2 Control Information: metadataEtag (odata.metadataEtag)

    @@ -527,7 +527,7 @@

    "ID": 2, "DynamicValue@type": "Date", "DynamicValue": "2016-09-22", - ... + }
    @@ -536,7 +536,7 @@

    "@context": "http://host/service/$metadata#Customers/$entity", "@type": "http://host/alternate/$metadata#Model.VipCustomer", "ID": 2, - ... + }

    4.5.4 Control Information: count (odata.count)

    @@ -607,7 +607,7 @@

    "@mediaReadLink": "Employees(1)/$value", "@mediaContentType": "image/jpeg", "ID": 1, - ... + }

    4.5.13 Control Information: removed (odata.removed)

    @@ -634,7 +634,7 @@

    "JulieSwa@live.com", "Julie.Swansworth@work.com" ], - ... + }
    @@ -774,7 +774,7 @@

    7.2 Comple

    Example 13:

    {
       "@context": "http://host/service/$metadata#Customers/$entity",
    -  ...
    +  
       "Address": {
         "Street": "Obere Str. 57",
         "City": "Berlin",
    @@ -790,12 +790,12 @@ 

    Example 14: partial collection of strings with next link

    {
       "@context": "http://host/service/$metadata#Customers/$entity",
    -  ...
    +  
       "EmailAddresses": [
         "Julie@Swansworth.com",
         "Julie.Swansworth@work.com"
       ],
    -  "EmailAddresses@nextLink": "..."
    +  "EmailAddresses@nextLink": "…"
     }

    A collection of primitive values that occurs in a property of type Edm.Untyped is interpreted as a collection of Edm.Boolean, Edm.String, and Edm.Decimal values, depending on the JavaScript type.

    @@ -816,7 +816,7 @@

    "Carrier": "Sprint" } ], - "PhoneNumbers@nextLink": "..." + "PhoneNumbers@nextLink": "…" }

    7.5 Untyped Value

    @@ -835,9 +835,9 @@

    @@ -847,9 +847,9 @@

    8.3 Expanded Navigation Property

    @@ -861,9 +861,9 @@

    {
       "@context": "http://host/service/$metadata#Customers/$entity",
       "Orders@count": 42,
    -  "Orders": [ ... ],
    -  "Orders@nextLink": "...",
    -  ...
    +  "Orders": [  ],
    +  "Orders@nextLink": "…",
    +  
     }

    8.4 Deep Insert

    @@ -874,21 +874,21 @@

    8.4 Deep Insert<
    {
       "ID": 11643,
       "Amount": 100,
    -  ...,
    +  ,
       "Customer": {
         "ID": "ANEWONE",
    -    ...
    +    
       },
       "Items": [
         {
           "Product": { "@id": "Products(28)" },
           "Quantity": 1,
    -      ...
    +      
         },
         {
           "Product": { "@id": "Products(39)" },
           "Quantity": 5,
    -      ...
    +      
         }
       ]
     }
    @@ -958,7 +958,7 @@

    8.6 "@etag": "W/\"MjAxMy0wNS0yN1QxMTo1OFo=\"", "ID": 1234, "Items@etag": "W/\"MjAxOS0wMy0xMlQxMDoyMlo=\"" - ... + }

    Note: the collection ETag for a navigation property may or may not be identical to the ETag of the containing entity, the example shows a different ETag for the Items collection.

    @@ -978,13 +978,13 @@

    9 Str

    Example 24:

    {
       "@context": "http://host/service/$metadata#Products/$entity",
    -  ...
    +  
       "Thumbnail@mediaReadLink": "http://server/Thumbnail546.jpg",
       "Thumbnail@mediaEditLink": "http://server/uploads/Thumbnail546.jpg",
       "Thumbnail@mediaContentType": "image/jpeg",
       "Thumbnail@mediaEtag": "W/\"####\"",
    -  "Thumbnail": "...base64url encoded value...",
    -  ...
    +  "Thumbnail": "…base64url encoded value…",
    +  
     }

    @@ -996,9 +996,9 @@

    10 Media Enti "@context": "http://host/service/$metadata#Employees/$entity", "@mediaReadLink": "Employees(1)/$value", "@mediaContentType": "image/jpeg", - "$value": "...base64url encoded value...", + "$value": "…base64url encoded value…", "ID": 1, - ... + }
    @@ -1043,7 +1043,7 @@

    Example 30: empty collection of complex values

    {
    -  "@context":"http://host/service/$metadata#Collection(Model.Address)",
    +  "@context": "http://host/service/$metadata#Collection(Model.Address)",
       "value": []
     }
    @@ -1065,14 +1065,14 @@

    Example 28:

    {
    -  "@context": "...",
    +  "@context": "…",
       "@count": 37,
       "value": [
    -    { ... },
    -    { ... },
    -    { ... }
    +    {  },
    +    {  },
    +    {  }
       ],
    -  "@nextLink": "...?$skiptoken=342r89"
    +  "@nextLink": "…?$skiptoken=342r89"
     }

    @@ -1140,7 +1140,7 @@

    15. { "@context": "#Orders/$entity", "@id": "Orders(10643)", - "ShippingAddress":{ + "ShippingAddress": { "Street": "23 Tsawassen Blvd.", "City": "Tsawassen", "Region": "BC", @@ -1246,9 +1246,9 @@

    15.3 D

    Example 36: deleted entity in OData 4.0 response — note that id is a property, not control information

    {
    -  "@context":"#Customers/$deletedEntity",
    -  "reason":"deleted",
    -  "id":"Customers('ANTON')"
    +  "@context": "#Customers/$deletedEntity",
    +  "reason": "deleted",
    +  "id": "Customers('ANTON')"
     }

    In OData 4.01 payloads the deleted-entity object MUST include the following properties, regardless of the specified metadata value:

    @@ -1261,19 +1261,19 @@

    15.3 D

    Example 37: deleted entity in OData 4.01 response with id control information (prefixed with an @)

    {
    -  "@context":"#Customers/$deletedEntity",
    -  "@removed":{
    -    "reason":"deleted",
    -    "@myannoation.deletedBy":"Mario"
    +  "@context": "#Customers/$deletedEntity",
    +  "@removed": {
    +    "reason": "deleted",
    +    "@myannoation.deletedBy": "Mario"
       },
    -  "@id":"Customers('ANTON')"
    +  "@id": "Customers('ANTON')"
     }

    Example 38: entity removed OData 4.01 response without id control information and instead all key fields (ID is the single key field of Customer)

    {
    -  "@removed":{},
    -  "ID":"ANTON"
    +  "@removed": {},
    +  "ID": "ANTON"
     }

    @@ -1342,7 +1342,7 @@

    { "@Org.OData.Core.V1.ContentID": "3", "@removed": {}, - "CustomerID":"ANTON" + "CustomerID": "ANTON" }, { "@Org.OData.Core.V1.ContentID": "4", @@ -1379,7 +1379,7 @@

    "@context": "#Customers/$link", "@Org.OData.Core.V1.ContentID": "5", "source": "Customers('ANATR')", - "relationship":" Orders", + "relationship": "Orders", "target": "Orders(10643)" }, { @@ -1450,8 +1450,8 @@

    }, { "@Org.OData.Core.V1.ContentID": "3", - "CustomerID":"ANTON" - "@Org.OData.Core.V1.DataModificationException": { + "CustomerID": "ANTON", + "@Org.OData.Core.V1.DataModificationException": { "failedOperation": "delete", "responseCode": 400, "info": { @@ -1484,7 +1484,7 @@

    "@context": "#Customers/$deletedLink", "@Org.OData.Core.V1.ContentID": "5", "source": "Customers('ANATR')", - "relationship":" Orders", + "relationship": "Orders", "target": "Orders(10643)", "@Org.OData.Core.V1.DataModificationException": { "failedOperation": "link", @@ -1534,7 +1534,7 @@

    16 Boun
    {
       "@context": "http://host/service/$metadata#Employees/$entity",
       "#Model.RemainingVacation": {},
    -  ...
    +  
     }
    @@ -1545,7 +1545,7 @@

    16 Boun "title": "Remaining vacation from year.", "target": "Employees(2)/RemainingVacation(Year=@Year)" }, - ... + }

    @@ -1556,7 +1556,7 @@

    16 Boun "title": "Remaining Vacation", "target": "Managers(22)/Employees/RemainingVacation" }, - "value": [ ... ] + "value": [ ] }

    @@ -1565,7 +1565,7 @@

    16 Boun "@context": "http://host/service/$metadata#Employees/$entity", "@type": "Model.Manager", "ID":22, - ... + "Employees#RemainingVacation": { "title": "RemainingVacation", "target": "Managers(22)/Employees/RemainingVacation" @@ -1587,7 +1587,7 @@

    17 Bound Acti
    {
       "@context": "http://host/service/$metadata#LeaveRequests/$entity",
       "#Model.Approve": {},
    -  ...
    +  
     }

    @@ -1598,7 +1598,7 @@

    17 Bound Acti "title": "Approve Leave Request", "target": "LeaveRequests(2)/Approve" }, - ... + }

    @@ -1609,7 +1609,7 @@

    17 Bound Acti "title": "Approve All Leave Requests", "target": "Employees(22)/Model.Manager/LeaveRequests/Approve" }, - "value": [ ... ] + "value": [ ] }

    @@ -1618,7 +1618,7 @@

    17 Bound Acti "@context": "http://host/service/$metadata#Employees/$entity", "@type": "Model.Manager", "ID": 22, - ... + "LeaveRequests#Model.Approve": { "title": "Approve All Leave Requests", "target": "Employees(22)/Model.Manager/LeaveRequests/Approve" @@ -1867,7 +1867,7 @@

    "body": <JSON representation of the Customer entity with key ALFKI> } ], - "@nextLink": "...?$skiptoken=YmF0Y2gx" + "@nextLink": "…?$skiptoken=YmF0Y2gx" }

    Client makes a GET request to the next link and receives a 202 response with the location of a new monitor resource.

    HTTP/1.1 202 Accepted
    @@ -1988,8 +1988,8 @@ 

    21.1 E } ], "innererror": { - "trace": [...], - "context": {...} + "trace": [], + "context": {} } } }

    diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md index 7ee29c591..66f21aa86 100644 --- a/docs/odata-json-format/odata-json-format.md +++ b/docs/odata-json-format/odata-json-format.md @@ -636,11 +636,11 @@ Example 2: ```json { "@context": "http://host/service/$metadata#Customers/$entity", - ... + … "@editLink": "Customers('ALFKI')", - ... + … "Orders@navigationLink": "Customers('ALFKI')/Orders", - ... + … } ``` ::: @@ -765,7 +765,7 @@ Example 4: { "@context": "http://host/service/$metadata#Customers/$entity", "@metadataEtag": "W/\"A1FF3E230954908F\"", - ... + … } ``` ::: @@ -873,7 +873,7 @@ metadata document of the same service with a dynamic property of type "ID": 2, "DynamicValue@type": "Date", "DynamicValue": "2016-09-22", - ... + … } ``` ::: @@ -886,7 +886,7 @@ metadata document of a different service "@context": "http://host/service/$metadata#Customers/$entity", "@type": "http://host/alternate/$metadata#Model.VipCustomer", "ID": 2, - ... + … } ``` ::: @@ -1124,7 +1124,7 @@ Example 7: "@mediaReadLink": "Employees(1)/$value", "@mediaContentType": "image/jpeg", "ID": 1, - ... + … } ``` ::: @@ -1167,7 +1167,7 @@ Example 8: Annotating primitive values within a collection "JulieSwa@live.com", "Julie.Swansworth@work.com" ], - ... + … } ``` ::: @@ -1434,7 +1434,7 @@ Example 13: ```json { "@context": "http://host/service/$metadata#Customers/$entity", - ... + … "Address": { "Street": "Obere Str. 57", "City": "Berlin", @@ -1462,12 +1462,12 @@ Example 14: partial collection of strings with next link ```json { "@context": "http://host/service/$metadata#Customers/$entity", - ... + … "EmailAddresses": [ "Julie@Swansworth.com", "Julie.Swansworth@work.com" ], - "EmailAddresses@nextLink": "..." + "EmailAddresses@nextLink": "…" } ``` ::: @@ -1498,7 +1498,7 @@ Example 15: partial collection of complex values with next link "Carrier": "Sprint" } ], - "PhoneNumbers@nextLink": "..." + "PhoneNumbers@nextLink": "…" } ``` ::: @@ -1555,9 +1555,9 @@ Example 16: ```json { "@context": "http://host/service/$metadata#Customers/$entity", - ... + … "Orders@navigationLink": "Customers('ALFKI')/Orders", - ... + … } ``` ::: @@ -1582,9 +1582,9 @@ Example 17: ```json { "@context": "http://host/service/$metadata#Customers/$entity", - ... + … "Orders@associationLink": "Customers('ALFKI')/Orders/$ref", - ... + … } ``` ::: @@ -1617,9 +1617,9 @@ Example 18: { "@context": "http://host/service/$metadata#Customers/$entity", "Orders@count": 42, - "Orders": [ ... ], - "Orders@nextLink": "...", - ... + "Orders": [ … ], + "Orders@nextLink": "…", + … } ``` ::: @@ -1640,21 +1640,21 @@ related to existing products: { "ID": 11643, "Amount": 100, - ..., + …, "Customer": { "ID": "ANEWONE", - ... + … }, "Items": [ { "Product": { "@id": "Products(28)" }, "Quantity": 1, - ... + … }, { "Product": { "@id": "Products(39)" }, "Quantity": 5, - ... + … } ] } @@ -1773,7 +1773,7 @@ Example 23: ETag for a collection of related entities "@etag": "W/\"MjAxMy0wNS0yN1QxMTo1OFo=\"", "ID": 1234, "Items@etag": "W/\"MjAxOS0wMy0xMlQxMDoyMlo=\"" - ... + … } ``` ::: @@ -1822,13 +1822,13 @@ Example 24: ```json { "@context": "http://host/service/$metadata#Products/$entity", - ... + … "Thumbnail@mediaReadLink": "http://server/Thumbnail546.jpg", "Thumbnail@mediaEditLink": "http://server/uploads/Thumbnail546.jpg", "Thumbnail@mediaContentType": "image/jpeg", "Thumbnail@mediaEtag": "W/\"####\"", - "Thumbnail": "...base64url encoded value...", - ... + "Thumbnail": "…base64url encoded value…", + … } ``` ::: @@ -1852,9 +1852,9 @@ Example 25: "@context": "http://host/service/$metadata#Employees/$entity", "@mediaReadLink": "Employees(1)/$value", "@mediaContentType": "image/jpeg", - "$value": "...base64url encoded value...", + "$value": "…base64url encoded value…", "ID": 1, - ... + … } ``` ::: @@ -1932,7 +1932,7 @@ Example 29: complex value Example 30: empty collection of complex values ```json { - "@context":"http://host/service/$metadata#Collection(Model.Address)", + "@context": "http://host/service/$metadata#Collection(Model.Address)", "value": [] } ``` @@ -2012,14 +2012,14 @@ partial result. Example 28: ```json { - "@context": "...", + "@context": "…", "@count": 37, "value": [ - { ... }, - { ... }, - { ... } + { … }, + { … }, + { … } ], - "@nextLink": "...?$skiptoken=342r89" + "@nextLink": "…?$skiptoken=342r89" } ``` ::: @@ -2149,7 +2149,7 @@ occurrence { "@context": "#Orders/$entity", "@id": "Orders(10643)", - "ShippingAddress":{ + "ShippingAddress": { "Street": "23 Tsawassen Blvd.", "City": "Tsawassen", "Region": "BC", @@ -2346,9 +2346,9 @@ Example 36: deleted entity in OData 4.0 response --- note that `id` is a property, not control information ```json { - "@context":"#Customers/$deletedEntity", - "reason":"deleted", - "id":"Customers('ANTON')" + "@context": "#Customers/$deletedEntity", + "reason": "deleted", + "id": "Customers('ANTON')" } ``` ::: @@ -2403,12 +2403,12 @@ Example 37: deleted entity in OData 4.01 response with `id` control information (prefixed with an `@`) ```json { - "@context":"#Customers/$deletedEntity", - "@removed":{ - "reason":"deleted", - "@myannoation.deletedBy":"Mario" + "@context": "#Customers/$deletedEntity", + "@removed": { + "reason": "deleted", + "@myannoation.deletedBy": "Mario" }, - "@id":"Customers('ANTON')" + "@id": "Customers('ANTON')" } ``` ::: @@ -2419,8 +2419,8 @@ control information and instead all key fields (`ID` is the single key field of `Customer`) ```json { - "@removed":{}, - "ID":"ANTON" + "@removed": {}, + "ID": "ANTON" } ``` ::: @@ -2526,7 +2526,7 @@ Prefer: return=minimal, continue-on-error { "@Org.OData.Core.V1.ContentID": "3", "@removed": {}, - "CustomerID":"ANTON" + "CustomerID": "ANTON" }, { "@Org.OData.Core.V1.ContentID": "4", @@ -2563,7 +2563,7 @@ Prefer: return=minimal, continue-on-error "@context": "#Customers/$link", "@Org.OData.Core.V1.ContentID": "5", "source": "Customers('ANATR')", - "relationship":" Orders", + "relationship": "Orders", "target": "Orders(10643)" }, { @@ -2636,7 +2636,7 @@ Preference-Applied: return=minimal, continue-on-error }, { "@Org.OData.Core.V1.ContentID": "3", - "CustomerID":"ANTON" + "CustomerID": "ANTON", "@Org.OData.Core.V1.DataModificationException": { "failedOperation": "delete", "responseCode": 400, @@ -2670,7 +2670,7 @@ Preference-Applied: return=minimal, continue-on-error "@context": "#Customers/$deletedLink", "@Org.OData.Core.V1.ContentID": "5", "source": "Customers('ANATR')", - "relationship":" Orders", + "relationship": "Orders", "target": "Orders(10643)", "@Org.OData.Core.V1.DataModificationException": { "failedOperation": "link", @@ -2779,7 +2779,7 @@ applicable { "@context": "http://host/service/$metadata#Employees/$entity", "#Model.RemainingVacation": {}, - ... + … } ``` ::: @@ -2794,7 +2794,7 @@ alias for the `Year` parameter "title": "Remaining vacation from year.", "target": "Employees(2)/RemainingVacation(Year=@Year)" }, - ... + … } ``` ::: @@ -2808,7 +2808,7 @@ Example 42: full representation in a collection "title": "Remaining Vacation", "target": "Managers(22)/Employees/RemainingVacation" }, - "value": [ ... ] + "value": [ … ] } ``` ::: @@ -2820,7 +2820,7 @@ Example 43: full representation in a nested collection "@context": "http://host/service/$metadata#Employees/$entity", "@type": "Model.Manager", "ID":22, - ... + … "Employees#RemainingVacation": { "title": "RemainingVacation", "target": "Managers(22)/Employees/RemainingVacation" @@ -2882,7 +2882,7 @@ Example 44: minimal representation in an entity { "@context": "http://host/service/$metadata#LeaveRequests/$entity", "#Model.Approve": {}, - ... + … } ``` ::: @@ -2896,7 +2896,7 @@ Example 45: full representation in an entity: "title": "Approve Leave Request", "target": "LeaveRequests(2)/Approve" }, - ... + … } ``` ::: @@ -2910,7 +2910,7 @@ Example 46: full representation in a collection "title": "Approve All Leave Requests", "target": "Employees(22)/Model.Manager/LeaveRequests/Approve" }, - "value": [ ... ] + "value": [ … ] } ``` ::: @@ -2922,7 +2922,7 @@ Example 47: full representation in a nested collection "@context": "http://host/service/$metadata#Employees/$entity", "@type": "Model.Manager", "ID": 22, - ... + … "LeaveRequests#Model.Approve": { "title": "Approve All Leave Requests", "target": "Employees(22)/Model.Manager/LeaveRequests/Approve" @@ -3425,7 +3425,7 @@ Content-Type: application/json "body": } ], - "@nextLink": "...?$skiptoken=YmF0Y2gx" + "@nextLink": "…?$skiptoken=YmF0Y2gx" } ``` @@ -3669,8 +3669,8 @@ Example 55: } ], "innererror": { - "trace": [...], - "context": {...} + "trace": […], + "context": {…} } } } diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html index 8a42b660c..075ab1b92 100644 --- a/docs/odata-protocol/odata-protocol.html +++ b/docs/odata-protocol/odata-protocol.html @@ -1184,7 +1184,7 @@

    10.19 10.20 $crossjoin Response

    Context URL template:

    {context-url}#Collection(Edm.ComplexType)
    -

    Responses to requests to the virtual collections $crossjoin(...) (see OData-URL) use the built-in abstract complex type. Single instances in these responses do not have a context URL.

    +

    Responses to requests to the virtual collections $crossjoin(…) (see OData-URL) use the built-in abstract complex type. Single instances in these responses do not have a context URL.


    11 Data Service Requests

    This chapter describes the semantics of the HTTP verbs GET, POST, PATCH, PUT, and DELETE for OData resources.

    @@ -1770,7 +1770,7 @@

    Content-Type: application/json { -  "Color": "taupe" + "Color": "taupe" }

    The response, if requested, is a collection payload containing the updated representation of each member identified by the request. If the update payload includes nested collections or nested delta collections, then they MUST be included in the response, as described in Update a Collection of Entities.

    @@ -2074,8 +2075,8 @@

    Example 86: the function MostRecentOrder can be bound to any URL that identifies a SampleModel.Customer

    <Function Name="MostRecentOrder" IsBound="true">
    -  <Parameter Name="customer" Type="SampleModel.Customer" />
    -  <ReturnType Type="SampleModel.Order" />
    +  <Parameter Name="customer" Type="SampleModel.Customer" />
    +  <ReturnType Type="SampleModel.Order" />
     </Function>
    @@ -2085,8 +2086,8 @@

    Example 88: the function Comparison can be bound to any URL that identifies a collection of entities

    <Function Name="Comparison" IsBound="true">
    -  <Parameter Name="in" Type="Collection(Edm.EntityType)" />
    -  <ReturnType Type="Diff.Overview" />
    +  <Parameter Name="in" Type="Collection(Edm.EntityType)" />
    +  <ReturnType Type="Diff.Overview" />
     </Function>

    @@ -2108,33 +2109,33 @@

    Example 91: given a GET request to http://host/service/Customers('ALFKI'), the service might respond with a Customer that includes the SampleEntities.MostRecentOrder function bound to the entity

    {
    -  "@context": ,
    -  "CustomerID": "ALFKI",
    -  "CompanyName": "Alfreds Futterkiste",
    -  "#SampleEntities.MostRecentOrder": {
    -    "title": "Most Recent Order",
    -    "target": "Customers('ALFKI')/SampleEntities.MostRecentOrder()"
    -  },
    -  
    +  "@context": ,
    +  "CustomerID": "ALFKI",
    +  "CompanyName": "Alfreds Futterkiste",
    +  "#SampleEntities.MostRecentOrder": {
    +    "title": "Most Recent Order",
    +    "target": "Customers('ALFKI')/SampleEntities.MostRecentOrder()"
    +  },
    +  
     }

    -

    An efficient format that assumes client knowledge of metadata may omit actions and functions from the payload  whose target URL can be computed via metadata following standard conventions defined in OData-URL.

    +

    An efficient format that assumes client knowledge of metadata may omit actions and functions from the payload whose target URL can be computed via metadata following standard conventions defined in OData-URL.

    Services can advertise that a function or action is not available for a particular instance by setting its value to null.

    Example 92: the SampleEntities.MostRecentOrder function is not available for customer ALFKI

    {
    -  "@context": ,
    -  "CustomerID": "ALFKI",
    -  "CompanyName": "Alfreds Futterkiste",
    -  "#SampleEntities.MostRecentOrder": null,
    -  
    +  "@context": ,
    +  "CustomerID": "ALFKI",
    +  "CompanyName": "Alfreds Futterkiste",
    +  "#SampleEntities.MostRecentOrder": null,
    +  
     }

    11.5.4 Functions

    Functions are operations exposed by an OData service that MUST return data and MUST have no observable side effects.

    11.5.4.1 Invoking a Function

    To invoke a function bound to a resource, the client issues a GET request to a function URL. A function URL may be obtained from a previously returned entity representation or constructed by appending the namespace- or alias-qualified function name to a URL that identifies a resource whose type is the same as, or derived from, the type of the binding parameter of the function. The value for the binding parameter is the value of the resource identified by the URL prior to appending the function name, and additional parameter values are specified using inline parameter syntax. If the function URL is obtained from a previously returned entity representation, parameter aliases that are identical to the parameter name preceded by an at (@) sign MUST be used. Clients MUST check if the obtained URL already contains a query part and appropriately precede the parameters either with an ampersand (&) or a question mark (?).

    -

    Services MAY additionally support invoking functions using the unqualified function name by defining one or more default namespaces through the Core.DefaultNamespace term defined in  OData-VocCore.

    +

    Services MAY additionally support invoking functions using the unqualified function name by defining one or more default namespaces through the Core.DefaultNamespace term defined in OData-VocCore.

    To request processing of the function only if the binding parameter value, an entity or collection of entities, is unmodified, the client includes the If-Match header with the latest known ETag value for the entity or collection of entities. The ETag value for a collection as a whole is transported in the ETag header of a collection response.

    Functions can be used within $filter or $orderby system query options. Such functions can be bound to a resource, as described above, or called directly by specifying the namespace- (or alias-) qualified function name. Parameter values for functions within $filter or $orderby are specified according to the inline parameter syntax.

    To invoke a function through a function import the client issues a GET request to a URL identifying the function import and passing parameter values using inline parameter syntax. The canonical URL for a function import is the service root, followed by the name of the function import. Services MAY support omitting the parentheses when invoking a function import with no parameters, but for maximum interoperability MUST also support invoking the function import with empty parentheses.

    @@ -2142,11 +2143,11 @@

    Example 93: add a new item to the list of items of the shopping cart returned by the composable MyShoppingCart function import

    POST http://host/service/MyShoppingCart()/Items
    - 
    +
     …

    If the function returns a value of type Edm.Stream and no additional path segments follow the function invocation, the response to the GET request follows the rules for requesting stream properties.

    -

    Parameter values passed to functions MUST be specified either as a URL literal (for primitive values) or as a JSON formatted OData object (for complex values, or collections of primitive or complex values). Entity typed values are passed as JSON formatted entities that MAY include a subset of the properties, or just the entity reference, as appropriate to the function.  

    +

    Parameter values passed to functions MUST be specified either as a URL literal (for primitive values) or as a JSON formatted OData object (for complex values, or collections of primitive or complex values). Entity typed values are passed as JSON formatted entities that MAY include a subset of the properties, or just the entity reference, as appropriate to the function.

    If a collection-valued function has no result for a given parameter value combination, the response is the format-specific representation of an empty collection. If a single-valued function with a nullable return-type has no result, the service returns 204 No Content.

    If a single-valued function with a non-nullable return type has no result, the service returns 4xx. For functions that return a single entity 404 Not Found is the appropriate response code.

    For a composable function the processing is stopped when the function result requires a 4xx response, and continues otherwise.

    @@ -2161,7 +2162,7 @@

    Example 95: return all Customers whose City property returns Western when passed to the Sales.SalesRegion function

    GET http://host/service/Customers?
    -      $filter=Sales.SalesRegion(City=$it/City) eq 'Western'
    + $filter=Sales.SalesRegion(City=$it/City) eq 'Western'

    A parameter alias can be used in place of an inline parameter value. The value for the alias is specified as a separate query option using the name of the parameter alias.

    @@ -2189,7 +2190,7 @@

    11.5.5 Actions

    Actions are operations exposed by an OData service that MAY have side effects when invoked. Actions MAY return data but MUST NOT be further composed with additional path segments.

    11.5.5.1 Invoking an Action

    To invoke an action bound to a resource, the client issues a POST request to an action URL. An action URL may be obtained from a previously returned entity representation or constructed by appending the namespace- or alias-qualified action name to a URL that identifies a resource whose type is the same as, or derives from, the type of the binding parameter of the action. The value for the binding parameter is the resource identified by the URL preceding the action name, and only the non-binding parameter values are passed in the request body according to the particular format.

    -

    Services MAY additionally support invoking actions using the unqualified action name by defining one or more default namespaces through the Core.DefaultNamespace term defined in  OData-VocCore.

    +

    Services MAY additionally support invoking actions using the unqualified action name by defining one or more default namespaces through the Core.DefaultNamespace term defined in OData-VocCore.

    To invoke an action through an action import, the client issues a POST request to a URL identifying the action import. The canonical URL for an action import is the service root, followed by the name of the action import. When invoking an action through an action import all parameter values MUST be passed in the request body according to the particular format.

    Non-binding parameters that are nullable or annotated with the term Core.OptionalParameter defined in OData-VocCore MAY be omitted from the request body. If an omitted parameter is not annotated (and thus nullable), it MUST be interpreted as having the null value. If it is annotated and the annotation specifies a DefaultValue, the omitted parameter is interpreted as having that default value. If omitted and the annotation does not specify a default value, the service is free on how to interpret the omitted parameter. Note: a nullable non-binding parameter is equivalent to being annotated as optional with a default value of null.

    4.01 services MUST support invoking actions with no non-binding parameters and parameterless action imports both without a request body and with a request body representing no parameters, according to the particular format. Interoperable clients SHOULD always include a request body, even when invoking actions with no non-binding parameters and parameterless action imports.

    @@ -2206,11 +2207,11 @@

    Content-Type: application/json { -  "items": [ -   { "product": 4001, "quantity": 2 }, -    { "product": 7062, "quantity": 1 }, + "items": [ + { "product": 4001, "quantity": 2 }, + { "product": 7062, "quantity": 1 }, ], -  "discountCode": "BLACKFRIDAY" + "discountCode": "BLACKFRIDAY" }

    11.5.5.2 Action Overload Resolution

    @@ -2280,7 +2281,7 @@

    11.7.7.1 Multipart Batch Request Body

    The body of a multipart batch request is made up of a series of individual requests and change sets, each represented as a distinct body part (i.e. preceded by a boundary delimiter line consisting of two dashes and the value of the boundary parameter specified in the Content-Type header, and the last body part followed by a closing boundary delimiter line consisting of two dashes, the boundary, and another two dashes).

    A body part representing an individual request MUST include a Content-Type header with value application/http.

    -

    The contents of a body part representing a change set MUST itself be a multipart document (see RFC2046) with one body part for each operation in the change set. [E]{.MsoCommentReference}ach body part representing an operation in the change set MUST specify a Content-ID header with a request identifier that is unique within the batch request.

    +

    The contents of a body part representing a change set MUST itself be a multipart document (see RFC2046) with one body part for each operation in the change set. Each body part representing an operation in the change set MUST specify a Content-ID header with a request identifier that is unique within the batch request.

    A Content-Transfer-Encoding header with value binary may be included for historic reasons although this header is not used by HTTP and only needed for transmission via E-Mail. Neither clients nor services should rely on this header being present.

    Preambles and epilogues in the multipart batch request body, as defined in RFC2046, are valid but are assigned no meaning and thus MUST be ignored by processors of multipart batch requests.

    The request URL of individual requests within a batch request or change set can use one of the following three formats:

    @@ -2289,7 +2290,7 @@

    Example 101:

    -
    GET https://host:1234/path/service/People(1) HTTP/1.1
    +
    GET https://host:1234/path/service/People(1) HTTP/1.1
    • Absolute resource path and separate Host header
    • @@ -2401,7 +2402,8 @@

      Content-ID: 1 GET /service/Employees(0) HTTP/1.1 -Host: host Accept: application/json - +Host: host +Accept: application/json ---batch_36522ad7-fc75-4b56-8c71-56071383e77b -Content-Type: application/http -Content-ID: 2 - -PATCH /service/Employees(0) HTTP/1.1 -Host: host -Content-Type: application/json -Content-Length: ### -If-Match: $1 - -{ -   "Salary": 75000 -} ---batch_36522ad7-fc75-4b56-8c71-56071383e77b-- + +--batch_36522ad7-fc75-4b56-8c71-56071383e77b +Content-Type: application/http +Content-ID: 2 + +PATCH /service/Employees(0) HTTP/1.1 +Host: host +Content-Type: application/json +Content-Length: ### +If-Match: $1 + +{ + "Salary": 75000 +} +--batch_36522ad7-fc75-4b56-8c71-56071383e77b--

      11.7.7.4 Processing a Multipart Batch Request

      The service MUST process the individual requests and change sets within a multipart batch request in the order received. Processing stops on the first error unless the continue-on-error preference is specified with an explicit or implicit value of true.

      @@ -2873,7 +2876,7 @@
      [RFC9110]

      Fielding, R., Ed., M. Nottingham, Ed., and J. Reschke, Ed., “HTTP Semantics”, RFC 9110, June 2022
      https://www.rfc-editor.org/info/rfc9110.

      A.2 Informative References

      -
      [ECMAScript]
      +
      [ECMAScript]

      ECMAScript 2023 Language Specification, 14th Edition, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.


      Appendix B. Safety, Security and Privacy Considerations

      diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md index 55a727c79..f867627c1 100644 --- a/docs/odata-protocol/odata-protocol.md +++ b/docs/odata-protocol/odata-protocol.md @@ -1312,7 +1312,10 @@ processing (if specified with an explicit value of `false`). The syntax of the `continue-on-error` preference is defined in [OData-ABNF](#ODataABNF). -The `continue-on-error` preference can also be used on a [delta update](#UpdateaCollectionofEntities), [set-based update](#UpdateMembersofaCollection), or [set-based delete](#DeleteMembersofaCollection) to request that the service +The `continue-on-error` preference can also be used on a +[delta update](#UpdateaCollectionofEntities), +[set-based update](#UpdateMembersofaCollection), or +[set-based delete](#DeleteMembersofaCollection) to request that the service continue attempting to process changes after receiving an error. A service MAY specify support for the `continue-on-error` preference @@ -1923,7 +1926,7 @@ This code serves as a sub-status for the HTTP error code specified in the response. - `message`: required non-null, non-empty, language-dependent, human-readable string describing the error. -The [`Content-Language`](#HeaderContentLanguage) header MUST contain the +The [`Content-Language`](#HeaderContentLanguage) header MUST contain the language code from [RFC5646](#rfc5646) corresponding to the language in which the value for message is written. - `target`: optional nullable, potentially @@ -2297,9 +2300,9 @@ Example 22: resource URL and corresponding context URL --- expand with `$levels` ``` http://host/service/Employees/Sales.Manager?$select=DirectReports -        &$expand=DirectReports($select=FirstName,LastName;$levels=4) + &$expand=DirectReports($select=FirstName,LastName;$levels=4) http://host/service/$metadata -        #Employees/Sales.Manager(DirectReports,DirectReports+(FirstName,LastName)) + #Employees/Sales.Manager(DirectReports,DirectReports+(FirstName,LastName)) ``` ::: @@ -2339,9 +2342,9 @@ the context URL. Example 23: resource URL and corresponding context URL ``` http://host/service/Employees(1)/Sales.Manager? -    $expand=DirectReports($select=FirstName,LastName;$levels=4) + $expand=DirectReports($select=FirstName,LastName;$levels=4) http://host/service/$metadata -       #Employees/Sales.Manager(DirectReports+(FirstName,LastName))/$entity + #Employees/Sales.Manager(DirectReports+(FirstName,LastName))/$entity ``` ::: @@ -2505,7 +2508,8 @@ Context URL templates: {context-url}#{entity-set}/$deletedEntity {context-url}#{entity-set}/$link - {context-url}#{entity-set}/$deletedLink + {context-url}#{entity-set}/$deletedLink + In addition to new or changed entities which have the canonical context URL for an entity, a delta response can contain deleted entities, new links, and deleted links. They are identified by the corresponding @@ -2651,7 +2655,8 @@ OData defines a number of system query options that allow refining the request. System query options are prefixed with the dollar (`$`) character, which is optional in OData 4.01. 4.01 services MUST support case-insensitive system query option names specified with or without the -`$` prefix. Clients that want to work with 4.0 services MUST use lower case names +`$` prefix. +Clients that want to work with 4.0 services MUST use lower case names and specify the `$` prefix. The result of the request MUST be as if the system query options were @@ -3064,9 +3069,9 @@ Example 45: compute total price for order items (line breaks only for readability) ``` GET http://host/service/Customers -   ?$filter=Orders/any(o:o/TotalPrice gt 100) -   &$expand=Orders($compute=Price mult Qty as TotalPrice -                  ;$select=Name,Price,Qty,TotalPrice) + ?$filter=Orders/any(o:o/TotalPrice gt 100) + &$expand=Orders($compute=Price mult Qty as TotalPrice + ;$select=Name,Price,Qty,TotalPrice) ``` ::: @@ -3660,8 +3665,8 @@ specify properties to return ``` GET http://host/service/$entity/Model.Customer ?$id=http://host/service/Customers('ALFKI') -      &$select=CompanyName,ContactName -      &$expand=Orders + &$select=CompanyName,ContactName + &$expand=Orders ``` ::: @@ -3677,7 +3682,7 @@ matching the request after applying any [`$search`](#SystemQueryOptionsearch) system query options, formatted as a simple primitive integer value with media type `text/plain`. Clients SHOULD NOT combine the system query options -[ ]{.MsoCommentReference}[`$top`](#SystemQueryOptiontop), +[`$top`](#SystemQueryOptiontop), [`$skip`](#SystemQueryOptionskip), [`$orderby`](#SystemQueryOptionorderby), [`$expand`](#SystemQueryOptionexpand), and @@ -3881,7 +3886,8 @@ MUST return changes, additions, or deletions to the expanded entities, as well as added or deleted links to expanded entities or nested collections representing current membership. If the defining query includes expanded references, then the delta link MUST return changes to -the membership in the set of expanded references.  +the membership in the set of expanded references. + Navigation properties specified in the [`$select`](#SystemQueryOptionselect) list of a defining query are not used to define the scope or contents of the items being tracked. Clients @@ -4181,15 +4187,15 @@ entity with links to an existing manager (of managers) and to two existing emplo annotation to the `Manager` and `DirectReports` navigation properties ```json { -  "@odata.type": "#Northwind.Manager", -  "ID": 1, -  "FirstName": "Pat", -  "LastName": "Griswold", + "@odata.type": "#Northwind.Manager", + "ID": 1, + "FirstName": "Pat", + "LastName": "Griswold", "Manager@odata.bind": "http://host/service/Employees(0)", -  "DirectReports@odata.bind": [ -    "http://host/service/Employees(5)", -    "http://host/service/Employees(6)" -  ] + "DirectReports@odata.bind": [ + "http://host/service/Employees(5)", + "http://host/service/Employees(6)" + ] } ``` ::: @@ -4200,15 +4206,15 @@ entity with links to an existing manager (of managers) and to two existing emplo within the `Manager` and `DirectReports` navigation properties ```json { -  "@type": "#Northwind.Manager", -  "ID": 1, -  "FirstName": "Pat", -  "LastName": "Griswold", + "@type": "#Northwind.Manager", + "ID": 1, + "FirstName": "Pat", + "LastName": "Griswold", "Manager": { "@id": "Employees(0)" }, -  "DirectReports": [ -    {"@id": "Employees(5)"}, -    {"@id": "Employees(6)"} -  ] + "DirectReports": [ + {"@id": "Employees(5)"}, + {"@id": "Employees(6)"} + ] } ``` ::: @@ -4398,21 +4404,21 @@ reports; two existing employees and one new employee named `Suzanne Brown`. The `LastName` of employee 6 is updated to `Smith`. ```json { -  "@type": "#Northwind.Manager", -  "FirstName" : "Patricia", -  "DirectReports": [ -    { -      "@id": "Employees(5)" -    }, -    { -      "@id": "Employees(6)", -      "LastName": "Smith" -    }, -    { -      "FirstName": "Suzanne", -      "LastName": "Brown" -    } -  ] + "@type": "#Northwind.Manager", + "FirstName": "Patricia", + "DirectReports": [ + { + "@id": "Employees(5)" + }, + { + "@id": "Employees(6)", + "LastName": "Smith" + }, + { + "FirstName": "Suzanne", + "LastName": "Brown" + } + ] } ``` ::: @@ -4454,33 +4460,33 @@ of employee 6 and link to it if necessary named "Suzanne Brown" and link to it ```json { -  "@type": "#Northwind.Manager", -  "FirstName": "Patricia", -  "DirectReports@delta": [ -    { -      "@removed": { -        "reason": "deleted" -      }, -      "@id": "Employees(3)" -    }, -    { -      "@removed": { -        "reason": "changed" -      }, -      "@id": "Employees(4)" -    }, -    { -      "@id": "Employees(5)" -    }, -    { -      "@id": "Employees(6)", -      "LastName": "Smith" -    }, -    { -      "FirstName": "Suzanne", -      "LastName": "Brown" -    } -  ] + "@type": "#Northwind.Manager", + "FirstName": "Patricia", + "DirectReports@delta": [ + { + "@removed": { + "reason": "deleted" + }, + "@id": "Employees(3)" + }, + { + "@removed": { + "reason": "changed" + }, + "@id": "Employees(4)" + }, + { + "@id": "Employees(5)" + }, + { + "@id": "Employees(6)", + "LastName": "Smith" + }, + { + "FirstName": "Suzanne", + "LastName": "Brown" + } + ] } ``` ::: @@ -4854,7 +4860,8 @@ The service MUST directly modify only those properties of the complex type specified in the payload of the `PATCH` request. If a complex-typed property is set to a different type in a `PATCH` request, -properties shared through inheritance, as well as dynamic properties, are retained (unless overwritten by new values in the payload). +properties shared through inheritance, as well as dynamic properties, +are retained (unless overwritten by new values in the payload). Other properties of the original type are discarded. The service MAY additionally support clients sending a `PUT` request to @@ -4936,7 +4943,7 @@ POST /service/Customers('ALFKI')/EmailAddresses?$index=1 Content-Type: application/json { -  "value": "alfred@futterkiste.de" + "value": "alfred@futterkiste.de" } ``` ::: @@ -5058,7 +5065,7 @@ PATCH /service/Products/$filter(@bar)/$each?@bar=Color eq 'beige-brown' Content-Type: application/json { -  "Color": "taupe" + "Color": "taupe" } ``` ::: @@ -5150,8 +5157,8 @@ Example 86: the function `MostRecentOrder` can be bound to any URL that identifies a `SampleModel.Customer` ```xml -   + + ``` ::: @@ -5170,8 +5177,8 @@ Example 88: the function `Comparison` can be bound to any URL that identifies a collection of entities ```xml -   -   + + ``` ::: @@ -5234,20 +5241,20 @@ a Customer that includes the `SampleEntities.MostRecentOrder` function bound to the entity ```json { -  "@context": …, -  "CustomerID": "ALFKI", -  "CompanyName": "Alfreds Futterkiste", -  "#SampleEntities.MostRecentOrder": { -    "title": "Most Recent Order", -    "target": "Customers('ALFKI')/SampleEntities.MostRecentOrder()" -  }, -  … + "@context": …, + "CustomerID": "ALFKI", + "CompanyName": "Alfreds Futterkiste", + "#SampleEntities.MostRecentOrder": { + "title": "Most Recent Order", + "target": "Customers('ALFKI')/SampleEntities.MostRecentOrder()" + }, + … } ``` ::: An efficient format that assumes client knowledge of metadata may omit -actions and functions from the payload  whose target URL can be computed +actions and functions from the payload whose target URL can be computed via metadata following standard conventions defined in [OData-URL](#ODataURL). @@ -5259,11 +5266,11 @@ Example 92: the `SampleEntities.MostRecentOrder` function is not available for customer `ALFKI` ```json { -  "@context": …, -  "CustomerID": "ALFKI", -  "CompanyName": "Alfreds Futterkiste", -  "#SampleEntities.MostRecentOrder": null, -  … + "@context": …, + "CustomerID": "ALFKI", + "CompanyName": "Alfreds Futterkiste", + "#SampleEntities.MostRecentOrder": null, + … } ``` ::: @@ -5296,7 +5303,7 @@ Services MAY additionally support invoking functions using the unqualified function name by defining one or more [default namespaces](#DefaultNamespaces) through the [`Core.DefaultNamespace`](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md#DefaultNamespace) term -defined in  [OData-VocCore](#ODataVocCore). +defined in [OData-VocCore](#ODataVocCore). To request processing of the function only if the binding parameter value, an entity or collection of entities, is unmodified, the client includes @@ -5336,7 +5343,7 @@ Example 93: add a new item to the list of items of the shopping cart returned by the composable `MyShoppingCart` function import ``` POST http://host/service/MyShoppingCart()/Items -  + … ``` ::: @@ -5350,7 +5357,7 @@ literal (for primitive values) or as a JSON formatted OData object (for complex values, or collections of primitive or complex values). Entity typed values are passed as JSON formatted entities that MAY include a subset of the properties, or just the entity reference, as appropriate -to the function.   +to the function. If a collection-valued function has no result for a given parameter value combination, the response is the format-specific representation of @@ -5394,7 +5401,7 @@ Example 95: return all Customers whose `City` property returns `Western` when passed to the `Sales.SalesRegion` function ``` GET http://host/service/Customers? -      $filter=Sales.SalesRegion(City=$it/City) eq 'Western' + $filter=Sales.SalesRegion(City=$it/City) eq 'Western' ``` ::: @@ -5502,7 +5509,7 @@ Services MAY additionally support invoking actions using the unqualified action name by defining one or more [default namespaces](#DefaultNamespaces) through the [`Core.DefaultNamespace`](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md#DefaultNamespace) term -defined in  [OData-VocCore](#ODataVocCore). +defined in [OData-VocCore](#ODataVocCore). To invoke an action through an action import, the client issues a `POST` request to a URL identifying the action import. The canonical URL for an @@ -5567,11 +5574,11 @@ If-Match: W/"MjAxOS0wMy0yMVQxMzowNVo=" Content-Type: application/json { -  "items": [ -   { "product": 4001, "quantity": 2 }, -    { "product": 7062, "quantity": 1 }, + "items": [ + { "product": 4001, "quantity": 2 }, + { "product": 7062, "quantity": 1 }, ], -  "discountCode": "BLACKFRIDAY" + "discountCode": "BLACKFRIDAY" } ``` ::: @@ -5839,7 +5846,7 @@ A body part representing an individual request MUST include a The contents of a body part representing a change set MUST itself be a multipart document (see [RFC2046](#rfc2046)) with one body part for each -operation in the change set. [E]{.MsoCommentReference}ach body part +operation in the change set. Each body part representing an operation in the change set MUST specify a `Content-ID` header with a [request identifier](#IdentifyingIndividualRequests) that is unique within the batch request. @@ -5861,7 +5868,7 @@ set can use one of the following three formats: ::: example Example 101: ``` -GET https://host:1234/path/service/People(1) HTTP/1.1 +GET https://host:1234/path/service/People(1) HTTP/1.1 ``` ::: @@ -6006,7 +6013,8 @@ Content-Type: application/http Content-ID: 1 POST /service/Customers HTTP/1.1 -Host: host Content-Type: application/json +Host: host +Content-Type: application/json Content-Length: ### @@ -6044,7 +6052,8 @@ Content-Type: application/http Content-ID: 1 GET /service/Employees(0) HTTP/1.1 -Host: host Accept: application/json +Host: host +Accept: application/json --batch_36522ad7-fc75-4b56-8c71-56071383e77b @@ -6058,7 +6067,7 @@ Content-Length: ### If-Match: $1 { -   "Salary": 75000 + "Salary": 75000 } --batch_36522ad7-fc75-4b56-8c71-56071383e77b-- ``` @@ -6513,7 +6522,8 @@ service: 1. MUST conform to the [OData 4.0 Minimal Conformance Level](#OData40MinimalConformanceLevel) -2. MUST be compliant with version 4.01 of the [OData-JSON](#ODataJSON) format +2. MUST be compliant with version 4.01 of the [OData-JSON](#ODataJSON) +format 3. MUST return the [`AsyncResult`](#HeaderAsyncResult) result header in the final response to an asynchronous request if asynchronous operations are supported. @@ -6785,8 +6795,9 @@ https://www.rfc-editor.org/info/rfc9110. ## A.2 Informative References -###### [ECMAScript] -_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/. +###### [ECMAScript] +_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. +https://www.ecma-international.org/publications-and-standards/standards/ecma-262/. ------- diff --git a/docs/odata-temporal-ext/odata-temporal-ext.html b/docs/odata-temporal-ext/odata-temporal-ext.html index 857a48083..b38847d13 100644 --- a/docs/odata-temporal-ext/odata-temporal-ext.html +++ b/docs/odata-temporal-ext/odata-temporal-ext.html @@ -263,7 +263,7 @@

      1.2.1.4 Time Slic

      Time slices for the same temporal object are non-overlapping, so for any given point in time there is at most one slice whose time period contains that point in time.

      Time slices for a temporal object need not cover the complete timeline. There can be points in time for which no time slice exists, indicating that the object’s values are not known to the service.

      1.2.1.4.1 Closed-Open Semantics
      -

      Time slices typically use closed-open semantics, following [SQL:2011]. This means the start is part of the period, the end is not part of the period, and for directly adjacent time slices the end of the earlier time slice is identical to the start of the next time slice. The period start must be less than the period end.

      +

      Time slices typically use closed-open semantics, following SQL:2011. This means the start is part of the period, the end is not part of the period, and for directly adjacent time slices the end of the earlier time slice is identical to the start of the next time slice. The period start must be less than the period end.

      1.2.1.4.2 Closed-Closed Semantics

      Some software systems predating the availability of temporal databases and with data type date for the application-time period start and end use closed-closed semantics. Temporal services on top of these systems can either convert their period end boundaries on-the-fly by adding one day on the way out and subtracting one day on the way in, or alternatively express the used time slice semantics via annotations.

      1.2.1.5 Snapshot Entity Set

      @@ -314,7 +314,7 @@

      2 Overview

    • Application time, also called actual time, business time, effective time, or valid time, and
    • System time, also called recording time, audit time, or transaction time.
    -

    Keeping track of time is typically done by storing data together with the time period for which that data is deemed valid or effective, using separate periods for application time and system time, and the time periods are part of the logical key for “records”. See [SQL:2011] or [Kulkarni] on how this is done in the SQL standard.

    +

    Keeping track of time is typically done by storing data together with the time period for which that data is deemed valid or effective, using separate periods for application time and system time, and the time periods are part of the logical key for “records”. See SQL:2011 or Kulkarni on how this is done in the SQL standard.

    A consumer’s perspective on this data can be different: even if time is tracked internally, the period of time may or may not be visible in a consumer’s perspective, and even if visible the related properties are often not considered part of an entity’s identity. For example, an employee is still the same person even after switching to another department.

    The goals of this extension are:

      @@ -1324,79 +1324,79 @@

      Example 6: Employees entity set from example model api-1 annotated with temporal terms

      "Employees": {
      -  "$Collection": true,
      -  "$Type": "OrgModel.Employee",
      -  "@Temporal.ApplicationTimeSupport": {
      -    "Timeline": {
      -      "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineSnapshot"
      -    },
      -    "UnitOfTime": {
      -      "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate"
      -    }
      -  }
      +  "$Collection": true,
      +  "$Type": "OrgModel.Employee",
      +  "@Temporal.ApplicationTimeSupport": {
      +    "Timeline": {
      +      "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineSnapshot"
      +    },
      +    "UnitOfTime": {
      +      "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate"
      +    }
      +  }
       },

      Example 7: history navigation property in entity set Employees from example model api-2 annotated with temporal terms

      "$Annotations": {
      -  "OrgModel.Default/Employees/history": {
      -    "@Temporal.ApplicationTimeSupport": {
      -      "Timeline": {
      -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineVisible",
      -        "TimeSliceStart": "From",
      -        "TimeSliceEnd": "To",
      -        "SupportedActions": [
      -          "Temporal.Update",
      -          "Temporal.Upsert",
      -          "Temporal.Delete"
      -        ]
      -      },
      -      "UnitOfTime": {
      -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate"
      -      }
      -    }
      -  }
      +  "OrgModel.Default/Employees/history": {
      +    "@Temporal.ApplicationTimeSupport": {
      +      "Timeline": {
      +        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineVisible",
      +        "TimeSliceStart": "From",
      +        "TimeSliceEnd": "To",
      +        "SupportedActions": [
      +          "Temporal.Update",
      +          "Temporal.Upsert",
      +          "Temporal.Delete"
      +        ]
      +      },
      +      "UnitOfTime": {
      +        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate"
      +      }
      +    }
      +  }
       }

      Example 8: CostCenters entity set containing time slices for multiple temporal objects, the temporal objects identified by combination of AreaID and CostCenterID

      "CostCenter": {
      -  "$Kind": "EntityType",
      -  "$Key": ["tsid"],
      -  "tsid": {},
      -  "AreaID": {},
      -  "CostCenterID": {},
      -  "ValidTo": { "$Type": "Edm.Date" },
      -  "ValidFrom": { "$Type": "Edm.Date" },
      -  "ProfitCenterID": { "$Nullable": true },
      -  "DepartmentID": { "$Nullable": true }
      +  "$Kind": "EntityType",
      +  "$Key": ["tsid"],
      +  "tsid": {},
      +  "AreaID": {},
      +  "CostCenterID": {},
      +  "ValidTo": { "$Type": "Edm.Date" },
      +  "ValidFrom": { "$Type": "Edm.Date" },
      +  "ProfitCenterID": { "$Nullable": true },
      +  "DepartmentID": { "$Nullable": true }
       },
       
       "Default": {
      -  "$Kind": "EntityContainer",
      -  "CostCenters": { "$Collection": true, "$Type": "this.CostCenter" }
      +  "$Kind": "EntityContainer",
      +  "CostCenters": { "$Collection": true, "$Type": "this.CostCenter" }
       },
       
       "$Annotations": {
      -  "this.Default/CostCenters": {
      -    "@Temporal.ApplicationTimeSupport": {
      -      "UnitOfTime": {
      -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.UnitOfTimeDate",
      -        "ClosedClosedPeriods": true
      -      },
      -      "Timeline": {
      -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.TimelineVisible",
      -        "PeriodStart": "ValidFrom",
      -        "PeriodEnd": "ValidTo",
      -        "ObjectKey": ["AreaID", "CostCenterID"]
      -      },
      -      "SupportedActions": [
      -        "Temporal.Update",
      -        "Temporal.Upsert",
      -        "Temporal.Delete"
      -      ]
      -    }
      -  }
      +  "this.Default/CostCenters": {
      +    "@Temporal.ApplicationTimeSupport": {
      +      "UnitOfTime": {
      +        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.UnitOfTimeDate",
      +        "ClosedClosedPeriods": true
      +      },
      +      "Timeline": {
      +        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.TimelineVisible",
      +        "PeriodStart": "ValidFrom",
      +        "PeriodEnd": "ValidTo",
      +        "ObjectKey": ["AreaID", "CostCenterID"]
      +      },
      +      "SupportedActions": [
      +        "Temporal.Update",
      +        "Temporal.Upsert",
      +        "Temporal.Delete"
      +      ]
      +    }
      +  }
       }

      @@ -1450,10 +1450,10 @@

      4.2.2
      GET /api-1/Employees('E314')

      results in

      {
      -  "@odata.context": "$metadata#Employees/$entity",
      -  "ID": "E314",
      -  "Name": "McDevitt",
      -  "Jobtitle": "Senior"
      +  "@odata.context": "$metadata#Employees/$entity",
      +  "ID": "E314",
      +  "Name": "McDevitt",
      +  "Jobtitle": "Senior"
       }
      @@ -1461,10 +1461,10 @@

      4.2.2
      GET /api-1/Employees('E314')?$at=2012-01-01

      results in

      {
      -  "@odata.context": "$metadata#Employees/$entity",
      -  "ID": "E314",
      -  "Name": "McDevitt",
      -  "Jobtitle": "Junior"
      +  "@odata.context": "$metadata#Employees/$entity",
      +  "ID": "E314",
      +  "Name": "McDevitt",
      +  "Jobtitle": "Junior"
       }

      @@ -1472,14 +1472,14 @@

      4.2.2
      GET /api-1/Employees?$filter=contains(Name,'i')&$at=2012-01-01

      results in one time slice for each employee matching the filter at the specified point in time — note that E401 back then does not satisfy this condition

      {
      -  "@odata.context": "$metadata#Employees",
      -  "value": [
      -    {
      -      "ID": "E314",
      -      "Name": "McDevitt",
      -      "Jobtitle": "Junior"
      -    }
      -  ]
      +  "@odata.context": "$metadata#Employees",
      +  "value": [
      +    {
      +      "ID": "E314",
      +      "Name": "McDevitt",
      +      "Jobtitle": "Junior"
      +    }
      +  ]
       }

      Expanding related entities in combination with $at is straight-forward: the response consists of the time slices of related entities that are valid at the requested point in time. The period boundaries of the nested entities reflect the actual validity of the related entities and are independent of the period boundaries of the base entity.

      @@ -1488,14 +1488,14 @@

      4.2.2
      GET /api-1/Employees('E314')?$at=2012-01-01&$expand=Department($at=2021-11-23)

      results in

      {
      -  "@odata.context": "$metadata#Employees/$entity",
      -  "ID": "E314",
      -  "Name": "McDevitt",
      -  "Jobtitle": "Junior",
      -  "Department": {
      -    "ID": "D08",
      -    "Name": "1st Level Support"
      -  }
      +  "@odata.context": "$metadata#Employees/$entity",
      +  "ID": "E314",
      +  "Name": "McDevitt",
      +  "Jobtitle": "Junior",
      +  "Department": {
      +    "ID": "D08",
      +    "Name": "1st Level Support"
      +  }
       }
      @@ -1503,21 +1503,21 @@

      4.2.2
      GET /api-1/Departments('D15')?$at=2015-01-01&$expand=Employees

      results in

      {
      -  "@odata.context": "$metadata#Departments/$entity",
      -  "ID": "D15",
      -  "Name": "Services",
      -  "Employees": [
      -    {
      -      "ID": "E314",
      -      "Name": "McDevitt",
      -      "Jobtitle": "Senior"
      -    },
      -    {
      -      "ID": "E401",
      -      "Name": "Gibson",
      -      "Jobtitle": "Expert"
      -    }
      -  ]
      +  "@odata.context": "$metadata#Departments/$entity",
      +  "ID": "D15",
      +  "Name": "Services",
      +  "Employees": [
      +    {
      +      "ID": "E314",
      +      "Name": "McDevitt",
      +      "Jobtitle": "Senior"
      +    },
      +    {
      +      "ID": "E401",
      +      "Name": "Gibson",
      +      "Jobtitle": "Expert"
      +    }
      +  ]
       }

      4.2.3 Query Options $from, $to, and $toInclusive

      @@ -1554,46 +1554,46 @@

      Example 14: retrieve employee history over a period of application time

      GET /api-2/Employees?$expand=history($select=Name,Jobtitle)
      -                    &$from=2012-03-01&$to=2025-01-01
      + &$from=2012-03-01&$to=2025-01-01

      results in one entity for each employee with time slices that overlap the specified application-time period:

      {
      -  "@odata.context": "$metadata#Employees",
      -  "value": [
      -    {
      -      "ID": "E314",
      -      "history": [
      -        {
      -          "Name": "McDevitt",
      -          "Jobtitle": "Junior",
      -          "From": "2011-01-01",
      -          "To": "2013-10-01"
      -        },
      -        {
      -          "Name": "McDevitt",
      -          "Jobtitle": "Senior",
      -          "From": "2013-10-01",
      -          "To": "2014-01-01"
      -        },
      -        {
      -          "Name": "McDevitt",
      -          "Jobtitle": "Senior",
      -          "From": "2014-01-01",
      -          "To": "9999-12-31"
      -        }
      -      ]
      -    },
      -    {
      -      "ID": "E401",
      -      "history": [
      -        {
      -          "Name": "Gibson",
      -          "Jobtitle": "Expert",
      -          "From": "2012-03-01",
      -          "To": "9999-12-31"
      -        }
      -      ]
      -    }
      -  ]
      +  "@odata.context": "$metadata#Employees",
      +  "value": [
      +    {
      +      "ID": "E314",
      +      "history": [
      +        {
      +          "Name": "McDevitt",
      +          "Jobtitle": "Junior",
      +          "From": "2011-01-01",
      +          "To": "2013-10-01"
      +        },
      +        {
      +          "Name": "McDevitt",
      +          "Jobtitle": "Senior",
      +          "From": "2013-10-01",
      +          "To": "2014-01-01"
      +        },
      +        {
      +          "Name": "McDevitt",
      +          "Jobtitle": "Senior",
      +          "From": "2014-01-01",
      +          "To": "9999-12-31"
      +        }
      +      ]
      +    },
      +    {
      +      "ID": "E401",
      +      "history": [
      +        {
      +          "Name": "Gibson",
      +          "Jobtitle": "Expert",
      +          "From": "2012-03-01",
      +          "To": "9999-12-31"
      +        }
      +      ]
      +    }
      +  ]
       }

      The history for the first employee contains two time slices that do not differ in the represented properties, caused by a department change, and the department is not part of the representation.

      The service could have combined these two time slices into one.

      @@ -1601,97 +1601,97 @@

      Example 15: retrieve all employees that ever worked for department D15, with their full history, and the department’s data at the start of each employee history time slice

      GET /api-2/Departments('D15')/Employees?
      -    $expand=history(
      +    $expand=history(
             @emp=$this;
      -      $expand=Department(
      -        $expand=history($at=@emp/From)
      -      )
      -    )
      + $expand=Department( + $expand=history($at=@emp/From) + ) + )

      has the following result with department names and budgets as of the beginning of each employee time slice:

      {
      -  "@odata.context": "$metadata#Employees",
      -  "value": [
      -    {
      -      "ID": "E314",
      -      "history": [
      -        {
      -          "Name": "McDevitt",
      -          "Jobtitle": "Junior",
      -          "From": "2011-01-01",
      -          "To": "2013-10-01",
      -          "Department": {
      -            "ID": "D08",
      -            "history": [{
      -              "Name": "Support",
      -              "Budget": 1000,
      -              "From": "2010-01-01",
      -              "To": "2012-10-01"
      -            }]
      -          }
      -        },
      -        {
      -          "Name": "McDevitt",
      -          "Jobtitle": "Senior",
      -          "From": "2013-10-01",
      -          "To": "2014-01-01",
      -          "Department": {
      -            "ID": "D08",
      -            "history": [{
      -              "Name": "1st Level Support",
      -              "Budget": 1250,
      -              "From": "2012-06-01",
      -              "To": "2014-01-01"
      -            }]
      -          }
      -        },
      -        {
      -          "Name": "McDevitt",
      -          "Jobtitle": "Senior",
      -          "From": "2014-01-01",
      -          "To": "9999-12-31",
      -          "Department": {
      -            "ID": "D15",
      -            "history": [{
      -              "Name": "Services",
      -              "Budget": 1170,
      -              "From": "2011-01-01",
      -              "To": "9999-12-31"
      -            }]
      -          }
      -        }
      -      ]
      -    },
      -    {
      -      "ID": "E401",
      -      "history": [
      -        {
      -          "Name": "Norman",
      -          "Jobtitle": "Expert",
      -          "From": "2009-11-01",
      -          "To": "2012-03-01",
      -          "Department": {
      -            "ID": "D15",
      -            "history": []
      -          }
      -        },
      -        {
      -          "Name": "Gibson",
      -          "Jobtitle": "Expert",
      -          "From": "2012-03-01",
      -          "To": "9999-12-31",
      -          "Department": {
      -            "ID": "D15",
      -            "history": [{
      -              "Name": "Services",
      -              "Budget": 1170,
      -              "From": "2011-01-01",
      -              "To": "9999-12-31"
      -            }]
      -          }
      -        }
      -      ]
      -    }
      -  ]
      +  "@odata.context": "$metadata#Employees",
      +  "value": [
      +    {
      +      "ID": "E314",
      +      "history": [
      +        {
      +          "Name": "McDevitt",
      +          "Jobtitle": "Junior",
      +          "From": "2011-01-01",
      +          "To": "2013-10-01",
      +          "Department": {
      +            "ID": "D08",
      +            "history": [{
      +              "Name": "Support",
      +              "Budget": 1000,
      +              "From": "2010-01-01",
      +              "To": "2012-10-01"
      +            }]
      +          }
      +        },
      +        {
      +          "Name": "McDevitt",
      +          "Jobtitle": "Senior",
      +          "From": "2013-10-01",
      +          "To": "2014-01-01",
      +          "Department": {
      +            "ID": "D08",
      +            "history": [{
      +              "Name": "1st Level Support",
      +              "Budget": 1250,
      +              "From": "2012-06-01",
      +              "To": "2014-01-01"
      +            }]
      +          }
      +        },
      +        {
      +          "Name": "McDevitt",
      +          "Jobtitle": "Senior",
      +          "From": "2014-01-01",
      +          "To": "9999-12-31",
      +          "Department": {
      +            "ID": "D15",
      +            "history": [{
      +              "Name": "Services",
      +              "Budget": 1170,
      +              "From": "2011-01-01",
      +              "To": "9999-12-31"
      +            }]
      +          }
      +        }
      +      ]
      +    },
      +    {
      +      "ID": "E401",
      +      "history": [
      +        {
      +          "Name": "Norman",
      +          "Jobtitle": "Expert",
      +          "From": "2009-11-01",
      +          "To": "2012-03-01",
      +          "Department": {
      +            "ID": "D15",
      +            "history": []
      +          }
      +        },
      +        {
      +          "Name": "Gibson",
      +          "Jobtitle": "Expert",
      +          "From": "2012-03-01",
      +          "To": "9999-12-31",
      +          "Department": {
      +            "ID": "D15",
      +            "history": [{
      +              "Name": "Services",
      +              "Budget": 1170,
      +              "From": "2011-01-01",
      +              "To": "9999-12-31"
      +            }]
      +          }
      +        }
      +      ]
      +    }
      +  ]
       }

      4.2.4 Interaction with Standard System Query Options

      @@ -1700,67 +1700,67 @@

      Example 16: retrieve employee history over a period of application time and filter on job title

      GET /api-2/Employees?$expand=history(
      -                       $select=Name,Jobtitle;
      -                       $from=2012-03-01&$to=2025-01-01;
      -                       $filter=contains(Jobtitle,'e')
      -                     )
      + $select=Name,Jobtitle; + $from=2012-03-01&$to=2025-01-01; + $filter=contains(Jobtitle,'e') + )

      results in one entity for each employee with time slices that overlap the specified application-time period and satisfy the filter condition (one less than in example 14):

      {
      -  "@odata.context": "$metadata#Employees",
      -  "value": [
      -    {
      -      "ID": "E314",
      -      "history": [
      -        {
      -          "Name": "McDevitt",
      -          "Jobtitle": "Senior",
      -          "From": "2013-10-01",
      -          "To": "2014-01-01"
      -        },
      -        {
      -          "Name": "McDevitt",
      -          "Jobtitle": "Senior",
      -          "From": "2014-01-01",
      -          "To": "9999-12-31"
      -        }
      -      ]
      -    },
      -    {
      -      "ID": "E401",
      -      "history": [
      -        {
      -          "Name": "Gibson",
      -          "Jobtitle": "Expert",
      -          "From": "2012-03-01",
      -          "To": "9999-12-31"
      -        }
      -      ]
      -    }
      -  ]
      +  "@odata.context": "$metadata#Employees",
      +  "value": [
      +    {
      +      "ID": "E314",
      +      "history": [
      +        {
      +          "Name": "McDevitt",
      +          "Jobtitle": "Senior",
      +          "From": "2013-10-01",
      +          "To": "2014-01-01"
      +        },
      +        {
      +          "Name": "McDevitt",
      +          "Jobtitle": "Senior",
      +          "From": "2014-01-01",
      +          "To": "9999-12-31"
      +        }
      +      ]
      +    },
      +    {
      +      "ID": "E401",
      +      "history": [
      +        {
      +          "Name": "Gibson",
      +          "Jobtitle": "Expert",
      +          "From": "2012-03-01",
      +          "To": "9999-12-31"
      +        }
      +      ]
      +    }
      +  ]
       }

      The lambda operators any() and all() are not influenced by temporal query options, they are interpreted for each time slice on the filtered collection, meaning “any related time slice satisfying the lambda expression” and “all related time slices satisfy the lambda expression”. The lambda expressions however can contain sub-expressions working on the period boundaries.

      Example 17: filter employees on their name at any point in time

      GET /api-2/Employees?$expand=history($select=Name,Jobtitle)
      -                    &$from=2015-01-01
      -                    &$filter=history/any(h:startswith(h/Name,'N'))
      + &$from=2015-01-01 + &$filter=history/any(h:startswith(h/Name,'N'))

      results in one employee whose name matches in the past, and the matching time slice is not in the requested time period

      {
      -  "@odata.context": "$metadata#Employees",
      -  "value": [
      -    {
      -      "ID": "E401",
      -      "history": [
      -        {
      -          "Name": "Gibson",
      -          "Jobtitle": "Expert",
      -          "From": "2012-03-01",
      -          "To": "9999-12-31"
      -        }
      -      ]
      -    }
      -  ]
      +  "@odata.context": "$metadata#Employees",
      +  "value": [
      +    {
      +      "ID": "E401",
      +      "history": [
      +        {
      +          "Name": "Gibson",
      +          "Jobtitle": "Expert",
      +          "From": "2012-03-01",
      +          "To": "9999-12-31"
      +        }
      +      ]
      +    }
      +  ]
       }

      4.2.5 Requesting Changes to Temporal Data

      @@ -1812,15 +1812,15 @@

      Content-Type: application/json { -  "deltaTimeslices": [ -    { -      "Timeslice": { -        "From": "2012-04-01", -        "To": "2014-07-01", -        "Budget": 1320 -      } -    } -  ] + "deltaTimeslices": [ + { + "Timeslice": { + "From": "2012-04-01", + "To": "2014-07-01", + "Budget": 1320 + } + } + ] }

      Given the example departments data the operation will split the time slice starting at 2012-01-01 creating a new time slice starting at 2012-04-01 which is then updated with the desired budget. It will then update the time slice starting at 2012-06-01 with the desired budget, and finally it will split the time slice starting at 2014-01-01 creating a new time slice starting at 2014-07-01, then update the original with the desired budget, leaving the new time slice starting at 2014-07-01 untouched:

      @@ -1897,54 +1897,54 @@

      {
      -  "@odata.context": "../../$metadata#Collection(Temporal.TimesliceWithPeriod)",
      -  "value": [
      -    {
      -      "Timeslice": {
      -        "@odata.context": "#Departments('D08')/history/$entity",
      -        "From": "2012-01-01",
      -        "To": "2012-04-01",
      -        "Name": "Support",
      -        "Budget": 1250
      -      }
      -    },
      -    {
      -      "Timeslice": {
      -        "@odata.context": "#Departments('D08')/history/$entity",
      -        "From": "2012-04-01",
      -        "To": "2012-06-01",
      -        "Name": "Support",
      -        "Budget": 1320
      -      }
      -    },
      -    {
      -      "Timeslice": {
      -        "@odata.context": "#Departments('D08')/history/$entity",
      -        "From": "2012-06-01",
      -        "To": "2014-01-01",
      -        "Name": "1st Level Support",
      -        "Budget": 1320
      -      }
      -    },
      -    {
      -      "Timeslice": {
      -        "@odata.context": "#Departments('D08')/history/$entity",
      -        "From": "2014-01-01",
      -        "To": "2014-07-01",
      -        "Name": "1st Level Support",
      -        "Budget": 1320
      -      }
      -    },
      -    {
      -      "Timeslice": {
      -        "@odata.context": "#Departments('D08')/history/$entity",
      -        "From": "2014-07-01",
      -        "To": "9999-12-31",
      -        "Name": "1st Level Support",
      -        "Budget": 1400
      -      }
      -    }
      -  ]
      +  "@odata.context": "../../$metadata#Collection(Temporal.TimesliceWithPeriod)",
      +  "value": [
      +    {
      +      "Timeslice": {
      +        "@odata.context": "#Departments('D08')/history/$entity",
      +        "From": "2012-01-01",
      +        "To": "2012-04-01",
      +        "Name": "Support",
      +        "Budget": 1250
      +      }
      +    },
      +    {
      +      "Timeslice": {
      +        "@odata.context": "#Departments('D08')/history/$entity",
      +        "From": "2012-04-01",
      +        "To": "2012-06-01",
      +        "Name": "Support",
      +        "Budget": 1320
      +      }
      +    },
      +    {
      +      "Timeslice": {
      +        "@odata.context": "#Departments('D08')/history/$entity",
      +        "From": "2012-06-01",
      +        "To": "2014-01-01",
      +        "Name": "1st Level Support",
      +        "Budget": 1320
      +      }
      +    },
      +    {
      +      "Timeslice": {
      +        "@odata.context": "#Departments('D08')/history/$entity",
      +        "From": "2014-01-01",
      +        "To": "2014-07-01",
      +        "Name": "1st Level Support",
      +        "Budget": 1320
      +      }
      +    },
      +    {
      +      "Timeslice": {
      +        "@odata.context": "#Departments('D08')/history/$entity",
      +        "From": "2014-07-01",
      +        "To": "9999-12-31",
      +        "Name": "1st Level Support",
      +        "Budget": 1400
      +      }
      +    }
      +  ]
       }

      The service could have joined the third and fourth time slice because they do not significantly differ.

      @@ -1952,17 +1952,17 @@

      api-1 (snapshot). Note that the period boundaries are not visible in api-1 and are provided as PeriodStart and PeriodEnd next to the Timeslice data. The PeriodEnd is omitted, meaning the end of application time.

      POST /api-1/Employees/Temporal.Update
       Content-Type: application/json
      - 
      +
       {
      -  "deltaTimeslices": [
      -    {
      -      "PeriodStart": "2021-10-01",
      -      "Timeslice": {
      -        "ID": "E401",
      -        "Jobtitle": "Ultimate Expert"
      -      }
      -    }
      -  ]
      +  "deltaTimeslices": [
      +    {
      +      "PeriodStart": "2021-10-01",
      +      "Timeslice": {
      +        "ID": "E401",
      +        "Jobtitle": "Ultimate Expert"
      +      }
      +    }
      +  ]
       }

      Given the example employee data the operation will split the time slice for employee E401 starting at 2012-03-01 creating a new time slice starting at 2021-10-01 which is then updated with the desired job title.

      4.3.2.2 Upsert during a Period

      @@ -2076,25 +2076,25 @@

      Content-Type: application/json { -  "deltaTimeslices": [ -    { -      "Timeslice": { -        "AreaID": "51", -        "CostCenterID": "C1", -        "ValidTo": "2001-03-31", -        "ValidFrom": "1984-04-01", -        "ProfitCenterID": "P2" -      } -    }, -    { -      "Timeslice": { -        "AreaID": "51", -        "CostCenterID": "C2", -        "ValidFrom": "2012-04-01", -        "DepartmentID": "D04" -      } -    } -  ] + "deltaTimeslices": [ + { + "Timeslice": { + "AreaID": "51", + "CostCenterID": "C1", + "ValidTo": "2001-03-31", + "ValidFrom": "1984-04-01", + "ProfitCenterID": "P2" + } + }, + { + "Timeslice": { + "AreaID": "51", + "CostCenterID": "C2", + "ValidFrom": "2012-04-01", + "DepartmentID": "D04" + } + } + ] }

      Given this example data (primary key in olive)

      @@ -2174,7 +2174,7 @@

      {
      -  "@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)",
      -  "value": [
      -    {
      -      "Timeslice": {
      -        "@odata.context": "#CostCenters/$entity",
      -        "tsid": "n",
      -        "AreaID": "51",
      -        "CostCenterID": "C1",
      -        "ValidTo": "1984-03-31",
      -        "ValidFrom": "1955-04-01",
      -        "ProfitCenterID": "P1",
      -        "DepartmentID": "D02"
      -      }
      -    },
      -    {
      -      "Timeslice": {
      -        "@odata.context": "#CostCenters/$entity",
      -        "tsid": "o",
      -        "AreaID": "51",
      -        "CostCenterID": "C1",
      -        "ValidTo": "2001-03-31",
      -        "ValidFrom": "1984-04-01",
      -        "ProfitCenterID": "P2",
      -        "DepartmentID": "D02"
      -      }
      -    },
      -    {
      -      "Timeslice": {
      -        "@odata.context": "#CostCenters/$entity",
      -        "tsid": "p",
      -        "AreaID": "51",
      -        "CostCenterID": "C1",
      -        "ValidTo": "9999-12-31",
      -        "ValidFrom": "2001-04-01",
      -        "ProfitCenterID": "P1",
      -        "DepartmentID": "D02"
      -      }
      -    },
      -    {
      -      "Timeslice": {
      -        "@odata.context": "#CostCenters/$entity",
      -        "tsid": "q",
      -        "AreaID": "51",
      -        "CostCenterID": "C2",
      -        "ValidTo": "9999-12-31",
      -        "ValidFrom": "2012-04-01",
      -        "ProfitCenterID": null,
      -        "DepartmentID": "D04"
      -      }
      -    }
      -  ]
      +  "@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)",
      +  "value": [
      +    {
      +      "Timeslice": {
      +        "@odata.context": "#CostCenters/$entity",
      +        "tsid": "n",
      +        "AreaID": "51",
      +        "CostCenterID": "C1",
      +        "ValidTo": "1984-03-31",
      +        "ValidFrom": "1955-04-01",
      +        "ProfitCenterID": "P1",
      +        "DepartmentID": "D02"
      +      }
      +    },
      +    {
      +      "Timeslice": {
      +        "@odata.context": "#CostCenters/$entity",
      +        "tsid": "o",
      +        "AreaID": "51",
      +        "CostCenterID": "C1",
      +        "ValidTo": "2001-03-31",
      +        "ValidFrom": "1984-04-01",
      +        "ProfitCenterID": "P2",
      +        "DepartmentID": "D02"
      +      }
      +    },
      +    {
      +      "Timeslice": {
      +        "@odata.context": "#CostCenters/$entity",
      +        "tsid": "p",
      +        "AreaID": "51",
      +        "CostCenterID": "C1",
      +        "ValidTo": "9999-12-31",
      +        "ValidFrom": "2001-04-01",
      +        "ProfitCenterID": "P1",
      +        "DepartmentID": "D02"
      +      }
      +    },
      +    {
      +      "Timeslice": {
      +        "@odata.context": "#CostCenters/$entity",
      +        "tsid": "q",
      +        "AreaID": "51",
      +        "CostCenterID": "C2",
      +        "ValidTo": "9999-12-31",
      +        "ValidFrom": "2012-04-01",
      +        "ProfitCenterID": null,
      +        "DepartmentID": "D04"
      +      }
      +    }
      +  ]
       }

      4.3.2.3 Delete during a Period

      @@ -2295,16 +2295,16 @@
      [RFC8174]

      Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017
      https://www.rfc-editor.org/info/rfc8174.

      A.2 Informative References

      -
      [Fowler]
      +
      [Fowler]

      Martin Fowler, “Temporal Patterns”, 16 February 2005
      http://martinfowler.com/eaaDev/timeNarrative.html.

      -
      [Kulkarni]
      +
      [Kulkarni]

      Krishna Kulkarni, “Temporal Features in SQL standard”, September 2012
      https://dbs.uni-leipzig.de/file/Temporal%20features%20in%20SQL2011.pdf.

      -
      [Snodgrass]
      +
      [Snodgrass]

      Richard T. Snodgrass, “Developing Time-Oriented Database Applications in SQL”, Morgan Kaufmann Publishers, Inc., San Francisco, July, 1999, ISBN 1-55860-436-7
      http://www2.cs.arizona.edu/people/rts/tdbbook.pdf and http://www2.cs.arizona.edu/people/rts/pp30-31.pdf.

      -
      [SQL:2011]
      +
      [SQL:2011]

      ISO/IEC 9075-2:2011 Information technology - Database languages - SQL - Part 2: Foundation (SQL/Foundation).


      Appendix B. Acknowledgments

      diff --git a/docs/odata-temporal-ext/odata-temporal-ext.md b/docs/odata-temporal-ext/odata-temporal-ext.md index b16755037..8878f5c90 100644 --- a/docs/odata-temporal-ext/odata-temporal-ext.md +++ b/docs/odata-temporal-ext/odata-temporal-ext.md @@ -210,7 +210,7 @@ that the object's values are not known to the service. ##### 1.2.1.4.1 Closed-Open Semantics -Time slices typically use closed-open semantics, following **[[SQL:2011]](#SQL)**. +Time slices typically use closed-open semantics, following [SQL:2011](#_SQL). This means the start is part of the period, the end is not part of the period, and for directly adjacent time slices the end of the earlier time slice is identical to the start of the next time slice. The period @@ -332,7 +332,7 @@ Keeping track of time is typically done by storing data together with the time period for which that data is deemed valid or effective, using separate periods for application time and system time, and the time periods are part of the logical key for "records". See -**[[SQL:2011]](#SQL)** or **[[Kulkarni]](#Kulkarni)** +[SQL:2011](#_SQL) or [Kulkarni](#_Kulkarni) on how this is done in the SQL standard. A consumer's perspective on this data can be different: even if time is @@ -1302,7 +1302,8 @@ structured type with the following properties: - If the period end property does not specify a default value, a default value of "ad infinitum" is assumed. - Records of type `TimelineVisible` MAY specify the property `ObjectKey`. - - `ObjectKey` is the "sub-key" or "alternate key" that identifies time slices for a single temporal object. It is only necessary if the annotated entity set can contain time slices + - `ObjectKey` is the "sub-key" or "alternate key" that identifies time slices for a single temporal object. + It is only necessary if the annotated entity set can contain time slices for more than one temporal object. The object key is a collection of property paths whose value combination uniquely identifies a temporal object. @@ -1316,16 +1317,16 @@ Example 6: `Employees` entity set from [example model `api-1`](#api1) annotated with temporal terms ```json "Employees": { -  "$Collection": true, -  "$Type": "OrgModel.Employee", -  "@Temporal.ApplicationTimeSupport": { -    "Timeline": { -      "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineSnapshot" -    }, -    "UnitOfTime": { -      "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate" -    } -  } + "$Collection": true, + "$Type": "OrgModel.Employee", + "@Temporal.ApplicationTimeSupport": { + "Timeline": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineSnapshot" + }, + "UnitOfTime": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate" + } + } }, ``` ::: @@ -1335,23 +1336,23 @@ Example 7: `history` navigation property in entity set `Employees` from [example model `api-2`](#api2) annotated with temporal terms ```json "$Annotations": { -  "OrgModel.Default/Employees/history": { -    "@Temporal.ApplicationTimeSupport": { -      "Timeline": { -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineVisible", -        "TimeSliceStart": "From", -        "TimeSliceEnd": "To", -        "SupportedActions": [ -          "Temporal.Update", -          "Temporal.Upsert", -          "Temporal.Delete" -        ] -      }, -      "UnitOfTime": { -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate" -      } -    } -  } + "OrgModel.Default/Employees/history": { + "@Temporal.ApplicationTimeSupport": { + "Timeline": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineVisible", + "TimeSliceStart": "From", + "TimeSliceEnd": "To", + "SupportedActions": [ + "Temporal.Update", + "Temporal.Upsert", + "Temporal.Delete" + ] + }, + "UnitOfTime": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate" + } + } + } } ``` ::: @@ -1362,42 +1363,42 @@ temporal objects, the temporal objects identified by combination of `AreaID` and `CostCenterID` ```json "CostCenter": { -  "$Kind": "EntityType", -  "$Key": ["tsid"], -  "tsid": {}, -  "AreaID": {}, -  "CostCenterID": {}, -  "ValidTo": { "$Type": "Edm.Date" }, -  "ValidFrom": { "$Type": "Edm.Date" }, -  "ProfitCenterID": { "$Nullable": true }, -  "DepartmentID": { "$Nullable": true } + "$Kind": "EntityType", + "$Key": ["tsid"], + "tsid": {}, + "AreaID": {}, + "CostCenterID": {}, + "ValidTo": { "$Type": "Edm.Date" }, + "ValidFrom": { "$Type": "Edm.Date" }, + "ProfitCenterID": { "$Nullable": true }, + "DepartmentID": { "$Nullable": true } }, "Default": { -  "$Kind": "EntityContainer", -  "CostCenters": { "$Collection": true, "$Type": "this.CostCenter" } + "$Kind": "EntityContainer", + "CostCenters": { "$Collection": true, "$Type": "this.CostCenter" } }, "$Annotations": { -  "this.Default/CostCenters": { -    "@Temporal.ApplicationTimeSupport": { -      "UnitOfTime": { -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.UnitOfTimeDate", -        "ClosedClosedPeriods": true -      }, -      "Timeline": { -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.TimelineVisible", -        "PeriodStart": "ValidFrom", -        "PeriodEnd": "ValidTo", -        "ObjectKey": ["AreaID", "CostCenterID"] -      }, -      "SupportedActions": [ -        "Temporal.Update", -        "Temporal.Upsert", -        "Temporal.Delete" -      ] -    } -  } + "this.Default/CostCenters": { + "@Temporal.ApplicationTimeSupport": { + "UnitOfTime": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.UnitOfTimeDate", + "ClosedClosedPeriods": true + }, + "Timeline": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.TimelineVisible", + "PeriodStart": "ValidFrom", + "PeriodEnd": "ValidTo", + "ObjectKey": ["AreaID", "CostCenterID"] + }, + "SupportedActions": [ + "Temporal.Update", + "Temporal.Upsert", + "Temporal.Delete" + ] + } + } } ``` ::: @@ -1510,10 +1511,10 @@ GET /api-1/Employees('E314') results in ```json { -  "@odata.context": "$metadata#Employees/$entity", -  "ID": "E314", -  "Name": "McDevitt", -  "Jobtitle": "Senior" + "@odata.context": "$metadata#Employees/$entity", + "ID": "E314", + "Name": "McDevitt", + "Jobtitle": "Senior" } ``` ::: @@ -1526,10 +1527,10 @@ GET /api-1/Employees('E314')?$at=2012-01-01 results in ```json { -  "@odata.context": "$metadata#Employees/$entity", -  "ID": "E314", -  "Name": "McDevitt", -  "Jobtitle": "Junior" + "@odata.context": "$metadata#Employees/$entity", + "ID": "E314", + "Name": "McDevitt", + "Jobtitle": "Junior" } ``` ::: @@ -1545,14 +1546,14 @@ specified point in time --- note that E401 back then does not satisfy this condition ```json { -  "@odata.context": "$metadata#Employees", -  "value": [ -    { -      "ID": "E314", -      "Name": "McDevitt", -      "Jobtitle": "Junior" -    } -  ] + "@odata.context": "$metadata#Employees", + "value": [ + { + "ID": "E314", + "Name": "McDevitt", + "Jobtitle": "Junior" + } + ] } ``` ::: @@ -1573,14 +1574,14 @@ GET /api-1/Employees('E314')?$at=2012-01-01&$expand=Department($at=2021-11-23) results in ```json { -  "@odata.context": "$metadata#Employees/$entity", -  "ID": "E314", -  "Name": "McDevitt", -  "Jobtitle": "Junior", -  "Department": { -    "ID": "D08", -    "Name": "1st Level Support" -  } + "@odata.context": "$metadata#Employees/$entity", + "ID": "E314", + "Name": "McDevitt", + "Jobtitle": "Junior", + "Department": { + "ID": "D08", + "Name": "1st Level Support" + } } ``` ::: @@ -1594,21 +1595,21 @@ GET /api-1/Departments('D15')?$at=2015-01-01&$expand=Employees results in ```json { -  "@odata.context": "$metadata#Departments/$entity", -  "ID": "D15", -  "Name": "Services", -  "Employees": [ -    { -      "ID": "E314", -      "Name": "McDevitt", -      "Jobtitle": "Senior" -    }, -    { -      "ID": "E401", -      "Name": "Gibson", -      "Jobtitle": "Expert" -    } -  ] + "@odata.context": "$metadata#Departments/$entity", + "ID": "D15", + "Name": "Services", + "Employees": [ + { + "ID": "E314", + "Name": "McDevitt", + "Jobtitle": "Senior" + }, + { + "ID": "E401", + "Name": "Gibson", + "Jobtitle": "Expert" + } + ] } ``` ::: @@ -1677,49 +1678,49 @@ application-time period boundaries as part of the default selection. Example 14: retrieve employee history over a period of application time ``` GET /api-2/Employees?$expand=history($select=Name,Jobtitle) -                    &$from=2012-03-01&$to=2025-01-01 + &$from=2012-03-01&$to=2025-01-01 ``` results in one entity for each employee with time slices that overlap the specified application-time period: ```json { -  "@odata.context": "$metadata#Employees", -  "value": [ -    { -      "ID": "E314", -      "history": [ -        { -          "Name": "McDevitt", -          "Jobtitle": "Junior", -          "From": "2011-01-01", -          "To": "2013-10-01" -        }, -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2013-10-01", -          "To": "2014-01-01" -        }, -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2014-01-01", -          "To": "9999-12-31" -        } -      ] -    }, -    { -      "ID": "E401", -      "history": [ -        { -          "Name": "Gibson", -          "Jobtitle": "Expert", -          "From": "2012-03-01", -          "To": "9999-12-31" -        } -      ] -    } -  ] + "@odata.context": "$metadata#Employees", + "value": [ + { + "ID": "E314", + "history": [ + { + "Name": "McDevitt", + "Jobtitle": "Junior", + "From": "2011-01-01", + "To": "2013-10-01" + }, + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2013-10-01", + "To": "2014-01-01" + }, + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2014-01-01", + "To": "9999-12-31" + } + ] + }, + { + "ID": "E401", + "history": [ + { + "Name": "Gibson", + "Jobtitle": "Expert", + "From": "2012-03-01", + "To": "9999-12-31" + } + ] + } + ] } ``` The history for the first employee contains two time slices that do not @@ -1735,100 +1736,100 @@ with their full history, and the department's data at the start of each employee history time slice ``` GET /api-2/Departments('D15')/Employees? -   $expand=history( + $expand=history( @emp=$this; -    $expand=Department( -       $expand=history($at=@emp/From) -     ) -  ) + $expand=Department( + $expand=history($at=@emp/From) + ) + ) ``` has the following result with department names and budgets as of the beginning of each employee time slice: ```json { -  "@odata.context": "$metadata#Employees", -  "value": [ -    { -      "ID": "E314", -      "history": [ -        { -          "Name": "McDevitt", -          "Jobtitle": "Junior", -          "From": "2011-01-01", -          "To": "2013-10-01", -          "Department": { -            "ID": "D08", -            "history": [{ -              "Name": "Support", -              "Budget": 1000, -              "From": "2010-01-01", -              "To": "2012-10-01" -            }] -          } -        }, -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2013-10-01", -          "To": "2014-01-01", -          "Department": { -            "ID": "D08", -            "history": [{ -              "Name": "1st Level Support", -              "Budget": 1250, -              "From": "2012-06-01", -              "To": "2014-01-01" -            }] -          } -        }, -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2014-01-01", -          "To": "9999-12-31", -          "Department": { -            "ID": "D15", -            "history": [{ -              "Name": "Services", -              "Budget": 1170, -              "From": "2011-01-01", -              "To": "9999-12-31" -            }] -          } -        } -      ] -    }, -    { -      "ID": "E401", -      "history": [ -        { -          "Name": "Norman", -          "Jobtitle": "Expert", -          "From": "2009-11-01", -          "To": "2012-03-01", -          "Department": { -            "ID": "D15", -            "history": [] -          } -        }, -        { -          "Name": "Gibson", -          "Jobtitle": "Expert", -          "From": "2012-03-01", -          "To": "9999-12-31", -          "Department": { -            "ID": "D15", -            "history": [{ -              "Name": "Services", -              "Budget": 1170, -              "From": "2011-01-01", -              "To": "9999-12-31" -            }] -          } -        } -      ] -    } -  ] + "@odata.context": "$metadata#Employees", + "value": [ + { + "ID": "E314", + "history": [ + { + "Name": "McDevitt", + "Jobtitle": "Junior", + "From": "2011-01-01", + "To": "2013-10-01", + "Department": { + "ID": "D08", + "history": [{ + "Name": "Support", + "Budget": 1000, + "From": "2010-01-01", + "To": "2012-10-01" + }] + } + }, + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2013-10-01", + "To": "2014-01-01", + "Department": { + "ID": "D08", + "history": [{ + "Name": "1st Level Support", + "Budget": 1250, + "From": "2012-06-01", + "To": "2014-01-01" + }] + } + }, + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2014-01-01", + "To": "9999-12-31", + "Department": { + "ID": "D15", + "history": [{ + "Name": "Services", + "Budget": 1170, + "From": "2011-01-01", + "To": "9999-12-31" + }] + } + } + ] + }, + { + "ID": "E401", + "history": [ + { + "Name": "Norman", + "Jobtitle": "Expert", + "From": "2009-11-01", + "To": "2012-03-01", + "Department": { + "ID": "D15", + "history": [] + } + }, + { + "Name": "Gibson", + "Jobtitle": "Expert", + "From": "2012-03-01", + "To": "9999-12-31", + "Department": { + "ID": "D15", + "history": [{ + "Name": "Services", + "Budget": 1170, + "From": "2011-01-01", + "To": "9999-12-31" + }] + } + } + ] + } + ] } ``` ::: @@ -1853,47 +1854,47 @@ Example 16: retrieve employee history over a period of application time and filter on job title ``` GET /api-2/Employees?$expand=history( -                       $select=Name,Jobtitle; -                       $from=2012-03-01&$to=2025-01-01; -                       $filter=contains(Jobtitle,'e') -                     ) + $select=Name,Jobtitle; + $from=2012-03-01&$to=2025-01-01; + $filter=contains(Jobtitle,'e') + ) ``` results in one entity for each employee with time slices that overlap the specified application-time period and satisfy the filter condition (one less than in [example 14](#employeeHistory)): ```json { -  "@odata.context": "$metadata#Employees", -  "value": [ -    { -      "ID": "E314", -      "history": [ -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2013-10-01", -          "To": "2014-01-01" -        }, -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2014-01-01", -          "To": "9999-12-31" -        } -      ] -    }, -    { -      "ID": "E401", -      "history": [ -        { -          "Name": "Gibson", -          "Jobtitle": "Expert", -          "From": "2012-03-01", -          "To": "9999-12-31" -        } -      ] -    } -  ] + "@odata.context": "$metadata#Employees", + "value": [ + { + "ID": "E314", + "history": [ + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2013-10-01", + "To": "2014-01-01" + }, + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2014-01-01", + "To": "9999-12-31" + } + ] + }, + { + "ID": "E401", + "history": [ + { + "Name": "Gibson", + "Jobtitle": "Expert", + "From": "2012-03-01", + "To": "9999-12-31" + } + ] + } + ] } ``` ::: @@ -1909,27 +1910,27 @@ the period boundaries. Example 17: filter employees on their name at any point in time ``` GET /api-2/Employees?$expand=history($select=Name,Jobtitle) -                    &$from=2015-01-01 -                    &$filter=history/any(h:startswith(h/Name,'N')) + &$from=2015-01-01 + &$filter=history/any(h:startswith(h/Name,'N')) ``` results in one employee whose name matches in the past, and the matching time slice is not in the requested time period ```json { -  "@odata.context": "$metadata#Employees", -  "value": [ -    { -      "ID": "E401", -      "history": [ -        { -          "Name": "Gibson", -          "Jobtitle": "Expert", -          "From": "2012-03-01", -          "To": "9999-12-31" -        } -      ] -    } -  ] + "@odata.context": "$metadata#Employees", + "value": [ + { + "ID": "E401", + "history": [ + { + "Name": "Gibson", + "Jobtitle": "Expert", + "From": "2012-03-01", + "To": "9999-12-31" + } + ] + } + ] } ``` ::: @@ -2074,15 +2075,15 @@ POST /api-2/Departments('D08')/history/Temporal.Update Content-Type: application/json { -  "deltaTimeslices": [ -    { -      "Timeslice": { -        "From": "2012-04-01", -        "To": "2014-07-01", -        "Budget": 1320 -      } -    } -  ] + "deltaTimeslices": [ + { + "Timeslice": { + "From": "2012-04-01", + "To": "2014-07-01", + "Budget": 1320 + } + } + ] } ``` Given the [example departments data](#ExampleData) @@ -2112,54 +2113,54 @@ D15 | 2011-01-01 | max | Services | 1170 It returns the resulting created or updated time slices ```json { -  "@odata.context": "../../$metadata#Collection(Temporal.TimesliceWithPeriod)", -  "value": [ -    { -      "Timeslice": { -        "@odata.context": "#Departments('D08')/history/$entity", -        "From": "2012-01-01", -        "To": "2012-04-01", -        "Name": "Support", -        "Budget": 1250 -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#Departments('D08')/history/$entity", -        "From": "2012-04-01", -        "To": "2012-06-01", -        "Name": "Support", -        "Budget": 1320 -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#Departments('D08')/history/$entity", -        "From": "2012-06-01", -        "To": "2014-01-01", -        "Name": "1st Level Support", -        "Budget": 1320 -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#Departments('D08')/history/$entity", -        "From": "2014-01-01", -        "To": "2014-07-01", -        "Name": "1st Level Support", -        "Budget": 1320 -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#Departments('D08')/history/$entity", -        "From": "2014-07-01", -        "To": "9999-12-31", -        "Name": "1st Level Support", -        "Budget": 1400 -      } -    } -  ] + "@odata.context": "../../$metadata#Collection(Temporal.TimesliceWithPeriod)", + "value": [ + { + "Timeslice": { + "@odata.context": "#Departments('D08')/history/$entity", + "From": "2012-01-01", + "To": "2012-04-01", + "Name": "Support", + "Budget": 1250 + } + }, + { + "Timeslice": { + "@odata.context": "#Departments('D08')/history/$entity", + "From": "2012-04-01", + "To": "2012-06-01", + "Name": "Support", + "Budget": 1320 + } + }, + { + "Timeslice": { + "@odata.context": "#Departments('D08')/history/$entity", + "From": "2012-06-01", + "To": "2014-01-01", + "Name": "1st Level Support", + "Budget": 1320 + } + }, + { + "Timeslice": { + "@odata.context": "#Departments('D08')/history/$entity", + "From": "2014-01-01", + "To": "2014-07-01", + "Name": "1st Level Support", + "Budget": 1320 + } + }, + { + "Timeslice": { + "@odata.context": "#Departments('D08')/history/$entity", + "From": "2014-07-01", + "To": "9999-12-31", + "Name": "1st Level Support", + "Budget": 1400 + } + } + ] } ``` The service could have joined the third and fourth time slice because @@ -2174,17 +2175,17 @@ application time with [`api-1`](#api1) (snapshot). Note that the period boundari ```json POST /api-1/Employees/Temporal.Update Content-Type: application/json -  + { -  "deltaTimeslices": [ -    { -      "PeriodStart": "2021-10-01", -      "Timeslice": { -        "ID": "E401", -        "Jobtitle": "Ultimate Expert" -      } -    } -  ] + "deltaTimeslices": [ + { + "PeriodStart": "2021-10-01", + "Timeslice": { + "ID": "E401", + "Jobtitle": "Ultimate Expert" + } + } + ] } ``` Given the [example employee data](#ExampleData) @@ -2208,29 +2209,29 @@ E401 | 2012-03-01 | *2021-10-01* | Gibson | Expert | D15 It returns the resulting created or updated time slices ```json { -  "@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)", -  "value": [ -    { -      "PeriodStart": "2012-03-01", -      "PeriodEnd": "2021-10-01", -      "Timeslice": { -        "@odata.context": "#Employees/$entity", -        "ID": "E401", -        "Name": "Gibson", -        "Jobtitle": "Expert" -      } -    }, -    { -      "PeriodStart": "2021-10-01", -      "PeriodEnd": "9999-12-31", -      "Timeslice": { -        "@odata.context": "#Employees/$entity", -        "ID": "E401", -        "Name": "Gibson", -        "Jobtitle": "Ultimate Expert" -      } -    } -  ] + "@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)", + "value": [ + { + "PeriodStart": "2012-03-01", + "PeriodEnd": "2021-10-01", + "Timeslice": { + "@odata.context": "#Employees/$entity", + "ID": "E401", + "Name": "Gibson", + "Jobtitle": "Expert" + } + }, + { + "PeriodStart": "2021-10-01", + "PeriodEnd": "9999-12-31", + "Timeslice": { + "@odata.context": "#Employees/$entity", + "ID": "E401", + "Name": "Gibson", + "Jobtitle": "Ultimate Expert" + } + } + ] } ``` ::: @@ -2268,25 +2269,25 @@ POST /api-3/CostCenters/Temporal.Upsert Content-Type: application/json { -  "deltaTimeslices": [ -    { -      "Timeslice": { -        "AreaID": "51", -        "CostCenterID": "C1", -        "ValidTo": "2001-03-31", -        "ValidFrom": "1984-04-01", -        "ProfitCenterID": "P2" -      } -    }, -    { -      "Timeslice": { -        "AreaID": "51", -        "CostCenterID": "C2", -        "ValidFrom": "2012-04-01", -        "DepartmentID": "D04" -      } -    } -  ] + "deltaTimeslices": [ + { + "Timeslice": { + "AreaID": "51", + "CostCenterID": "C1", + "ValidTo": "2001-03-31", + "ValidFrom": "1984-04-01", + "ProfitCenterID": "P2" + } + }, + { + "Timeslice": { + "AreaID": "51", + "CostCenterID": "C2", + "ValidFrom": "2012-04-01", + "DepartmentID": "D04" + } + } + ] } ``` Given this example data (primary key in olive) @@ -2316,63 +2317,63 @@ tsid | AreaID | CostCenterID | ValidTo | ValidFrom | ProfitCenterID | De n | 51 | C1 | *1984-03-31* | 1955-04-01 | P1 | D02 *o* | *51* | *C1* | *2001-03-31* | *1984-04-01* | *P2* | *D02* *p* | *51* | *C1* | *max* | *2001-04-01* | *P1* | *D02* -*q* | *51* | *C2* | *max* | *2012-04-01* |   | *D04* +*q* | *51* | *C2* | *max* | *2012-04-01* | | *D04* :::: It returns the resulting created or updated time slices per affected temporal object ```json { -  "@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)", -  "value": [ -    { -      "Timeslice": { -        "@odata.context": "#CostCenters/$entity", -        "tsid": "n", -        "AreaID": "51", -        "CostCenterID": "C1", -        "ValidTo": "1984-03-31", -        "ValidFrom": "1955-04-01", -        "ProfitCenterID": "P1", -        "DepartmentID": "D02" -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#CostCenters/$entity", -        "tsid": "o", -        "AreaID": "51", -        "CostCenterID": "C1", -        "ValidTo": "2001-03-31", -        "ValidFrom": "1984-04-01", -        "ProfitCenterID": "P2", -        "DepartmentID": "D02" -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#CostCenters/$entity", -        "tsid": "p", -        "AreaID": "51", -        "CostCenterID": "C1", -        "ValidTo": "9999-12-31", -        "ValidFrom": "2001-04-01", -        "ProfitCenterID": "P1", -        "DepartmentID": "D02" -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#CostCenters/$entity", -        "tsid": "q", -        "AreaID": "51", -        "CostCenterID": "C2", -        "ValidTo": "9999-12-31", -        "ValidFrom": "2012-04-01", -        "ProfitCenterID": null, -        "DepartmentID": "D04" -      } -    } -  ] + "@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)", + "value": [ + { + "Timeslice": { + "@odata.context": "#CostCenters/$entity", + "tsid": "n", + "AreaID": "51", + "CostCenterID": "C1", + "ValidTo": "1984-03-31", + "ValidFrom": "1955-04-01", + "ProfitCenterID": "P1", + "DepartmentID": "D02" + } + }, + { + "Timeslice": { + "@odata.context": "#CostCenters/$entity", + "tsid": "o", + "AreaID": "51", + "CostCenterID": "C1", + "ValidTo": "2001-03-31", + "ValidFrom": "1984-04-01", + "ProfitCenterID": "P2", + "DepartmentID": "D02" + } + }, + { + "Timeslice": { + "@odata.context": "#CostCenters/$entity", + "tsid": "p", + "AreaID": "51", + "CostCenterID": "C1", + "ValidTo": "9999-12-31", + "ValidFrom": "2001-04-01", + "ProfitCenterID": "P1", + "DepartmentID": "D02" + } + }, + { + "Timeslice": { + "@odata.context": "#CostCenters/$entity", + "tsid": "q", + "AreaID": "51", + "CostCenterID": "C2", + "ValidTo": "9999-12-31", + "ValidFrom": "2012-04-01", + "ProfitCenterID": null, + "DepartmentID": "D04" + } + } + ] } ``` ::: @@ -2390,7 +2391,7 @@ the period end of type `Edm.Date` is the last day in the period or the first day after the period. This works identical to the SQL statement DELETE FOR PORTION OF: - + 1. The "delta time slices" in `deltaTimeslices` are processed in the order of the collection. 2. For each delta time slice all time slices from the bound collection @@ -2494,21 +2495,22 @@ https://www.rfc-editor.org/info/rfc2119. _Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017_ https://www.rfc-editor.org/info/rfc8174. -## A.2 Informative References -###### [Fowler] +## A.2 Informative References + +###### [Fowler] _Martin Fowler, "Temporal Patterns", 16 February 2005_ http://martinfowler.com/eaaDev/timeNarrative.html. -###### [Kulkarni] +###### [Kulkarni] _Krishna Kulkarni, "Temporal Features in SQL standard", September 2012_ https://dbs.uni-leipzig.de/file/Temporal%20features%20in%20SQL2011.pdf. -###### [Snodgrass] +###### [Snodgrass] _Richard T. Snodgrass, "Developing Time-Oriented Database Applications in SQL", Morgan Kaufmann Publishers, Inc., San Francisco, July, 1999, ISBN 1-55860-436-7_ http://www2.cs.arizona.edu/people/rts/tdbbook.pdf and http://www2.cs.arizona.edu/people/rts/pp30-31.pdf. -###### [SQL:2011] +###### [SQL:2011] _ISO/IEC 9075-2:2011 Information technology - Database languages - SQL - Part 2: Foundation (SQL/Foundation)_. ------- diff --git a/docs/odata-url-conventions/odata-url-conventions.html b/docs/odata-url-conventions/odata-url-conventions.html index acc533eb6..cd6f79f42 100644 --- a/docs/odata-url-conventions/odata-url-conventions.html +++ b/docs/odata-url-conventions/odata-url-conventions.html @@ -1176,7 +1176,7 @@

      5.1.1.7.1 matchespattern

      The matchespattern function has the following signature:

      Edm.Boolean matchespattern(Edm.String,Edm.String)
      -

      The second parameter MUST evaluate to a string containing an [ECMAScript] (JavaScript) regular expression. The matchespattern function returns true if the first parameter evaluates to a string matching that regular expression, using syntax and semantics of [ECMAScript] regular expressions, otherwise it returns false.

      +

      The second parameter MUST evaluate to a string containing an matchespattern function returns true if the first parameter evaluates to a string matching that regular expression, using syntax and semantics of ECMAScript regular expressions, otherwise it returns false.

      Example 81: all customers with a CompanyName that match the (percent-encoded) regular expression ^A.*e$

      http://host/service/Customers?$filter=matchespattern(CompanyName,'%5EA.*e$')
      @@ -1946,7 +1946,7 @@
      [XML-Schema-2]

      W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes. D. Peterson, S. Gao, C. M. Sperberg-McQueen, H. S. Thompson, P. V. Biron, A. Malhotra, Editors, W3C Recommendation, 5 April 2012.
      http://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/. Latest version available at http://www.w3.org/TR/xmlschema11-2/.

      A.2 Informative References

      -
      [ECMAScript]
      +
      [ECMAScript]

      ECMAScript 2023 Language Specification, 14th Edition, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.


      Appendix B. Safety, Security and Privacy Considerations

      diff --git a/docs/odata-url-conventions/odata-url-conventions.md b/docs/odata-url-conventions/odata-url-conventions.md index dfd77bfa7..30f9ed101 100644 --- a/docs/odata-url-conventions/odata-url-conventions.md +++ b/docs/odata-url-conventions/odata-url-conventions.md @@ -385,7 +385,8 @@ that the rules in [OData-ABNF](#ODataABNF) assume that URLs and URL parts have been percent-encoding normalized as described in [section 6.2.2.2](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.2) of [RFC3986](#rfc3986) before applying the grammar to them, i.e. -all characters in the unreserved set (see rule `unreserved` in [OData-ABNF](#ODataABNF)) are plain literals and not percent-encoded. +all characters in the unreserved set (see rule `unreserved` in +[OData-ABNF](#ODataABNF)) are plain literals and not percent-encoded. For characters outside of the unreserved set that are significant to OData the ABNF rules explicitly state whether the percent-encoded representation is treated identical to the plain literal representation. @@ -1047,7 +1048,8 @@ by `$top`, `$skip`, `$orderby`, or `$expand`. The count is calculated after applying any [`/$filter`](#AddressingaSubsetofaCollection) path segments, or -[`$filter`](#SystemQueryOptionfilter) or [`$search`](#SystemQueryOptionsearch) system query options to the collection. +[`$filter`](#SystemQueryOptionfilter) or +[`$search`](#SystemQueryOptionsearch) system query options to the collection. ::: example Example 30: the number of related entities @@ -1783,7 +1785,9 @@ lower case operator names. The `add` operator adds the left and right numeric operands. -For operands of type `Edm.Decimal` the scale of the result is ${\rm scaleof}(A {\ \tt add\ } B) = \max({\rm scaleof}(A), {\rm scaleof}(B))$, or `variable` if any operand has variable scale. +For operands of type `Edm.Decimal` the scale of the result is +${\rm scaleof}(A {\ \tt add\ } B) = \max({\rm scaleof}(A), {\rm scaleof}(B))$, +or `variable` if any operand has variable scale. The `add` operator is also valid for the following time-related operands: @@ -1808,7 +1812,8 @@ today minus a positive duration smaller than one day is yesterday. The `sub` operator subtracts the right numeric operand from the left numeric operand. -For operands of type `Edm.Decimal` the scale of the result is ${\rm scaleof}(A {\ \tt sub\ } B) = \max({\rm scaleof}(A), {\rm scaleof}(B))$, +For operands of type `Edm.Decimal` the scale of the result is +${\rm scaleof}(A {\ \tt sub\ } B) = \max({\rm scaleof}(A), {\rm scaleof}(B))$, or `variable` if any operand has variable scale. The `sub` operator is also valid for the following time-related @@ -2316,10 +2321,9 @@ Edm.Boolean matchespattern(Edm.String,Edm.String) ``` The second parameter MUST evaluate to a string containing an -[**[ECMAScript]**](#ECMAScript) (JavaScript) regular expression. The `matchespattern` function returns true if the first parameter evaluates to a string matching that regular expression, using syntax and semantics -of [**[ECMAScript]**](#ECMAScript) regular expressions, otherwise it +of [ECMAScript](#_ECMAScript) regular expressions, otherwise it returns false. ::: example @@ -3433,15 +3437,18 @@ A path MUST NOT appear in more than one expand item. Query options can be applied to an expanded navigation property by appending a semicolon-separated list of query options, enclosed in -parentheses, to the navigation property name. Allowed system query options are +parentheses, to the navigation property name. +Allowed system query options are [`$compute`](#SystemQueryOptioncompute), [`$select`](#SystemQueryOptionselect), -`$expand`, and [`$levels`](#ExpandOptionlevels) for all navigation properties, plus +`$expand`, and +[`$levels`](#ExpandOptionlevels) for all navigation properties, plus [`$filter`](#SystemQueryOptionfilter), [`$orderby`](#SystemQueryOptionorderby), [`$skip`](#SystemQueryOptionstopandskip), [`$top`](#SystemQueryOptionstopandskip), [`$count`](#SystemQueryOptioncount), and -[`$search`](#SystemQueryOptionsearch) for collection-valued navigation properties. +[`$search`](#SystemQueryOptionsearch) +for collection-valued navigation properties. ::: example Example 117: all categories and for each category all related products @@ -3613,7 +3620,8 @@ The `$select` system query option is interpreted relative to the entity type or complex type of the resources identified by the resource path section of the URL. Each select item in the `$select` clause indicates that the response MUST include the declared or dynamic properties, -actions and functions identified by that select item. If a select item is a path expression traversing an entity or complex property that is `null` on an instance, then +actions and functions identified by that select item. +If a select item is a path expression traversing an entity or complex property that is `null` on an instance, then the null-valued entity or complex property is included and represented as `null`. The simplest form of a select item explicitly requests a property defined on the entity type of the resources identified by the resource path section of the URL. @@ -4035,8 +4043,9 @@ http://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/. Latest version available ## A.2 Informative References -###### [ECMAScript] -_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/. +###### [ECMAScript] +_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. +https://www.ecma-international.org/publications-and-standards/standards/ecma-262/. ------- diff --git a/odata-csdl/1 Introduction.md b/odata-csdl/1 Introduction.md index 4705b36bb..3c3eb9088 100644 --- a/odata-csdl/1 Introduction.md +++ b/odata-csdl/1 Introduction.md @@ -498,8 +498,8 @@ responses. The facets in the following subsections modify or constrain the acceptable values of primitive typed model elements, for example a [structural property](#StructuralProperty), -action or function [parameter](#Parameter), -action or function [return type](#ReturnType), or +action or function [parameter](#Parameter), +action or function [return type](#ReturnType), or [term](#Term). For single-valued model elements the facets apply to the value of the diff --git a/odata-csdl/14 Vocabulary and Annotation.md b/odata-csdl/14 Vocabulary and Annotation.md index e324b9c6b..861733ec9 100644 --- a/odata-csdl/14 Vocabulary and Annotation.md +++ b/odata-csdl/14 Vocabulary and Annotation.md @@ -3115,7 +3115,7 @@ Example ##ex: "$Function": "odata.fillUriTemplate" } }, - + "@Core.LongDescription#element": { "$UrlRef": "http://host/wiki/HowToUse" } diff --git a/odata-csdl/Appendix.md b/odata-csdl/Appendix.md index 330e2570c..d73c00fd8 100644 --- a/odata-csdl/Appendix.md +++ b/odata-csdl/Appendix.md @@ -111,7 +111,7 @@ http://www.w3.org/TR/2008/REC-xml-20081126/. Latest version available at http:// ###### [XML-Base] _XML Base (Second Edition)_. J. Marsh, R. Tobin, Editors, W3C Recommendation, 28 January 2009. -http://www.w3.org/TR/2009/REC-xmlbase-20090128/. Latest version available at http://www.w3.org/TR/xmlbase/. +http://www.w3.org/TR/2009/REC-xmlbase-20090128/. Latest version available at http://www.w3.org/TR/xmlbase/. ###### [XML-Schema-1] _W3C XML Schema Definition Language (XSD) 1.1 Part 1: Structures_. D. Beech, M. Maloney, C. M. Sperberg-McQueen, H. S. Thompson, S. Gao, N. Mendelsohn, Editors, W3C Recommendation, 5 April 2012. diff --git a/odata-json-format/10 Media Entity.md b/odata-json-format/10 Media Entity.md index ebdd4f23c..028949238 100644 --- a/odata-json-format/10 Media Entity.md +++ b/odata-json-format/10 Media Entity.md @@ -5,12 +5,12 @@ Media entities are entities that describe a media resource, for example a photo. They are represented as entities that contain additional -[`media*`](#ControlInformationmediaodatamedia) control information. +[`media*`](#ControlInformationmediaodatamedia) control information. If the actual stream data for the media entity is included, it is represented as property named `$value` whose string value is the base64url-encoded value of the media stream, see [RFC4648](rfc4648). - + ::: example Example ##ex: ```json @@ -49,7 +49,7 @@ represented as an object with a single name/value pair whose name is `value`. Its value is the JSON representation of a [collection of complex type values](#CollectionofComplexValues) or [collection of primitive values](#CollectionofPrimitiveValues). - + ::: example Example ##ex: primitive value ```json @@ -59,7 +59,7 @@ Example ##ex: primitive value } ``` ::: - + ::: example Example ##ex: collection of primitive values ```json @@ -69,7 +69,7 @@ Example ##ex: collection of primitive values } ``` ::: - + ::: example Example ##ex: empty collection of primitive values ```json @@ -79,7 +79,7 @@ Example ##ex: empty collection of primitive values } ``` ::: - + ::: example Example ##ex: complex value ```json @@ -93,7 +93,7 @@ Example ##ex: complex value } ``` ::: - + ::: example Example ##ex: empty collection of complex values ```json @@ -201,7 +201,7 @@ entity and MAY contain the [`type`](#ControlInformationtypeodatatype) control information and [instance annotations](#InstanceAnnotations), but no additional properties or control information. -A collection of entity references is represented as a [collection of entities](#CollectionofEntities), +A collection of entity references is represented as a [collection of entities](#CollectionofEntities), with entity reference representations instead of entity representations as items in the array value of the `value` name/value pair. The outermost JSON object in a response MUST contain a @@ -210,7 +210,7 @@ control information and MAY contain [`count`](#ControlInformationcountodatacount), [`nextLink`](#ControlInformationnextLinkodatanextLink), or [`deltaLink`](#ControlInformationdeltaLinkodatadeltaLink) control information. - + ::: example Example ##ex: entity reference to order 10643 ```json @@ -220,7 +220,7 @@ Example ##ex: entity reference to order 10643 } ``` ::: - + ::: example Example ##ex: collection of entity references ```json diff --git a/odata-json-format/16 Bound Function.md b/odata-json-format/16 Bound Function.md index 73e0a2ed7..e1aa7cbd0 100644 --- a/odata-json-format/16 Bound Function.md +++ b/odata-json-format/16 Bound Function.md @@ -59,7 +59,7 @@ title as a string. If [`metadata=minimal`](#metadataminimalodatametadataminimal) is requested, the `target` name/value pair MUST be included if its value differs from the canonical function or action URL. - + ::: example Example ##ex: minimal representation of a function where all overloads are applicable @@ -71,7 +71,7 @@ applicable } ``` ::: - + ::: example Example ##ex: full representation of a specific overload with parameter alias for the `Year` parameter @@ -86,7 +86,7 @@ alias for the `Year` parameter } ``` ::: - + ::: example Example ##ex: full representation in a collection ```json @@ -163,7 +163,7 @@ title as a string. If [`metadata=minimal`](#metadataminimalodatametadataminimal) is requested, the `target` name/value pair MUST be included if its value differs from the canonical function or action URL. - + ::: example Example ##ex: minimal representation in an entity ```json @@ -174,7 +174,7 @@ Example ##ex: minimal representation in an entity } ``` ::: - + ::: example Example ##ex: full representation in an entity: ```json @@ -188,7 +188,7 @@ Example ##ex: full representation in an entity: } ``` ::: - + ::: example Example ##ex: full representation in a collection ```json diff --git a/odata-json-format/19 Batch Requests and Responses.md b/odata-json-format/19 Batch Requests and Responses.md index fadc49519..c5d6bf97f 100644 --- a/odata-json-format/19 Batch Requests and Responses.md +++ b/odata-json-format/19 Batch Requests and Responses.md @@ -123,7 +123,7 @@ A `body` MUST NOT be specified if the `method` is `get` or `delete`. The request object and the `headers` object MUST NOT contain name/value pairs with duplicate names. This is in conformance with [RFC7493](#rfc7493). - + ::: example Example ##ex_batchRequest: a batch request that contains the following individual requests in the order listed @@ -186,7 +186,7 @@ The entity returned by a preceding request can be referenced in the request URL of subsequent requests. If the `Location` header in the response contains a relative URL, clients MUST be able to resolve it relative to the request's URL even if that contains such a reference. - + ::: example Example ##ex: a batch request that contains the following operations in the order listed: @@ -328,7 +328,7 @@ same value. If any response within an atomicity group returns a failure code, all requests within that atomicity group are considered failed, regardless -of their individual returned status code. The service MAY return +of their individual returned status code. The service MAY return `424 Failed Dependency` for statements within an atomicity group that fail or are not attempted due to other failures within the same atomicity group. @@ -354,7 +354,7 @@ Relative URLs in a response object follow the rules for [relative URLs](#RelativeURLs) based on the request URL of the corresponding request. Especially: URLs in responses MUST NOT contain `$`-prefixed request identifiers. - + ::: example Example ##ex: referencing the batch request [example ##batchRequest] above, assume all the requests except the final query request succeed. In this case the @@ -412,7 +412,7 @@ control information in the JSON batch response, thus signaling that the response is only a partial result. A subsequent `GET` request to the next link MAY result in a `202 Accepted` response with a `location` header pointing to a new status monitor resource. - + ::: example Example ##ex: referencing the example 47 above again, assume that the request is sent with the `respond-async` preference. This @@ -502,7 +502,7 @@ the service responds with a JSON batch response. In this case the asynchronously executed individual request with a `status` of `202`, a `location` header pointing to an individual status monitor resource, and optionally a `retry-after` header. - + ::: example Example ##ex: the first individual request is processed asynchronously, the second synchronously, the batch itself is processed synchronously @@ -528,4 +528,4 @@ Content-Type: application/json ] } ``` -::: +::: diff --git a/odata-json-format/20 Instance Annotations.md b/odata-json-format/20 Instance Annotations.md index 14f626902..400e16f98 100644 --- a/odata-json-format/20 Instance Annotations.md +++ b/odata-json-format/20 Instance Annotations.md @@ -143,7 +143,7 @@ concerns around information disclosure. Error responses MAY contain [annotations](#InstanceAnnotations) in any of its JSON objects. - + ::: example Example ##ex: ```json @@ -192,7 +192,7 @@ header-appropriate way: Unicode characters beyond `00FF` within JSON strings are encoded as `\uXXXX` or `\uXXXX\uXXXX` (see [RFC8259](#rfc8259), section 7) - + ::: example Example ##ex: note that this is one HTTP header line without any line breaks or optional whitespace diff --git a/odata-json-format/23 Conformance.md b/odata-json-format/23 Conformance.md index 0aa7da393..54d38d714 100644 --- a/odata-json-format/23 Conformance.md +++ b/odata-json-format/23 Conformance.md @@ -6,7 +6,7 @@ Conforming clients MUST be prepared to consume a service that uses any or all of the constructs defined in this specification. The exception to this are the constructs defined in Delta Response, which are only required for clients that request changes. - + In order to be a conforming consumer of the OData JSON format, a client or service: 1. MUST either: diff --git a/odata-json-format/3 Requesting the JSON Format.md b/odata-json-format/3 Requesting the JSON Format.md index 8677b1f3c..e2f380f22 100644 --- a/odata-json-format/3 Requesting the JSON Format.md +++ b/odata-json-format/3 Requesting the JSON Format.md @@ -193,7 +193,7 @@ If not specified, or specified as `IEEE754Compatible=false`, all numbers MUST be serialized as JSON numbers. This enables support for JavaScript numbers that are defined to be -64-bit binary format IEEE 754 values (see **[[ECMAScript](#ECMAScript), [section 4.3.1.9](http://www.ecma-international.org/ecma-262/5.1/#sec-4.3.19)]**) +64-bit binary format IEEE 754 values (see [ECMAScript](#_ECMAScript), [section 4.3.1.9](http://www.ecma-international.org/ecma-262/5.1/#sec-4.3.19)) resulting in integers losing precision past 15 digits, and decimals losing precision due to the conversion from base 10 to base 2. diff --git a/odata-json-format/4 Common Characteristics.md b/odata-json-format/4 Common Characteristics.md index ce6360b4a..b591c2d2f 100644 --- a/odata-json-format/4 Common Characteristics.md +++ b/odata-json-format/4 Common Characteristics.md @@ -29,7 +29,7 @@ parameter if `Edm.Int64` and `Edm.Decimal` numbers are represented as strings. Requests and responses MAY add the `streaming` parameter with -a value of `true` or `false`, see section +a value of `true` or `false`, see section "[Payload Ordering Constraints](#PayloadOrderingConstraints)". ## ##subsec Message Body diff --git a/odata-json-format/5 Service Document.md b/odata-json-format/5 Service Document.md index 09ab16a27..6140d0505 100644 --- a/odata-json-format/5 Service Document.md +++ b/odata-json-format/5 Service Document.md @@ -50,7 +50,7 @@ Service documents MAY contain [annotations](#InstanceAnnotations) in any of its JSON objects. Services MUST NOT produce name/value pairs other than the ones explicitly defined in this section, and clients MUST ignore unknown name/value pairs. - + ::: example Example ##ex: ```json @@ -112,7 +112,7 @@ An entity representation can be (modified and) round-tripped to the service directly. The [context URL](#ControlInformationcontextodatacontext) is used in requests only as a base for [relative URLs](#RelativeURLs). - + ::: example Example ##ex: entity with `metadata=minimal` ```json diff --git a/odata-json-format/7 Structural Property.md b/odata-json-format/7 Structural Property.md index 4e88b435b..691e5069c 100644 --- a/odata-json-format/7 Structural Property.md +++ b/odata-json-format/7 Structural Property.md @@ -5,7 +5,7 @@ A property within an entity or complex type instance is represented as a name/value pair. The name MUST be the name of the property; a non-null value is -represented depending on its type as a [primitive value](#PrimitiveValue), +represented depending on its type as a [primitive value](#PrimitiveValue), a [complex value](#ComplexValue), a [collection of primitive values](#CollectionofPrimitiveValues), or a [collection of complex values](#CollectionofComplexValues). @@ -31,7 +31,7 @@ Values of type `Edm.String` are represented as JSON strings, using the JSON string escaping rules. Values of type `Edm.Binary`, `Edm.Date`, -`Edm.DateTimeOffset`, `Edm.Duration`, +`Edm.DateTimeOffset`, `Edm.Duration`, `Edm.Guid`, and `Edm.TimeOfDay` are represented as JSON strings whose content satisfies the rules `binaryValue`, `dateValue`, `dateTimeOffsetValue`, @@ -61,7 +61,7 @@ payload. Whether the value represents a geography type or geometry type is inferred from its usage or specified using the [`type`](#ControlInformationtypeodatatype) control information. - + ::: example Example ##ex: ```json @@ -94,7 +94,7 @@ name/value pair for each property that makes up the complex type. Each property value is formatted as appropriate for the type of the property. It MAY have name/value pairs for [instance annotations](#InstanceAnnotations) and control information. - + ::: example Example ##ex: ```json @@ -122,7 +122,7 @@ element in the array is the representation of a [primitive value](#PrimitiveValue). A JSON literal `null` represents a null value within the collection. An empty collection is represented as an empty array. - + ::: example Example ##ex: partial collection of strings with next link ```json @@ -147,7 +147,7 @@ depending on the JavaScript type. A collection of complex values is represented as a JSON array; each element in the array is the representation of a [complex value](#ComplexValue). A JSON literal `null` represents a null value within the collection. An empty collection is represented as an empty array. - + ::: example Example ##ex: partial collection of complex values with next link ```json @@ -215,7 +215,7 @@ client requests `metadata=full` or the navigation link cannot be computed, e.g. if it is within a collection of complex type instances. If it is represented it MUST immediately precede the expanded navigation property if the latter is represented. - + ::: example Example ##ex: ```json @@ -242,7 +242,7 @@ cannot be computed by appending `/$ref` to the navigation link. If it is represented, it MUST immediately precede the navigation link if the latter is represented, otherwise it MUST immediately precede the expanded navigation property if it is represented. - + ::: example Example ##ex: ```json @@ -276,7 +276,7 @@ represented as an empty JSON array. The navigation property MAY include [`nextLink`](#ControlInformationnextLinkodatanextLink) control information. If a navigation property is expanded with the suffix `/$count`, only the [`count`](#ControlInformationcountodatacount) control information is represented. - + ::: example Example ##ex: ```json @@ -298,7 +298,7 @@ new entities MAY be specified using the same representation as for an Deep inserts are not allowed in update operations using `PUT` or `PATCH` requests. - + ::: example Example ##ex: inserting a new order for a new customer with order items related to existing products: @@ -339,7 +339,7 @@ the navigation property it belongs to and has a single value for single-valued navigation properties or an array of values for collection navigation properties. For nullable single-valued navigation properties the value `null` may be used to remove the relationship. - + ::: example Example ##ex: assign an existing product to an existing category with a partial update request against the product @@ -360,7 +360,7 @@ For requests containing an `OData-Version` header with a value of `4.01`, a relationship is bound to an existing entity using the same representation as for an [expanded entity reference](#EntityReference). - + ::: example Example ##ex: assign an existing product to an existing category with a partial update request against the product @@ -373,7 +373,7 @@ Content-Type: application/json } ``` ::: - + ::: example Example ##ex: submit a partial update request to: - modify the name of an existing category @@ -408,7 +408,7 @@ Content-Type: application/json OData 4.01 services MUST support both the OData 4.0 representation, for requests containing an `OData-Version` header with a value of `4.0`, and the OData 4.01 representation, for requests -containing an `OData-Version` header with a value of `4.01`. +containing an `OData-Version` header with a value of `4.01`. Clients MUST NOT use `@odata.bind` in requests with an `OData-Version` header with a value of `4.01`. @@ -430,7 +430,7 @@ that can be used in a subsequent request to determine if the collection has changed. Services MAY include this control information as appropriate. - + ::: example Example ##ex: ETag for a collection of related entities ```json @@ -483,7 +483,7 @@ If the included stream property has no value, the non-existing stream data is represented as `null` and the control information [`mediaContentType`](#ControlInformationmediaodatamedia) is not necessary. - + ::: example Example ##ex: ```json diff --git a/odata-json-format/Appendix.md b/odata-json-format/Appendix.md index 6d50ee3a9..754579e6e 100644 --- a/odata-json-format/Appendix.md +++ b/odata-json-format/Appendix.md @@ -74,10 +74,10 @@ https://www.rfc-editor.org/info/rfc8174. _Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017_. https://www.rfc-editor.org/info/rfc8259. -## ##subasec Informative References +## ##subasec Informative References -###### [ECMAScript] -_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. +###### [ECMAScript] +_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/. ------- diff --git a/odata-protocol/10 Context URL.md b/odata-protocol/10 Context URL.md index d24e0f61a..2453daedb 100644 --- a/odata-protocol/10 Context URL.md +++ b/odata-protocol/10 Context URL.md @@ -344,9 +344,9 @@ Example ##ex: resource URL and corresponding context URL --- expand with `$levels` ``` http://host/service/Employees/Sales.Manager?$select=DirectReports -        &$expand=DirectReports($select=FirstName,LastName;$levels=4) + &$expand=DirectReports($select=FirstName,LastName;$levels=4) http://host/service/$metadata -        #Employees/Sales.Manager(DirectReports,DirectReports+(FirstName,LastName)) + #Employees/Sales.Manager(DirectReports,DirectReports+(FirstName,LastName)) ``` ::: @@ -386,9 +386,9 @@ the context URL. Example ##ex: resource URL and corresponding context URL ``` http://host/service/Employees(1)/Sales.Manager? -    $expand=DirectReports($select=FirstName,LastName;$levels=4) + $expand=DirectReports($select=FirstName,LastName;$levels=4) http://host/service/$metadata -       #Employees/Sales.Manager(DirectReports+(FirstName,LastName))/$entity + #Employees/Sales.Manager(DirectReports+(FirstName,LastName))/$entity ``` ::: @@ -552,7 +552,7 @@ Context URL templates: {context-url}#{entity-set}/$deletedEntity {context-url}#{entity-set}/$link - {context-url}#{entity-set}/$deletedLink + {context-url}#{entity-set}/$deletedLink In addition to new or changed entities which have the canonical context URL for an entity, a delta response can contain deleted entities, new diff --git a/odata-protocol/11 Data Service Requests.md b/odata-protocol/11 Data Service Requests.md index b5afa982e..4c4ef6314 100644 --- a/odata-protocol/11 Data Service Requests.md +++ b/odata-protocol/11 Data Service Requests.md @@ -116,7 +116,7 @@ OData defines a number of system query options that allow refining the request. System query options are prefixed with the dollar (`$`) character, which is optional in OData 4.01. 4.01 services MUST support case-insensitive system query option names specified with or without the -`$` prefix. +`$` prefix. Clients that want to work with 4.0 services MUST use lower case names and specify the `$` prefix. @@ -530,9 +530,9 @@ Example ##ex: compute total price for order items (line breaks only for readability) ``` GET http://host/service/Customers -   ?$filter=Orders/any(o:o/TotalPrice gt 100) -   &$expand=Orders($compute=Price mult Qty as TotalPrice -                  ;$select=Name,Price,Qty,TotalPrice) + ?$filter=Orders/any(o:o/TotalPrice gt 100) + &$expand=Orders($compute=Price mult Qty as TotalPrice + ;$select=Name,Price,Qty,TotalPrice) ``` ::: @@ -1126,8 +1126,8 @@ specify properties to return ``` GET http://host/service/$entity/Model.Customer ?$id=http://host/service/Customers('ALFKI') -      &$select=CompanyName,ContactName -      &$expand=Orders + &$select=CompanyName,ContactName + &$expand=Orders ``` ::: @@ -1143,7 +1143,7 @@ matching the request after applying any [`$search`](#SystemQueryOptionsearch) system query options, formatted as a simple primitive integer value with media type `text/plain`. Clients SHOULD NOT combine the system query options -[ ]{.MsoCommentReference}[`$top`](#SystemQueryOptiontop), +[`$top`](#SystemQueryOptiontop), [`$skip`](#SystemQueryOptionskip), [`$orderby`](#SystemQueryOptionorderby), [`$expand`](#SystemQueryOptionexpand), and @@ -1347,7 +1347,7 @@ MUST return changes, additions, or deletions to the expanded entities, as well as added or deleted links to expanded entities or nested collections representing current membership. If the defining query includes expanded references, then the delta link MUST return changes to -the membership in the set of expanded references.  +the membership in the set of expanded references. Navigation properties specified in the [`$select`](#SystemQueryOptionselect) list of a defining query are not diff --git a/odata-protocol/11.4 Data Modification.md b/odata-protocol/11.4 Data Modification.md index fc3da90b5..7a4241059 100644 --- a/odata-protocol/11.4 Data Modification.md +++ b/odata-protocol/11.4 Data Modification.md @@ -212,15 +212,15 @@ entity with links to an existing manager (of managers) and to two existing emplo annotation to the `Manager` and `DirectReports` navigation properties ```json { -  "@odata.type": "#Northwind.Manager", -  "ID": 1, -  "FirstName": "Pat", -  "LastName": "Griswold", + "@odata.type": "#Northwind.Manager", + "ID": 1, + "FirstName": "Pat", + "LastName": "Griswold", "Manager@odata.bind": "http://host/service/Employees(0)", -  "DirectReports@odata.bind": [ -    "http://host/service/Employees(5)", -    "http://host/service/Employees(6)" -  ] + "DirectReports@odata.bind": [ + "http://host/service/Employees(5)", + "http://host/service/Employees(6)" + ] } ``` ::: @@ -231,15 +231,15 @@ entity with links to an existing manager (of managers) and to two existing emplo within the `Manager` and `DirectReports` navigation properties ```json { -  "@type": "#Northwind.Manager", -  "ID": 1, -  "FirstName": "Pat", -  "LastName": "Griswold", + "@type": "#Northwind.Manager", + "ID": 1, + "FirstName": "Pat", + "LastName": "Griswold", "Manager": { "@id": "Employees(0)" }, -  "DirectReports": [ -    {"@id": "Employees(5)"}, -    {"@id": "Employees(6)"} -  ] + "DirectReports": [ + {"@id": "Employees(5)"}, + {"@id": "Employees(6)"} + ] } ``` ::: @@ -429,21 +429,21 @@ reports; two existing employees and one new employee named `Suzanne Brown`. The `LastName` of employee 6 is updated to `Smith`. ```json { -  "@type": "#Northwind.Manager", -  "FirstName" : "Patricia", -  "DirectReports": [ -    { -      "@id": "Employees(5)" -    }, -    { -      "@id": "Employees(6)", -      "LastName": "Smith" -    }, -    { -      "FirstName": "Suzanne", -      "LastName": "Brown" -    } -  ] + "@type": "#Northwind.Manager", + "FirstName": "Patricia", + "DirectReports": [ + { + "@id": "Employees(5)" + }, + { + "@id": "Employees(6)", + "LastName": "Smith" + }, + { + "FirstName": "Suzanne", + "LastName": "Brown" + } + ] } ``` ::: @@ -485,33 +485,33 @@ of employee 6 and link to it if necessary named "Suzanne Brown" and link to it ```json { -  "@type": "#Northwind.Manager", -  "FirstName": "Patricia", -  "DirectReports@delta": [ -    { -      "@removed": { -        "reason": "deleted" -      }, -      "@id": "Employees(3)" -    }, -    { -      "@removed": { -        "reason": "changed" -      }, -      "@id": "Employees(4)" -    }, -    { -      "@id": "Employees(5)" -    }, -    { -      "@id": "Employees(6)", -      "LastName": "Smith" -    }, -    { -      "FirstName": "Suzanne", -      "LastName": "Brown" -    } -  ] + "@type": "#Northwind.Manager", + "FirstName": "Patricia", + "DirectReports@delta": [ + { + "@removed": { + "reason": "deleted" + }, + "@id": "Employees(3)" + }, + { + "@removed": { + "reason": "changed" + }, + "@id": "Employees(4)" + }, + { + "@id": "Employees(5)" + }, + { + "@id": "Employees(6)", + "LastName": "Smith" + }, + { + "FirstName": "Suzanne", + "LastName": "Brown" + } + ] } ``` ::: @@ -885,7 +885,7 @@ The service MUST directly modify only those properties of the complex type specified in the payload of the `PATCH` request. If a complex-typed property is set to a different type in a `PATCH` request, -properties shared through inheritance, as well as dynamic properties, +properties shared through inheritance, as well as dynamic properties, are retained (unless overwritten by new values in the payload). Other properties of the original type are discarded. @@ -968,7 +968,7 @@ POST /service/Customers('ALFKI')/EmailAddresses?$index=1 Content-Type: application/json { -  "value": "alfred@futterkiste.de" + "value": "alfred@futterkiste.de" } ``` ::: @@ -1090,7 +1090,7 @@ PATCH /service/Products/$filter(@bar)/$each?@bar=Color eq 'beige-brown' Content-Type: application/json { -  "Color": "taupe" + "Color": "taupe" } ``` ::: diff --git a/odata-protocol/11.5 Operations.md b/odata-protocol/11.5 Operations.md index 7e7ac8573..bc4a56ec8 100644 --- a/odata-protocol/11.5 Operations.md +++ b/odata-protocol/11.5 Operations.md @@ -24,8 +24,8 @@ Example ##ex: the function `MostRecentOrder` can be bound to any URL that identifies a `SampleModel.Customer` ```xml -   + + ``` ::: @@ -44,8 +44,8 @@ Example ##ex: the function `Comparison` can be bound to any URL that identifies a collection of entities ```xml -   -   + + ``` ::: @@ -108,20 +108,20 @@ a Customer that includes the `SampleEntities.MostRecentOrder` function bound to the entity ```json { -  "@context": …, -  "CustomerID": "ALFKI", -  "CompanyName": "Alfreds Futterkiste", -  "#SampleEntities.MostRecentOrder": { -    "title": "Most Recent Order", -    "target": "Customers('ALFKI')/SampleEntities.MostRecentOrder()" -  }, -  … + "@context": …, + "CustomerID": "ALFKI", + "CompanyName": "Alfreds Futterkiste", + "#SampleEntities.MostRecentOrder": { + "title": "Most Recent Order", + "target": "Customers('ALFKI')/SampleEntities.MostRecentOrder()" + }, + … } ``` ::: An efficient format that assumes client knowledge of metadata may omit -actions and functions from the payload  whose target URL can be computed +actions and functions from the payload whose target URL can be computed via metadata following standard conventions defined in [OData-URL](#ODataURL). @@ -133,11 +133,11 @@ Example ##ex: the `SampleEntities.MostRecentOrder` function is not available for customer `ALFKI` ```json { -  "@context": …, -  "CustomerID": "ALFKI", -  "CompanyName": "Alfreds Futterkiste", -  "#SampleEntities.MostRecentOrder": null, -  … + "@context": …, + "CustomerID": "ALFKI", + "CompanyName": "Alfreds Futterkiste", + "#SampleEntities.MostRecentOrder": null, + … } ``` ::: @@ -170,7 +170,7 @@ Services MAY additionally support invoking functions using the unqualified function name by defining one or more [default namespaces](#DefaultNamespaces) through the [`Core.DefaultNamespace`](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md#DefaultNamespace) term -defined in  [OData-VocCore](#ODataVocCore). +defined in [OData-VocCore](#ODataVocCore). To request processing of the function only if the binding parameter value, an entity or collection of entities, is unmodified, the client includes @@ -210,7 +210,7 @@ Example ##ex: add a new item to the list of items of the shopping cart returned by the composable `MyShoppingCart` function import ``` POST http://host/service/MyShoppingCart()/Items -  + … ``` ::: @@ -224,7 +224,7 @@ literal (for primitive values) or as a JSON formatted OData object (for complex values, or collections of primitive or complex values). Entity typed values are passed as JSON formatted entities that MAY include a subset of the properties, or just the entity reference, as appropriate -to the function.   +to the function. If a collection-valued function has no result for a given parameter value combination, the response is the format-specific representation of @@ -268,7 +268,7 @@ Example ##ex: return all Customers whose `City` property returns `Western` when passed to the `Sales.SalesRegion` function ``` GET http://host/service/Customers? -      $filter=Sales.SalesRegion(City=$it/City) eq 'Western' + $filter=Sales.SalesRegion(City=$it/City) eq 'Western' ``` ::: @@ -376,7 +376,7 @@ Services MAY additionally support invoking actions using the unqualified action name by defining one or more [default namespaces](#DefaultNamespaces) through the [`Core.DefaultNamespace`](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md#DefaultNamespace) term -defined in  [OData-VocCore](#ODataVocCore). +defined in [OData-VocCore](#ODataVocCore). To invoke an action through an action import, the client issues a `POST` request to a URL identifying the action import. The canonical URL for an @@ -441,11 +441,11 @@ If-Match: W/"MjAxOS0wMy0yMVQxMzowNVo=" Content-Type: application/json { -  "items": [ -   { "product": 4001, "quantity": 2 }, -    { "product": 7062, "quantity": 1 }, + "items": [ + { "product": 4001, "quantity": 2 }, + { "product": 7062, "quantity": 1 }, ], -  "discountCode": "BLACKFRIDAY" + "discountCode": "BLACKFRIDAY" } ``` ::: diff --git a/odata-protocol/11.7 Batch Requests.md b/odata-protocol/11.7 Batch Requests.md index 053512319..4579ab56c 100644 --- a/odata-protocol/11.7 Batch Requests.md +++ b/odata-protocol/11.7 Batch Requests.md @@ -175,7 +175,7 @@ A body part representing an individual request MUST include a The contents of a body part representing a change set MUST itself be a multipart document (see [RFC2046](#rfc2046)) with one body part for each -operation in the change set. [E]{.MsoCommentReference}ach body part +operation in the change set. Each body part representing an operation in the change set MUST specify a `Content-ID` header with a [request identifier](#IdentifyingIndividualRequests) that is unique within the batch request. @@ -197,7 +197,7 @@ set can use one of the following three formats: ::: example Example ##ex: ``` -GET https://host:1234/path/service/People(1) HTTP/1.1 +GET https://host:1234/path/service/People(1) HTTP/1.1 ``` ::: @@ -342,7 +342,7 @@ Content-Type: application/http Content-ID: 1 POST /service/Customers HTTP/1.1 -Host: host  +Host: host Content-Type: application/json Content-Length: ### @@ -381,7 +381,7 @@ Content-Type: application/http Content-ID: 1 GET /service/Employees(0) HTTP/1.1 -Host: host  +Host: host Accept: application/json @@ -396,7 +396,7 @@ Content-Length: ### If-Match: $1 { -   "Salary": 75000 + "Salary": 75000 } --batch_36522ad7-fc75-4b56-8c71-56071383e77b-- ``` diff --git a/odata-protocol/12 Conformance.md b/odata-protocol/12 Conformance.md index f57a0b396..5a8c06149 100644 --- a/odata-protocol/12 Conformance.md +++ b/odata-protocol/12 Conformance.md @@ -223,7 +223,7 @@ service: 1. MUST conform to the [OData 4.0 Minimal Conformance Level](#OData40MinimalConformanceLevel) -2. MUST be compliant with version 4.01 of the [OData-JSON](#ODataJSON) +2. MUST be compliant with version 4.01 of the [OData-JSON](#ODataJSON) format 3. MUST return the [`AsyncResult`](#HeaderAsyncResult) result header in the final response to an asynchronous request if asynchronous operations diff --git a/odata-protocol/8 Header Fields.md b/odata-protocol/8 Header Fields.md index 90ab47503..fcabed4a8 100644 --- a/odata-protocol/8 Header Fields.md +++ b/odata-protocol/8 Header Fields.md @@ -433,9 +433,9 @@ processing (if specified with an explicit value of `false`). The syntax of the `continue-on-error` preference is defined in [OData-ABNF](#ODataABNF). -The `continue-on-error` preference can also be used on a -[delta update](#UpdateaCollectionofEntities), -[set-based update](#UpdateMembersofaCollection), or +The `continue-on-error` preference can also be used on a +[delta update](#UpdateaCollectionofEntities), +[set-based update](#UpdateMembersofaCollection), or [set-based delete](#DeleteMembersofaCollection) to request that the service continue attempting to process changes after receiving an error. @@ -1047,7 +1047,7 @@ This code serves as a sub-status for the HTTP error code specified in the response. - `message`: required non-null, non-empty, language-dependent, human-readable string describing the error. -The [`Content-Language`](#HeaderContentLanguage) header MUST contain the +The [`Content-Language`](#HeaderContentLanguage) header MUST contain the language code from [RFC5646](#rfc5646) corresponding to the language in which the value for message is written. - `target`: optional nullable, potentially diff --git a/odata-protocol/Appendix.md b/odata-protocol/Appendix.md index 98c05d4e4..25dbc10cf 100644 --- a/odata-protocol/Appendix.md +++ b/odata-protocol/Appendix.md @@ -80,8 +80,8 @@ https://www.rfc-editor.org/info/rfc9110. ## ##subasec Informative References -###### [ECMAScript] -_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. +###### [ECMAScript] +_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/. ------- diff --git a/odata-temporal-ext/1 Introduction.md b/odata-temporal-ext/1 Introduction.md index 0e552ef61..2b2539ac3 100644 --- a/odata-temporal-ext/1 Introduction.md +++ b/odata-temporal-ext/1 Introduction.md @@ -61,7 +61,7 @@ that the object's values are not known to the service. ##### ##subsubsubsubsec Closed-Open Semantics -Time slices typically use closed-open semantics, following **[[SQL:2011]](#SQL)**. +Time slices typically use closed-open semantics, following [SQL:2011](#_SQL). This means the start is part of the period, the end is not part of the period, and for directly adjacent time slices the end of the earlier time slice is identical to the start of the next time slice. The period diff --git a/odata-temporal-ext/2 Overview.md b/odata-temporal-ext/2 Overview.md index 160f42f93..7c2fc2038 100644 --- a/odata-temporal-ext/2 Overview.md +++ b/odata-temporal-ext/2 Overview.md @@ -18,7 +18,7 @@ Keeping track of time is typically done by storing data together with the time period for which that data is deemed valid or effective, using separate periods for application time and system time, and the time periods are part of the logical key for "records". See -**[[SQL:2011]](#SQL)** or **[[Kulkarni]](#Kulkarni)** +[SQL:2011](#_SQL) or [Kulkarni](#_Kulkarni) on how this is done in the SQL standard. A consumer's perspective on this data can be different: even if time is diff --git a/odata-temporal-ext/3 Vocabulary.md b/odata-temporal-ext/3 Vocabulary.md index a5981fc64..28840c326 100644 --- a/odata-temporal-ext/3 Vocabulary.md +++ b/odata-temporal-ext/3 Vocabulary.md @@ -32,7 +32,7 @@ structured type with the following properties: - If the period end property does not specify a default value, a default value of "ad infinitum" is assumed. - Records of type `TimelineVisible` MAY specify the property `ObjectKey`. - - `ObjectKey` is the "sub-key" or "alternate key" that identifies time slices for a single temporal object. + - `ObjectKey` is the "sub-key" or "alternate key" that identifies time slices for a single temporal object. It is only necessary if the annotated entity set can contain time slices for more than one temporal object. The object key is a collection of property paths whose value combination uniquely identifies a temporal @@ -47,16 +47,16 @@ Example ##ex: `Employees` entity set from [example model `api-1`](#api1) annotated with temporal terms ```json "Employees": { -  "$Collection": true, -  "$Type": "OrgModel.Employee", -  "@Temporal.ApplicationTimeSupport": { -    "Timeline": { -      "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineSnapshot" -    }, -    "UnitOfTime": { -      "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate" -    } -  } + "$Collection": true, + "$Type": "OrgModel.Employee", + "@Temporal.ApplicationTimeSupport": { + "Timeline": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineSnapshot" + }, + "UnitOfTime": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate" + } + } }, ``` ::: @@ -66,23 +66,23 @@ Example ##ex: `history` navigation property in entity set `Employees` from [example model `api-2`](#api2) annotated with temporal terms ```json "$Annotations": { -  "OrgModel.Default/Employees/history": { -    "@Temporal.ApplicationTimeSupport": { -      "Timeline": { -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineVisible", -        "TimeSliceStart": "From", -        "TimeSliceEnd": "To", -        "SupportedActions": [ -          "Temporal.Update", -          "Temporal.Upsert", -          "Temporal.Delete" -        ] -      }, -      "UnitOfTime": { -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate" -      } -    } -  } + "OrgModel.Default/Employees/history": { + "@Temporal.ApplicationTimeSupport": { + "Timeline": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineVisible", + "TimeSliceStart": "From", + "TimeSliceEnd": "To", + "SupportedActions": [ + "Temporal.Update", + "Temporal.Upsert", + "Temporal.Delete" + ] + }, + "UnitOfTime": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate" + } + } + } } ``` ::: @@ -93,42 +93,42 @@ temporal objects, the temporal objects identified by combination of `AreaID` and `CostCenterID` ```json "CostCenter": { -  "$Kind": "EntityType", -  "$Key": ["tsid"], -  "tsid": {}, -  "AreaID": {}, -  "CostCenterID": {}, -  "ValidTo": { "$Type": "Edm.Date" }, -  "ValidFrom": { "$Type": "Edm.Date" }, -  "ProfitCenterID": { "$Nullable": true }, -  "DepartmentID": { "$Nullable": true } + "$Kind": "EntityType", + "$Key": ["tsid"], + "tsid": {}, + "AreaID": {}, + "CostCenterID": {}, + "ValidTo": { "$Type": "Edm.Date" }, + "ValidFrom": { "$Type": "Edm.Date" }, + "ProfitCenterID": { "$Nullable": true }, + "DepartmentID": { "$Nullable": true } }, "Default": { -  "$Kind": "EntityContainer", -  "CostCenters": { "$Collection": true, "$Type": "this.CostCenter" } + "$Kind": "EntityContainer", + "CostCenters": { "$Collection": true, "$Type": "this.CostCenter" } }, "$Annotations": { -  "this.Default/CostCenters": { -    "@Temporal.ApplicationTimeSupport": { -      "UnitOfTime": { -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.UnitOfTimeDate", -        "ClosedClosedPeriods": true -      }, -      "Timeline": { -        "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.TimelineVisible", -        "PeriodStart": "ValidFrom", -        "PeriodEnd": "ValidTo", -        "ObjectKey": ["AreaID", "CostCenterID"] -      }, -      "SupportedActions": [ -        "Temporal.Update", -        "Temporal.Upsert", -        "Temporal.Delete" -      ] -    } -  } + "this.Default/CostCenters": { + "@Temporal.ApplicationTimeSupport": { + "UnitOfTime": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.UnitOfTimeDate", + "ClosedClosedPeriods": true + }, + "Timeline": { + "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.TimelineVisible", + "PeriodStart": "ValidFrom", + "PeriodEnd": "ValidTo", + "ObjectKey": ["AreaID", "CostCenterID"] + }, + "SupportedActions": [ + "Temporal.Update", + "Temporal.Upsert", + "Temporal.Delete" + ] + } + } } ``` ::: diff --git a/odata-temporal-ext/4 Temporal Requests.md b/odata-temporal-ext/4 Temporal Requests.md index b708fb8de..f0d29a7e8 100644 --- a/odata-temporal-ext/4 Temporal Requests.md +++ b/odata-temporal-ext/4 Temporal Requests.md @@ -106,10 +106,10 @@ GET /api-1/Employees('E314') results in ```json { -  "@odata.context": "$metadata#Employees/$entity", -  "ID": "E314", -  "Name": "McDevitt", -  "Jobtitle": "Senior" + "@odata.context": "$metadata#Employees/$entity", + "ID": "E314", + "Name": "McDevitt", + "Jobtitle": "Senior" } ``` ::: @@ -122,10 +122,10 @@ GET /api-1/Employees('E314')?$at=2012-01-01 results in ```json { -  "@odata.context": "$metadata#Employees/$entity", -  "ID": "E314", -  "Name": "McDevitt", -  "Jobtitle": "Junior" + "@odata.context": "$metadata#Employees/$entity", + "ID": "E314", + "Name": "McDevitt", + "Jobtitle": "Junior" } ``` ::: @@ -141,14 +141,14 @@ specified point in time --- note that E401 back then does not satisfy this condition ```json { -  "@odata.context": "$metadata#Employees", -  "value": [ -    { -      "ID": "E314", -      "Name": "McDevitt", -      "Jobtitle": "Junior" -    } -  ] + "@odata.context": "$metadata#Employees", + "value": [ + { + "ID": "E314", + "Name": "McDevitt", + "Jobtitle": "Junior" + } + ] } ``` ::: @@ -169,14 +169,14 @@ GET /api-1/Employees('E314')?$at=2012-01-01&$expand=Department($at=2021-11-23) results in ```json { -  "@odata.context": "$metadata#Employees/$entity", -  "ID": "E314", -  "Name": "McDevitt", -  "Jobtitle": "Junior", -  "Department": { -    "ID": "D08", -    "Name": "1st Level Support" -  } + "@odata.context": "$metadata#Employees/$entity", + "ID": "E314", + "Name": "McDevitt", + "Jobtitle": "Junior", + "Department": { + "ID": "D08", + "Name": "1st Level Support" + } } ``` ::: @@ -190,21 +190,21 @@ GET /api-1/Departments('D15')?$at=2015-01-01&$expand=Employees results in ```json { -  "@odata.context": "$metadata#Departments/$entity", -  "ID": "D15", -  "Name": "Services", -  "Employees": [ -    { -      "ID": "E314", -      "Name": "McDevitt", -      "Jobtitle": "Senior" -    }, -    { -      "ID": "E401", -      "Name": "Gibson", -      "Jobtitle": "Expert" -    } -  ] + "@odata.context": "$metadata#Departments/$entity", + "ID": "D15", + "Name": "Services", + "Employees": [ + { + "ID": "E314", + "Name": "McDevitt", + "Jobtitle": "Senior" + }, + { + "ID": "E401", + "Name": "Gibson", + "Jobtitle": "Expert" + } + ] } ``` ::: @@ -273,49 +273,49 @@ application-time period boundaries as part of the default selection. Example ##ex_employeeHistory: retrieve employee history over a period of application time ``` GET /api-2/Employees?$expand=history($select=Name,Jobtitle) -                    &$from=2012-03-01&$to=2025-01-01 + &$from=2012-03-01&$to=2025-01-01 ``` results in one entity for each employee with time slices that overlap the specified application-time period: ```json { -  "@odata.context": "$metadata#Employees", -  "value": [ -    { -      "ID": "E314", -      "history": [ -        { -          "Name": "McDevitt", -          "Jobtitle": "Junior", -          "From": "2011-01-01", -          "To": "2013-10-01" -        }, -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2013-10-01", -          "To": "2014-01-01" -        }, -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2014-01-01", -          "To": "9999-12-31" -        } -      ] -    }, -    { -      "ID": "E401", -      "history": [ -        { -          "Name": "Gibson", -          "Jobtitle": "Expert", -          "From": "2012-03-01", -          "To": "9999-12-31" -        } -      ] -    } -  ] + "@odata.context": "$metadata#Employees", + "value": [ + { + "ID": "E314", + "history": [ + { + "Name": "McDevitt", + "Jobtitle": "Junior", + "From": "2011-01-01", + "To": "2013-10-01" + }, + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2013-10-01", + "To": "2014-01-01" + }, + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2014-01-01", + "To": "9999-12-31" + } + ] + }, + { + "ID": "E401", + "history": [ + { + "Name": "Gibson", + "Jobtitle": "Expert", + "From": "2012-03-01", + "To": "9999-12-31" + } + ] + } + ] } ``` The history for the first employee contains two time slices that do not @@ -331,100 +331,100 @@ with their full history, and the department's data at the start of each employee history time slice ``` GET /api-2/Departments('D15')/Employees? -   $expand=history( + $expand=history( @emp=$this; -    $expand=Department( -       $expand=history($at=@emp/From) -     ) -  ) + $expand=Department( + $expand=history($at=@emp/From) + ) + ) ``` has the following result with department names and budgets as of the beginning of each employee time slice: ```json { -  "@odata.context": "$metadata#Employees", -  "value": [ -    { -      "ID": "E314", -      "history": [ -        { -          "Name": "McDevitt", -          "Jobtitle": "Junior", -          "From": "2011-01-01", -          "To": "2013-10-01", -          "Department": { -            "ID": "D08", -            "history": [{ -              "Name": "Support", -              "Budget": 1000, -              "From": "2010-01-01", -              "To": "2012-10-01" -            }] -          } -        }, -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2013-10-01", -          "To": "2014-01-01", -          "Department": { -            "ID": "D08", -            "history": [{ -              "Name": "1st Level Support", -              "Budget": 1250, -              "From": "2012-06-01", -              "To": "2014-01-01" -            }] -          } -        }, -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2014-01-01", -          "To": "9999-12-31", -          "Department": { -            "ID": "D15", -            "history": [{ -              "Name": "Services", -              "Budget": 1170, -              "From": "2011-01-01", -              "To": "9999-12-31" -            }] -          } -        } -      ] -    }, -    { -      "ID": "E401", -      "history": [ -        { -          "Name": "Norman", -          "Jobtitle": "Expert", -          "From": "2009-11-01", -          "To": "2012-03-01", -          "Department": { -            "ID": "D15", -            "history": [] -          } -        }, -        { -          "Name": "Gibson", -          "Jobtitle": "Expert", -          "From": "2012-03-01", -          "To": "9999-12-31", -          "Department": { -            "ID": "D15", -            "history": [{ -              "Name": "Services", -              "Budget": 1170, -              "From": "2011-01-01", -              "To": "9999-12-31" -            }] -          } -        } -      ] -    } -  ] + "@odata.context": "$metadata#Employees", + "value": [ + { + "ID": "E314", + "history": [ + { + "Name": "McDevitt", + "Jobtitle": "Junior", + "From": "2011-01-01", + "To": "2013-10-01", + "Department": { + "ID": "D08", + "history": [{ + "Name": "Support", + "Budget": 1000, + "From": "2010-01-01", + "To": "2012-10-01" + }] + } + }, + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2013-10-01", + "To": "2014-01-01", + "Department": { + "ID": "D08", + "history": [{ + "Name": "1st Level Support", + "Budget": 1250, + "From": "2012-06-01", + "To": "2014-01-01" + }] + } + }, + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2014-01-01", + "To": "9999-12-31", + "Department": { + "ID": "D15", + "history": [{ + "Name": "Services", + "Budget": 1170, + "From": "2011-01-01", + "To": "9999-12-31" + }] + } + } + ] + }, + { + "ID": "E401", + "history": [ + { + "Name": "Norman", + "Jobtitle": "Expert", + "From": "2009-11-01", + "To": "2012-03-01", + "Department": { + "ID": "D15", + "history": [] + } + }, + { + "Name": "Gibson", + "Jobtitle": "Expert", + "From": "2012-03-01", + "To": "9999-12-31", + "Department": { + "ID": "D15", + "history": [{ + "Name": "Services", + "Budget": 1170, + "From": "2011-01-01", + "To": "9999-12-31" + }] + } + } + ] + } + ] } ``` ::: @@ -449,47 +449,47 @@ Example ##ex: retrieve employee history over a period of application time and filter on job title ``` GET /api-2/Employees?$expand=history( -                       $select=Name,Jobtitle; -                       $from=2012-03-01&$to=2025-01-01; -                       $filter=contains(Jobtitle,'e') -                     ) + $select=Name,Jobtitle; + $from=2012-03-01&$to=2025-01-01; + $filter=contains(Jobtitle,'e') + ) ``` results in one entity for each employee with time slices that overlap the specified application-time period and satisfy the filter condition (one less than in [example ##employeeHistory]): ```json { -  "@odata.context": "$metadata#Employees", -  "value": [ -    { -      "ID": "E314", -      "history": [ -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2013-10-01", -          "To": "2014-01-01" -        }, -        { -          "Name": "McDevitt", -          "Jobtitle": "Senior", -          "From": "2014-01-01", -          "To": "9999-12-31" -        } -      ] -    }, -    { -      "ID": "E401", -      "history": [ -        { -          "Name": "Gibson", -          "Jobtitle": "Expert", -          "From": "2012-03-01", -          "To": "9999-12-31" -        } -      ] -    } -  ] + "@odata.context": "$metadata#Employees", + "value": [ + { + "ID": "E314", + "history": [ + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2013-10-01", + "To": "2014-01-01" + }, + { + "Name": "McDevitt", + "Jobtitle": "Senior", + "From": "2014-01-01", + "To": "9999-12-31" + } + ] + }, + { + "ID": "E401", + "history": [ + { + "Name": "Gibson", + "Jobtitle": "Expert", + "From": "2012-03-01", + "To": "9999-12-31" + } + ] + } + ] } ``` ::: @@ -505,27 +505,27 @@ the period boundaries. Example ##ex: filter employees on their name at any point in time ``` GET /api-2/Employees?$expand=history($select=Name,Jobtitle) -                    &$from=2015-01-01 -                    &$filter=history/any(h:startswith(h/Name,'N')) + &$from=2015-01-01 + &$filter=history/any(h:startswith(h/Name,'N')) ``` results in one employee whose name matches in the past, and the matching time slice is not in the requested time period ```json { -  "@odata.context": "$metadata#Employees", -  "value": [ -    { -      "ID": "E401", -      "history": [ -        { -          "Name": "Gibson", -          "Jobtitle": "Expert", -          "From": "2012-03-01", -          "To": "9999-12-31" -        } -      ] -    } -  ] + "@odata.context": "$metadata#Employees", + "value": [ + { + "ID": "E401", + "history": [ + { + "Name": "Gibson", + "Jobtitle": "Expert", + "From": "2012-03-01", + "To": "9999-12-31" + } + ] + } + ] } ``` ::: diff --git a/odata-temporal-ext/4.3 Modifying Temporal Data.md b/odata-temporal-ext/4.3 Modifying Temporal Data.md index 66729812d..f0d136c9e 100644 --- a/odata-temporal-ext/4.3 Modifying Temporal Data.md +++ b/odata-temporal-ext/4.3 Modifying Temporal Data.md @@ -121,15 +121,15 @@ POST /api-2/Departments('D08')/history/Temporal.Update Content-Type: application/json { -  "deltaTimeslices": [ -    { -      "Timeslice": { -        "From": "2012-04-01", -        "To": "2014-07-01", -        "Budget": 1320 -      } -    } -  ] + "deltaTimeslices": [ + { + "Timeslice": { + "From": "2012-04-01", + "To": "2014-07-01", + "Budget": 1320 + } + } + ] } ``` Given the [example departments data](#ExampleData) @@ -159,54 +159,54 @@ D15 | 2011-01-01 | max | Services | 1170 It returns the resulting created or updated time slices ```json { -  "@odata.context": "../../$metadata#Collection(Temporal.TimesliceWithPeriod)", -  "value": [ -    { -      "Timeslice": { -        "@odata.context": "#Departments('D08')/history/$entity", -        "From": "2012-01-01", -        "To": "2012-04-01", -        "Name": "Support", -        "Budget": 1250 -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#Departments('D08')/history/$entity", -        "From": "2012-04-01", -        "To": "2012-06-01", -        "Name": "Support", -        "Budget": 1320 -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#Departments('D08')/history/$entity", -        "From": "2012-06-01", -        "To": "2014-01-01", -        "Name": "1st Level Support", -        "Budget": 1320 -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#Departments('D08')/history/$entity", -        "From": "2014-01-01", -        "To": "2014-07-01", -        "Name": "1st Level Support", -        "Budget": 1320 -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#Departments('D08')/history/$entity", -        "From": "2014-07-01", -        "To": "9999-12-31", -        "Name": "1st Level Support", -        "Budget": 1400 -      } -    } -  ] + "@odata.context": "../../$metadata#Collection(Temporal.TimesliceWithPeriod)", + "value": [ + { + "Timeslice": { + "@odata.context": "#Departments('D08')/history/$entity", + "From": "2012-01-01", + "To": "2012-04-01", + "Name": "Support", + "Budget": 1250 + } + }, + { + "Timeslice": { + "@odata.context": "#Departments('D08')/history/$entity", + "From": "2012-04-01", + "To": "2012-06-01", + "Name": "Support", + "Budget": 1320 + } + }, + { + "Timeslice": { + "@odata.context": "#Departments('D08')/history/$entity", + "From": "2012-06-01", + "To": "2014-01-01", + "Name": "1st Level Support", + "Budget": 1320 + } + }, + { + "Timeslice": { + "@odata.context": "#Departments('D08')/history/$entity", + "From": "2014-01-01", + "To": "2014-07-01", + "Name": "1st Level Support", + "Budget": 1320 + } + }, + { + "Timeslice": { + "@odata.context": "#Departments('D08')/history/$entity", + "From": "2014-07-01", + "To": "9999-12-31", + "Name": "1st Level Support", + "Budget": 1400 + } + } + ] } ``` The service could have joined the third and fourth time slice because @@ -221,17 +221,17 @@ application time with [`api-1`](#api1) (snapshot). Note that the period boundari ```json POST /api-1/Employees/Temporal.Update Content-Type: application/json -  + { -  "deltaTimeslices": [ -    { -      "PeriodStart": "2021-10-01", -      "Timeslice": { -        "ID": "E401", -        "Jobtitle": "Ultimate Expert" -      } -    } -  ] + "deltaTimeslices": [ + { + "PeriodStart": "2021-10-01", + "Timeslice": { + "ID": "E401", + "Jobtitle": "Ultimate Expert" + } + } + ] } ``` Given the [example employee data](#ExampleData) @@ -255,29 +255,29 @@ E401 | 2012-03-01 | *2021-10-01* | Gibson | Expert | D15 It returns the resulting created or updated time slices ```json { -  "@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)", -  "value": [ -    { -      "PeriodStart": "2012-03-01", -      "PeriodEnd": "2021-10-01", -      "Timeslice": { -        "@odata.context": "#Employees/$entity", -        "ID": "E401", -        "Name": "Gibson", -        "Jobtitle": "Expert" -      } -    }, -    { -      "PeriodStart": "2021-10-01", -      "PeriodEnd": "9999-12-31", -      "Timeslice": { -        "@odata.context": "#Employees/$entity", -        "ID": "E401", -        "Name": "Gibson", -        "Jobtitle": "Ultimate Expert" -      } -    } -  ] + "@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)", + "value": [ + { + "PeriodStart": "2012-03-01", + "PeriodEnd": "2021-10-01", + "Timeslice": { + "@odata.context": "#Employees/$entity", + "ID": "E401", + "Name": "Gibson", + "Jobtitle": "Expert" + } + }, + { + "PeriodStart": "2021-10-01", + "PeriodEnd": "9999-12-31", + "Timeslice": { + "@odata.context": "#Employees/$entity", + "ID": "E401", + "Name": "Gibson", + "Jobtitle": "Ultimate Expert" + } + } + ] } ``` ::: @@ -315,25 +315,25 @@ POST /api-3/CostCenters/Temporal.Upsert Content-Type: application/json { -  "deltaTimeslices": [ -    { -      "Timeslice": { -        "AreaID": "51", -        "CostCenterID": "C1", -        "ValidTo": "2001-03-31", -        "ValidFrom": "1984-04-01", -        "ProfitCenterID": "P2" -      } -    }, -    { -      "Timeslice": { -        "AreaID": "51", -        "CostCenterID": "C2", -        "ValidFrom": "2012-04-01", -        "DepartmentID": "D04" -      } -    } -  ] + "deltaTimeslices": [ + { + "Timeslice": { + "AreaID": "51", + "CostCenterID": "C1", + "ValidTo": "2001-03-31", + "ValidFrom": "1984-04-01", + "ProfitCenterID": "P2" + } + }, + { + "Timeslice": { + "AreaID": "51", + "CostCenterID": "C2", + "ValidFrom": "2012-04-01", + "DepartmentID": "D04" + } + } + ] } ``` Given this example data (primary key in olive) @@ -363,63 +363,63 @@ tsid | AreaID | CostCenterID | ValidTo | ValidFrom | ProfitCenterID | De n | 51 | C1 | *1984-03-31* | 1955-04-01 | P1 | D02 *o* | *51* | *C1* | *2001-03-31* | *1984-04-01* | *P2* | *D02* *p* | *51* | *C1* | *max* | *2001-04-01* | *P1* | *D02* -*q* | *51* | *C2* | *max* | *2012-04-01* |   | *D04* +*q* | *51* | *C2* | *max* | *2012-04-01* | | *D04* :::: It returns the resulting created or updated time slices per affected temporal object ```json { -  "@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)", -  "value": [ -    { -      "Timeslice": { -        "@odata.context": "#CostCenters/$entity", -        "tsid": "n", -        "AreaID": "51", -        "CostCenterID": "C1", -        "ValidTo": "1984-03-31", -        "ValidFrom": "1955-04-01", -        "ProfitCenterID": "P1", -        "DepartmentID": "D02" -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#CostCenters/$entity", -        "tsid": "o", -        "AreaID": "51", -        "CostCenterID": "C1", -        "ValidTo": "2001-03-31", -        "ValidFrom": "1984-04-01", -        "ProfitCenterID": "P2", -        "DepartmentID": "D02" -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#CostCenters/$entity", -        "tsid": "p", -        "AreaID": "51", -        "CostCenterID": "C1", -        "ValidTo": "9999-12-31", -        "ValidFrom": "2001-04-01", -        "ProfitCenterID": "P1", -        "DepartmentID": "D02" -      } -    }, -    { -      "Timeslice": { -        "@odata.context": "#CostCenters/$entity", -        "tsid": "q", -        "AreaID": "51", -        "CostCenterID": "C2", -        "ValidTo": "9999-12-31", -        "ValidFrom": "2012-04-01", -        "ProfitCenterID": null, -        "DepartmentID": "D04" -      } -    } -  ] + "@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)", + "value": [ + { + "Timeslice": { + "@odata.context": "#CostCenters/$entity", + "tsid": "n", + "AreaID": "51", + "CostCenterID": "C1", + "ValidTo": "1984-03-31", + "ValidFrom": "1955-04-01", + "ProfitCenterID": "P1", + "DepartmentID": "D02" + } + }, + { + "Timeslice": { + "@odata.context": "#CostCenters/$entity", + "tsid": "o", + "AreaID": "51", + "CostCenterID": "C1", + "ValidTo": "2001-03-31", + "ValidFrom": "1984-04-01", + "ProfitCenterID": "P2", + "DepartmentID": "D02" + } + }, + { + "Timeslice": { + "@odata.context": "#CostCenters/$entity", + "tsid": "p", + "AreaID": "51", + "CostCenterID": "C1", + "ValidTo": "9999-12-31", + "ValidFrom": "2001-04-01", + "ProfitCenterID": "P1", + "DepartmentID": "D02" + } + }, + { + "Timeslice": { + "@odata.context": "#CostCenters/$entity", + "tsid": "q", + "AreaID": "51", + "CostCenterID": "C2", + "ValidTo": "9999-12-31", + "ValidFrom": "2012-04-01", + "ProfitCenterID": null, + "DepartmentID": "D04" + } + } + ] } ``` ::: @@ -437,7 +437,7 @@ the period end of type `Edm.Date` is the last day in the period or the first day after the period. This works identical to the SQL statement DELETE FOR PORTION OF: - + 1. The "delta time slices" in `deltaTimeslices` are processed in the order of the collection. 2. For each delta time slice all time slices from the bound collection diff --git a/odata-temporal-ext/Appendix.md b/odata-temporal-ext/Appendix.md index 66370fab0..c7c1e8645 100644 --- a/odata-temporal-ext/Appendix.md +++ b/odata-temporal-ext/Appendix.md @@ -54,22 +54,22 @@ https://www.rfc-editor.org/info/rfc2119. _Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017_ https://www.rfc-editor.org/info/rfc8174. -## ##subasec Informative References +## ##subasec Informative References -###### [Fowler] +###### [Fowler] _Martin Fowler, "Temporal Patterns", 16 February 2005_ http://martinfowler.com/eaaDev/timeNarrative.html. -###### [Kulkarni] +###### [Kulkarni] _Krishna Kulkarni, "Temporal Features in SQL standard", September 2012_ https://dbs.uni-leipzig.de/file/Temporal%20features%20in%20SQL2011.pdf. -###### [Snodgrass] +###### [Snodgrass] _Richard T. Snodgrass, "Developing Time-Oriented Database Applications in SQL", Morgan Kaufmann Publishers, Inc., San Francisco, July, 1999, ISBN 1-55860-436-7_ http://www2.cs.arizona.edu/people/rts/tdbbook.pdf and http://www2.cs.arizona.edu/people/rts/pp30-31.pdf. -###### [SQL:2011] +###### [SQL:2011] _ISO/IEC 9075-2:2011 Information technology - Database languages - SQL - Part 2: Foundation (SQL/Foundation)_. ------- diff --git a/odata-url-conventions/1 Introduction.md b/odata-url-conventions/1 Introduction.md index e7c646ab1..0fec9be99 100644 --- a/odata-url-conventions/1 Introduction.md +++ b/odata-url-conventions/1 Introduction.md @@ -143,7 +143,7 @@ that the rules in [OData-ABNF](#ODataABNF) assume that URLs and URL parts have been percent-encoding normalized as described in [section 6.2.2.2](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.2) of [RFC3986](#rfc3986) before applying the grammar to them, i.e. -all characters in the unreserved set (see rule `unreserved` in +all characters in the unreserved set (see rule `unreserved` in [OData-ABNF](#ODataABNF)) are plain literals and not percent-encoded. For characters outside of the unreserved set that are significant to OData the ABNF rules explicitly state whether the percent-encoded diff --git a/odata-url-conventions/4 Resource Path.md b/odata-url-conventions/4 Resource Path.md index 373d7ec8c..916bedc6e 100644 --- a/odata-url-conventions/4 Resource Path.md +++ b/odata-url-conventions/4 Resource Path.md @@ -597,7 +597,7 @@ by `$top`, `$skip`, `$orderby`, or `$expand`. The count is calculated after applying any [`/$filter`](#AddressingaSubsetofaCollection) path segments, or -[`$filter`](#SystemQueryOptionfilter) or +[`$filter`](#SystemQueryOptionfilter) or [`$search`](#SystemQueryOptionsearch) system query options to the collection. ::: example diff --git a/odata-url-conventions/5 Query Options.md b/odata-url-conventions/5 Query Options.md index cc1b6b331..4621804f5 100644 --- a/odata-url-conventions/5 Query Options.md +++ b/odata-url-conventions/5 Query Options.md @@ -344,8 +344,8 @@ lower case operator names. The `add` operator adds the left and right numeric operands. -For operands of type `Edm.Decimal` the scale of the result is -${\rm scaleof}(A {\ \tt add\ } B) = \max({\rm scaleof}(A), {\rm scaleof}(B))$, +For operands of type `Edm.Decimal` the scale of the result is +${\rm scaleof}(A {\ \tt add\ } B) = \max({\rm scaleof}(A), {\rm scaleof}(B))$, or `variable` if any operand has variable scale. The `add` operator is also valid for the following time-related @@ -371,7 +371,7 @@ today minus a positive duration smaller than one day is yesterday. The `sub` operator subtracts the right numeric operand from the left numeric operand. -For operands of type `Edm.Decimal` the scale of the result is +For operands of type `Edm.Decimal` the scale of the result is ${\rm scaleof}(A {\ \tt sub\ } B) = \max({\rm scaleof}(A), {\rm scaleof}(B))$, or `variable` if any operand has variable scale. @@ -880,10 +880,9 @@ Edm.Boolean matchespattern(Edm.String,Edm.String) ``` The second parameter MUST evaluate to a string containing an -[**[ECMAScript]**](#ECMAScript) (JavaScript) regular expression. The `matchespattern` function returns true if the first parameter evaluates to a string matching that regular expression, using syntax and semantics -of [**[ECMAScript]**](#ECMAScript) regular expressions, otherwise it +of [ECMAScript](#_ECMAScript) regular expressions, otherwise it returns false. ::: example @@ -1997,18 +1996,18 @@ A path MUST NOT appear in more than one expand item. Query options can be applied to an expanded navigation property by appending a semicolon-separated list of query options, enclosed in -parentheses, to the navigation property name. +parentheses, to the navigation property name. Allowed system query options are [`$compute`](#SystemQueryOptioncompute), [`$select`](#SystemQueryOptionselect), -`$expand`, and +`$expand`, and [`$levels`](#ExpandOptionlevels) for all navigation properties, plus [`$filter`](#SystemQueryOptionfilter), [`$orderby`](#SystemQueryOptionorderby), [`$skip`](#SystemQueryOptionstopandskip), [`$top`](#SystemQueryOptionstopandskip), [`$count`](#SystemQueryOptioncount), and -[`$search`](#SystemQueryOptionsearch) - for collection-valued navigation properties. +[`$search`](#SystemQueryOptionsearch) +for collection-valued navigation properties. ::: example Example ##ex: all categories and for each category all related products @@ -2181,7 +2180,7 @@ The `$select` system query option is interpreted relative to the entity type or complex type of the resources identified by the resource path section of the URL. Each select item in the `$select` clause indicates that the response MUST include the declared or dynamic properties, -actions and functions identified by that select item. +actions and functions identified by that select item. If a select item is a path expression traversing an entity or complex property that is `null` on an instance, then the null-valued entity or complex property is included and represented as `null`. The simplest form of a select item explicitly requests a property defined on the entity diff --git a/odata-url-conventions/Appendix.md b/odata-url-conventions/Appendix.md index e95b448c6..cf41d23f9 100644 --- a/odata-url-conventions/Appendix.md +++ b/odata-url-conventions/Appendix.md @@ -56,8 +56,8 @@ http://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/. Latest version available ## ##subasec Informative References -###### [ECMAScript] -_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. +###### [ECMAScript] +_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/. ------- From e637cdc46f78234e6c870bf201d5ce51e97110d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Mon, 4 Dec 2023 15:42:07 +0100 Subject: [PATCH 22/22] Make build tools more robust (#190) --- docs/odata-csdl-json/odata-csdl-json.html | 552 ++++++------ docs/odata-csdl-json/odata-csdl-json.md | 434 +++++----- docs/odata-csdl-xml/odata-csdl-xml.html | 730 ++++++++-------- docs/odata-csdl-xml/odata-csdl-xml.md | 626 +++++++------- .../odata-temporal-ext.html | 807 +----------------- docs/odata-temporal-ext/odata-temporal-ext.md | 804 +---------------- lib/README.md | 8 +- lib/build-pdf.js | 2 +- lib/build.js | 6 +- lib/clean.mjs | 38 +- lib/iterator.js | 44 +- lib/number.js | 213 ++--- lib/pdf.js | 2 +- test/test-data/source.md | 6 + test/test-data/test.html | 8 + test/test-data/test.md.txt | 7 + 16 files changed, 1360 insertions(+), 2927 deletions(-) diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html index e6e202a4c..c6d74eb8b 100644 --- a/docs/odata-csdl-json/odata-csdl-json.html +++ b/docs/odata-csdl-json/odata-csdl-json.html @@ -644,8 +644,8 @@

      3.4.1 MaxLength

      A positive integer value specifying the maximum length of a binary, stream or string value. For binary or stream values this is the octet length of the binary data, for string values it is the character length (number of code points for Unicode).

      If no maximum length is specified, clients SHOULD expect arbitrary length.

      -

      Type Facet Members

      -

      $MaxLength

      +

      Type Facet Members

      +

      $MaxLength

      The value of $MaxLength is a positive integer.

      Note: OData-CSDL-XML defines a symbolic value max that is only allowed in OData 4.0 responses. This symbolic value is not allowed in CDSL JSON documents at all. Services MAY instead specify the concrete maximum length supported for the type by the service or omit the member entirely.

      @@ -654,8 +654,8 @@

      3.4.2 Precision

      For a temporal value (datetime-with-timezone-offset, duration, or time-of-day): the number of decimal places allowed in the seconds portion of the value; it MUST be a non-negative integer between zero and twelve.

      Note: service authors SHOULD be aware that some clients are unable to support a precision greater than 28 for decimal values and 7 for temporal values. Client developers MUST be aware of the potential for data loss when round-tripping values of greater precision. Updating via PATCH and exclusively specifying modified values will reduce the risk for unintended data loss.

      Note: model elements with duration values and a granularity less than seconds (e.g. minutes, hours, days) can be annotated with the term Measures.DurationGranularity, see OData-VocMeasures.

      -
      -

      $Precision

      +
      +

      $Precision

      The value of $Precision is a number.

      Absence of $Precision means unspecified precision both for decimal and temporal values.

      @@ -674,8 +674,8 @@

      3.4.3 Scale

      An integer value means that the number of digits to the right of the decimal point may vary from zero to the value of the Scale facet, and the number of digits to the left of the decimal point may vary from one to the value of the Precision facet minus the value of the Scale facet. If Precision is equal to Scale, a single zero MUST precede the decimal point.

      The value of Scale MUST be less than or equal to the value of Precision.

      Note: if the underlying data store allows negative scale, services may use a Precision with the absolute value of the negative scale added to the actual number of significant decimal digits, and client-provided values may have to be rounded before being stored.

      -
      -

      $Scale

      +
      +

      $Scale

      The value of $Scale is a number or a string with one of the symbolic values floating or variable.

      Services SHOULD use lower-case values; clients SHOULD accept values in a case-insensitive manner.

      Absence of $Scale means variable.

      @@ -718,16 +718,16 @@

      $Scale

      3.4.4 Unicode

      For a string-typed model element the Unicode facet indicates whether the it might contain and accept string values with Unicode characters (code points) beyond the ASCII character set. The value false indicates that the it will only contain and accept string values with characters limited to the ASCII character set.

      If no value is specified, the Unicode facet defaults to true.

      -
      -

      $Unicode

      +
      +

      $Unicode

      The value of $Unicode is one of the Boolean literals true or false. Absence of the member means true.

      3.4.5 SRID

      For a geometry- or geography-typed model element the SRID facet identifies which spatial reference system is applied to its values.

      The value of the SRID facet MUST be a non-negative integer or the special value variable. If no value is specified, the facet defaults to 0 for Geometry types or 4326 for Geography types.

      The valid values of the SRID facet and their meanings are as defined by the European Petroleum Survey Group EPSG.

      -
      -

      $SRID

      +
      +

      $SRID

      The value of $SRID is a string containing a number or the symbolic value variable.

      3.5 Built-In Abstract Types

      @@ -790,14 +790,14 @@

      -

      Document Object

      +

      Document Object

      A CSDL JSON document consists of a single JSON object. This document object MUST contain the member $Version.

      The document object MAY contain the member $Reference to reference other CSDL documents.

      It also MAY contain members for schemas.

      If the CSDL JSON document is the metadata document of an OData service, the document object MUST contain the member $EntityContainer.

      -

      $Version

      +

      $Version

      The value of $Version is a string containing either 4.0 or 4.01.

      -

      $EntityContainer

      +

      $EntityContainer

      The value of $EntityContainer is the namespace-qualified name of the entity container of that service. This is the only place where a model element MUST be referenced with its namespace-qualified name and use of the alias-qualified name is not allowed.

      @@ -816,9 +816,9 @@

      4.1 ReferenceA reference MAY be annotated.

      The Core.SchemaVersion annotation, defined in OData-VocCore, MAY be used to indicate a particular version of the referenced document. If the Core.SchemaVersion annotation is present, the $schemaversion system query option, defined OData-Protocol, SHOULD be used when retrieving the referenced schema document.

      -

      $Reference

      +

      $Reference

      The value of $Reference is an object that contains one member per referenced CSDL document. The name of the pair is a URI for the referenced document. The URI MAY be relative to the document containing the $Reference. The value of each member is a reference object.

      -

      Reference Object

      +

      Reference Object

      The reference object MAY contain the members $Include and $IncludeAnnotations as well as annotations.

      @@ -850,12 +850,12 @@

      4.2

      The alias MUST NOT be one of the reserved values Edm, odata, System, or Transient.

      An alias is only valid within the document in which it is declared; a referencing document may define its own aliases for included schemas.

      -

      $Include

      +

      $Include

      The value of $Include is an array. Array items are objects that MUST contain the member $Namespace and MAY contain the member $Alias.

      The item objects MAY contain annotations.

      -

      $Namespace

      +

      $Namespace

      The value of $Namespace is a string containing the namespace of the included schema.

      -

      $Alias

      +

      $Alias

      The value of $Alias is a string containing the alias for the included schema.

      @@ -900,13 +900,13 @@

      target MAY be specified. If a target namespace is specified, only those annotations which apply a term form the specified term namespace to a model element of the target namespace (with the specified qualifier, if present) SHOULD be included. If no target namespace is specified, all annotations within the referenced document from the specified term namespace (taking into account the qualifier, if present) SHOULD be included.

      The target namespace also provides consumers insight about what namespaces are present in the referenced document. If the consumer is not interested in that particular target namespace, the consumer can opt not to inspect the referenced document.

      -

      $IncludeAnnotations

      +

      $IncludeAnnotations

      The value of $IncludeAnnotations is an array. Array items are objects that MUST contain the member $TermNamespace and MAY contain the members $Qualifier and $TargetNamespace.

      -

      $TermNamespace

      +

      $TermNamespace

      The value of $TermNamespace is a namespace.

      -

      $Qualifier

      +

      $Qualifier

      The value of $Qualifier is a simple identifier.

      -

      $TargetNamespace

      +

      $TargetNamespace

      The value of $TargetNamespace is a namespace.

      @@ -955,8 +955,8 @@

      5 Schema

      Services SHOULD NOT have actions and functions with the same name, and MUST NOT have actions and functions with the same name bound to the same type.

      Names are case-sensitive, but service authors SHOULD NOT choose names that differ only in case.

      The namespace MUST NOT be one of the reserved values Edm, odata, System, or Transient.

      -
      -

      Schema Object

      +
      +

      Schema Object

      A schema is represented as a member of the document object whose name is the schema namespace. Its value is an object that MAY contain the members $Alias and $Annotations.

      The schema object MAY contain members representing entity types, complex types, enumeration types, type definitions, actions, functions, terms, and an entity container.

      The schema object MAY also contain annotations that apply to the schema itself.

      @@ -966,8 +966,8 @@

      5.1 Alias

      If a schema specifies an alias, the alias MUST be used instead of the namespace within qualified names throughout the document to identify model elements of that schema. A mixed use of namespace-qualified names and alias-qualified names is not allowed.

      Aliases are document-global, so all schemas defined within or included into a document MUST have different aliases, and aliases MUST differ from the namespaces of all schemas defined within or included into a document. Aliases defined by a schema can be used throughout the containing document and are not restricted to the schema that defines them.

      The alias MUST NOT be one of the reserved values Edm, odata, System, or Transient.

      -
      -

      $Alias

      +
      +

      $Alias

      The value of $Alias is a string containing the alias for the schema.

      @@ -983,8 +983,8 @@

      $Alias

      }

      5.2 Annotations with External Targeting

      -
      -

      $Annotations

      +
      +

      $Annotations

      The value of $Annotations is an object with one member per annotation target. The member name is a path identifying the annotation target, the member value is an object containing annotations for that target.

      @@ -1005,8 +1005,8 @@

      6 Entity Type

      The entity type’s name is a simple identifier that MUST be unique within its schema.

      An entity type can define two types of properties. A structural property is a named reference to a primitive, complex, or enumeration type, or a collection of primitive, complex, or enumeration types. A navigation property is a named reference to another entity type or collection of entity types.

      All properties MUST have a unique name within an entity type. Properties MUST NOT have the same name as the declaring entity type. They MAY have the same name as one of the direct or indirect base types or derived types.

      -
      -

      Entity Type Object

      +
      +

      Entity Type Object

      An entity type is represented as a member of the schema object whose name is the unqualified name of the entity type and whose value is an object.

      The entity type object MUST contain the member $Kind with a string value of EntityType.

      It MAY contain the members $BaseType, $Abstract, $OpenType, $HasStream, and $Key.

      @@ -1033,8 +1033,8 @@

      key as well as structural and navigation properties of its base type.

      An entity type MUST NOT introduce an inheritance cycle by specifying a base type.

      -
      -

      $BaseType

      +
      +

      $BaseType

      The value of $BaseType is the qualified name of the base type.

      @@ -1061,24 +1061,24 @@

      key or derive from a base type with a defined key.

      An abstract entity type MUST NOT inherit from a non-abstract entity type.

      -
      -

      $Abstract

      +
      +

      $Abstract

      The value of $Abstract is one of the Boolean literals true or false. Absence of the member means false.

      6.3 Open Entity Type

      An entity type MAY indicate that it is open and allows clients to add properties dynamically to instances of the type by specifying uniquely named property values in the payload used to insert or update an instance of the type.

      An entity type derived from an open entity type MUST indicate that it is also open.

      Note: structural and navigation properties MAY be returned by the service on instances of any structured type, whether or not the type is marked as open. Clients MUST always be prepared to deal with additional properties on instances of any structured type, see OData-Protocol.

      -
      -

      $OpenType

      +
      +

      $OpenType

      The value of $OpenType is one of the Boolean literals true or false. Absence of the member means false.

      6.4 Media Entity Type

      An entity type that does not specify a base type MAY indicate that it is a media entity type. Media entities are entities that represent a media stream, such as a photo. Use a media entity if the out-of-band stream is the main topic of interest and the media entity is just additional structured information attached to the stream. Use a normal entity with one or more properties of type Edm.Stream if the structured data of the entity is the main topic of interest and the stream data is just additional information attached to the structured data. For more information on media entities see OData-Protocol.

      An entity type derived from a media entity type MUST indicate that it is also a media entity type.

      Media entity types MAY specify a list of acceptable media types using an annotation with term Core.AcceptableMediaTypes, see OData-VocCore.

      -
      -

      $HasStream

      +
      +

      $HasStream

      The value of $HasStream is one of the Boolean literals true or false. Absence of the member means false.

      6.5 Key

      @@ -1109,8 +1109,8 @@

      6.5 Key

      If the key property is a property of a complex property (recursively) or of a directly related entity type, the key MUST specify an alias for that property that MUST be a simple identifier and MUST be unique within the set of aliases, structural and navigation properties of the declaring entity type and any of its base types.

      An alias MUST NOT be defined if the key property is a primitive property of the entity type itself.

      For key properties that are a property of a complex or navigation property, the alias MUST be used in the key predicate of URLs instead of the path to the property because the required percent-encoding of the forward slash separating segments of the path to the property would make URL construction and parsing rather complicated. The alias MUST NOT be used in the query part of URLs, where paths to properties don’t require special encoding and are a standard constituent of expressions anyway.

      -
      -

      $Key

      +
      +

      $Key

      The value of $Key is an array with one item per key property.

      Key properties without a key alias are represented as strings containing the property name.

      Key properties with a key alias are represented as objects with one member whose name is the key alias and whose value is a string containing the path to the property.

      @@ -1194,8 +1194,8 @@

      type.

      The property’s name MUST be a simple identifier. It is used when referencing, serializing or deserializing the property. It MUST be unique within the set of structural and navigation properties of the declaring structured type, and MUST NOT match the name of any navigation property in any of its base types. If a structural property with the same name is defined in any of this type’s base types, then the property’s type MUST be a type derived from the type specified for the property of the base type and constrains this property to be of the specified subtype for instances of this structured type. The name MUST NOT match the name of any structural or navigation property of any of this type’s base types for OData 4.0 responses.

      Names are case-sensitive, but service authors SHOULD NOT choose names that differ only in case.

      -
      -

      Property Object

      +
      +

      Property Object

      Structural properties are represented as members of the object representing a structured type. The member name is the property name, the member value is an object.

      The property object MAY contain the member $Kind with a string value of Property. This member SHOULD be omitted to reduce document size.

      It MAY contain the members $Type, $Collection, $Nullable, $MaxLength, $Unicode, $Precision, $Scale, $SRID, and $DefaultValue.

      @@ -1220,8 +1220,8 @@

      7.1 Type

      The property’s type MUST be a primitive type, complex type, or enumeration type in scope, or a collection of one of these types.

      A collection-valued property MAY be annotated with the Core.Ordered term, defined in OData-VocCore, to specify that it supports a stable ordering.

      A collection-valued property MAY be annotated with the Core.PositionalInsert term, defined in OData-VocCore, to specify that it supports inserting items into a specific ordinal position.

      -
      -

      $Type and $Collection

      +
      +

      $Type and $Collection

      For single-valued properties the value of $Type is the qualified name of the property’s type.

      For collection-valued properties the value of $Type is the qualified name of the property’s item type, and the member $Collection MUST be present with the literal value true.

      Absence of the $Type member means the type is Edm.String. This member SHOULD be omitted for string properties to reduce document size.

      @@ -1234,8 +1234,8 @@

      $Type and 7.2 Nullable

      A Boolean value specifying whether the property can have the value null.

      -
      -

      $Nullable

      +
      +

      $Nullable

      The value of $Nullable is one of the Boolean literals true or false. Absence of the member means false.

      For single-valued properties the value true means that the property allows the null value.

      For collection-valued properties the value will always be a collection that MAY be empty. In this case $Nullable applies to items of the collection and specifies whether the collection MAY contain null values.

      @@ -1243,8 +1243,8 @@

      $Nullable

      7.3 Default Value

      A primitive- or enumeration-typed property MAY define a default value that is used if the property is not explicitly represented in an annotation or the body of a request or response.

      If no value is specified, the client SHOULD NOT assume a default value.

      -
      -

      $DefaultValue

      +
      +

      $DefaultValue

      The value of $DefaultValue is the type-specific JSON representation of the default value of the property, see OData-JSON. For properties of type Edm.Decimal and Edm.Int64 the representation depends on the media type parameter IEEE754Compatible.


      @@ -1252,8 +1252,8 @@

      simple identifier. It is used when referencing, serializing or deserializing the navigation property. It MUST be unique within the set of structural and navigation properties of the declaring structured type, and MUST NOT match the name of any structural property in any of its base types. If a navigation property with the same name is defined in any of this type’s base types, then the navigation property’s type MUST be a type derived from the type specified for the navigation property of the base type, and constrains this navigation property to be of the specified subtype for instances of this structured type. The name MUST NOT match the name of any structural or navigation property of any of this type’s base types for OData 4.0 responses.

      Names are case-sensitive, but service authors SHOULD NOT choose names that differ only in case.

      -
      -

      Navigation Property Object

      +

    If no on-delete action is specified, the action taken by the service is not predictable by the client and could vary per entity.

    -
    -

    $OnDelete

    +
    +

    $OnDelete

    The value of $OnDelete is a string with one of the values Cascade, None, SetNull, or SetDefault.

    Annotations for $OnDelete are prefixed with $OnDelete.

    @@ -1413,8 +1413,8 @@

    9 Complex Type

    The complex type’s name is a simple identifier that MUST be unique within its schema.

    A complex type can define two types of properties. A structural property is a named reference to a primitive, complex, or enumeration type, or a collection of primitive, complex, or enumeration types. A navigation property is a named reference to an entity type or a collection of entity types.

    All properties MUST have a unique name within a complex type. Properties MUST NOT have the same name as the declaring complex type. They MAY have the same name as one of the direct or indirect base types or derived types.

    -
    -

    Complex Type Object

    +
    +

    Complex Type Object

    A complex type is represented as a member of the schema object whose name is the unqualified name of the complex type and whose value is an object.

    The complex type object MUST contain the member $Kind with a string value of ComplexType. It MAY contain the members $BaseType, $Abstract, and $OpenType. It also MAY contain members representing structural properties and navigation properties as well as annotations.

    @@ -1459,22 +1459,22 @@

    section 14.2.

    -
    -

    $BaseType

    +
    +

    $BaseType

    The value of $BaseType is the qualified name of the base type.

    9.2 Abstract Complex Type

    A complex type MAY indicate that it is abstract and cannot have instances.

    -
    -

    $Abstract

    +
    +

    $Abstract

    The value of $Abstract is one of the Boolean literals true or false. Absence of the member means false.

    9.3 Open Complex Type

    A complex type MAY indicate that it is open and allows clients to add properties dynamically to instances of the type by specifying uniquely named property values in the payload used to insert or update an instance of the type.

    A complex type derived from an open complex type MUST indicate that it is also open.

    Note: structural and navigation properties MAY be returned by the service on instances of any structured type, whether or not the type is marked as open. Clients MUST always be prepared to deal with additional properties on instances of any structured type, see OData‑Protocol.

    -
    -

    $OpenType

    +
    +

    $OpenType

    The value of $OpenType is one of the Boolean literals true or false. Absence of the member means false.


    @@ -1483,8 +1483,8 @@

    1

    The enumeration type’s name is a simple identifier that MUST be unique within its schema.

    Although enumeration types have an underlying numeric value, the preferred representation for an enumeration value is the member name. Discrete sets of numeric values should be represented as numeric values annotated with the AllowedValues annotation defined in OData-VocCore.

    Enumeration types marked as flags allow values that consist of more than one enumeration member at a time.

    -
    -

    Enumeration Type Object

    +
    +

    Enumeration Type Object

    An enumeration type is represented as a member of the schema object whose name is the unqualified name of the enumeration type and whose value is an object.

    The enumeration type object MUST contain the member $Kind with a string value of EnumType.

    It MAY contain the members $UnderlyingType and $IsFlags.

    @@ -1506,15 +1506,15 @@

    Enumeration

    10.1 Underlying Integer Type

    An enumeration type MAY specify one of Edm.Byte, Edm.SByte, Edm.Int16, Edm.Int32, or Edm.Int64 as its underlying type.

    If not explicitly specified, Edm.Int32 is used as the underlying type.

    -
    -

    $UnderlyingType

    +
    +

    $UnderlyingType

    The value of $UnderlyingType is the qualified name of the underlying type.

    10.2 Flags Enumeration Type

    An enumeration type MAY indicate that the enumeration type allows multiple members to be selected simultaneously.

    If not explicitly specified, only one enumeration type member MAY be selected simultaneously.

    -
    -

    $IsFlags

    +
    +

    $IsFlags

    The value of $IsFlags is one of the Boolean literals true or false. Absence of the member means false.

    @@ -1544,8 +1544,8 @@

    -

    Enumeration Member Object

    +
    +

    Enumeration Member Object

    Enumeration type members are represented as JSON object members, where the object member name is the enumeration member name and the object member value is the enumeration member value.

    For members of flags enumeration types a combined enumeration member value is equivalent to the bitwise OR of the discrete values.

    Annotations for enumeration members are prefixed with the enumeration member name.

    @@ -1569,8 +1569,8 @@

    11 T

    The type definition’s name is a simple identifier that MUST be unique within its schema.

    Type definitions can be used wherever a primitive type is used (other than as the underlying type in a new type definition) and are type-comparable with their underlying types and any type definitions defined using the same underlying type.

    It is up to the definition of a term to specify whether and how annotations with this term propagate to places where the annotated type definition is used, and whether they can be overridden.

    -
    -

    Type Definition Object

    +
    +

    Type Definition Object

    A type definition is represented as a member of the schema object whose name is the unqualified name of the type definition and whose value is an object.

    The type definition object MUST contain the member $Kind with a string value of TypeDefinition and the member $UnderlyingType. It MAY contain the members $MaxLength, $Unicode, $Precision, $Scale, and $SRID, and it MAY contain annotations.

    @@ -1600,8 +1600,8 @@

    Type Defini

    11.1 Underlying Primitive Type

    The underlying type of a type definition MUST be a primitive type that MUST NOT be another type definition.

    -
    -

    $UnderlyingType

    +
    +

    $UnderlyingType

    The value of $UnderlyingType is the qualified name of the underlying type.

    The type definition MAY specify facets applicable to the underlying type. Possible facets are: $MaxLength, $Unicode, $Precision, $Scale, or $SRID.

    @@ -1620,8 +1620,8 @@

    Bound actions support overloading (multiple actions having the same name within the same schema) by binding parameter type. The combination of action name and the binding parameter type MUST be unique within a schema.

    Unbound actions do not support overloads. The names of all unbound actions MUST be unique within a schema.

    An unbound action MAY have the same name as a bound action.

    -
    -

    Action Overload Object

    +
    +

    Action Overload Object

    An action is represented as a member of the schema object whose name is the unqualified name of the action and whose value is an array. The array contains one object per action overload.

    The action overload object MUST contain the member $Kind with a string value of Action.

    It MAY contain the members $IsBound, $EntitySetPath, $Parameter, and $ReturnType, and it MAY contain annotations.

    @@ -1647,8 +1647,8 @@

    type definitions can be used to disambiguate overloads for both bound and unbound functions, even if they specify the same underlying type.

    -
    -

    Function Overload Object

    +
    +

    Function Overload Object

    A function is represented as a member of the schema object whose name is the unqualified name of the function and whose value is an array. The array contains one object per function overload.

    The function overload object MUST contain the member $Kind with a string value of Function.

    It MUST contain the member $ReturnType, and it MAY contain the members $IsBound, $EntitySetPath, and $Parameter, and it MAY contain annotations.

    @@ -1658,8 +1658,8 @@

    action import.

    Unbound functions are invoked as static functions within a common expression (see OData-URL, section 5.1.1), or from the entity container through a function import.

    -
    -

    $IsBound

    +
    +

    $IsBound

    The value of $IsBound is one of the Boolean literals true or false. Absence of the member means false.

    12.6 Entity Set Path

    @@ -1667,15 +1667,15 @@

    12.6

    The entity set path consists of a series of segments joined together with forward slashes.

    The first segment of the entity set path MUST be the name of the binding parameter. The remaining segments of the entity set path MUST represent navigation segments or type casts.

    A navigation segment names the simple identifier of the navigation property to be traversed. A type-cast segment names the qualified name of the entity type that should be returned from the type cast.

    -
    -

    $EntitySetPath

    +
    +

    $EntitySetPath

    The value of $EntitySetPath is a string containing the entity set path.

    12.7 Composable Function

    A function MAY indicate that it is composable. If not explicitly indicated, it is not composable.

    A composable function can be invoked with additional path segments or key predicates appended to the resource path that identifies the composable function, and with system query options as appropriate for the type returned by the composable function.

    -
    -

    $IsComposable

    +
    +

    $IsComposable

    The value of $IsComposable is one of the Boolean literals true or false. Absence of the member means false.

    12.8 Return Type

    @@ -1683,14 +1683,14 @@

    12.8 Return Typ

    The facets MaxLength, Precision, Scale, and SRID can be used as appropriate to specify value restrictions of the return type, as well as the Unicode facet for 4.01 and greater payloads.

    For a single-valued return type the facets apply to the returned value. For a collection-valued return type the facets apply to the items in the returned collection.

    -

    $ReturnType

    +

    $ReturnType

    The value of $ReturnType is an object. It MAY contain the members $Type, $Collection, $Nullable, $MaxLength, $Unicode, $Precision, $Scale, and $SRID.

    It also MAY contain annotations.

    -

    $Type and $Collection

    +

    $Type and $Collection

    For single-valued return types the value of $Type is the qualified name of the returned type.

    For collection-valued return types the value of $Type is the qualified name of the returned item type, and the member $Collection MUST be present with the literal value true.

    Absence of the $Type member means the type is Edm.String.

    -

    $Nullable

    +

    $Nullable

    The value of $Nullable is one of the Boolean literals true or false. Absence of the member means false.

    If the return type is a collection of entity types, the $Nullable member has no meaning and MUST NOT be specified.

    For other collection-valued return types the result will always be a collection that MAY be empty. In this case $Nullable applies to items of the collection and specifies whether the collection MAY contain null values.

    @@ -1704,18 +1704,18 @@

    12.9 Parameter<

    The facets MaxLength, Precision, Scale, or SRID can be used as appropriate to specify value restrictions of the parameter, as well as the Unicode facet for 4.01 and greater payloads.

    For single-valued parameters the facets apply to the parameter value. If the parameter value is a collection, the facets apply to the items in the collection.

    -

    $Parameter

    +

    $Parameter

    The value of $Parameter is an array. The array contains one object per parameter.

    -

    Parameter Object

    +

    Parameter Object

    A parameter object MUST contain the member $Name, and it MAY contain the members $Type, $Collection, $Nullable, $MaxLength, $Unicode, $Precision, $Scale, and $SRID.

    Parameter objects MAY also contain annotations.

    -

    $Name

    +

    $Name

    The value of $Name is a string containing the parameter name.

    -

    $Type and $Collection

    +

    $Type and $Collection

    For single-valued parameters the value of $Type is the qualified name of the accepted type.

    For collection-valued parameters the value of $Type is the qualified name of the accepted item type, and the member $Collection MUST be present with the literal value true.

    Absence of the $Type member means the type is Edm.String.

    -

    $Nullable

    +

    $Nullable

    The value of $Nullable is one of the Boolean literals true or false. Absence of the member means false.

    For single-valued parameters the value true means that the parameter accepts a null value.

    For collection-valued parameters the parameter value will always be a collection that MAY be empty. In this case $Nullable applies to items of the collection and specifies whether the collection MAY contain null values.

    @@ -1785,8 +1785,8 @@

    1

    An entity set can expose instances of the specified entity type as well as any entity type inherited from the specified entity type.

    A singleton allows addressing a single entity directly from the entity container without having to know its key, and without requiring an entity set.

    A function import or an action import is used to expose a function or action defined in an entity model as a top level resource.

    -
    -

    Entity Container Object

    +
    +

    Entity Container Object

    An entity container is represented as a member of the schema object whose name is the unqualified name of the entity container and whose value is an object.

    The entity container object MUST contain the member $Kind with a string value of EntityContainer.

    The entity container object MAY contain the member $Extends, members representing entity sets, singletons, action imports, and function imports, as well as annotations.

    @@ -1835,8 +1835,8 @@

    An entity container MAY specify that it extends another entity container in scope. All children of the “base” entity container are added to the “extending” entity container.

    If the “extending” entity container defines an entity set with the same name as defined in any of its “base” containers, then the entity set’s type MUST specify an entity type derived from the entity type specified for the identically named entity set in the “base” container. The same holds for singletons. Action imports and function imports cannot be redefined, nor can the “extending” container define a child with the same name as a child of a different kind in a “base” container.

    Note: services should not introduce cycles by extending entity containers. Clients should be prepared to process cycles introduced by extending entity containers.

    -
    -

    $Extends

    +
    +

    $Extends

    The value of $Extends is the qualified name of the entity container to be extended.

    @@ -1855,15 +1855,15 @@

    13.2 Entity SetAn entity set MAY indicate whether it is included in the service document. If not explicitly indicated, it is included.

    Entity sets that cannot be queried without specifying additional query options SHOULD NOT be included in the service document.

    -

    Entity Set Object

    +

    Entity Set Object

    An entity set is represented as a member of the entity container object whose name is the name of the entity set and whose value is an object.

    The entity set object MUST contain the members $Collection and $Type.

    It MAY contain the members $IncludeInServiceDocument and $NavigationPropertyBinding as well as annotations.

    -

    $Collection

    +

    $Collection

    The value of $Collection is the Booelan value true.

    -

    $Type

    +

    $Type

    The value of $Type is the qualified name of an entity type.

    -

    $IncludeInServiceDocument

    +

    $IncludeInServiceDocument

    The value of $IncludeInServiceDocument is one of the Boolean literals true or false. Absence of the member means true.

    13.3 Singleton

    @@ -1872,13 +1872,13 @@

    13.3 Singleton<

    A singleton MUST specify a type that MUST be an entity type in scope.

    A singleton MUST reference an instance its entity type.

    -

    Singleton Object

    +

    Singleton Object

    A singleton is represented as a member of the entity container object whose name is the name of the singleton and whose value is an object.

    The singleton object MUST contain the member $Type and it MAY contain the member $Nullable.

    It MAY contain the member $NavigationPropertyBinding as well as annotations.

    -

    $Type

    +

    $Type

    The value of $Type is the qualified name of an entity type.

    -

    $Nullable

    +

    $Nullable

    The value of $Nullable is one of the Boolean literals true or false. Absence of the member means false.In OData 4.0 responses this member MUST NOT be specified.

    13.4 Navigation Property Binding

    @@ -1896,8 +1896,8 @@

    13.4.

    A navigation property binding MUST specify a target via a simple identifier or target path. It specifies the entity set, singleton, or containment navigation property that contains the related entities.

    If the target is a simple identifier, it MUST resolve to an entity set or singleton defined in the same entity container.

    If the target is a target path, it MUST resolve to an entity set, singleton, or direct or indirect containment navigation property of a singleton in scope. The path can traverse single-valued containment navigation properties or single-valued complex properties before ending in a containment navigation property, and there MUST NOT be any non-containment navigation properties prior to the final segment.

    -
    -

    $NavigationPropertyBinding

    +
    @@ -1936,14 +1936,14 @@

    13.5 Acti

    An action import MUST specify the name of an unbound action in scope.

    If the imported action returns an entity or a collection of entities, a simple identifier or target path value MAY be specified to identify the entity set that contains the returned entities. If a simple identifier is specified, it MUST resolve to an entity set defined in the same entity container. If a target path is specified, it MUST resolve to an entity set in scope.

    -

    Action Import Object

    +

    Action Import Object

    An action import is represented as a member of the entity container object whose name is the name of the action import and whose value is an object.

    The action import object MUST contain the member $Action.

    It MAY contain the member $EntitySet.

    It MAY also contain annotations.

    -

    $Action

    +

    $Action

    The value of $Action is a string containing the qualified name of an unbound action.

    -

    $EntitySet

    +

    $EntitySet

    The value of $EntitySet is a string containing either the unqualified name of an entity set in the same entity container or a path to an entity set in a different entity container.

    13.6 Function Import

    @@ -1953,16 +1953,16 @@

    13.

    If the imported function returns an entity or a collection of entities, a simple identifier or target path value MAY be specified to identify the entity set that contains the returned entities. If a simple identifier is specified, it MUST resolve to an entity set defined in the same entity container. If a target path is specified, it MUST resolve to an entity set in scope.

    A function import for a parameterless function MAY indicate whether it is included in the service document. If not explicitly indicated, it is not included.

    -

    Function Import Object

    +

    Function Import Object

    A function import is represented as a member of the entity container object whose name is the name of the function import and whose value is an object.

    The function import object MUST contain the member $Function.

    It MAY contain the members $EntitySet and $IncludeInServiceDocument.

    It MAY also contain annotations.

    -

    $Function

    +

    $Function

    The value of $Function is a string containing the qualified name of an unbound function.

    -

    $EntitySet

    +

    $EntitySet

    The value of $EntitySet is a string containing either the unqualified name of an entity set in the same entity container or a path to an entity set in a different entity container.

    -

    $IncludeInServiceDocument

    +

    $IncludeInServiceDocument

    The value of $IncludeInServiceDocument is one of the Boolean literals true or false. Absence of the member means false.


    @@ -2021,28 +2021,28 @@

    14.1 Term

    The term’s name is a simple identifier that MUST be unique within its schema.

    The term’s type MUST be a type in scope, or a collection of a type in scope.

    -

    Term Object

    +

    Term Object

    A term is represented as a member of the schema object whose name is the unqualified name of the term and whose value is an object.

    The term object MUST contain the member $Kind with a string value of Term.

    It MAY contain the members $Type, $Collection, $Nullable, $DefaultValue, $BaseTerm, $AppliesTo, $MaxLength, $Precision, $Scale, and $SRID, as well as $Unicode for 4.01 and greater payloads.

    It MAY contain annotations.

    -

    $Type and $Collection

    +

    $Type and $Collection

    For single-valued terms the value of $Type is the qualified name of the term’s type.

    For collection-valued terms the value of $Type is the qualified name of the term’s item type, and the member $Collection MUST be present with the literal value true.

    Absence of the $Type member means the type is Edm.String.

    -

    $Nullable

    +

    $Nullable

    The value of $Nullable is one of the Boolean literals true or false. Absence of the member means false.

    For single-valued terms the value true means that annotations may have the null value.

    For collection-valued terms the annotation value will always be a collection that MAY be empty. In this case $Nullable applies to items of the collection and specifies whether the collection MAY contain null values.

    -

    $DefaultValue

    +

    $DefaultValue

    The value of $DefaultValue is the type-specific JSON representation of the default value of the term, see OData-JSON.

    Note: the $DefaultValue member is purely for documentation and isomorphy to OData-CSDLXML. Annotations in CSDL JSON documents MUST always specify an explicit value.

    14.1.1 Specialized Term

    A term MAY specialize another term in scope by specifying it as its base term.

    When applying a specialized term, the base term MUST also be applied with the same qualifier, and so on until a term without a base term is reached.

    -
    -

    $BaseTerm

    +
    +

    $BaseTerm

    The value of $BaseTerm is the qualified name of the base term.

    14.1.2 Applicability

    @@ -2189,8 +2189,8 @@

    14.1.2 -
    -

    $AppliesTo

    +
    +

    $AppliesTo

    The value of $AppliesTo is an array whose items are strings containing symbolic values from the table above that identify model elements the term is intended to be applied to.

    @@ -2210,8 +2210,8 @@

    $AppliesTo14.2 Annotation

    An annotation applies a term to a model element and defines how to calculate a value for the term application. Both term and model element MUST be in scope. Section 14.1.2 specifies which model elements MAY be annotated with a term.

    The value of an annotation is specified as an annotation expression, which is either a constant expression representing a constant value, or a dynamic expression. The most common construct for assigning an annotation value is a path expression that refers to a property of the same or a related structured type.

    -
    -

    Annotation Member

    +
    +

    Annotation Member

    An annotation is represented as a member whose name consists of an at (@) character, followed by the qualified name of a term, optionally followed by a hash (#) and a qualifier.

    The value of the annotation MUST be a constant expression or dynamic expression.

    The annotation can be a member of the object representing the model element it annotates, or a second-level member of the $Annotations member of a schema object.

    @@ -2718,8 +2718,8 @@

    14.4.1.

    14.4.1.7 Value Path

    The value path expression allows assigning a value by traversing an object graph. It can be used in annotations that target entity containers, entity sets, entity types, complex types, navigation properties of structured types, and structural properties of structured types. Its argument is an instance path.

    The value of the path expression is the instance or collection of instances identified by the path.

    -
    -

    $Path

    +
    +

    $Path

    Path expressions are represented as an object with a single member $Path whose value is a string containing a path.

    @@ -2753,13 +2753,13 @@

    OData-URL.

    The other comparison operators require two operand expressions that evaluate to comparable values.

    -

    $And and $Or

    +

    $And and $Or

    The And and Or logical expressions are represented as an object with a single member whose value is an array with two annotation expressions. The member name is one of $And, or $Or.

    It MAY contain annotations.

    -

    $Not

    +

    $Not

    Negation expressions are represented as an object with a single member $Not whose value is an annotation expression.

    It MAY contain annotations.

    -

    $Eq, $Ne, $Gt, $Ge, $Lt, $Le, $Has, and $In

    +

    $Eq, $Ne, $Gt, $Ge, $Lt, $Le, $Has, and $In

    All comparison expressions are represented as an object with a single member whose value is an array with two annotation expressions. The member name is one of $Eq, $Ne, $Gt, $Ge, $Lt, $Le, $Has, or $In.

    They MAY contain annotations.

    @@ -2900,10 +2900,10 @@

    -

    $Neg

    +

    $Neg

    Negation expressions are represented as an object with a single member $Neg whose value is an annotation expression.

    It MAY contain annotations.

    -

    $Add, $Sub, $Mul, $Div, $DivBy, and $Mod

    +

    $Add, $Sub, $Mul, $Div, $DivBy, and $Mod

    These arithmetic expressions are represented as an object with as single member whose value is an array with two annotation expressions. The member name is one of $Add, $Sub, $Neg, $Mul, $Div, $DivBy, or $Mod.

    They MAY contain annotations.

    @@ -2977,8 +2977,8 @@

    14.4.4 Apply Client-Side Functions

    The apply expression enables a value to be obtained by applying a client-side function. The apply expression MAY have operand expressions. The operand expressions are used as parameters to the client-side function.

    -
    -

    $Apply and $Function

    +
    +

    $Apply and $Function

    Apply expressions are represented as an object with a member $Apply whose value is an array of annotation expressions, and a member $Function whose value is a string containing the qualified name of the client-side function to be applied.

    It MAY contain annotations.

    @@ -3070,8 +3070,8 @@

    14.4.5 Cast

    The cast expression casts the value obtained from its single child expression to the specified type. The cast expression follows the same rules as the cast canonical function defined in OData-URL.

    -
    -

    $Cast

    +
    +

    $Cast

    Cast expressions are represented as an object with a member $Cast whose value is an annotation expression, a member $Type whose value is a string containing the qualified type name, and optionally a member $Collection with a value of true.

    It MAY contain annotations.

    If the specified type is a primitive type or a collection of primitive types, the facet members $MaxLength, $Unicode, $Precision, $Scale, and $SRID MAY be specified if applicable to the specified primitive type. If the facet members are not specified, their values are considered unspecified.

    @@ -3103,8 +3103,8 @@

    14.4.7 If-The

    The first child expression is the condition and MUST evaluate to a Boolean result, e.g. the comparison and logical operators can be used.

    The second and third child expressions are evaluated conditionally. The result MUST be type compatible with the type expected by the surrounding expression.

    If the first expression evaluates to true, the second expression MUST be evaluated and its value MUST be returned as the result of the if-then-else expression. If the first expression evaluates to false and a third child element is present, it MUST be evaluated and its value MUST be returned as the result of the if-then-else expression. If no third expression is present, nothing is added to the surrounding collection.

    -
    -

    $If

    +
    +

    $If

    Conditional expressions are represented as an object with a member $If whose value is an array of two or three annotation expressions.

    It MAY contain annotations.

    @@ -3122,8 +3122,8 @@

    $If

    14.4.8 Is-Of

    The is-of expression checks whether the value obtained from its single child expression is compatible with the specified type. It returns true if the child expression returns a type that is compatible with the specified type, and false otherwise.

    -
    -

    $IsOf

    +
    +

    $IsOf

    Is-of expressions are represented as an object with a member $IsOf whose value is an annotation expression, a member $Type whose value is a string containing an qualified type name, and optionally a member $Collection with a value of true.

    It MAY contain annotations.

    If the specified type is a primitive type or a collection of primitive types, the facet members $MaxLength, $Unicode, $Precision, $Scale, and $SRID MAY be specified if applicable to the specified primitive type. If the facet members are not specified, their values are considered unspecified.

    @@ -3141,8 +3141,8 @@

    14

    The labeled element expression assigns a name to its single child expression. The value of the child expression can then be reused elsewhere with a labeled element reference expression.

    A labeled element expression MUST contain exactly one child expression. The value of the child expression is also the value of the labeled element expression.

    A labeled element expression MUST provide a simple identifier value as its name that MUST be unique within the schema containing the expression.

    -
    -

    $LabeledElement

    +
    +

    $LabeledElement

    Labeled element expressions are represented as an object with a member $LabeledElement whose value is an annotation expression, and a member $Name whose value is a string containing the labeled element’s name.

    It MAY contain annotations.

    @@ -3157,8 +3157,8 @@

    $LabeledEle

    14.4.10 Labeled Element Reference

    The labeled element reference expression MUST specify the qualified name of a labeled element expression in scope and returns the value of the identified labeled element expression as its value.

    -
    -

    $LabeledElementReference

    +
    +

    $LabeledElementReference

    Labeled element reference expressions are represented as an object with a member $LabeledElementReference whose value is a string containing an qualified name.

    @@ -3176,8 +3176,8 @@

    14.4.11 Null

    Example 85:

    "@UI.DisplayName": null,
    -
    -

    $Null

    +
    +

    $Null

    Null expression containing annotations are represented as an object with a member $Null whose value is the literal null.

    @@ -3236,8 +3236,8 @@

    14.4.13

    The URL reference expression enables a value to be obtained by sending a GET request.

    The URL reference expression MUST contain exactly one expression of type Edm.String. Its value is treated as a URL that MAY be relative or absolute; relative URLs are relative to the URL of the document containing the URL reference expression, or relative to a base URL specified in a format-specific way.

    The response body of the GET request MUST be returned as the result of the URL reference expression. The result of the URL reference expression MUST be type compatible with the type expected by the surrounding expression.

    -
    -

    $UrlRef

    +
    +

    $UrlRef

    URL reference expressions are represented as an object with a single member $UrlRef whose value is an annotation expression.

    It MAY contain annotations.

    @@ -3654,161 +3654,161 @@
    [OpenUI5]

    Appendix B. Table of JSON Objects and Members

    diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md index 94e059bdc..47479fe44 100644 --- a/docs/odata-csdl-json/odata-csdl-json.md +++ b/docs/odata-csdl-json/odata-csdl-json.md @@ -641,8 +641,8 @@ If no maximum length is specified, clients SHOULD expect arbitrary length. ::: {.varjson .rep} -### Type Facet Members -### `$MaxLength` +### Type Facet Members +### `$MaxLength` The value of `$MaxLength` is a positive integer. @@ -677,7 +677,7 @@ Note: model elements with duration values and a granularity less than seconds see [OData-VocMeasures](#ODataVocMeasures). ::: {.varjson .rep} -### `$Precision` +### `$Precision` The value of `$Precision` is a number. @@ -728,7 +728,7 @@ scale added to the actual number of significant decimal digits, and client-provided values may have to be rounded before being stored. ::: {.varjson .rep} -### `$Scale` +### `$Scale` The value of `$Scale` is a number or a string with one of the symbolic values `floating` or `variable`. @@ -804,7 +804,7 @@ limited to the ASCII character set. If no value is specified, the `Unicode` facet defaults to `true`. ::: {.varjson .rep} -### `$Unicode` +### `$Unicode` The value of `$Unicode` is one of the Boolean literals `true` or `false`. Absence of the member means `true`. @@ -824,7 +824,7 @@ The valid values of the `SRID` facet and their meanings are as defined by the European Petroleum Survey Group [EPSG](#_EPSG). ::: {.varjson .rep} -### `$SRID` +### `$SRID` The value of `$SRID` is a string containing a number or the symbolic value `variable`. @@ -907,7 +907,7 @@ combination of term and qualifier. ::: {.varjson .rep} -### Document Object +### Document Object A CSDL JSON document consists of a single JSON object. This document object MUST contain the member `$Version`. @@ -917,11 +917,11 @@ It also MAY contain members for schemas. If the CSDL JSON document is the metadata document of an OData service, the document object MUST contain the member `$EntityContainer`. -### `$Version` +### `$Version` The value of `$Version` is a string containing either `4.0` or `4.01`. -### `$EntityContainer` +### `$EntityContainer` The value of `$EntityContainer` is the namespace-qualified name of the entity container of that service. This is the only place where a model element MUST be referenced with its namespace-qualified name and use of the alias-qualified name is not allowed. ::: @@ -966,14 +966,14 @@ annotation is present, the `$schemaversion` system query option, defined referenced schema document. ::: {.varjson .rep} -### `$Reference` +### `$Reference` The value of `$Reference` is an object that contains one member per referenced CSDL document. The name of the pair is a URI for the referenced document. The URI MAY be relative to the document containing the `$Reference`. The value of each member is a reference object. -### Reference Object +### Reference Object The reference object MAY contain the members [`$Include`](#IncludedSchema) and @@ -1040,19 +1040,19 @@ An alias is only valid within the document in which it is declared; a referencing document may define its own aliases for included schemas. ::: {.varjson .rep} -### `$Include` +### `$Include` The value of `$Include` is an array. Array items are objects that MUST contain the member `$Namespace` and MAY contain the member `$Alias`. The item objects MAY contain [annotations](#Annotation). -### `$Namespace` +### `$Namespace` The value of `$Namespace` is a string containing the namespace of the included schema. -### `$Alias` +### `$Alias` The value of `$Alias` is a string containing the alias for the included schema. @@ -1137,21 +1137,21 @@ not interested in that particular target namespace, the consumer can opt not to inspect the referenced document. ::: {.varjson .rep} -### `$IncludeAnnotations` +### `$IncludeAnnotations` The value of `$IncludeAnnotations` is an array. Array items are objects that MUST contain the member `$TermNamespace` and MAY contain the members `$Qualifier` and `$TargetNamespace`. -### `$TermNamespace` +### `$TermNamespace` The value of `$TermNamespace` is a namespace. -### `$Qualifier` +### `$Qualifier` The value of `$Qualifier` is a simple identifier. -### `$TargetNamespace` +### `$TargetNamespace` The value of `$TargetNamespace` is a namespace. ::: @@ -1233,7 +1233,7 @@ The namespace MUST NOT be one of the reserved values `Edm`, `odata`, `System`, or `Transient`. ::: {.varjson .rep} -### Schema Object +### Schema Object A schema is represented as a member of the document object whose name is the schema namespace. Its value is an object that MAY contain the @@ -1273,7 +1273,7 @@ The alias MUST NOT be one of the reserved values `Edm`, `odata`, `System`, or `Transient`. ::: {.varjson .rep} -### `$Alias` +### `$Alias` The value of `$Alias` is a string containing the alias for the schema. ::: @@ -1299,7 +1299,7 @@ description for the schema ## 5.2 Annotations with External Targeting ::: {.varjson .rep} -### `$Annotations` +### `$Annotations` The value of `$Annotations` is an object with one member per [annotation target](#Target). The member name is a path identifying the [annotation @@ -1350,7 +1350,7 @@ the same name as one of the direct or indirect base types or derived types. ::: {.varjson .rep} -### Entity Type Object +### Entity Type Object An entity type is represented as a member of the schema object whose name is the unqualified name of the entity type and whose value is an @@ -1402,7 +1402,7 @@ An entity type MUST NOT introduce an inheritance cycle by specifying a base type. ::: {.varjson .rep} -### `$BaseType` +### `$BaseType` The value of `$BaseType` is the qualified name of the base type. ::: @@ -1447,7 +1447,7 @@ An abstract entity type MUST NOT inherit from a non-abstract entity type. ::: {.varjson .rep} -### `$Abstract` +### `$Abstract` The value of `$Abstract` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -1471,7 +1471,7 @@ properties on instances of any structured type, see [OData-Protocol](#ODataProtocol). ::: {.varjson .rep} -### `$OpenType` +### `$OpenType` The value of `$OpenType` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -1500,7 +1500,7 @@ annotation with term see [OData-VocCore](#ODataVocCore). ::: {.varjson .rep} -### `$HasStream` +### `$HasStream` The value of `$HasStream` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -1584,7 +1584,7 @@ used in the query part of URLs, where paths to properties don't require special encoding and are a standard constituent of expressions anyway. ::: {.varjson .rep} -### `$Key` +### `$Key` The value of `$Key` is an array with one item per key property. @@ -1716,7 +1716,7 @@ Names are case-sensitive, but service authors SHOULD NOT choose names that differ only in case. ::: {.varjson .rep} -### Property Object +### Property Object Structural properties are represented as members of the object representing a structured type. The member name is the property name, @@ -1771,7 +1771,7 @@ term, defined in [OData-VocCore](#ODataVocCore), to specify that it supports inserting items into a specific ordinal position. ::: {.varjson .rep} -### `$Type` and `$Collection` +### `$Type` and `$Collection` For single-valued properties the value of `$Type` is the qualified name of the property's type. @@ -1802,7 +1802,7 @@ A Boolean value specifying whether the property can have the value `null`. ::: {.varjson .rep} -### `$Nullable` +### `$Nullable` The value of `$Nullable` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -1826,7 +1826,7 @@ the body of a request or response. If no value is specified, the client SHOULD NOT assume a default value. ::: {.varjson .rep} -### `$DefaultValue` +### `$DefaultValue` The value of `$DefaultValue` is the type-specific JSON representation of the default value of the property, see @@ -1862,7 +1862,7 @@ Names are case-sensitive, but service authors SHOULD NOT choose names that differ only in case. ::: {.varjson .rep} -### Navigation Property Object +### Navigation Property Object Navigation properties are represented as members of the object representing a structured type. The member name is the property name, @@ -1945,7 +1945,7 @@ term, defined in [OData-VocCore](#ODataVocCore), to specify that it supports inserting items into a specific ordinal position. ::: {.varjson .rep} -### `$Type` and `$Collection` +### `$Type` and `$Collection` For single-valued navigation properties the value of `$Type` is the qualified name of the navigation property's type. @@ -1966,7 +1966,7 @@ Nullable MUST NOT be specified for a collection-valued navigation property, a collection is allowed to have zero items. ::: {.varjson .rep} -### `$Nullable` +### `$Nullable` The value of `$Nullable` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -2006,7 +2006,7 @@ navigation property is defined on a type derived from the type of the partner navigation property. ::: {.varjson .rep} -### `$Partner` +### `$Partner` The value of `$Partner` is a string containing the path to the partner navigation property. @@ -2081,7 +2081,7 @@ entity. This may lead to problems for clients if the contained entity can also be reached via a non-containment navigation path. ::: {.varjson .rep} -### `$ContainsTarget` +### `$ContainsTarget` The value of `$ContainsTarget` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -2114,7 +2114,7 @@ property and the principal property are not nullable, then the dependent property MUST NOT be nullable. ::: {.varjson .rep} -### `$ReferentialConstraint` +### `$ReferentialConstraint` The value of `$ReferentialConstraint` is an object with one member per referential constraint. The member name is the path to the dependent @@ -2191,7 +2191,7 @@ If no on-delete action is specified, the action taken by the service is not predictable by the client and could vary per entity. ::: {.varjson .rep} -### `$OnDelete` +### `$OnDelete` The value of `$OnDelete` is a string with one of the values `Cascade`, `None`, `SetNull`, or `SetDefault`. @@ -2247,7 +2247,7 @@ the same name as one of the direct or indirect base types or derived types. ::: {.varjson .rep} -### Complex Type Object +### Complex Type Object A complex type is represented as a member of the schema object whose name is the unqualified name of the complex type and whose value is an @@ -2318,7 +2318,7 @@ The rules for annotations of derived complex types are described in [section 14.2](#Annotation). ::: {.varjson .rep} -### `$BaseType` +### `$BaseType` The value of `$BaseType` is the qualified name of the base type. ::: @@ -2330,7 +2330,7 @@ A complex type MAY indicate that it is abstract and cannot have instances. ::: {.varjson .rep} -### `$Abstract` +### `$Abstract` The value of `$Abstract` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -2354,7 +2354,7 @@ properties on instances of any structured type, see [OData‑Protocol](#ODataProtocol). ::: {.varjson .rep} -### `$OpenType` +### `$OpenType` The value of `$OpenType` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -2382,7 +2382,7 @@ Enumeration types marked as flags allow values that consist of more than one enumeration member at a time. ::: {.varjson .rep} -### Enumeration Type Object +### Enumeration Type Object An enumeration type is represented as a member of the schema object whose name is the unqualified name of the enumeration type and whose @@ -2425,7 +2425,7 @@ An enumeration type MAY specify one of `Edm.Byte`, `Edm.SByte`, If not explicitly specified, `Edm.Int32` is used as the underlying type. ::: {.varjson .rep} -### `$UnderlyingType` +### `$UnderlyingType` The value of `$UnderlyingType` is the qualified name of the underlying type. @@ -2441,7 +2441,7 @@ If not explicitly specified, only one enumeration type member MAY be selected simultaneously. ::: {.varjson .rep} -### `$IsFlags` +### `$IsFlags` The value of `$IsFlags` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -2496,7 +2496,7 @@ selected members is the bitwise OR of the discrete numeric member values. ::: {.varjson .rep} -### Enumeration Member Object +### Enumeration Member Object Enumeration type members are represented as JSON object members, where the object member name is the enumeration member name and the object @@ -2550,7 +2550,7 @@ annotations with this term propagate to places where the annotated type definition is used, and whether they can be overridden. ::: {.varjson .rep} -### Type Definition Object +### Type Definition Object A type definition is represented as a member of the schema object whose name is the unqualified name of the type definition and whose value is @@ -2599,7 +2599,7 @@ The underlying type of a type definition MUST be a primitive type that MUST NOT be another type definition. ::: {.varjson .rep} -### `$UnderlyingType` +### `$UnderlyingType` The value of `$UnderlyingType` is the qualified name of the underlying type. @@ -2662,7 +2662,7 @@ schema. An unbound action MAY have the same name as a bound action. ::: {.varjson .rep} -### Action Overload Object +### Action Overload Object An action is represented as a member of the schema object whose name is the unqualified name of the action and whose value is an array. The @@ -2728,7 +2728,7 @@ disambiguate overloads for both bound and unbound functions, even if they specify the same underlying type. ::: {.varjson .rep} -### Function Overload Object +### Function Overload Object A function is represented as a member of the schema object whose name is the unqualified name of the function and whose value is an array. The @@ -2761,7 +2761,7 @@ Unbound functions are invoked as static functions within a common expression or from the entity container through a [function import](#FunctionImport). ::: {.varjson .rep} -### `$IsBound` +### `$IsBound` The value of `$IsBound` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -2788,7 +2788,7 @@ type-cast segment names the [qualified name](#QualifiedName) of the entity type that should be returned from the type cast. ::: {.varjson .rep} -### `$EntitySetPath` +### `$EntitySetPath` The value of `$EntitySetPath` is a string containing the entity set path. @@ -2806,7 +2806,7 @@ composable function, and with system query options as appropriate for the type returned by the composable function. ::: {.varjson .rep} -### `$IsComposable` +### `$IsComposable` The value of `$IsComposable` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -2828,7 +2828,7 @@ For a collection-valued return type the facets apply to the items in the returned collection. ::: {.varjson .rep} -### `$ReturnType` +### `$ReturnType` The value of `$ReturnType` is an object. It MAY contain the members `$Type`, `$Collection`, `$Nullable`, [`$MaxLength`](#MaxLength), @@ -2837,7 +2837,7 @@ and [`$SRID`](#SRID). It also MAY contain [annotations](#Annotation). -### `$Type` and `$Collection` +### `$Type` and `$Collection` For single-valued return types the value of `$Type` is the qualified name of the returned type. @@ -2848,7 +2848,7 @@ present with the literal value `true`. Absence of the `$Type` member means the type is `Edm.String`. -### `$Nullable` +### `$Nullable` The value of `$Nullable` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -2893,12 +2893,12 @@ the parameter value is a collection, the facets apply to the items in the collection. ::: {.varjson .rep} -### `$Parameter` +### `$Parameter` The value of `$Parameter` is an array. The array contains one object per parameter. -### Parameter Object +### Parameter Object A parameter object MUST contain the member `$Name`, and it MAY contain the members `$Type`, `$Collection`, `$Nullable`, @@ -2907,11 +2907,11 @@ the members `$Type`, `$Collection`, `$Nullable`, Parameter objects MAY also contain [annotations](#Annotation). -### `$Name` +### `$Name` The value of `$Name` is a string containing the parameter name. -### `$Type` and `$Collection` +### `$Type` and `$Collection` For single-valued parameters the value of `$Type` is the qualified name of the accepted type. @@ -2922,7 +2922,7 @@ present with the literal value `true`. Absence of the `$Type` member means the type is `Edm.String`. -### `$Nullable` +### `$Nullable` The value of `$Nullable` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -3046,7 +3046,7 @@ import*](#ActionImport) is used to expose a function or action defined in an entity model as a top level resource. ::: {.varjson .rep} -### Entity Container Object +### Entity Container Object An entity container is represented as a member of the schema object whose name is the unqualified name of the entity container and whose @@ -3127,7 +3127,7 @@ containers. Clients should be prepared to process cycles introduced by extending entity containers. ::: {.varjson .rep} -### `$Extends` +### `$Extends` The value of `$Extends` is the qualified name of the entity container to be extended. @@ -3169,7 +3169,7 @@ Entity sets that cannot be queried without specifying additional query options SHOULD NOT be included in the service document. ::: {.varjson .rep} -### Entity Set Object +### Entity Set Object An entity set is represented as a member of the entity container object whose name is the name of the entity set and whose value is an object. @@ -3181,15 +3181,15 @@ It MAY contain the members `$IncludeInServiceDocument` and [`$NavigationPropertyBinding`](#NavigationPropertyBinding) as well as [annotations](#Annotation). -### `$Collection` +### `$Collection` The value of `$Collection` is the Booelan value `true`. -### `$Type` +### `$Type` The value of `$Type` is the qualified name of an entity type. -### `$IncludeInServiceDocument` +### `$IncludeInServiceDocument` The value of `$IncludeInServiceDocument` is one of the Boolean literals `true` or `false`. Absence of the member means `true`. @@ -3209,7 +3209,7 @@ A singleton MUST specify a type that MUST be an entity type in scope. A singleton MUST reference an instance its entity type. ::: {.varjson .rep} -### Singleton Object +### Singleton Object A singleton is represented as a member of the entity container object whose name is the name of the singleton and whose value is an object. @@ -3221,11 +3221,11 @@ It MAY contain the member [`$NavigationPropertyBinding`](#NavigationPropertyBinding) as well as [annotations](#Annotation). -### `$Type` +### `$Type` The value of `$Type` is the qualified name of an entity type. -### `$Nullable` +### `$Nullable` The value of `$Nullable` is one of the Boolean literals `true` or `false`. Absence of the member means `false`.In OData 4.0 responses this @@ -3305,7 +3305,7 @@ before ending in a containment navigation property, and there MUST NOT be any non-containment navigation properties prior to the final segment. ::: {.varjson .rep} -### `$NavigationPropertyBinding` +### `$NavigationPropertyBinding` The value of `$NavigationPropertyBinding` is an object. It consists of members whose name is the navigation property binding path and whose @@ -3379,7 +3379,7 @@ container. If a [target path](#TargetPath) is specified, it MUST resolve to an entity set in scope. ::: {.varjson .rep} -### Action Import Object +### Action Import Object An action import is represented as a member of the entity container object whose name is the name of the action import and whose value is an @@ -3391,12 +3391,12 @@ It MAY contain the member `$EntitySet`. It MAY also contain [annotations](#Annotation). -### `$Action` +### `$Action` The value of `$Action` is a string containing the qualified name of an unbound action. -### `$EntitySet` +### `$EntitySet` The value of `$EntitySet` is a string containing either the unqualified name of an entity set in the same entity container or a path to an @@ -3429,7 +3429,7 @@ is included in the service document. If not explicitly indicated, it is not included. ::: {.varjson .rep} -### Function Import Object +### Function Import Object A function import is represented as a member of the entity container object whose name is the name of the function import and whose value is @@ -3441,18 +3441,18 @@ It MAY contain the members `$EntitySet` and `$IncludeInServiceDocument`. It MAY also contain [annotations](#Annotation). -### `$Function` +### `$Function` The value of `$Function` is a string containing the qualified name of an unbound function. -### `$EntitySet` +### `$EntitySet` The value of `$EntitySet` is a string containing either the unqualified name of an entity set in the same entity container or a path to an entity set in a different entity container. -### `$IncludeInServiceDocument` +### `$IncludeInServiceDocument` The value of `$IncludeInServiceDocument` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -3569,7 +3569,7 @@ The term's type MUST be a type in scope, or a collection of a type in scope. ::: {.varjson .rep} -### Term Object +### Term Object A term is represented as a member of the schema object whose name is the unqualified name of the term and whose value is an object. @@ -3586,7 +3586,7 @@ It MAY contain the members `$Type`, `$Collection`, `$Nullable`, `$DefaultValue`, It MAY contain [annotations](#Annotation). -### `$Type` and `$Collection` +### `$Type` and `$Collection` For single-valued terms the value of `$Type` is the qualified name of the term's type. @@ -3597,7 +3597,7 @@ with the literal value `true`. Absence of the `$Type` member means the type is `Edm.String`. -### `$Nullable` +### `$Nullable` The value of `$Nullable` is one of the Boolean literals `true` or `false`. Absence of the member means `false`. @@ -3610,7 +3610,7 @@ collection that MAY be empty. In this case `$Nullable` applies to items of the collection and specifies whether the collection MAY contain `null` values. -### `$DefaultValue` +### `$DefaultValue` The value of `$DefaultValue` is the type-specific JSON representation of the default value of the term, see @@ -3632,7 +3632,7 @@ with the same qualifier, and so on until a term without a base term is reached. ::: {.varjson .rep} -### `$BaseTerm` +### `$BaseTerm` The value of `$BaseTerm` is the qualified name of the base term. ::: @@ -3685,7 +3685,7 @@ Symbolic Value|Model Element `UrlRef` |UrlRef annotation expression ::: {.varjson .rep} -### `$AppliesTo` +### `$AppliesTo` The value of `$AppliesTo` is an array whose items are strings containing symbolic values from the table above that identify model elements the @@ -3728,7 +3728,7 @@ an annotation value is a [path expression](#ValuePath) that refers to a property of the same or a related structured type. ::: {.varjson .rep} -### Annotation Member +### Annotation Member An annotation is represented as a member whose name consists of an at (`@`) character, followed by the qualified name of a term, optionally @@ -4614,7 +4614,7 @@ The value of the path expression is the instance or collection of instances identified by the path. ::: {.varjson .rep} -### `$Path` +### `$Path` Path expressions are represented as an object with a single member `$Path` whose value is a string containing a path. @@ -4666,7 +4666,7 @@ The other comparison operators require two operand expressions that evaluate to comparable values. ::: {.varjson .rep} -### `$And` and `$Or` +### `$And` and `$Or` The `And` and `Or` logical expressions are represented as an object with a single member whose value is an array with two annotation expressions. @@ -4674,14 +4674,14 @@ The member name is one of `$And`, or `$Or`. It MAY contain [annotations](#Annotation). -### `$Not` +### `$Not` Negation expressions are represented as an object with a single member `$Not` whose value is an annotation expression. It MAY contain [annotations](#Annotation). -### `$Eq`, `$Ne`, `$Gt`, `$Ge`, `$Lt`, `$Le`, `$Has`, and `$In` +### `$Eq`, `$Ne`, `$Gt`, `$Ge`, `$Lt`, `$Le`, `$Has`, and `$In` All comparison expressions are represented as an object with a single member whose value is an array with two annotation expressions. The @@ -4815,14 +4815,14 @@ to a numeric value. The other arithmetic operators require two operand expressions that evaluate to numeric values. ::: {.varjson .rep} -### `$Neg` +### `$Neg` Negation expressions are represented as an object with a single member `$Neg` whose value is an annotation expression. It MAY contain [annotations](#Annotation). -### `$Add`, `$Sub`, `$Mul`, `$Div`, `$DivBy`, and `$Mod` +### `$Add`, `$Sub`, `$Mul`, `$Div`, `$DivBy`, and `$Mod` These arithmetic expressions are represented as an object with as single member whose value is an array with two annotation expressions. The @@ -4913,7 +4913,7 @@ The operand expressions are used as parameters to the client-side function. ::: {.varjson .rep} -### `$Apply` and `$Function` +### `$Apply` and `$Function` Apply expressions are represented as an object with a member `$Apply` whose value is an array of annotation expressions, and a member @@ -5094,7 +5094,7 @@ rules as the `cast` canonical function defined in [OData-URL](#ODataURL). ::: {.varjson .rep} -### `$Cast` +### `$Cast` Cast expressions are represented as an object with a member `$Cast` whose value is an annotation expression, a member `$Type` whose value is @@ -5177,7 +5177,7 @@ third expression is present, nothing is added to the surrounding collection. ::: {.varjson .rep} -### `$If` +### `$If` Conditional expressions are represented as an object with a member `$If` whose value is an array of two or three annotation expressions. @@ -5212,7 +5212,7 @@ child expression is compatible with the specified type. It returns the specified type, and `false` otherwise. ::: {.varjson .rep} -### `$IsOf` +### `$IsOf` Is-of expressions are represented as an object with a member `$IsOf` whose value is an annotation expression, a member `$Type` whose value is @@ -5259,7 +5259,7 @@ identifier](#SimpleIdentifier) value as its name that MUST be unique within the schema containing the expression. ::: {.varjson .rep} -### `$LabeledElement` +### `$LabeledElement` Labeled element expressions are represented as an object with a member `$LabeledElement` whose value is an annotation expression, and a member @@ -5290,7 +5290,7 @@ in scope and returns the value of the identified labeled element expression as its value. ::: {.varjson .rep} -### `$LabeledElementReference` +### `$LabeledElementReference` Labeled element reference expressions are represented as an object with a member `$LabeledElementReference` whose value is a string containing @@ -5326,7 +5326,7 @@ Example 85: ::: ::: {.varjson .rep} -### `$Null` +### `$Null` Null expression containing [annotations](#Annotations) are represented as an object with a member `$Null` whose value is the literal `null`. @@ -5441,7 +5441,7 @@ expression MUST be type compatible with the type expected by the surrounding expression. ::: {.varjson .rep} -### `$UrlRef` +### `$UrlRef` URL reference expressions are represented as an object with a single member `$UrlRef` whose value is an annotation expression. @@ -5982,124 +5982,124 @@ https://openui5.hana.ondemand.com/1.40.10/#docs/guide/87aac894a40640f89920d7b2a4 # Appendix B. Table of JSON Objects and Members ::: toc -- [Type Facet Members](#TypeFacetMembers1) - - [`$MaxLength`](#MaxLength1.1) - - [`$Precision`](#Precision1.2) - - [`$Scale`](#Scale1.3) - - [`$Unicode`](#Unicode1.4) - - [`$SRID`](#SRID1.5) -- [Document Object](#DocumentObject2) - - [`$Version`](#Version2.1) - - [`$EntityContainer`](#EntityContainer2.2) - - [`$Reference`](#Reference2.3) -- [Reference Object](#ReferenceObject3) - - [`$Include`](#Include3.1) - - [`$Namespace`](#Namespace3.2) - - [`$Alias`](#Alias3.3) - - [`$IncludeAnnotations`](#IncludeAnnotations3.4) - - [`$TermNamespace`](#TermNamespace3.5) - - [`$Qualifier`](#Qualifier3.6) - - [`$TargetNamespace`](#TargetNamespace3.7) -- [Schema Object](#SchemaObject4) - - [`$Alias`](#Alias4.1) - - [`$Annotations`](#Annotations4.2) -- [Entity Type Object](#EntityTypeObject5) - - [`$BaseType`](#BaseType5.1) - - [`$Abstract`](#Abstract5.2) - - [`$OpenType`](#OpenType5.3) - - [`$HasStream`](#HasStream5.4) - - [`$Key`](#Key5.5) -- [Property Object](#PropertyObject6) - - [`$Type`](#Type6.1) - - [`$Collection`](#Collection6.2) - - [`$Nullable`](#Nullable6.3) - - [`$DefaultValue`](#DefaultValue6.4) -- [Navigation Property Object](#NavigationPropertyObject7) - - [`$Type`](#Type7.1) - - [`$Collection`](#Collection7.2) - - [`$Nullable`](#Nullable7.3) - - [`$Partner`](#Partner7.4) - - [`$ContainsTarget`](#ContainsTarget7.5) - - [`$ReferentialConstraint`](#ReferentialConstraint7.6) - - [`$OnDelete`](#OnDelete7.7) -- [Complex Type Object](#ComplexTypeObject8) - - [`$BaseType`](#BaseType8.1) - - [`$Abstract`](#Abstract8.2) - - [`$OpenType`](#OpenType8.3) -- [Enumeration Type Object](#EnumerationTypeObject9) - - [`$UnderlyingType`](#UnderlyingType9.1) - - [`$IsFlags`](#IsFlags9.2) -- [Enumeration Member Object](#EnumerationMemberObject10) -- [Type Definition Object](#TypeDefinitionObject11) - - [`$UnderlyingType`](#UnderlyingType11.1) -- [Action Overload Object](#ActionOverloadObject12) -- [Function Overload Object](#FunctionOverloadObject13) - - [`$IsBound`](#IsBound13.1) - - [`$EntitySetPath`](#EntitySetPath13.2) - - [`$IsComposable`](#IsComposable13.3) - - [`$ReturnType`](#ReturnType13.4) - - [`$Type`](#Type13.5) - - [`$Collection`](#Collection13.6) - - [`$Nullable`](#Nullable13.7) - - [`$Parameter`](#Parameter13.8) -- [Parameter Object](#ParameterObject14) - - [`$Name`](#Name14.1) - - [`$Type`](#Type14.2) - - [`$Collection`](#Collection14.3) - - [`$Nullable`](#Nullable14.4) -- [Entity Container Object](#EntityContainerObject15) - - [`$Extends`](#Extends15.1) -- [Entity Set Object](#EntitySetObject16) - - [`$Collection`](#Collection16.1) - - [`$Type`](#Type16.2) - - [`$IncludeInServiceDocument`](#IncludeInServiceDocument16.3) -- [Singleton Object](#SingletonObject17) - - [`$Type`](#Type17.1) - - [`$Nullable`](#Nullable17.2) - - [`$NavigationPropertyBinding`](#NavigationPropertyBinding17.3) -- [Action Import Object](#ActionImportObject18) - - [`$Action`](#Action18.1) - - [`$EntitySet`](#EntitySet18.2) -- [Function Import Object](#FunctionImportObject19) - - [`$Function`](#Function19.1) - - [`$EntitySet`](#EntitySet19.2) - - [`$IncludeInServiceDocument`](#IncludeInServiceDocument19.3) -- [Term Object](#TermObject20) - - [`$Type`](#Type20.1) - - [`$Collection`](#Collection20.2) - - [`$Nullable`](#Nullable20.3) - - [`$DefaultValue`](#DefaultValue20.4) - - [`$BaseTerm`](#BaseTerm20.5) - - [`$AppliesTo`](#AppliesTo20.6) -- [Annotation Member](#AnnotationMember21) - - [`$Path`](#Path21.1) - - [`$And`](#And21.2) - - [`$Or`](#Or21.3) - - [`$Not`](#Not21.4) - - [`$Eq`](#Eq21.5) - - [`$Ne`](#Ne21.6) - - [`$Gt`](#Gt21.7) - - [`$Ge`](#Ge21.8) - - [`$Lt`](#Lt21.9) - - [`$Le`](#Le21.10) - - [`$Has`](#Has21.11) - - [`$In`](#In21.12) - - [`$Neg`](#Neg21.13) - - [`$Add`](#Add21.14) - - [`$Sub`](#Sub21.15) - - [`$Mul`](#Mul21.16) - - [`$Div`](#Div21.17) - - [`$DivBy`](#DivBy21.18) - - [`$Mod`](#Mod21.19) - - [`$Apply`](#Apply21.20) - - [`$Function`](#Function21.21) - - [`$Cast`](#Cast21.22) - - [`$If`](#If21.23) - - [`$IsOf`](#IsOf21.24) - - [`$LabeledElement`](#LabeledElement21.25) - - [`$LabeledElementReference`](#LabeledElementReference21.26) - - [`$Null`](#Null21.27) - - [`$UrlRef`](#UrlRef21.28) +- [Type Facet Members](#TypeFacetMembers.1) + - [`$MaxLength`](#MaxLength.1.1) + - [`$Precision`](#Precision.1.2) + - [`$Scale`](#Scale.1.3) + - [`$Unicode`](#Unicode.1.4) + - [`$SRID`](#SRID.1.5) +- [Document Object](#DocumentObject.2) + - [`$Version`](#Version.2.1) + - [`$EntityContainer`](#EntityContainer.2.2) + - [`$Reference`](#Reference.2.3) +- [Reference Object](#ReferenceObject.3) + - [`$Include`](#Include.3.1) + - [`$Namespace`](#Namespace.3.2) + - [`$Alias`](#Alias.3.3) + - [`$IncludeAnnotations`](#IncludeAnnotations.3.4) + - [`$TermNamespace`](#TermNamespace.3.5) + - [`$Qualifier`](#Qualifier.3.6) + - [`$TargetNamespace`](#TargetNamespace.3.7) +- [Schema Object](#SchemaObject.4) + - [`$Alias`](#Alias.4.1) + - [`$Annotations`](#Annotations.4.2) +- [Entity Type Object](#EntityTypeObject.5) + - [`$BaseType`](#BaseType.5.1) + - [`$Abstract`](#Abstract.5.2) + - [`$OpenType`](#OpenType.5.3) + - [`$HasStream`](#HasStream.5.4) + - [`$Key`](#Key.5.5) +- [Property Object](#PropertyObject.6) + - [`$Type`](#Type.6.1) + - [`$Collection`](#Collection.6.2) + - [`$Nullable`](#Nullable.6.3) + - [`$DefaultValue`](#DefaultValue.6.4) +- [Navigation Property Object](#NavigationPropertyObject.7) + - [`$Type`](#Type.7.1) + - [`$Collection`](#Collection.7.2) + - [`$Nullable`](#Nullable.7.3) + - [`$Partner`](#Partner.7.4) + - [`$ContainsTarget`](#ContainsTarget.7.5) + - [`$ReferentialConstraint`](#ReferentialConstraint.7.6) + - [`$OnDelete`](#OnDelete.7.7) +- [Complex Type Object](#ComplexTypeObject.8) + - [`$BaseType`](#BaseType.8.1) + - [`$Abstract`](#Abstract.8.2) + - [`$OpenType`](#OpenType.8.3) +- [Enumeration Type Object](#EnumerationTypeObject.9) + - [`$UnderlyingType`](#UnderlyingType.9.1) + - [`$IsFlags`](#IsFlags.9.2) +- [Enumeration Member Object](#EnumerationMemberObject.10) +- [Type Definition Object](#TypeDefinitionObject.11) + - [`$UnderlyingType`](#UnderlyingType.11.1) +- [Action Overload Object](#ActionOverloadObject.12) +- [Function Overload Object](#FunctionOverloadObject.13) + - [`$IsBound`](#IsBound.13.1) + - [`$EntitySetPath`](#EntitySetPath.13.2) + - [`$IsComposable`](#IsComposable.13.3) + - [`$ReturnType`](#ReturnType.13.4) + - [`$Type`](#Type.13.5) + - [`$Collection`](#Collection.13.6) + - [`$Nullable`](#Nullable.13.7) + - [`$Parameter`](#Parameter.13.8) +- [Parameter Object](#ParameterObject.14) + - [`$Name`](#Name.14.1) + - [`$Type`](#Type.14.2) + - [`$Collection`](#Collection.14.3) + - [`$Nullable`](#Nullable.14.4) +- [Entity Container Object](#EntityContainerObject.15) + - [`$Extends`](#Extends.15.1) +- [Entity Set Object](#EntitySetObject.16) + - [`$Collection`](#Collection.16.1) + - [`$Type`](#Type.16.2) + - [`$IncludeInServiceDocument`](#IncludeInServiceDocument.16.3) +- [Singleton Object](#SingletonObject.17) + - [`$Type`](#Type.17.1) + - [`$Nullable`](#Nullable.17.2) + - [`$NavigationPropertyBinding`](#NavigationPropertyBinding.17.3) +- [Action Import Object](#ActionImportObject.18) + - [`$Action`](#Action.18.1) + - [`$EntitySet`](#EntitySet.18.2) +- [Function Import Object](#FunctionImportObject.19) + - [`$Function`](#Function.19.1) + - [`$EntitySet`](#EntitySet.19.2) + - [`$IncludeInServiceDocument`](#IncludeInServiceDocument.19.3) +- [Term Object](#TermObject.20) + - [`$Type`](#Type.20.1) + - [`$Collection`](#Collection.20.2) + - [`$Nullable`](#Nullable.20.3) + - [`$DefaultValue`](#DefaultValue.20.4) + - [`$BaseTerm`](#BaseTerm.20.5) + - [`$AppliesTo`](#AppliesTo.20.6) +- [Annotation Member](#AnnotationMember.21) + - [`$Path`](#Path.21.1) + - [`$And`](#And.21.2) + - [`$Or`](#Or.21.3) + - [`$Not`](#Not.21.4) + - [`$Eq`](#Eq.21.5) + - [`$Ne`](#Ne.21.6) + - [`$Gt`](#Gt.21.7) + - [`$Ge`](#Ge.21.8) + - [`$Lt`](#Lt.21.9) + - [`$Le`](#Le.21.10) + - [`$Has`](#Has.21.11) + - [`$In`](#In.21.12) + - [`$Neg`](#Neg.21.13) + - [`$Add`](#Add.21.14) + - [`$Sub`](#Sub.21.15) + - [`$Mul`](#Mul.21.16) + - [`$Div`](#Div.21.17) + - [`$DivBy`](#DivBy.21.18) + - [`$Mod`](#Mod.21.19) + - [`$Apply`](#Apply.21.20) + - [`$Function`](#Function.21.21) + - [`$Cast`](#Cast.21.22) + - [`$If`](#If.21.23) + - [`$IsOf`](#IsOf.21.24) + - [`$LabeledElement`](#LabeledElement.21.25) + - [`$LabeledElementReference`](#LabeledElementReference.21.26) + - [`$Null`](#Null.21.27) + - [`$UrlRef`](#UrlRef.21.28) ::: ------- diff --git a/docs/odata-csdl-xml/odata-csdl-xml.html b/docs/odata-csdl-xml/odata-csdl-xml.html index 4f19532fa..31317bf25 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.html +++ b/docs/odata-csdl-xml/odata-csdl-xml.html @@ -637,8 +637,8 @@

    3.4.1 MaxLength

    A positive integer value specifying the maximum length of a binary, stream or string value. For binary or stream values this is the octet length of the binary data, for string values it is the character length (number of code points for Unicode).

    If no maximum length is specified, clients SHOULD expect arbitrary length.

    -

    Type Facet Attributes

    -

    Attribute MaxLength

    +

    Type Facet Attributes

    +

    Attribute MaxLength

    The value of MaxLength is a positive integer or the symbolic value max as a shorthand for the maximum length supported for the type by the service.

    Note: the symbolic value max is only allowed in OData 4.0 responses; it is deprecated in OData 4.01. While clients MUST be prepared for this symbolic value, OData 4.01 and greater services MUST NOT return the symbolic value max and MAY instead specify the concrete maximum length supported for the type by the service or omit the attribute entirely.

    @@ -647,8 +647,8 @@

    3.4.2 Precision

    For a temporal value (datetime-with-timezone-offset, duration, or time-of-day): the number of decimal places allowed in the seconds portion of the value; it MUST be a non-negative integer between zero and twelve.

    Note: service authors SHOULD be aware that some clients are unable to support a precision greater than 28 for decimal values and 7 for temporal values. Client developers MUST be aware of the potential for data loss when round-tripping values of greater precision. Updating via PATCH and exclusively specifying modified values will reduce the risk for unintended data loss.

    Note: model elements with duration values and a granularity less than seconds (e.g. minutes, hours, days) can be annotated with the term Measures.DurationGranularity, see OData-VocMeasures.

    -
    -

    Attribute Precision

    +
    +

    Attribute Precision

    The value of Precision is a number.

    If not specified for a decimal value, the decimal value has unspecified precision.

    If not specified for a temporal value, the temporal value has a precision of zero.

    @@ -665,8 +665,8 @@

    3.4.3 Scale

    An integer value means that the number of digits to the right of the decimal point may vary from zero to the value of the Scale facet, and the number of digits to the left of the decimal point may vary from one to the value of the Precision facet minus the value of the Scale facet. If Precision is equal to Scale, a single zero MUST precede the decimal point.

    The value of Scale MUST be less than or equal to the value of Precision.

    Note: if the underlying data store allows negative scale, services may use a Precision with the absolute value of the negative scale added to the actual number of significant decimal digits, and client-provided values may have to be rounded before being stored.

    -
    -

    Attribute Scale

    +
    +

    Attribute Scale

    The value of Scale is a number or one of the symbolic values floating or variable.

    Services SHOULD use lower-case values; clients SHOULD accept values in a case-insensitive manner.

    If not specified, the Scale facet defaults to zero.

    @@ -695,16 +695,16 @@

    Attribute Scale

    3.4.4 Unicode

    For a string-typed model element the Unicode facet indicates whether the it might contain and accept string values with Unicode characters (code points) beyond the ASCII character set. The value false indicates that the it will only contain and accept string values with characters limited to the ASCII character set.

    If no value is specified, the Unicode facet defaults to true.

    -
    -

    Attribute Unicode

    +
    +

    Attribute Unicode

    The value of Unicode is one of the Boolean literals true or false. Absence of the attribute means true.

    3.4.5 SRID

    For a geometry- or geography-typed model element the SRID facet identifies which spatial reference system is applied to its values.

    The value of the SRID facet MUST be a non-negative integer or the special value variable. If no value is specified, the facet defaults to 0 for Geometry types or 4326 for Geography types.

    The valid values of the SRID facet and their meanings are as defined by the European Petroleum Survey Group EPSG.

    -
    -

    Attribute SRID

    +
    +

    Attribute SRID

    The value of SRID is a number or the symbolic value variable.

    3.5 Built-In Abstract Types

    @@ -769,12 +769,12 @@

    4
    -

    Element edmx:Edmx

    +

    Element edmx:Edmx

    The edmx:Edmx element is the root element of a CSDL XML document. It MUST contain the Version attribute and it MUST contain exactly one edmx:DataServices element.

    It MAY contain edmx:Reference elements to reference other CSDL documents.

    -

    Attribute Version

    +

    Attribute Version

    The Version attribute specifies the OData protocol version of the service. For OData 4.0 responses the value of this attribute MUST be 4.0. For OData 4.01 responses the value of this attribute MUST be 4.01. Services MUST return an OData 4.0 response if the request was made with an OData-MaxVersion header with a value of 4.0.

    -

    Element edmx:DataServices

    +

    Element edmx:DataServices

    The edmx:DataServices element MUST contain one or more edm:Schema elements which define the schemas exposed by the OData service.

    @@ -792,11 +792,11 @@

    4.1 ReferenceA reference MAY be annotated.

    The Core.SchemaVersion annotation, defined in OData-VocCore, MAY be used to indicate a particular version of the referenced document. If the Core.SchemaVersion annotation is present, the $schemaversion system query option, defined OData-Protocol, SHOULD be used when retrieving the referenced schema document.

    -

    Element edmx:Reference

    +

    Element edmx:Reference

    The edmx:Reference element specifies external CSDL documents referenced by the referencing document. The child elements edmx:Include and edmx:IncludeAnnotations specify which parts of the referenced document are available for use in the referencing document.

    The edmx:Reference element MUST contain the Uri attribute, and it MUST contain at least one edmx:Include or edmx:IncludeAnnotations child element.

    It MAY contain edm:Annotation elements.

    -

    Attribute Uri

    +

    Attribute Uri

    The value of Uri is an absolute or relative URI; relative URIs are relative to the xml:base attribute, see XML-Base.

    @@ -829,12 +829,12 @@

    4.2

    The alias MUST NOT be one of the reserved values Edm, odata, System, or Transient.

    An alias is only valid within the document in which it is declared; a referencing document may define its own aliases for included schemas.

    -

    Element edmx:Include

    +

    Element edmx:Include

    The edmx:Include element specifies a schema to include from the referenced CSDL document. It MUST provide the Namespace attribute and it MAY provide the Alias attribute.

    It MAY contain edm:Annotation elements.

    -

    Attribute Namespace

    +

    Attribute Namespace

    The value of Namespace is the namespace of a schema defined in the referenced CSDL document.

    -

    Attribute Alias

    +

    Attribute Alias

    The value of Alias is a simple identifier that can be used in qualified names instead of the namespace.

    @@ -866,14 +866,14 @@

    target MAY be specified. If a target namespace is specified, only those annotations which apply a term form the specified term namespace to a model element of the target namespace (with the specified qualifier, if present) SHOULD be included. If no target namespace is specified, all annotations within the referenced document from the specified term namespace (taking into account the qualifier, if present) SHOULD be included.

    The target namespace also provides consumers insight about what namespaces are present in the referenced document. If the consumer is not interested in that particular target namespace, the consumer can opt not to inspect the referenced document.

    -

    Element edmx:IncludeAnnotations

    +

    Element edmx:IncludeAnnotations

    The edmx:IncludeAnnotations element specifies the annotations to include from the referenced CSDL document. If no edmx:IncludeAnnotations element is specified, a client MAY ignore all annotations in the referenced document that are not explicitly used in an edm:Path expression of the referencing document.

    The edmx:IncludeAnnotations element MUST provide the TermNamespace attribute, and it MAY provide the Qualifier and TargetNamespace attribute.

    -

    Attribute TermNamespace

    +

    Attribute TermNamespace

    The value of TermNamespace is a namespace.

    -

    Attribute Qualifier

    +

    Attribute Qualifier

    The value of Qualifier is a simple identifier.

    -

    Attribute TargetNamespace

    +

    Attribute TargetNamespace

    The value of TargetNamespace is a namespace.

    @@ -912,10 +912,10 @@

    5 Schema

    Names are case-sensitive, but service authors SHOULD NOT choose names that differ only in case.

    The namespace MUST NOT be one of the reserved values Edm, odata, System, or Transient.

    -

    Element edm:Schema

    +

    Element edm:Schema

    The edm:Schema element defines a schema. It MUST contain the Namespace attribute and it MAY contain the Alias attribute.

    It MAY contain elements edm:Action, edm:Annotations, edm:Annotation, edm:ComplexType, edm:EntityContainer, edm:EntityType, edm:EnumType, edm:Function, edm:Term, or edm:TypeDefinition.

    -

    Attribute Namespace

    +

    Attribute Namespace

    The value of Namespace is the namespace of the schema

    5.1 Alias

    @@ -923,8 +923,8 @@

    5.1 Alias

    If a schema specifies an alias, the alias MAY be used instead of the namespace within qualified names to identify model elements of that schema. An alias only provides a more convenient notation, allowing a short string to be substituted for a long namespace. Every model element that can be identified via an alias-qualified name can alternatively be identified via its full namespace-qualified name.

    Aliases are document-global, so all schemas defined within or included into a document MUST have different aliases, and aliases MUST differ from the namespaces of all schemas defined within or included into a document. Aliases defined by a schema can be used throughout the containing document and are not restricted to the schema that defines them.

    The alias MUST NOT be one of the reserved values Edm, odata, System, or Transient.

    -
    -

    Attribute Alias

    +
    +

    Attribute Alias

    The value of Alias is a simple identifier.

    @@ -936,12 +936,12 @@

    Attribute Alias

    5.2 Annotations with External Targeting

    -

    Element edm:Annotations

    +

    Element edm:Annotations

    The edm:Annotations element is used to apply a group of annotations to a single model element. It MUST contain the Target attribute and it MAY contain the Qualifier attribute.

    It MUST contain at least one edm:Annotation element.

    -

    Attribute Target

    +

    Attribute Target

    The value of Target is a path expression identifying the annotation target. It MUST resolve to a model element in scope.

    -

    Attribute Qualifier

    +

    Attribute Qualifier

    The value of Qualifier is a simple identifier.

    @@ -958,12 +958,12 @@

    6 Entity Type

    An entity type can define two types of properties. A structural property is a named reference to a primitive, complex, or enumeration type, or a collection of primitive, complex, or enumeration types. A navigation property is a named reference to another entity type or collection of entity types.

    All properties MUST have a unique name within an entity type. Properties MUST NOT have the same name as the declaring entity type. They MAY have the same name as one of the direct or indirect base types or derived types.

    -

    Element edm:EntityType

    +

    Element edm:EntityType

    The edm:EntityType element MUST contain the Name attribute, and it MAY contain the BaseType, Abstract, OpenType, and HasStream attributes.

    It MAY contain edm:Property and edm:NavigationProperty elements describing the properties of the entity type.

    It MAY contain one edm:Key element.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the entity type’s name.

    @@ -982,8 +982,8 @@

    key as well as structural and navigation properties of its base type.

    An entity type MUST NOT introduce an inheritance cycle by specifying a base type.

    -
    -

    Attribute BaseType

    +
    +

    Attribute BaseType

    The value of BaseType is the qualified name of the base type.

    @@ -1000,24 +1000,24 @@

    key or derive from a base type with a defined key.

    An abstract entity type MUST NOT inherit from a non-abstract entity type.

    -
    -

    Attribute Abstract

    +
    +

    Attribute Abstract

    The value of Abstract is one of the Boolean literals true or false. Absence of the attribute means false.

    6.3 Open Entity Type

    An entity type MAY indicate that it is open and allows clients to add properties dynamically to instances of the type by specifying uniquely named property values in the payload used to insert or update an instance of the type.

    An entity type derived from an open entity type MUST indicate that it is also open.

    Note: structural and navigation properties MAY be returned by the service on instances of any structured type, whether or not the type is marked as open. Clients MUST always be prepared to deal with additional properties on instances of any structured type, see OData-Protocol.

    -
    -

    Attribute OpenType

    +
    +

    Attribute OpenType

    The value of OpenType is one of the Boolean literals true or false. Absence of the attribute means false.

    6.4 Media Entity Type

    An entity type that does not specify a base type MAY indicate that it is a media entity type. Media entities are entities that represent a media stream, such as a photo. Use a media entity if the out-of-band stream is the main topic of interest and the media entity is just additional structured information attached to the stream. Use a normal entity with one or more properties of type Edm.Stream if the structured data of the entity is the main topic of interest and the stream data is just additional information attached to the structured data. For more information on media entities see OData-Protocol.

    An entity type derived from a media entity type MUST indicate that it is also a media entity type.

    Media entity types MAY specify a list of acceptable media types using an annotation with term Core.AcceptableMediaTypes, see OData-VocCore.

    -
    -

    Attribute HasStream

    +
    +

    Attribute HasStream

    The value of HasStream is one of the Boolean literals true or false. Absence of the attribute means false.

    6.5 Key

    @@ -1049,13 +1049,13 @@

    6.5 Key

    An alias MUST NOT be defined if the key property is a primitive property of the entity type itself.

    For key properties that are a property of a complex or navigation property, the alias MUST be used in the key predicate of URLs instead of the path to the property because the required percent-encoding of the forward slash separating segments of the path to the property would make URL construction and parsing rather complicated. The alias MUST NOT be used in the query part of URLs, where paths to properties don’t require special encoding and are a standard constituent of expressions anyway.

    -

    Element edm:Key

    +

    Element edm:Key

    The edm:Key element MUST contain at least one edm:PropertyRef element.

    -

    Element edm:PropertyRef

    +

    Element edm:PropertyRef

    The edm:PropertyRef element MUST contain the Name attribute and MAY contain the Alias attribute.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is a path expression leading to a primitive property. The names of the properties in the path are joined together by forward slashes.

    -

    Attribute Alias

    +

    Attribute Alias

    The value of Alias is a simple identifier.

    @@ -1115,10 +1115,10 @@

    simple identifier. It is used when referencing, serializing or deserializing the property. It MUST be unique within the set of structural and navigation properties of the declaring structured type, and MUST NOT match the name of any navigation property in any of its base types. If a structural property with the same name is defined in any of this type’s base types, then the property’s type MUST be a type derived from the type specified for the property of the base type and constrains this property to be of the specified subtype for instances of this structured type. The name MUST NOT match the name of any structural or navigation property of any of this type’s base types for OData 4.0 responses.

    Names are case-sensitive, but service authors SHOULD NOT choose names that differ only in case.

    -

    Element edm:Property

    +

    Element edm:Property

    The edm:Property element MUST contain the Name and the Type attribute, and it MAY contain the attributes Nullable, MaxLength, Unicode, Precision, Scale, SRID, and DefaultValue.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the property’s name.

    @@ -1134,8 +1134,8 @@

    7.1 Type

    The property’s type MUST be a primitive type, complex type, or enumeration type in scope, or a collection of one of these types.

    A collection-valued property MAY be annotated with the Core.Ordered term, defined in OData-VocCore, to specify that it supports a stable ordering.

    A collection-valued property MAY be annotated with the Core.PositionalInsert term, defined in OData-VocCore, to specify that it supports inserting items into a specific ordinal position.

    -
    -

    Attribute Type

    +
    +

    Attribute Type

    For single-valued properties the value of Type is the qualified name of the property’s type.

    For collection-valued properties the value of Type is the character sequence Collection( followed by the qualified name of the property’s item type, followed by a closing parenthesis ).

    @@ -1145,8 +1145,8 @@

    Attribute Type<

    7.2 Nullable

    A Boolean value specifying whether the property can have the value null.

    -
    -

    Attribute Nullable

    +
    +

    Attribute Nullable

    The value of Nullable is one of the Boolean literals true or false.

    For single-valued properties the value true means that the property allows the null value.

    For collection-valued properties the value will always be a collection that MAY be empty. In this case the Nullable attribute applies to items of the collection and specifies whether the collection MAY contain null values.

    @@ -1157,8 +1157,8 @@

    Attribute 7.3 Default Value

    A primitive- or enumeration-typed property MAY define a default value that is used if the property is not explicitly represented in an annotation or the body of a request or response.

    If no value is specified, the client SHOULD NOT assume a default value.

    -
    -

    Attribute DefaultValue

    +
    +

    Attribute DefaultValue

    Default values of type Edm.String MUST be represented according to the XML escaping rules for character data in attribute values. Values of other primitive types MUST be represented according to the appropriate alternative in the primitiveValue rule defined in OData-ABNF, i.e. Edm.Binary as binaryValue, Edm.Boolean as booleanValue etc.


    @@ -1167,11 +1167,11 @@

    simple identifier. It is used when referencing, serializing or deserializing the navigation property. It MUST be unique within the set of structural and navigation properties of the declaring structured type, and MUST NOT match the name of any structural property in any of its base types. If a navigation property with the same name is defined in any of this type’s base types, then the navigation property’s type MUST be a type derived from the type specified for the navigation property of the base type, and constrains this navigation property to be of the specified subtype for instances of this structured type. The name MUST NOT match the name of any structural or navigation property of any of this type’s base types for OData 4.0 responses.

    Names are case-sensitive, but service authors SHOULD NOT choose names that differ only in case.

    -

    Element edm:NavigationProperty

    +

    Element edm:NavigationProperty

    The edm:NavigationProperty element MUST contain the Name and Type attributes, and it MAY contain the attributes Nullable, Partner, and ContainsTarget.

    It MAY contain child elements edm:ReferentialConstraint and at most one child element edm:OnDelete.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the navigation property’s name.

    @@ -1196,16 +1196,16 @@

    key defined.

    A collection-valued navigation property MAY be annotated with the Core.Ordered term, defined in OData-VocCore, to specify that it supports a stable ordering.

    A collection-valued navigation property MAY be annotated with the Core.PositionalInsert term, defined in OData-VocCore, to specify that it supports inserting items into a specific ordinal position.

    -
    -

    Attribute Type

    +
    +

    Attribute Type

    For single-valued navigation properties the value of Type is the qualified name of the navigation property’s type.

    For collection-valued navigation properties the value of Type is the character sequence Collection( followed by the qualified name of the navigation property’s item type, followed by a closing parenthesis ).

    8.2 Nullable Navigation Property

    A Boolean value specifying whether the declaring type MAY have no related entity. If false, instances of the declaring structured type MUST always have a related entity.

    Nullable MUST NOT be specified for a collection-valued navigation property, a collection is allowed to have zero items.

    -
    -

    Attribute Nullable

    +
    +

    Attribute Nullable

    The value of Nullable is one of the Boolean literals true or false. Absence of the attribute means true.

    8.3 Partner Navigation Property

    @@ -1214,8 +1214,8 @@

    If the partner navigation property is single-valued, it MUST lead back to the source entity from all related entities. If the partner navigation property is collection-valued, the source entity MUST be part of that collection.

    If no partner navigation property is specified, no assumptions can be made as to whether one of the navigation properties on the target type will lead back to the source entity.

    If a partner navigation property is specified, this partner navigation property MUST either specify the current navigation property as its partner to define a bi-directional relationship or it MUST NOT specify a partner navigation property. The latter can occur if the partner navigation property is defined on a complex type, or if the current navigation property is defined on a type derived from the type of the partner navigation property.

    -
    -

    Attribute Partner

    +
    +

    Attribute Partner

    The value of Partner is the path to the of the partner navigation property.

    8.4 Containment Navigation Property

    @@ -1231,8 +1231,8 @@

    nullable (for the root of the tree) and single-valued (for the parent of a non-root entity). If the containment is not recursive, the partner navigation property MUST NOT be nullable.

    An entity type inheritance chain MUST NOT contain more than one navigation property with a partner navigation property that is a containment navigation property.

    Note: without a partner navigation property, there is no reliable way for a client to determine which entity contains a given contained entity. This may lead to problems for clients if the contained entity can also be reached via a non-containment navigation path.

    -
    -

    Attribute ContainsTarget

    +
    +

    Attribute ContainsTarget

    The value of ContainsTarget is one of the Boolean literals true or false. Absence of the attribute means false.

    8.5 Referential Constraint

    @@ -1242,12 +1242,12 @@

    -

    Element edm:ReferentialConstraint

    +

    Element edm:ReferentialConstraint

    The edm:ReferentialConstraint element MUST contain the attributes Property and ReferencedProperty.

    It MAY contain edm:Annotation elements.

    -

    Attribute Property

    +

    Attribute Property

    The Property attribute specifies the property that takes part in the referential constraint on the dependent structured type. Its value MUST be a path expression resolving to a property of the dependent structured type itself or to a property of a complex property (recursively) of the dependent structured type. The names of the properties in the path are joined together by forward slashes. The path is relative to the dependent structured type declaring the navigation property.

    -

    Attribute ReferencedProperty

    +

    Attribute ReferencedProperty

    The ReferencedProperty attribute specifies the corresponding property of the principal entity type. Its value MUST be a path expression resolving to a property of the principal entity type itself or to a property of a complex property (recursively) of the principal entity type that MUST have the same type as the property of the dependent entity type. The path is relative to the entity type that is the target of the navigation property.

    @@ -1285,10 +1285,10 @@

    8.6

    If no on-delete action is specified, the action taken by the service is not predictable by the client and could vary per entity.

    -

    Element edm:OnDelete

    +

    Element edm:OnDelete

    The edm:OnDelete element MUST contain the Action attribute.

    It MAY contain edm:Annotation elements.

    -

    Attribute Action

    +

    Attribute Action

    The value of Action is one of the values Cascade, None, SetNull, or SetDefault.

    @@ -1310,11 +1310,11 @@

    9 Complex Type

    A complex type can define two types of properties. A structural property is a named reference to a primitive, complex, or enumeration type, or a collection of primitive, complex, or enumeration types. A navigation property is a named reference to an entity type or a collection of entity types.

    All properties MUST have a unique name within a complex type. Properties MUST NOT have the same name as the declaring complex type. They MAY have the same name as one of the direct or indirect base types or derived types.

    -

    Element edm:ComplexType

    +

    Element edm:ComplexType

    The edm:ComplexType element MUST contain the Name attribute, and it MAY contain the BaseType, Abstract, and OpenType attributes.

    It MAY contain edm:Property and edm:NavigationProperty elements describing the properties of the complex type.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the complex type’s name.

    @@ -1341,22 +1341,22 @@

    section 14.2.

    -
    -

    Attribute BaseType

    +
    +

    Attribute BaseType

    The value of BaseType is the qualified name of the base type.

    9.2 Abstract Complex Type

    A complex type MAY indicate that it is abstract and cannot have instances.

    -
    -

    Attribute Abstract

    +
    +

    Attribute Abstract

    The value of Abstract is one of the Boolean literals true or false. Absence of the attribute means false.

    9.3 Open Complex Type

    A complex type MAY indicate that it is open and allows clients to add properties dynamically to instances of the type by specifying uniquely named property values in the payload used to insert or update an instance of the type.

    A complex type derived from an open complex type MUST indicate that it is also open.

    Note: structural and navigation properties MAY be returned by the service on instances of any structured type, whether or not the type is marked as open. Clients MUST always be prepared to deal with additional properties on instances of any structured type, see OData‑Protocol.

    -
    -

    Attribute OpenType

    +
    +

    Attribute OpenType

    The value of OpenType is one of the Boolean literals true or false. Absence of the attribute means false.


    @@ -1366,11 +1366,11 @@

    1

    Although enumeration types have an underlying numeric value, the preferred representation for an enumeration value is the member name. Discrete sets of numeric values should be represented as numeric values annotated with the AllowedValues annotation defined in OData-VocCore.

    Enumeration types marked as flags allow values that consist of more than one enumeration member at a time.

    -

    Element edm:EnumType

    +

    Element edm:EnumType

    The edm:EnumType element MUST contain the Name attribute, and it MAY contain the UnderlyingType and IsFlags attributes.

    It MUST contain one or more edm:Member elements defining the members of the enumeration type.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the enumeration type’s name.

    @@ -1385,15 +1385,15 @@

    10.1 Underlying Integer Type

    An enumeration type MAY specify one of Edm.Byte, Edm.SByte, Edm.Int16, Edm.Int32, or Edm.Int64 as its underlying type.

    If not explicitly specified, Edm.Int32 is used as the underlying type.

    -
    -

    Attribute UnderlyingType

    +
    +

    Attribute UnderlyingType

    The value of UnderlyingType is the qualified name of the underlying type.

    10.2 Flags Enumeration Type

    An enumeration type MAY indicate that the enumeration type allows multiple members to be selected simultaneously.

    If not explicitly specified, only one enumeration type member MAY be selected simultaneously.

    -
    -

    Attribute IsFlags

    +
    +

    Attribute IsFlags

    The value of IsFlags is one of the Boolean literals true or false. Absence of the attribute means false.

    @@ -1421,12 +1421,12 @@

    -

    Element edm:Member

    +

    Element edm:Member

    The edm:Member element MUST contain the Name attribute and it MAY contain the Value attribute.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the enumeration member’s name.

    -

    Attribute Value

    +

    Attribute Value

    If the IsFlags attribute has a value of false, either all members MUST specify an integer value for the Value attribute, or all members MUST NOT specify a value for the Value attribute. If no values are specified, the members are assigned consecutive integer values in the order of their appearance, starting with zero for the first member. Client libraries MUST preserve elements in document order.

    If the IsFlags attribute has a value of true, a non-negative integer value MUST be specified for the Value attribute. A combined value is equivalent to the bitwise OR of the discrete values.

    @@ -1454,10 +1454,10 @@

    11 T

    Type definitions can be used wherever a primitive type is used (other than as the underlying type in a new type definition) and are type-comparable with their underlying types and any type definitions defined using the same underlying type.

    It is up to the definition of a term to specify whether and how annotations with this term propagate to places where the annotated type definition is used, and whether they can be overridden.

    -

    Element edm:TypeDefinition

    +

    Element edm:TypeDefinition

    The edm:TypeDefinition element MUST contain the Name and UnderlyingType attributes.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the type definition’s name.

    @@ -1479,8 +1479,8 @@

    11.1 Underlying Primitive Type

    The underlying type of a type definition MUST be a primitive type that MUST NOT be another type definition.

    -
    -

    Attribute UnderlyingType

    +
    +

    Attribute UnderlyingType

    The value of UnderlyingType is the qualified name of the underlying type.

    The type definition MAY specify facets applicable to the underlying type. Possible facets are: MaxLength, Unicode, Precision, Scale, or SRID.

    @@ -1500,11 +1500,11 @@

    Unbound actions do not support overloads. The names of all unbound actions MUST be unique within a schema.

    An unbound action MAY have the same name as a bound action.

    -

    Element edm:Action

    +

    Element edm:Action

    The edm:Action element MUST contain the Name attribute and it MAY contain the IsBound and EntitySetPath attributes.

    It MAY contain at most one edm:ReturnType element and MAY contain edm:Parameter elements.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the action’s name.

    12.3 Function

    @@ -1529,11 +1529,11 @@

    type definitions can be used to disambiguate overloads for both bound and unbound functions, even if they specify the same underlying type.

    -

    Element edm:Function

    +

    Element edm:Function

    The edm:Function element MUST contain the Name attribute and it MAY contain the IsBound and EntitySetPath attributes.

    It MUST contain one edm:ReturnType element, and it MAY contain edm:Parameter elements.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the action’s name.

    12.5 Bound or Unbound Action or Function Overloads

    @@ -1541,8 +1541,8 @@

    action import.

    Unbound functions are invoked as static functions within a common expression (see OData-URL, section 5.1.1), or from the entity container through a function import.

    -
    -

    Attribute IsBound

    +
    +

    Attribute IsBound

    The value of IsBound is one of the Boolean literals true or false. Absence of the attribute means false.

    12.6 Entity Set Path

    @@ -1550,15 +1550,15 @@

    12.6

    The entity set path consists of a series of segments joined together with forward slashes.

    The first segment of the entity set path MUST be the name of the binding parameter. The remaining segments of the entity set path MUST represent navigation segments or type casts.

    A navigation segment names the simple identifier of the navigation property to be traversed. A type-cast segment names the qualified name of the entity type that should be returned from the type cast.

    -
    -

    Attribute EntitySetPath

    +
    +

    Attribute EntitySetPath

    The value of EntitySetPath is the entity set path.

    12.7 Composable Function

    A function MAY indicate that it is composable. If not explicitly indicated, it is not composable.

    A composable function can be invoked with additional path segments or key predicates appended to the resource path that identifies the composable function, and with system query options as appropriate for the type returned by the composable function.

    -
    -

    Attribute IsComposable

    +
    +

    Attribute IsComposable

    The value of IsComposable is one of the Boolean literals true or false. Absence of the attribute means false.

    12.8 Return Type

    @@ -1566,13 +1566,13 @@

    12.8 Return Typ

    The facets MaxLength, Precision, Scale, and SRID can be used as appropriate to specify value restrictions of the return type, as well as the Unicode facet for 4.01 and greater payloads.

    For a single-valued return type the facets apply to the returned value. For a collection-valued return type the facets apply to the items in the returned collection.

    -

    Element edm:ReturnType

    +

    Element edm:ReturnType

    The edm:ReturnType element MUST contain the Type attribute, and it MAY contain the attributes Nullable, MaxLength, Unicode, Precision, Scale, and SRID.

    It MAY contain edm:Annotation elements.

    -

    Attribute Type

    +

    Attribute Type

    For single-valued return types the value of Type is the qualified name of the return type.

    For collection-valued return types the value of Type is the character sequence Collection( followed by the qualified name of the return item type, followed by a closing parenthesis ).

    -

    Attribute Nullable

    +

    Attribute Nullable

    The value of Nullable is one of the Boolean literals true or false. Absence of the attribute means true.

    If the return type is a collection of entity types, the Nullable attribute has no meaning and MUST NOT be specified.

    For other collection-valued return types the result will always be a collection that MAY be empty. In this case the Nullable attribute applies to items of the collection and specifies whether the collection MAY contain null values.

    @@ -1586,15 +1586,15 @@

    12.9 Parameter<

    The facets MaxLength, Precision, Scale, or SRID can be used as appropriate to specify value restrictions of the parameter, as well as the Unicode facet for 4.01 and greater payloads.

    For single-valued parameters the facets apply to the parameter value. If the parameter value is a collection, the facets apply to the items in the collection.

    -

    Element edm:Parameter

    +

    Element edm:Parameter

    The edm:Parameter element MUST contain the Name and the Type attribute, and it MAY contain the attributes Nullable, MaxLength, Unicode, Precision, Scale, and SRID.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the parameter’s name.

    -

    Attribute Type

    +

    Attribute Type

    For single-valued parameters the value of Type is the qualified name of the parameter.

    For collection-valued parameters the value of Type is the character sequence Collection( followed by the qualified name of the parameter’s type, followed by a closing parenthesis ).

    -

    Attribute Nullable

    +

    Attribute Nullable

    The value of Nullable is one of the Boolean literals true or false. Absence of the attribute means true.

    The value true means that the parameter accepts a null value.

    @@ -1633,10 +1633,10 @@

    1

    A singleton allows addressing a single entity directly from the entity container without having to know its key, and without requiring an entity set.

    A function import or an action import is used to expose a function or action defined in an entity model as a top level resource.

    -

    Element edm:EntityContainer

    +

    Element edm:EntityContainer

    The edm:EntityContainer MUST contain one or more edm:EntitySet, edm:Singleton, edm:ActionImport, or edm:FunctionImport elements.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the entity container’s name.

    @@ -1662,8 +1662,8 @@

    An entity container MAY specify that it extends another entity container in scope. All children of the “base” entity container are added to the “extending” entity container.

    If the “extending” entity container defines an entity set with the same name as defined in any of its “base” containers, then the entity set’s type MUST specify an entity type derived from the entity type specified for the identically named entity set in the “base” container. The same holds for singletons. Action imports and function imports cannot be redefined, nor can the “extending” container define a child with the same name as a child of a different kind in a “base” container.

    Note: services should not introduce cycles by extending entity containers. Clients should be prepared to process cycles introduced by extending entity containers.

    -
    -

    Attribute Extends

    +
    +

    Attribute Extends

    The value of Extends is the qualified name of the entity container to be extended.

    @@ -1680,15 +1680,15 @@

    13.2 Entity SetAn entity set MAY indicate whether it is included in the service document. If not explicitly indicated, it is included.

    Entity sets that cannot be queried without specifying additional query options SHOULD NOT be included in the service document.

    -

    Element edm:EntitySet

    +

    Element edm:EntitySet

    The edm:EntitySet element MUST contain the attributes Name and EntityType, and it MAY contain the IncludeInServiceDocument attribute.

    It MAY contain edm:NavigationPropertyBinding elements.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the entity set’s name.

    -

    Attribute EntityType

    +

    Attribute EntityType

    The value of EntityType is the qualified name of an entity type in scope.

    -

    Attribute IncludeInServiceDocument

    +

    Attribute IncludeInServiceDocument

    The value of IncludeInServiceDocument is one of the Boolean literals true or false. Absence of the attribute means true.

    13.3 Singleton

    @@ -1697,15 +1697,15 @@

    13.3 Singleton<

    A singleton MUST specify a type that MUST be an entity type in scope.

    A singleton MUST reference an instance its entity type.

    -

    Element edm:Singleton

    +

    Element edm:Singleton

    The edm:Singleton element MUST include the attributes Name and Type, and it MAY contain the Nullable attribute.

    It MAY contain edm:NavigationPropertyBinding elements.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the singleton’s name.

    -

    Attribute Type

    +

    Attribute Type

    The value of Type is whose value is the qualified name of an entity type in scope.

    -

    Attribute Nullable

    +

    Attribute Nullable

    The value of Nullable is one of the Boolean literals true or false.

    If no value is specified, the Nullable attribute defaults to false.

    In OData 4.0 responses this attribute MUST NOT be specified.

    @@ -1726,11 +1726,11 @@

    13.4.

    If the target is a simple identifier, it MUST resolve to an entity set or singleton defined in the same entity container.

    If the target is a target path, it MUST resolve to an entity set, singleton, or direct or indirect containment navigation property of a singleton in scope. The path can traverse single-valued containment navigation properties or single-valued complex properties before ending in a containment navigation property, and there MUST NOT be any non-containment navigation properties prior to the final segment.

    -

    Element edm:NavigationPropertyBinding

    +

    Element edm:NavigationPropertyBinding

    The edm:NavigationPropertyBinding element MUST contain the attributes Path and Target.

    -

    Attribute Path

    +

    Attribute Path

    The value of Path is a path expression.

    -

    Attribute Target

    +

    Attribute Target

    The value of Target is a target path.

    @@ -1760,14 +1760,14 @@

    13.5 Acti

    An action import MUST specify the name of an unbound action in scope.

    If the imported action returns an entity or a collection of entities, a simple identifier or target path value MAY be specified to identify the entity set that contains the returned entities. If a simple identifier is specified, it MUST resolve to an entity set defined in the same entity container. If a target path is specified, it MUST resolve to an entity set in scope.

    -

    Element edm:ActionImport

    +

    Element edm:ActionImport

    The edm:ActionImport element MUST contain the attributes Name and Action, and it MAY contain the EntitySet attribute.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the action import’s name.

    -

    Attribute Action

    +

    Attribute Action

    The value of Action is the qualified name of an unbound action.

    -

    Attribute EntitySet

    +

    Attribute EntitySet

    The value of EntitySet is either the unqualified name of an entity set in the same entity container or a path to an entity set in a different entity container.

    13.6 Function Import

    @@ -1777,16 +1777,16 @@

    13.

    If the imported function returns an entity or a collection of entities, a simple identifier or target path value MAY be specified to identify the entity set that contains the returned entities. If a simple identifier is specified, it MUST resolve to an entity set defined in the same entity container. If a target path is specified, it MUST resolve to an entity set in scope.

    A function import for a parameterless function MAY indicate whether it is included in the service document. If not explicitly indicated, it is not included.

    -

    Element edm:FunctionImport

    +

    Element edm:FunctionImport

    The edm:FunctionImport element MUST contain the attributes Name and Function, and it MAY contain the attributes EntitySet and IncludeInServiceDocument.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the function import’s name.

    -

    Attribute Function

    +

    Attribute Function

    The value of Function is the qualified name of an unbound function.

    -

    Attribute EntitySet

    +

    Attribute EntitySet

    The value of EntitySet is either the unqualified name of an entity set in the same entity container or a path to an entity set in a different entity container.

    -

    Attribute IncludeInServiceDocument

    +

    Attribute IncludeInServiceDocument

    The value of IncludeInServiceDocument is one of the Boolean literals true or false. Absence of the attribute means false.


    @@ -1832,24 +1832,24 @@

    14.1 Term

    The term’s name is a simple identifier that MUST be unique within its schema.

    The term’s type MUST be a type in scope, or a collection of a type in scope.

    -

    Element edm:Term

    +

    Element edm:Term

    The edm:Term element MUST contain the attributes Name and Type. It MAY contain the attributes Nullable, DefaultValue, BaseTerm and AppliesTo.

    The facets MaxLength, Precision, Scale, and SRID can be used as appropriate, as well as the Unicode facet attribute for 4.01 and greater payloads.

    A edm:Term element whose Type attribute specifies a primitive or enumeration type MAY define a value for the DefaultValue attribute.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the term’s name.

    -

    Attribute Type

    +

    Attribute Type

    For single-valued terms the value of Type is the qualified name of the term’s type.

    For collection-valued properties the value of Type is the character sequence Collection( followed by the qualified name of the property’s item type, followed by a closing parenthesis ).

    -

    Attribute Nullable

    +

    Attribute Nullable

    The value of Nullable is one of the Boolean literals true or false.

    For single-valued terms the value true means that annotations may have the null value.

    For collection-valued terms the annotation value will always be a collection that MAY be empty. In this case the Nullable attribute applies to items of the collection and specifies whether the collection MAY contain null values.

    If no value is specified for a single-valued term, the Nullable attribute defaults to true.

    In OData 4.01 responses a collection-valued term MUST specify a value for the Nullable attribute.

    If no value is specified for a collection-valued term, the client cannot assume any default value. Clients SHOULD be prepared for this situation even in OData 4.01 responses.

    -

    Attribute DefaultValue

    +

    Attribute DefaultValue

    The value of this attribute determines the value of the term when applied in an edm:Annotation without providing an expression.

    Default values of type Edm.String MUST be represented according to the XML escaping rules for character data in attribute values. Values of other primitive types MUST be represented according to the appropriate alternative in the primitiveValue rule defined in OData-ABNF, i.e. Edm.Binary as binaryValue, Edm.Boolean as booleanValue etc.

    If no value is specified, the DefaultValue attribute defaults to null.

    @@ -1857,8 +1857,8 @@

    14.1.1 Specialized Term

    A term MAY specialize another term in scope by specifying it as its base term.

    When applying a specialized term, the base term MUST also be applied with the same qualifier, and so on until a term without a base term is reached.

    -
    -

    Attribute BaseTerm

    +
    +

    Attribute BaseTerm

    The value of BaseTerm is the qualified name of the base term.

    14.1.2 Applicability

    @@ -2005,8 +2005,8 @@

    14.1.2 -
    -

    Attribute AppliesTo

    +
    +

    Attribute AppliesTo

    The value of AppliesTo is a whitespace-separated list of symbolic values from the table above that identify model elements the term is intended to be applied to.

    @@ -2025,13 +2025,13 @@

    14.2 Annotation<

    An annotation applies a term to a model element and defines how to calculate a value for the term application. Both term and model element MUST be in scope. Section 14.1.2 specifies which model elements MAY be annotated with a term.

    The value of an annotation is specified as an annotation expression, which is either a constant expression representing a constant value, or a dynamic expression. The most common construct for assigning an annotation value is a path expression that refers to a property of the same or a related structured type.

    -

    Element edm:Annotation

    +

    Element edm:Annotation

    The edm:Annotation element MUST contain the attribute Term, and it MAY contain the attribute Qualifier.

    The value of the annotation MAY be a constant expression or dynamic expression.

    If no expression is specified for a term with a primitive type, the annotation evaluates to the default value of the term definition. If no expression is specified for a term with a complex type, the annotation evaluates to a complex instance with default values for its properties. If no expression is specified for a collection-valued term, the annotation evaluates to an empty collection.

    An edm:Annotation element can be used as a child of the model element it annotates, or as the child of an edm:Annotations element that targets the model element to be annotated.

    An edm:Annotation element MAY contain edm:Annotation elements that annotate the annotation.

    -

    Attribute Term

    +

    Attribute Term

    The value of Term is the qualified name of a term in scope.

    @@ -2053,8 +2053,8 @@

    14.2.1 Qualifier

    A term can be applied multiple times to the same model element by providing a qualifier to distinguish the annotations. The qualifier is a simple identifier.

    The combination of target model element, term, and qualifier uniquely identifies an annotation.

    -
    -

    Attribute Qualifier

    +
    +

    Attribute Qualifier

    Annotation elements that are children of an edm:Annotations element MUST NOT provide a value for the qualifier attribute if the parent edm:Annotations element provides a value for the qualifier attribute.

    @@ -2204,8 +2204,8 @@

    14.2.2 Target

    14.3 Constant Expression

    Constant expressions allow assigning a constant value to an applied term.

    14.3.1 Binary

    -
    -

    Expression edm:Binary

    +
    +

    Expression edm:Binary

    The edm:Binary expression evaluates to a primitive binary value. A binary expression MUST be assigned a value conforming to the rule binaryValue in OData-ABNF.

    The binary expression MAY be provided using element notation or attribute notation.

    @@ -2218,8 +2218,8 @@

    Expression </Annotation>

    14.3.2 Boolean

    -
    -

    Expression edm:Bool

    +
    +

    Expression edm:Bool

    The edm:Bool expression evaluates to a primitive Boolean value. A Boolean expression MUST be assigned a Boolean value.

    The Boolean expression MAY be provided using element notation or attribute notation.

    @@ -2232,8 +2232,8 @@

    Expression </Annotation>

    14.3.3 Date

    -
    -

    Expression edm:Date

    +
    +

    Expression edm:Date

    The edm:Date expression evaluates to a primitive date value. A date expression MUST be assigned a value of type xs:date, see XML-Schema-2, section 3.3.9. The value MUST also conform to rule dateValue in OData-ABNF, i.e. it MUST NOT contain a time-zone offset.

    The date expression MAY be provided using element notation or attribute notation.

    @@ -2246,8 +2246,8 @@

    Expression </Annotation>

    14.3.4 DateTimeOffset

    -
    -

    Expression edm:DateTimeOffset

    +
    +

    Expression edm:DateTimeOffset

    The edm:DateTimeOffset expression evaluates to a primitive datetimestamp value with a time-zone offset. A datetimestamp expression MUST be assigned a value of type xs:dateTimeStamp, see XML-Schema-2, section 3.4.28. The value MUST also conform to rule dateTimeOffsetValue in OData-ABNF, i.e. it MUST NOT contain an end-of-day fragment (24:00:00).

    The datetimestamp expression MAY be provided using element notation or attribute notation.

    @@ -2262,8 +2262,8 @@

    </Annotation>

    14.3.5 Decimal

    -
    -

    Expression edm:Decimal

    +
    +

    Expression edm:Decimal

    The edm:Decimal expression evaluates to a primitive decimal value. A decimal expression MUST be assigned a value conforming to the rule decimalValue in OData-ABNF.

    The decimal expression MAY be provided using element notation or attribute notation.

    @@ -2278,8 +2278,8 @@

    Expression </Annotation>

    14.3.6 Duration

    -
    -

    Expression edm:Duration

    +
    +

    Expression edm:Duration

    The edm:Duration expression evaluates to a primitive duration value. A duration expression MUST be assigned a value of type xs:dayTimeDuration, see XML-Schema-2, section 3.4.27.

    The duration expression MAY be provided using element notation or attribute notation.

    @@ -2292,8 +2292,8 @@

    Expressio </Annotation>

    14.3.7 Enumeration Member

    -
    -

    Expression edm:EnumMember

    +
    +

    Expression edm:EnumMember

    The edm:EnumMember expression references a member of an enumeration type. An enumeration member expression MUST be assigned a value that consists of the qualified name of the enumeration type, followed by a forward slash and the name of the enumeration member. If the enumeration type specifies an IsFlags attribute with value true, the expression MAY also be assigned a whitespace-separated list of values. Each of these values MUST resolve to the name of a member of the enumeration type of the specified term.

    The enumeration member expression MAY be provided using element notation or attribute notation.

    @@ -2316,8 +2316,8 @@

    Expre </Annotation>

    14.3.8 Floating-Point Number

    -
    -

    Expression edm:Float

    +
    +

    Expression edm:Float

    The edm:Float expression evaluates to a primitive floating point (or double) value. A float expression MUST be assigned a value conforming to the rule doubleValue in OData-ABNF.

    The float expression MAY be provided using element notation or attribute notation.

    @@ -2330,8 +2330,8 @@

    Expression </Annotation>

    14.3.9 Guid

    -
    -

    Expression edm:Guid

    +
    +

    Expression edm:Guid

    The edm:Guid expression evaluates to a primitive guid value. A guid expression MUST be assigned a value conforming to the rule guidValue in OData-ABNF.

    The guid expression MAY be provided using element notation or attribute notation.

    @@ -2345,8 +2345,8 @@

    Expression </Annotation>

    14.3.10 Integer

    -
    -

    Expression edm:Int

    +
    +

    Expression edm:Int

    The edm:Int expression evaluates to a primitive integer value. An integer MUST be assigned a value conforming to the rule int64Value in OData-ABNF.

    The integer expression MAY be provided using element notation or attribute notation.

    @@ -2361,8 +2361,8 @@

    Expression ed </Annotation>

    14.3.11 String

    -
    -

    Expression edm:String

    +
    +

    Expression edm:String

    The edm:String expression evaluates to a primitive string value. A string expression MUST be assigned a value of the type xs:string, see XML-Schema-2, section 3.3.1.

    The string expression MAY be provided using element notation or attribute notation.

    @@ -2375,8 +2375,8 @@

    Expression </Annotation>

    14.3.12 Time of Day

    -
    -

    Expression edm:TimeOfDay

    +
    +

    Expression edm:TimeOfDay

    The edm:TimeOfDay expression evaluates to a primitive time value. A time-of-day expression MUST be assigned a value conforming to the rule timeOfDayValue in OData-ABNF.

    The time-of-day expression MAY be provided using element notation or attribute notation.

    @@ -2521,8 +2521,8 @@

    1

    A term or term property of type Edm.AnnotationPath can be annotated with the term Validation.AllowedTerms (see OData-VocValidation) if its intended value is an annotation path that ends in a term cast with one of the listed terms.

    The value of the annotation path expression is the path itself, not the value of the annotation identified by the path. This is useful for terms that reuse or refer to other terms.

    -
    -

    Expression edm:AnnotationPath

    +
    +

    Expression edm:AnnotationPath

    The edm:AnnotationPath expression MAY be provided using element notation or attribute notation.

    @@ -2540,8 +2540,8 @@

    14.4.1.4 Model Element Path

    The model element path expression provides a value for terms or term properties that specify the built-in type Edm.ModelElementPath. Its argument is a model path.

    The value of the model element path expression is the path itself, not the instance(s) identified by the path.

    -
    -

    Expression edm:ModelElementPath

    +
    +

    Expression edm:ModelElementPath

    The edm:ModelElementPath expression MAY be provided using element notation or attribute notation.

    @@ -2559,8 +2559,8 @@

    -

    Expression edm:NavigationPropertyPath

    +
    +

    Expression edm:NavigationPropertyPath

    The edm:NavigationPropertyPath expression MAY be provided using element notation or attribute notation.

    @@ -2584,8 +2584,8 @@

    14.4.1.
  • A non-null path MUST resolve to a model element whose type is a primitive or complex type, an enumeration type, a type definition, or a collection of one of these types.
  • The value of the property path expression is the path itself, not the value of the structural property or the value of the term cast identified by the path.

    -
    -

    Expression edm:PropertyPath

    +
    +

    Expression edm:PropertyPath

    The edm:PropertyPath MAY be provided using either element notation or attribute notation.

    @@ -2606,8 +2606,8 @@

    E

    14.4.1.7 Value Path

    The value path expression allows assigning a value by traversing an object graph. It can be used in annotations that target entity containers, entity sets, entity types, complex types, navigation properties of structured types, and structural properties of structured types. Its argument is an instance path.

    The value of the path expression is the instance or collection of instances identified by the path.

    -
    -

    Expression edm:Path

    +
    +

    Expression edm:Path

    The edm:Path expression MAY be provided using element notation or attribute notation.

    @@ -2640,13 +2640,13 @@

    OData-URL.

    The other comparison operators require two operand expressions that evaluate to comparable values.

    -

    Expressions edm:And and edm:Or

    +

    Expressions edm:And and edm:Or

    The And and Or logical expressions are represented as elements edm:And and edm:Or that MUST contain two annotation expressions.

    It MAY contain edm:Annotation elements.

    -

    Expression edm:Not

    +

    Expression edm:Not

    Negation expressions are represented as an element edm:Not that MUST contain a single annotation expression.

    It MAY contain edm:Annotation elements.

    -

    Expressions edm:Eq, edm:Ne, edm:Gt, edm:Ge, edm:Lt, edm:Le, edm:Has, and edm:In

    +

    Expressions edm:Eq, edm:Ne, edm:Gt, edm:Ge, edm:Lt, edm:Le, edm:Has, and edm:In

    All comparison expressions are represented as an element that MUST contain two annotation expressions.

    They MAY contain edm:Annotation elements.

    @@ -2741,10 +2741,10 @@

    -

    Expression edm:Neg

    +

    Expression edm:Neg

    Negation expressions are represented as an element edm:Neg that MUST contain a single annotation expression.

    It MAY contain edm:Annotation elements.

    -

    Expressions edm:Add, edm:Sub, edm:Mul, edm:Div, edm:DivBy, and edm:Mod

    +

    Expressions edm:Add, edm:Sub, edm:Mul, edm:Div, edm:DivBy, and edm:Mod

    These arithmetic expressions are represented as an element that MUST contain two annotation expressions.

    They MAY contain edm:Annotation elements.

    @@ -2781,10 +2781,10 @@

    14.4.4 Apply Client-Side Functions

    The apply expression enables a value to be obtained by applying a client-side function. The apply expression MAY have operand expressions. The operand expressions are used as parameters to the client-side function.

    -

    Expression edm:Apply

    +

    Expression edm:Apply

    The edm:Apply element MUST contain the Function attribute and MAY contain annotation expressions as operands for the applied function.

    It MAY contain more edm:Annotation elements.

    -

    Attribute Function

    +

    Attribute Function

    The value of Function is the qualified name of the client-side function to apply.

    OData defines the following functions. Services MAY support additional functions that MUST be qualified with a namespace other than odata. Function names qualified with odata are reserved for this specification and its future versions.

    @@ -2847,10 +2847,10 @@

    14.4.5 Cast

    The cast expression casts the value obtained from its single child expression to the specified type. The cast expression follows the same rules as the cast canonical function defined in OData-URL.

    -

    Expression edm:Cast

    +

    Expression edm:Cast

    The edm:Cast element MUST contain the Type attribute and MUST contain exactly one expression.

    It MAY contain edm:Annotation elements.

    -

    Attribute Type

    +

    Attribute Type

    The value of Type is a qualified type name in scope, or the character sequence Collection( followed by the qualified name of a type in scope, followed by a closing parenthesis ).

    If the specified type is a primitive type or a collection of a primitive type, the facet attributes MaxLength, Unicode, Precision, Scale, and SRID MAY be specified if applicable to the specified primitive type. If the facet attributes are not specified, their values are considered unspecified.

    @@ -2864,8 +2864,8 @@

    14.4.6 Collection

    The collection expression enables a value to be obtained from zero or more item expressions. The value calculated by the collection expression is the collection of the values calculated by each of the item expressions. The values of the child expressions MUST all be type compatible.

    -
    -

    Expression edm:Collection

    +
    +

    Expression edm:Collection

    The edm:Collection element contains zero or more child expressions.

    @@ -2883,8 +2883,8 @@

    14.4.7 If-The

    The first child expression is the condition and MUST evaluate to a Boolean result, e.g. the comparison and logical operators can be used.

    The second and third child expressions are evaluated conditionally. The result MUST be type compatible with the type expected by the surrounding expression.

    If the first expression evaluates to true, the second expression MUST be evaluated and its value MUST be returned as the result of the if-then-else expression. If the first expression evaluates to false and a third child element is present, it MUST be evaluated and its value MUST be returned as the result of the if-then-else expression. If no third expression is present, nothing is added to the surrounding collection.

    -
    -

    Expression edm:If

    +
    +

    Expression edm:If

    The edm:If element MUST contain two or three child expressions that MUST use element notation.

    It MAY contain edm:Annotation elements.

    @@ -2900,8 +2900,8 @@

    Expression edm:

    14.4.8 Is-Of

    The is-of expression checks whether the value obtained from its single child expression is compatible with the specified type. It returns true if the child expression returns a type that is compatible with the specified type, and false otherwise.

    -
    -

    Expression edm:UrlRef

    +
    +

    Expression edm:UrlRef

    The edm:UrlRef expression MAY be provided using element notation or attribute notation.

    Relative URLs are relative to the xml:base attribute, see XML-Base.

    In element notation it MAY contain edm:Annotation elements.

    @@ -2919,11 +2919,11 @@

    14

    A labeled element expression MUST contain exactly one child expression. The value of the child expression is also the value of the labeled element expression.

    A labeled element expression MUST provide a simple identifier value as its name that MUST be unique within the schema containing the expression.

    -

    Expression edm:LabeledElement

    +

    Expression edm:LabeledElement

    The edm:LabeledElement element MUST contain the Name attribute.

    It MUST contain a child expression written either in attribute notation or element notation.

    It MAY contain edm:Annotation elements.

    -

    Attribute Name

    +

    Attribute Name

    The value of Name is the labeled element’s name.

    @@ -2940,8 +2940,8 @@

    14.4.10 Labeled Element Reference

    The labeled element reference expression MUST specify the qualified name of a labeled element expression in scope and returns the value of the identified labeled element expression as its value.

    -
    -

    Expression edm:LabeledElementReference

    +
    +

    Expression edm:LabeledElementReference

    The edm:LabeledElementReference element MUST contain the qualified name of a labeled element expression in its body.

    @@ -2952,8 +2952,8 @@

    14.4.11 Null

    The null expression indicates the absence of a value. The null expression MAY be annotated.

    -
    -

    Expression edm:Null

    +
    +

    Expression edm:Null

    The edm:Null element MAY contain edm:Annotation elements.

    @@ -2976,15 +2976,15 @@

    14.4.12 Record

    A record expression contains zero or more property value expressions. For each single-valued structural or navigation property of the record expression’s type that is neither nullable nor specifies a default value a property value expression MUST be provided. The only exception is if the record expression is the value of an annotation for a term that has a base term whose type is structured and directly or indirectly inherits from the type of its base term. In this case, property values that already have been specified in the annotation for the base term or its base term etc. need not be specified again.

    For collection-valued properties the absence of a property value expression is equivalent to specifying an empty collection as its value.

    -

    Expression edm:Record

    +

    Expression edm:Record

    The edm:Record element MAY contain the Type attribute and MAY contain edm:PropertyValue elements.

    It MAY contain edm:Annotation elements.

    -

    Attribute Type

    +

    Attribute Type

    The value of Type is the qualified name of a structured type in scope.

    -

    Element edm:PropertyValue

    +

    Element edm:PropertyValue

    The edm:PropertyValue element MUST contain the Property attribute, and it MUST contain exactly one expression that MAY be provided using either element notation or attribute notation.

    It MAY contain edm:Annotation elements.

    -

    Attribute Property

    +

    Attribute Property

    The value of Property is the name of a property of the type of the enclosing edm:Record expression.

    @@ -3015,8 +3015,8 @@

    14.4.13

    The URL reference expression enables a value to be obtained by sending a GET request.

    The URL reference expression MUST contain exactly one expression of type Edm.String. Its value is treated as a URL that MAY be relative or absolute; relative URLs are relative to the URL of the document containing the URL reference expression, or relative to a base URL specified in a format-specific way.

    The response body of the GET request MUST be returned as the result of the URL reference expression. The result of the URL reference expression MUST be type compatible with the type expected by the surrounding expression.

    -
    -

    Expression edm:UrlRef

    +
    +

    Expression edm:UrlRef

    The edm:UrlRef expression MAY be provided using element notation or attribute notation.

    Relative URLs are relative to the xml:base attribute, see XML-Base.

    In element notation it MAY contain edm:Annotation elements.

    @@ -3318,243 +3318,243 @@
    [OpenUI5]

    Appendix B. Table of XML Elements and Attributes


    diff --git a/docs/odata-csdl-xml/odata-csdl-xml.md b/docs/odata-csdl-xml/odata-csdl-xml.md index 8e5e9d69f..a0f65d5e4 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.md +++ b/docs/odata-csdl-xml/odata-csdl-xml.md @@ -582,8 +582,8 @@ length. ::: {.varxml .rep} -### Type Facet Attributes -### Attribute `MaxLength` +### Type Facet Attributes +### Attribute `MaxLength` The value of `MaxLength` is a positive integer or the symbolic value `max` as a shorthand for the maximum length supported for the type by @@ -621,7 +621,7 @@ see [OData-VocMeasures](#ODataVocMeasures). ::: {.varxml .rep} -### Attribute `Precision` +### Attribute `Precision` The value of `Precision` is a number. @@ -677,7 +677,7 @@ client-provided values may have to be rounded before being stored. ::: {.varxml .rep} -### Attribute `Scale` +### Attribute `Scale` The value of `Scale` is a number or one of the symbolic values `floating` or `variable`. @@ -735,7 +735,7 @@ If no value is specified, the `Unicode` facet defaults to `true`. ::: {.varxml .rep} -### Attribute `Unicode` +### Attribute `Unicode` The value of `Unicode` is one of the Boolean literals `true` or `false`. Absence of the attribute means `true`. @@ -755,7 +755,7 @@ by the European Petroleum Survey Group [EPSG](#_EPSG). ::: {.varxml .rep} -### Attribute `SRID` +### Attribute `SRID` The value of `SRID` is a number or the symbolic value `variable`. ::: @@ -839,7 +839,7 @@ combination of term and qualifier. ::: {.varxml .rep} -### Element `edmx:Edmx` +### Element `edmx:Edmx` The `edmx:Edmx` element is the root element of a CSDL XML document. It MUST contain the `Version` attribute and it MUST contain exactly one @@ -848,7 +848,7 @@ MUST contain the `Version` attribute and it MUST contain exactly one It MAY contain [`edmx:Reference`](#Reference) elements to reference other CSDL documents. -### Attribute `Version` +### Attribute `Version` The `Version` attribute specifies the OData protocol version of the service. For OData 4.0 responses the value of this attribute MUST be @@ -856,7 +856,7 @@ service. For OData 4.0 responses the value of this attribute MUST be `4.01`. Services MUST return an OData 4.0 response if the request was made with an `OData-MaxVersion` header with a value of `4.0`. -### Element `edmx:DataServices` +### Element `edmx:DataServices` The `edmx:DataServices` element MUST contain one or more [`edm:Schema`](#Schema) elements which define the schemas exposed by the @@ -903,7 +903,7 @@ referenced schema document. ::: {.varxml .rep} -### Element `edmx:Reference` +### Element `edmx:Reference` The `edmx:Reference` element specifies external CSDL documents referenced by the referencing document. The child elements @@ -918,7 +918,7 @@ MUST contain at least one [`edmx:Include`](#IncludedSchema) or It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Uri` +### Attribute `Uri` The value of `Uri` is an absolute or relative URI; relative URIs are relative to the `xml:base` attribute, see @@ -987,7 +987,7 @@ referencing document may define its own aliases for included schemas. ::: {.varxml .rep} -### Element `edmx:Include` +### Element `edmx:Include` The `edmx:Include` element specifies a schema to include from the referenced CSDL document. It MUST provide the `Namespace` attribute and @@ -995,12 +995,12 @@ it MAY provide the `Alias` attribute. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Namespace` +### Attribute `Namespace` The value of `Namespace` is the namespace of a schema defined in the referenced CSDL document. -### Attribute `Alias` +### Attribute `Alias` The value of `Alias` is a [simple identifier](#SimpleIdentifier) that can be used in qualified names instead of the namespace. @@ -1072,7 +1072,7 @@ not to inspect the referenced document. ::: {.varxml .rep} -### Element `edmx:IncludeAnnotations` +### Element `edmx:IncludeAnnotations` The `edmx:IncludeAnnotations` element specifies the annotations to include from the referenced CSDL document. If no @@ -1084,15 +1084,15 @@ The `edmx:IncludeAnnotations` element MUST provide the `TermNamespace` attribute, and it MAY provide the `Qualifier` and `TargetNamespace` attribute. -### Attribute `TermNamespace` +### Attribute `TermNamespace` The value of `TermNamespace` is a namespace. -### Attribute `Qualifier` +### Attribute `Qualifier` The value of `Qualifier` is a [simple identifier](#SimpleIdentifier). -### Attribute `TargetNamespace` +### Attribute `TargetNamespace` The value of `TargetNamespace` is a namespace. ::: @@ -1162,7 +1162,7 @@ The namespace MUST NOT be one of the reserved values `Edm`, `odata`, ::: {.varxml .rep} -### Element `edm:Schema` +### Element `edm:Schema` The `edm:Schema` element defines a schema. It MUST contain the `Namespace` attribute and it MAY @@ -1176,7 +1176,7 @@ It MAY contain elements [`edm:Action`](#Action), [`edm:Function`](#Function), [`edm:Term`](#Term), or [`edm:TypeDefinition`](#TypeDefinition). -### Attribute `Namespace` +### Attribute `Namespace` The value of `Namespace` is the namespace of the schema ::: @@ -1207,7 +1207,7 @@ The alias MUST NOT be one of the reserved values `Edm`, `odata`, ::: {.varxml .rep} -### Attribute `Alias` +### Attribute `Alias` The value of `Alias` is a [simple identifier](#SimpleIdentifier). ::: @@ -1228,7 +1228,7 @@ schema ::: {.varxml .rep} -### Element `edm:Annotations` +### Element `edm:Annotations` The `edm:Annotations` element is used to apply a group of annotations to a single model element. It MUST contain the `Target` attribute and it @@ -1236,12 +1236,12 @@ MAY contain the `Qualifier` attribute. It MUST contain at least one [`edm:Annotation`](#Annotation) element. -### Attribute `Target` +### Attribute `Target` The value of `Target` is a path expression identifying the [annotation target](#Target). It MUST resolve to a model element in scope. -### Attribute `Qualifier` +### Attribute `Qualifier` The value of `Qualifier` is a [simple identifier](#SimpleIdentifier). ::: @@ -1283,7 +1283,7 @@ types. ::: {.varxml .rep} -### Element `edm:EntityType` +### Element `edm:EntityType` The `edm:EntityType` element MUST contain the `Name` attribute, and it MAY contain the [`BaseType`](#DerivedEntityType), @@ -1298,7 +1298,7 @@ It MAY contain one [`edm:Key`](#Key) element. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the entity type's name. ::: @@ -1332,7 +1332,7 @@ base type. ::: {.varxml .rep} -### Attribute `BaseType` +### Attribute `BaseType` The value of `BaseType` is the qualified name of the base type. ::: @@ -1366,7 +1366,7 @@ type. ::: {.varxml .rep} -### Attribute `Abstract` +### Attribute `Abstract` The value of `Abstract` is one of the Boolean literals `true` or `false`. Absence of the attribute means `false`. @@ -1390,7 +1390,7 @@ properties on instances of any structured type, see ::: {.varxml .rep} -### Attribute `OpenType` +### Attribute `OpenType` The value of `OpenType` is one of the Boolean literals `true` or `false`. Absence of the attribute means `false`. @@ -1419,7 +1419,7 @@ see [OData-VocCore](#ODataVocCore). ::: {.varxml .rep} -### Attribute `HasStream` +### Attribute `HasStream` The value of `HasStream` is one of the Boolean literals `true` or `false`. Absence of the attribute means `false`. @@ -1506,23 +1506,23 @@ special encoding and are a standard constituent of expressions anyway. ::: {.varxml .rep} -### Element `edm:Key` +### Element `edm:Key` The `edm:Key` element MUST contain at least one `edm:PropertyRef` element. -### Element `edm:PropertyRef` +### Element `edm:PropertyRef` The `edm:PropertyRef` element MUST contain the `Name` attribute and MAY contain the `Alias` attribute. -### Attribute `Name` +### Attribute `Name` The value of `Name` is a path expression leading to a primitive property. The names of the properties in the path are joined together by forward slashes. -### Attribute `Alias` +### Attribute `Alias` The value of `Alias` is a [simple identifier](#SimpleIdentifier). ::: @@ -1622,7 +1622,7 @@ that differ only in case. ::: {.varxml .rep} -### Element `edm:Property` +### Element `edm:Property` The `edm:Property` element MUST contain the `Name` and the `Type` attribute, and it MAY contain the attributes @@ -1632,7 +1632,7 @@ attribute, and it MAY contain the attributes It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the property's name. ::: @@ -1669,7 +1669,7 @@ supports inserting items into a specific ordinal position. ::: {.varxml .rep} -### Attribute `Type` +### Attribute `Type` For single-valued properties the value of `Type` is the qualified name of the property's type. @@ -1694,7 +1694,7 @@ A Boolean value specifying whether the property can have the value ::: {.varxml .rep} -### Attribute `Nullable` +### Attribute `Nullable` The value of `Nullable` is one of the Boolean literals `true` or `false`. @@ -1728,7 +1728,7 @@ If no value is specified, the client SHOULD NOT assume a default value. ::: {.varxml .rep} -### Attribute `DefaultValue` +### Attribute `DefaultValue` Default values of type `Edm.String` MUST be represented according to the XML escaping rules for character data in attribute values. Values of @@ -1765,7 +1765,7 @@ that differ only in case. ::: {.varxml .rep} -### Element `edm:NavigationProperty` +### Element `edm:NavigationProperty` The `edm:NavigationProperty` element MUST contain the `Name` and `Type` attributes, and it MAY contain the attributes @@ -1779,7 +1779,7 @@ child element [`edm:OnDelete`](#OnDeleteAction). It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the navigation property's name. ::: @@ -1830,7 +1830,7 @@ supports inserting items into a specific ordinal position. ::: {.varxml .rep} -### Attribute `Type` +### Attribute `Type` For single-valued navigation properties the value of `Type` is the qualified name of the navigation property's type. @@ -1851,7 +1851,7 @@ property, a collection is allowed to have zero items. ::: {.varxml .rep} -### Attribute `Nullable` +### Attribute `Nullable` The value of `Nullable` is one of the Boolean literals `true` or `false`. Absence of the attribute means `true`. @@ -1891,7 +1891,7 @@ partner navigation property. ::: {.varxml .rep} -### Attribute `Partner` +### Attribute `Partner` The value of `Partner` is the path to the of the partner navigation property. @@ -1966,7 +1966,7 @@ can also be reached via a non-containment navigation path. ::: {.varxml .rep} -### Attribute `ContainsTarget` +### Attribute `ContainsTarget` The value of `ContainsTarget` is one of the Boolean literals `true` or `false`. Absence of the attribute means `false`. @@ -2000,14 +2000,14 @@ property MUST NOT be nullable. ::: {.varxml .rep} -### Element `edm:ReferentialConstraint` +### Element `edm:ReferentialConstraint` The `edm:ReferentialConstraint` element MUST contain the attributes `Property` and `ReferencedProperty`. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Property` +### Attribute `Property` The `Property` attribute specifies the property that takes part in the referential constraint on the dependent structured type. Its value MUST @@ -2017,7 +2017,7 @@ dependent structured type. The names of the properties in the path are joined together by forward slashes. The path is relative to the dependent structured type declaring the navigation property. -### Attribute `ReferencedProperty` +### Attribute `ReferencedProperty` The `ReferencedProperty` attribute specifies the corresponding property of the principal entity type. Its value MUST be a path expression @@ -2085,13 +2085,13 @@ not predictable by the client and could vary per entity. ::: {.varxml .rep} -### Element `edm:OnDelete` +### Element `edm:OnDelete` The `edm:OnDelete` element MUST contain the `Action` attribute. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Action` +### Attribute `Action` The value of `Action` is one of the values `Cascade`, `None`, `SetNull`, or `SetDefault`. @@ -2141,7 +2141,7 @@ types. ::: {.varxml .rep} -### Element `edm:ComplexType` +### Element `edm:ComplexType` The `edm:ComplexType` element MUST contain the `Name` attribute, and it MAY contain the [`BaseType`](#DerivedComplexType), @@ -2154,7 +2154,7 @@ properties of the complex type. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the complex type's name. ::: @@ -2197,7 +2197,7 @@ The rules for annotations of derived complex types are described in ::: {.varxml .rep} -### Attribute `BaseType` +### Attribute `BaseType` The value of `BaseType` is the qualified name of the base type. ::: @@ -2209,7 +2209,7 @@ instances. ::: {.varxml .rep} -### Attribute `Abstract` +### Attribute `Abstract` The value of `Abstract` is one of the Boolean literals `true` or `false`. Absence of the attribute means `false`. @@ -2233,7 +2233,7 @@ properties on instances of any structured type, see ::: {.varxml .rep} -### Attribute `OpenType` +### Attribute `OpenType` The value of `OpenType` is one of the Boolean literals `true` or `false`. Absence of the attribute means `false`. @@ -2262,7 +2262,7 @@ one enumeration member at a time. ::: {.varxml .rep} -### Element `edm:EnumType` +### Element `edm:EnumType` The `edm:EnumType` element MUST contain the Name attribute, and it MAY contain the [`UnderlyingType`](#UnderlyingIntegerType) and @@ -2273,7 +2273,7 @@ elements defining the members of the enumeration type. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the enumeration type's name. ::: @@ -2299,7 +2299,7 @@ If not explicitly specified, `Edm.Int32` is used as the underlying type. ::: {.varxml .rep} -### Attribute `UnderlyingType` +### Attribute `UnderlyingType` The value of `UnderlyingType` is the qualified name of the underlying type. @@ -2316,7 +2316,7 @@ selected simultaneously. ::: {.varxml .rep} -### Attribute `IsFlags` +### Attribute `IsFlags` The value of `IsFlags` is one of the Boolean literals `true` or `false`. Absence of the attribute means `false`. @@ -2368,18 +2368,18 @@ values. ::: {.varxml .rep} -### Element `edm:Member` +### Element `edm:Member` The `edm:Member` element MUST contain the `Name` attribute and it MAY contain the `Value` attribute. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the enumeration member's name. -### Attribute `Value` +### Attribute `Value` If the [`IsFlags`](#FlagsEnumerationType) attribute has a value of `false`, either all members MUST specify an integer value for the @@ -2439,14 +2439,14 @@ definition is used, and whether they can be overridden. ::: {.varxml .rep} -### Element `edm:TypeDefinition` +### Element `edm:TypeDefinition` The `edm:TypeDefinition` element MUST contain the `Name` and [`UnderlyingType`](#UnderlyingPrimitiveType) attributes. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the type definition's name. ::: @@ -2479,7 +2479,7 @@ MUST NOT be another type definition. ::: {.varxml .rep} -### Attribute `UnderlyingType` +### Attribute `UnderlyingType` The value of `UnderlyingType` is the qualified name of the underlying type. @@ -2541,7 +2541,7 @@ An unbound action MAY have the same name as a bound action. ::: {.varxml .rep} -### Element `edm:Action` +### Element `edm:Action` The `edm:Action` element MUST contain the `Name` attribute and it MAY contain the [`IsBound`](#BoundorUnboundActionorFunctionOverloads) and @@ -2552,7 +2552,7 @@ MAY contain [`edm:Parameter`](#Parameter) elements. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the action's name. ::: @@ -2607,7 +2607,7 @@ they specify the same underlying type. ::: {.varxml .rep} -### Element `edm:Function` +### Element `edm:Function` The `edm:Function` element MUST contain the `Name` attribute and it MAY contain the [`IsBound`](#BoundorUnboundActionorFunctionOverloads) and @@ -2618,7 +2618,7 @@ contain [`edm:Parameter`](#Parameter) elements. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the action's name. ::: @@ -2641,7 +2641,7 @@ or from the entity container through a [function import](#FunctionImport). ::: {.varxml .rep} -### Attribute `IsBound` +### Attribute `IsBound` The value of `IsBound` is one of the Boolean literals `true` or `false`. Absence of the attribute means `false`. @@ -2668,7 +2668,7 @@ entity type that should be returned from the type cast. ::: {.varxml .rep} -### Attribute `EntitySetPath` +### Attribute `EntitySetPath` The value of `EntitySetPath` is the entity set path. ::: @@ -2685,7 +2685,7 @@ the type returned by the composable function. ::: {.varxml .rep} -### Attribute `IsComposable` +### Attribute `IsComposable` The value of `IsComposable` is one of the Boolean literals `true` or `false`. Absence of the attribute means `false`. @@ -2707,7 +2707,7 @@ returned collection. ::: {.varxml .rep} -### Element `edm:ReturnType` +### Element `edm:ReturnType` The `edm:ReturnType` element MUST contain the `Type` attribute, and it MAY contain the attributes `Nullable`, [`MaxLength`](#MaxLength), @@ -2716,7 +2716,7 @@ MAY contain the attributes `Nullable`, [`MaxLength`](#MaxLength), It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Type` +### Attribute `Type` For single-valued return types the value of `Type` is the qualified name of the return type. @@ -2725,7 +2725,7 @@ For collection-valued return types the value of `Type` is the character sequence `Collection(` followed by the qualified name of the return item type, followed by a closing parenthesis `)`. -### Attribute `Nullable` +### Attribute `Nullable` The value of `Nullable` is one of the Boolean literals `true` or `false`. Absence of the attribute means `true`. @@ -2771,7 +2771,7 @@ the collection. ::: {.varxml .rep} -### Element `edm:Parameter` +### Element `edm:Parameter` The `edm:Parameter` element MUST contain the `Name` and the `Type` attribute, and it MAY contain the attributes `Nullable`, @@ -2780,11 +2780,11 @@ attribute, and it MAY contain the attributes `Nullable`, It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the parameter's name. -### Attribute `Type` +### Attribute `Type` For single-valued parameters the value of `Type` is the qualified name of the parameter. @@ -2793,7 +2793,7 @@ For collection-valued parameters the value of `Type` is the character sequence `Collection(` followed by the qualified name of the parameter's type, followed by a closing parenthesis `)`. -### Attribute `Nullable` +### Attribute `Nullable` The value of `Nullable` is one of the Boolean literals `true` or `false`. Absence of the attribute means `true`. @@ -2880,7 +2880,7 @@ in an entity model as a top level resource. ::: {.varxml .rep} -### Element `edm:EntityContainer` +### Element `edm:EntityContainer` The `edm:EntityContainer` MUST contain one or more [`edm:EntitySet`](#EntitySet), [`edm:Singleton`](#Singleton), @@ -2889,7 +2889,7 @@ The `edm:EntityContainer` MUST contain one or more It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the entity container's name. ::: @@ -2938,7 +2938,7 @@ extending entity containers. ::: {.varxml .rep} -### Attribute `Extends` +### Attribute `Extends` The value of `Extends` is the qualified name of the entity container to be extended. @@ -2977,7 +2977,7 @@ options SHOULD NOT be included in the service document. ::: {.varxml .rep} -### Element `edm:EntitySet` +### Element `edm:EntitySet` The `edm:EntitySet` element MUST contain the attributes `Name` and `EntityType`, and it MAY contain the `IncludeInServiceDocument` @@ -2988,16 +2988,16 @@ It MAY contain It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the entity set's name. -### Attribute `EntityType` +### Attribute `EntityType` The value of `EntityType` is the qualified name of an entity type in scope. -### Attribute `IncludeInServiceDocument` +### Attribute `IncludeInServiceDocument` The value of `IncludeInServiceDocument` is one of the Boolean literals `true` or `false`. Absence of the attribute means `true`. @@ -3017,7 +3017,7 @@ A singleton MUST reference an instance its entity type. ::: {.varxml .rep} -### Element `edm:Singleton` +### Element `edm:Singleton` The `edm:Singleton` element MUST include the attributes `Name` and `Type`, and it MAY contain the `Nullable` attribute. @@ -3027,16 +3027,16 @@ It MAY contain It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the singleton's name. -### Attribute `Type` +### Attribute `Type` The value of `Type` is whose value is the [qualified name](#QualifiedName) of an entity type in scope. -### Attribute `Nullable` +### Attribute `Nullable` The value of `Nullable` is one of the Boolean literals `true` or `false`. @@ -3122,16 +3122,16 @@ be any non-containment navigation properties prior to the final segment. ::: {.varxml .rep} -### Element `edm:NavigationPropertyBinding` +### Element `edm:NavigationPropertyBinding` The `edm:NavigationPropertyBinding` element MUST contain the attributes `Path` and `Target`. -### Attribute `Path` +### Attribute `Path` The value of `Path` is a path expression. -### Attribute `Target` +### Attribute `Target` The value of `Target` is a [target path](#TargetPath). ::: @@ -3189,22 +3189,22 @@ to an entity set in scope. ::: {.varxml .rep} -### Element `edm:ActionImport` +### Element `edm:ActionImport` The `edm:ActionImport` element MUST contain the attributes `Name` and `Action`, and it MAY contain the `EntitySet` attribute. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the action import's name. -### Attribute `Action` +### Attribute `Action` The value of `Action` is the qualified name of an unbound action. -### Attribute `EntitySet` +### Attribute `EntitySet` The value of `EntitySet` is either the unqualified name of an entity set in the same entity container or a path to an entity set in a different @@ -3237,7 +3237,7 @@ not included. ::: {.varxml .rep} -### Element `edm:FunctionImport` +### Element `edm:FunctionImport` The `edm:FunctionImport` element MUST contain the attributes `Name` and `Function`, and it MAY contain the attributes `EntitySet` and @@ -3245,21 +3245,21 @@ The `edm:FunctionImport` element MUST contain the attributes `Name` and It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the function import's name. -### Attribute `Function` +### Attribute `Function` The value of `Function` is the qualified name of an unbound function. -### Attribute `EntitySet` +### Attribute `EntitySet` The value of `EntitySet` is either the unqualified name of an entity set in the same entity container or a path to an entity set in a different entity container. -### Attribute `IncludeInServiceDocument` +### Attribute `IncludeInServiceDocument` The value of `IncludeInServiceDocument` is one of the Boolean literals `true` or `false`. Absence of the attribute means `false`. @@ -3363,7 +3363,7 @@ scope. ::: {.varxml .rep} -### Element `edm:Term` +### Element `edm:Term` The `edm:Term` element MUST contain the attributes `Name` and `Type`. It MAY contain the attributes `Nullable`, `DefaultValue`, [`BaseTerm`](#SpecializedTerm) and [`AppliesTo`](#Applicability). @@ -3378,11 +3378,11 @@ enumeration type MAY define a value for the `DefaultValue` attribute. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the term's name. -### Attribute `Type` +### Attribute `Type` For single-valued terms the value of `Type` is the qualified name of the term's type. @@ -3391,7 +3391,7 @@ For collection-valued properties the value of `Type` is the character sequence `Collection(` followed by the qualified name of the property's item type, followed by a closing parenthesis `)`. -### Attribute `Nullable` +### Attribute `Nullable` The value of `Nullable` is one of the Boolean literals `true` or `false`. @@ -3413,7 +3413,7 @@ If no value is specified for a collection-valued term, the client cannot assume any default value. Clients SHOULD be prepared for this situation even in OData 4.01 responses. -### Attribute `DefaultValue` +### Attribute `DefaultValue` The value of this attribute determines the value of the term when applied in an [`edm:Annotation`](#Annotation) without providing an @@ -3441,7 +3441,7 @@ reached. ::: {.varxml .rep} -### Attribute `BaseTerm` +### Attribute `BaseTerm` The value of `BaseTerm` is the qualified name of the base term. ::: @@ -3495,7 +3495,7 @@ Symbolic Value|Model Element ::: {.varxml .rep} -### Attribute `AppliesTo` +### Attribute `AppliesTo` The value of `AppliesTo` is a whitespace-separated list of symbolic values from the table above that identify model elements the term is @@ -3536,7 +3536,7 @@ property of the same or a related structured type. ::: {.varxml .rep} -### Element `edm:Annotation` +### Element `edm:Annotation` The `edm:Annotation` element MUST contain the attribute `Term`, and it MAY contain the attribute [`Qualifier`](#Qualifier). @@ -3560,7 +3560,7 @@ targets the model element to be annotated. An `edm:Annotation` element MAY contain [`edm:Annotation`](#Annotation) elements that annotate the annotation. -### Attribute `Term` +### Attribute `Term` The value of `Term` is the qualified name of a [term](#Term) in scope. ::: @@ -3615,7 +3615,7 @@ identifies an annotation. ::: {.varxml .rep} -### Attribute `Qualifier` +### Attribute `Qualifier` Annotation elements that are children of an [`edm:Annotations`](#AnnotationswithExternalTargeting) element MUST NOT @@ -3696,7 +3696,7 @@ term. ::: {.varxml .rep} -### Expression `edm:Binary` +### Expression `edm:Binary` The `edm:Binary` expression evaluates to a primitive binary value. A binary expression MUST be assigned a value conforming to the rule @@ -3722,7 +3722,7 @@ Example 43: base64url-encoded binary value (OData) ::: {.varxml .rep} -### Expression `edm:Bool` +### Expression `edm:Bool` The `edm:Bool` expression evaluates to a primitive Boolean value. A Boolean expression MUST be assigned a Boolean value. @@ -3747,7 +3747,7 @@ Example 44: ::: {.varxml .rep} -### Expression `edm:Date` +### Expression `edm:Date` The `edm:Date` expression evaluates to a primitive date value. A date expression MUST be assigned a value of type `xs:date`, see @@ -3776,7 +3776,7 @@ Example 45: ::: {.varxml .rep} -### Expression `edm:DateTimeOffset` +### Expression `edm:DateTimeOffset` The `edm:DateTimeOffset` expression evaluates to a primitive datetimestamp value with a time-zone offset. A datetimestamp expression @@ -3810,7 +3810,7 @@ Example 46: ::: {.varxml .rep} -### Expression `edm:Decimal` +### Expression `edm:Decimal` The `edm:Decimal` expression evaluates to a primitive decimal value. A decimal expression MUST be assigned a value conforming to the rule @@ -3841,7 +3841,7 @@ Example 48: element notation ::: {.varxml .rep} -### Expression `edm:Duration` +### Expression `edm:Duration` The `edm:Duration` expression evaluates to a primitive duration value. A duration expression MUST be assigned a value of type @@ -3869,7 +3869,7 @@ Example 49: ::: {.varxml .rep} -### Expression `edm:EnumMember` +### Expression `edm:EnumMember` The `edm:EnumMember` expression references a [member](#EnumerationTypeMember) of an [enumeration @@ -3914,7 +3914,7 @@ Example 51: combined value for `IsFlags` enumeration type ::: {.varxml .rep} -### Expression `edm:Float` +### Expression `edm:Float` The `edm:Float` expression evaluates to a primitive floating point (or double) value. A float expression MUST be assigned a value conforming to @@ -3940,7 +3940,7 @@ Example 52: ::: {.varxml .rep} -### Expression `edm:Guid` +### Expression `edm:Guid` The `edm:Guid` expression evaluates to a primitive guid value. A guid expression MUST be assigned a value conforming to the rule `guidValue` @@ -3968,7 +3968,7 @@ Example 53: ::: {.varxml .rep} -### Expression `edm:Int` +### Expression `edm:Int` The `edm:Int` expression evaluates to a primitive integer value. An integer MUST be assigned a value conforming to the rule `int64Value` in @@ -3999,7 +3999,7 @@ Example 55: element notation ::: {.varxml .rep} -### Expression `edm:String` +### Expression `edm:String` The `edm:String` expression evaluates to a primitive string value. A string expression MUST be assigned a value of the type `xs:string`, see @@ -4026,7 +4026,7 @@ Example 56: ::: {.varxml .rep} -### Expression `edm:TimeOfDay` +### Expression `edm:TimeOfDay` The `edm:TimeOfDay` expression evaluates to a primitive time value. A time-of-day expression MUST be assigned a value conforming to the rule @@ -4397,7 +4397,7 @@ that reuse or refer to other terms. ::: {.varxml .rep} -### Expression `edm:AnnotationPath` +### Expression `edm:AnnotationPath` The `edm:AnnotationPath` expression MAY be provided using element notation or attribute notation. @@ -4431,7 +4431,7 @@ the instance(s) identified by the path. ::: {.varxml .rep} -### Expression `edm:ModelElementPath` +### Expression `edm:ModelElementPath` The `edm:ModelElementPath` expression MAY be provided using element notation or attribute notation. @@ -4467,7 +4467,7 @@ not the entitiy or collection of entities identified by the path. ::: {.varxml .rep} -### Expression `edm:NavigationPropertyPath` +### Expression `edm:NavigationPropertyPath` The `edm:NavigationPropertyPath` expression MAY be provided using element notation or attribute notation. @@ -4510,7 +4510,7 @@ identified by the path. ::: {.varxml .rep} -### Expression `edm:PropertyPath` +### Expression `edm:PropertyPath` The `edm:PropertyPath` MAY be provided using either element notation or attribute notation. @@ -4548,7 +4548,7 @@ instances identified by the path. ::: {.varxml .rep} -### Expression `edm:Path` +### Expression `edm:Path` The `edm:Path` expression MAY be provided using element notation or attribute notation. @@ -4599,21 +4599,21 @@ evaluate to comparable values. ::: {.varxml .rep} -### Expressions `edm:And` and `edm:Or` +### Expressions `edm:And` and `edm:Or` The `And` and `Or` logical expressions are represented as elements `edm:And` and `edm:Or` that MUST contain two annotation expressions. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Expression `edm:Not` +### Expression `edm:Not` Negation expressions are represented as an element `edm:Not` that MUST contain a single annotation expression. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Expressions `edm:Eq`, `edm:Ne`, `edm:Gt`, `edm:Ge`, `edm:Lt`, `edm:Le`, `edm:Has`, and `edm:In` +### Expressions `edm:Eq`, `edm:Ne`, `edm:Gt`, `edm:Ge`, `edm:Lt`, `edm:Le`, `edm:Has`, and `edm:In` All comparison expressions are represented as an element that MUST contain two annotation expressions. @@ -4699,14 +4699,14 @@ expressions that evaluate to numeric values. ::: {.varxml .rep} -### Expression `edm:Neg` +### Expression `edm:Neg` Negation expressions are represented as an element `edm:Neg` that MUST contain a single annotation expression. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Expressions `edm:Add`, `edm:Sub`, `edm:Mul`, `edm:Div`, `edm:DivBy`, and `edm:Mod` +### Expressions `edm:Add`, `edm:Sub`, `edm:Mul`, `edm:Div`, `edm:DivBy`, and `edm:Mod` These arithmetic expressions are represented as an element that MUST contain two annotation expressions. @@ -4756,14 +4756,14 @@ function. ::: {.varxml .rep} -### Expression `edm:Apply` +### Expression `edm:Apply` The `edm:Apply` element MUST contain the `Function` attribute and MAY contain annotation expressions as operands for the applied function. It MAY contain more [`edm:Annotation`](#Annotation) elements. -### Attribute `Function` +### Attribute `Function` The value of `Function` is the [qualified name](#QualifiedName) of the client-side function to apply. @@ -4912,14 +4912,14 @@ rules as the `cast` canonical function defined in ::: {.varxml .rep} -### Expression `edm:Cast` +### Expression `edm:Cast` The `edm:Cast` element MUST contain the `Type` attribute and MUST contain exactly one expression. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Type` +### Attribute `Type` The value of `Type` is a qualified type name in scope, or the character sequence `Collection(` followed by the qualified name of a type in @@ -4955,7 +4955,7 @@ compatible. ::: {.varxml .rep} -### Expression `edm:Collection` +### Expression `edm:Collection` The `edm:Collection` element contains zero or more child expressions. ::: @@ -5001,7 +5001,7 @@ collection. ::: {.varxml .rep} -### Expression `edm:If` +### Expression `edm:If` The `edm:If` element MUST contain two or three child expressions that MUST use element notation. @@ -5034,7 +5034,7 @@ the specified type, and `false` otherwise. ::: {.varxml .rep} -### Expression `edm:UrlRef` +### Expression `edm:UrlRef` The `edm:UrlRef` expression MAY be provided using element notation or attribute notation. @@ -5075,7 +5075,7 @@ within the schema containing the expression. ::: {.varxml .rep} -### Expression `edm:LabeledElement` +### Expression `edm:LabeledElement` The `edm:LabeledElement` element MUST contain the Name attribute. @@ -5084,7 +5084,7 @@ or element notation. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Name` +### Attribute `Name` The value of `Name` is the labeled element's name. ::: @@ -5114,7 +5114,7 @@ expression as its value. ::: {.varxml .rep} -### Expression `edm:LabeledElementReference` +### Expression `edm:LabeledElementReference` The `edm:LabeledElementReference` element MUST contain the qualified name of a labeled element expression in its body. @@ -5139,7 +5139,7 @@ expression MAY be annotated. ::: {.varxml .rep} -### Expression `edm:Null` +### Expression `edm:Null` The `edm:Null` element MAY contain [`edm:Annotation`](#Annotation) elements. @@ -5190,18 +5190,18 @@ expression is equivalent to specifying an empty collection as its value. ::: {.varxml .rep} -### Expression `edm:Record` +### Expression `edm:Record` The `edm:Record` element MAY contain the `Type` attribute and MAY contain `edm:PropertyValue` elements. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Type` +### Attribute `Type` The value of `Type` is the qualified name of a structured type in scope. -### Element `edm:PropertyValue` +### Element `edm:PropertyValue` The `edm:PropertyValue` element MUST contain the `Property` attribute, and it MUST contain exactly one expression that MAY be provided using @@ -5209,7 +5209,7 @@ either element notation or attribute notation. It MAY contain [`edm:Annotation`](#Annotation) elements. -### Attribute `Property` +### Attribute `Property` The value of `Property` is the name of a property of the type of the enclosing `edm:Record` expression. @@ -5266,7 +5266,7 @@ surrounding expression. ::: {.varxml .rep} -### Expression `edm:UrlRef` +### Expression `edm:UrlRef` The `edm:UrlRef` expression MAY be provided using element notation or attribute notation. @@ -5696,169 +5696,169 @@ https://openui5.hana.ondemand.com/1.40.10/#docs/guide/87aac894a40640f89920d7b2a4 # Appendix B. Table of XML Elements and Attributes ::: toc -- [Type Facet Attributes](#TypeFacetAttributes1) - - [Attribute `MaxLength`](#AttributeMaxLength1.1) - - [Attribute `Precision`](#AttributePrecision1.2) - - [Attribute `Scale`](#AttributeScale1.3) - - [Attribute `Unicode`](#AttributeUnicode1.4) - - [Attribute `SRID`](#AttributeSRID1.5) -- [Element `edmx:Edmx`](#ElementedmxEdmx2) - - [Attribute `Version`](#AttributeVersion2.1) -- [Element `edmx:DataServices`](#ElementedmxDataServices3) -- [Element `edmx:Reference`](#ElementedmxReference4) - - [Attribute `Uri`](#AttributeUri4.1) -- [Element `edmx:Include`](#ElementedmxInclude5) - - [Attribute `Namespace`](#AttributeNamespace5.1) - - [Attribute `Alias`](#AttributeAlias5.2) -- [Element `edmx:IncludeAnnotations`](#ElementedmxIncludeAnnotations6) - - [Attribute `TermNamespace`](#AttributeTermNamespace6.1) - - [Attribute `Qualifier`](#AttributeQualifier6.2) - - [Attribute `TargetNamespace`](#AttributeTargetNamespace6.3) -- [Element `edm:Schema`](#ElementedmSchema7) - - [Attribute `Namespace`](#AttributeNamespace7.1) - - [Attribute `Alias`](#AttributeAlias7.2) -- [Element `edm:Annotations`](#ElementedmAnnotations8) - - [Attribute `Target`](#AttributeTarget8.1) - - [Attribute `Qualifier`](#AttributeQualifier8.2) -- [Element `edm:EntityType`](#ElementedmEntityType9) - - [Attribute `Name`](#AttributeName9.1) - - [Attribute `BaseType`](#AttributeBaseType9.2) - - [Attribute `Abstract`](#AttributeAbstract9.3) - - [Attribute `OpenType`](#AttributeOpenType9.4) - - [Attribute `HasStream`](#AttributeHasStream9.5) -- [Element `edm:Key`](#ElementedmKey10) -- [Element `edm:PropertyRef`](#ElementedmPropertyRef11) - - [Attribute `Name`](#AttributeName11.1) - - [Attribute `Alias`](#AttributeAlias11.2) -- [Element `edm:Property`](#ElementedmProperty12) - - [Attribute `Name`](#AttributeName12.1) - - [Attribute `Type`](#AttributeType12.2) - - [Attribute `Nullable`](#AttributeNullable12.3) - - [Attribute `DefaultValue`](#AttributeDefaultValue12.4) -- [Element `edm:NavigationProperty`](#ElementedmNavigationProperty13) - - [Attribute `Name`](#AttributeName13.1) - - [Attribute `Type`](#AttributeType13.2) - - [Attribute `Nullable`](#AttributeNullable13.3) - - [Attribute `Partner`](#AttributePartner13.4) - - [Attribute `ContainsTarget`](#AttributeContainsTarget13.5) -- [Element `edm:ReferentialConstraint`](#ElementedmReferentialConstraint14) - - [Attribute `Property`](#AttributeProperty14.1) - - [Attribute `ReferencedProperty`](#AttributeReferencedProperty14.2) -- [Element `edm:OnDelete`](#ElementedmOnDelete15) - - [Attribute `Action`](#AttributeAction15.1) -- [Element `edm:ComplexType`](#ElementedmComplexType16) - - [Attribute `Name`](#AttributeName16.1) - - [Attribute `BaseType`](#AttributeBaseType16.2) - - [Attribute `Abstract`](#AttributeAbstract16.3) - - [Attribute `OpenType`](#AttributeOpenType16.4) -- [Element `edm:EnumType`](#ElementedmEnumType17) - - [Attribute `Name`](#AttributeName17.1) - - [Attribute `UnderlyingType`](#AttributeUnderlyingType17.2) - - [Attribute `IsFlags`](#AttributeIsFlags17.3) -- [Element `edm:Member`](#ElementedmMember18) - - [Attribute `Name`](#AttributeName18.1) - - [Attribute `Value`](#AttributeValue18.2) -- [Element `edm:TypeDefinition`](#ElementedmTypeDefinition19) - - [Attribute `Name`](#AttributeName19.1) - - [Attribute `UnderlyingType`](#AttributeUnderlyingType19.2) -- [Element `edm:Action`](#ElementedmAction20) - - [Attribute `Name`](#AttributeName20.1) -- [Element `edm:Function`](#ElementedmFunction21) - - [Attribute `Name`](#AttributeName21.1) - - [Attribute `IsBound`](#AttributeIsBound21.2) - - [Attribute `EntitySetPath`](#AttributeEntitySetPath21.3) - - [Attribute `IsComposable`](#AttributeIsComposable21.4) -- [Element `edm:ReturnType`](#ElementedmReturnType22) - - [Attribute `Type`](#AttributeType22.1) - - [Attribute `Nullable`](#AttributeNullable22.2) -- [Element `edm:Parameter`](#ElementedmParameter23) - - [Attribute `Name`](#AttributeName23.1) - - [Attribute `Type`](#AttributeType23.2) - - [Attribute `Nullable`](#AttributeNullable23.3) -- [Element `edm:EntityContainer`](#ElementedmEntityContainer24) - - [Attribute `Name`](#AttributeName24.1) - - [Attribute `Extends`](#AttributeExtends24.2) -- [Element `edm:EntitySet`](#ElementedmEntitySet25) - - [Attribute `Name`](#AttributeName25.1) - - [Attribute `EntityType`](#AttributeEntityType25.2) - - [Attribute `IncludeInServiceDocument`](#AttributeIncludeInServiceDocument25.3) -- [Element `edm:Singleton`](#ElementedmSingleton26) - - [Attribute `Name`](#AttributeName26.1) - - [Attribute `Type`](#AttributeType26.2) - - [Attribute `Nullable`](#AttributeNullable26.3) -- [Element `edm:NavigationPropertyBinding`](#ElementedmNavigationPropertyBinding27) - - [Attribute `Path`](#AttributePath27.1) - - [Attribute `Target`](#AttributeTarget27.2) -- [Element `edm:ActionImport`](#ElementedmActionImport28) - - [Attribute `Name`](#AttributeName28.1) - - [Attribute `Action`](#AttributeAction28.2) - - [Attribute `EntitySet`](#AttributeEntitySet28.3) -- [Element `edm:FunctionImport`](#ElementedmFunctionImport29) - - [Attribute `Name`](#AttributeName29.1) - - [Attribute `Function`](#AttributeFunction29.2) - - [Attribute `EntitySet`](#AttributeEntitySet29.3) - - [Attribute `IncludeInServiceDocument`](#AttributeIncludeInServiceDocument29.4) -- [Element `edm:Term`](#ElementedmTerm30) - - [Attribute `Name`](#AttributeName30.1) - - [Attribute `Type`](#AttributeType30.2) - - [Attribute `Nullable`](#AttributeNullable30.3) - - [Attribute `DefaultValue`](#AttributeDefaultValue30.4) - - [Attribute `BaseTerm`](#AttributeBaseTerm30.5) - - [Attribute `AppliesTo`](#AttributeAppliesTo30.6) -- [Element `edm:Annotation`](#ElementedmAnnotation31) - - [Attribute `Term`](#AttributeTerm31.1) - - [Attribute `Qualifier`](#AttributeQualifier31.2) -- [Expression `edm:Binary`](#ExpressionedmBinary32) -- [Expression `edm:Bool`](#ExpressionedmBool33) -- [Expression `edm:Date`](#ExpressionedmDate34) -- [Expression `edm:DateTimeOffset`](#ExpressionedmDateTimeOffset35) -- [Expression `edm:Decimal`](#ExpressionedmDecimal36) -- [Expression `edm:Duration`](#ExpressionedmDuration37) -- [Expression `edm:EnumMember`](#ExpressionedmEnumMember38) -- [Expression `edm:Float`](#ExpressionedmFloat39) -- [Expression `edm:Guid`](#ExpressionedmGuid40) -- [Expression `edm:Int`](#ExpressionedmInt41) -- [Expression `edm:String`](#ExpressionedmString42) -- [Expression `edm:TimeOfDay`](#ExpressionedmTimeOfDay43) -- [Expression `edm:AnnotationPath`](#ExpressionedmAnnotationPath44) -- [Expression `edm:ModelElementPath`](#ExpressionedmModelElementPath45) -- [Expression `edm:NavigationPropertyPath`](#ExpressionedmNavigationPropertyPath46) -- [Expression `edm:PropertyPath`](#ExpressionedmPropertyPath47) -- [Expression `edm:Path`](#ExpressionedmPath48) -- [Expressions `edm:And`](#ExpressionsedmAnd49) - - [`edm:Or`](#edmOr49.1) -- [Expression `edm:Not`](#ExpressionedmNot50) -- [Expressions `edm:Eq`](#ExpressionsedmEq51) - - [`edm:Ne`](#edmNe51.1) - - [`edm:Gt`](#edmGt51.2) - - [`edm:Ge`](#edmGe51.3) - - [`edm:Lt`](#edmLt51.4) - - [`edm:Le`](#edmLe51.5) - - [`edm:Has`](#edmHas51.6) - - [`edm:In`](#edmIn51.7) -- [Expression `edm:Neg`](#ExpressionedmNeg52) -- [Expressions `edm:Add`](#ExpressionsedmAdd53) - - [`edm:Sub`](#edmSub53.1) - - [`edm:Mul`](#edmMul53.2) - - [`edm:Div`](#edmDiv53.3) - - [`edm:DivBy`](#edmDivBy53.4) - - [`edm:Mod`](#edmMod53.5) -- [Expression `edm:Apply`](#ExpressionedmApply54) - - [Attribute `Function`](#AttributeFunction54.1) -- [Expression `edm:Cast`](#ExpressionedmCast55) - - [Attribute `Type`](#AttributeType55.1) -- [Expression `edm:Collection`](#ExpressionedmCollection56) -- [Expression `edm:If`](#ExpressionedmIf57) -- [Expression `edm:UrlRef`](#ExpressionedmUrlRef58) -- [Expression `edm:LabeledElement`](#ExpressionedmLabeledElement59) - - [Attribute `Name`](#AttributeName59.1) -- [Expression `edm:LabeledElementReference`](#ExpressionedmLabeledElementReference60) -- [Expression `edm:Null`](#ExpressionedmNull61) -- [Expression `edm:Record`](#ExpressionedmRecord62) - - [Attribute `Type`](#AttributeType62.1) -- [Element `edm:PropertyValue`](#ElementedmPropertyValue63) - - [Attribute `Property`](#AttributeProperty63.1) -- [Expression `edm:UrlRef`](#ExpressionedmUrlRef64) +- [Type Facet Attributes](#TypeFacetAttributes.1) + - [Attribute `MaxLength`](#AttributeMaxLength.1.1) + - [Attribute `Precision`](#AttributePrecision.1.2) + - [Attribute `Scale`](#AttributeScale.1.3) + - [Attribute `Unicode`](#AttributeUnicode.1.4) + - [Attribute `SRID`](#AttributeSRID.1.5) +- [Element `edmx:Edmx`](#ElementedmxEdmx.2) + - [Attribute `Version`](#AttributeVersion.2.1) +- [Element `edmx:DataServices`](#ElementedmxDataServices.3) +- [Element `edmx:Reference`](#ElementedmxReference.4) + - [Attribute `Uri`](#AttributeUri.4.1) +- [Element `edmx:Include`](#ElementedmxInclude.5) + - [Attribute `Namespace`](#AttributeNamespace.5.1) + - [Attribute `Alias`](#AttributeAlias.5.2) +- [Element `edmx:IncludeAnnotations`](#ElementedmxIncludeAnnotations.6) + - [Attribute `TermNamespace`](#AttributeTermNamespace.6.1) + - [Attribute `Qualifier`](#AttributeQualifier.6.2) + - [Attribute `TargetNamespace`](#AttributeTargetNamespace.6.3) +- [Element `edm:Schema`](#ElementedmSchema.7) + - [Attribute `Namespace`](#AttributeNamespace.7.1) + - [Attribute `Alias`](#AttributeAlias.7.2) +- [Element `edm:Annotations`](#ElementedmAnnotations.8) + - [Attribute `Target`](#AttributeTarget.8.1) + - [Attribute `Qualifier`](#AttributeQualifier.8.2) +- [Element `edm:EntityType`](#ElementedmEntityType.9) + - [Attribute `Name`](#AttributeName.9.1) + - [Attribute `BaseType`](#AttributeBaseType.9.2) + - [Attribute `Abstract`](#AttributeAbstract.9.3) + - [Attribute `OpenType`](#AttributeOpenType.9.4) + - [Attribute `HasStream`](#AttributeHasStream.9.5) +- [Element `edm:Key`](#ElementedmKey.10) +- [Element `edm:PropertyRef`](#ElementedmPropertyRef.11) + - [Attribute `Name`](#AttributeName.11.1) + - [Attribute `Alias`](#AttributeAlias.11.2) +- [Element `edm:Property`](#ElementedmProperty.12) + - [Attribute `Name`](#AttributeName.12.1) + - [Attribute `Type`](#AttributeType.12.2) + - [Attribute `Nullable`](#AttributeNullable.12.3) + - [Attribute `DefaultValue`](#AttributeDefaultValue.12.4) +- [Element `edm:NavigationProperty`](#ElementedmNavigationProperty.13) + - [Attribute `Name`](#AttributeName.13.1) + - [Attribute `Type`](#AttributeType.13.2) + - [Attribute `Nullable`](#AttributeNullable.13.3) + - [Attribute `Partner`](#AttributePartner.13.4) + - [Attribute `ContainsTarget`](#AttributeContainsTarget.13.5) +- [Element `edm:ReferentialConstraint`](#ElementedmReferentialConstraint.14) + - [Attribute `Property`](#AttributeProperty.14.1) + - [Attribute `ReferencedProperty`](#AttributeReferencedProperty.14.2) +- [Element `edm:OnDelete`](#ElementedmOnDelete.15) + - [Attribute `Action`](#AttributeAction.15.1) +- [Element `edm:ComplexType`](#ElementedmComplexType.16) + - [Attribute `Name`](#AttributeName.16.1) + - [Attribute `BaseType`](#AttributeBaseType.16.2) + - [Attribute `Abstract`](#AttributeAbstract.16.3) + - [Attribute `OpenType`](#AttributeOpenType.16.4) +- [Element `edm:EnumType`](#ElementedmEnumType.17) + - [Attribute `Name`](#AttributeName.17.1) + - [Attribute `UnderlyingType`](#AttributeUnderlyingType.17.2) + - [Attribute `IsFlags`](#AttributeIsFlags.17.3) +- [Element `edm:Member`](#ElementedmMember.18) + - [Attribute `Name`](#AttributeName.18.1) + - [Attribute `Value`](#AttributeValue.18.2) +- [Element `edm:TypeDefinition`](#ElementedmTypeDefinition.19) + - [Attribute `Name`](#AttributeName.19.1) + - [Attribute `UnderlyingType`](#AttributeUnderlyingType.19.2) +- [Element `edm:Action`](#ElementedmAction.20) + - [Attribute `Name`](#AttributeName.20.1) +- [Element `edm:Function`](#ElementedmFunction.21) + - [Attribute `Name`](#AttributeName.21.1) + - [Attribute `IsBound`](#AttributeIsBound.21.2) + - [Attribute `EntitySetPath`](#AttributeEntitySetPath.21.3) + - [Attribute `IsComposable`](#AttributeIsComposable.21.4) +- [Element `edm:ReturnType`](#ElementedmReturnType.22) + - [Attribute `Type`](#AttributeType.22.1) + - [Attribute `Nullable`](#AttributeNullable.22.2) +- [Element `edm:Parameter`](#ElementedmParameter.23) + - [Attribute `Name`](#AttributeName.23.1) + - [Attribute `Type`](#AttributeType.23.2) + - [Attribute `Nullable`](#AttributeNullable.23.3) +- [Element `edm:EntityContainer`](#ElementedmEntityContainer.24) + - [Attribute `Name`](#AttributeName.24.1) + - [Attribute `Extends`](#AttributeExtends.24.2) +- [Element `edm:EntitySet`](#ElementedmEntitySet.25) + - [Attribute `Name`](#AttributeName.25.1) + - [Attribute `EntityType`](#AttributeEntityType.25.2) + - [Attribute `IncludeInServiceDocument`](#AttributeIncludeInServiceDocument.25.3) +- [Element `edm:Singleton`](#ElementedmSingleton.26) + - [Attribute `Name`](#AttributeName.26.1) + - [Attribute `Type`](#AttributeType.26.2) + - [Attribute `Nullable`](#AttributeNullable.26.3) +- [Element `edm:NavigationPropertyBinding`](#ElementedmNavigationPropertyBinding.27) + - [Attribute `Path`](#AttributePath.27.1) + - [Attribute `Target`](#AttributeTarget.27.2) +- [Element `edm:ActionImport`](#ElementedmActionImport.28) + - [Attribute `Name`](#AttributeName.28.1) + - [Attribute `Action`](#AttributeAction.28.2) + - [Attribute `EntitySet`](#AttributeEntitySet.28.3) +- [Element `edm:FunctionImport`](#ElementedmFunctionImport.29) + - [Attribute `Name`](#AttributeName.29.1) + - [Attribute `Function`](#AttributeFunction.29.2) + - [Attribute `EntitySet`](#AttributeEntitySet.29.3) + - [Attribute `IncludeInServiceDocument`](#AttributeIncludeInServiceDocument.29.4) +- [Element `edm:Term`](#ElementedmTerm.30) + - [Attribute `Name`](#AttributeName.30.1) + - [Attribute `Type`](#AttributeType.30.2) + - [Attribute `Nullable`](#AttributeNullable.30.3) + - [Attribute `DefaultValue`](#AttributeDefaultValue.30.4) + - [Attribute `BaseTerm`](#AttributeBaseTerm.30.5) + - [Attribute `AppliesTo`](#AttributeAppliesTo.30.6) +- [Element `edm:Annotation`](#ElementedmAnnotation.31) + - [Attribute `Term`](#AttributeTerm.31.1) + - [Attribute `Qualifier`](#AttributeQualifier.31.2) +- [Expression `edm:Binary`](#ExpressionedmBinary.32) +- [Expression `edm:Bool`](#ExpressionedmBool.33) +- [Expression `edm:Date`](#ExpressionedmDate.34) +- [Expression `edm:DateTimeOffset`](#ExpressionedmDateTimeOffset.35) +- [Expression `edm:Decimal`](#ExpressionedmDecimal.36) +- [Expression `edm:Duration`](#ExpressionedmDuration.37) +- [Expression `edm:EnumMember`](#ExpressionedmEnumMember.38) +- [Expression `edm:Float`](#ExpressionedmFloat.39) +- [Expression `edm:Guid`](#ExpressionedmGuid.40) +- [Expression `edm:Int`](#ExpressionedmInt.41) +- [Expression `edm:String`](#ExpressionedmString.42) +- [Expression `edm:TimeOfDay`](#ExpressionedmTimeOfDay.43) +- [Expression `edm:AnnotationPath`](#ExpressionedmAnnotationPath.44) +- [Expression `edm:ModelElementPath`](#ExpressionedmModelElementPath.45) +- [Expression `edm:NavigationPropertyPath`](#ExpressionedmNavigationPropertyPath.46) +- [Expression `edm:PropertyPath`](#ExpressionedmPropertyPath.47) +- [Expression `edm:Path`](#ExpressionedmPath.48) +- [Expressions `edm:And`](#ExpressionsedmAnd.49) + - [`edm:Or`](#edmOr.49.1) +- [Expression `edm:Not`](#ExpressionedmNot.50) +- [Expressions `edm:Eq`](#ExpressionsedmEq.51) + - [`edm:Ne`](#edmNe.51.1) + - [`edm:Gt`](#edmGt.51.2) + - [`edm:Ge`](#edmGe.51.3) + - [`edm:Lt`](#edmLt.51.4) + - [`edm:Le`](#edmLe.51.5) + - [`edm:Has`](#edmHas.51.6) + - [`edm:In`](#edmIn.51.7) +- [Expression `edm:Neg`](#ExpressionedmNeg.52) +- [Expressions `edm:Add`](#ExpressionsedmAdd.53) + - [`edm:Sub`](#edmSub.53.1) + - [`edm:Mul`](#edmMul.53.2) + - [`edm:Div`](#edmDiv.53.3) + - [`edm:DivBy`](#edmDivBy.53.4) + - [`edm:Mod`](#edmMod.53.5) +- [Expression `edm:Apply`](#ExpressionedmApply.54) + - [Attribute `Function`](#AttributeFunction.54.1) +- [Expression `edm:Cast`](#ExpressionedmCast.55) + - [Attribute `Type`](#AttributeType.55.1) +- [Expression `edm:Collection`](#ExpressionedmCollection.56) +- [Expression `edm:If`](#ExpressionedmIf.57) +- [Expression `edm:UrlRef`](#ExpressionedmUrlRef.58) +- [Expression `edm:LabeledElement`](#ExpressionedmLabeledElement.59) + - [Attribute `Name`](#AttributeName.59.1) +- [Expression `edm:LabeledElementReference`](#ExpressionedmLabeledElementReference.60) +- [Expression `edm:Null`](#ExpressionedmNull.61) +- [Expression `edm:Record`](#ExpressionedmRecord.62) + - [Attribute `Type`](#AttributeType.62.1) +- [Element `edm:PropertyValue`](#ElementedmPropertyValue.63) + - [Attribute `Property`](#AttributeProperty.63.1) +- [Expression `edm:UrlRef`](#ExpressionedmUrlRef.64) ::: ------- diff --git a/docs/odata-temporal-ext/odata-temporal-ext.html b/docs/odata-temporal-ext/odata-temporal-ext.html index b38847d13..83df4312a 100644 --- a/docs/odata-temporal-ext/odata-temporal-ext.html +++ b/docs/odata-temporal-ext/odata-temporal-ext.html @@ -330,819 +330,18 @@

    2.1 Exampl

    Example 2: model for api-1 with snapshot entity sets (hidden application time), key properties marked with {id}

    - - - - - - - - - -
    -
    -
    - Employee -
    -
    -
    -
    - - Employee - -
    -
    - - - -
    -
    -
    - ID: Edm.String {id} -
    -
    -
    -
    - - ID: Edm.String {id} - -
    -
    - - - -
    -
    -
    - Name: Edm.String -
    -
    -
    -
    - - Name: Edm.String - -
    -
    - - - -
    -
    -
    - Jobtitle: Edm.String -
    -
    -
    -
    - - Jobtitle: Edm.String - -
    -
    - - - - - - -
    -
    -
    - Department -
    -
    -
    -
    - - Department - -
    -
    - - - -
    -
    -
    - ID: Edm.String {id} -
    -
    -
    -
    - - ID: Edm.String {id} - -
    -
    - - - -
    -
    -
    - Name: Edm.String -
    -
    -
    -
    - - Name: Edm.String - -
    -
    - - - - - - -
    -
    -
    -
    - - * - -
    -
    - - Employees - -
    -
    -
    -
    -
    - - *... - -
    -
    - - - -
    -
    -
    -
    -
    - - 1 - -
    -
    - - Department - -
    -
    -
    -
    -
    -
    - - 1... - -
    -
    -
    - - - - - Text is not SVG - cannot display - - - -
    - +

    $\[include diagrams/api-1.drawio.svg\]$

    and

    Example 3: model for api-2 with timeline entity sets (visible application time), key properties marked with {id}

    - - - - - - - - - -
    -
    -
    - Employee_history -
    -
    -
    -
    - - Employee_history - -
    -
    - - - -
    -
    -
    - From: Edm.Date {id} -
    -
    -
    -
    - - From: Edm.Date {id} - -
    -
    - - - -
    -
    -
    - To: Edm.Date -
    -
    -
    -
    - - To: Edm.Date - -
    -
    - - - -
    -
    -
    - Name: Edm.String -
    -
    -
    -
    - - Name: Edm.String - -
    -
    - - - -
    -
    -
    - Jobtitle: Edm.String -
    -
    -
    -
    - - Jobtitle: Edm.String - -
    -
    - - - - - - -
    -
    -
    - Department_history -
    -
    -
    -
    - - Department_history - -
    -
    - - - -
    -
    -
    - From: Edm.Date {id} -
    -
    -
    -
    - - From: Edm.Date {id} - -
    -
    - - - -
    -
    -
    - To: Edm.Date -
    -
    -
    -
    - - To: Edm.Date - -
    -
    - - - -
    -
    -
    - Name: Edm.String -
    -
    -
    -
    - - Name: Edm.String - -
    -
    - - - -
    -
    -
    - Budget: Edm.Decimal -
    -
    -
    -
    - - Budget: Edm.Decimal - -
    -
    - - - - - - -
    -
    -
    - Employee -
    -
    -
    -
    - - Employee - -
    -
    - - - -
    -
    -
    - ID: Edm.String {id} -
    -
    -
    -
    - - ID: Edm.String {id} - -
    -
    - - - - - - -
    -
    -
    - Department -
    -
    -
    -
    - - Department - -
    -
    - - - -
    -
    -
    - ID: Edm.String {id} -
    -
    -
    -
    - - ID: Edm.String {id} - -
    -
    - - - - - -
    -
    -
    -
    - - * - -
    -
    - - Employees - -
    -
    -
    -
    -
    - - *... - -
    -
    - - - - - -
    -
    -
    -
    - - * - -
    -
    - history -
    -
    -
    -
    -
    - - *... - -
    -
    - - - - - -
    -
    -
    -
    - - * - -
    -
    - history -
    -
    -
    -
    -
    - - *... - -
    -
    - - - -
    -
    -
    -
    -
    - - 1 - -
    -
    - - Department - -
    -
    -
    -
    -
    -
    - - 1... - -
    -
    - - -
    - - - - - Text is not SVG - cannot display - - - -
    - +

    $\[include diagrams/api-2.drawio.svg\]$

    2.2 Example Data

    Both API models in the previous section are views on the same underlying data. A possible storage model for this data is:

    Example 4: simple storage model: object key in dark green, temporal sub-key in light green, foreign keys in orange, non-key fields in blue

    - - - - - - - - - -
    -
    -
    - Employee -
    -
    -
    -
    - - Employee - -
    -
    - - - - -
    -
    -
    - ID: String {id} -
    -
    -
    -
    - - ID: String {id} - -
    -
    - - - - -
    -
    -
    - From: Date {id} -
    -
    -
    -
    - - From: Date {id} - -
    -
    - - - - -
    -
    -
    - To: Date -
    -
    -
    -
    - - To: Date - -
    -
    - - - - -
    -
    -
    - Name: String -
    -
    -
    -
    - - Name: String - -
    -
    - - - - -
    -
    -
    - Jobtitle: String -
    -
    -
    -
    - - Jobtitle: String - -
    -
    - - - - -
    -
    -
    - Department.ID -
    -
    -
    -
    - - Department.ID - -
    -
    - - - - - - -
    -
    -
    - Department -
    -
    -
    -
    - - Department - -
    -
    - - - - -
    -
    -
    - ID: String {id} -
    -
    -
    -
    - - ID: String {id} - -
    -
    - - - - -
    -
    -
    - From: Date {id} -
    -
    -
    -
    - - From: Date {id} - -
    -
    - - - - -
    -
    -
    - To: Date -
    -
    -
    -
    - - To: Date - -
    -
    - - - - -
    -
    -
    - Name: String -
    -
    -
    -
    - - Name: String - -
    -
    - - - - -
    -
    -
    - Budget: Decimal -
    -
    -
    -
    - - Budget: Decimal - -
    -
    - - - -
    -
    -
    -
    -
    - 1 -
    -
    -
    -
    -
    -
    - - 1 - -
    -
    - - -
    - - - - - Text is not SVG - cannot display - - - -
    - +

    $\[include diagrams/db.drawio.svg\]$

    The period start date is used as the temporal sub-key for identifying time slices together with the key of the temporal object.

    Note: alternatively, the period end date could have been used as temporal sub-key, or the primary key of the time slice tables could have been an artificial key (sequence number, UUID, …) with both the temporal object key and the period boundaries as non-key fields.

    The following example data will be used to further illustrate the capabilities introduced by this extension. It assumes that the example services only support four-digit years.

    diff --git a/docs/odata-temporal-ext/odata-temporal-ext.md b/docs/odata-temporal-ext/odata-temporal-ext.md index 8878f5c90..4df375882 100644 --- a/docs/odata-temporal-ext/odata-temporal-ext.md +++ b/docs/odata-temporal-ext/odata-temporal-ext.md @@ -372,192 +372,7 @@ Example 2: model for `api-1` with snapshot entit application time), key properties marked with {id} ::: - - - - - - - - - -
    -
    -
    - Employee -
    -
    -
    -
    - - Employee - -
    -
    - - - -
    -
    -
    - ID: Edm.String {id} -
    -
    -
    -
    - - ID: Edm.String {id} - -
    -
    - - - -
    -
    -
    - Name: Edm.String -
    -
    -
    -
    - - Name: Edm.String - -
    -
    - - - -
    -
    -
    - Jobtitle: Edm.String -
    -
    -
    -
    - - Jobtitle: Edm.String - -
    -
    - - - - - - -
    -
    -
    - Department -
    -
    -
    -
    - - Department - -
    -
    - - - -
    -
    -
    - ID: Edm.String {id} -
    -
    -
    -
    - - ID: Edm.String {id} - -
    -
    - - - -
    -
    -
    - Name: Edm.String -
    -
    -
    -
    - - Name: Edm.String - -
    -
    - - - - - - -
    -
    -
    -
    - - * - -
    -
    - - Employees - -
    -
    -
    -
    -
    - - *... - -
    -
    - - - -
    -
    -
    -
    -
    - - 1 - -
    -
    - - Department - -
    -
    -
    -
    -
    -
    - - 1... - -
    -
    -
    - - - - - Text is not SVG - cannot display - - - -
    +$$$include diagrams/api-1.drawio.svg$$$ and @@ -566,361 +381,7 @@ Example 3: model for `api-2` with timeline entit application time), key properties marked with {id} ::: - - - - - - - - - -
    -
    -
    - Employee_history -
    -
    -
    -
    - - Employee_history - -
    -
    - - - -
    -
    -
    - From: Edm.Date {id} -
    -
    -
    -
    - - From: Edm.Date {id} - -
    -
    - - - -
    -
    -
    - To: Edm.Date -
    -
    -
    -
    - - To: Edm.Date - -
    -
    - - - -
    -
    -
    - Name: Edm.String -
    -
    -
    -
    - - Name: Edm.String - -
    -
    - - - -
    -
    -
    - Jobtitle: Edm.String -
    -
    -
    -
    - - Jobtitle: Edm.String - -
    -
    - - - - - - -
    -
    -
    - Department_history -
    -
    -
    -
    - - Department_history - -
    -
    - - - -
    -
    -
    - From: Edm.Date {id} -
    -
    -
    -
    - - From: Edm.Date {id} - -
    -
    - - - -
    -
    -
    - To: Edm.Date -
    -
    -
    -
    - - To: Edm.Date - -
    -
    - - - -
    -
    -
    - Name: Edm.String -
    -
    -
    -
    - - Name: Edm.String - -
    -
    - - - -
    -
    -
    - Budget: Edm.Decimal -
    -
    -
    -
    - - Budget: Edm.Decimal - -
    -
    - - - - - - -
    -
    -
    - Employee -
    -
    -
    -
    - - Employee - -
    -
    - - - -
    -
    -
    - ID: Edm.String {id} -
    -
    -
    -
    - - ID: Edm.String {id} - -
    -
    - - - - - - -
    -
    -
    - Department -
    -
    -
    -
    - - Department - -
    -
    - - - -
    -
    -
    - ID: Edm.String {id} -
    -
    -
    -
    - - ID: Edm.String {id} - -
    -
    - - - - - -
    -
    -
    -
    - - * - -
    -
    - - Employees - -
    -
    -
    -
    -
    - - *... - -
    -
    - - - - - -
    -
    -
    -
    - - * - -
    -
    - history -
    -
    -
    -
    -
    - - *... - -
    -
    - - - - - -
    -
    -
    -
    - - * - -
    -
    - history -
    -
    -
    -
    -
    - - *... - -
    -
    - - - -
    -
    -
    -
    -
    - - 1 - -
    -
    - - Department - -
    -
    -
    -
    -
    -
    - - 1... - -
    -
    - - -
    - - - - - Text is not SVG - cannot display - - - -
    +$$$include diagrams/api-2.drawio.svg$$$ ## 2.2 Example Data @@ -932,266 +393,7 @@ Example 4: simple storage model: object key in dark green, temporal sub-key in light green, foreign keys in orange, non-key fields in blue ::: - - - - - - - - - -
    -
    -
    - Employee -
    -
    -
    -
    - - Employee - -
    -
    - - - - -
    -
    -
    - ID: String {id} -
    -
    -
    -
    - - ID: String {id} - -
    -
    - - - - -
    -
    -
    - From: Date {id} -
    -
    -
    -
    - - From: Date {id} - -
    -
    - - - - -
    -
    -
    - To: Date -
    -
    -
    -
    - - To: Date - -
    -
    - - - - -
    -
    -
    - Name: String -
    -
    -
    -
    - - Name: String - -
    -
    - - - - -
    -
    -
    - Jobtitle: String -
    -
    -
    -
    - - Jobtitle: String - -
    -
    - - - - -
    -
    -
    - Department.ID -
    -
    -
    -
    - - Department.ID - -
    -
    - - - - - - -
    -
    -
    - Department -
    -
    -
    -
    - - Department - -
    -
    - - - - -
    -
    -
    - ID: String {id} -
    -
    -
    -
    - - ID: String {id} - -
    -
    - - - - -
    -
    -
    - From: Date {id} -
    -
    -
    -
    - - From: Date {id} - -
    -
    - - - - -
    -
    -
    - To: Date -
    -
    -
    -
    - - To: Date - -
    -
    - - - - -
    -
    -
    - Name: String -
    -
    -
    -
    - - Name: String - -
    -
    - - - - -
    -
    -
    - Budget: Decimal -
    -
    -
    -
    - - Budget: Decimal - -
    -
    - - - -
    -
    -
    -
    -
    - 1 -
    -
    -
    -
    -
    -
    - - 1 - -
    -
    - - -
    - - - - - Text is not SVG - cannot display - - - -
    +$$$include diagrams/db.drawio.svg$$$ The period start date is used as the temporal sub-key for identifying time slices together with the key of the temporal object. diff --git a/lib/README.md b/lib/README.md index ebca07a42..54997c7a0 100644 --- a/lib/README.md +++ b/lib/README.md @@ -77,10 +77,10 @@ new Number("odata-data-aggregation-ext").build(proc.stdin); The HTML file uses CSS stylesheets contained in the [`docs/*/styles`](../docs/odata-data-aggregation-ext/styles) subfolder in order to render keywords in the same font (MathJax Typewriter) whether they occur standalone or in a formula: -| Keyword occurs | Markdown source | Rendered result | -| ------------------ | ------------------------------------ | ------------------------------------ | -| standalone | `` The `aggregate` transformation `` | The ${\tt aggregate}$ transformation | -| in MathJax formula | `${\tt aggregate}(α{\tt\ as\ }D)$` | ${\tt aggregate}(α{\tt\ as\ }D)$ | +| Keyword occurs | Markdown source | Rendered result | +| ------------------ | ---------------------------------- | ------------------------------------ | +| standalone | ``The `aggregate` transformation`` | The ${\tt aggregate}$ transformation | +| in MathJax formula | `${\tt aggregate}(α{\tt\ as\ }D)$` | ${\tt aggregate}(α{\tt\ as\ }D)$ | A monospaced font (Courier New) is used for OData requests and their JSON or XML responses. diff --git a/lib/build-pdf.js b/lib/build-pdf.js index 7a579aaff..5f83987d6 100644 --- a/lib/build-pdf.js +++ b/lib/build-pdf.js @@ -10,7 +10,7 @@ iterator(function (srcname, name, variant, meta) { console.log( refreshed ? "✓" : "=", srcname, - variant === "meta" ? "" : variant + variant === "meta" ? "" : variant, ); }) .catch((error) => { diff --git a/lib/build.js b/lib/build.js index b538990d6..cae144610 100644 --- a/lib/build.js +++ b/lib/build.js @@ -22,7 +22,7 @@ iterator(function (srcname, name, variant, meta) { "--metadata-file": `${__dirname}/../${srcname}/${variant}.yaml`, }); html.stdout.pipe( - fs.createWriteStream(`${__dirname}/../docs/${name}/${name}.html`) + fs.createWriteStream(`${__dirname}/../docs/${name}/${name}.html`), ); new Number(srcname, variant, meta) .build( @@ -34,7 +34,7 @@ iterator(function (srcname, name, variant, meta) { .on("end", function () { md.end(); html.stdin.end(); - }) + }), ) .then(() => { console.log("✓", srcname, variant === "meta" ? "" : variant); @@ -53,5 +53,5 @@ fs.writeFileSync( This repository contains working drafts for OData specifications: ${docs.sort().join("\n")} -` +`, ); diff --git a/lib/clean.mjs b/lib/clean.mjs index b97e2956e..4485211ea 100644 --- a/lib/clean.mjs +++ b/lib/clean.mjs @@ -18,7 +18,7 @@ const clean = old .replaceAll("\r\n", "\n") .replace( /( |\n|\s)+<\/span>/g, - " " + " ", ) .replace(/[\d\. \n]*<\/a>/g, "") .replace(/([^>]*)<\/a>/g, "$1") @@ -28,30 +28,30 @@ const clean = old // clean up formatting .replace( /([^<]*)<\/span>/g, - "$1" + "$1", ) .replace( /([^<]*)<\/span>/g, - "$5" + "$5", ) .replace( /([^<]*)<\/span>/g, - "$1" + "$1", ) .replace(/([^<]*)<\/span>/g, "$1") .replace( /([^<]*)<\/span>/g, - "$2" + "$2", ) .replace(/([^<]*)<\/span>/g, "$2") .replace( /([^<]*)<\/span>/g, - "$2" + "$2", ) .replace(/([^<]*)<\/span>/g, "$1") .replace( /([^<]*)([^<]*)<\/b><\/span>/g, - "$1$2" + "$1$2", ) .replace(/([^<]*)<\/span>/g, "$1") .replace(/([^<]*)<\/span>/g, "$1") @@ -61,7 +61,7 @@ const clean = old // clean up code formatting .replace( /([^<]*)<\/span>/g, - "$4" + "$4", ) .replace(/([^<]*)<\/span>/g, "$1") .replace(/([^<]*)<\/span>/g, "$1") @@ -70,11 +70,11 @@ const clean = old .replaceAll("", "") .replace( /((|<\/code>|[^<])*)<\/span>/g, - "$2" + "$2", ) .replace( /([^<]*)<\/p>/g, - "

    $1

    " + "

    $1

    ", ) .replace(/ <\/code><\/span>/g, "") .replace(/ <\/i><\/span>/g, "") @@ -82,7 +82,7 @@ const clean = old // clean up headings .replace( /((|<\/code>|[^<])*)<\/a><\/h/g, - "$1[\d\.\s]*/g, "

    ##sec ") .replace(/

    [\d\.\s]*/g, "

    ##subsec ") @@ -94,7 +94,7 @@ const clean = old // TODO: clean up more
    tags .replace( /
    ([\s\S]*?)<\/div>/g, - "$1" + "$1", ) // clean up references @@ -134,11 +134,11 @@ const final = raw // bullet points .replace( /\n\[· \]\{style="(font-size:[\d\.]+pt;)?font-family:\n?Symbol(;color:black)?(;font-style:normal)?"\}/g, - "- " + "- ", ) .replace( /\n\[\[·[ \n]\]\{style="(font-size:[\d\.]+pt;)?font-family:Symbol(;\n?color:(black|windowtext))?"\}\]\{[^}]*\}/g, - "- " + "- ", ) // code blocks .replace( @@ -149,25 +149,25 @@ const final = raw .replace(/`\n\n`/g, "\n") .replace(/^`/, "") .replace(/`$/, "") + - "\n```\n" + "\n```\n", ) // CSDL representation-specific stuff .replace( /^::: \{style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 8.0pt;\nmargin-left:21.55pt;margin-right:0in"\}\n/gm, - "::: csdlHeadline\n" + "::: csdlHeadline\n", ) .replace( /^::: \{style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 8.0pt;\nmargin-left:21.55pt;margin-right:21.55pt"\}\n/gm, - "::: csdl\n" + "::: csdl\n", ) // examples: twice for consecutive examples without empty lines between them .replace( /\nExample \d+:([\s\S]*?)\n\n/g, - "\n::: example\nExample ##ex:$1\n:::\n\n" + "\n::: example\nExample ##ex:$1\n:::\n\n", ) .replace( /\n ?Example \d+:([\s\S]*?)\n\n/g, - "\n::: example\nExample ##ex:$1\n:::\n\n" + "\n::: example\nExample ##ex:$1\n:::\n\n", ) // minor tweaks .replace(/\[([^\]]+)\]\{#_Toc[^}]+\}/g, "$1"); diff --git a/lib/iterator.js b/lib/iterator.js index 101ddfe7d..f43d48876 100644 --- a/lib/iterator.js +++ b/lib/iterator.js @@ -2,25 +2,27 @@ const fs = require("fs"); const yaml = require("js-yaml"); module.exports = function (callback) { - fs.readdirSync(__dirname + "/..", { withFileTypes: true }).forEach(function ( - doc - ) { - if (doc.isDirectory() && doc.name.startsWith("odata-")) { - fs.readdirSync(`${__dirname}/../${doc.name}`) - .filter((fn) => fn.endsWith(".yaml")) - .forEach(function (metaname) { - var meta = yaml.load( - fs.readFileSync(`${__dirname}/../${doc.name}/${metaname}`) - ); - var name = - metaname === "meta.yaml" || !meta.dirname ? doc.name : meta.dirname; - callback( - doc.name, - name, - metaname.substring(0, metaname.length - 5), - meta - ); - }); - } - }); + fs.readdirSync(__dirname + "/..", { withFileTypes: true }).forEach( + function (doc) { + if (doc.isDirectory() && doc.name.startsWith("odata-")) { + fs.readdirSync(`${__dirname}/../${doc.name}`) + .filter((fn) => fn.endsWith(".yaml")) + .forEach(function (metaname) { + var meta = yaml.load( + fs.readFileSync(`${__dirname}/../${doc.name}/${metaname}`), + ); + var name = + metaname === "meta.yaml" || !meta.dirname + ? doc.name + : meta.dirname; + callback( + doc.name, + name, + metaname.substring(0, metaname.length - 5), + meta, + ); + }); + } + }, + ); }; diff --git a/lib/number.js b/lib/number.js index a1c9357dd..1377f4bc4 100644 --- a/lib/number.js +++ b/lib/number.js @@ -51,6 +51,7 @@ class Number { function (resolve, reject) { this.fence = undefined; this.skipping = undefined; + var lineno = 0; createInterface({ input: fs.createReadStream(this.dir + "/" + file), crlfDelay: Infinity, @@ -58,59 +59,68 @@ class Number { .on( "line", function (line) { + lineno++; if (this.skip(line)) return; - for (var m, regex = //g; (m = regex.exec(line)); ) - this.refs[m[1]] = true; - m = line.match(/ ##([A-Za-z0-9.]+)(_([A-Za-z0-9]+))?/); - if (m && line[m.index + m[0].length] !== "]") { - if ( - !m[1].startsWith("sub") && - m[1].endsWith("isec") && - !this.toc[m[1]] + try { + for ( + var m, regex = //g; + (m = regex.exec(line)); + ) - this.toc[m[1]] = { sub: [] }; - if (m[1].endsWith("sec")) { - m = line.match( - / ##([A-Za-z0-9.]+)(?:_[A-Za-z0-9]+)?\s+(.+)$/, - ); - m[3] = m[2].replace(/[^A-Za-z0-9]/g, ""); - } - this.counter[m[1]] = (this.counter[m[1]] || 0) + 1; - for (var subc in this.counter) - if (subc.endsWith("sub" + m[1])) this.counter[subc] = 0; - this.number[this.match] = this.secno(m[1]); - for (var supc = m[1]; supc.startsWith("sub"); ) - this.number[this.match] = - this.secno((supc = supc.substring(3))) + - "." + - this.number[this.match]; - if (m[1].endsWith("isec")) { - m[3] += this.number[this.match]; - this.number[this.match] = "i" + this.number[this.match]; - } - if (m[1].endsWith("sec")) { - var s = this.number[this.match]; - this.toc[s] = { - number: s, - name: m[2], - href: m[3], - sub: [], - }; - var p = s.substring(0, s.lastIndexOf(".")); - if (p === "" && m[1].endsWith("isec")) p = m[1]; - this.toc[p]?.sub.push(this.toc[s]); - } - if (m[2]) { - this.refs[m[3]] = this.number[this.match]; - this.number[this.match] = `${ - this.number[this.match].startsWith("i") - ? "" - : this.number[this.match] - }${m[1] === "asec" ? "." : ""}`; + this.refs[m[1]] = true; + m = line.match(/ ##([A-Za-z0-9.]+)(_([A-Za-z0-9]+))?/); + if (m && line[m.index + m[0].length] !== "]") { + if ( + !m[1].startsWith("sub") && + m[1].endsWith("isec") && + !this.toc[m[1]] + ) + this.toc[m[1]] = { sub: [] }; + if (m[1].endsWith("sec")) { + m = line.match( + / ##([A-Za-z0-9.]+)(?:_[A-Za-z0-9]+)?\s+(.+)$/, + ); + m[3] = m[2].replace(/[^A-Za-z0-9]/g, ""); + } + this.counter[m[1]] = (this.counter[m[1]] || 0) + 1; + for (var subc in this.counter) + if (subc.endsWith("sub" + m[1])) this.counter[subc] = 0; + this.number[this.match] = this.secno(m[1]); + for (var supc = m[1]; supc.startsWith("sub"); ) + this.number[this.match] = + this.secno((supc = supc.substring(3))) + + "." + + this.number[this.match]; + if (m[1].endsWith("isec")) { + m[3] += "." + this.number[this.match]; + this.number[this.match] = "i" + this.number[this.match]; + } + if (m[1].endsWith("sec")) { + var s = this.number[this.match]; + this.toc[s] = { + number: s, + name: m[2], + href: m[3], + sub: [], + }; + var p = s.substring(0, s.lastIndexOf(".")); + if (p === "" && m[1].endsWith("isec")) p = m[1]; + this.toc[p]?.sub.push(this.toc[s]); + } + if (m[2]) { + this.refs[m[3]] = this.number[this.match]; + this.number[this.match] = `${ + this.number[this.match].startsWith("i") + ? "" + : this.number[this.match] + }${m[1] === "asec" ? "." : ""}`; + } + this.match++; } - this.match++; + } catch (e) { + this.errors.push(`${file}#${lineno}: ${e.toString()}`); } }.bind(this), ) @@ -134,60 +144,59 @@ class Number { function (line) { lineno++; if (this.skip(line)) return; - var m1 = line.match(/^\$\$\$include\s+(.*?)\$\$\$\s*$/); - if (m1) { - try { - out.write(fs.readFileSync(this.dir + "/" + m1[1])); - } catch (e) { - this.errors.push(e); - } - return; - } - m1 = line.match(/^\$\$\$(.*?isec)\$\$\$\s*$/); - if (m1) this.tableofcontents(this.toc[m1[1]]?.sub || [], out, ""); - else { - line = line.replace( - /\$\$\$(.*?)\$\$\$/g, - function (m, p) { - return this.meta[p] || m; - }.bind(this), - ); - for (var m, regex = /\]\(#(.*?)\)/g; (m = regex.exec(line)); ) - if (!this.refs[m[1]]) - this.errors.push( - `${this.dir}/${file}(${lineno}): Undefined link #${m[1]}`, - ); - m = line.match(/ ##([A-Za-z0-9.]+)(_([A-Za-z0-9]+))?/); - var outline = line; - if (m && line[m.index + m[0].length] !== "]") { - var prefix = line.substring(0, m.index) + " "; - var suffix = line.substring(m.index + m[0].length); - if (m[1].endsWith("sec")) - outline = ( - prefix + - this.number[this.match].replace(/<\/a>$/, suffix + "") - ) - .replace(/(Appendix )()/, "$2$1") - .replace(/(,? )(<\/a>)$/, "$2$1"); - else outline = prefix + this.number[this.match] + suffix; - this.match++; - } - out.write( - outline.replace( - /##([A-Za-z0-9.]+)\]/g, + try { + var m1 = line.match(/^\$\$\$(.*?isec)\$\$\$$/); + if (m1) + this.tableofcontents(this.toc[m1[1]]?.sub || [], out, ""); + else { + line = line.replace( + /\$\$\$(.*?)\$\$\$/g, function (m, p) { - var r = this.refs[p]; - if (r) return `${r}](#${p})`; - else { - this.errors.push( - `${this.dir}/${file}(${lineno}): Undefined link ##${p}`, - ); - return `~~${p}~~]`; - } + return this.meta[p] || m; }.bind(this), - ), - ); - if (!/\S\s$/.test(line)) out.write("\n"); + ); + for (var m, regex = /\]\(#(.*?)\)/g; (m = regex.exec(line)); ) + if (!this.refs[m[1]]) + this.errors.push( + `${this.dir}/${file}(${lineno}): Undefined link #${m[1]}`, + ); + m = line.match(/ ##([A-Za-z0-9.]+)(_([A-Za-z0-9]+))?/); + var outline = line; + if (m && line[m.index + m[0].length] !== "]") { + var prefix = line.substring(0, m.index) + " "; + var suffix = line.substring(m.index + m[0].length); + if (m[1].endsWith("sec")) + outline = ( + prefix + + this.number[this.match].replace( + /<\/a>$/, + suffix + "", + ) + ) + .replace(/(Appendix )?()\s*/, "$2$1") + .replace(/(,? )(<\/a>)$/, "$2$1"); + else outline = prefix + this.number[this.match] + suffix; + this.match++; + } + out.write( + outline.replace( + /##([A-Za-z0-9.]+)\]/g, + function (m, p) { + var r = this.refs[p]; + if (r) return `${r}](#${p})`; + else { + this.errors.push( + `${this.dir}/${file}(${lineno}): Undefined link ##${p}`, + ); + return `~~${p}~~]`; + } + }.bind(this), + ), + ); + if (!/\S\s$/.test(line)) out.write("\n"); + } + } catch (e) { + this.errors.push(`${file}#${lineno}: ${e.toString()}`); } }.bind(this), ) diff --git a/lib/pdf.js b/lib/pdf.js index 42e93bc77..7067992d6 100644 --- a/lib/pdf.js +++ b/lib/pdf.js @@ -39,7 +39,7 @@ module.exports = async function (name, _variant, meta, force) { }); const page = await browser.newPage(); const htmlUrl = url.pathToFileURL( - `${__dirname}/../docs/${name}/${name}.html` + `${__dirname}/../docs/${name}/${name}.html`, ).href; await page.goto(htmlUrl, { waitUntil: "networkidle2", diff --git a/test/test-data/source.md b/test/test-data/source.md index 78d694712..9ec016de4 100644 --- a/test/test-data/source.md +++ b/test/test-data/source.md @@ -5,12 +5,18 @@ $$$pagetitle$$$ Example ##ex_ref: [Section ##Firstsubsection] contains [example ##ref]. +### ##isec Matrix + $$\matrix{ {\tt concat}(T,\hfill&\tt (1)\\ \quad{\tt aggregate}(α{\tt\ as\ }D))\hfill&\tt (2) }$$ +### ##subisec Table + A|B -|- C| D + +$$$isec$$$ diff --git a/test/test-data/test.html b/test/test-data/test.html index ef74cb567..82a85eda9 100644 --- a/test/test-data/test.html +++ b/test/test-data/test.html @@ -41,7 +41,9 @@

    1 First sec

    1.1 First subsection

    Test document

    Example 1: Section 1.1 contains example 1.

    +

    Matrix

    \[\matrix{ {\tt concat}(T,\hfill&\tt (1)\\ \quad{\tt aggregate}(α{\tt\ as\ }D))\hfill&\tt (2) }\]

    +

    Table

    @@ -56,5 +58,11 @@

    1

    + diff --git a/test/test-data/test.md.txt b/test/test-data/test.md.txt index 55609dc2f..ee31f3dfe 100644 --- a/test/test-data/test.md.txt +++ b/test/test-data/test.md.txt @@ -14,9 +14,16 @@ Test document Example 1: [Section 1.1](#Firstsubsection) contains [example 1](#ref). +### Matrix + $$\matrix{ {\tt concat}(T,\hfill&\tt (1)\\ \quad{\tt aggregate}(α{\tt\ as\ }D))\hfill&\tt (2) }$$ +### Table + A|B -|- C| D +- [Matrix](#Matrix.1) + - [Table](#Table.1.1) +