Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow cycles #19

Draft
wants to merge 147 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
147 commits
Select commit Hold shift + click to select a range
5d66d4d
Adapt terminology to the multi-parent case
HeikoTheissen May 19, 2023
09e9929
Avoid the word tree
HeikoTheissen May 23, 2023
23d69c8
Root means zero parents
HeikoTheissen May 23, 2023
890b53b
Subhierarchies have different roots.
HeikoTheissen May 23, 2023
02179ca
Allow for orphans
HeikoTheissen May 23, 2023
b097c0a
Island orphans
HeikoTheissen May 23, 2023
26d9806
Merge remote-tracking branch 'trial/main' into multiple-parents
HeikoTheissen May 25, 2023
36323cc
Errors in JSON code
HeikoTheissen May 25, 2023
8ee987e
style change
HeikoTheissen May 25, 2023
59cbfd9
Variable clean-up
HeikoTheissen May 25, 2023
884e089
CSDL-XML-Link
HeikoTheissen May 25, 2023
3ec3059
Non-standard roots
HeikoTheissen May 25, 2023
125b493
Avoid overlong line
HeikoTheissen May 25, 2023
ec3f3e0
First three parts (#11)
ralfhandl May 25, 2023
802159d
Merge branch 'tc/2023-05-31' of [email protected]:standardapi/odata-spec…
HeikoTheissen May 25, 2023
51d8798
Hierarchy maintenance (#7)
HeikoTheissen May 26, 2023
25ce482
Merge branch 'multiple-parents' of [email protected]:standardapi/odata-s…
HeikoTheissen May 26, 2023
9acc7b3
fine-tuning
HeikoTheissen May 26, 2023
b4ae6d9
fine-tuning
HeikoTheissen May 26, 2023
b6c2eba
extended example 109
HeikoTheissen May 26, 2023
e193e06
corrected example 109
HeikoTheissen May 26, 2023
d771974
rephrased
HeikoTheissen May 26, 2023
416ca06
replace @odata.type with @type etc.
HeikoTheissen May 26, 2023
a60efb9
indentation
HeikoTheissen May 26, 2023
6de8c2e
typos
HeikoTheissen May 26, 2023
c42f5ed
TC 2023-05-31 - additions Ralf (#12)
ralfhandl May 26, 2023
b810924
Merge branch 'tc/2023-05-31' of [email protected]:standardapi/odata-spec…
HeikoTheissen May 26, 2023
1b5da52
References in variable list
HeikoTheissen May 26, 2023
e3e8ebb
Sharpen ancestors definition
HeikoTheissen May 26, 2023
b68f856
Merge remote-tracking branch 'trial/tc/2023-05-31' into multiple-parents
HeikoTheissen May 26, 2023
1aabf22
@odata.id -> @id
HeikoTheissen May 26, 2023
79cf020
indentation
HeikoTheissen May 26, 2023
a2a1331
indentation
HeikoTheissen May 26, 2023
6f87a7f
@ralfhandl's suggestions
HeikoTheissen May 31, 2023
91f5c68
RH 2023-05-31 part 3 (#13)
ralfhandl May 31, 2023
95f4422
For each occurrence
HeikoTheissen May 31, 2023
0c42441
Merge remote-tracking branch 'trial/tc/2023-05-31' into multiple-parents
HeikoTheissen May 31, 2023
5575a69
Explicitly mention other values of M
HeikoTheissen May 31, 2023
bcc7d8e
example for non-standard root
HeikoTheissen May 31, 2023
5f193b0
Remove Phobos South Pole
HeikoTheissen May 31, 2023
657210b
Preserving -> subset, precedence -> order
HeikoTheissen May 31, 2023
50ba8ae
Merge remote-tracking branch 'trial/tc/2023-05-31' into multiple-parents
HeikoTheissen May 31, 2023
fa6a5c7
Merge remote-tracking branch 'trial/main' into multiple-parents
HeikoTheissen May 31, 2023
ba37eff
post-merge
HeikoTheissen May 31, 2023
96e7cdf
typo
HeikoTheissen Jun 1, 2023
eeb6315
@GEricson's suggestion
HeikoTheissen Jun 1, 2023
194c896
Merge remote-tracking branch 'origin/main' into tc/2023-06-07
HeikoTheissen Jun 1, 2023
ff9cbd4
fine-tuning
HeikoTheissen Jun 1, 2023
3c43afd
AvailableOnAggregates
HeikoTheissen Jun 1, 2023
34b0fc2
More detailed revision history
HeikoTheissen Jun 1, 2023
30b0245
Include branch in title
HeikoTheissen Jun 1, 2023
c326f31
Remove redundant statement in `concat`
HeikoTheissen Jun 1, 2023
d793461
@sthagen's suggestion
HeikoTheissen Jun 1, 2023
1109928
fine-tuning
HeikoTheissen Jun 1, 2023
5ca0800
Merge remote-tracking branch 'origin/main' into tc/2023-06-07
HeikoTheissen Jun 1, 2023
afc6b51
@GeraldKrause's suggestions
HeikoTheissen Jun 1, 2023
ee685b3
Merge remote-tracking branch 'origin/main' into multiple-parents
HeikoTheissen Jun 1, 2023
30876fd
Merge remote-tracking branch 'origin/tc/2023-06-07' into
HeikoTheissen Jun 1, 2023
5c93574
post-merge
HeikoTheissen Jun 1, 2023
fce3cc6
Merge remote-tracking branch 'origin/main' into tc/2023-06-07
HeikoTheissen Jun 2, 2023
972d730
Merge remote-tracking branch 'origin/main' into tc/2023-06-07
HeikoTheissen Jun 2, 2023
6f7664c
Merge remote-tracking branch 'origin/main' into tc/2023-06-07
HeikoTheissen Jun 2, 2023
ab570b1
Merge branch 'main' of [email protected]:oasis-tcs/odata-specs.git into
HeikoTheissen Jun 2, 2023
a0c741d
Add reference for $filter=AbsentProperty eq null
HeikoTheissen Jun 2, 2023
716c74c
Merge remote-tracking branch 'origin/tc/2023-06-07' into
HeikoTheissen Jun 2, 2023
efd545c
Allow cycles
HeikoTheissen Jun 2, 2023
34110aa
@GeraldKrause's suggestions
HeikoTheissen Jun 3, 2023
6ea1764
Merge remote-tracking branch 'origin/main' into tc/2023-06-07
HeikoTheissen Jun 3, 2023
aa82a52
Merge remote-tracking branch 'origin/tc/2023-06-07' into
HeikoTheissen Jun 3, 2023
9ee946a
typos
HeikoTheissen Jun 3, 2023
9548d3a
Distance
HeikoTheissen Jun 3, 2023
94fb9fb
@GeraldKrause's suggestions
HeikoTheissen Jun 5, 2023
bc67562
Fine-tuning
HeikoTheissen Jun 5, 2023
f3436aa
typo
HeikoTheissen Jun 5, 2023
8bf6f07
Merge remote-tracking branch 'origin/main' into tc/2023-06-07
HeikoTheissen Jun 5, 2023
e5f4f46
@GeraldKrause - MON
HeikoTheissen Jun 6, 2023
927a7f4
Avoid page break in example data
HeikoTheissen Jun 6, 2023
e767d61
Trigger a PDF generation via GitHub Actions
HeikoTheissen Jun 6, 2023
87fad4b
auto-refreshed
HeikoTheissen Jun 6, 2023
e665708
re-phrasing
HeikoTheissen Jun 6, 2023
377d7cf
typo
HeikoTheissen Jun 6, 2023
e8dd8af
Examples 64 and 65
HeikoTheissen Jun 6, 2023
ae77df0
Merge remote-tracking branch 'origin/tc/2023-06-07' into
HeikoTheissen Jun 6, 2023
adbcf4d
Orphan example
HeikoTheissen Jun 6, 2023
90a1683
Merge remote-tracking branch 'origin/tc/2023-06-07' into
HeikoTheissen Jun 7, 2023
35d7160
@ralfhandl's suggestions
HeikoTheissen Jun 7, 2023
0b20c59
Example 64 rephrased
HeikoTheissen Jun 7, 2023
1709099
fine-tuning
HeikoTheissen Jun 7, 2023
d5b37f3
Merge remote-tracking branch 'origin/main' into tc/2023-06-07
HeikoTheissen Jun 7, 2023
8907fc1
Improve test
HeikoTheissen Jun 7, 2023
92c6ef9
Merge remote-tracking branch 'origin/tc/2023-06-07' into
HeikoTheissen Jun 7, 2023
ed8d26e
Root node <> start node
HeikoTheissen Jun 7, 2023
1664403
Rephrased
HeikoTheissen Jun 7, 2023
37211e1
Merge branch 'tc/2023-06-14' into multiple-parents
HeikoTheissen Jun 7, 2023
803574c
TC 2023-06-14
HeikoTheissen Jun 7, 2023
7e64005
Merge branch 'tc/2023-06-14' into multiple-parents
HeikoTheissen Jun 7, 2023
d42c8f7
Merge branch 'tc/2023-06-14' into multiple-parents
HeikoTheissen Jun 7, 2023
b278ada
Post-merge
HeikoTheissen Jun 7, 2023
db36e2c
No page-break after heading
HeikoTheissen Jun 12, 2023
a6d9035
Recursive hierarchy = parent + start nodes
HeikoTheissen Jun 12, 2023
bc60aeb
UpNode, actual and visible totals
HeikoTheissen Jun 13, 2023
7364668
rephrasing
HeikoTheissen Jun 13, 2023
15329e5
Move actual vs. visual example
HeikoTheissen Jun 14, 2023
59feb92
UpNode -> UpPath
HeikoTheissen Jun 14, 2023
3fb52d4
rephrasing
HeikoTheissen Jun 14, 2023
85c61b5
@ralfhandl's suggestions
HeikoTheissen Jun 14, 2023
6a5e2b5
descendants/ancestors with maximum distance
HeikoTheissen Jun 15, 2023
96d4a2b
Rephrase lib/README.md
HeikoTheissen Jun 15, 2023
c34e9d4
rephrasing
HeikoTheissen Jun 15, 2023
954caf5
Avoid // in web server
HeikoTheissen Jun 15, 2023
807ddb4
Cycle without UpNode is possible
HeikoTheissen Jun 15, 2023
beae7ad
Prohibit term casts in aggregatable expressions
HeikoTheissen Jun 15, 2023
6758209
SHOULD -> MAY
HeikoTheissen Jun 15, 2023
86e83fd
Remove redundancy
HeikoTheissen Jun 16, 2023
4eca918
Remark about start nodes of H'
HeikoTheissen Jun 16, 2023
318b8bd
Hierarchical parameter p
HeikoTheissen Jun 16, 2023
f7cad3a
Merge remote-tracking branch 'origin/tc/2023-06-14' into
HeikoTheissen Jun 16, 2023
ab004bd
missing Nullable
HeikoTheissen Jun 16, 2023
d6bb2f7
Discussion with SADL
HeikoTheissen Jun 19, 2023
f717376
POST multiple parents
HeikoTheissen Jun 19, 2023
44d247f
Avoid referential constraint in example 119
HeikoTheissen Jun 19, 2023
774307d
Rephrased
HeikoTheissen Jun 19, 2023
1b3e754
Merge remote-tracking branch 'origin/main' into multiple-parents
HeikoTheissen Jun 19, 2023
383a22d
PDF generation
invalid-email-address Jun 19, 2023
b502c4a
Example 119
HeikoTheissen Jun 20, 2023
bbb0844
Merge remote-tracking branch 'origin/main' into tc/2023-06-14
HeikoTheissen Jun 20, 2023
be61d82
Merge remote-tracking branch 'origin/tc/2023-06-14' into multiple-par…
HeikoTheissen Jun 20, 2023
040baa8
Merge branch 'multiple-parents' of [email protected]:oasis-tcs/odata-spe…
HeikoTheissen Jun 20, 2023
c1d3a62
Definition of root node
HeikoTheissen Jun 20, 2023
4aee568
Multiple parents with weights
HeikoTheissen Jun 21, 2023
e1c2873
Make root
HeikoTheissen Jun 21, 2023
6ae33b8
last-minute changes
HeikoTheissen Jun 21, 2023
3af5f99
Merge remote-tracking branch 'origin/main' into multiple-parents
HeikoTheissen Jun 22, 2023
0eab13d
Simplify `rolluprecursive` (#18)
HeikoTheissen Jun 23, 2023
ad05bc3
As discussed with @GeraldKrause
HeikoTheissen Jun 23, 2023
338063b
Define orphans only in connection with traverse (general case)
HeikoTheissen Jun 26, 2023
d1d73a9
@GeraldKrause's suggestions
HeikoTheissen Jun 26, 2023
70c068f
rephrased node identifier
HeikoTheissen Jun 26, 2023
159815a
rephrased again
HeikoTheissen Jun 26, 2023
16f9de2
@ThomasChadzelek's correction
HeikoTheissen Jun 26, 2023
eb1ddda
Remove redundancy from recursive hierarchy definition
HeikoTheissen Jun 27, 2023
9210ad6
Remove informative reference
HeikoTheissen Jun 27, 2023
bb5b3ee
Node identifier and parents for non-nodes are arbitrary
HeikoTheissen Jun 27, 2023
305c6f8
last-minute changes
HeikoTheissen Jun 28, 2023
17c2446
As discussed with @Hubert-Heijkers
HeikoTheissen Jun 28, 2023
c8a8fe0
Disallow cycles
HeikoTheissen Jun 28, 2023
e00013b
Re-allow cycles
HeikoTheissen Jun 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,963 changes: 1,126 additions & 837 deletions docs/odata-data-aggregation-ext/odata-data-aggregation-ext.html

Large diffs are not rendered by default.

667 changes: 497 additions & 170 deletions docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions docs/odata-data-aggregation-ext/styles/odata.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@ a:target {
}

a[href^="#OData"],
a[href^="#RFC"] {
a[href^="#RFC"],
a[href^="#SQL"] {
font-weight: bold;
}

a[href^="#OData"]::before,
a[href^="#RFC"]::before {
a[href^="#RFC"]::before,
a[href^="#SQL"]::before {
content: "[";
font-weight: bold;
}

a[href^="#OData"]::after,
a[href^="#RFC"]::after {
a[href^="#RFC"]::after,
a[href^="#SQL"]::after {
content: "]";
font-weight: bold;
}
Expand Down
3 changes: 2 additions & 1 deletion odata-data-aggregation-ext/1 Introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This specification adds aggregation functionality to the Open Data Protocol (ODa
### ##subsubsec Definitions of Terms

This specification defines the following terms:
- <a name="AggregatableExpression">_Aggregatable Expression_</a> – an [expression](#Expression) resulting in a value of an [aggregatable primitive type](#AggregatablePrimitiveType)
- <a name="AggregatableExpression">_Aggregatable Expression_</a> – an [expression](#Expression) not involving term casts and resulting in a value of a complex or entity or an [aggregatable primitive type](#AggregatablePrimitiveType)
- <a name="AggregateExpression">_Aggregate Expression_</a> – argument of the `aggregate` [transformation](#Transformationaggregate) or [function](#Functionaggregate) defined in [section ##AggregationAlgorithm]
- <a name="AggregatablePrimitiveType">_Aggregatable Primitive Type_</a> – a primitive type other than `Edm.Stream` or subtypes of `Edm.Geography` or `Edm.Geometry`
- <a name="DataAggregationPath">_Data Aggregation Path_</a> – a path that consists of one or more segments joined together by forward slashes (`/`). Segments are names of declared or dynamic structural or navigation properties, or type-cast segments consisting of the (optionally qualified) name of a structured type that is derived from the type identified by the preceding path segment to reach properties declared by the derived type.
Expand All @@ -24,6 +24,7 @@ This specification defines the following terms:
The following non-exhaustive list contains variable names that are used throughout this document:
- $A,B,C$ – collections of instances
- $H$ – hierarchical collection
- $H'$ – subset of nodes from a hierarchical collection
- $u,v,w$ – instances in a collection
- $x$ – an instance in a hierarchical collection, called a node
- $p,q,r$ – paths
Expand Down
2 changes: 1 addition & 1 deletion odata-data-aggregation-ext/3.2 Basic Aggregation.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The property is a dynamic property, except for a special case in type 4. In type
_Types of aggregate expressions:_
1. A path $p=p_1$ or $p=p_1/p_2$ where the last segment of $p_1$ has a complex or entity or [aggregatable primitive type](#AggregatablePrimitiveType) whose values can be aggregated using the specified [aggregation method](#AggregationMethods) $g$, or $p=p_2$ if the input set can be aggregated using the [custom aggregation method](#CustomAggregationMethods) $g$.
Let $f(A)=g(A)$.
2. An [aggregatable expression](#AggregatableExpression).
2. An [aggregatable expression](#AggregatableExpression) whose values can be aggregated using the specified [aggregation method](#AggregationMethods) $g$.
Let $f(A)=g(B)$ where $B$ is the collection consisting of the values of the aggregatable expression evaluated relative to [each occurrence](#SamenessandOrder) in $A$ with null values removed from $B$. In this type, $p$ is absent.
3. A path $p/{\tt\$count}$ (see [section ##AggregateExpressioncount]) with optional prefix $p/{}$ where $p=p_1$ or $p=p_2$ or $p=p_1/p_2$.
Let $f(A)$ be the [cardinality](#SamenessandOrder) of $A$.
Expand Down
80 changes: 44 additions & 36 deletions odata-data-aggregation-ext/5 Vocabulary for Data Aggregation.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,39 +174,47 @@ The term `LeveledHierarchy` MUST be applied with a qualifier that can be used to

### ##subsubsec Recursive Hierarchy

A recursive hierarchy organizes entities of a collection as nodes of one or more tree structures. This structure does not need to be as uniform as a leveled hierarchy. It is described by a complex term `RecursiveHierarchy` with these properties:
- The `NodeProperty` allows identifying a node in the hierarchy. It MUST be a path with single-valued segments ending in a primitive property.
- The `ParentNavigationProperty` allows navigation to the instance or instances representing the parent nodes. It MUST be a collection-valued or nullable single-valued navigation property path that addresses the entity type annotated with this term. Nodes MUST NOT form cycles when following parent navigation properties.
A recursive hierarchy is defined on a collection of entities by
- determining which entities are part of the hierarchy and giving every such entity a single primitive non-null value that uniquely identifies it within the hierarchy. These entities are called _nodes_, and the primitive value is called the _node identifier_, and
- associating with every node zero or more nodes from the same collection, called its _parent nodes_.

The term `RecursiveHierarchy` can only be applied to entity types, and MUST be applied with a qualifier, which is used to reference the hierarchy in transformations operating on recursive hierarchies, in [grouping with `rolluprecursive`](#Groupingwithrolluprecursive), and in [hierarchy functions](#HierarchyFunctions).
The recursive hierarchy is described in the model by an annotation of the entity type with the complex term `RecursiveHierarchy` with these properties:
- The `NodeProperty` MUST be a path with single-valued segments ending in a primitive property. This property holds the node identifier of an entity that is a node in the hierarchy.
- The `ParentNavigationProperty` MUST be a collection-valued or nullable single-valued navigation property path that addresses the entity type annotated with this term. It navigates from an entity that is a node in the hierarchy to its parent nodes.

A _node_ is an instance of an entity type annotated with `RecursiveHierarchy`. It may have a _parent node_ that is the instance reached via the `ParentNavigationProperty`. A _recursive hierarchy_ is a collection of such nodes with unique node identifiers.
The term `RecursiveHierarchy` can only be applied to entity types, and MUST be applied with a qualifier, which is used to reference the hierarchy in transformations operating on recursive hierarchies, in [grouping with `rolluprecursive`](#Groupingwithrolluprecursive), and in [hierarchy functions](#HierarchyFunctions). The same entity can serve as nodes in different recursive hierarchies, given different qualifiers.

A node without parent node is a _root node_, a node is a _child node_ of its parent node, a node without child nodes is a _leaf node_. Nodes with the same parent node are _sibling nodes_ and so are root nodes. The _descendants_ of a node are its child nodes, their child nodes, and so on, up to and including all leaf nodes that can be reached. A node together with its descendants forms a _sub-hierarchy_ of the hierarchy. The _ancestors_ of a node are its parent node, the parent of its parent node, and so on, up to and including a root node that can be reached. A recursive hierarchy can have one or more root nodes.
A _root node_ is a node without parent nodes. A recursive hierarchy can have one or more root nodes. A node is a _child node_ of its parent nodes, a node without child nodes is a _leaf node_. Two nodes with a common parent node are _sibling nodes_ and so are two root nodes.

The term `UpNode` can be used in hierarchical result sets to associate with each instance one of its ancestors, which is again annotated with `UpNode` and so on until a path to the root is constructed.
The _descendants with maximum distance $d≥1$_ of a node are its child nodes and, if $d>1$, the descendants of these child nodes with maximum distance $d-1$. The _descendants_ are the descendants with maximum distance $d=∞$. A node together with its descendants forms a _sub-hierarchy_ of the hierarchy.

The _ancestors with maximum distance $d≥1$_ of a node are its parent nodes and, if $d>1$, the ancestors of these parent nodes with maximum distance $d-1$. The _ancestors_ are the ancestors with maximum distance $d=∞$.

The term `UpPath` can be used in hierarchical result sets to associate with each instance one of its ancestors, one ancestor of that ancestor and so on. The term `Cycle` is used to tag instances in hierarchical result sets that are their own ancestor and therefore part of a _cycle_. These instance annotations are introduced in [section ##Transformationtraverse].

#### ##subsubsubsec Hierarchy Functions

For testing the position of a given entity in a recursive hierarchy, the Aggregation vocabulary [OData-VocAggr](#ODataVocAggr) defines unbound functions. These have
- a parameter pair `HierarchyNodes`, `HierarchyQualifier` where `HierarchyNodes` is a collection and `HierarchyQualifier` is the qualifier of a `RecursiveHierarchy` annotation on its common entity type. The node identifiers in this collection define the recursive hierarchy.
- a parameter `Node` that contains the node identifier of the entity to be tested. Note that the test result depends only on this node identifier, not on any other property of the given entity
- additional parameters, depending on the type of test (see below).
- additional parameters, depending on the type of test (see below)
- a Boolean return value for the outcome of the test.

The following functions are defined:
- `isroot` tests if the given entity is a root of the hierarchy
- `isdescendant` tests if the given entity is a descendant of an ancestor node (whose node identifier is given in a parameter `Ancestor`) with a maximum distance `MaxDistance`, or equals the ancestor if `IncludeSelf` is true
- `isancestor` tests if the given entity is an ancestor of a descendant node (whose node identifier is given in a parameter `Descendant`) with a maximum distance `MaxDistance`, or equals the descendant if `IncludeSelf` is true
- `issibling` tests if the given entity and another entity (whose node identifier is given in a parameter `Other`) have the same parent node or both are roots, but are not the same
- `isleaf` tests if the given entity is without descendants.
- `isroot` tests if the given entity is a root node of the hierarchy.
- `isdescendant` tests if the given entity is a descendant with maximum distance `MaxDistance` of an ancestor node (whose node identifier is given in a parameter `Ancestor`), or equals the ancestor if `IncludeSelf` is true.
- `isancestor` tests if the given entity is an ancestor with maximum distance `MaxDistance` of a descendant node (whose node identifier is given in a parameter `Descendant`), or equals the descendant if `IncludeSelf` is true.
- `issibling` tests if the given entity and another entity (whose node identifier is given in a parameter `Other`) are sibling nodes.
- `isleaf` tests if the given entity is a leaf node.

Another function `rollupnode` is defined that can only be used in connection with [`rolluprecursive`](#Groupingwithrolluprecursive).

### ##subsubsec Hierarchy Examples

The hierarchy terms can be applied to the [Example Data Model](#ExampleDataModel).

::: example
Example ##ex: leveled hierarchies for products and time, and a recursive hierarchy for the sales organizations
Example ##ex: leveled hierarchies for products and time, and a recursive hierarchy for the sales organizations:
```xml
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
Version="4.0">
Expand All @@ -228,28 +236,28 @@ Example ##ex: leveled hierarchies for products and time, and a recursive hierarc
</Annotation>
</Annotations>

<Annotations Target="SalesModel.Time">
<Annotation Term="Aggregation.LeveledHierarchy"
Qualifier="TimeHierarchy">
<Collection>
<PropertyPath>Year</PropertyPath>
<PropertyPath>Quarter</PropertyPath>
<PropertyPath>Month</PropertyPath>
</Collection>
</Annotation>
</Annotations>

<Annotations Target="SalesModel.SalesOrganization">
<Annotation Term="Aggregation.RecursiveHierarchy"
Qualifier="SalesOrgHierarchy">
<Record>
<PropertyValue Property="NodeProperty"
PropertyPath="ID" />
<PropertyValue Property="ParentNavigationProperty"
PropertyPath="Superordinate" />
</Record>
</Annotation>
</Annotations>
<Annotations Target="SalesModel.Time">
<Annotation Term="Aggregation.LeveledHierarchy"
Qualifier="TimeHierarchy">
<Collection>
<PropertyPath>Year</PropertyPath>
<PropertyPath>Quarter</PropertyPath>
<PropertyPath>Month</PropertyPath>
</Collection>
</Annotation>
</Annotations>

<Annotations Target="SalesModel.SalesOrganization">
<Annotation Term="Aggregation.RecursiveHierarchy"
Qualifier="SalesOrgHierarchy">
<Record>
<PropertyValue Property="NodeProperty"
PropertyPath="ID" />
<PropertyValue Property="ParentNavigationProperty"
PropertyPath="Superordinate" />
</Record>
</Annotation>
</Annotations>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Expand Down
Loading