apg-js-examples
Version:
Examples of using the suite of apg-js applications and libraries.
1,100 lines (914 loc) • 57.6 kB
Plain Text
;------------------------------------------------------------------------------
; OData ABNF Construction Rules Version 4.01 and 4.0
;------------------------------------------------------------------------------
; 17 September 2020
;------------------------------------------------------------------------------
;
; Technical Committee:
; OASIS Open Data Protocol (OData) TC
; https://www.oasis-open.org/committees/odata
;
; Chairs:
; - Ralf Handl (ralf.handl@sap.com), SAP SE
; - Michael Pizzo (mikep@microsoft.com), Microsoft
;
; Editors:
; - Ralf Handl (ralf.handl@sap.com), SAP SE
; - Michael Pizzo (mikep@microsoft.com), Microsoft
; - Martin Zurmuehl (martin.zurmuehl@sap.com), SAP SE
;
; Additional artifacts:
; This grammar is one component of a Work Product which consists of:
; - OData Version 4.01 Part 1: Protocol
; - OData Version 4.01 Part 2: URL Conventions
; - OData ABNF Construction Rules Version 4.01 (this document)
; - OData ABNF Test Cases Version 4.01
;
; Related work:
; This specification replaces or supersedes:
; - OData ABNF Construction Rules Version 4.0
; This work product is related to
; - 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
;
; Abstract:
; The Open Data Protocol (OData) enables the creation of REST-based data
; services, which allow resources, identified using Uniform Resource
; Identifiers (URLs) and defined in a data model, to be published and
; edited by Web clients using simple HTTP messages. This document defines
; the URL syntax for requests and the serialization format for primitive
; literals in request and response payloads.
;
; Overview:
; This grammar uses the ABNF defined in RFC5234 and RFC7405.
;
; The following rules assume that URIs have been percent-encoding normalized
; as described in section 6.2.2.2 of RFC3986
; (http://tools.ietf.org/html/rfc3986#section-6.2.2.2)
; before applying the grammar to them, i.e. all characters in the unreserved
; set (see rule "unreserved" below) are plain literals and NOT
; percent-encoded.
;
; For characters outside the unreserved set the rules explicitly state
; whether the percent-encoded representation is treated identical to the
; plain literal representation.
;
; One prominent example is the single quote that delimits OData primitive
; type literals: %27 and ' are treated identically, so a single quote within
; a string literal is "encoded" as two consecutive single quotes in either
; literal or percent-encoded representation.
;
; Contents:
; 1. Resource Path
; 2. Query Options
; 3. Context URL Fragments
; 4. Expressions
; 5. JSON format for function parameters
; 6. Names and identifiers
; 7. Literal Data Values
; 8. Header values
; 9. Punctuation
;
; A. URI syntax [RFC3986]
; B. IRI syntax [RFC3986]
; C. ABNF core definitions [RFC5234]
;
;------------------------------------------------------------------------------
dummyStartRule = odataUri / header / primitiveValue ; just to please the test parser
;------------------------------------------------------------------------------
odataUri = serviceRoot [ odataRelativeUri ]
serviceRoot = ( "https" / "http" ) ; Note: case-insensitive
"://" host [ ":" port ]
"/" *( segment-nz "/" )
; Note: dollar-prefixed path segments are case-sensitive!
odataRelativeUri = %s"$batch" [ "?" batchOptions ]
/ %s"$entity" "?" entityOptions
/ %s"$entity" "/" optionallyQualifiedEntityTypeName "?" entityCastOptions
/ %s"$metadata" [ "?" metadataOptions ] [ context ]
/ resourcePath [ "?" queryOptions ]
;------------------------------------------------------------------------------
; 1. Resource Path
;------------------------------------------------------------------------------
resourcePath = entitySetName [ collectionNavigation ]
/ singletonEntity [ singleNavigation ]
/ actionImportCall
/ entityColFunctionImportCall [ collectionNavigation ]
/ entityFunctionImportCall [ singleNavigation ]
/ complexColFunctionImportCall [ complexColPath ]
/ complexFunctionImportCall [ complexPath ]
/ primitiveColFunctionImportCall [ collectionPath ]
/ primitiveFunctionImportCall [ primitivePath ]
/ functionImportCallNoParens [ querySegment ]
/ crossjoin [ querySegment ]
/ %s"$all" [ "/" optionallyQualifiedEntityTypeName ]
collectionNavigation = collectionNavPath
/ "/" optionallyQualifiedEntityTypeName [ collectionNavPath ]
collectionNavPath = keyPredicate [ singleNavigation ]
/ filterInPath [ collectionNavigation ]
/ each [ boundOperation ]
/ boundOperation
/ count
/ ref
/ querySegment
keyPredicate = simpleKey / compoundKey / keyPathSegments
simpleKey = OPEN ( parameterAlias / keyPropertyValue ) CLOSE
compoundKey = OPEN keyValuePair *( COMMA keyValuePair ) CLOSE
keyValuePair = ( primitiveKeyProperty / keyPropertyAlias ) EQ ( parameterAlias / keyPropertyValue )
keyPropertyValue = primitiveLiteral
keyPropertyAlias = odataIdentifier
keyPathSegments = 1*( "/" keyPathLiteral )
keyPathLiteral = *pchar
singleNavigation = singleNavPath
/ "/" optionallyQualifiedEntityTypeName [ singleNavPath ]
singleNavPath = "/" propertyPath
/ boundOperation
/ ref
/ value ; request the media resource of a media entity
/ querySegment
propertyPath = entityColNavigationProperty [ collectionNavigation ]
/ entityNavigationProperty [ singleNavigation ]
/ complexColProperty [ complexColPath ]
/ complexProperty [ complexPath ]
/ primitiveColProperty [ collectionPath ]
/ primitiveProperty [ primitivePath ]
/ streamProperty [ boundOperation ]
collectionPath = count / boundOperation / ordinalIndex / querySegment
primitivePath = value / boundOperation / querySegment
complexColPath = collectionPath
/ "/" optionallyQualifiedComplexTypeName [ collectionPath ]
complexPath = complexNavPath
/ "/" optionallyQualifiedComplexTypeName [ complexNavPath ]
complexNavPath = "/" propertyPath
/ boundOperation
/ querySegment
filterInPath = %s"/$filter" OPEN boolCommonExpr CLOSE
each = %s"/$each"
count = %s"/$count"
ref = %s"/$ref"
value = %s"/$value"
querySegment = %s"/$query"
ordinalIndex = "/" [ "-" ] 1*DIGIT
; boundOperation segments can only be composed if the type of the previous segment
; matches the type of the first parameter of the action or function being called.
; Note that the rule name reflects the return type of the function.
boundOperation = "/" ( boundActionCall
/ boundEntityColFunctionCall [ collectionNavigation ]
/ boundEntityFunctionCall [ singleNavigation ]
/ boundComplexColFunctionCall [ complexColPath ]
/ boundComplexFunctionCall [ complexPath ]
/ boundPrimitiveColFunctionCall [ collectionPath ]
/ boundPrimitiveFunctionCall [ primitivePath ]
/ boundFunctionCallNoParens [ querySegment ]
)
actionImportCall = actionImport
boundActionCall = [ namespace "." ] action
; with the added restriction that the binding parameter MUST be either an entity or collection of entities
; and is specified by reference using the URI immediately preceding (to the left) of the boundActionCall
; The following boundXxxFunctionCall rules have the added restrictions that
; - the function MUST support binding, and
; - the binding parameter type MUST match the type of resource identified by the
; URI immediately preceding (to the left) of the boundXxxFunctionCall, and
; - the functionParameters MUST NOT include the bindingParameter.
boundEntityFunctionCall = [ namespace "." ] entityFunction functionParameters
boundEntityColFunctionCall = [ namespace "." ] entityColFunction functionParameters
boundComplexFunctionCall = [ namespace "." ] complexFunction functionParameters
boundComplexColFunctionCall = [ namespace "." ] complexColFunction functionParameters
boundPrimitiveFunctionCall = [ namespace "." ] primitiveFunction functionParameters
boundPrimitiveColFunctionCall = [ namespace "." ] primitiveColFunction functionParameters
boundFunctionCallNoParens = [ namespace "." ] entityFunction
/ [ namespace "." ] entityColFunction
/ [ namespace "." ] complexFunction
/ [ namespace "." ] complexColFunction
/ [ namespace "." ] primitiveFunction
/ [ namespace "." ] primitiveColFunction
entityFunctionImportCall = entityFunctionImport functionParameters
entityColFunctionImportCall = entityColFunctionImport functionParameters
complexFunctionImportCall = complexFunctionImport functionParameters
complexColFunctionImportCall = complexColFunctionImport functionParameters
primitiveFunctionImportCall = primitiveFunctionImport functionParameters
primitiveColFunctionImportCall = primitiveColFunctionImport functionParameters
functionImportCallNoParens = entityFunctionImport
/ entityColFunctionImport
/ complexFunctionImport
/ complexColFunctionImport
/ primitiveFunctionImport
/ primitiveColFunctionImport
functionParameters = OPEN [ functionParameter *( COMMA functionParameter ) ] CLOSE
functionParameter = parameterName EQ ( parameterAlias / primitiveLiteral )
parameterName = odataIdentifier
parameterAlias = AT odataIdentifier
crossjoin = %s"$crossjoin" OPEN
entitySetName *( COMMA entitySetName )
CLOSE
;------------------------------------------------------------------------------
; 2. Query Options
;------------------------------------------------------------------------------
queryOptions = queryOption *( "&" queryOption )
queryOption = systemQueryOption
/ aliasAndValue
/ nameAndValue
/ customQueryOption
batchOptions = batchOption *( "&" batchOption )
batchOption = format
/ customQueryOption
metadataOptions = metadataOption *( "&" metadataOption )
metadataOption = format
/ customQueryOption
entityOptions = *( entityIdOption "&" ) id *( "&" entityIdOption )
entityIdOption = format
/ customQueryOption
entityCastOptions = *( entityCastOption "&" ) id *( "&" entityCastOption )
entityCastOption = entityIdOption
/ expand
/ select
id = ( "$id" / "id" ) EQ IRI-in-query
systemQueryOption = compute
/ deltatoken
/ expand
/ filter
/ format
/ id
/ inlinecount
/ orderby
/ schemaversion
/ search
/ select
/ skip
/ skiptoken
/ top
/ index
compute = ( "$compute" / "compute" ) EQ computeItem *( COMMA computeItem )
computeItem = commonExpr RWS "as" RWS computedProperty
computedProperty = odataIdentifier
expand = ( "$expand" / "expand" ) EQ expandItem *( COMMA expandItem )
expandItem = "$value"
/ expandPath
/ optionallyQualifiedEntityTypeName "/" expandPath
expandPath = *( ( complexProperty / complexColProperty / optionallyQualifiedComplexTypeName / complexAnnotationInQuery ) "/" )
( STAR [ ref / OPEN levels CLOSE ]
/ streamProperty
/ ( navigationProperty / entityAnnotationInQuery ) [ "/" optionallyQualifiedEntityTypeName ]
[ ref [ OPEN expandRefOption *( SEMI expandRefOption ) CLOSE ]
/ count [ OPEN expandCountOption *( SEMI expandCountOption ) CLOSE ]
/ OPEN expandOption *( SEMI expandOption ) CLOSE
]
)
expandCountOption = filter
/ search
expandRefOption = expandCountOption
/ orderby
/ skip
/ top
/ inlinecount
expandOption = expandRefOption
/ select
/ expand
/ compute
/ levels
/ aliasAndValue
levels = ( "$levels" / "levels" ) EQ ( oneToNine *DIGIT / "max" )
filter = ( "$filter" / "filter" ) EQ boolCommonExpr
orderby = ( "$orderby" / "orderby" ) EQ orderbyItem *( COMMA orderbyItem )
orderbyItem = commonExpr [ RWS ( "asc" / "desc" ) ]
skip = ( "$skip" / "skip" ) EQ 1*DIGIT
top = ( "$top" / "top" ) EQ 1*DIGIT
index = ( "$index" / "index" ) EQ [ "-" ] 1*DIGIT
format = ( "$format" / "format" ) EQ
( "atom"
/ "json"
/ "xml"
/ 1*pchar "/" 1*pchar ; <a data service specific value indicating a
) ; format specific to the specific data service> or
; <An IANA-defined [IANA-MMT] content type>
inlinecount = ( "$count" / "count" ) EQ booleanValue
schemaversion = ( "$schemaversion" / "schemaversion" ) EQ ( STAR / 1*unreserved )
search = ( "$search" / "search" ) EQ BWS ( searchExpr / searchExpr-incomplete )
searchExpr = ( searchParenExpr
/ searchNegateExpr
/ searchPhrase
/ searchWord
) [ searchOrExpr
/ searchAndExpr
]
searchParenExpr = OPEN BWS searchExpr BWS CLOSE
; NOT is a unary operator if followed by a search expression
searchNegateExpr = %s"NOT" RWS searchExpr
; AND and OR are binary operators if they appear between search expressions
searchOrExpr = RWS %s"OR" RWS searchExpr
searchAndExpr = RWS [ %s"AND" RWS ] searchExpr
searchPhrase = quotation-mark 1*( qchar-no-AMP-DQUOTE / SP ) quotation-mark
; A searchWord is a sequence of one or more non-whitespace characters, excluding
; - literal or percent-encoded parentheses "(", "%28", "%29", ")"
; - literal or percent-encoded double-quotes '"' and "%22"
; - the semicolon ";"
; Percent-encoding is allowed, and required for characters with special meaning in the query part of a URL, especially "&" and "#".
; Expressing this in ABNF is somewhat clumsy, so the following rule is overly generous.
; Note: the words AND, OR, and NOT are sometimes operators, depending on their position within a search expression.
searchWord = searchChar *( searchChar / SQUOTE )
searchChar = unreserved / pct-encoded-no-DQUOTE / "!" / "*" / "+" / "," / ":" / "@" / "/" / "?" / "$" / "="
searchExpr-incomplete = SQUOTE *( SQUOTE-in-string / qchar-no-AMP-SQUOTE / quotation-mark / SP ) SQUOTE
select = ( "$select" / "select" ) EQ selectItem *( COMMA selectItem )
selectItem = STAR
/ allOperationsInSchema
/ selectProperty
/ optionallyQualifiedActionName
/ optionallyQualifiedFunctionName
/ ( optionallyQualifiedEntityTypeName / optionallyQualifiedComplexTypeName )
"/" ( selectProperty
/ optionallyQualifiedActionName
/ optionallyQualifiedFunctionName
)
selectProperty = primitiveProperty / primitiveAnnotationInQuery
/ ( primitiveColProperty / primitiveColAnnotationInQuery ) [ OPEN selectOptionPC *( SEMI selectOptionPC ) CLOSE ]
/ navigationProperty
/ selectPath [ OPEN selectOption *( SEMI selectOption ) CLOSE
/ "/" selectProperty
]
selectPath = ( complexProperty / complexColProperty / complexAnnotationInQuery ) [ "/" optionallyQualifiedComplexTypeName ]
selectOptionPC = filter / search / inlinecount / orderby / skip / top
selectOption = selectOptionPC
/ compute / select / aliasAndValue
allOperationsInSchema = namespace "." STAR
; The parameterNames uniquely identify the bound function overload
; Necessary only if it has overloads
optionallyQualifiedActionName = [ namespace "." ] action
optionallyQualifiedFunctionName = [ namespace "." ] function [ OPEN parameterNames CLOSE ]
; The names of all non-binding parameters, separated by commas
parameterNames = parameterName *( COMMA parameterName )
deltatoken = "$deltatoken" EQ 1*( qchar-no-AMP )
skiptoken = "$skiptoken" EQ 1*( qchar-no-AMP )
aliasAndValue = parameterAlias EQ parameterValue
nameAndValue = parameterName EQ parameterValue
parameterValue = arrayOrObject
/ commonExpr
customQueryOption = customName [ EQ customValue ]
customName = qchar-no-AMP-EQ-AT-DOLLAR *( qchar-no-AMP-EQ )
customValue = *( qchar-no-AMP )
complexAnnotationInQuery = annotationInQuery ; complex-valued annotation
entityAnnotationInQuery = annotationInQuery ; entity-valued annotation
primitiveAnnotationInQuery = annotationInQuery ; primitive-valued annotation
primitiveColAnnotationInQuery = annotationInQuery ; primitive collection-valued annotation
;------------------------------------------------------------------------------
; 3. Context URL Fragments
;------------------------------------------------------------------------------
context = "#" contextFragment
contextFragment = %s"Collection($ref)"
/ %s"$ref"
/ %s"Collection(Edm.EntityType)"
/ %s"Collection(Edm.ComplexType)"
/ singletonEntity [ navigation *( containmentNavigation ) [ "/" qualifiedEntityTypeName ] ] [ selectList ]
/ qualifiedTypeName [ selectList ]
/ entitySet ( %s"/$deletedEntity" / %s"/$link" / %s"/$deletedLink" )
/ entitySet keyPredicate "/" contextPropertyPath [ selectList ]
/ entitySet [ selectList ] [ %s"/$entity" / %s"/$delta" ]
entitySet = entitySetName *( containmentNavigation ) [ "/" qualifiedEntityTypeName ]
containmentNavigation = keyPredicate [ "/" qualifiedEntityTypeName ] navigation
navigation = *( "/" complexProperty [ "/" qualifiedComplexTypeName ] ) "/" navigationProperty
selectList = OPEN [ selectListItem *( COMMA selectListItem ) ] CLOSE
selectListItem = STAR ; all structural properties
/ allOperationsInSchema
/ [ ( qualifiedEntityTypeName / qualifiedComplexTypeName ) "/" ]
( qualifiedActionName
/ qualifiedFunctionName
/ selectListProperty
)
selectListProperty = primitiveProperty
/ primitiveColProperty
/ ( navigationProperty / entityAnnotationInFragment ) [ "+" ] [ selectList ]
/ ( complexProperty / complexColProperty / complexAnnotationInFragment ) [ "/" qualifiedComplexTypeName ] [ "/" selectListProperty ]
contextPropertyPath = primitiveProperty
/ primitiveColProperty
/ complexColProperty
/ complexProperty [ [ "/" qualifiedComplexTypeName ] "/" contextPropertyPath ]
qualifiedActionName = namespace "." action
qualifiedFunctionName = namespace "." function [ OPEN parameterNames CLOSE ]
complexAnnotationInFragment = annotationInFragment ; complex-valued annotation
entityAnnotationInFragment = annotationInFragment ; entity-valued annotation
;------------------------------------------------------------------------------
; 4. Expressions
;------------------------------------------------------------------------------
; Note: a boolCommonExpr is also a commonExpr, e.g. sort by Boolean
commonExpr = ( primitiveLiteral
/ arrayOrObject
/ rootExpr
/ firstMemberExpr
/ functionExpr
/ negateExpr
/ methodCallExpr
/ parenExpr
/ castExpr
/ isofExpr
/ notExpr
)
[ addExpr
/ subExpr
/ mulExpr
/ divExpr
/ divbyExpr
/ modExpr
]
[ eqExpr
/ neExpr
/ ltExpr
/ leExpr
/ gtExpr
/ geExpr
/ hasExpr
/ inExpr
]
[ andExpr
/ orExpr
]
boolCommonExpr = commonExpr ; resulting in a Boolean
rootExpr = %s"$root/" ( entitySetName keyPredicate / singletonEntity ) [ singleNavigationExpr ]
firstMemberExpr = memberExpr
/ inscopeVariableExpr [ "/" memberExpr ]
memberExpr = directMemberExpr
/ ( optionallyQualifiedEntityTypeName / optionallyQualifiedComplexTypeName ) "/" directMemberExpr
directMemberExpr = propertyPathExpr
/ boundFunctionExpr
/ annotationExpr
propertyPathExpr = ( entityColNavigationProperty [ collectionNavigationExpr ]
/ entityNavigationProperty [ singleNavigationExpr ]
/ complexColProperty [ complexColPathExpr ]
/ complexProperty [ complexPathExpr ]
/ primitiveColProperty [ collectionPathExpr ]
/ primitiveProperty [ primitivePathExpr ]
/ streamProperty [ primitivePathExpr ]
)
annotationExpr = annotationInQuery
[ collectionPathExpr
/ singleNavigationExpr
/ complexPathExpr
/ primitivePathExpr
]
annotationInQuery = AT [ namespace "." ] termName [ HASH annotationQualifier ]
annotationInFragment = AT [ namespace "." ] termName [ "#" annotationQualifier ]
annotationQualifier = odataIdentifier
inscopeVariableExpr = implicitVariableExpr
/ parameterAlias
/ lambdaVariableExpr ; only allowed inside a lambdaPredicateExpr
implicitVariableExpr = %s"$it" ; the current instance of the resource identified by the resource path
/ %s"$this" ; the instance on which the query option is evaluated
lambdaVariableExpr = odataIdentifier
collectionNavigationExpr = [ "/" optionallyQualifiedEntityTypeName ]
( collectionPathExpr
/ keyPredicate [ singleNavigationExpr ]
/ filterExpr [ collectionNavigationExpr ]
)
singleNavigationExpr = "/" memberExpr
filterExpr = %s"/$filter" OPEN boolCommonExpr CLOSE
complexColPathExpr = collectionPathExpr
/ "/" optionallyQualifiedComplexTypeName [ collectionPathExpr ]
collectionPathExpr = count [ OPEN expandCountOption *( SEMI expandCountOption ) CLOSE ]
/ filterExpr [ collectionPathExpr ]
/ "/" anyExpr
/ "/" allExpr
/ "/" boundFunctionExpr
/ "/" annotationExpr
complexPathExpr = "/" directMemberExpr
/ "/" optionallyQualifiedComplexTypeName [ "/" directMemberExpr ]
primitivePathExpr = "/" [ annotationExpr / boundFunctionExpr ]
boundFunctionExpr = functionExpr ; boundFunction segments can only be composed if the type of the
; previous segment matches the type of the first function parameter
functionExpr = [ namespace "." ]
( entityColFunction functionExprParameters [ collectionNavigationExpr ]
/ entityFunction functionExprParameters [ singleNavigationExpr ]
/ complexColFunction functionExprParameters [ complexColPathExpr ]
/ complexFunction functionExprParameters [ complexPathExpr ]
/ primitiveColFunction functionExprParameters [ collectionPathExpr ]
/ primitiveFunction functionExprParameters [ primitivePathExpr ]
)
functionExprParameters = OPEN [ functionExprParameter *( COMMA functionExprParameter ) ] CLOSE
functionExprParameter = parameterName EQ ( parameterAlias / parameterValue )
anyExpr = "any" OPEN BWS [ lambdaVariableExpr BWS COLON BWS lambdaPredicateExpr ] BWS CLOSE
allExpr = "all" OPEN BWS lambdaVariableExpr BWS COLON BWS lambdaPredicateExpr BWS CLOSE
lambdaPredicateExpr = boolCommonExpr ; containing at least one lambdaVariableExpr
methodCallExpr = indexOfMethodCallExpr
/ toLowerMethodCallExpr
/ toUpperMethodCallExpr
/ trimMethodCallExpr
/ substringMethodCallExpr
/ concatMethodCallExpr
/ lengthMethodCallExpr
/ matchesPatternMethodCallExpr
/ yearMethodCallExpr
/ monthMethodCallExpr
/ dayMethodCallExpr
/ hourMethodCallExpr
/ minuteMethodCallExpr
/ secondMethodCallExpr
/ fractionalsecondsMethodCallExpr
/ totalsecondsMethodCallExpr
/ dateMethodCallExpr
/ timeMethodCallExpr
/ roundMethodCallExpr
/ floorMethodCallExpr
/ ceilingMethodCallExpr
/ distanceMethodCallExpr
/ geoLengthMethodCallExpr
/ totalOffsetMinutesMethodCallExpr
/ minDateTimeMethodCallExpr
/ maxDateTimeMethodCallExpr
/ nowMethodCallExpr
/ caseMethodCallExpr
/ boolMethodCallExpr
boolMethodCallExpr = endsWithMethodCallExpr
/ startsWithMethodCallExpr
/ containsMethodCallExpr
/ intersectsMethodCallExpr
/ hasSubsetMethodCallExpr
/ hasSubsequenceMethodCallExpr
concatMethodCallExpr = "concat" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE
containsMethodCallExpr = "contains" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE
endsWithMethodCallExpr = "endswith" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE
indexOfMethodCallExpr = "indexof" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE
lengthMethodCallExpr = "length" OPEN BWS commonExpr BWS CLOSE
matchesPatternMethodCallExpr = "matchesPattern" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE
startsWithMethodCallExpr = "startswith" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE
substringMethodCallExpr = "substring" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS [ COMMA BWS commonExpr BWS ] CLOSE
toLowerMethodCallExpr = "tolower" OPEN BWS commonExpr BWS CLOSE
toUpperMethodCallExpr = "toupper" OPEN BWS commonExpr BWS CLOSE
trimMethodCallExpr = "trim" OPEN BWS commonExpr BWS CLOSE
yearMethodCallExpr = "year" OPEN BWS commonExpr BWS CLOSE
monthMethodCallExpr = "month" OPEN BWS commonExpr BWS CLOSE
dayMethodCallExpr = "day" OPEN BWS commonExpr BWS CLOSE
hourMethodCallExpr = "hour" OPEN BWS commonExpr BWS CLOSE
minuteMethodCallExpr = "minute" OPEN BWS commonExpr BWS CLOSE
secondMethodCallExpr = "second" OPEN BWS commonExpr BWS CLOSE
fractionalsecondsMethodCallExpr = "fractionalseconds" OPEN BWS commonExpr BWS CLOSE
totalsecondsMethodCallExpr = "totalseconds" OPEN BWS commonExpr BWS CLOSE
dateMethodCallExpr = "date" OPEN BWS commonExpr BWS CLOSE
timeMethodCallExpr = "time" OPEN BWS commonExpr BWS CLOSE
totalOffsetMinutesMethodCallExpr = "totaloffsetminutes" OPEN BWS commonExpr BWS CLOSE
minDateTimeMethodCallExpr = "mindatetime" OPEN BWS CLOSE
maxDateTimeMethodCallExpr = "maxdatetime" OPEN BWS CLOSE
nowMethodCallExpr = "now" OPEN BWS CLOSE
roundMethodCallExpr = "round" OPEN BWS commonExpr BWS CLOSE
floorMethodCallExpr = "floor" OPEN BWS commonExpr BWS CLOSE
ceilingMethodCallExpr = "ceiling" OPEN BWS commonExpr BWS CLOSE
distanceMethodCallExpr = "geo.distance" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE
geoLengthMethodCallExpr = "geo.length" OPEN BWS commonExpr BWS CLOSE
intersectsMethodCallExpr = "geo.intersects" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE
hasSubsetMethodCallExpr = "hassubset" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE
hasSubsequenceMethodCallExpr = "hassubsequence" OPEN BWS commonExpr BWS COMMA BWS commonExpr BWS CLOSE
caseMethodCallExpr = "case" OPEN BWS boolCommonExpr BWS COLON BWS commonExpr BWS
*( COMMA BWS boolCommonExpr BWS COLON BWS commonExpr BWS ) CLOSE
parenExpr = OPEN BWS commonExpr BWS CLOSE
listExpr = OPEN BWS primitiveLiteral BWS *( COMMA BWS primitiveLiteral BWS ) CLOSE
andExpr = RWS "and" RWS boolCommonExpr
orExpr = RWS "or" RWS boolCommonExpr
eqExpr = RWS "eq" RWS commonExpr
neExpr = RWS "ne" RWS commonExpr
ltExpr = RWS "lt" RWS commonExpr
leExpr = RWS "le" RWS commonExpr
gtExpr = RWS "gt" RWS commonExpr
geExpr = RWS "ge" RWS commonExpr
inExpr = RWS "in" RWS ( listExpr / commonExpr )
hasExpr = RWS "has" RWS enum
addExpr = RWS "add" RWS commonExpr
subExpr = RWS "sub" RWS commonExpr
mulExpr = RWS "mul" RWS commonExpr
divExpr = RWS "div" RWS commonExpr
divbyExpr = RWS "divby" RWS commonExpr
modExpr = RWS "mod" RWS commonExpr
negateExpr = "-" BWS commonExpr
notExpr = "not" RWS boolCommonExpr
isofExpr = "isof" OPEN BWS [ commonExpr BWS COMMA BWS ] optionallyQualifiedTypeName BWS CLOSE
castExpr = "cast" OPEN BWS [ commonExpr BWS COMMA BWS ] optionallyQualifiedTypeName BWS CLOSE
;------------------------------------------------------------------------------
; 5. JSON format for queries
;------------------------------------------------------------------------------
; Note: the query part of a URI needs to be percent-encoding normalized before
; applying these rules, see comment at the top of this file
;------------------------------------------------------------------------------
arrayOrObject = array
/ object
array = begin-array
[ valueInUrl *( value-separator valueInUrl ) ]
end-array
object = begin-object
[ member *( value-separator member ) ]
end-object
member = stringInUrl name-separator valueInUrl
valueInUrl = stringInUrl
/ commonExpr
; JSON syntax: adapted to URI restrictions from [RFC8259]
begin-object = BWS ( "{" / "%7B" ) BWS
end-object = BWS ( "}" / "%7D" )
begin-array = BWS ( "[" / "%5B" ) BWS
end-array = BWS ( "]" / "%5D" )
quotation-mark = DQUOTE / "%22"
name-separator = BWS COLON BWS
value-separator = BWS COMMA BWS
stringInUrl = quotation-mark *charInJSON quotation-mark
charInJSON = qchar-unescaped
/ qchar-JSON-special
/ escape ( quotation-mark
/ escape
/ ( "/" / "%2F" ) ; solidus U+002F - literal form is allowed in the query part of a URL
/ %s"b" ; backspace U+0008
/ %s"f" ; form feed U+000C
/ %s"n" ; line feed U+000A
/ %s"r" ; carriage return U+000D
/ %s"t" ; tab U+0009
/ %s"u" 4HEXDIG ; U+XXXX
)
qchar-JSON-special = SP / ":" / "{" / "}" / "[" / "]" ; some agents put these unencoded into the query part of a URL
escape = "\" / "%5C" ; reverse solidus U+005C
;------------------------------------------------------------------------------
; 6. Names and identifiers
;------------------------------------------------------------------------------
qualifiedTypeName = singleQualifiedTypeName
/ %s"Collection" OPEN singleQualifiedTypeName CLOSE
optionallyQualifiedTypeName = singleQualifiedTypeName
/ %s"Collection" OPEN singleQualifiedTypeName CLOSE
/ singleTypeName
/ %s"Collection" OPEN singleTypeName CLOSE
singleQualifiedTypeName = qualifiedEntityTypeName
/ qualifiedComplexTypeName
/ qualifiedTypeDefinitionName
/ qualifiedEnumTypeName
/ primitiveTypeName
singleTypeName = entityTypeName
/ complexTypeName
/ typeDefinitionName
/ enumerationTypeName
qualifiedEntityTypeName = namespace "." entityTypeName
qualifiedComplexTypeName = namespace "." complexTypeName
qualifiedTypeDefinitionName = namespace "." typeDefinitionName
qualifiedEnumTypeName = namespace "." enumerationTypeName
optionallyQualifiedEntityTypeName = [ namespace "." ] entityTypeName
optionallyQualifiedComplexTypeName = [ namespace "." ] complexTypeName
; an alias is just a single-part namespace
namespace = namespacePart *( "." namespacePart )
namespacePart = odataIdentifier
entitySetName = odataIdentifier
singletonEntity = odataIdentifier
entityTypeName = odataIdentifier
complexTypeName = odataIdentifier
typeDefinitionName = odataIdentifier
enumerationTypeName = odataIdentifier
enumerationMember = odataIdentifier
termName = odataIdentifier
; Note: this pattern is overly restrictive, the normative definition is type TSimpleIdentifier in OData EDM XML Schema
odataIdentifier = identifierLeadingCharacter *127identifierCharacter
identifierLeadingCharacter = ALPHA / "_" ; plus Unicode characters from the categories L or Nl
identifierCharacter = ALPHA / "_" / DIGIT ; plus Unicode characters from the categories L, Nl, Nd, Mn, Mc, Pc, or Cf
primitiveTypeName = %s"Edm." ( %s"Binary"
/ %s"Boolean"
/ %s"Byte"
/ %s"Date"
/ %s"DateTimeOffset"
/ %s"Decimal"
/ %s"Double"
/ %s"Duration"
/ %s"Guid"
/ %s"Int16"
/ %s"Int32"
/ %s"Int64"
/ %s"SByte"
/ %s"Single"
/ %s"Stream"
/ %s"String"
/ %s"TimeOfDay"
/ abstractSpatialTypeName [ concreteSpatialTypeName ]
)
abstractSpatialTypeName = %s"Geography"
/ %s"Geometry"
concreteSpatialTypeName = %s"Collection"
/ %s"LineString"
/ %s"MultiLineString"
/ %s"MultiPoint"
/ %s"MultiPolygon"
/ %s"Point"
/ %s"Polygon"
primitiveProperty = primitiveKeyProperty / primitiveNonKeyProperty
primitiveKeyProperty = odataIdentifier
primitiveNonKeyProperty = odataIdentifier
primitiveColProperty = odataIdentifier
complexProperty = odataIdentifier
complexColProperty = odataIdentifier
streamProperty = odataIdentifier
navigationProperty = entityNavigationProperty / entityColNavigationProperty
entityNavigationProperty = odataIdentifier
entityColNavigationProperty = odataIdentifier
action = odataIdentifier
actionImport = odataIdentifier
function = entityFunction
/ entityColFunction
/ complexFunction
/ complexColFunction
/ primitiveFunction
/ primitiveColFunction
entityFunction = odataIdentifier
entityColFunction = odataIdentifier
complexFunction = odataIdentifier
complexColFunction = odataIdentifier
primitiveFunction = odataIdentifier
primitiveColFunction = odataIdentifier
entityFunctionImport = odataIdentifier
entityColFunctionImport = odataIdentifier
complexFunctionImport = odataIdentifier
complexColFunctionImport = odataIdentifier
primitiveFunctionImport = odataIdentifier
primitiveColFunctionImport = odataIdentifier
;------------------------------------------------------------------------------
; 7. Literal Data Values
;------------------------------------------------------------------------------
; in URLs
primitiveLiteral = nullValue ; plain values up to int64Value
/ booleanValue
/ guidValue
/ dateTimeOffsetValueInUrl
/ dateValue
/ timeOfDayValueInUrl
/ decimalValue
/ doubleValue
/ singleValue
/ sbyteValue
/ byteValue
/ int16Value
/ int32Value
/ int64Value
/ string ; single-quoted
/ duration
/ enum
/ binary ; all others are quoted and prefixed
/ geographyCollection
/ geographyLineString
/ geographyMultiLineString
/ geographyMultiPoint
/ geographyMultiPolygon
/ geographyPoint
/ geographyPolygon
/ geometryCollection
/ geometryLineString
/ geometryMultiLineString
/ geometryMultiPoint
/ geometryMultiPolygon
/ geometryPoint
/ geometryPolygon
; in Atom and JSON message bodies and CSDL DefaultValue attributes
primitiveValue = booleanValue
/ guidValue
/ durationValue
/ dateTimeOffsetValue
/ dateValue
/ timeOfDayValue
/ enumValue
/ fullCollectionLiteral
/ fullLineStringLiteral
/ fullMultiPointLiteral
/ fullMultiLineStringLiteral
/ fullMultiPolygonLiteral
/ fullPointLiteral
/ fullPolygonLiteral
/ decimalValue
/ doubleValue
/ singleValue
/ sbyteValue
/ byteValue
/ int16Value
/ int32Value
/ int64Value
/ binaryValue
; also valid are:
; - any XML string for strings in Atom and CSDL documents
; - any JSON string for JSON documents
nullValue = %s"null"
; base64url encoding according to http://tools.ietf.org/html/rfc4648#section-5
binary = "binary" SQUOTE binaryValue SQUOTE
binaryValue = *(4base64char) [ base64b16 / base64b8 ]
base64b16 = 2base64char ( %s"A" / %s"E" / %s"I" / %s"M" / %s"Q" / %s"U" / %s"Y" / %s"c" / %s"g" / %s"k" / %s"o" / %s"s" / %s"w" / %s"0" / %s"4" / %s"8" ) [ "=" ]
base64b8 = base64char ( %s"A" / %s"Q" / %s"g" / %s"w" ) [ "==" ]
base64char = ALPHA / DIGIT / "-" / "_"
booleanValue = "true" / "false"
decimalValue = [ SIGN ] 1*DIGIT [ "." 1*DIGIT ] [ "e" [ SIGN ] 1*DIGIT ] / nanInfinity
doubleValue = decimalValue ; IEEE 754 binary64 floating-point number (15-17 decimal digits)
singleValue = decimalValue ; IEEE 754 binary32 floating-point number (6-9 decimal digits)
nanInfinity = %s"NaN" / %s"-INF" / %s"INF"
guidValue = 8HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 12HEXDIG
byteValue = 1*3DIGIT ; numbers in the range from 0 to 255
sbyteValue = [ SIGN ] 1*3DIGIT ; numbers in the range from -128 to 127
int16Value = [ SIGN ] 1*5DIGIT ; numbers in the range from -32768 to 32767
int32Value = [ SIGN ] 1*10DIGIT ; numbers in the range from -2147483648 to 2147483647
int64Value = [ SIGN ] 1*19DIGIT ; numbers in the range from -9223372036854775808 to 9223372036854775807
string = SQUOTE *( SQUOTE-in-string / pchar-no-SQUOTE ) SQUOTE
SQUOTE-in-string = SQUOTE SQUOTE ; two consecutive single quotes represent one within a string literal
dateValue = year "-" month "-" day
dateTimeOffsetValue = year "-" month "-" day "T" timeOfDayValue ( "Z" / SIGN hour ":" minute )
dateTimeOffsetValueInUrl = year "-" month "-" day "T" timeOfDayValueInUrl ( "Z" / SIGN hour COLON minute )
duration = [ "duration" ] SQUOTE durationValue SQUOTE
durationValue = [ SIGN ] "P" [ 1*DIGIT "D" ] [ "T" [ 1*DIGIT "H" ] [ 1*DIGIT "M" ] [ 1*DIGIT [ "." 1*DIGIT ] "S" ] ]
; the above is an approximation of the rules for an xml dayTimeDuration.
; see the lexical representation for dayTimeDuration in http://www.w3.org/TR/xmlschema11-2#dayTimeDuration for more information
timeOfDayValue = hour ":" minute [ ":" second [ "." fractionalSeconds ] ]
timeOfDayValueInUrl = hour COLON minute [ COLON second [ "." fractionalSeconds ] ]
oneToNine = "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9"
zeroToFiftyNine = ( "0" / "1" / "2" / "3" / "4" / "5" ) DIGIT
year = [ "-" ] ( "0" 3DIGIT / oneToNine 3*DIGIT )
month = "0" oneToNine
/ "1" ( "0" / "1" / "2" )
day = "0" oneToNine
/ ( "1" / "2" ) DIGIT
/ "3" ( "0" / "1" )
hour = ( "0" / "1" ) DIGIT
/ "2" ( "0" / "1" / "2" / "3" )
minute = zeroToFiftyNine
second = zeroToFiftyNine / "60" ; for leap seconds
fractionalSeconds = 1*12DIGIT
enum = [ qualifiedEnumTypeName ] SQUOTE enumValue SQUOTE
enumValue = singleEnumValue *( COMMA singleEnumValue )
singleEnumValue = enumerationMember / enumMemberValue
enumMemberValue = int64Value
geographyCollection = geographyPrefix SQUOTE fullCollectionLiteral SQUOTE
fullCollectionLiteral = sridLiteral collectionLiteral
collectionLiteral = "Collection(" geoLiteral *( COMMA geoLiteral ) CLOSE
geoLiteral = collectionLiteral
/ lineStringLiteral
/ multiPointLiteral
/ multiLineStringLiteral
/ multiPolygonLiteral
/ pointLiteral
/ polygonLiteral
geographyLineString = geographyPrefix SQUOTE fullLineStringLiteral SQUOTE
fullLineStringLiteral = sridLiteral lineStringLiteral
lineStringLiteral = "LineString" lineStringData
lineStringData = OPEN positionLiteral 1*( COMMA positionLiteral ) CLOSE
geographyMultiLineString = geographyPrefix SQUOTE fullMultiLineStringLiteral SQUOTE
fullMultiLineStringLiteral = sridLiteral multiLineStringLiteral
multiLineStringLiteral = "MultiLineString(" [ lineStringData *( COMMA lineStringData ) ] CLOSE
geographyMultiPoint = geographyPrefix SQUOTE fullMultiPointLiteral SQUOTE
fullMultiPointLiteral = sridLiteral multiPointLiteral
multiPointLiteral = "MultiPoint(" [ pointData *( COMMA pointData ) ] CLOSE
geographyMultiPolygon = geographyPrefix SQUOTE fullMultiPolygonLiteral SQUOTE
fullMultiPolygonLiteral = sridLiteral multiPolygonLiteral
multiPolygonLiteral = "MultiPolygon(" [ polygonData *( COMMA polygonData ) ] CLOSE
geographyPoint = geographyPrefix SQUOTE fullPointLiteral SQUOTE
fullPointLiteral = sridLiteral pointLiteral
sridLiteral = "SRID" EQ 1*5DIGIT SEMI
pointLiteral ="Point" pointData
pointData = OPEN positionLiteral CLOSE
positionLiteral = doubleValue SP doubleValue [ SP doubleValue ] [ SP doubleValue ] ; longitude, latitude, altitude/elevation (optional), linear referencing measure (optional)
geographyPolygon = geographyPrefix SQUOTE fullPolygonLiteral SQUOTE
fullPolygonLiteral = sridLiteral polygonLiteral
polygonLiteral = "Polygon" polygonData
polygonData = OPEN ringLiteral *( COMMA ringLiteral ) CLOSE
ringLiteral = OPEN positionLiteral *( COMMA positionLiteral ) CLOSE
; Within each ringLiteral, the first and last positionLiteral elements MUST be an exact syntactic match to each other.
; Within the polygonData, the ringLiterals MUST specify their points in appropriate winding order.
; In order of traversal, points to the left side of the ring are interpreted as being in the polygon.
geometryCollection = geometryPrefix SQUOTE fullCollectionLiteral SQUOTE
geometryLineString = geometryPrefix SQUOTE fullLineStringLiteral SQUOTE
geometryMultiLineString = geometryPrefix SQUOTE fullMultiLineStringLiteral SQUOTE
geometryMultiPoint = geometryPrefix SQUOTE fullMultiPointLiteral SQUOTE
geometryMultiPolygon = geometryPrefix SQUOTE fullMultiPolygonLiteral SQUOTE
geometryPoint = geometryPrefix SQUOTE fullPointLiteral SQUOTE
geometryPolygon = geometryPrefix SQUOTE fullPolygonLiteral SQUOTE
geographyPrefix = "geography"
geometryPrefix = "geometry"
;------------------------------------------------------------------------------
; 8. Header values
;------------------------------------------------------------------------------
header = content-id
/ isolation
/ odata-entityid
/ odata-error
/ odata-maxversion
/ odata-version
/ prefer
content-id = "Content-ID" ":" OWS request-id
isolation = [ "OData-" ] "Isolation" ":" OWS "snapshot"
request-id = 1*unreserved
odata-entityid = "OData-EntityID" ":" OWS IRI-in-header
; Note: the header value is a JSON object restricted to characters allowed in a header
odata-error = "OData-Error" ":" OWS "{" DQUOTE %s"code" DQUOTE ":" *( VCHAR / SP )
odata-maxversion = "OData-MaxVersion" ":" OWS 1*DIGIT "." 1*DIGIT
odata-version = "OData-Version" ":" OWS "4.0" [ oneToNine ]
prefer = "Prefer" ":" OWS preference *( OWS "," OWS preference )
preference = allowEntityReferencesPreference
/ callbackPreference
/ continueOnErrorPreference
/ includeAnnotationsPreference
/ maxpagesizePreference
/ omitValuesPreference
/ respondAsyncPreference
/ returnPreference
/ trackChangesPreference
/ waitPreference
; and everything allowed by https://tools.ietf.org/html/rfc7240
; / ( parameter / token ) *( OWS ";" [ OWS ( parameter / token ) ] )
allowEntityReferencesPreference = [ "odata." ] "allow-entityreferences"
callbackPreference = [ "odata." ] "callback" OWS ";" OWS "url" EQ-h DQUOTE URI DQUOTE
continueOnErrorPreference = [ "odata." ] "continue-on-error" [ EQ-h booleanValue ]
includeAnnotationsPreference = [ "odata." ] "include-annotations" EQ-h DQUOTE annotationsList DQUOTE
annotationsList = annotationIdentifier *("," annotationIdentifier)
annotationIdentifier = [ excludeOperator ]
( STAR
/ namespace "." ( termName / STAR )
)
[ "#" odataIdentifier ]
excludeOperator = "-"
maxpagesizePreference = [ "odata."