Skip to content

Commit 4d903e4

Browse files
committed
GH-4990: adjust cloning for context var + unit test coverage
Mage sure to have null-safe clone also for the context variable. Covered the finding with a unit test
1 parent a173941 commit 4d903e4

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

tools/federation/src/main/java/org/eclipse/rdf4j/federated/evaluation/FederationEvalStrategy.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ protected Set<Endpoint> performSourceSelection(FedXArbitraryLengthPath pathExpr,
333333
identifiedMembers = new HashSet<>(members);
334334
} else {
335335
StatementPattern checkStmt = new StatementPattern(stmt.getScope(), new Var("subject"),
336-
stmt.getPredicateVar().clone(), new Var("object"), stmt.getContextVar());
336+
clone(stmt.getPredicateVar()), new Var("object"), clone(stmt.getContextVar()));
337337
@SuppressWarnings("unused") // only used as artificial parent
338338
HolderNode holderParent = new HolderNode(checkStmt);
339339

@@ -364,6 +364,13 @@ protected Set<Endpoint> performSourceSelection(FedXArbitraryLengthPath pathExpr,
364364
return identifiedMembers;
365365
}
366366

367+
private Var clone(Var var) {
368+
if (var == null) {
369+
return null;
370+
}
371+
return var.clone();
372+
}
373+
367374
protected void optimizeJoinOrder(TupleExpr query, QueryInfo queryInfo, GenericInfoOptimizer info) {
368375
// optimize statement groups and join order
369376
new StatementGroupAndJoinOptimizer(queryInfo, DefaultFedXCostModel.INSTANCE).optimize(query);

tools/federation/src/test/java/org/eclipse/rdf4j/federated/PropertyPathTests.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,4 +301,52 @@ public void testZeroLengthPath_length2_crossRepository() throws Exception {
301301

302302
}
303303

304+
@Test
305+
public void testPropertyPath_sourceSelection_crossRepository() throws Exception {
306+
307+
prepareTest(Arrays.asList("/tests/basic/data_emptyStore.ttl", "/tests/basic/data_emptyStore.ttl"));
308+
309+
Repository repo1 = getRepository(1);
310+
Repository repo2 = getRepository(2);
311+
312+
try (RepositoryConnection con = repo1.getConnection()) {
313+
con.add(Values.iri("http://example.org/A"), RDFS.SUBCLASSOF, Values.iri("http://example.org/B"),
314+
Values.iri("http://example.org/graph1"));
315+
}
316+
317+
try (RepositoryConnection con = repo2.getConnection()) {
318+
con.add(Values.iri("http://example.org/B"), RDFS.SUBCLASSOF, Values.iri("http://example.org/C"),
319+
Values.iri("http://example.org/graph2"));
320+
}
321+
322+
Repository fedxRepo = fedxRule.getRepository();
323+
324+
// 1a: bound (matching) object
325+
try (RepositoryConnection con = fedxRepo.getConnection()) {
326+
TupleQuery tupleQuery = con.prepareTupleQuery(
327+
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> "
328+
+ "SELECT * WHERE { "
329+
+ " ?subClass (rdfs:subClassOf+) <http://example.org/C> . "
330+
+ " } "
331+
);
332+
333+
Assertions.assertEquals(2, QueryResults.asSet(tupleQuery.evaluate()).size());
334+
}
335+
336+
// 1b: with named graph
337+
try (RepositoryConnection con = fedxRepo.getConnection()) {
338+
TupleQuery tupleQuery = con.prepareTupleQuery(
339+
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> "
340+
+ "SELECT * WHERE { "
341+
+ " GRAPH <http://example.org/graph2> {"
342+
+ " ?subClass (rdfs:subClassOf+) <http://example.org/C> . "
343+
+ " }"
344+
+ "} "
345+
);
346+
347+
Assertions.assertEquals(1, QueryResults.asSet(tupleQuery.evaluate()).size());
348+
}
349+
350+
}
351+
304352
}

0 commit comments

Comments
 (0)