Skip to content

Commit ca9b892

Browse files
authored
Merge pull request github#3143 from ginsbach/the
Uniqueness aggregate in handbook and reference
2 parents 7b7ff1f + a91a5c3 commit ca9b892

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

docs/language/ql-handbook/expressions.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,22 @@ The following aggregates are available in QL:
296296
evaluates to the empty set (instead of defaulting to ``0`` or the empty string).
297297
This is useful if you're only interested in results where the aggregation body is non-trivial.
298298

299+
.. index:: unique
300+
301+
- ``unique``: This aggregate depends on the values of ``<expression>`` over all possible assignments to
302+
the aggregation variables. If there is a unique value of ``<expression>`` over the aggregation variables,
303+
then the aggregate evaluates to that value.
304+
Otherwise, the aggregate has no value.
305+
306+
For example, the following query returns the positive integers ``1``, ``2``, ``3``, ``4``, ``5``.
307+
For negative integers ``x``, the expressions ``x`` and ``x.abs()`` have different values, so the
308+
value for ``y`` in the aggregate expression is not uniquely determined. ::
309+
310+
from int x
311+
where x in [-5 .. 5] and x != 0
312+
select unique(int y | y = x or y = x.abs() | y)
313+
314+
The ``unique`` aggregate is supported from release 2.1.0 of the CodeQL CLI, and release 1.24 of LGTM Enterprise.
299315

300316
Evaluation of aggregates
301317
========================

docs/language/ql-spec/language.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,7 @@ An aggregation can be written in one of two forms:
10581058

10591059
aggregation ::= aggid ("[" expr "]")? "(" (var_decls)? ("|" (formula)? ("|" as_exprs ("order" "by" aggorderbys)?)?)? ")"
10601060
| aggid ("[" expr "]")? "(" as_exprs ("order" "by" aggorderbys)? ")"
1061+
| "unique" "(" var_decls "|" (formula)? ("|" as_exprs)? ")"
10611062

10621063
aggid ::= "avg" | "concat" | "count" | "max" | "min" | "rank" | "strictconcat" | "strictcount" | "strictsum" | "sum"
10631064

@@ -1098,7 +1099,7 @@ The typing environment for ordering directives is obtained by taking the typing
10981099

10991100
The number and types of the aggregation expressions are restricted as follows:
11001101

1101-
- A ``max``, ``min`` or ``rank`` aggregation must have a single expression.
1102+
- A ``max``, ``min``, ``rank`` or ``unique`` aggregation must have a single expression.
11021103
- The type of the expression in a ``max``, ``min`` or ``rank`` aggregation without an ordering directive expression must be an orderable type.
11031104
- A ``count`` or ``strictcount`` aggregation must not have an expression.
11041105
- A ``sum``, ``strictsum`` or ``avg`` aggregation must have a single aggregation expression, which must have a type which is a subtype of ``float``.
@@ -1140,6 +1141,8 @@ The values of the aggregation expression are given by applying the aggregation f
11401141

11411142
- If the aggregation id is ``strictconcat``, then the result is the same as for ``concat`` except in the case where there are no aggregation tuples in which case the aggregation has no value.
11421143

1144+
- If the aggregation id is ``unique``, then the result is the value of the aggregation variable if there is precisely one such value. Otherwise, the aggregation has no value.
1145+
11431146
Any
11441147
~~~
11451148

@@ -1976,7 +1979,8 @@ The complete grammar for QL is as follows:
19761979

19771980
aggregation ::= aggid ("[" expr "]")? "(" (var_decls)? ("|" (formula)? ("|" as_exprs ("order" "by" aggorderbys)?)?)? ")"
19781981
| aggid ("[" expr "]")? "(" as_exprs ("order" "by" aggorderbys)? ")"
1979-
1982+
| "unique" "(" var_decls "|" (formula)? ("|" as_exprs)? ")"
1983+
19801984
aggid ::= "avg" | "concat" | "count" | "max" | "min" | "rank" | "strictconcat" | "strictcount" | "strictsum" | "sum"
19811985

19821986
aggorderbys ::= aggorderby ("," aggorderby)*

0 commit comments

Comments
 (0)