Let \(T\) be a transformation sequence, \(P_1\) stand in for zero or more property paths and \(P_2\) for zero or more rollup
or rolluprecursive
operators or property paths. The transformation \({\tt groupby}((P_1,{\tt rolluprecursive}(H,Q,p,S),P_2),T)\) is computed by the following algorithm, which invokes itself recursively if the number of rolluprecursive
operators in the first argument of the groupby
transformation, which is called \(M\), is greater than one. Let \(N\) be the recursion depth of the algorithm, starting with 1.
The rolluprecursive
algorithm:
A property \(χ_N\) appears in the algorithm, but is not present in the output set. It is explained later (see example 66). \(Z_N\) is a transformation whose output set is its input set with property \(χ_N\) removed.
-Let \(x_1,…,x_n\) be the nodes in \(H'\), possibly with repetitions. If the optional transformation sequence \(S\) ends with a traverse
transformation, as in example 118, the sequence \(x_1,…,x_n\) MUST have the preorder or postorder established by that traversal, otherwise its order is arbitrary. Then the transformation \({\tt groupby}((P_1,{\tt rolluprecursive}(H,Q,p,S),P_2),T)\) is defined as equivalent to \[{\tt concat}(R(x_1),…,R(x_n))\] with no order defined on the output set unless \(S\) ends with a traverse
transformation.
+Let \(x_1,…,x_n\) be the nodes in \(H'\), possibly with repetitions. If the optional transformation sequence \(S\) ends with a traverse
transformation, as in example 118, the sequence \(x_1,…,x_n\) MUST have the preorder or postorder established by that traversal, and the transformation \({\tt groupby}((P_1,{\tt rolluprecursive}(H,Q,p,S),P_2),T)\) is defined as equivalent to \[{\tt concat}(R(x_1),…,R(x_n)).\]
+Otherwise, if \(S\) is not specified or does not end with a traverse
transformation, the output set of the transformation \({\tt groupby}((P_1,{\tt rolluprecursive}(H,Q,p,S),P_2),T)\) is the concatenation of \(R(x_1),…,R(x_n)\). The order of occurrences from the same \(R(x_i)\) remains the same, and no order is defined between occurrences from different \(R(x_i)\) and \(R(x_j)\).
\(R(x)\) is a transformation that processes the entire sub-hierarchy rooted at \(x\), which is the output set of \(F(x)\). The output set of \(R(x)\) is a collection of aggregated instances for all rollup results.
-If at least one of \(P_1\) or \(P_2\) is non-empty, then \[R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/{\tt groupby}((P_1,P_2),T/Z_N/\Pi_G(σ(x)))\] with no order defined on the output set.
+If at least one of \(P_1\) or \(P_2\) is non-empty, then \[R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/{\tt groupby}((P_1,P_2),T/Z_N/\Pi_G(σ(x))).\]
The property \(χ_N=x\) is present during the evaluation of \(T\), but not afterwards. If \(P_2\) contains a rolluprecursive
operator, the evaluation of the formula involves a recursive invocation (with \(N\) increased by 1) of the rolluprecursive
algorithm.
-Otherwise if \(P_1\) and \(P_2\) are empty, then \[R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/T/Z_N/\Pi_G(σ(x))\] with no order defined on the output set.
+Otherwise if \(P_1\) and \(P_2\) are empty, then \[R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/T/Z_N/\Pi_G(σ(x)).\]
\(F(x)\) is defined as follows: If \(p\) contains only single-valued segments, then \[\matrix{ F(x)={\tt filter}(\hbox{\tt Aggregation.isdescendant}(\hfill\\ \quad {\tt HierarchyNodes}=H,\;{\tt HierarchyQualifier}=\hbox{\tt{'$Q$'}},\hfill\\ \quad {\tt Node}=p,\;{\tt Ancestor}=x[q],\;{\tt IncludeSelf}={\tt true})).\hfill }\]
Otherwise \(p=p_1/…/p_k/r\) with \(k≥1\) and \[\matrix{ F(x)={\tt filter}(\hfill\\ \hskip1pc p_1/{\tt any}(y_1:\hfill\\ \hskip2pc y_1/p_2/{\tt any}(y_2:\hfill\\ \hskip3pc ⋱\hfill\\ \hskip4pc y_{k-1}/p_k/{\tt any}(y_k:\hfill\\ \hskip5pc \hbox{\tt Aggregation.isdescendant}(\hfill\\ \hskip6pc {\tt HierarchyNodes}=H,\;{\tt HierarchyQualifier}=\hbox{\tt{'$Q$'}},\hfill\\ \hskip6pc {\tt Node}=y_k/r,\;{\tt Ancestor}=x[q],\;{\tt IncludeSelf}={\tt true}\hfill\\ \hskip5pc )\hfill\\ \hskip4pc )\hfill\\ \hskip3pc ⋰\hfill\\ \hskip2pc )\hfill\\ \hskip1pc )\hfill\\ )\hfill }\] where \(y_1,…,y_k\) denote lambdaVariableExpr
s and \({}/r\) may be absent. (See example 113 for a case with \(k=1\).)
Informatively speaking, the effect of the algorithm can be summarized as follows: If \(M≥1\) and \(\hat F_N(x)\) denotes the collection of all instances that are related to a node \(x\) as determined by \(F(x)\) in the recursive hierarchy of the \(N\)-th rolluprecursive
operator, then \(T\) is applied to each of the intersections of \(\hat F_1(χ_1),…,\hat F_M(χ_M)\), as \(χ_N\) runs over all nodes of the \(N\)-th recursive hierarchy for \(1≤N≤M\). Into the instances of the resulting output sets the \(\Pi_G\) transformations inject information about the nodes \(χ_1,…,χ_M\).
diff --git a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md
index c5c720c2..8fb6c9a7 100644
--- a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md
+++ b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md
@@ -82,7 +82,7 @@ When referencing this specification the following citation format should be used
**[OData-Data-Agg-v4.0]**
_OData Extension for Data Aggregation Version 4.0_.
-Edited by Ralf Handl, Hubert Heijkers, Gerald Krause, Michael Pizzo, Heiko Theißen, and Martin Zurmuehl. 28 June 2023. OASIS Committee Specification Draft 04.
+Edited by Ralf Handl, Hubert Heijkers, Gerald Krause, Michael Pizzo, Heiko Theißen, and Martin Zurmuehl. 28 June 2023. Committee Specification Draft 04.
https://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/csd04/odata-data-aggregation-ext-v4.0-csd04.html.
Latest stage: https://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/odata-data-aggregation-ext-v4.0.html.
@@ -2672,7 +2672,7 @@ Example 59: assume the product is an implicit input for a function bound to a co
The transformations and the `rolluprecursive` operator defined in this section are called hierarchical, because they make use of a recursive hierarchy and are defined in terms of hierarchy functions introduced in the previous section.
-With the exceptions of `traverse` and `rolluprecursive` whose fourth parameter ends with `traverse`, the hierarchical transformations do not define an order on the output set. An order can be reinstated by a subsequent `orderby` or `traverse` transformation or a `$orderby`.
+The transformations `ancestors` and `descendants` do not define an order on the output set. An order can be imposed by a subsequent `orderby` or `traverse` transformation or a `$orderby`. The output set of `traverse` is in preorder or postorder, and grouping with `rolluprecursive` orders its output set in analogy with [simple grouping](#SimpleGrouping).
The algorithmic descriptions of the transformations make use of a _union_ of collections, this is defined as an unordered collection containing the items from all these collections and from which duplicates have been removed.
@@ -2974,21 +2974,20 @@ _The `rolluprecursive` algorithm:_
A property $χ_N$ appears in the algorithm, but is not present in the output set. It is explained later (see [example 66](#rollupnode)). $Z_N$ is a transformation whose output set is its input set with property $χ_N$ removed.
-Let $x_1,…,x_n$ be the nodes in $H'$, possibly with repetitions. If the optional transformation sequence $S$ ends with a [`traverse`](#Transformationtraverse) transformation, as in [example 118](#weighted), the sequence $x_1,…,x_n$ MUST have the preorder or postorder established by that traversal, otherwise its order is arbitrary. Then the transformation ${\tt groupby}((P_1,{\tt rolluprecursive}(H,Q,p,S),P_2),T)$ is defined as equivalent to
-$${\tt concat}(R(x_1),…,R(x_n))$$
-with no order defined on the output set unless $S$ ends with a `traverse` transformation.
+Let $x_1,…,x_n$ be the nodes in $H'$, possibly with repetitions. If the optional transformation sequence $S$ ends with a [`traverse`](#Transformationtraverse) transformation, as in [example 118](#weighted), the sequence $x_1,…,x_n$ MUST have the preorder or postorder established by that traversal, and the transformation ${\tt groupby}((P_1,{\tt rolluprecursive}(H,Q,p,S),P_2),T)$ is defined as equivalent to
+$${\tt concat}(R(x_1),…,R(x_n)).$$
+
+Otherwise, if $S$ is not specified or does not end with a `traverse` transformation, the output set of the transformation ${\tt groupby}((P_1,{\tt rolluprecursive}(H,Q,p,S),P_2),T)$ is the concatenation of $R(x_1),…,R(x_n)$. The order of occurrences from the same $R(x_i)$ remains the same, and no order is defined between occurrences from different $R(x_i)$ and $R(x_j)$.
$R(x)$ is a transformation that processes the entire sub-hierarchy rooted at $x$, which is the output set of $F(x)$. The output set of $R(x)$ is a collection of aggregated instances for all rollup results.
If at least one of $P_1$ or $P_2$ is non-empty, then
-$$R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/{\tt groupby}((P_1,P_2),T/Z_N/\Pi_G(σ(x)))$$
-with no order defined on the output set.
+$$R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/{\tt groupby}((P_1,P_2),T/Z_N/\Pi_G(σ(x))).$$
The property $χ_N=x$ is present during the evaluation of $T$, but not afterwards. If $P_2$ contains a `rolluprecursive` operator, the evaluation of the formula involves a recursive invocation (with $N$ increased by 1) of the `rolluprecursive` algorithm.
Otherwise if $P_1$ and $P_2$ are empty, then
-$$R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/T/Z_N/\Pi_G(σ(x))$$
-with no order defined on the output set.
+$$R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/T/Z_N/\Pi_G(σ(x)).$$
$F(x)$ is defined as follows: If $p$ contains only single-valued segments, then
$$\matrix{ F(x)={\tt filter}(\hbox{\tt Aggregation.isdescendant}(\hfill\\ \quad {\tt HierarchyNodes}=H,\;{\tt HierarchyQualifier}=\hbox{\tt{'$Q$'}},\hfill\\ \quad {\tt Node}=p,\;{\tt Ancestor}=x[q],\;{\tt IncludeSelf}={\tt true})).\hfill }$$
diff --git a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.pdf b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.pdf
index 542bd733..8bf1df9c 100644
Binary files a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.pdf and b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.pdf differ
diff --git a/lib/server.js b/lib/server.js
index 19240508..797ec635 100644
--- a/lib/server.js
+++ b/lib/server.js
@@ -9,9 +9,10 @@ var app = express()
.get("/*", function (req, res, next) {
if (req.path.endsWith("/")) {
try {
- req.query["-T"] = execSync("git branch --show-current", {
+ var branch = execSync("git branch --show-current", {
cwd: __dirname,
}).toString();
+ if (branch) req.query["-T"] = branch;
} catch (e) {}
var dir = req.params[0].substring(0, req.params[0].length - 1);
try {
diff --git a/odata-data-aggregation-ext/0 frontmatter.md b/odata-data-aggregation-ext/0 frontmatter.md
index 5842c521..a93f01d7 100644
--- a/odata-data-aggregation-ext/0 frontmatter.md
+++ b/odata-data-aggregation-ext/0 frontmatter.md
@@ -82,7 +82,7 @@ When referencing this specification the following citation format should be used
**[OData-Data-Agg-v4.0]**
_$$$pagetitle$$$_.
-Edited by Ralf Handl, Hubert Heijkers, Gerald Krause, Michael Pizzo, Heiko Theißen, and Martin Zurmuehl. $$$pubdate$$$. OASIS Committee Specification Draft 04.
+Edited by Ralf Handl, Hubert Heijkers, Gerald Krause, Michael Pizzo, Heiko Theißen, and Martin Zurmuehl. $$$pubdate$$$. $$$subtitle$$$.
https://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/csd04/odata-data-aggregation-ext-v4.0-csd04.html.
Latest stage: https://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/odata-data-aggregation-ext-v4.0.html.
diff --git a/odata-data-aggregation-ext/6 Hierarchical Transformations.md b/odata-data-aggregation-ext/6 Hierarchical Transformations.md
index 631fe361..ec058e9a 100644
--- a/odata-data-aggregation-ext/6 Hierarchical Transformations.md
+++ b/odata-data-aggregation-ext/6 Hierarchical Transformations.md
@@ -4,7 +4,7 @@
The transformations and the `rolluprecursive` operator defined in this section are called hierarchical, because they make use of a recursive hierarchy and are defined in terms of hierarchy functions introduced in the previous section.
-With the exceptions of `traverse` and `rolluprecursive` whose fourth parameter ends with `traverse`, the hierarchical transformations do not define an order on the output set. An order can be reinstated by a subsequent `orderby` or `traverse` transformation or a `$orderby`.
+The transformations `ancestors` and `descendants` do not define an order on the output set. An order can be imposed by a subsequent `orderby` or `traverse` transformation or a `$orderby`. The output set of `traverse` is in preorder or postorder, and grouping with `rolluprecursive` orders its output set in analogy with [simple grouping](#SimpleGrouping).
The algorithmic descriptions of the transformations make use of a _union_ of collections, this is defined as an unordered collection containing the items from all these collections and from which duplicates have been removed.
@@ -356,21 +356,20 @@ _The `rolluprecursive` algorithm:_
A property $χ_N$ appears in the algorithm, but is not present in the output set. It is explained later (see [example ##rollupnode]). $Z_N$ is a transformation whose output set is its input set with property $χ_N$ removed.
-Let $x_1,…,x_n$ be the nodes in $H'$, possibly with repetitions. If the optional transformation sequence $S$ ends with a [`traverse`](#Transformationtraverse) transformation, as in [example ##weighted], the sequence $x_1,…,x_n$ MUST have the preorder or postorder established by that traversal, otherwise its order is arbitrary. Then the transformation ${\tt groupby}((P_1,{\tt rolluprecursive}(H,Q,p,S),P_2),T)$ is defined as equivalent to
-$${\tt concat}(R(x_1),…,R(x_n))$$
-with no order defined on the output set unless $S$ ends with a `traverse` transformation.
+Let $x_1,…,x_n$ be the nodes in $H'$, possibly with repetitions. If the optional transformation sequence $S$ ends with a [`traverse`](#Transformationtraverse) transformation, as in [example ##weighted], the sequence $x_1,…,x_n$ MUST have the preorder or postorder established by that traversal, and the transformation ${\tt groupby}((P_1,{\tt rolluprecursive}(H,Q,p,S),P_2),T)$ is defined as equivalent to
+$${\tt concat}(R(x_1),…,R(x_n)).$$
+
+Otherwise, if $S$ is not specified or does not end with a `traverse` transformation, the output set of the transformation ${\tt groupby}((P_1,{\tt rolluprecursive}(H,Q,p,S),P_2),T)$ is the concatenation of $R(x_1),…,R(x_n)$. The order of occurrences from the same $R(x_i)$ remains the same, and no order is defined between occurrences from different $R(x_i)$ and $R(x_j)$.
$R(x)$ is a transformation that processes the entire sub-hierarchy rooted at $x$, which is the output set of $F(x)$. The output set of $R(x)$ is a collection of aggregated instances for all rollup results.
If at least one of $P_1$ or $P_2$ is non-empty, then
-$$R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/{\tt groupby}((P_1,P_2),T/Z_N/\Pi_G(σ(x)))$$
-with no order defined on the output set.
+$$R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/{\tt groupby}((P_1,P_2),T/Z_N/\Pi_G(σ(x))).$$
The property $χ_N=x$ is present during the evaluation of $T$, but not afterwards. If $P_2$ contains a `rolluprecursive` operator, the evaluation of the formula involves a recursive invocation (with $N$ increased by 1) of the `rolluprecursive` algorithm.
Otherwise if $P_1$ and $P_2$ are empty, then
-$$R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/T/Z_N/\Pi_G(σ(x))$$
-with no order defined on the output set.
+$$R(x)=F(x)/{\tt compute}(x{\tt\ as\ }χ_N)/T/Z_N/\Pi_G(σ(x)).$$
$F(x)$ is defined as follows: If $p$ contains only single-valued segments, then
$$\matrix{
diff --git a/odata-data-aggregation-ext/8 Conformance.md b/odata-data-aggregation-ext/8 Conformance.md
index 6b0c094a..a0c256e6 100644
--- a/odata-data-aggregation-ext/8 Conformance.md
+++ b/odata-data-aggregation-ext/8 Conformance.md
@@ -118,7 +118,7 @@ Michael Pizzo
Martin Zurmuehl|
Added compute transformation
Minor clean-up
-Committee Specification Draft 04|$$$pubdateISO$$$|
+$$$subtitle$$$|$$$pubdateISO$$$|
Ralf Handl
Hubert Heijkers
Gerald Krause