diff --git a/README.md b/README.md index 038cb9cd6..072df99e2 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,18 @@ Documents are generated from Markdown sources using Node.js modules described [h 3. Download and install [git](https://git-scm.com/), verify via `git -v` 4. Optionally download and install [GitHub Desktop](https://desktop.github.com/) 5. Clone this repository -6. In the local repository folder run `npm install`, verify via `npm test` +6. In the local repository folder run `npm install`, verify via `npm test` + Repeat this step if the test fails with an error message like the following after upgrading to a new Chrome version: + ``` + 1 failing + + 1) OASIS doc build + Puppeteer: + Error: Could not find Chrome (ver. 116.0.5845.96). This can occur if either + 1. you did not perform an installation before running the script (e.g. `npm install`) or + 2. your cache path is incorrectly configured (which is: C:\Users\D024504\.cache\puppeteer). + For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration. + ``` ### Document preparation diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html index d5d994e9a..34a3eb55d 100644 --- a/docs/odata-csdl-json/odata-csdl-json.html +++ b/docs/odata-csdl-json/odata-csdl-json.html @@ -2238,73 +2238,141 @@

14.2.2 Target

The target of an annotation is the model element the term is applied to.

The target of an annotation MAY be specified indirectly by "nesting" the annotation within the model element. Whether and how this is possible is described per model element in this specification.

The target of an annotation MAY also be specified directly; this allows defining an annotation in a different schema than the targeted model element.

-

This external targeting is only possible for model elements that are uniquely identified within their parent, and all their ancestor elements are uniquely identified within their parent:

- +

This external targeting is only possible for model elements that are uniquely identified within their parent, and all their ancestor elements are uniquely identified within their parent.

These are the direct children of a schema with a unique name (i.e. except actions and functions whose overloads to not possess a natural identifier), and all direct children of an entity container.

-

External targeting is possible for actions, functions, their parameters, and their return type, either in a way that applies to all overloads of the action or function or all parameters of that name across all overloads, or in a way that identifies a single overload.

-

External targeting is also possible for properties and navigation properties of singletons or entities in a particular entity set. These annotations override annotations on the properties or navigation properties targeted via the declaring structured type.

-

The allowed path expressions are:

- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Model elementCan be targeted with path expression (see also section 14.4.1.1)

Example 42: Target expressions

Action overloadqualified name of action followed by parentheses containing the binding parameter type of a bound action overload to identify that bound overload, or by empty parentheses to identify the unbound overload
MySchema.MyAction(MySchema.MyBindingType) 
MySchema.MyAction(Collection(MySchema.BindingType))
MySchema.MyAction()
all overloads of an Actionqualified name of action
MySchema.MyAction
Action Importqualified name of entity container followed by a segment containing the action import name
MySchema.MyEntityContainer/MyActionImport
Annotation on a model elementpath expression identifying the model element followed by a segment containing an at (@) prepended to the qualified name of a term, optionally suffixed with a hash (#) and the qualifier of an annotation
MySchema.MyEntityType/@MyVocabulary.MyTerm 
MySchema.MyEntityType/@MyVocabulary.MyTerm#MyQualifier
Complex Typequalified name of complex type
MySchema.MyComplexType
Entity Containerqualified name of entity container
MySchema.MyEntityContainer
Entity Setqualified name of entity container followed by a segment containing the entity set name
MySchema.MyEntityContainer/MyEntitySet
Entity Typequalified name of entity type
MySchema.MyEntityType
Enumeration Typequalified name of enumeration type
MySchema.MyEnumType
Enumeration Type Memberqualified name of enumeration type followed by a segment containing the name of a child element
MySchema.MyEnumType/MyMember
Function overloadqualified name of function followed by parentheses containing the comma-separated list of the parameter types of a bound or unbound function overload in the order of their definition in the function overload
MySchema.MyFunction(MySchema.MyBindingParamType, 
First.NonBinding.ParamType)
MySchema.MyFunction(First.NonBinding.ParamType,
Second.NonBinding.ParamType)
all overloads of a Functionqualified name of function
MySchema.MyFunction
Function Importqualified name of entity container followed by a segment containing the function import name
MySchema.MyEntityContainer/MyFunctionImport
Navigation Property via containerqualified name of entity container followed by a segment containing a singleton or entity set name and zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast
MySchema.MyEntityContainer/MyEntitySet 
/MyNavigationProperty
MySchema.MyEntityContainer/MyEntitySet
/MySchema.MyEntityType/MyNavProperty
MySchema.MyEntityContainer/MyEntitySet
/MyComplexProperty/MyNavProperty
MySchema.MyEntityContainer/MySingleton
/MyComplexProperty/MyNavProperty
Navigation Property via structured typequalified name of structured type followed by zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast
MySchema.MyEntityType/MyNavigationProperty 
MySchema.MyComplexType/MyNavigationProperty
Parameterqualified name of entity container followed by a segment containing an action or function import name followed by a segment containing a parameter name
MySchema.MyEntityContainer/MyFunctionImport/MyParameter
Parameterqualified name of action or function optionally followed by a parenthesized expression as in the first row followed by a segment containing the name of a child element
MySchema.MyFunction/MyParameter
Property via containerqualified name of entity container followed by a segment containing a singleton or entity set name and zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast
MySchema.MyEntityContainer/MyEntitySet 
/MyProperty
MySchema.MyEntityContainer/MyEntitySet
/MySchema.MyEntityType/MyProperty
MySchema.MyEntityContainer/MyEntitySet
/MyComplexProperty/MyProperty
Property via structured typequalified name of structured type followed by zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast
MySchema.MyEntityType/MyProperty 
MySchema.MyComplexType/MyProperty
Return Typequalified name of entity container followed by a segment containing an action or function import name followed by a segment containing $ReturnType
MySchema.MyEntityContainer/MyFunctionImport/$ReturnType
Return Typequalified name of action or function optionally followed by a parenthesized expression as in the first row followed by a segment containing $ReturnType
MySchema.MyFunction/$ReturnType 
MySchema.MyFunction(MySchema.MyBindingParamType,
First.NonBinding.ParamType)/$ReturnType
Singletonqualified name of entity container followed by a segment containing a singleton name
MySchema.MyEntityContainer/MySingleton
Termqualified name of term
MySchema.MyTerm
Type Definitionqualified name of type definition
MySchema.MyTypeDefinition

All qualified names used in a target path MUST be in scope.

-
-

Example 42: Target expressions

-
MySchema.MyEntityType
-MySchema.MyEntityType/MyProperty
-MySchema.MyEntityType/MyNavigationProperty
-MySchema.MyComplexType
-MySchema.MyComplexType/MyProperty
-MySchema.MyComplexType/MyNavigationProperty
-MySchema.MyEnumType
-MySchema.MyEnumType/MyMember
-MySchema.MyTypeDefinition
-MySchema.MyTerm
-MySchema.MyEntityContainer
-MySchema.MyEntityContainer/MyEntitySet
-MySchema.MyEntityContainer/MySingleton
-MySchema.MyEntityContainer/MyActionImport
-MySchema.MyEntityContainer/MyFunctionImport
-MySchema.MyAction
-MySchema.MyAction(MySchema.MyBindingType)
-MySchema.MyAction()
-MySchema.MyFunction
-MySchema.MyFunction(MySchema.MyBindingParamType,First.NonBinding.ParamType)
-MySchema.MyFunction(First.NonBinding.ParamType,Second.NonBinding.ParamType)
-MySchema.MyFunction/MyParameter
-MySchema.MyEntityContainer/MyEntitySet/MyProperty
-MySchema.MyEntityContainer/MyEntitySet/MyNavigationProperty
-MySchema.MyEntityContainer/MyEntitySet/MySchema.MyEntityType/MyProperty
-MySchema.MyEntityContainer/MyEntitySet/MySchema.MyEntityType/MyNavProperty
-MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyProperty
-MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyNavigationProperty
-MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyNavigationProperty
-
+

External targeting is possible for properties and navigation properties of singletons or entities in a particular entity set. These annotations override annotations on the properties or navigation properties targeted via the declaring structured type.

14.3 Constant Expression

Constant expressions allow assigning a constant value to an applied term.

14.3.1 Binary

@@ -2313,7 +2381,7 @@

14.3.1 Binary

Example 43: base64url-encoded binary value (OData)

-
"@UI.Thumbnail": "T0RhdGE"
+
"@UI.Thumbnail": "T0RhdGE"

14.3.2 Boolean

@@ -2321,7 +2389,7 @@

14.3.2 Boolean

Example 44:

-
"@UI.ReadOnly": true
+
"@UI.ReadOnly": true

14.3.3 Date

@@ -2329,7 +2397,7 @@

14.3.3 Date

Example 45:

-
"@vCard.birthDay": "2000-01-01"
+
"@vCard.birthDay": "2000-01-01"

14.3.4 DateTimeOffset

@@ -2337,7 +2405,7 @@

14.

Example 46:

-
"@UI.LastUpdated": "2000-01-01T16:00:00.000Z"
+
"@UI.LastUpdated": "2000-01-01T16:00:00.000Z"

14.3.5 Decimal

@@ -2345,11 +2413,11 @@

14.3.5 Decimal

Example 47: default representation as a number

-
"@UI.Width": 3.14
+
"@UI.Width": 3.14

Example 48: "safe" representation as a string

-
"@UI.Width": "3.14"
+
"@UI.Width": "3.14"

14.3.6 Duration

@@ -2357,7 +2425,7 @@

14.3.6 Duration

Example 49:

-
"@task.duration": "P7D"
+
"@task.duration": "P7D"

14.3.7 Enumeration Member

@@ -2365,13 +2433,13 @@

Example 50: single value Red with numeric value and symbolic value

-
"@self.HasPattern": "1"
-
"@self.HasPattern": "Red"
+
"@self.HasPattern": "1"
+
"@self.HasPattern": "Red"

Example 51: combined value Red,Striped with numeric value 1 + 16 and symbolic value

-
"@self.HasPattern": "17"
-
"@self.HasPattern": "Red,Striped"
+
"@self.HasPattern": "17"
+
"@self.HasPattern": "Red,Striped"

14.3.8 Floating-Point Number

@@ -2379,8 +2447,8 @@

Example 52:

-
"@UI.FloatWidth": 3.14
-
"@UI.FloatWidth": "INF"
+
"@UI.FloatWidth": 3.14
+
"@UI.FloatWidth": "INF"

14.3.9 Guid

@@ -2388,7 +2456,7 @@

14.3.9 Guid

Example 53:

-
"@UI.Id": "21EC2020-3AEA-1069-A2DD-08002B30309D"
+
"@UI.Id": "21EC2020-3AEA-1069-A2DD-08002B30309D"

14.3.10 Integer

@@ -2396,11 +2464,11 @@

14.3.10 Integer

Example 54: default representation as a number

-
"@An.Int": 42
+
"@An.Int": 42

Example 55: "safe" representation as a string

-
"@A.Very.Long.Int": "9007199254740992"
+
"@A.Very.Long.Int": "9007199254740992"

14.3.11 String

@@ -2408,7 +2476,7 @@

14.3.11 String

Example 56:

-
"@UI.DisplayName": "Product Catalog"
+
"@UI.DisplayName": "Product Catalog"

14.3.12 Time of Day

@@ -2416,7 +2484,7 @@

14.3.12 Time of

Example 57:

-
"@UI.EndTime": "21:45:00"
+
"@UI.EndTime": "21:45:00"

14.4 Dynamic Expression

Dynamic expressions allow assigning a calculated value to an applied term.

@@ -2505,11 +2573,11 @@

1

Example 67:

-
"@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.

@@ -2519,7 +2587,7 @@

Example 68:

-
"@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:

@@ -2532,14 +2600,14 @@

Example 69:

-
"@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:

@@ -2552,14 +2620,14 @@

14.4.1.

Example 70:

-
"@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.

@@ -2570,13 +2638,13 @@

$Path

Example 71:

-
"@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.

@@ -2612,98 +2680,98 @@

<

Example 72:

-
{
-  "$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.

@@ -2756,71 +2824,71 @@

Example 73:

-
{
-  "$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.

@@ -2835,24 +2903,24 @@

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

Example 74:

-
"@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

@@ -2864,56 +2932,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 75: 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.

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 76: 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 77:

-
{
-  "$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.

@@ -2925,12 +2993,12 @@

$Cast

Example 78:

-
"@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.

@@ -2939,11 +3007,11 @@

14.4.6 Collecti

Example 79:

-
"@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.

@@ -2957,15 +3025,15 @@

$If

Example 80: 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.

@@ -2977,12 +3045,12 @@

$IsOf

Example 81:

-
"@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.

@@ -2995,12 +3063,12 @@

$LabeledEle

Example 82:

-
"@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.

@@ -3010,9 +3078,9 @@

Example 83:

-
"@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.

@@ -3021,7 +3089,7 @@

14.4.11 Null

Example 84:

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

$Null

@@ -3029,10 +3097,10 @@

$Null

Example 85:

-
"@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.

@@ -3046,34 +3114,34 @@

14.4.12 Record

Example 86: this annotation "morphs" the entity type from example 8 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"
-    }
-  }
-}
+
"@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"
+    }
+  }
+}

14.4.13 URL Reference

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

@@ -3086,29 +3154,29 @@

$UrlRef

Example 87:

-
"@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

@@ -3146,270 +3214,270 @@

16 CSDL Ex

16.1 Products and Categories Example

Example 89:

-
{
-  "$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 90:

-
{
-  "$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 84c987342..86ec5c59c 100644 --- a/docs/odata-csdl-json/odata-csdl-json.md +++ b/docs/odata-csdl-json/odata-csdl-json.md @@ -3815,120 +3815,46 @@ element. This external targeting is only possible for model elements that are uniquely identified within their parent, and all their ancestor elements -are uniquely identified within their parent: - -- [Action](#Action) (single or all overloads) -- [Action Import](#ActionImport) -- [Complex Type](#ComplexType) -- [Entity Container](#EntityContainer) -- [Entity Set](#EntitySet) -- [Entity Type](#EntityType) -- [Enumeration Type](#EnumerationType) -- [Enumeration Type Member](#EnumerationTypeMember) -- [Function](#Function) (single or all overloads) -- [Function Import](#FunctionImport) -- [Navigation Property](#NavigationProperty) (via type, entity set, or - singleton) -- [Parameter](#Parameter) of an action or function (single overloads - or all overloads defining the - parameter) -- [Property](#StructuralProperty) (via type, entity set, or singleton) -- [Return Type](#ReturnType) of an action or function (single or all - overloads) -- [Singleton](#Singleton) -- [Type Definition](#TypeDefinition) +are uniquely identified within their parent. These are the direct children of a schema with a unique name (i.e. except actions and functions whose overloads to not possess a natural identifier), and all direct children of an entity container. -External targeting is possible for actions, functions, their parameters, -and their return type, either in a way that applies to all overloads of -the action or function or all parameters of that name across all -overloads, or in a way that identifies a single overload. - -External targeting is also possible for properties and navigation +Model element| Can be targeted with path expression (see also [section 14.4.1.1](#PathSyntax))|

Example 42: Target expressions

+-----|-----|----- +[Action](#Action) overload| qualified name of action followed by parentheses containing the binding parameter type of a bound action overload to identify that bound overload, or by empty parentheses to identify the unbound overload|
`MySchema.MyAction(MySchema.MyBindingType)` 
`MySchema.MyAction(Collection(MySchema.BindingType))`
`MySchema.MyAction()`
+all overloads of an [Action](#Action)| qualified name of action|
`MySchema.MyAction`
+[Action Import](#ActionImport)| qualified name of entity container followed by a segment containing the action import name|
`MySchema.MyEntityContainer/MyActionImport`
+[Annotation](#Annotation) on a model element| path expression identifying the model element followed by a segment containing an at (`@`) prepended to the qualified name of a term, optionally suffixed with a hash (`#`) and the qualifier of an annotation|
`MySchema.MyEntityType/@MyVocabulary.MyTerm` 
`MySchema.MyEntityType/@MyVocabulary.MyTerm#MyQualifier`
+[Complex Type](#ComplexType)| qualified name of complex type|
`MySchema.MyComplexType`
+[Entity Container](#EntityContainer)| qualified name of entity container|
`MySchema.MyEntityContainer`
+[Entity Set](#EntitySet)| qualified name of entity container followed by a segment containing the entity set name|
`MySchema.MyEntityContainer/MyEntitySet`
+[Entity Type](#EntityType)| qualified name of entity type|
`MySchema.MyEntityType`
+[Enumeration Type](#EnumerationType)| qualified name of enumeration type|
`MySchema.MyEnumType`
+[Enumeration Type Member](#EnumerationTypeMember)| qualified name of enumeration type followed by a segment containing the name of a child element|
`MySchema.MyEnumType/MyMember`
+[Function](#Function) overload| qualified name of function followed by parentheses containing the comma-separated list of the parameter types of a bound or unbound function overload in the order of their definition in the function overload|
`MySchema.MyFunction(MySchema.MyBindingParamType,` 
` First.NonBinding.ParamType)`
`MySchema.MyFunction(First.NonBinding.ParamType,`
` Second.NonBinding.ParamType)`
+all overloads of a [Function](#Function)| qualified name of function|
`MySchema.MyFunction`
+[Function Import](#FunctionImport)| qualified name of entity container followed by a segment containing the function import name|
`MySchema.MyEntityContainer/MyFunctionImport`
+[Navigation Property](#NavigationProperty) via container| qualified name of entity container followed by a segment containing a singleton or entity set name and zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast| 
`MySchema.MyEntityContainer/MyEntitySet` 
` /MyNavigationProperty`
`MySchema.MyEntityContainer/MyEntitySet`
` /MySchema.MyEntityType/MyNavProperty`
`MySchema.MyEntityContainer/MyEntitySet`
` /MyComplexProperty/MyNavProperty`
`MySchema.MyEntityContainer/MySingleton`
` /MyComplexProperty/MyNavProperty`
+[Navigation Property](#NavigationProperty) via structured type| qualified name of structured type followed by zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast|
`MySchema.MyEntityType/MyNavigationProperty` 
`MySchema.MyComplexType/MyNavigationProperty`
+[Parameter](#Parameter)| qualified name of entity container followed by a segment containing an action or function import name followed by a segment containing a parameter name|
`MySchema.MyEntityContainer/MyFunctionImport/MyParameter`
+[Parameter](#Parameter)| qualified name of action or function optionally followed by a parenthesized expression as in the first row followed by a segment containing the name of a child element|
`MySchema.MyFunction/MyParameter`
+[Property](#StructuralProperty) via container| qualified name of entity container followed by a segment containing a singleton or entity set name and zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast|
`MySchema.MyEntityContainer/MyEntitySet` 
` /MyProperty`
`MySchema.MyEntityContainer/MyEntitySet`
` /MySchema.MyEntityType/MyProperty`
`MySchema.MyEntityContainer/MyEntitySet`
` /MyComplexProperty/MyProperty`
+[Property](#StructuralProperty) via structured type| qualified name of structured type followed by zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast|
`MySchema.MyEntityType/MyProperty` 
`MySchema.MyComplexType/MyProperty`
+[Return Type](#ReturnType)| qualified name of entity container followed by a segment containing an action or function import name followed by a segment containing `$ReturnType`|
`MySchema.MyEntityContainer/MyFunctionImport/$ReturnType`
+[Return Type](#ReturnType)| qualified name of action or function optionally followed by a parenthesized expression as in the first row followed by a segment containing `$ReturnType`|
`MySchema.MyFunction/$ReturnType` 
`MySchema.MyFunction(MySchema.MyBindingParamType,`
` First.NonBinding.ParamType)/$ReturnType`
+[Singleton](#Singleton)| qualified name of entity container followed by a segment containing a singleton name|
`MySchema.MyEntityContainer/MySingleton`
+[Term](#Term)| qualified name of term|
`MySchema.MyTerm`
+[Type Definition](#TypeDefinition)| qualified name of type definition|
`MySchema.MyTypeDefinition`
+ +All [qualified names](#QualifiedName) used in a target path MUST be in scope. + +External targeting is possible for properties and navigation properties of singletons or entities in a particular entity set. These annotations override annotations on the properties or navigation properties targeted via the declaring structured type. -The allowed path expressions are: -- [qualified name](#QualifiedName) -of schema child -- [qualified -name](#QualifiedName) of schema child followed by a forward slash and -name of child element -- [qualified -name](#QualifiedName) of structured type followed by zero or more -property, navigation property, or type-cast segments, each segment -starting with a forward slash -- [qualified name](#QualifiedName) -of an entity container followed by a segment containing a singleton or -entity set name and zero or more property, navigation property, or -type-cast segments -- [qualified -name](#QualifiedName) of an action followed by parentheses containing -the [qualified name](#QualifiedName) of the binding parameter *type* of -a bound action overload to identify that bound overload, or by empty -parentheses to identify the unbound overload -- [qualified name](#QualifiedName) of a -function followed by parentheses containing the comma-separated list of -[qualified names](#QualifiedName) of the parameter *types* of a bound -or unbound function overload in the order of their definition in the -function overload -- [qualified -name](#QualifiedName) of an action or function, optionally followed by -parentheses as described in the two previous bullet points to identify a -single overload, followed by a forward slash and either a parameter name -or `$ReturnType` -- [qualified -name](#QualifiedName) of an entity container followed by a segment -containing an action or function import name, optionally followed by a -forward slash and either a parameter name or `$ReturnType` - -- One of the preceding, followed by a forward slash, an at (`@`), the - [qualified name](#QualifiedName) of a term, and optionally a hash - (`#`) and the qualifier of an - annotation - -All [qualified names](#QualifiedName) used in a target path MUST be in -scope. - -::: example -Example 42: Target expressions -``` -MySchema.MyEntityType -MySchema.MyEntityType/MyProperty -MySchema.MyEntityType/MyNavigationProperty -MySchema.MyComplexType -MySchema.MyComplexType/MyProperty -MySchema.MyComplexType/MyNavigationProperty -MySchema.MyEnumType -MySchema.MyEnumType/MyMember -MySchema.MyTypeDefinition -MySchema.MyTerm -MySchema.MyEntityContainer -MySchema.MyEntityContainer/MyEntitySet -MySchema.MyEntityContainer/MySingleton -MySchema.MyEntityContainer/MyActionImport -MySchema.MyEntityContainer/MyFunctionImport -MySchema.MyAction -MySchema.MyAction(MySchema.MyBindingType) -MySchema.MyAction() -MySchema.MyFunction -MySchema.MyFunction(MySchema.MyBindingParamType,First.NonBinding.ParamType) -MySchema.MyFunction(First.NonBinding.ParamType,Second.NonBinding.ParamType) -MySchema.MyFunction/MyParameter -MySchema.MyEntityContainer/MyEntitySet/MyProperty -MySchema.MyEntityContainer/MyEntitySet/MyNavigationProperty -MySchema.MyEntityContainer/MyEntitySet/MySchema.MyEntityType/MyProperty -MySchema.MyEntityContainer/MyEntitySet/MySchema.MyEntityType/MyNavProperty -MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyProperty -MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyNavigationProperty -MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyNavigationProperty -``` -::: - ## 14.3 Constant Expression Constant expressions allow assigning a constant value to an applied diff --git a/docs/odata-csdl-json/styles/odata.css b/docs/odata-csdl-json/styles/odata.css index 1c4385312..a309b83c0 100644 --- a/docs/odata-csdl-json/styles/odata.css +++ b/docs/odata-csdl-json/styles/odata.css @@ -220,6 +220,10 @@ h6 { page-break-after: avoid; } +td { + page-break-inside: avoid; +} + h2[id="22-example-data"] { page-break-before: always; } diff --git a/docs/odata-csdl-xml/odata-csdl-xml.html b/docs/odata-csdl-xml/odata-csdl-xml.html index ea56c0906..44b834939 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.html +++ b/docs/odata-csdl-xml/odata-csdl-xml.html @@ -2032,73 +2032,141 @@

14.2.2 Target

The target of an annotation is the model element the term is applied to.

The target of an annotation MAY be specified indirectly by "nesting" the annotation within the model element. Whether and how this is possible is described per model element in this specification.

The target of an annotation MAY also be specified directly; this allows defining an annotation in a different schema than the targeted model element.

-

This external targeting is only possible for model elements that are uniquely identified within their parent, and all their ancestor elements are uniquely identified within their parent:

- +

This external targeting is only possible for model elements that are uniquely identified within their parent, and all their ancestor elements are uniquely identified within their parent.

These are the direct children of a schema with a unique name (i.e. except actions and functions whose overloads to not possess a natural identifier), and all direct children of an entity container.

-

External targeting is possible for actions, functions, their parameters, and their return type, either in a way that applies to all overloads of the action or function or all parameters of that name across all overloads, or in a way that identifies a single overload.

-

External targeting is also possible for properties and navigation properties of singletons or entities in a particular entity set. These annotations override annotations on the properties or navigation properties targeted via the declaring structured type.

-

The allowed path expressions are:

-
    -
  • qualified name of schema child

  • -
  • qualified name of schema child followed by a forward slash and name of child element

  • -
  • qualified name of structured type followed by zero or more property, navigation property, or type-cast segments, each segment starting with a forward slash

  • -
  • qualified name of an entity container followed by a segment containing a singleton or entity set name and zero or more property, navigation property, or type-cast segments

  • -
  • qualified name of an action followed by parentheses containing the qualified name of the binding parameter type of a bound action overload to identify that bound overload, or by empty parentheses to identify the unbound overload

  • -
  • qualified name of a function followed by parentheses containing the comma-separated list of qualified names of the parameter types of a bound or unbound function overload in the order of their definition in the function overload

  • -
  • qualified name of an action or function, optionally followed by parentheses as described in the two previous bullet points to identify a single overload, followed by a forward slash and either a parameter name or $ReturnType

  • -
  • qualified name of an entity container followed by a segment containing an action or function import name, optionally followed by a forward slash and either a parameter name or $ReturnType

  • -
  • One of the preceding, followed by a forward slash, an at (@), the qualified name of a term, and optionally a hash (#) and the qualifier of an annotation

  • -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Model elementCan be targeted with path expression (see also section 14.4.1.1)

Example 42: Target expressions

Action overloadqualified name of action followed by parentheses containing the binding parameter type of a bound action overload to identify that bound overload, or by empty parentheses to identify the unbound overload
MySchema.MyAction(MySchema.MyBindingType) 
MySchema.MyAction(Collection(MySchema.BindingType))
MySchema.MyAction()
all overloads of an Actionqualified name of action
MySchema.MyAction
Action Importqualified name of entity container followed by a segment containing the action import name
MySchema.MyEntityContainer/MyActionImport
Annotation on a model elementpath expression identifying the model element followed by a segment containing an at (@) prepended to the qualified name of a term, optionally suffixed with a hash (#) and the qualifier of an annotation
MySchema.MyEntityType/@MyVocabulary.MyTerm 
MySchema.MyEntityType/@MyVocabulary.MyTerm#MyQualifier
Complex Typequalified name of complex type
MySchema.MyComplexType
Entity Containerqualified name of entity container
MySchema.MyEntityContainer
Entity Setqualified name of entity container followed by a segment containing the entity set name
MySchema.MyEntityContainer/MyEntitySet
Entity Typequalified name of entity type
MySchema.MyEntityType
Enumeration Typequalified name of enumeration type
MySchema.MyEnumType
Enumeration Type Memberqualified name of enumeration type followed by a segment containing the name of a child element
MySchema.MyEnumType/MyMember
Function overloadqualified name of function followed by parentheses containing the comma-separated list of the parameter types of a bound or unbound function overload in the order of their definition in the function overload
MySchema.MyFunction(MySchema.MyBindingParamType, 
First.NonBinding.ParamType)
MySchema.MyFunction(First.NonBinding.ParamType,
Second.NonBinding.ParamType)
all overloads of a Functionqualified name of function
MySchema.MyFunction
Function Importqualified name of entity container followed by a segment containing the function import name
MySchema.MyEntityContainer/MyFunctionImport
Navigation Property via containerqualified name of entity container followed by a segment containing a singleton or entity set name and zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast
MySchema.MyEntityContainer/MyEntitySet 
/MyNavigationProperty
MySchema.MyEntityContainer/MyEntitySet
/MySchema.MyEntityType/MyNavProperty
MySchema.MyEntityContainer/MyEntitySet
/MyComplexProperty/MyNavProperty
MySchema.MyEntityContainer/MySingleton
/MyComplexProperty/MyNavProperty
Navigation Property via structured typequalified name of structured type followed by zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast
MySchema.MyEntityType/MyNavigationProperty 
MySchema.MyComplexType/MyNavigationProperty
Parameterqualified name of entity container followed by a segment containing an action or function import name followed by a segment containing a parameter name
MySchema.MyEntityContainer/MyFunctionImport/MyParameter
Parameterqualified name of action or function optionally followed by a parenthesized expression as in the first row followed by a segment containing the name of a child element
MySchema.MyFunction/MyParameter
Property via containerqualified name of entity container followed by a segment containing a singleton or entity set name and zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast
MySchema.MyEntityContainer/MyEntitySet 
/MyProperty
MySchema.MyEntityContainer/MyEntitySet
/MySchema.MyEntityType/MyProperty
MySchema.MyEntityContainer/MyEntitySet
/MyComplexProperty/MyProperty
Property via structured typequalified name of structured type followed by zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast
MySchema.MyEntityType/MyProperty 
MySchema.MyComplexType/MyProperty
Return Typequalified name of entity container followed by a segment containing an action or function import name followed by a segment containing $ReturnType
MySchema.MyEntityContainer/MyFunctionImport/$ReturnType
Return Typequalified name of action or function optionally followed by a parenthesized expression as in the first row followed by a segment containing $ReturnType
MySchema.MyFunction/$ReturnType 
MySchema.MyFunction(MySchema.MyBindingParamType,
First.NonBinding.ParamType)/$ReturnType
Singletonqualified name of entity container followed by a segment containing a singleton name
MySchema.MyEntityContainer/MySingleton
Termqualified name of term
MySchema.MyTerm
Type Definitionqualified name of type definition
MySchema.MyTypeDefinition

All qualified names used in a target path MUST be in scope.

-
-

Example 42: Target expressions

-
MySchema.MyEntityType
-MySchema.MyEntityType/MyProperty
-MySchema.MyEntityType/MyNavigationProperty
-MySchema.MyComplexType
-MySchema.MyComplexType/MyProperty
-MySchema.MyComplexType/MyNavigationProperty
-MySchema.MyEnumType
-MySchema.MyEnumType/MyMember
-MySchema.MyTypeDefinition
-MySchema.MyTerm
-MySchema.MyEntityContainer
-MySchema.MyEntityContainer/MyEntitySet
-MySchema.MyEntityContainer/MySingleton
-MySchema.MyEntityContainer/MyActionImport
-MySchema.MyEntityContainer/MyFunctionImport
-MySchema.MyAction
-MySchema.MyAction(MySchema.MyBindingType)
-MySchema.MyAction()
-MySchema.MyFunction
-MySchema.MyFunction(MySchema.MyBindingParamType,First.NonBinding.ParamType)
-MySchema.MyFunction(First.NonBinding.ParamType,Second.NonBinding.ParamType)
-MySchema.MyFunction/MyParameter
-MySchema.MyEntityContainer/MyEntitySet/MyProperty
-MySchema.MyEntityContainer/MyEntitySet/MyNavigationProperty
-MySchema.MyEntityContainer/MyEntitySet/MySchema.MyEntityType/MyProperty
-MySchema.MyEntityContainer/MyEntitySet/MySchema.MyEntityType/MyNavProperty
-MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyProperty
-MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyNavigationProperty
-MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyNavigationProperty
-
+

External targeting is possible for properties and navigation properties of singletons or entities in a particular entity set. These annotations override annotations on the properties or navigation properties targeted via the declaring structured type.

14.3 Constant Expression

Constant expressions allow assigning a constant value to an applied term.

14.3.1 Binary

@@ -2109,11 +2177,11 @@

Expression

Example 43: base64url-encoded binary value (OData)

-
<Annotation Term="org.example.display.Thumbnail" Binary="T0RhdGE" />
-
-<Annotation Term="org.example.display.Thumbnail">
-  <Binary>T0RhdGE</Binary>
-</Annotation>
+
<Annotation Term="org.example.display.Thumbnail" Binary="T0RhdGE" />
+
+<Annotation Term="org.example.display.Thumbnail">
+  <Binary>T0RhdGE</Binary>
+</Annotation>

14.3.2 Boolean

@@ -2123,11 +2191,11 @@

Expression

Example 44:

-
<Annotation Term="org.example.display.ReadOnly" Bool="true" />
-
-<Annotation Term="org.example.display.ReadOnly">
-  <Bool>true</Bool>
-</Annotation>
+
<Annotation Term="org.example.display.ReadOnly" Bool="true" />
+
+<Annotation Term="org.example.display.ReadOnly">
+  <Bool>true</Bool>
+</Annotation>

14.3.3 Date

@@ -2137,11 +2205,11 @@

Expression

Example 45:

-
<Annotation Term="org.example.vCard.birthDay" Date="2000-01-01" />
-
-<Annotation Term="org.example.vCard.birthDay">
-  <Date>2000-01-01</Date>
-</Annotation>
+
<Annotation Term="org.example.vCard.birthDay" Date="2000-01-01" />
+
+<Annotation Term="org.example.vCard.birthDay">
+  <Date>2000-01-01</Date>
+</Annotation>

14.3.4 DateTimeOffset

@@ -2151,13 +2219,13 @@

Example 46:

-
<Annotation Term="org.example.display.LastUpdated"
-
-            DateTimeOffset="2000-01-01T16:00:00.000Z" />
-
-<Annotation Term="org.example.display.LastUpdated">
-  <DateTimeOffset>2000-01-01T16:00:00.000-09:00</DateTimeOffset>
-</Annotation>
+
<Annotation Term="org.example.display.LastUpdated"
+
+            DateTimeOffset="2000-01-01T16:00:00.000Z" />
+
+<Annotation Term="org.example.display.LastUpdated">
+  <DateTimeOffset>2000-01-01T16:00:00.000-09:00</DateTimeOffset>
+</Annotation>

14.3.5 Decimal

@@ -2167,13 +2235,13 @@

Expression

Example 47: attribute notation

-
<Annotation Term="org.example.display.Width" Decimal="3.14" />
+
<Annotation Term="org.example.display.Width" Decimal="3.14" />

Example 48: element notation

-
<Annotation Term="org.example.display.Width">
-  <Decimal>3.14</Decimal>
-</Annotation>
+
<Annotation Term="org.example.display.Width">
+  <Decimal>3.14</Decimal>
+</Annotation>

14.3.6 Duration

@@ -2183,11 +2251,11 @@

Expressio

Example 49:

-
<Annotation Term="org.example.task.duration" Duration="P7D" />
-
-<Annotation Term="org.example.task.duration">
-  <Duration>P11DT23H59M59.999999999999S</Duration>
-</Annotation>
+
<Annotation Term="org.example.task.duration" Duration="P7D" />
+
+<Annotation Term="org.example.task.duration">
+  <Duration>P11DT23H59M59.999999999999S</Duration>
+</Annotation>

14.3.7 Enumeration Member

@@ -2197,22 +2265,22 @@

Expre

Example 50: single value

+
<Annotation Term="org.example.HasPattern"
+             EnumMember="org.example.Pattern/Red" />
+
+<Annotation Term="org.example.HasPattern">
+  <EnumMember>org.example.Pattern/Red</EnumMember>
+</Annotation>
+
+
+

Example 51: combined value for IsFlags enumeration type

<Annotation Term="org.example.HasPattern"
-             EnumMember="org.example.Pattern/Red" />
+           EnumMember="org.example.Pattern/Red org.example.Pattern/Striped" />
 
 <Annotation Term="org.example.HasPattern">
-  <EnumMember>org.example.Pattern/Red</EnumMember>
+  <EnumMember>org.example.Pattern/Red org.example.Pattern/Striped</EnumMember>
 </Annotation>
-
-

Example 51: combined value for IsFlags enumeration type

-
<Annotation Term="org.example.HasPattern"
-           EnumMember="org.example.Pattern/Red org.example.Pattern/Striped" />
-
-<Annotation Term="org.example.HasPattern">
-  <EnumMember>org.example.Pattern/Red org.example.Pattern/Striped</EnumMember>
-</Annotation>
-

14.3.8 Floating-Point Number

Expression edm:Float

@@ -2221,11 +2289,11 @@

Expression

Example 52:

-
<Annotation Term="org.example.display.Width" Float="3.14" />
-
-<Annotation Term="org.example.display.Width">
-  <Float>3.14</Float>
-</Annotation>
+
<Annotation Term="org.example.display.Width" Float="3.14" />
+
+<Annotation Term="org.example.display.Width">
+  <Float>3.14</Float>
+</Annotation>

14.3.9 Guid

@@ -2235,12 +2303,12 @@

Expression

Example 53:

-
<Annotation Term="org.example.display.Id"
-            Guid="21EC2020-3AEA-1069-A2DD-08002B30309D" />
-
-<Annotation Term="org.example.display.Id">
-  <Guid>21EC2020-3AEA-1069-A2DD-08002B30309D</Guid>
-</Annotation>
+
<Annotation Term="org.example.display.Id"
+            Guid="21EC2020-3AEA-1069-A2DD-08002B30309D" />
+
+<Annotation Term="org.example.display.Id">
+  <Guid>21EC2020-3AEA-1069-A2DD-08002B30309D</Guid>
+</Annotation>

14.3.10 Integer

@@ -2250,13 +2318,13 @@

Expression ed

Example 54: attribute notation

-
<Annotation Term="org.example.display.Width" Int="42" />
+
<Annotation Term="org.example.display.Width" Int="42" />

Example 55: element notation

-
<Annotation Term="org.example.display.Width">
-  <Int>42</Int>
-</Annotation>
+
<Annotation Term="org.example.display.Width">
+  <Int>42</Int>
+</Annotation>

14.3.11 String

@@ -2266,11 +2334,11 @@

Expression

Example 56:

-
<Annotation Term="org.example.display.DisplayName" String="Product Catalog" />
-
-<Annotation Term="org.example.display.DisplayName">
-  <String>Product Catalog</String>
-</Annotation>
+
<Annotation Term="org.example.display.DisplayName" String="Product Catalog" />
+
+<Annotation Term="org.example.display.DisplayName">
+  <String>Product Catalog</String>
+</Annotation>

14.3.12 Time of Day

@@ -2280,11 +2348,11 @@

Express

Example 57:

-
<Annotation Term="org.example.display.EndTime" TimeOfDay="21:45:00" />
-
-<Annotation Term="org.example.display.EndTime">
-  <TimeOfDay>21:45:00</TimeOfDay>
-</Annotation>
+
<Annotation Term="org.example.display.EndTime" TimeOfDay="21:45:00" />
+
+<Annotation Term="org.example.display.EndTime">
+  <TimeOfDay>21:45:00</TimeOfDay>
+</Annotation>

14.4 Dynamic Expression

Dynamic expressions allow assigning a calculated value to an applied term.

@@ -2374,15 +2442,15 @@

Example 67:

-
<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.

@@ -2393,12 +2461,12 @@

Example 68:

-
<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:

@@ -2412,18 +2480,18 @@

Example 69:

-
<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:

@@ -2437,18 +2505,18 @@

E

Example 70:

-
<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.

@@ -2459,11 +2527,11 @@

Expression

Example 71:

-
<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.

@@ -2499,52 +2567,52 @@

Example 72:

-
<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.

@@ -2597,33 +2665,33 @@

Example 73:

-
<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.

@@ -2640,17 +2708,17 @@

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

Example 74:

-
<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

@@ -2662,34 +2730,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 75: 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.

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 76: 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 77:

-
<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.

@@ -2703,11 +2771,11 @@

Example 78:

-
<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.

@@ -2717,13 +2785,13 @@

Expre

Example 79:

-
<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.

@@ -2737,13 +2805,13 @@

Expression edm:

Example 80: 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.

@@ -2755,11 +2823,11 @@

Expression

Example 81:

-
<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.

@@ -2775,15 +2843,15 @@

Example 82:

-
<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.

@@ -2793,9 +2861,9 @@

Example 83:

-
<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.

@@ -2805,17 +2873,17 @@

Expression

Example 84:

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

Example 85:

-
<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.

@@ -2836,25 +2904,25 @@

Example 86: this annotation "morphs" the entity type from example 8 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>
+
<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>

14.4.13 URL Reference

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

@@ -2868,24 +2936,24 @@

Expression

Example 87:

-
<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

@@ -2923,153 +2991,153 @@

16 CSDL Ex

16.1 Products and Categories Example

Example 89:

-
<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="self.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="self.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 90:

-
<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 b8f24af5e..a60890723 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.md +++ b/docs/odata-csdl-xml/odata-csdl-xml.md @@ -3610,120 +3610,46 @@ element. This external targeting is only possible for model elements that are uniquely identified within their parent, and all their ancestor elements -are uniquely identified within their parent: - -- [Action](#Action) (single or all overloads) -- [Action Import](#ActionImport) -- [Complex Type](#ComplexType) -- [Entity Container](#EntityContainer) -- [Entity Set](#EntitySet) -- [Entity Type](#EntityType) -- [Enumeration Type](#EnumerationType) -- [Enumeration Type Member](#EnumerationTypeMember) -- [Function](#Function) (single or all overloads) -- [Function Import](#FunctionImport) -- [Navigation Property](#NavigationProperty) (via type, entity set, or - singleton) -- [Parameter](#Parameter) of an action or function (single overloads - or all overloads defining the - parameter) -- [Property](#StructuralProperty) (via type, entity set, or singleton) -- [Return Type](#ReturnType) of an action or function (single or all - overloads) -- [Singleton](#Singleton) -- [Type Definition](#TypeDefinition) +are uniquely identified within their parent. These are the direct children of a schema with a unique name (i.e. except actions and functions whose overloads to not possess a natural identifier), and all direct children of an entity container. -External targeting is possible for actions, functions, their parameters, -and their return type, either in a way that applies to all overloads of -the action or function or all parameters of that name across all -overloads, or in a way that identifies a single overload. - -External targeting is also possible for properties and navigation +Model element| Can be targeted with path expression (see also [section 14.4.1.1](#PathSyntax))|

Example 42: Target expressions

+-----|-----|----- +[Action](#Action) overload| qualified name of action followed by parentheses containing the binding parameter type of a bound action overload to identify that bound overload, or by empty parentheses to identify the unbound overload|
`MySchema.MyAction(MySchema.MyBindingType)` 
`MySchema.MyAction(Collection(MySchema.BindingType))`
`MySchema.MyAction()`
+all overloads of an [Action](#Action)| qualified name of action|
`MySchema.MyAction`
+[Action Import](#ActionImport)| qualified name of entity container followed by a segment containing the action import name|
`MySchema.MyEntityContainer/MyActionImport`
+[Annotation](#Annotation) on a model element| path expression identifying the model element followed by a segment containing an at (`@`) prepended to the qualified name of a term, optionally suffixed with a hash (`#`) and the qualifier of an annotation|
`MySchema.MyEntityType/@MyVocabulary.MyTerm` 
`MySchema.MyEntityType/@MyVocabulary.MyTerm#MyQualifier`
+[Complex Type](#ComplexType)| qualified name of complex type|
`MySchema.MyComplexType`
+[Entity Container](#EntityContainer)| qualified name of entity container|
`MySchema.MyEntityContainer`
+[Entity Set](#EntitySet)| qualified name of entity container followed by a segment containing the entity set name|
`MySchema.MyEntityContainer/MyEntitySet`
+[Entity Type](#EntityType)| qualified name of entity type|
`MySchema.MyEntityType`
+[Enumeration Type](#EnumerationType)| qualified name of enumeration type|
`MySchema.MyEnumType`
+[Enumeration Type Member](#EnumerationTypeMember)| qualified name of enumeration type followed by a segment containing the name of a child element|
`MySchema.MyEnumType/MyMember`
+[Function](#Function) overload| qualified name of function followed by parentheses containing the comma-separated list of the parameter types of a bound or unbound function overload in the order of their definition in the function overload|
`MySchema.MyFunction(MySchema.MyBindingParamType,` 
` First.NonBinding.ParamType)`
`MySchema.MyFunction(First.NonBinding.ParamType,`
` Second.NonBinding.ParamType)`
+all overloads of a [Function](#Function)| qualified name of function|
`MySchema.MyFunction`
+[Function Import](#FunctionImport)| qualified name of entity container followed by a segment containing the function import name|
`MySchema.MyEntityContainer/MyFunctionImport`
+[Navigation Property](#NavigationProperty) via container| qualified name of entity container followed by a segment containing a singleton or entity set name and zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast| 
`MySchema.MyEntityContainer/MyEntitySet` 
` /MyNavigationProperty`
`MySchema.MyEntityContainer/MyEntitySet`
` /MySchema.MyEntityType/MyNavProperty`
`MySchema.MyEntityContainer/MyEntitySet`
` /MyComplexProperty/MyNavProperty`
`MySchema.MyEntityContainer/MySingleton`
` /MyComplexProperty/MyNavProperty`
+[Navigation Property](#NavigationProperty) via structured type| qualified name of structured type followed by zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast|
`MySchema.MyEntityType/MyNavigationProperty` 
`MySchema.MyComplexType/MyNavigationProperty`
+[Parameter](#Parameter)| qualified name of entity container followed by a segment containing an action or function import name followed by a segment containing a parameter name|
`MySchema.MyEntityContainer/MyFunctionImport/MyParameter`
+[Parameter](#Parameter)| qualified name of action or function optionally followed by a parenthesized expression as in the first row followed by a segment containing the name of a child element|
`MySchema.MyFunction/MyParameter`
+[Property](#StructuralProperty) via container| qualified name of entity container followed by a segment containing a singleton or entity set name and zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast|
`MySchema.MyEntityContainer/MyEntitySet` 
` /MyProperty`
`MySchema.MyEntityContainer/MyEntitySet`
` /MySchema.MyEntityType/MyProperty`
`MySchema.MyEntityContainer/MyEntitySet`
` /MyComplexProperty/MyProperty`
+[Property](#StructuralProperty) via structured type| qualified name of structured type followed by zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast|
`MySchema.MyEntityType/MyProperty` 
`MySchema.MyComplexType/MyProperty`
+[Return Type](#ReturnType)| qualified name of entity container followed by a segment containing an action or function import name followed by a segment containing `$ReturnType`|
`MySchema.MyEntityContainer/MyFunctionImport/$ReturnType`
+[Return Type](#ReturnType)| qualified name of action or function optionally followed by a parenthesized expression as in the first row followed by a segment containing `$ReturnType`|
`MySchema.MyFunction/$ReturnType` 
`MySchema.MyFunction(MySchema.MyBindingParamType,`
` First.NonBinding.ParamType)/$ReturnType`
+[Singleton](#Singleton)| qualified name of entity container followed by a segment containing a singleton name|
`MySchema.MyEntityContainer/MySingleton`
+[Term](#Term)| qualified name of term|
`MySchema.MyTerm`
+[Type Definition](#TypeDefinition)| qualified name of type definition|
`MySchema.MyTypeDefinition`
+ +All [qualified names](#QualifiedName) used in a target path MUST be in scope. + +External targeting is possible for properties and navigation properties of singletons or entities in a particular entity set. These annotations override annotations on the properties or navigation properties targeted via the declaring structured type. -The allowed path expressions are: -- [qualified name](#QualifiedName) -of schema child -- [qualified -name](#QualifiedName) of schema child followed by a forward slash and -name of child element -- [qualified -name](#QualifiedName) of structured type followed by zero or more -property, navigation property, or type-cast segments, each segment -starting with a forward slash -- [qualified name](#QualifiedName) -of an entity container followed by a segment containing a singleton or -entity set name and zero or more property, navigation property, or -type-cast segments -- [qualified -name](#QualifiedName) of an action followed by parentheses containing -the [qualified name](#QualifiedName) of the binding parameter *type* of -a bound action overload to identify that bound overload, or by empty -parentheses to identify the unbound overload -- [qualified name](#QualifiedName) of a -function followed by parentheses containing the comma-separated list of -[qualified names](#QualifiedName) of the parameter *types* of a bound -or unbound function overload in the order of their definition in the -function overload -- [qualified -name](#QualifiedName) of an action or function, optionally followed by -parentheses as described in the two previous bullet points to identify a -single overload, followed by a forward slash and either a parameter name -or `$ReturnType` -- [qualified -name](#QualifiedName) of an entity container followed by a segment -containing an action or function import name, optionally followed by a -forward slash and either a parameter name or `$ReturnType` - -- One of the preceding, followed by a forward slash, an at (`@`), the - [qualified name](#QualifiedName) of a term, and optionally a hash - (`#`) and the qualifier of an - annotation - -All [qualified names](#QualifiedName) used in a target path MUST be in -scope. - -::: example -Example 42: Target expressions -``` -MySchema.MyEntityType -MySchema.MyEntityType/MyProperty -MySchema.MyEntityType/MyNavigationProperty -MySchema.MyComplexType -MySchema.MyComplexType/MyProperty -MySchema.MyComplexType/MyNavigationProperty -MySchema.MyEnumType -MySchema.MyEnumType/MyMember -MySchema.MyTypeDefinition -MySchema.MyTerm -MySchema.MyEntityContainer -MySchema.MyEntityContainer/MyEntitySet -MySchema.MyEntityContainer/MySingleton -MySchema.MyEntityContainer/MyActionImport -MySchema.MyEntityContainer/MyFunctionImport -MySchema.MyAction -MySchema.MyAction(MySchema.MyBindingType) -MySchema.MyAction() -MySchema.MyFunction -MySchema.MyFunction(MySchema.MyBindingParamType,First.NonBinding.ParamType) -MySchema.MyFunction(First.NonBinding.ParamType,Second.NonBinding.ParamType) -MySchema.MyFunction/MyParameter -MySchema.MyEntityContainer/MyEntitySet/MyProperty -MySchema.MyEntityContainer/MyEntitySet/MyNavigationProperty -MySchema.MyEntityContainer/MyEntitySet/MySchema.MyEntityType/MyProperty -MySchema.MyEntityContainer/MyEntitySet/MySchema.MyEntityType/MyNavProperty -MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyProperty -MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyNavigationProperty -MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyNavigationProperty -``` -::: - ## 14.3 Constant Expression Constant expressions allow assigning a constant value to an applied diff --git a/docs/odata-csdl-xml/styles/odata.css b/docs/odata-csdl-xml/styles/odata.css index 1c4385312..a309b83c0 100644 --- a/docs/odata-csdl-xml/styles/odata.css +++ b/docs/odata-csdl-xml/styles/odata.css @@ -220,6 +220,10 @@ h6 { page-break-after: avoid; } +td { + page-break-inside: avoid; +} + h2[id="22-example-data"] { page-break-before: always; } diff --git a/docs/odata-data-aggregation-ext/styles/odata.css b/docs/odata-data-aggregation-ext/styles/odata.css index 1c4385312..a309b83c0 100644 --- a/docs/odata-data-aggregation-ext/styles/odata.css +++ b/docs/odata-data-aggregation-ext/styles/odata.css @@ -220,6 +220,10 @@ h6 { page-break-after: avoid; } +td { + page-break-inside: avoid; +} + h2[id="22-example-data"] { page-break-before: always; } diff --git a/docs/odata-json-format/odata-json-format.html b/docs/odata-json-format/odata-json-format.html index f42a260fd..6853057c8 100644 --- a/docs/odata-json-format/odata-json-format.html +++ b/docs/odata-json-format/odata-json-format.html @@ -509,6 +509,7 @@

19.1 Batc }

19.2 Referencing New Entities

-

The entity returned by a preceding request can be referenced in the request URL of subsequent requests.

+

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 49: a batch request that contains the following operations in the order listed:

    diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md index 4e9cbac18..6d014668d 100644 --- a/docs/odata-json-format/odata-json-format.md +++ b/docs/odata-json-format/odata-json-format.md @@ -829,6 +829,8 @@ following is true: - The type is for a property whose type is not declared in `$metadata`. +It MAY appear in other cases in requests and responses if its value does not contradict the type declared in `$metadata`. + The following heuristics are used to determine the primitive type of a dynamic property in the absence of the `type` control information: @@ -3007,7 +3009,9 @@ Content-Length: ### ## 19.2 Referencing New Entities The entity returned by a preceding request can be referenced in the -request URL of subsequent requests. +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 49: a batch request that contains the following operations in diff --git a/docs/odata-json-format/styles/odata.css b/docs/odata-json-format/styles/odata.css index 1c4385312..a309b83c0 100644 --- a/docs/odata-json-format/styles/odata.css +++ b/docs/odata-json-format/styles/odata.css @@ -220,6 +220,10 @@ h6 { page-break-after: avoid; } +td { + page-break-inside: avoid; +} + h2[id="22-example-data"] { page-break-before: always; } diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html index d4186e574..fbc790cbf 100644 --- a/docs/odata-protocol/odata-protocol.html +++ b/docs/odata-protocol/odata-protocol.html @@ -1720,7 +1720,7 @@

    If-Match request header in a Data Modification Request or Action Request on a resource that requires optimistic concurrency control, the service responds with a 428 Precondition Required and MUST ensure that no observable change occurs as a result of the request. Clients can attempt to disable optimistic concurrency control by specifying If-Match with a value of *. Services MAY reject such requests.

    For requests including an OData-Version header value of 4.01, any ETag values specified in the request body of an update request MUST be * or match the current value for the record being updated.

    11.4.1.2 Handling of DateTimeOffset Values

    -

    Services SHOULD preserve the offset of Edm.DateTimeOffset values, if possible. However, where the underlying storage does not support offset services may be forced to normalize the value to some common time zone (i.e. UTC) in which case the result would be returned with that time zone offset. If the service normalizes values, it MUST fail evaluation of the query functions year, month, day, hour, and time for literal values that are not stated in the time zone of the normalized values.

    +

    Services SHOULD preserve the offset of Edm.DateTimeOffset values, if possible. However, where the underlying storage does not support offset services may be forced to normalize the value to some common time zone (for example UTC) in which case the result would be returned with that time zone offset. If the service normalizes values, it MUST fail evaluation of the query functions year, month, day, hour, and time for literal values that are not stated in the time zone of the normalized values.

    11.4.1.3 Handling of Properties Not Advertised in Metadata

    Clients MUST be prepared to receive additional properties in an entity or complex type instance that are not advertised in metadata, even for types not marked as open. By using PATCH when updating entities, clients can ensure that such properties values are not lost if omitted from the update request.

    11.4.1.4 Handling of Integrity Constraints

    @@ -2217,7 +2217,7 @@

    OData-ABNF.

    The representation of the request identifier is format-specific, as are the rules for which individual requests require an identifier.

    11.7.4 Referencing Returned Entities

    -

    Entities created by an insert request can be referenced in the request URL of subsequent requests by using the request identifier prefixed with a $ character as the first segment of the request URL.

    +

    Entities created by an insert request can be referenced in the request URL of subsequent requests by using the request identifier prefixed with a $ character as the first segment of the request URL. 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.

    If the $-prefixed request identifier is identical to the name of a top-level system resource ($batch, $crossjoin, $all, $entity, $root, $id, $metadata, or other system resources defined according to the OData-Version of the protocol specified in the request), then the reference to the top-level system resource is used. This collision can be avoided by e.g. using only numeric request identifiers.

    Services MAY also support referencing within request bodies, in which case they SHOULD advertise this support by specifying the ReferencesInRequestBodiesSupported property in the Capabilities.BatchSupport term applied to the entity container, see OData-VocCap.

    11.7.5 Referencing the ETag of an Entity

    diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md index 0e53ad2e6..98284010e 100644 --- a/docs/odata-protocol/odata-protocol.md +++ b/docs/odata-protocol/odata-protocol.md @@ -4004,7 +4004,7 @@ for the record being updated. Services SHOULD preserve the offset of `Edm.DateTimeOffset` values, if possible. However, where the underlying storage does not support offset services may be forced to normalize the value to some common time zone -(i.e. UTC) in which case the result would be returned with that time +(for example UTC) in which case the result would be returned with that time zone offset. If the service normalizes values, it MUST fail evaluation of the [query functions](#BuiltinQueryFunctions) `year`, `month`, `day`, `hour`, and `time` for literal values that are not stated in the time @@ -5667,7 +5667,9 @@ the rules for which individual requests require an identifier. Entities created by an [insert](#CreateanEntity) request can be referenced in the request URL of subsequent requests by using the request identifier prefixed with a `$` character as the first segment of -the request URL. +the request URL. If the [`Location`](#HeaderLocation) 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. If the `$`-prefixed request identifier is identical to the name of a top-level system resource (`$batch`, `$crossjoin,` `$all,` `$entity`, diff --git a/docs/odata-protocol/styles/odata.css b/docs/odata-protocol/styles/odata.css index 1c4385312..a309b83c0 100644 --- a/docs/odata-protocol/styles/odata.css +++ b/docs/odata-protocol/styles/odata.css @@ -220,6 +220,10 @@ h6 { page-break-after: avoid; } +td { + page-break-inside: avoid; +} + h2[id="22-example-data"] { page-break-before: always; } diff --git a/docs/odata-temporal-ext/odata-temporal-ext.html b/docs/odata-temporal-ext/odata-temporal-ext.html index fe5427e4c..d9960b80f 100644 --- a/docs/odata-temporal-ext/odata-temporal-ext.html +++ b/docs/odata-temporal-ext/odata-temporal-ext.html @@ -330,18 +330,819 @@

    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

    + + + + + + + + + +
    +
    +
    + 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 + + + +
    +

    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

    + + + + + + + + + +
    +
    +
    + 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 + + + +
    +

    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

    + + + + + + + + + +
    +
    +
    + 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 + + + +
    +

    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 0716934f4..3c033c901 100644 --- a/docs/odata-temporal-ext/odata-temporal-ext.md +++ b/docs/odata-temporal-ext/odata-temporal-ext.md @@ -372,7 +372,192 @@ 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
    + + + + + + + + + +
    +
    +
    + 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 + + + +
    and @@ -381,7 +566,361 @@ 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
    + + + + + + + + + +
    +
    +
    + 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 + + + +
    ## 2.2 Example Data @@ -393,7 +932,266 @@ 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
    + + + + + + + + + +
    +
    +
    + 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 + + + +
    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/docs/odata-temporal-ext/styles/odata.css b/docs/odata-temporal-ext/styles/odata.css index 1c4385312..a309b83c0 100644 --- a/docs/odata-temporal-ext/styles/odata.css +++ b/docs/odata-temporal-ext/styles/odata.css @@ -220,6 +220,10 @@ h6 { page-break-after: avoid; } +td { + page-break-inside: avoid; +} + h2[id="22-example-data"] { page-break-before: always; } diff --git a/docs/odata-url-conventions/odata-url-conventions.html b/docs/odata-url-conventions/odata-url-conventions.html index 8a7ff4356..04988f8b2 100644 --- a/docs/odata-url-conventions/odata-url-conventions.html +++ b/docs/odata-url-conventions/odata-url-conventions.html @@ -1234,7 +1234,7 @@
    5.1.1.8.2 day
    Edm.Int32 day(Edm.Date)
     Edm.Int32 day(Edm.DateTimeOffset)

    The day function returns the day component Date or DateTimeOffset parameter value, evaluated in the time zone of the DateTimeOffset parameter value. The dayMethodCallExpr syntax rule defines how the day function is invoked.

    -

    Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone (i.e. UTC) MUST fail evaluation of the day function for literal Edm.DateTimeOffset values that are not stated in the time zone of the normalized values.

    +

    Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the day function for literal Edm.DateTimeOffset values that are not stated in the time zone of the normalized values.

    Example 85: all employees born on the 8th day of a month

    http://host/service/Employees?$filter=day(BirthDate) eq 8
    @@ -1253,7 +1253,7 @@
    5.1.1.8.4 hour<
    Edm.Int32 hour(Edm.DateTimeOffset)
     Edm.Int32 hour(Edm.TimeOfDay)

    The hour function returns the hour component (0 to 23) of the DateTimeOffset or TimeOfDay parameter value, evaluated in the time zone of the DateTimeOffset parameter value. The hourMethodCallExpr syntax rule defines how the hour function is invoked.

    -

    Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone (i.e. UTC) MUST fail evaluation of the hour function for literal Edm.DateTimeOffset values that are not stated in the time zone of the normalized values.

    +

    Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the hour function for literal Edm.DateTimeOffset values that are not stated in the time zone of the normalized values.

    Example 87: all employees born in hour 4, between 04:00 (inclusive) and 05:00 (exclusive)

    http://host/service/Employees?$filter=hour(BirthDate) eq 4
    @@ -1280,7 +1280,7 @@
    5.1.1.8.8 month<
    Edm.Int32 month(Edm.Date)
     Edm.Int32 month(Edm.DateTimeOffset)

    The month function returns the month component of the Date or DateTimeOffset parameter value, evaluated in the time zone of the DateTimeOffset parameter value. The monthMethodCallExpr syntax rule defines how the month function is invoked.

    -

    Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone (i.e. UTC) MUST fail evaluation of the month function for literal Edm.DateTimeOffset values that are not stated in the time zone of the normalized values.

    +

    Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the month function for literal Edm.DateTimeOffset values that are not stated in the time zone of the normalized values.

    Example 89: all employees born in May

    http://host/service/Employees?$filter=month(BirthDate) eq 5
    @@ -1289,7 +1289,7 @@
    5.1.1.8.9 now

    The now function has the following signature:

    Edm.DateTimeOffset now()

    The now function returns the current point in time (date and time with time zone) as a DateTimeOffset value.

    -

    Services are free to choose the time zone for the current point, e.g. UTC. Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone SHOULD return a value in the normalized time zone (i.e., UTC).

    +

    Services are free to choose the time zone for the current point, for example UTC. Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone SHOULD return a value in the normalized time zone (for example UTC).

    5.1.1.8.10 second

    The second function has the following signatures:

    Edm.Int32 second(Edm.DateTimeOffset)
    @@ -1303,7 +1303,7 @@ 
    5.1.1.8.11 timeThe time function has the following signature:

    Edm.TimeOfDay time(Edm.DateTimeOffset)

    The time function returns the time part of the DateTimeOffset parameter value, evaluated in the time zone of the DateTimeOffset parameter value.

    -

    Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone (i.e. UTC) MUST fail evaluation of the time function for literal Edm.DateTimeOffset values that are not stated in the time zone of the normalized values.

    +

    Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the time function for literal Edm.DateTimeOffset values that are not stated in the time zone of the normalized values.

    5.1.1.8.12 totaloffsetminutes

    The totaloffsetminutes function has the following signature:

    Edm.Int32 totaloffsetminutes(Edm.DateTimeOffset)
    @@ -1317,7 +1317,7 @@
    5.1.1.8.14 yearEdm.Int32 year(Edm.Date) Edm.Int32 year(Edm.DateTimeOffset)

    The year function returns the year component of the Date or DateTimeOffset parameter value, evaluated in the time zone of the DateTimeOffset parameter value. The yearMethodCallExpr syntax rule defines how the year function is invoked.

    -

    Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone (i.e. UTC) MUST fail evaluation of the year function for literal Edm.DateTimeOffset values that are not stated in the time zone of the normalized values.

    +

    Services that are unable to preserve the offset of Edm.DateTimeOffset values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the year function for literal Edm.DateTimeOffset values that are not stated in the time zone of the normalized values.

    Example 91: all employees born in 1971

    http://host/service/Employees?$filter=year(BirthDate) eq 1971
    @@ -1755,7 +1755,7 @@

    $filter, $select, $orderby, $skip, $top, $count, $search, and $expand.

    Example 117: all categories and for each category all related products with a discontinued date equal to null

    diff --git a/docs/odata-url-conventions/odata-url-conventions.md b/docs/odata-url-conventions/odata-url-conventions.md index ed6c1e59b..c7d4865c2 100644 --- a/docs/odata-url-conventions/odata-url-conventions.md +++ b/docs/odata-url-conventions/odata-url-conventions.md @@ -2364,7 +2364,7 @@ parameter value. The `dayMethodCallExpr` syntax rule defines how the `day` function is invoked. Services that are unable to preserve the offset of `Edm.DateTimeOffset` -values and instead normalize the values to some common time zone (i.e. +values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the `day` function for literal `Edm.DateTimeOffset` values that are not stated in the time zone of the normalized values. @@ -2414,7 +2414,7 @@ zone of the `DateTimeOffset` parameter value. The `hourMethodCallExpr` syntax rule defines how the `hour` function is invoked. Services that are unable to preserve the offset of `Edm.DateTimeOffset` -values and instead normalize the values to some common time zone (i.e. +values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the `hour` function for literal `Edm.DateTimeOffset` values that are not stated in the time zone of the normalized values. @@ -2485,7 +2485,7 @@ The `month` function returns the month component of the `Date` or defines how the `month` function is invoked. Services that are unable to preserve the offset of `Edm.DateTimeOffset` -values and instead normalize the values to some common time zone (i.e. +values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the `month` function for literal `Edm.DateTimeOffset` values that are not stated in the time zone of the normalized values. @@ -2508,11 +2508,11 @@ Edm.DateTimeOffset now() The `now` function returns the current point in time (date and time with time zone) as a `DateTimeOffset` value. -Services are free to choose the time zone for the current point, e.g. +Services are free to choose the time zone for the current point, for example UTC. Services that are unable to preserve the offset of `Edm.DateTimeOffset` values and instead normalize the values to some common time zone SHOULD return a value in the normalized time zone -(i.e., UTC). +(for example UTC). ##### 5.1.1.8.10 `second` @@ -2550,7 +2550,7 @@ parameter value, evaluated in the time zone of the `DateTimeOffset` parameter value. Services that are unable to preserve the offset of `Edm.DateTimeOffset` -values and instead normalize the values to some common time zone (i.e. +values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the `time` function for literal `Edm.DateTimeOffset` values that are not stated in the time zone of the normalized values. @@ -2593,7 +2593,7 @@ The `year` function returns the year component of the `Date` or defines how the `year` function is invoked. Services that are unable to preserve the offset of `Edm.DateTimeOffset` -values and instead normalize the values to some common time zone (i.e. +values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the `year` function for literal `Edm.DateTimeOffset` values that are not stated in the time zone of the normalized values. @@ -3325,7 +3325,7 @@ http://host/service/Customers?$expand=Addresses/Country ``` ::: -A property MUST NOT appear in more than one expand item. +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 diff --git a/docs/odata-url-conventions/styles/odata.css b/docs/odata-url-conventions/styles/odata.css index 1c4385312..a309b83c0 100644 --- a/docs/odata-url-conventions/styles/odata.css +++ b/docs/odata-url-conventions/styles/odata.css @@ -220,6 +220,10 @@ h6 { page-break-after: avoid; } +td { + page-break-inside: avoid; +} + h2[id="22-example-data"] { page-break-before: always; } diff --git a/lib/README.md b/lib/README.md index 09c5ae282..40483f2b7 100644 --- a/lib/README.md +++ b/lib/README.md @@ -22,6 +22,7 @@ The [`number.js`](number.js) module generates a single Markdown document by prep - Generate section and example numbers - Generate a table of contents - Resolve references +- Include files like `$$$include images/drawing.svg$$$` - Replace placeholders like `$$$pagetitle$$$` with values from a [`meta.yaml`](../odata-data-aggregation-ext/meta.yaml) file - Join multiple lines that end with a single space into one line - Sections of the file between `: varXXX` and `:` or between `::: {.varXXX ...}` and `:::` belong to a variant. One source file can contain several variants. @@ -89,7 +90,11 @@ The [`pdf.js`](pdf.js) module uses a headless browser ([`puppeteer`](https://git The following scripts can be executed manually or as part of a GitHub Action: -- [`npm run build`](build.js) runs the conversion and writes the Markdown output as well as the HTML output into the [`docs/*`](../docs) folder. The Markdown file starts with a byte-order mark (`EF BB BF`) so that it is recognized as UTF-8 when loaded from github.io. +- [`npm run build`](build.js) runs the conversion and writes the following into the [`docs/*`](../docs) folder: + - the Markdown output + - the HTML output + - a copy of the common [`styles`](../styles) folder + - a copy of the document-specific `*/images` folder, if this exists. - [`npm run pdf`](build-pdf.mjs) runs the PDF conversion and writes the PDF document into the [`docs/*`](../docs) folder. - [`npm test`](../test) runs a test suite. diff --git a/lib/build.js b/lib/build.js index ca1371e42..b538990d6 100644 --- a/lib/build.js +++ b/lib/build.js @@ -10,6 +10,13 @@ iterator(function (srcname, name, variant, meta) { fs.cpSync(`${__dirname}/../styles`, `${__dirname}/../docs/${name}/styles`, { recursive: true, }); + const srcImages = `${__dirname}/../${srcname}/images`; + if (fs.existsSync(srcImages)) { + const targetImages = `${__dirname}/../docs/${name}/images`; + if (fs.existsSync(targetImages)) + fs.rmSync(targetImages, { recursive: true }); + fs.cpSync(srcImages, targetImages, { recursive: true }); + } var md = fs.createWriteStream(`${__dirname}/../docs/${name}/${name}.md`); var html = pandoc({ "--metadata-file": `${__dirname}/../${srcname}/${variant}.yaml`, diff --git a/lib/number.js b/lib/number.js index 2d8efa6fa..a1c9357dd 100644 --- a/lib/number.js +++ b/lib/number.js @@ -15,7 +15,7 @@ class Number { this.meta = meta || yaml.load( - fs.readFileSync(dir + "/" + (this.variant || "meta") + ".yaml") + fs.readFileSync(dir + "/" + (this.variant || "meta") + ".yaml"), ); } @@ -71,7 +71,7 @@ class Number { this.toc[m[1]] = { sub: [] }; if (m[1].endsWith("sec")) { m = line.match( - / ##([A-Za-z0-9.]+)(?:_[A-Za-z0-9]+)?\s+(.+)$/ + / ##([A-Za-z0-9.]+)(?:_[A-Za-z0-9]+)?\s+(.+)$/, ); m[3] = m[2].replace(/[^A-Za-z0-9]/g, ""); } @@ -112,10 +112,10 @@ class Number { } this.match++; } - }.bind(this) + }.bind(this), ) .on("close", resolve); - }.bind(this) + }.bind(this), ); } @@ -134,19 +134,28 @@ class Number { function (line) { lineno++; if (this.skip(line)) return; - var m1 = line.match(/^\$\$\$(.*?isec)\$\$\$$/); + 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) + }.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]}` + `${this.dir}/${file}(${lineno}): Undefined link #${m[1]}`, ); m = line.match(/ ##([A-Za-z0-9.]+)(_([A-Za-z0-9]+))?/); var outline = line; @@ -171,19 +180,19 @@ class Number { if (r) return `${r}](#${p})`; else { this.errors.push( - `${this.dir}/${file}(${lineno}): Undefined link ##${p}` + `${this.dir}/${file}(${lineno}): Undefined link ##${p}`, ); return `~~${p}~~]`; } - }.bind(this) - ) + }.bind(this), + ), ); if (!/\S\s$/.test(line)) out.write("\n"); } - }.bind(this) + }.bind(this), ) .on("close", resolve); - }.bind(this) + }.bind(this), ); } @@ -192,7 +201,7 @@ class Number { out.write( `${indent}- [${ s.number.startsWith("i") ? "" : s.number + " " - }${s.name.replace(/,? $/, "")}](#${s.href})\n` + }${s.name.replace(/,? $/, "")}](#${s.href})\n`, ); this.tableofcontents(s.sub, out, indent + " "); } diff --git a/lib/server.js b/lib/server.js index c9e90dcae..07961651a 100644 --- a/lib/server.js +++ b/lib/server.js @@ -10,18 +10,26 @@ const liveReloadServer = livereload.createServer({ extraExts: ["md"] }); liveReloadServer.watch(path.join(__dirname, "..")); const connectLivereload = require("connect-livereload"); +const statics = { images: {} }; -var app = express() +const app = express() + .enable("strict routing") .use(connectLivereload()) - .use("/styles", express.static(`${__dirname}/../styles`)) .get("/", function (_req, res, _next) { var docs = []; iterator(function (srcname, name, variant) { - docs.push(`
  • ${name}
  • `); + docs.push( + `
  • ${name}
  • `, + ); }); res.send(`

    Documents

      ${docs.join("")}
    `); }) - .get("/:doc", function (req, res, next) { + .get("/:doc", function (req, res, _next) { + var url = new URL("s://" + req.originalUrl); + url.pathname += "/"; + res.redirect(url.href.substring(4)); + }) + .get("/:doc/", function (req, res, next) { try { var branch = execSync("git branch --show-current", { cwd: __dirname, @@ -31,7 +39,7 @@ var app = express() try { var number = new Number( __dirname + "/../" + req.params.doc, - req.query.variant + req.query.variant, ); var meta = `${__dirname}/../${req.params.doc}/${ req.query.variant || "meta" @@ -50,6 +58,12 @@ var app = express() } catch (err) { next(); } + }) + .use("/:doc/styles", express.static(`${__dirname}/../styles`)) + .use("/:doc/images", function (req, res, next) { + (statics.images[req.params.doc] ||= express.static( + `${__dirname}/../${req.params.doc}/images`, + ))(req, res, next); }); if (module.parent) module.exports = app; diff --git a/odata-csdl/14 Vocabulary and Annotation.md b/odata-csdl/14 Vocabulary and Annotation.md index 24a586a36..8933056ed 100644 --- a/odata-csdl/14 Vocabulary and Annotation.md +++ b/odata-csdl/14 Vocabulary and Annotation.md @@ -528,120 +528,118 @@ element. This external targeting is only possible for model elements that are uniquely identified within their parent, and all their ancestor elements -are uniquely identified within their parent: - -- [Action](#Action) (single or all overloads) -- [Action Import](#ActionImport) -- [Complex Type](#ComplexType) -- [Entity Container](#EntityContainer) -- [Entity Set](#EntitySet) -- [Entity Type](#EntityType) -- [Enumeration Type](#EnumerationType) -- [Enumeration Type Member](#EnumerationTypeMember) -- [Function](#Function) (single or all overloads) -- [Function Import](#FunctionImport) -- [Navigation Property](#NavigationProperty) (via type, entity set, or - singleton) -- [Parameter](#Parameter) of an action or function (single overloads - or all overloads defining the - parameter) -- [Property](#StructuralProperty) (via type, entity set, or singleton) -- [Return Type](#ReturnType) of an action or function (single or all - overloads) -- [Singleton](#Singleton) -- [Type Definition](#TypeDefinition) +are uniquely identified within their parent. These are the direct children of a schema with a unique name (i.e. except actions and functions whose overloads to not possess a natural identifier), and all direct children of an entity container. -External targeting is possible for actions, functions, their parameters, -and their return type, either in a way that applies to all overloads of -the action or function or all parameters of that name across all -overloads, or in a way that identifies a single overload. - -External targeting is also possible for properties and navigation +Model element| +Can be targeted with path expression (see also [section ##PathSyntax])| +

    Example ##ex: Target expressions

    +-----|-----|----- +[Action](#Action) overload| +qualified name of action followed by parentheses containing the binding parameter type of a bound action overload to identify that bound overload, or by empty parentheses to identify the unbound overload| +
    `MySchema.MyAction(MySchema.MyBindingType)` 
    +
    `MySchema.MyAction(Collection(MySchema.BindingType))` +
    `MySchema.MyAction()`
    +all overloads of an [Action](#Action)| +qualified name of action| +
    `MySchema.MyAction`
    +[Action Import](#ActionImport)| +qualified name of entity container followed by a segment containing the action import name| +
    `MySchema.MyEntityContainer/MyActionImport`
    +[Annotation](#Annotation) on a model element| +path expression identifying the model element followed by a segment containing an at (`@`) prepended to the qualified name of a term, optionally suffixed with a hash (`#`) and the qualifier of an annotation| +
    `MySchema.MyEntityType/@MyVocabulary.MyTerm` 
    +
    `MySchema.MyEntityType/@MyVocabulary.MyTerm#MyQualifier`
    +[Complex Type](#ComplexType)| +qualified name of complex type| +
    `MySchema.MyComplexType`
    +[Entity Container](#EntityContainer)| +qualified name of entity container| +
    `MySchema.MyEntityContainer`
    +[Entity Set](#EntitySet)| +qualified name of entity container followed by a segment containing the entity set name| +
    `MySchema.MyEntityContainer/MyEntitySet`
    +[Entity Type](#EntityType)| +qualified name of entity type| +
    `MySchema.MyEntityType`
    +[Enumeration Type](#EnumerationType)| +qualified name of enumeration type| +
    `MySchema.MyEnumType`
    +[Enumeration Type Member](#EnumerationTypeMember)| +qualified name of enumeration type followed by a segment containing the name of a child element| +
    `MySchema.MyEnumType/MyMember`
    +[Function](#Function) overload| +qualified name of function followed by parentheses containing the comma-separated list of the parameter types of a bound or unbound function overload in the order of their definition in the function overload| +
    `MySchema.MyFunction(MySchema.MyBindingParamType,` 
    +
    ` First.NonBinding.ParamType)` +
    `MySchema.MyFunction(First.NonBinding.ParamType,` +
    ` Second.NonBinding.ParamType)`
    +all overloads of a [Function](#Function)| +qualified name of function| +
    `MySchema.MyFunction`
    +[Function Import](#FunctionImport)| +qualified name of entity container followed by a segment containing the function import name| +
    `MySchema.MyEntityContainer/MyFunctionImport`
    +[Navigation Property](#NavigationProperty) via container| 
    +qualified name of entity container followed by a segment containing a singleton or entity set name and zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast| 
    +
    `MySchema.MyEntityContainer/MyEntitySet` 
    +
    ` /MyNavigationProperty` +
    `MySchema.MyEntityContainer/MyEntitySet` +
    ` /MySchema.MyEntityType/MyNavProperty` +
    `MySchema.MyEntityContainer/MyEntitySet` +
    ` /MyComplexProperty/MyNavProperty` +
    `MySchema.MyEntityContainer/MySingleton` +
    ` /MyComplexProperty/MyNavProperty`
    +[Navigation Property](#NavigationProperty) via structured type| +qualified name of structured type followed by zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast| +
    `MySchema.MyEntityType/MyNavigationProperty` 
    +
    `MySchema.MyComplexType/MyNavigationProperty`
    +[Parameter](#Parameter)| +qualified name of entity container followed by a segment containing an action or function import name followed by a segment containing a parameter name| +
    `MySchema.MyEntityContainer/MyFunctionImport/MyParameter`
    +[Parameter](#Parameter)| +qualified name of action or function optionally followed by a parenthesized expression as in the first row followed by a segment containing the name of a child element| +
    `MySchema.MyFunction/MyParameter`
    +[Property](#StructuralProperty) via container| +qualified name of entity container followed by a segment containing a singleton or entity set name and zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast| +
    `MySchema.MyEntityContainer/MyEntitySet` 
    +
    ` /MyProperty` +
    `MySchema.MyEntityContainer/MyEntitySet` +
    ` /MySchema.MyEntityType/MyProperty` +
    `MySchema.MyEntityContainer/MyEntitySet` +
    ` /MyComplexProperty/MyProperty`
    +[Property](#StructuralProperty) via structured type| +qualified name of structured type followed by zero or more segments containing the name of a structural or navigation property, or a type-cast or term-cast| +
    `MySchema.MyEntityType/MyProperty` 
    +
    `MySchema.MyComplexType/MyProperty`
    +[Return Type](#ReturnType)| +qualified name of entity container followed by a segment containing an action or function import name followed by a segment containing `$ReturnType`| +
    `MySchema.MyEntityContainer/MyFunctionImport/$ReturnType`
    +[Return Type](#ReturnType)| +qualified name of action or function optionally followed by a parenthesized expression as in the first row followed by a segment containing `$ReturnType`| +
    `MySchema.MyFunction/$ReturnType` 
    +
    `MySchema.MyFunction(MySchema.MyBindingParamType,` +
    ` First.NonBinding.ParamType)/$ReturnType`
    +[Singleton](#Singleton)| +qualified name of entity container followed by a segment containing a singleton name| +
    `MySchema.MyEntityContainer/MySingleton`
    +[Term](#Term)| +qualified name of term| +
    `MySchema.MyTerm`
    +[Type Definition](#TypeDefinition)| +qualified name of type definition| +
    `MySchema.MyTypeDefinition`
    + +All [qualified names](#QualifiedName) used in a target path MUST be in scope. + +External targeting is possible for properties and navigation properties of singletons or entities in a particular entity set. These annotations override annotations on the properties or navigation properties targeted via the declaring structured type. -The allowed path expressions are: -- [qualified name](#QualifiedName) -of schema child -- [qualified -name](#QualifiedName) of schema child followed by a forward slash and -name of child element -- [qualified -name](#QualifiedName) of structured type followed by zero or more -property, navigation property, or type-cast segments, each segment -starting with a forward slash -- [qualified name](#QualifiedName) -of an entity container followed by a segment containing a singleton or -entity set name and zero or more property, navigation property, or -type-cast segments -- [qualified -name](#QualifiedName) of an action followed by parentheses containing -the [qualified name](#QualifiedName) of the binding parameter *type* of -a bound action overload to identify that bound overload, or by empty -parentheses to identify the unbound overload -- [qualified name](#QualifiedName) of a -function followed by parentheses containing the comma-separated list of -[qualified names](#QualifiedName) of the parameter *types* of a bound -or unbound function overload in the order of their definition in the -function overload -- [qualified -name](#QualifiedName) of an action or function, optionally followed by -parentheses as described in the two previous bullet points to identify a -single overload, followed by a forward slash and either a parameter name -or `$ReturnType` -- [qualified -name](#QualifiedName) of an entity container followed by a segment -containing an action or function import name, optionally followed by a -forward slash and either a parameter name or `$ReturnType` - -- One of the preceding, followed by a forward slash, an at (`@`), the - [qualified name](#QualifiedName) of a term, and optionally a hash - (`#`) and the qualifier of an - annotation - -All [qualified names](#QualifiedName) used in a target path MUST be in -scope. - -::: example -Example ##ex: Target expressions -``` -MySchema.MyEntityType -MySchema.MyEntityType/MyProperty -MySchema.MyEntityType/MyNavigationProperty -MySchema.MyComplexType -MySchema.MyComplexType/MyProperty -MySchema.MyComplexType/MyNavigationProperty -MySchema.MyEnumType -MySchema.MyEnumType/MyMember -MySchema.MyTypeDefinition -MySchema.MyTerm -MySchema.MyEntityContainer -MySchema.MyEntityContainer/MyEntitySet -MySchema.MyEntityContainer/MySingleton -MySchema.MyEntityContainer/MyActionImport -MySchema.MyEntityContainer/MyFunctionImport -MySchema.MyAction -MySchema.MyAction(MySchema.MyBindingType) -MySchema.MyAction() -MySchema.MyFunction -MySchema.MyFunction(MySchema.MyBindingParamType,First.NonBinding.ParamType) -MySchema.MyFunction(First.NonBinding.ParamType,Second.NonBinding.ParamType) -MySchema.MyFunction/MyParameter -MySchema.MyEntityContainer/MyEntitySet/MyProperty -MySchema.MyEntityContainer/MyEntitySet/MyNavigationProperty -MySchema.MyEntityContainer/MyEntitySet/MySchema.MyEntityType/MyProperty -MySchema.MyEntityContainer/MyEntitySet/MySchema.MyEntityType/MyNavProperty -MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyProperty -MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyNavigationProperty -MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyNavigationProperty -``` -::: - ## ##subsec Constant Expression Constant expressions allow assigning a constant value to an applied diff --git a/odata-json-format/19 Batch Requests and Responses.md b/odata-json-format/19 Batch Requests and Responses.md index 09647fd48..00944e295 100644 --- a/odata-json-format/19 Batch Requests and Responses.md +++ b/odata-json-format/19 Batch Requests and Responses.md @@ -180,7 +180,9 @@ Content-Length: ### ## ##subsec Referencing New Entities The entity returned by a preceding request can be referenced in the -request URL of subsequent requests. +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 diff --git a/odata-json-format/4 Common Characteristics.md b/odata-json-format/4 Common Characteristics.md index 5003d7f23..366a04275 100644 --- a/odata-json-format/4 Common Characteristics.md +++ b/odata-json-format/4 Common Characteristics.md @@ -294,6 +294,8 @@ following is true: - The type is for a property whose type is not declared in `$metadata`. +It MAY appear in other cases in requests and responses if its value does not contradict the type declared in `$metadata`. + The following heuristics are used to determine the primitive type of a dynamic property in the absence of the `type` control information: diff --git a/odata-protocol/11.4 Data Modification.md b/odata-protocol/11.4 Data Modification.md index c08b936db..76ec0c6c5 100644 --- a/odata-protocol/11.4 Data Modification.md +++ b/odata-protocol/11.4 Data Modification.md @@ -75,7 +75,7 @@ for the record being updated. Services SHOULD preserve the offset of `Edm.DateTimeOffset` values, if possible. However, where the underlying storage does not support offset services may be forced to normalize the value to some common time zone -(i.e. UTC) in which case the result would be returned with that time +(for example UTC) in which case the result would be returned with that time zone offset. If the service normalizes values, it MUST fail evaluation of the [query functions](#BuiltinQueryFunctions) `year`, `month`, `day`, `hour`, and `time` for literal values that are not stated in the time diff --git a/odata-protocol/11.7 Batch Requests.md b/odata-protocol/11.7 Batch Requests.md index 6e4e0abb7..6ceb42e4b 100644 --- a/odata-protocol/11.7 Batch Requests.md +++ b/odata-protocol/11.7 Batch Requests.md @@ -105,7 +105,9 @@ the rules for which individual requests require an identifier. Entities created by an [insert](#CreateanEntity) request can be referenced in the request URL of subsequent requests by using the request identifier prefixed with a `$` character as the first segment of -the request URL. +the request URL. If the [`Location`](#HeaderLocation) 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. If the `$`-prefixed request identifier is identical to the name of a top-level system resource (`$batch`, `$crossjoin,` `$all,` `$entity`, diff --git a/odata-temporal-ext/2 Overview.md b/odata-temporal-ext/2 Overview.md index 3a4853bde..160f42f93 100644 --- a/odata-temporal-ext/2 Overview.md +++ b/odata-temporal-ext/2 Overview.md @@ -58,7 +58,7 @@ Example ##ex_api1: 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 @@ -67,7 +67,7 @@ Example ##ex_api2: 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$$$ ## ##subsec Example Data @@ -79,7 +79,7 @@ Example ##ex: 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/odata-temporal-ext/diagrams/README.md b/odata-temporal-ext/diagrams/README.md deleted file mode 100644 index f3feb3edf..000000000 --- a/odata-temporal-ext/diagrams/README.md +++ /dev/null @@ -1,4 +0,0 @@ -Diagrams in the [Draw.io](https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio) `example-model.drawio` file are exported as `*.svg` and then embedded into the `.md` files without changes. - -Note: star `*` characters in a diagram description needs to be escaped as `\*` to avoid -interpretation as markdown. diff --git a/odata-temporal-ext/diagrams/api-1.drawio.svg b/odata-temporal-ext/diagrams/api-1.drawio.svg new file mode 100644 index 000000000..d0414882c --- /dev/null +++ b/odata-temporal-ext/diagrams/api-1.drawio.svg @@ -0,0 +1,186 @@ + + + + + + + + + +
    +
    +
    + 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 + + + +
    diff --git a/odata-temporal-ext/diagrams/api-1.svg b/odata-temporal-ext/diagrams/api-1.svg deleted file mode 100644 index b17470763..000000000 --- a/odata-temporal-ext/diagrams/api-1.svg +++ /dev/null @@ -1 +0,0 @@ -
    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
    \ No newline at end of file diff --git a/odata-temporal-ext/diagrams/api-2.drawio.svg b/odata-temporal-ext/diagrams/api-2.drawio.svg new file mode 100644 index 000000000..b4cfe12b8 --- /dev/null +++ b/odata-temporal-ext/diagrams/api-2.drawio.svg @@ -0,0 +1,355 @@ + + + + + + + + + +
    +
    +
    + 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 + + + +
    diff --git a/odata-temporal-ext/diagrams/api-2.svg b/odata-temporal-ext/diagrams/api-2.svg deleted file mode 100644 index f832e2925..000000000 --- a/odata-temporal-ext/diagrams/api-2.svg +++ /dev/null @@ -1 +0,0 @@ -
    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
    \ No newline at end of file diff --git a/odata-temporal-ext/diagrams/db.drawio.svg b/odata-temporal-ext/diagrams/db.drawio.svg new file mode 100644 index 000000000..e1fa16baf --- /dev/null +++ b/odata-temporal-ext/diagrams/db.drawio.svg @@ -0,0 +1,260 @@ + + + + + + + + + +
    +
    +
    + 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 + + + +
    diff --git a/odata-temporal-ext/diagrams/db.svg b/odata-temporal-ext/diagrams/db.svg deleted file mode 100644 index 0cc58df72..000000000 --- a/odata-temporal-ext/diagrams/db.svg +++ /dev/null @@ -1 +0,0 @@ -
    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
    \ No newline at end of file diff --git a/odata-temporal-ext/diagrams/example-model.drawio b/odata-temporal-ext/diagrams/example-model.drawio deleted file mode 100644 index 3e804637c..000000000 --- a/odata-temporal-ext/diagrams/example-model.drawio +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/odata-url-conventions/5 Query Options.md b/odata-url-conventions/5 Query Options.md index c00da2198..72830adc7 100644 --- a/odata-url-conventions/5 Query Options.md +++ b/odata-url-conventions/5 Query Options.md @@ -970,7 +970,7 @@ parameter value. The `dayMethodCallExpr` syntax rule defines how the `day` function is invoked. Services that are unable to preserve the offset of `Edm.DateTimeOffset` -values and instead normalize the values to some common time zone (i.e. +values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the `day` function for literal `Edm.DateTimeOffset` values that are not stated in the time zone of the normalized values. @@ -1020,7 +1020,7 @@ zone of the `DateTimeOffset` parameter value. The `hourMethodCallExpr` syntax rule defines how the `hour` function is invoked. Services that are unable to preserve the offset of `Edm.DateTimeOffset` -values and instead normalize the values to some common time zone (i.e. +values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the `hour` function for literal `Edm.DateTimeOffset` values that are not stated in the time zone of the normalized values. @@ -1091,7 +1091,7 @@ The `month` function returns the month component of the `Date` or defines how the `month` function is invoked. Services that are unable to preserve the offset of `Edm.DateTimeOffset` -values and instead normalize the values to some common time zone (i.e. +values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the `month` function for literal `Edm.DateTimeOffset` values that are not stated in the time zone of the normalized values. @@ -1114,11 +1114,11 @@ Edm.DateTimeOffset now() The `now` function returns the current point in time (date and time with time zone) as a `DateTimeOffset` value. -Services are free to choose the time zone for the current point, e.g. +Services are free to choose the time zone for the current point, for example UTC. Services that are unable to preserve the offset of `Edm.DateTimeOffset` values and instead normalize the values to some common time zone SHOULD return a value in the normalized time zone -(i.e., UTC). +(for example UTC). ##### ##subsubsubsubsec `second` @@ -1156,7 +1156,7 @@ parameter value, evaluated in the time zone of the `DateTimeOffset` parameter value. Services that are unable to preserve the offset of `Edm.DateTimeOffset` -values and instead normalize the values to some common time zone (i.e. +values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the `time` function for literal `Edm.DateTimeOffset` values that are not stated in the time zone of the normalized values. @@ -1199,7 +1199,7 @@ The `year` function returns the year component of the `Date` or defines how the `year` function is invoked. Services that are unable to preserve the offset of `Edm.DateTimeOffset` -values and instead normalize the values to some common time zone (i.e. +values and instead normalize the values to some common time zone (for example UTC) MUST fail evaluation of the `year` function for literal `Edm.DateTimeOffset` values that are not stated in the time zone of the normalized values. @@ -1931,7 +1931,7 @@ http://host/service/Customers?$expand=Addresses/Country ``` ::: -A property MUST NOT appear in more than one expand item. +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 diff --git a/styles/odata.css b/styles/odata.css index 1c4385312..a309b83c0 100644 --- a/styles/odata.css +++ b/styles/odata.css @@ -220,6 +220,10 @@ h6 { page-break-after: avoid; } +td { + page-break-inside: avoid; +} + h2[id="22-example-data"] { page-break-before: always; }