diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html index bae8b6b8..4dbc9382 100644 --- a/docs/odata-protocol/odata-protocol.html +++ b/docs/odata-protocol/odata-protocol.html @@ -2270,15 +2270,21 @@

1

If the target URL terminates in a type cast segment, then the segment MUST specify the type of, or a type derived from, the type of the collection, and the entity MUST be created as that specified type.

To create an open entity (an instance of an open type), additional property values beyond those specified in the metadata MAY be sent in the request body. The service MUST treat these as dynamic properties and add them to the created instance.

If the entity being created is not an open entity, additional property values beyond those specified in the metadata SHOULD NOT be sent in the request body. The service MUST fail if unable to persist all property values specified in the request.

-

Non-insertable properties SHOULD be omitted from the request body. If they are provided, services MUST either ignore the values in the request body or fail the request if the provided values do not match the service-determined values.

+

If non-insertable properties are included in the request body, services MUST either ignore them or fail the request if the provided values do not match the service-determined values.

Non-insertable properties include (and are not limited to)

-

Services MUST return an error if the request body contains a value for a property that in principle can be specified on insert but the request cannot currently be executed respecting the specified value, for example, due to permissions or state of the object. Properties with a default value, nullable properties, and collection-valued properties omitted from the request are set to the default value, null, or an empty collection, respectively.

+

Properties tagged with Core.Computed MAY additionally be tagged with the term Core.PostCondition, see OData-VocCore, if the service does not ignore them. Based on this tag (or based on out-of-band knowledge about the service behavior) clients can provide these properties in an insert request and benefit from the certainty that, if the request succeeds, their service-determined values match the provided values. Providing such properties effectively imposes “post-conditions” that must be met for the request to succeed.

+

Otherwise, clients SHOULD omit non-insertable properties from the request body.

+
+

Example 76: The entity SalesOrder has a property ExportRegulationsState which is tagged with Core.Computed and Core.PostCondition and which the service determines based on the product and destination country. Clients can specify it with value Allowed to impose a “post-condition” that a sales order is created only if it meets export regulations.

+
+

Services MUST return an error if the request body contains a value for a property that in principle can be specified on insert but the request cannot currently be executed respecting the specified value, for example, due to permissions or state of the object.

+

Properties with a default value, nullable properties, and collection-valued properties omitted from the request are set to the default value, null, or an empty collection, respectively.

Services MAY add dynamic properties to the created entity as long as their names do not conflict with the names of declared properties and client-specified dynamic properties.

Upon successful creation of the entity, the service MUST respond with either 201 Created and a representation of the created entity, or 204 No Content if the request included a return=minimal preference and did not include the system query options $select and $expand, or if a representation of the created entity could not be constructed. In either case, if the service is able to construct the edit URL or read URL of the created entity, the response MUST contain that URL in a Location header.

@@ -2287,7 +2293,7 @@
@@ -2749,7 +2755,7 @@

-

Example 90: invoke the MostRecentOrder function on each entity in the entity set Customers

+

Example 91: invoke the MostRecentOrder function on each entity in the entity set Customers

GET http://host/service/Customers/$each/SampleModel.MostRecentOrder()

The client MAY specify the continue-on-error preference, in which case the service MAY continue processing actions after a failure. In this case, the service MUST, regardless of the return preference, return a response containing at least the members identified by the request for which the action failed. Such members MUST be annotated with the term Core.DataModificationException with a failedOperation value of invoke.

@@ -2760,7 +2766,7 @@

format.

-

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

+

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

{
   "@context": ,
   "CustomerID": "ALFKI",
@@ -2775,7 +2781,7 @@ 

OData-URL.

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

-

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

+

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

{
   "@context": ,
   "CustomerID": "ALFKI",
@@ -2800,7 +2806,7 @@ 

inline parameter syntax. The canonical URL for a function import is the service root, followed by the name of the function import. Services MAY support omitting the parentheses when invoking a function import with no parameters, but for maximum interoperability MUST also support invoking the function import with empty parentheses.

If the function is composable, additional path segments may be appended to the URL that identifies the composable function (or function import) as appropriate for the type returned by the function (or function import). The last path segment determines the system query options and HTTP verbs that can be used with this this URL, e.g. if the last path segment is a multi-valued navigation property, a POST request may be used to create a new entity in the identified collection.

-

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

+

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

POST http://host/service/MyShoppingCart()/Items
 
 …
@@ -2817,22 +2823,22 @@
-

Example 94: invoke a Sales.EmployeesByManager function which takes a single ManagerID parameter via the function import EmployeesByManager

+

Example 95: invoke a Sales.EmployeesByManager function which takes a single ManagerID parameter via the function import EmployeesByManager

GET http://host/service/EmployeesByManager(ManagerID=3)
-

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

+

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

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

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

-

Example 96: invoke a Sales.EmployeesByManager function via the function import EmployeesByManager, passing 3 for the ManagerID parameter

+

Example 97: invoke a Sales.EmployeesByManager function via the function import EmployeesByManager, passing 3 for the ManagerID parameter

GET http://host/service/EmployeesByManager(ManagerID=@p1)?@p1=3

Services MAY in addition allow implicit parameter aliases for function imports and for functions that are the last path segment of the URL. An implicit parameter alias is the parameter name, optionally preceded by an at (@) sign. When using implicit parameter aliases, parentheses MUST NOT be appended to the function (import) name. The value for each parameter MUST be specified as a separate query option with the name of the parameter alias. If a parameter name is identical to a system query option name (without the optional $ prefix), the parameter name MUST be prefixed with an at (@) sign.

-

Example 97: invoke a Sales.EmployeesByManager function via the function import EmployeesByManager, passing 3 for the ManagerID parameter using the implicit parameter alias

+

Example 98: invoke a Sales.EmployeesByManager function via the function import EmployeesByManager, passing 3 for the ManagerID parameter using the implicit parameter alias

GET http://host/service/EmployeesByManager?ManagerID=3

Non-binding parameters annotated with the term Core.OptionalParameter defined in OData-VocCore MAY be omitted. If it is annotated and the annotation specifies a DefaultValue, the omitted parameter is interpreted as having that default value. If omitted and the annotation does not specify a default value, the service is free on how to interpret the omitted parameter.

@@ -2872,7 +2878,7 @@

204 No Content on success.

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

-

Example 98: invoke the SampleEntities.CreateOrder action using Customers('ALFKI') as the customer (or binding parameter). The values 2 for the quantity parameter and BLACKFRIDAY for the discountCode parameter are passed in the body of the request. Invoke the action only if the customer’s ETag still matches.

+

Example 99: invoke the SampleEntities.CreateOrder action using Customers('ALFKI') as the customer (or binding parameter). The values 2 for the quantity parameter and BLACKFRIDAY for the discountCode parameter are passed in the body of the request. Invoke the action only if the customer’s ETag still matches.

POST http://host/service/Customers('ALFKI')/SampleEntities.CreateOrder
 If-Match: W/"MjAxOS0wMy0yMVQxMzowNVo="
 Content-Type: application/json
@@ -2923,7 +2929,7 @@ 

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

-

Example 99: multipart batch request

+

Example 100: multipart batch request

POST /service/$batch HTTP/1.1
 Host: odata.org
 OData-Version: 4.0
@@ -2933,7 +2939,7 @@ 

-

Example 100: JSON batch request

+

Example 101: JSON batch request

POST /service/$batch HTTP/1.1
 Host: odata.org
 OData-Version: 4.01
@@ -2960,7 +2966,7 @@ 

11.7.4 Referencing Returned Entities

-

Entities created by an insert request or an action 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. Services MUST treat this segment like the URL in the Location header of the response to the request identified by the segment. If the Location header in the response to the subsequent request contains a relative URL, clients MUST be able to resolve it relative to the request’s URL even if that contains such a reference. See example 105.

+

Entities created by an insert request or an action 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. Services MUST treat this segment like the URL in the Location header of the response to the request identified by the segment. If the Location header in the response to the subsequent request contains a relative URL, clients MUST be able to resolve it relative to the request’s URL even if that contains such a reference. See example 106.

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.

@@ -2994,14 +3000,14 @@

Absolute URI with schema, host, port, and absolute resource path.
-

Example 101:

+

Example 102:

GET https://host:1234/path/service/People(1) HTTP/1.1
  • Absolute resource path and separate Host header
-

Example 102:

+

Example 103:

PATCH /path/service/People(1) HTTP/1.1
 Host: myserver.mydomain.org:1234
 Content-Type: application/json
@@ -3012,7 +3018,7 @@ 

Resource path relative to the batch request URI.
-

Example 103:

+

Example 104:

DELETE People(1) HTTP/1.1

Services MUST support all three formats for URLs of individual requests.

@@ -3024,7 +3030,7 @@

Processors of batch requests MAY choose to disallow additional HTTP constructs in HTTP requests serialized within body parts. For example, a processor may choose to disallow chunked encoding to be used by such HTTP requests.

-

Example 104: a batch request that contains the following individual requests in the order listed

+

Example 105: a batch request that contains the following individual requests in the order listed

  1. A query request
  2. A change set that contains the following requests: @@ -3090,7 +3096,7 @@

    insert request or an action can be referenced in the request URL of subsequent requests within the same change set. Services MAY also support referencing across change sets, in which case they SHOULD advertise this support by specifying the ReferencesAcrossChangeSetsSupported property in the Capabilities.BatchSupport term applied to the entity container, see OData-VocCap.

    -

    Example 105: a batch request that contains the following operations in the order listed:

    +

    Example 106: a batch request that contains the following operations in the order listed:

    A change set that contains the following requests:

    • Insert a new entity (with Content-ID = 1)
    • @@ -3150,14 +3156,14 @@

      example 102). This gives the effective second request URL http://host/service/Customers('ALFKI')/Orders as base URI for the second Location URL, which therefore resolves to http://host/service/Customers('ALFKI')/Orders(1).

      +

      The second Location URL Orders(1) is relative with its base URI being the second request URL $1/Orders. To get an absolute base URI, the client must replace the $1 with the first Location URL Customers('ALFKI') and resolve the resulting URL Customers('ALFKI')/Orders(1) relative to its base URI, which is http://host/service/Customers (determined from the first request URL /service/Customers and the Host: host header as in example 103). This gives the effective second request URL http://host/service/Customers('ALFKI')/Orders as base URI for the second Location URL, which therefore resolves to http://host/service/Customers('ALFKI')/Orders(1).

    11.7.7.3 Referencing an ETag

    -

    Example 106: a batch request that contains the following operations in the order listed:

    +

    Example 107: a batch request that contains the following operations in the order listed:

    • Get an employee (with Content-ID = 1)
    • Update the salary only if the employee has not changed
    • @@ -3197,7 +3203,7 @@

      11.7.7.4 Referencing Response Body Values

      -

      Example 107: a batch request that contains the following operations in the order listed:

      +

      Example 108: a batch request that contains the following operations in the order listed:

      • Get an employee (with Content-ID = 1)
      • Get all employees residing in the same building
      • @@ -3246,9 +3252,9 @@

        Asynchronously processed batch requests can return interim results and end with a 202 Accepted as the last part of the multipart response. Therefore, the respond-async preference MUST NOT be applied to individual requests within a batch if the batch response is a multipart response.

      The body of a multipart response to a JSON batch request contains one body part for each processed or accepted request. The order of the body parts is insignificant as each body part MUST contain the Content-ID header with the value of the id name/value pair of the corresponding request object.

      -

      A response to an operation in a batch MUST be formatted exactly as it would have appeared outside of a batch as described in the corresponding subsections of chapter Data Service Requests. Relative URLs in each individual response are relative to the request URL of the corresponding individual request (see example 105). URLs in responses MUST NOT contain $-prefixed request identifiers.

      +

      A response to an operation in a batch MUST be formatted exactly as it would have appeared outside of a batch as described in the corresponding subsections of chapter Data Service Requests. Relative URLs in each individual response are relative to the request URL of the corresponding individual request (see example 106). URLs in responses MUST NOT contain $-prefixed request identifiers.

      -

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

      +

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

      HTTP/1.1 200 OK
       OData-Version: 4.0
       Content-Length: ####
      @@ -3302,7 +3308,7 @@ 

      A service MAY return interim results to an asynchronously executing batch. It does this by responding with 200 OK to a GET request to the monitor resource and including a 202 Accepted response as the last part of the multipart response. The client can use the monitor URL returned in this 202 Accepted response to continue processing the batch response.

      Since a change set is executed atomically, 202 Accepted MUST NOT be returned within a change set.

      -

      Example 109: referencing the example 104 above again, assume that

      +

      Example 110: referencing the example 105 above again, assume that

      HTTP/1.1 202 Accepted
       Location: http://service-root/async-monitor-0
       Retry-After: ###
      diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md
      index 8ac825c9..0adfc8ac 100644
      --- a/docs/odata-protocol/odata-protocol.md
      +++ b/docs/odata-protocol/odata-protocol.md
      @@ -4180,20 +4180,40 @@ values beyond those specified in the metadata SHOULD NOT be sent in the
       request body. The service MUST fail if unable to persist all property
       values specified in the request.
       
      -Non-insertable properties SHOULD be omitted from the request body.
      -If they are provided, services MUST either ignore the values in the request body or fail the request
      +If non-insertable properties are included in the request body,
      +services MUST either ignore them or fail the request
       if the provided values do not match the service-determined values.
       
       Non-insertable properties include (and are not limited to)
       
       - dependent properties that are tied to non-key properties of the principal entity through a referential constraint [OData-CSDL, section 8.5](#ODataCSDL) (informally: "denormalized" properties),
      -- properties annotated with the term
      +- properties tagged with the term
         [`Core.Computed`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#Computed), see [OData-VocCore](#ODataVocCore),
       - properties listed as `NonInsertableProperties` of term [`Capabilities.InsertRestrictions`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Capabilities.V1.md#InsertRestrictions), see [OData-VocCap](#ODataVocCap),
       - properties annotated with term
         [`Core.Permissions`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#Permissions), see [OData-VocCore](#ODataVocCore), where the annotation value does not have the `Write` flag.
       
      +Properties tagged with `Core.Computed` MAY additionally be tagged with the term
      +[`Core.PostCondition`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#PostCondition),
      +see [OData-VocCore](#ODataVocCore), if the service does not ignore them.
      +Based on this tag (or based on out-of-band knowledge about the service behavior)
      +clients can provide these properties in an insert request
      +and benefit from the certainty that, if the request succeeds, their service-determined values match
      +the provided values. Providing such properties effectively imposes "post-conditions"
      +that must be met for the request to succeed.
      +
      +Otherwise, clients SHOULD omit non-insertable properties from the request body.
      +
      +::: example
      +Example 76: The entity `SalesOrder` has a property `ExportRegulationsState`
      +which is tagged with `Core.Computed` and `Core.PostCondition` and which
      +the service determines based on the product and destination country.
      +Clients can specify it with value `Allowed` to impose a "post-condition" that a sales order is created
      +only if it meets export regulations.
      +:::
      +
       Services MUST return an error if the request body contains a value for a property that in principle can be specified on insert but the request cannot currently be executed respecting the specified value, for example, due to permissions or state of the object.
      +
       Properties with a default value, nullable properties, and
       collection-valued properties omitted from the request are set to the
       default value, null, or an empty collection, respectively.
      @@ -4220,7 +4240,7 @@ request body.
       The representation for referencing related entities is format-specific.
       
       ::: example
      -Example 76: using the JSON format, 4.0 clients can create a new manager
      +Example 77: using the JSON format, 4.0 clients can create a new manager
       entity with links to an existing manager (of managers) and to two existing employees by applying the `odata.bind`
       annotation to the `Manager` and `DirectReports` navigation properties
       
      @@ -4241,7 +4261,7 @@ annotation to the `Manager` and `DirectReports` navigation properties
       :::
       
       ::: example
      -Example 77: using the JSON format, 4.01 clients can create a new manager
      +Example 78: using the JSON format, 4.01 clients can create a new manager
       entity with links to an existing manager (of managers) and to two existing employees by including the entity-ids
       within the `Manager` and `DirectReports` navigation properties
       
      @@ -4378,7 +4398,7 @@ Non-updatable properties include (and are not limited to)
       
       - key properties,
       - dependent properties that are tied to non-key properties of the principal entity through a referential constraint [OData-CSDL, section 8.5](#ODataCSDL) (informally: "denormalized" properties),
      -- properties annotated with the terms
      +- properties tagged with the terms
         [`Core.Computed`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#Computed) or [`Core.Immutable`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#Immutable), see [OData-VocCore](#ODataVocCore),
       - properties listed as `NonUpdatableProperties` of term [`Capabilities.UpdateRestrictions`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Capabilities.V1.md#UpdateRestrictions), see [OData-VocCap](#ODataVocCap),
       - properties annotated with term
      @@ -4387,7 +4407,9 @@ Non-updatable properties include (and are not limited to)
       Services MUST return an error if the request body contains a value for a
       property that in principle can be specified on update but the request cannot currently be executed respecting the specified value, for example, due to permissions or state of the object.
       
      -Clients SHOULD use `PATCH` and specify only those properties intended to be changed.
      +Clients can provide non-updatable properties to impose "post-conditions" as explained
      +for [non-insertable properties](#CreateanEntity). Otherwise,
      +clients SHOULD use `PATCH` and specify only those properties intended to be changed.
       
       The entity-id cannot be changed when updating an entity.
       However, format-specific rules might in some cases require providing
      @@ -4451,7 +4473,7 @@ set of entities to be related according to that relationship and MUST
       NOT include added links, deleted links, or deleted entities.
       
       ::: example
      -Example 78: using the JSON format, a 4.01 `PATCH` request can update a
      +Example 79: using the JSON format, a 4.01 `PATCH` request can update a
       manager entity. Following the update, the manager has three direct
       reports; two existing employees and one new employee named
       `Suzanne Brown`. The `LastName` of employee 6 is updated to `Smith`.
      @@ -4501,7 +4523,7 @@ entity is to be created. If any nested entities contain both id and key
       fields, they MUST identify the same entity, or the request is invalid.
       
       ::: example
      -Example 79: using the JSON format, a 4.01 `PATCH` request can specify a
      +Example 80: using the JSON format, a 4.01 `PATCH` request can specify a
       nested delta representation to:
       
       - delete employee 3 and
      @@ -4793,7 +4815,7 @@ payload unless explicitly requested with [`$expand`](#SystemQueryOptionexpand).
       Instead, the values are generally read or written through URLs.
       
       ::: example
      -Example 80: read an entity and select a stream property
      +Example 81: read an entity and select a stream property
       
       ```
       GET http://host/service/Products(1)?$select=Thumbnail
      @@ -4824,7 +4846,7 @@ The response MAY be a redirect to the media read link of the stream property
       if the media read link is different from the canonical URL.
       
       ::: example
      -Example 81: directly read a stream property of an entity
      +Example 82: directly read a stream property of an entity
       
       ```
       GET http://host/service/Products(1)/Thumbnail
      @@ -4875,7 +4897,7 @@ attempts to set the property to null and results in an error if the
       property is non-nullable.
       
       ::: example
      -Example 82: delete the stream value using the media edit link retrieved in [example 80](#entityWithStreamProperty)
      +Example 83: delete the stream value using the media edit link retrieved in [example 81](#entityWithStreamProperty)
       
       ```
       DELETE http://server/uploads/Thumbnail546.jpg
      @@ -5029,7 +5051,7 @@ ordinal number indexes from the end of the collection, with -1
       representing an insert as the last item in the collection.
       
       ::: example
      -Example 83: Insert a new email address at the second position
      +Example 84: Insert a new email address at the second position
       
       ```json
       POST /service/Customers('ALFKI')/EmailAddresses?$index=1
      @@ -5191,7 +5213,7 @@ semantics described in [Update a Collection of
       Entities](#UpdateaCollectionofEntities) applies.
       
       ::: example
      -Example 84: change the color of all beige-brown products
      +Example 85: change the color of all beige-brown products
       
       ```json
       PATCH /service/Products/$filter(@bar)/$each?@bar=Color eq 'beige-brown'
      @@ -5237,7 +5259,7 @@ The request resource path of the collection MAY contain type-cast or
       filter segments to subset the collection.
       
       ::: example
      -Example 85: delete all products older than 3
      +Example 86: delete all products older than 3
       
       ```
       DELETE /service/Products/$filter(Age gt 3)/$each
      @@ -5289,7 +5311,7 @@ by that URL is used as the *binding parameter value*. Only aliases
       defined in the metadata document of the service can be used in URLs.
       
       ::: example
      -Example 86: the function `MostRecentOrder` can be bound to any URL that
      +Example 87: the function `MostRecentOrder` can be bound to any URL that
       identifies a `SampleModel.Customer`
       ```xml
       
      @@ -5300,7 +5322,7 @@ identifies a `SampleModel.Customer`
       :::
       
       ::: example
      -Example 87: invoke the `MostRecentOrder` function with the value of the
      +Example 88: invoke the `MostRecentOrder` function with the value of the
       binding parameter `customer` being the entity identified by
       `http://host/service/Customers(6)`
       ```
      @@ -5309,7 +5331,7 @@ GET http://host/service/Customers(6)/SampleModel.MostRecentOrder()
       :::
       
       ::: example
      -Example 88: the function `Comparison` can be bound to any URL that
      +Example 89: the function `Comparison` can be bound to any URL that
       identifies a collection of entities
       ```xml
       
      @@ -5320,7 +5342,7 @@ identifies a collection of entities
       :::
       
       ::: example
      -Example 89: invoke the `Comparison` function on the set of red products
      +Example 90: invoke the `Comparison` function on the set of red products
       ```
       GET http://host/service/Products/$filter(Color eq 'Red')/Diff.Comparison()
       ```
      @@ -5343,7 +5365,7 @@ result type of the bound operation. If the bound operation returns a
       collection, the response is a collection of collections.
       
       ::: example
      -Example 90: invoke the `MostRecentOrder` function on each entity in the
      +Example 91: invoke the `MostRecentOrder` function on each entity in the
       entity set `Customers`
       ```
       GET http://host/service/Customers/$each/SampleModel.MostRecentOrder()
      @@ -5371,7 +5393,7 @@ or entity collection within the payload. The representation of an action
       or function depends on the [format](#Formats).
       
       ::: example
      -Example 91: given a `GET` request to
      +Example 92: given a `GET` request to
       `http://host/service/Customers('ALFKI')`, the service might respond with
       a Customer that includes the `SampleEntities.MostRecentOrder` function
       bound to the entity
      @@ -5398,7 +5420,7 @@ Services can advertise that a function or action is not available for a
       particular instance by setting its value to null.
       
       ::: example
      -Example 92: the `SampleEntities.MostRecentOrder` function is not
      +Example 93: the `SampleEntities.MostRecentOrder` function is not
       available for customer `ALFKI`
       ```json
       {
      @@ -5482,7 +5504,7 @@ segment is a multi-valued navigation property, a `POST` request may be
       used to create a new entity in the identified collection.
       
       ::: example
      -Example 93: add a new item to the list of items of the shopping cart
      +Example 94: add a new item to the list of items of the shopping cart
       returned by the composable `MyShoppingCart` function import
       ```
       POST http://host/service/MyShoppingCart()/Items
      @@ -5531,7 +5553,7 @@ Each parameter value is represented as a name/value pair in the format
       and `Value` is the parameter value.
       
       ::: example
      -Example 94: invoke a `Sales.EmployeesByManager` function which takes a
      +Example 95: invoke a `Sales.EmployeesByManager` function which takes a
       single `ManagerID` parameter via the function import
       `EmployeesByManager`
       ```
      @@ -5540,7 +5562,7 @@ GET http://host/service/EmployeesByManager(ManagerID=3)
       :::
       
       ::: example
      -Example 95: return all Customers whose `City` property returns
      +Example 96: return all Customers whose `City` property returns
       `Western` when passed to the `Sales.SalesRegion` function
       ```
       GET http://host/service/Customers?
      @@ -5553,7 +5575,7 @@ parameter value. The value for the alias is specified as a separate
       query option using the name of the parameter alias.
       
       ::: example
      -Example 96: invoke a `Sales.EmployeesByManager` function via the
      +Example 97: invoke a `Sales.EmployeesByManager` function via the
       function import `EmployeesByManager`, passing 3 for the `ManagerID`
       parameter
       ```
      @@ -5573,7 +5595,7 @@ optional `$` prefix), the parameter name MUST be prefixed with an at
       (`@`) sign.
       
       ::: example
      -Example 97: invoke a `Sales.EmployeesByManager` function via the
      +Example 98: invoke a `Sales.EmployeesByManager` function via the
       function import `EmployeesByManager`, passing 3 for the `ManagerID`
       parameter using the implicit parameter alias
       ```
      @@ -5713,7 +5735,7 @@ collection as a whole is transported in the [`ETag`](#HeaderETag) header of a
       collection response.
       
       ::: example
      -Example 98: invoke the `SampleEntities.CreateOrder` action using
      +Example 99: invoke the `SampleEntities.CreateOrder` action using
       `Customers('ALFKI')` as the customer (or binding parameter). The values
       `2` for the `quantity` parameter and `BLACKFRIDAY` for the
       `discountCode` parameter are passed in the body of the request. Invoke
      @@ -5860,7 +5882,7 @@ format](#MultipartBatchFormat) MUST contain a
       [RFC2046](#rfc2046).
       
       ::: example
      -Example 99: multipart batch request
      +Example 100: multipart batch request
       ```
       POST /service/$batch HTTP/1.1
       Host: odata.org
      @@ -5875,7 +5897,7 @@ A batch request using the JSON batch format MUST contain a
       `Content-Type` header specifying a content type of `application/json`.
       
       ::: example
      -Example 100: JSON batch request
      +Example 101: JSON batch request
       ```
       POST /service/$batch HTTP/1.1
       Host: odata.org
      @@ -5930,7 +5952,7 @@ the request URL. Services MUST treat this segment like the URL in the
       [`Location`](#HeaderLocation) header of the response to the request identified by the segment.
       If the `Location` header in the response to the subsequent request contains a relative URL,
       clients MUST be able to resolve it relative to the request's URL even if
      -that contains such a reference. See [example 105](#batchcontentid).
      +that contains such a reference. See [example 106](#batchcontentid).
       
       If the `$`-prefixed request identifier is identical to the name of a
       top-level system resource (`$batch`, `$crossjoin`, `$all`, `$entity`,
      @@ -6031,7 +6053,7 @@ set can use one of the following three formats:
       - Absolute URI with schema, host, port, and absolute resource path.
       
       ::: example
      -Example 101:
      +Example 102:
       ```
       GET https://host:1234/path/service/People(1) HTTP/1.1
       ```
      @@ -6040,7 +6062,7 @@ GET https://host:1234/path/service/People(1) HTTP/1.1
       - Absolute resource path and separate `Host` header
       
       ::: example
      -Example 102:
      +Example 103:
       ```json
       PATCH /path/service/People(1) HTTP/1.1
       Host: myserver.mydomain.org:1234
      @@ -6053,7 +6075,7 @@ Content-Type: application/json
       - Resource path relative to the batch request URI.
       
       ::: example
      -Example 103:
      +Example 104:
       ```
       DELETE People(1) HTTP/1.1
       ```
      @@ -6078,7 +6100,7 @@ processor may choose to disallow chunked encoding to be used by such
       HTTP requests.
       
       ::: example
      -Example 104: a batch request that contains the following individual
      +Example 105: a batch request that contains the following individual
       requests in the order listed
       
         1. A query request
      @@ -6157,7 +6179,7 @@ which case they SHOULD advertise this support by specifying the
       term applied to the entity container, see [OData-VocCap](#ODataVocCap).
       
       ::: example
      -Example 105: a batch request that contains the following operations in
      +Example 106: a batch request that contains the following operations in
       the order listed:
       
       A change set that contains the following requests:
      @@ -6229,7 +6251,7 @@ request URL `$1/Orders`. To get an absolute base URI, the client must replace th
       resulting URL `Customers('ALFKI')/Orders(1)` relative to its base URI, which is
       `http://host/service/Customers` (determined from the
       first request URL `/service/Customers` and the `Host: host` header
      -as in [example 102](#batchhost)). This gives the effective second request URL
      +as in [example 103](#batchhost)). This gives the effective second request URL
       `http://host/service/Customers('ALFKI')/Orders` as base URI for the second `Location`
       URL, which therefore resolves to `http://host/service/Customers('ALFKI')/Orders(1)`.
       :::
      @@ -6237,7 +6259,7 @@ URL, which therefore resolves to `http://host/service/Customers('ALFKI')/Orders(
       #### 11.7.7.3 Referencing an ETag
       
       ::: example
      -Example 106: a batch request that contains the following operations in
      +Example 107: a batch request that contains the following operations in
       the order listed:
       
       - Get an employee (with `Content-ID = 1`)
      @@ -6278,7 +6300,7 @@ If-Match: $1
       #### 11.7.7.4 Referencing Response Body Values
       
       ::: example
      -Example 107: a batch request that contains the following operations in
      +Example 108: a batch request that contains the following operations in
       the order listed:
       
       - Get an employee (with `Content-ID = 1`)
      @@ -6371,11 +6393,11 @@ A response to an operation in a batch MUST be formatted exactly as it
       would have appeared outside of a batch as described in the corresponding
       subsections of chapter [Data Service Requests](#DataServiceRequests).
       Relative URLs in each individual response are relative to the request
      -URL of the corresponding individual request (see [example 105](#batchcontentid)).
      +URL of the corresponding individual request (see [example 106](#batchcontentid)).
       URLs in responses MUST NOT contain `$`-prefixed request identifiers.
       
       ::: example
      -Example 108: referencing the batch request [example 104](#batchRequest) above, assume all
      +Example 109: referencing the batch request [example 105](#batchRequest) above, assume all
       the requests except the final query request succeed. In this case the
       response would be
       ```
      @@ -6451,7 +6473,7 @@ Since a change set is executed atomically,
       a change set.
       
       ::: example
      -Example 109: referencing the [example 104](#batchRequest) above again, assume that
      +Example 110: referencing the [example 105](#batchRequest) above again, assume that
       ```
       HTTP/1.1 202 Accepted
       Location: http://service-root/async-monitor-0
      diff --git a/odata-protocol/11.4 Data Modification.md b/odata-protocol/11.4 Data Modification.md
      index cdcc419d..0450a48f 100644
      --- a/odata-protocol/11.4 Data Modification.md	
      +++ b/odata-protocol/11.4 Data Modification.md	
      @@ -178,20 +178,40 @@ values beyond those specified in the metadata SHOULD NOT be sent in the
       request body. The service MUST fail if unable to persist all property
       values specified in the request.
       
      -Non-insertable properties SHOULD be omitted from the request body.
      -If they are provided, services MUST either ignore the values in the request body or fail the request
      +If non-insertable properties are included in the request body,
      +services MUST either ignore them or fail the request
       if the provided values do not match the service-determined values.
       
       Non-insertable properties include (and are not limited to)
       
       - dependent properties that are tied to non-key properties of the principal entity through a referential constraint [OData-CSDL, section 8.5](#ODataCSDL) (informally: "denormalized" properties),
      -- properties annotated with the term
      +- properties tagged with the term
         [`Core.Computed`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#Computed), see [OData-VocCore](#ODataVocCore),
       - properties listed as `NonInsertableProperties` of term [`Capabilities.InsertRestrictions`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Capabilities.V1.md#InsertRestrictions), see [OData-VocCap](#ODataVocCap),
       - properties annotated with term
         [`Core.Permissions`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#Permissions), see [OData-VocCore](#ODataVocCore), where the annotation value does not have the `Write` flag.
       
      +Properties tagged with `Core.Computed` MAY additionally be tagged with the term
      +[`Core.PostCondition`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#PostCondition),
      +see [OData-VocCore](#ODataVocCore), if the service does not ignore them.
      +Based on this tag (or based on out-of-band knowledge about the service behavior)
      +clients can provide these properties in an insert request
      +and benefit from the certainty that, if the request succeeds, their service-determined values match
      +the provided values. Providing such properties effectively imposes "post-conditions"
      +that must be met for the request to succeed.
      +
      +Otherwise, clients SHOULD omit non-insertable properties from the request body.
      +
      +::: example
      +Example ##ex: The entity `SalesOrder` has a property `ExportRegulationsState`
      +which is tagged with `Core.Computed` and `Core.PostCondition` and which
      +the service determines based on the product and destination country.
      +Clients can specify it with value `Allowed` to impose a "post-condition" that a sales order is created
      +only if it meets export regulations.
      +:::
      +
       Services MUST return an error if the request body contains a value for a property that in principle can be specified on insert but the request cannot currently be executed respecting the specified value, for example, due to permissions or state of the object.
      +
       Properties with a default value, nullable properties, and
       collection-valued properties omitted from the request are set to the
       default value, null, or an empty collection, respectively.
      @@ -376,7 +396,7 @@ Non-updatable properties include (and are not limited to)
       
       - key properties,
       - dependent properties that are tied to non-key properties of the principal entity through a referential constraint [OData-CSDL, section 8.5](#ODataCSDL) (informally: "denormalized" properties),
      -- properties annotated with the terms
      +- properties tagged with the terms
         [`Core.Computed`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#Computed) or [`Core.Immutable`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#Immutable), see [OData-VocCore](#ODataVocCore),
       - properties listed as `NonUpdatableProperties` of term [`Capabilities.UpdateRestrictions`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Capabilities.V1.md#UpdateRestrictions), see [OData-VocCap](#ODataVocCap),
       - properties annotated with term
      @@ -385,7 +405,9 @@ Non-updatable properties include (and are not limited to)
       Services MUST return an error if the request body contains a value for a
       property that in principle can be specified on update but the request cannot currently be executed respecting the specified value, for example, due to permissions or state of the object.
       
      -Clients SHOULD use `PATCH` and specify only those properties intended to be changed.
      +Clients can provide non-updatable properties to impose "post-conditions" as explained
      +for [non-insertable properties](#CreateanEntity). Otherwise,
      +clients SHOULD use `PATCH` and specify only those properties intended to be changed.
       
       The entity-id cannot be changed when updating an entity.
       However, format-specific rules might in some cases require providing