Skip to content

Commit 7034492

Browse files
authored
GH-5033: fix pushing of limits for simple ASK queries in FedX (#5034)
2 parents 414ad36 + 099646a commit 7034492

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

tools/federation/src/main/java/org/eclipse/rdf4j/federated/optimizer/LimitOptimizer.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,18 @@ public void meet(Slice node) throws OptimizationException {
6565
applicableLimitInScope = node.getLimit();
6666
}
6767
super.meet(node);
68+
69+
TupleExpr expr = node.getArg();
70+
// if the top most element is a statement (e.g. for an ASK query with single statement pattern),
71+
// i.e. no join, union or
72+
// any other complex pattern, we can push the limit
73+
// => this case typically represents a query with a single BGP
74+
if (expr instanceof FedXStatementPattern) {
75+
if (applicableLimitInScope > 0) {
76+
pushLimit((FedXStatementPattern) expr, applicableLimitInScope);
77+
}
78+
}
79+
6880
applicableLimitInScope = -1;
6981

7082
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 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+
package org.eclipse.rdf4j.federated;
12+
13+
import java.util.Arrays;
14+
15+
import org.eclipse.rdf4j.model.vocabulary.FOAF;
16+
import org.eclipse.rdf4j.query.QueryResults;
17+
import org.eclipse.rdf4j.query.TupleQuery;
18+
import org.eclipse.rdf4j.repository.Repository;
19+
import org.eclipse.rdf4j.repository.RepositoryConnection;
20+
import org.junit.jupiter.api.Assertions;
21+
import org.junit.jupiter.api.Test;
22+
23+
public class LimitTests extends SPARQLBaseTest {
24+
25+
@Test
26+
public void testLimitPushing_Select_SingleStatement() throws Exception {
27+
28+
// datsets contain both instances of foaf:Person
29+
prepareTest(
30+
Arrays.asList("/tests/data/data1.ttl", "/tests/data/data2.ttl"));
31+
32+
Repository fedxRepo = fedxRule.getRepository();
33+
34+
try (RepositoryConnection conn = fedxRepo.getConnection()) {
35+
36+
String query = "SELECT * WHERE { ?person a <" + FOAF.PERSON.stringValue() + "> } LIMIT 2";
37+
TupleQuery tq = conn.prepareTupleQuery(query);
38+
Assertions.assertEquals(2, QueryResults.asList(tq.evaluate()).size());
39+
40+
// check that the query plan contains information about limit
41+
String queryPlan = fedxRule.getFederationContext().getQueryManager().getQueryPlan(query);
42+
Assertions.assertTrue(queryPlan.contains("Upper Limit: 2"));
43+
}
44+
}
45+
46+
@Test
47+
public void testLimitPushing_Ask_SingleStatement() throws Exception {
48+
49+
// datsets contain both instances of foaf:Person
50+
prepareTest(
51+
Arrays.asList("/tests/data/data1.ttl", "/tests/data/data2.ttl"));
52+
53+
Repository fedxRepo = fedxRule.getRepository();
54+
55+
try (RepositoryConnection conn = fedxRepo.getConnection()) {
56+
57+
String query = "ASK { ?person a <" + FOAF.PERSON.stringValue() + "> }";
58+
Assertions.assertTrue(conn.prepareBooleanQuery(query).evaluate());
59+
60+
// check that the query plan contains information about limit
61+
String queryPlan = fedxRule.getFederationContext().getQueryManager().getQueryPlan(query);
62+
Assertions.assertTrue(queryPlan.contains("Upper Limit: 1"));
63+
64+
// also run a query with no backing data
65+
query = "ASK { ?organization a <" + FOAF.ORGANIZATION.stringValue() + "> }";
66+
Assertions.assertFalse(conn.prepareBooleanQuery(query).evaluate());
67+
}
68+
}
69+
}

0 commit comments

Comments
 (0)