-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into ODATA-1506-order-by-index-nested-option
- Loading branch information
Showing
7 changed files
with
1,942 additions
and
996 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,61 @@ | ||
;------------------------------------------------------------------------------ | ||
; OData Aggregation ABNF Construction Rules Version 4.0 | ||
;------------------------------------------------------------------------------ | ||
; 04 November 2015 | ||
; | ||
; Latest version: https://github.com/oasis-tcs/odata-abnf/blob/main/abnf/odata-aggregation-abnf.txt | ||
; 19 September 2023 | ||
;------------------------------------------------------------------------------ | ||
; | ||
; Technical Committee: | ||
; OASIS Open Data Protocol (OData) TC | ||
; https://www.oasis-open.org/committees/odata | ||
; | ||
; Chairs: | ||
; - Barbara Hartel (barbara.hartel@sap.com), SAP AG | ||
; - Ram Jeyaraman (Ram.Jeyaraman@microsoft.com), Microsoft | ||
; - Ralf Handl (ralf.handl@sap.com), SAP SE | ||
; - Michael Pizzo (mikep@microsoft.com), Microsoft | ||
; | ||
; Editors: | ||
; - Ralf Handl ([email protected]), SAP AG | ||
; - Ralf Handl ([email protected]), SAP SE | ||
; - Hubert Heijkers ([email protected]), IBM | ||
; - Gerald Krause ([email protected]), SAP AG | ||
; - Gerald Krause ([email protected]), SAP SE | ||
; - Michael Pizzo ([email protected]), Microsoft | ||
; - Martin Zurmuehl ([email protected]), SAP AG | ||
; - Martin Zurmuehl ([email protected]), SAP SE | ||
; - Heiko Theissen ([email protected]), SAP SE | ||
; | ||
; Additional artifacts: | ||
; Additional artifacts: | ||
; This grammar is one component of a Work Product which consists of: | ||
; - OData Extension for Data Aggregation Version 4.0 | ||
; - OData Aggregation ABNF Construction Rules Version 4.0 | ||
; - OData Aggregation ABNF Test Cases | ||
; - OData Aggregation Vocabulary | ||
; - OData Aggregation ABNF Construction Rules Version 4.0 (this document) | ||
; - OData Aggregation ABNF Test Cases Version 4.0 | ||
; | ||
; Related work: | ||
; This specification is related to: | ||
; - OData Version 4.0 Part 1: Protocol | ||
; - OData Version 4.0 Part 2: URL Conventions | ||
; - OData Version 4.0 Part 3: CSDL | ||
; - OData ABNF Construction Rules Version 4.0 | ||
; - OData Core Vocabulary | ||
; - OData Measures Vocabulary | ||
; - OData JSON Format Version 4.0 | ||
; - OData Version 4.01 Part 1: Protocol | ||
; - OData Version 4.01 Part 2: URL Conventions | ||
; - OData ABNF Construction Rules Version 4.01 | ||
; - OData ABNF Test Cases Version 4.01 | ||
; - OData Common Schema Definition Language (CSDL) JSON Representation Version 4.01 | ||
; - OData Common Schema Definition Language (CSDL) XML Representation Version 4.01 | ||
; - OData JSON Format Version 4.01 | ||
; This specification replaces or supersedes: | ||
; - None | ||
; | ||
; Declared XML namespaces: | ||
; - None | ||
; | ||
; Abstract: | ||
; This specification adds basic grouping and aggregation functionality (e.g. | ||
; This specification adds basic grouping and aggregation functionality (such as | ||
; sum, min, and max) to the Open Data Protocol (OData) without changing any | ||
; of the base principles of OData. | ||
; | ||
; Overview: | ||
; This grammar uses the ABNF defined in RFC5234 and RFC7405. | ||
; This grammar uses the ABNF defined in RFC5234 and RFC7405. | ||
; | ||
; It extends the OData ABNF Construction Rules Version 4.0 | ||
; It extends the OData ABNF Construction Rules Version 4.01 | ||
; | ||
; Contents: | ||
; 1. New alternatives for OData ABNF Construction Rules | ||
; 2. System Query Option $apply | ||
; 3. Extensions to $filter | ||
; 3. Extensions to $filter | ||
; | ||
;------------------------------------------------------------------------------ | ||
|
||
|
@@ -70,8 +69,11 @@ expandOption =/ apply | |
|
||
boolMethodCallExpr =/ isdefinedExpr | ||
|
||
primitiveProperty =/ expressionAlias / customAggregate | ||
primitiveProperty =/ customAggregate | ||
|
||
firstMemberExpr =/ currCollectionExpr | ||
|
||
collectionPathExpr =/ %s"/aggregate" OPEN BWS aggregateFunctionExpr BWS CLOSE | ||
|
||
;------------------------------------------------------------------------------ | ||
; 2. System Query Option $apply | ||
|
@@ -80,96 +82,180 @@ primitiveProperty =/ expressionAlias / customAggregate | |
apply = ( "$apply" / "apply" ) EQ applyExpr | ||
applyExpr = applyTrafo *( "/" applyTrafo ) | ||
applyTrafo = aggregateTrafo | ||
/ bottomcountTrafo | ||
/ bottompercentTrafo | ||
/ bottomsumTrafo | ||
/ computeTrafo | ||
/ concatTrafo | ||
/ expandTrafo | ||
/ filterTrafo | ||
/ groupbyTrafo | ||
/ identityTrafo | ||
/ searchTrafo | ||
/ topcountTrafo | ||
/ toppercentTrafo | ||
/ topsumTrafo | ||
/ customFunction | ||
|
||
aggregateTrafo = %s"aggregate" OPEN BWS aggregateItem *( BWS COMMA BWS aggregateItem ) BWS CLOSE | ||
aggregateItem = %s"$count" asAlias | ||
/ aggregateExpr | ||
aggregateExpr = commonExpr aggregateWith [ aggregateFrom ] asAlias | ||
/ pathPrefix primitiveProperty aggregateWith [ aggregateFrom ] asAlias | ||
/ pathPrefix customAggregate [ customFrom asAlias ] | ||
/ pathPrefix pathSegment OPEN aggregateExpr CLOSE | ||
aggregateWith = RWS %s"with" RWS aggregateMethod | ||
aggregateFrom = RWS %s"from" RWS groupingProperty aggregateWith [ aggregateFrom ] | ||
customFrom = RWS %s"from" RWS groupingProperty [ aggregateWith ] [ customFrom ] | ||
aggregateMethod = %s"sum" | ||
/ %s"min" | ||
/ %s"max" | ||
/ %s"average" | ||
/ %s"countdistinct" | ||
/ namespace "." odataIdentifier | ||
/ joinTrafo | ||
/ nestTrafo | ||
/ outerjoinTrafo | ||
/ preservingTrafo | ||
preservingTrafo = bottomcountTrafo | ||
/ bottompercentTrafo | ||
/ bottomsumTrafo | ||
/ filterTrafo | ||
/ identityTrafo | ||
/ orderbyTrafo | ||
/ searchTrafo | ||
/ skipTrafo | ||
/ topTrafo | ||
/ topcountTrafo | ||
/ toppercentTrafo | ||
/ topsumTrafo | ||
/ ancestorsTrafo | ||
/ descendantsTrafo | ||
/ traverseTrafo | ||
/ customFunction ; custom functions could be preserving, hence are allowed in preservingTrafos | ||
preservingTrafos = preservingTrafo *( "/" preservingTrafo ) | ||
|
||
aggregateTrafo = %s"aggregate" OPEN BWS aggregateExpr *( BWS COMMA BWS aggregateExpr ) BWS CLOSE | ||
aggregateExpr = ( aggrPathPrefix / aggrCastPath ) nonprimAggWith [ aggregateFrom ] asAlias | ||
/ aggregatableExpW [ aggregateFrom ] asAlias | ||
/ aggregateCount [ aggregateFrom ] asAlias | ||
/ aggregateCustom [ [ customFrom ] asAlias ] | ||
aggregatableExpr = commonExpr ; resulting in an aggregatable value | ||
aggregatableExpW = aggregatableExpr aggregateWith | ||
/ [ aggrCastPath "/" ] aggrPrimPath aggregateWith | ||
aggrPathPrefix = [ aggrCastPath "/" ] aggrPropPath | ||
aggregateWith = RWS %s"with" RWS aggregateMethod | ||
nonprimAggWith = RWS %s"with" RWS nonprimAggMethod | ||
aggregateFrom = RWS %s"from" RWS groupingProperties aggregateWith [ aggregateFrom ] | ||
customFrom = RWS %s"from" RWS groupingProperties [ aggregateWith ] [ customFrom ] | ||
aggregateMethod = %s"sum" | ||
/ %s"min" | ||
/ %s"max" | ||
/ %s"average" | ||
/ nonprimAggMethod | ||
nonprimAggMethod = %s"countdistinct" | ||
/ namespace "." odataIdentifier ; custom aggregation methods may work on non-primitive values | ||
aggregateCount = %s"$count" | ||
/ [ aggrCastPath "/" ] aggrPrimPath count | ||
/ ( aggrPathPrefix / aggrCastPath ) count | ||
|
||
aggregateCustom = [ ( aggrPathPrefix / aggrCastPath ) "/" ] customAggregate | ||
|
||
asAlias = RWS %s"as" RWS expressionAlias | ||
expressionAlias = odataIdentifier | ||
|
||
customAggregate = odataIdentifier | ||
|
||
groupingProperty = pathPrefix | ||
( entityNavigationProperty [ "/" qualifiedEntityTypeName ] | ||
/ primitiveProperty | ||
/ complexProperty | ||
) | ||
pathPrefix = [ ( qualifiedEntityTypeName / qualifiedComplexTypeName ) "/" ] *( pathSegment "/" ) | ||
pathSegment = ( complexProperty / complexColProperty ) [ "/" qualifiedComplexTypeName ] | ||
/ navigationProperty [ "/" qualifiedEntityTypeName ] | ||
|
||
computeTrafo = %s"compute" OPEN BWS computeExpr *( BWS COMMA BWS computeExpr ) BWS CLOSE | ||
computeExpr = commonExpr asAlias | ||
|
||
bottomcountTrafo = %s"bottomcount" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
bottompercentTrafo = %s"bottompercent" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
bottomsumTrafo = %s"bottomsum" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
|
||
concatTrafo = %s"concat" OPEN BWS applyExpr 1*( BWS COMMA BWS applyExpr ) BWS CLOSE | ||
|
||
expandTrafo = %s"expand" OPEN BWS expandNavPath BWS COMMA BWS | ||
( expandTrafo *( BWS COMMA BWS expandTrafo ) | ||
/ filterTrafo *( BWS COMMA BWS expandTrafo ) | ||
) BWS CLOSE | ||
expandNavPath = [ ( qualifiedEntityTypeName / qualifiedComplexTypeName ) "/" ] | ||
*( ( complexProperty / complexColProperty ) "/" [ qualifiedComplexTypeName "/" ] ) | ||
navigationProperty [ "/" qualifiedEntityTypeName ] | ||
|
||
filterTrafo = %s"filter" OPEN BWS boolCommonExpr BWS CLOSE | ||
|
||
searchTrafo = %s"search" OPEN BWS searchExpr BWS CLOSE | ||
|
||
groupbyTrafo = %s"groupby" OPEN BWS groupbyList [ BWS COMMA BWS applyExpr ] BWS CLOSE | ||
groupbyList = OPEN BWS groupbyElement *( BWS COMMA BWS groupbyElement ) BWS CLOSE | ||
groupbyElement = groupingProperty / rollupSpec | ||
rollupSpec = %s"rollup" OPEN BWS | ||
( %s"$all" / groupingProperty ) | ||
1*( BWS COMMA BWS groupingProperty ) | ||
BWS CLOSE | ||
|
||
identityTrafo = %s"identity" | ||
|
||
topcountTrafo = %s"topcount" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
toppercentTrafo = %s"toppercent" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
topsumTrafo = %s"topsum" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
|
||
customFunction = namespace "." ( entityColFunction / complexColFunction / primitiveColFunction ) functionExprParameters | ||
|
||
; Three flavors of data aggregation paths are defined now: | ||
; - one for use in aggregate, whose segments can be single- or collection-valued (rules with prefix aggr) | ||
; - one for use in groupby, whose segments must be single-valued (rules with prefix sngl) | ||
; - one for use in addnested, without entity-valued segments (rule with prefix nest) | ||
; Term casts are not allowed in data aggregation paths. | ||
aggrPropStep = ( complexProperty / complexColProperty / entityNavigationProperty / entityColNavigationProperty ) | ||
[ "/" aggrCastPath ] | ||
aggrPropPath = aggrPropStep [ "/" aggrPropPath ] | ||
aggrPrimPath = aggrPropStep "/" aggrPrimPath | ||
/ primitiveProperty / primitiveColProperty / streamProperty | ||
aggrCastPath = optionallyQualifiedComplexTypeName / optionallyQualifiedEntityTypeName | ||
|
||
nestPropPath = ( complexProperty / complexColProperty ) [ [ "/" optionallyQualifiedComplexTypeName ] "/" nestPropPath ] | ||
|
||
snglPropPath = ( complexProperty / entityNavigationProperty ) [ [ "/" aggrCastPath ] "/" snglPropPath ] | ||
snglPrimPath = ( complexProperty / entityNavigationProperty ) [ "/" aggrCastPath ] "/" snglPrimPath | ||
/ primitiveProperty / streamProperty | ||
|
||
groupingProperty = [ aggrCastPath "/" ] ( snglPrimPath / snglPropPath ) | ||
groupingProperties = groupingProperty *( BWS COMMA BWS groupingProperty ) | ||
|
||
; Expressions evaluable on a collection | ||
collectionExpr = commonExpr ; but where every firstMemberExpr must be a currCollectionExpr | ||
currCollectionExpr = %s"$these" collectionPathExpr | ||
|
||
computeTrafo = %s"compute" OPEN BWS computeExpr *( BWS COMMA BWS computeExpr ) BWS CLOSE | ||
computeExpr = commonExpr asAlias | ||
|
||
bottomcountTrafo = %s"bottomcount" OPEN BWS collectionExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
bottompercentTrafo = %s"bottompercent" OPEN BWS collectionExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
bottomsumTrafo = %s"bottomsum" OPEN BWS collectionExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
|
||
concatTrafo = %s"concat" OPEN BWS applyExpr 1*( BWS COMMA BWS applyExpr ) BWS CLOSE | ||
|
||
nestTrafo = %s"nest" OPEN BWS nestApplyExpr BWS CLOSE | ||
/ %s"addnested" OPEN BWS nestPath BWS COMMA BWS nestApplyExpr BWS CLOSE | ||
nestPath = [ aggrCastPath "/" ] | ||
( [ nestPropPath "/" ] navigationProperty [ "/" optionallyQualifiedEntityTypeName ] | ||
/ nestPropPath | ||
) | ||
nestApplyExpr = applyExpr asAlias *( BWS COMMA BWS applyExpr asAlias ) | ||
|
||
joinTrafo = %s"join" OPEN BWS joinProperty asAlias [ BWS COMMA BWS applyExpr ] BWS CLOSE | ||
outerjoinTrafo = %s"outerjoin" OPEN BWS joinProperty asAlias [ BWS COMMA BWS applyExpr ] BWS CLOSE | ||
joinProperty = ( complexColProperty | ||
/ complexAnnotationInQuery ; must be collection-valued | ||
/ entityColNavigationProperty [ "/" optionallyQualifiedEntityTypeName ] | ||
/ entityAnnotationInQuery ; must be collection-valued | ||
) | ||
|
||
ancestorsTrafo = %s"ancestors" OPEN BWS | ||
recHierReference BWS | ||
COMMA BWS preservingTrafos BWS | ||
[ COMMA BWS 1*DIGIT BWS ] | ||
[ COMMA BWS %s"keep start" BWS ] | ||
CLOSE | ||
|
||
descendantsTrafo = %s"descendants" OPEN BWS | ||
recHierReference BWS | ||
COMMA BWS preservingTrafos BWS | ||
[ COMMA BWS 1*DIGIT BWS ] | ||
[ COMMA BWS %s"keep start" BWS ] | ||
CLOSE | ||
|
||
traverseTrafo = %s"traverse" OPEN BWS | ||
recHierReference BWS | ||
COMMA BWS ( %s"preorder" / %s"postorder" ) BWS | ||
[ COMMA BWS preservingTrafos BWS ] | ||
[ COMMA BWS orderbyItem *( BWS COMMA BWS orderbyItem ) BWS ] | ||
CLOSE | ||
|
||
recHierReference = rootExpr ; must have type Collection(Edm.EntityType) | ||
BWS COMMA BWS recHierQualifier | ||
BWS COMMA BWS recHierPropertyPath | ||
recHierQualifier = odataIdentifier | ||
recHierPropertyPath = [ aggrCastPath "/" ] aggrPrimPath | ||
|
||
filterTrafo = %s"filter" OPEN BWS boolCommonExpr BWS CLOSE | ||
|
||
searchTrafo = %s"search" OPEN BWS ( searchExpr / searchExpr-incomplete ) BWS CLOSE | ||
|
||
groupbyTrafo = %s"groupby" OPEN BWS groupbyList [ BWS COMMA BWS applyExpr ] BWS CLOSE | ||
groupbyList = OPEN BWS groupbyElement *( BWS COMMA BWS groupbyElement ) BWS CLOSE | ||
groupbyElement = groupingProperty / rollupLevels / rollupRecursive | ||
|
||
rollupLevels = %s"rollup" OPEN BWS ( rollupUnnamedHier / rollupNamedHier ) BWS CLOSE | ||
rollupRecursive = %s"rolluprecursive" OPEN BWS | ||
recHierReference BWS | ||
[ COMMA BWS preservingTrafos BWS ] | ||
CLOSE | ||
|
||
rollupUnnamedHier = groupingProperty 1*( BWS COMMA BWS groupingProperty ) | ||
rollupNamedHier = odataIdentifier ; qualifier of Aggregation.LeveledHierarchy annotation | ||
|
||
identityTrafo = %s"identity" | ||
|
||
topcountTrafo = %s"topcount" OPEN BWS collectionExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
toppercentTrafo = %s"toppercent" OPEN BWS collectionExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
topsumTrafo = %s"topsum" OPEN BWS collectionExpr BWS COMMA BWS commonExpr BWS CLOSE | ||
|
||
topTrafo = %s"top" OPEN BWS 1*DIGIT BWS CLOSE | ||
skipTrafo = %s"skip" OPEN BWS 1*DIGIT BWS CLOSE | ||
|
||
orderbyTrafo = %s"orderby" OPEN orderbyItem *( BWS COMMA BWS orderbyItem ) CLOSE | ||
|
||
customFunction = namespace "." ( entityColFunction / complexColFunction / primitiveColFunction ) functionExprParameters | ||
|
||
|
||
;------------------------------------------------------------------------------ | ||
; 3. Extensions to $filter | ||
; 3. New functions | ||
;------------------------------------------------------------------------------ | ||
|
||
isdefinedExpr = %s"isdefined" OPEN BWS ( firstMemberExpr ) BWS CLOSE | ||
|
||
aggregateFunctionExpr = aggregatableExpW [ aggregateFrom ] | ||
/ aggrPathPrefix nonprimAggWith [ aggregateFrom ] | ||
/ aggregateCount [ aggregateFrom ] | ||
/ aggregateCustom [ customFrom ] | ||
|
||
;------------------------------------------------------------------------------ | ||
; End of odata-aggregation-abnf | ||
|
Oops, something went wrong.