Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: V4.0_CS02
    • Fix Version/s: V4.0_CSD04
    • Component/s: Data Aggregation
    • Labels:
      None
    • Environment:

      Applied

    • Proposal:
      Hide
      • The aggregate function is considered a collectionPathExpr (rather than a methodCallExpr) and must be prepended with a navigation path that addresses the input collection (in the sense of ODATA-1244). In the argument of the aggregation function, common expressions are evaluated according to the rules for lambda operators. (The lambda variable evaluates to the current instance within the addressed collection, whereas an unprefixed Amount would be evaluated in the context of the Products instance currently being filtered.)
        Products?$filter=Sales/aggregate(s:s/Amount mul TaxRate with sum) gt 100
      • Instead of a navigation path, the input collection can also be addressed by the keyword $these. A new kind of propertyPathExpr is introduced in which $these addresses the "current collection" (defined below), in analogy with the current instance $this [OData-URL, section 5.1.1.14.6]. The current collection is also at the origin of the path $these, therefore s/Amount could be replaced by Amount in the following example.
        Sales?$apply=groupby((Product),filter($these/aggregate(s:s/Amount) lt 100))
      • $these can be prepended to collection path expressions like any, all and aggregate. (But we allow only $these/aggregate for now, so as not to touch the core spec.) See also ODATA-1456.
      • In a system query option (possibly nested within $expand or $select), when evaluating the boolCommonExpr in a filter or the commonExpr in an orderbyItem or computeItem, the current collection is the collection being filtered or ordered or augmented.
        Products?$select=Sales($filter=$these/aggregate(s:Price with avg) gt $this/Price)
        
      • In an $apply transformation, when evaluating the boolCommonExpr in a filterTrafo or the commonExpr in a computeExpr, the current collection is the input set of the transformation.
      • When evaluating a commonExpr in its nearest collectionPathExpr, the current collection is the collection identified by the navigation path before the collectionPathExpr. This allows things like
        Products?$filter=Sales/any(p:p/Amount gt $these/aggregate(q:Amount))
        

      See also oasis-tcs/odata-abnf#37.

      The third paragraph in [OData-Aggr, section 3.24 "Function aggregate"] must be rewritten to reflect the rules above. The $these keyword and "current collection" concept introduced in these rules are not mentioned outside of that section for now. See https://www.oasis-open.org/apps/org/workgroup/odata/download.php/69074/ODATA-1451.docx

      Show
      The aggregate function is considered a  collectionPathExpr  (rather than a methodCallExpr ) and must be prepended with a navigation path that addresses the input collection (in the sense of ODATA-1244 ). In the argument of the aggregation function, common expressions are evaluated according to the rules for lambda operators . (The lambda variable evaluates to the current instance within the addressed collection, whereas an unprefixed Amount would be evaluated in the context of the Products instance currently being filtered.) Products?$filter=Sales/aggregate(s:s/Amount mul TaxRate with sum) gt 100 Instead of a navigation path, the input collection can also be addressed by the keyword  $these . A new kind of  propertyPathExpr  is introduced in which  $these addresses the "current collection" (defined below), in analogy with the current instance $this   [OData-URL, section 5.1.1.14.6] . The current collection is also at the origin of the path $these , therefore s/Amount could be replaced by Amount in the following example. Sales?$apply=groupby((Product),filter($these/aggregate(s:s/Amount) lt 100)) $these can be prepended to collection path expressions like any , all and aggregate . (But we allow only $these/aggregate for now, so as not to touch the core spec.) See also ODATA-1456 . In a system query option (possibly nested within  $expand or $select ), when evaluating the boolCommonExpr in a filter or the commonExpr in an orderbyItem or  computeItem , the current collection is the collection being filtered or ordered or augmented. Products?$select=Sales($filter=$these/aggregate(s:Price with avg) gt $ this /Price) In an $apply  transformation, when evaluating the boolCommonExpr in a filterTrafo or the commonExpr in a computeExpr , the current collection is the input set of the transformation. When evaluating a commonExpr in its nearest collectionPathExpr , the current collection is the collection identified by the navigation path before the collectionPathExpr . This allows things like Products?$filter=Sales/any(p:p/Amount gt $these/aggregate(q:Amount)) See also oasis-tcs/odata-abnf#37 . The third paragraph in [OData-Aggr, section 3.24 "Function aggregate"] must be rewritten to reflect the rules above. The $these keyword and "current collection" concept introduced in these rules are not mentioned outside of that section for now. See  https://www.oasis-open.org/apps/org/workgroup/odata/download.php/69074/ODATA-1451.docx
    • Resolution:
      Show
      https://www.oasis-open.org/apps/org/workgroup/odata/download.php/69078/odata-data-aggregation-ext-v4.0-wd05.docx 2022-02-11: Resolution edited to allow the aggregate function in /$filter segments and orderby transformations: https://www.oasis-open.org/apps/org/workgroup/odata/download.php/69595/odata-data-aggregation-ext-v4.0-wd05.docx

      Description

      The current specification of the aggregate function (ODATA-1244) leaves undefined what the "input collection" is in cases like

      $filter=Sales/any(p:aggregate(p/Amount mul TaxRate with sum) gt 5) 
      

      that include property paths with and without lambda variable.

        Attachments

          Activity

          Hide
          handl Ralf Handl added a comment -

          Context instance is an excellent name for the existing symbol $this.

          How about defining an explicit symbol $these for the context collection and requiring the aggregate(...) common expression to be prefixed with a collection path, which can be $these?

          So we could use pathToCollection/aggregate(...) to aggregate a collection within the context instance, and $these/aggregate(...) to aggregate the context collection itself.

          This would avoid to make aggregate working implicitly on the not yet defined context collection, in contrast to all other expressions.

          Show
          handl Ralf Handl added a comment - Context instance is an excellent name for the existing symbol $this . How about defining an explicit symbol $these for the context collection and requiring the aggregate(...) common expression to be prefixed with a collection path, which can be $these ? So we could use pathToCollection/aggregate(...) to aggregate a collection within the context instance, and $these/aggregate(...) to aggregate the context collection itself. This would avoid to make aggregate working implicitly on the not yet defined context collection, in contrast to all other expressions.
          Hide
          heiko.theissen Heiko Theissen added a comment - - edited

          That means replacing all the bullet points from the description with:

          • The aggregate function must be prepended with a navigation path that identifies a collection. Inside it, common expressions are evaluated like in lambda operators. The lambda variable evaluates to the current instance within that collection.
            Products?$filter=Sales/aggregate(p:p/Amount) gt 100
            
          • $these is a new kind of collectionPathExpr that evaluates to a "current collection" (defined below), in analogy with the current instance $this [OData-URL, section 5.1.1.14.6].
          • $these can be prepended to collection path expressions like any, all and aggregate. (But we allow only $these/aggregate for now, so as not to touch the core spec.) See also ODATA-1456.
          • In a system query option, when evaluating the boolCommonExpr in a filter or the commonExpr in a computeExpr, the current collection is the resource addressed by the resource path [OData-URL, section 4]. If the addressed resource is a single instance, the current collection is undefined.
          • In an $apply transformation, when evaluating the boolCommonExpr in a filterTrafo or the commonExpr in a computeExpr, the current collection is the input set of the transformation.
          • When evaluating a commonExpr in its nearest collectionPathExpr, the current collection is the collection addressed by the path that prepends the collectionPathExpr. This allows things like
            Products?$filter=Sales/any(p:p/Amount gt $these/aggregate(q:q/Amount))
            

          But can we introduce $these in OData V4.01 without changing the core spec? Perhaps by restricting its use to within $apply?

          Wording question: "current collection" or "context collection"?

          Show
          heiko.theissen Heiko Theissen added a comment - - edited That means replacing all the bullet points from the description with: The aggregate function must be prepended with a navigation path that identifies a collection. Inside it, common expressions are evaluated like in lambda operators. The lambda variable evaluates to the current instance within that collection. Products?$filter=Sales/aggregate(p:p/Amount) gt 100 $these is a new kind of collectionPathExpr that evaluates to a "current collection" (defined below), in analogy with the current instance $this   [OData-URL, section 5.1.1.14.6] . $these can be prepended to collection path expressions like any , all and aggregate . (But we allow only $these/aggregate for now, so as not to touch the core spec.) See also ODATA-1456 . In a system query option, when evaluating the boolCommonExpr in a filter or the commonExpr in a computeExpr , the current collection is the resource addressed by the resource path  [OData-URL, section 4] . If the addressed resource is a single instance, the current collection is undefined. In an $apply  transformation, when evaluating the boolCommonExpr in a filterTrafo or the commonExpr in a computeExpr , the current collection is the input set of the transformation. When evaluating a commonExpr in its nearest collectionPathExpr , the current collection is the collection addressed by the path that prepends the collectionPathExpr . This allows things like Products?$filter=Sales/any(p:p/Amount gt $these/aggregate(q:q/Amount)) But can we introduce $these in OData V4.01 without changing the core spec? Perhaps by restricting its use to within $apply ? Wording question: "current collection" or "context collection"?
          Hide
          handl Ralf Handl added a comment -

          Adding aggregate(...) as a common expression extends the core spec, so adding $these/aggregate(...) instead does not make a difference.

          Regarding the fourth bullet: when would we need to aggregate over a single instance instead of just using a normal common expression or $compute?

          If we don't need it, I'd rephrase the fourth bullet point to:

          • When evaluating a query option like $filter and $compute on a collection-valued resource, the context collection is the resource addressed by the resource path [OData-URL, section 4]. If the addressed resource is a single instance, the context collection is not defined.
          Show
          handl Ralf Handl added a comment - Adding aggregate(...) as a common expression extends the core spec, so adding $these/aggregate(...) instead does not make a difference. Regarding the fourth bullet: when would we need to aggregate over a single instance instead of just using a normal common expression or $compute ? If we don't need it, I'd rephrase the fourth bullet point to: When evaluating a query option like $filter and $compute on a collection-valued resource, the context collection is the resource addressed by the resource path [OData-URL, section 4] . If the addressed resource is a single instance, the context collection is not defined.
          Hide
          heiko.theissen Heiko Theissen added a comment - - edited

          Merged PR #37 into PR #35 in oasis-tcs/odata-abnf.

          Show
          heiko.theissen Heiko Theissen added a comment - - edited Merged PR #37 into PR #35 in oasis-tcs/odata-abnf.
          Hide
          heiko.theissen Heiko Theissen added a comment - - edited

          TC 2021-09-23: RESOLVED as proposed.

          Show
          heiko.theissen Heiko Theissen added a comment - - edited TC 2021-09-23: RESOLVED as proposed.

            People

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

              Dates

              • Created:
                Updated:
                Resolved: