Skip to content

Commit 75b7a34

Browse files
committed
fixes based on review
1 parent e700cbb commit 75b7a34

3 files changed

Lines changed: 34 additions & 2 deletions

File tree

core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/GroupIterator.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,10 @@ private void operate(BindingSet bs, Predicate<?> predicate, Object t) {
479479
return createNAryCustomAggregate(ge, operator, aggOperator, nAryFactory.get());
480480
}
481481
if (unaryFactory.isPresent()) {
482+
if (argumentCount != 1) {
483+
throw new QueryEvaluationException("Custom unary aggregate function '" + aggOperator.getIRI()
484+
+ "' expects exactly 1 argument, got " + argumentCount);
485+
}
482486
return createUnaryCustomAggregate(ge, operator, aggOperator, unaryFactory.get());
483487
}
484488

core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/GroupIteratorTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,29 @@ public void testCustomAggregateFunction_WrongIri() throws QueryEvaluationExcepti
274274
}
275275
}
276276

277+
@Test
278+
public void testCustomAggregateFunction_MultipleArgsRejected() throws QueryEvaluationException {
279+
BindingSetAssignment assignment = new BindingSetAssignment();
280+
var list = new ArrayList<BindingSet>();
281+
for (int i = 1; i < 10; i++) {
282+
var bindings = new QueryBindingSet();
283+
bindings.addBinding("a", VF.createLiteral(i));
284+
bindings.addBinding("b", VF.createLiteral(i * 2));
285+
list.add(bindings);
286+
}
287+
assignment.setBindingSets(Collections.unmodifiableList(list));
288+
289+
Group group = new Group(assignment);
290+
group.addGroupElement(new GroupElem("customSum",
291+
new AggregateFunctionCall(List.of(Var.of("a"), Var.of("b")), AGGREGATE_FUNCTION_FACTORY.getIri(),
292+
false)));
293+
try (GroupIterator gi = new GroupIterator(EVALUATOR, group, EmptyBindingSet.getInstance(), CONTEXT)) {
294+
assertThatExceptionOfType(QueryEvaluationException.class)
295+
.isThrownBy(() -> gi.next().getBinding("customSum").getValue())
296+
.withMessageContaining("expects exactly 1 argument");
297+
}
298+
}
299+
277300
@Test
278301
public void testCustomNAryAggregateFunction_Nonempty() throws QueryEvaluationException {
279302
AggregateNAryFunctionFactory nAryFactory = new FakeAggregateNAryFunctionFactory();

core/queryparser/sparql/src/main/java/org/eclipse/rdf4j/query/parser/sparql/aggregate/AggregateNAryFunction.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*
99
* SPDX-License-Identifier: BSD-3-Clause
1010
*******************************************************************************/
11+
// Some portions generated by Codex
1112
package org.eclipse.rdf4j.query.parser.sparql.aggregate;
1213

1314
import java.util.List;
@@ -40,9 +41,13 @@ protected AggregateNAryFunction(BiFunction<Integer, BindingSet, Value> evaluatio
4041
* Process an aggregate with tuple-level distinctness for n-ary functions.
4142
*
4243
* @param bindingSet the current binding set
43-
* @param distinctTuple predicate to check if the tuple of argument values is distinct. the tuple may contain
44+
* @param distinctTuple predicate to check if the tuple of argument values is distinct. The tuple may contain an
4445
* arbitrary amount of arguments, therefore if necessary single argument distinctness can be
45-
* checked inside the predicate. Mixing argument sizes of tuples is not recommended.
46+
* checked inside the predicate. Mixing argument sizes of tuples is not recommended. Note: do
47+
* not mutate (or reuse) a mutable {@link List} instance after passing it to
48+
* {@code distinctTuple.test(...)} because the predicate may keep it in a hash-based set. If
49+
* you construct tuples using a mutable list, pass an immutable snapshot (e.g.
50+
* {@code List.copyOf(tuple)}).
4651
* @param agv the aggregate collector
4752
* @throws QueryEvaluationException if evaluation fails
4853
*/

0 commit comments

Comments
 (0)