Skip to content

Commit 0964238

Browse files
committed
bug fix
1 parent 54bb50a commit 0964238

2 files changed

Lines changed: 119 additions & 10 deletions

File tree

core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/StatementPatternQueryEvaluationStep.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -531,18 +531,20 @@ private DirectLookupResult cacheDirectLookupIfSmall(DirectLookupKey directLookup
531531
return new DirectLookupResult(iteration, -1);
532532
}
533533

534-
List<Statement> statements = new ArrayList<>(DIRECT_LOOKUP_CACHE_MAX_STATEMENTS);
535-
while (iteration.hasNext()) {
536-
if (statements.size() == DIRECT_LOOKUP_CACHE_MAX_STATEMENTS) {
537-
iteration.close();
538-
return new DirectLookupResult(reopenUncachedIteration(subject, predicate, object, contexts), -1);
534+
try (iteration) {
535+
List<Statement> statements = new ArrayList<>(DIRECT_LOOKUP_CACHE_MAX_STATEMENTS);
536+
while (iteration.hasNext()) {
537+
if (statements.size() == DIRECT_LOOKUP_CACHE_MAX_STATEMENTS) {
538+
return new DirectLookupResult(reopenUncachedIteration(subject, predicate, object, contexts), -1);
539+
}
540+
statements.add(iteration.next());
539541
}
540-
statements.add(iteration.next());
541-
}
542542

543-
statements = List.copyOf(statements);
544-
putCachedDirectLookup(directLookupKey, DirectLookupCacheEntry.statements(statements));
545-
return new DirectLookupResult(new CloseableIteratorIteration<>(statements.iterator()), statements.size());
543+
statements = List.copyOf(statements);
544+
545+
putCachedDirectLookup(directLookupKey, DirectLookupCacheEntry.statements(statements));
546+
return new DirectLookupResult(new CloseableIteratorIteration<>(statements.iterator()), statements.size());
547+
}
546548
}
547549

548550
private CloseableIteration<? extends Statement> reopenUncachedIteration(Resource subject, IRI predicate,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Eclipse RDF4J contributors.
3+
*
4+
* All rights reserved. This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Distribution License v1.0
6+
* which accompanies this distribution, and is available at
7+
* http://www.eclipse.org/org/documents/edl-v10.php.
8+
*
9+
* SPDX-License-Identifier: BSD-3-Clause
10+
*******************************************************************************/
11+
// Some portions generated by Codex
12+
package org.eclipse.rdf4j.query.algebra.evaluation.impl.evaluationsteps;
13+
14+
import static org.assertj.core.api.Assertions.assertThat;
15+
16+
import java.util.Iterator;
17+
import java.util.List;
18+
19+
import org.eclipse.rdf4j.common.iteration.AbstractCloseableIteration;
20+
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
21+
import org.eclipse.rdf4j.model.IRI;
22+
import org.eclipse.rdf4j.model.Resource;
23+
import org.eclipse.rdf4j.model.Statement;
24+
import org.eclipse.rdf4j.model.Value;
25+
import org.eclipse.rdf4j.model.ValueFactory;
26+
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
27+
import org.eclipse.rdf4j.query.BindingSet;
28+
import org.eclipse.rdf4j.query.Dataset;
29+
import org.eclipse.rdf4j.query.MutableBindingSet;
30+
import org.eclipse.rdf4j.query.QueryEvaluationException;
31+
import org.eclipse.rdf4j.query.algebra.StatementPattern;
32+
import org.eclipse.rdf4j.query.algebra.Var;
33+
import org.eclipse.rdf4j.query.algebra.evaluation.TripleSource;
34+
import org.eclipse.rdf4j.query.algebra.evaluation.impl.QueryEvaluationContext;
35+
import org.junit.jupiter.api.Test;
36+
37+
class StatementPatternQueryEvaluationStepDirectLookupCacheTest {
38+
39+
@Test
40+
void cachedFullyBoundEvaluateClosesDrainedSourceIteration() {
41+
QueryEvaluationContext context = new QueryEvaluationContext.Minimal((Dataset) null);
42+
TrackingFullyBoundTripleSource tripleSource = new TrackingFullyBoundTripleSource();
43+
StatementPattern statementPattern = new StatementPattern(new Var("s"), new Var("p"), new Var("o"));
44+
StatementPatternQueryEvaluationStep evaluationStep = new StatementPatternQueryEvaluationStep(
45+
statementPattern,
46+
context,
47+
tripleSource);
48+
49+
MutableBindingSet bindings = context.createBindingSet();
50+
bindings.addBinding("s", tripleSource.statement.getSubject());
51+
bindings.addBinding("p", tripleSource.statement.getPredicate());
52+
bindings.addBinding("o", tripleSource.statement.getObject());
53+
54+
try (CloseableIteration<BindingSet> iteration = evaluationStep.evaluate(bindings)) {
55+
assertThat(iteration.hasNext()).isTrue();
56+
assertThat(iteration.next()).isSameAs(bindings);
57+
assertThat(iteration.hasNext()).isFalse();
58+
}
59+
60+
assertThat(tripleSource.lastIteration.isClosed()).isTrue();
61+
}
62+
63+
private static final class TrackingFullyBoundTripleSource implements TripleSource {
64+
65+
private final ValueFactory valueFactory = SimpleValueFactory.getInstance();
66+
private final Statement statement = valueFactory.createStatement(
67+
valueFactory.createIRI("urn:subj"),
68+
valueFactory.createIRI("urn:pred"),
69+
valueFactory.createLiteral("obj"));
70+
private TrackingStatementIteration lastIteration;
71+
72+
@Override
73+
public CloseableIteration<? extends Statement> getStatements(Resource subj, IRI pred, Value obj,
74+
Resource... contexts) throws QueryEvaluationException {
75+
lastIteration = new TrackingStatementIteration(List.of(statement));
76+
return lastIteration;
77+
}
78+
79+
@Override
80+
public ValueFactory getValueFactory() {
81+
return valueFactory;
82+
}
83+
}
84+
85+
private static final class TrackingStatementIteration extends AbstractCloseableIteration<Statement> {
86+
87+
private final Iterator<Statement> iterator;
88+
89+
private TrackingStatementIteration(List<Statement> statements) {
90+
iterator = statements.iterator();
91+
}
92+
93+
@Override
94+
public boolean hasNext() {
95+
return iterator.hasNext();
96+
}
97+
98+
@Override
99+
public Statement next() {
100+
return iterator.next();
101+
}
102+
103+
@Override
104+
protected void handleClose() {
105+
}
106+
}
107+
}

0 commit comments

Comments
 (0)