Details

    • Type: New Feature
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: V4.0_CSD03
    • Fix Version/s: V4.0_CSD04
    • Labels:
      None
    • Environment:

      Proposed

    • Proposal:
      Hide

      Make use of existing specification text in section 14.2.2 Target.

      For vocabulary terms Aggregation.CustomAggregate and Aggregation.ApplySupported, add AppliesTo="Collection" and tag these terms with a new annotation in the Core vocabulary:

      <Term Name="AppliesViaContainer" Type="Core.Tag" DefaultValue="true" Nullable="false" AppliesTo="Term">
       <Annotation Term="Core.Description" String="The target path of an annotation with this term must start with an entity container or the annotation must be embedded within an entity container, entity set or singleton"/>
      </Term>
      

      Deprecate terms Groupable, Aggregatable, complex type NavigationPropertyAggregationCapabilities.

      For compatibility reasons, do not use this technique for annotations in the Capabilities vocabulary.

      Show
      Make use of existing specification text in section 14.2.2 Target . For vocabulary terms  Aggregation.CustomAggregate  and Aggregation.ApplySupported , add  AppliesTo="Collection" and tag these terms with a new annotation in the Core vocabulary: <Term Name= "AppliesViaContainer" Type= "Core.Tag" DefaultValue= "true" Nullable= "false" AppliesTo= "Term" > <Annotation Term= "Core.Description" String= "The target path of an annotation with this term must start with an entity container or the annotation must be embedded within an entity container, entity set or singleton" /> </Term> Deprecate terms Groupable , Aggregatable , complex type NavigationPropertyAggregationCapabilities . For compatibility reasons, do not use this technique for annotations in the Capabilities vocabulary.
    • Resolution:
      Show
      PR #101 .

      Description

      NavigationPropertyBindings are used to assign an entity set to a Path ending in a non-containment navigation property. The assigned entity set can then be the target for annotations like Aggregation.CustomAggregate (see https://issues.oasis-open.org/browse/ODATA-1382).

      Paths ending in a containment navigation property, which implicitly define an entity set, are treated totally different, however. In order to define a custom aggregate on this implicit entity set, the annotation Capabilities.NavigationRestrictions with type Aggregation.NavigationPropertyAggregationCapabilities/CustomAggregates must be used.

      An easier alternative would be to use external targeting with a path that ends in a containment navigation property:
       

      <Annotations Target="namespace.ContainerName/me/Mails">
       <Annotation Term="Aggregation.CustomAggregate" Qualifier="JunkRating" String="Edm.Int32"/>
      </Annotations>
      

        Attachments

          Activity

          Hide
          handl Ralf Handl added a comment -

          How would "external targeting" work for Navigation Property Bindings? Most SAP tools only use "external targeting" syntax.

          Show
          handl Ralf Handl added a comment - How would "external targeting" work for Navigation Property Bindings? Most SAP tools only use "external targeting" syntax.
          Hide
          heiko.theissen Heiko Theissen added a comment -

          A NavigationPropertyBindingVariant (working title) would have to be allowed as an annotation target, e.g., as

          <Annotations Target="me/Mails/$NavigationPropertyBindingVariant">
          
          Show
          heiko.theissen Heiko Theissen added a comment - A NavigationPropertyBindingVariant (working title) would have to be allowed as an annotation target, e.g., as <Annotations Target= "me/Mails/$NavigationPropertyBindingVariant" >
          Hide
          handl Ralf Handl added a comment -

          To be in line with the other targets (start from schema child, then dive into structure), it would rather be

          <Annotations Target="namespace.ContainerName/me/$NavigationPropertyBindingVariant/Mails">
          
          Show
          handl Ralf Handl added a comment - To be in line with the other targets (start from schema child, then dive into structure), it would rather be <Annotations Target= "namespace.ContainerName/me/$NavigationPropertyBindingVariant/Mails" >
          Hide
          heiko.theissen Heiko Theissen added a comment - - edited

          OK. What about replacing the working title with ContainmentNavigationProperty? (Without a Target, we shouldn't speak of a binding, right?)

          Show
          heiko.theissen Heiko Theissen added a comment - - edited OK. What about replacing the working title with ContainmentNavigationProperty ? (Without a Target , we shouldn't speak of a binding, right?)
          Hide
          heiko.theissen Heiko Theissen added a comment - - edited

          If we support external targeting only, can we even avoid the new object ContainmentNavigationProperty? Add a sentence to OData-CSDL, section 8.4:

          An annotation whose term applies to an entity set can also target the implicit entity set defined by a containment navigation property. The path expression for such a target must end in a containment navigation property followed by /$EntitySet

          Example:

          <Annotations Target="namespace.ContainerName/me/Mails/$EntitySet">
           <Annotation Term="Aggregation.CustomAggregate" Qualifier="JunkRating" String="Edm.Int32"/>
          </Annotations>
          

          In order to address such annotations in a Path, the path syntax must be extended to include something like

          <Path>me/Mails/@Aggregation.CustomAggregate</Path>
          
          Show
          heiko.theissen Heiko Theissen added a comment - - edited If we support external targeting only, can we even avoid the new object  ContainmentNavigationProperty ? Add a sentence to OData-CSDL, section 8.4 : An annotation whose term applies to an entity set can also target the implicit entity set defined by a containment navigation property. The path expression for such a target must end in a containment navigation property followed by /$EntitySet Example: <Annotations Target= "namespace.ContainerName/me/Mails/$EntitySet" > <Annotation Term= "Aggregation.CustomAggregate" Qualifier= "JunkRating" String= "Edm.Int32" /> </Annotations> In order to address such annotations in a Path , the path syntax must be extended to include something like <Path> me/Mails/@Aggregation.CustomAggregate </Path>
          Hide
          handl Ralf Handl added a comment -

          The current target syntax in 14.2.2 Target already allows navigation segments after an entity set:

          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.

          • [...]
          • 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

          This seems to cover already the desired feature without requiring new syntax.

          Show
          handl Ralf Handl added a comment - The current target syntax in 14.2.2 Target already allows navigation segments after an entity set: 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. [...] 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 This seems to cover already the desired feature without requiring new syntax.
          Hide
          heiko.theissen Heiko Theissen added a comment -

          But such annotations then target the navigation property (in our example, Mails), not the (implicit or explicit) entity set at the navigation property's target.

          Show
          heiko.theissen Heiko Theissen added a comment - But such annotations then target the navigation property (in our example, Mails ), not the (implicit or explicit) entity set at the navigation property's target.
          Hide
          handl Ralf Handl added a comment -

          So what's the problem / the difference?

          Show
          handl Ralf Handl added a comment - So what's the problem / the difference?
          Hide
          heiko.theissen Heiko Theissen added a comment -

          Doesn't it make a difference whether you annotate an entity set or a navigation property?

          Show
          heiko.theissen Heiko Theissen added a comment - Doesn't it make a difference whether you annotate an entity set or a navigation property?
          Hide
          handl Ralf Handl added a comment -

          Conceptually entity sets and singletons are containment navigation properties of the implicit "service entity type" of the entity container.

          Show
          handl Ralf Handl added a comment - Conceptually entity sets and singletons are containment navigation properties of the implicit "service entity type" of the entity container.
          Hide
          heiko.theissen Heiko Theissen added a comment -

          I want to annotate the implicit entity set that is defined by the containment navigation property Mails on the singleton me. Then I cannot use the target namespace.ContainerName/me/Mails because that addresses the containment navigation property. But I want to address the implicit entity set.

          Show
          heiko.theissen Heiko Theissen added a comment - I want to annotate the implicit entity set that is defined by the containment navigation property Mails on the singleton me . Then I cannot use the target namespace.ContainerName/me/Mails because that addresses the containment navigation property. But I want to address the implicit entity set.
          Hide
          handl Ralf Handl added a comment -

          The navigation property is addressed via namespace.entityTypeOfMe/Mails. And the type of the Mails property via namespace.typeOfMails

          Do we really need syntax to differentiate between

          • the implicit entity set defined by the Mails containment navigation property of singleton me, and
          • the use of type namespace.typeOfMails as the type of the property Mails of the singleton me?
          Show
          handl Ralf Handl added a comment - The navigation property is addressed via namespace.entityTypeOfMe/Mails . And the type of the Mails property via namespace.typeOfMails .  Do we really need syntax to differentiate between the implicit entity set defined by the Mails containment navigation property of singleton me , and the use of type namespace.typeOfMails as the type of the property Mails of the singleton me ?
          Hide
          heiko.theissen Heiko Theissen added a comment - - edited

          Note that the proposed extension of a term definition makes sense only for containment navigation properties and the implicit entity sets they define. An "entity set defined by a non-containment navigation property" (via NavigationPropertyBinding) is just a named entity set and can be annotated as such.

          I believe that capabilities and other annotations of such an entity set should not depend on the path via which the entity set is reached, because the entity set exists independently of that path. This is different for implicit entity sets, which are contained in an instance from another entity set (or singleton), hence they are dependent on the path.

          In other words: Path-dependent capabilities and annotations make sense only for implicit entity sets, i.e., for containment navigation properties.

          Example: An entity set Orders has two navigation properties

          • items – contained in Order
          • superImportantItems – non-contained projection on “items” in same entity

          Then capabilities should be annotated for the "defining path" Orders/items, but not for the "reference path" Orders/superImportantItems.

          In cases where annotations of an explicit (named) entity set shall depend on the path, Capabilities.NavigationPropertyRestrictions can be used instead.

          Show
          heiko.theissen Heiko Theissen added a comment - - edited Note that the proposed extension of a term definition makes sense only for  containment navigation properties and the implicit entity sets they define. An "entity set defined by a non-containment navigation property" (via NavigationPropertyBinding) is just a named entity set and can be annotated as such. I believe that capabilities and other annotations of such an entity set should not depend on the path via which the entity set is reached, because the entity set exists independently of that path. This is different for  implicit entity sets, which are contained in an instance from another entity set (or singleton), hence they are dependent on the path. In other words: Path-dependent capabilities and annotations make sense only for implicit entity sets, i.e., for containment navigation properties. Example: An entity set Orders has two navigation properties items – contained in Order superImportantItems – non-contained projection on “items” in same entity Then capabilities should be annotated for the "defining path" Orders/items , but not for the "reference path" Orders/superImportantItems . In cases where annotations of an explicit (named) entity set  shall depend on the path, Capabilities.NavigationPropertyRestrictions can be used instead.
          Hide
          heiko.theissen Heiko Theissen added a comment -

          Will try to rephrase so that non-containment navigation properties are also covered.

          Show
          heiko.theissen Heiko Theissen added a comment - Will try to rephrase so that non-containment navigation properties are also covered.
          Hide
          heiko.theissen Heiko Theissen added a comment - - edited
          • Discourage Groupable, Aggregatable, NavigationPropertyAggregationCapabilities
          • Can AppliesViaContainer be combined with AppliesTo="ComplexType"?
          • AppliesViaContainer also for AvailableOnAggregates?
          • What about Capabilities vocabulary?
            • ChangeTracking
            • NavigationRestrictions
            • OperationRestrictions
            • ModificationQueryOptions
            • MediaLocationUpdateSupported
          Show
          heiko.theissen Heiko Theissen added a comment - - edited Discourage Groupable, Aggregatable, NavigationPropertyAggregationCapabilities Can AppliesViaContainer be combined with AppliesTo="ComplexType"? AppliesViaContainer also for AvailableOnAggregates? What about Capabilities vocabulary? ChangeTracking NavigationRestrictions OperationRestrictions ModificationQueryOptions MediaLocationUpdateSupported
          Hide
          heiko.theissen Heiko Theissen added a comment - - edited

          Are the following statements true or false?

          The annotation from the example given in the description can be addressed via the path

          /namespace.ContainerName/me/Mails/@Aggregation.CustomAggregate#JunkRating
          

          (using a term cast, like in OData-CSDL, example 61).

          The annotation from the example given in the description can be addressed via the path

          /namespace.ContainerName/me/Mails@Aggregation.CustomAggregate#JunkRating
          

          (without term cast, like in [OData-CSDL, example 64]).

          I would like the first to be true (important to me!) and the second false (less important to me). But is that what the spec says?

          Show
          heiko.theissen Heiko Theissen added a comment - - edited Are the following statements true or false? The annotation from the example given in the description can be addressed via the path /namespace.ContainerName/me/Mails/@Aggregation.CustomAggregate#JunkRating (using a term cast, like in OData-CSDL , example 61). The annotation from the example given in the description can be addressed via the path /namespace.ContainerName/me/Mails@Aggregation.CustomAggregate#JunkRating (without term cast, like in [OData-CSDL, example 64] ). I would like the first to be true (important to me!) and the second false (less important to me). But is that what the spec says?
          Hide
          handl Ralf Handl added a comment -

          Examples 61 and 64 talk about paths in annotation expressions, for example in an AnnotationPath:

          • use example-61 syntax to address an annotation that is attached to the target type of the navigation property
          • use example-64 syntax to address an annotation that is attached to the navigation property itself

          The annotation example in the description uses external targeting, so it attaches the annotation to the navigation property itself, and an AnnotationPath expression has to use example-64 syntax to address this annotation.

          You can use example-61 syntax if the annotation would target the entity type that is referenced in the Mails navigation property, e.g. namespace.MailType.

          Show
          handl Ralf Handl added a comment - Examples 61 and 64 talk about paths in annotation expressions, for example in an AnnotationPath : use example-61 syntax to address an annotation that is attached to the target type of the navigation property use example-64 syntax to address an annotation that is attached to the navigation property itself The annotation example in the description uses external targeting, so it attaches the annotation to the navigation property itself, and an AnnotationPath expression has to use example-64 syntax to address this annotation. You can use example-61 syntax if the annotation would target the entity type that is referenced in the Mails navigation property, e.g. namespace.MailType .
          Hide
          heiko.theissen Heiko Theissen added a comment - - edited

          OK, you convinced me.

          Show
          heiko.theissen Heiko Theissen added a comment - - edited OK, you convinced me.
          Hide
          mikep Michael Pizzo (Inactive) added a comment - - edited

          2021-3-11 - Decided to defer resolution of this issue until we decide our intentions for representing the existing non-aggregation navigation property restrictions.

          Show
          mikep Michael Pizzo (Inactive) added a comment - - edited 2021-3-11 - Decided to defer resolution of this issue until we decide our intentions for representing the existing non-aggregation navigation property restrictions.
          Hide
          heiko.theissen Heiko Theissen added a comment - - edited

          "Core" navigation property restrictions could be represented by the Capabilities.NavigationPropertyRestriction type, but all non-core ones (whether from the Aggregation vocabulary or some other, perhaps future, vocabulary) cannot: Because if every vocabulary introduced its own sub-type (like Aggregation.NavigationPropertyAggregationCapabilities has done), a given Capabilities.NavigationRestrictions/RestrictedProperties annotation could choose only one of these subtypes, so it could not express both a custom aggregate and a restriction from a future vocabulary on the same NavigationProperty. (No multiple inheritance.)

          On the other hand, it is infeasible if every vocabulary had to insert its restrictions into the Capabilities.NavigationPropertyRestriction type.

          Show
          heiko.theissen Heiko Theissen added a comment - - edited "Core" navigation property restrictions could be represented by the Capabilities.NavigationPropertyRestriction type, but all non-core ones (whether from the Aggregation vocabulary or some other, perhaps future, vocabulary) cannot: Because if every vocabulary introduced its own sub-type (like Aggregation.NavigationPropertyAggregationCapabilities has done), a given Capabilities.NavigationRestrictions/RestrictedProperties annotation could choose only one of these subtypes, so it could not express both a custom aggregate and a restriction from a future vocabulary on the same NavigationProperty . (No multiple inheritance.) On the other hand, it is infeasible if every vocabulary had to insert its restrictions into the Capabilities.NavigationPropertyRestriction type.
          Hide
          handl Ralf Handl added a comment -

          Good point!

          Maybe we should add mixins in V5 �

          Show
          handl Ralf Handl added a comment - Good point! Maybe we should add mixins in V5 �
          Hide
          heiko.theissen Heiko Theissen added a comment - - edited

          An annotation like

          /namespace.ContainerName/me/Mails@Aggregation.CustomAggregate#JunkRating
          

          can be addressed via an Edm.AnnotationPath, for example in a bar chart annotation if the aggregated value shall be represented as the height of a bar.

          By contrast, the Edm.PropertyPath

          /namespace.ContainerName/me/@Capabilities.NavigationRestrictions
          /RestrictedProperties/1/CustomAggregates/0
          

          is much more cumbersome (especially the index segments) and, not being an Edm.AnnotationPath, cannot be governed by Validation.AllowedTerms.

          Show
          heiko.theissen Heiko Theissen added a comment - - edited An annotation like /namespace.ContainerName/me/Mails@Aggregation.CustomAggregate#JunkRating can be addressed via an Edm.AnnotationPath , for example in a bar chart annotation if the aggregated value shall be represented as the height of a bar. By contrast, the Edm.PropertyPath /namespace.ContainerName/me/@Capabilities.NavigationRestrictions /RestrictedProperties/1/CustomAggregates/0 is much more cumbersome (especially the index segments) and, not being an Edm.AnnotationPath , cannot be governed by Validation.AllowedTerms .
          Hide
          mikep Michael Pizzo (Inactive) added a comment -

          Note: there are solutions to having multiple vocabularies extend NavigationRestrictions (for example, through dynamic properties).

          Show
          mikep Michael Pizzo (Inactive) added a comment - Note: there are solutions to having multiple vocabularies extend NavigationRestrictions (for example, through dynamic properties).
          Hide
          handl Ralf Handl added a comment -

          2021-03-18

          Show
          handl Ralf Handl added a comment - 2021-03-18

            People

            • Assignee:
              Unassigned
              Reporter:
              heiko.theissen Heiko Theissen
            • Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: