Skip to content

Commit 1c82151

Browse files
committed
add failing test
1 parent 9e92234 commit 1c82151

1 file changed

Lines changed: 130 additions & 0 deletions

File tree

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 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+
12+
package org.eclipse.rdf4j.sail.memory;
13+
14+
import static org.junit.jupiter.api.Assertions.assertEquals;
15+
16+
import java.io.IOException;
17+
import java.io.StringReader;
18+
import java.util.Arrays;
19+
import java.util.LinkedHashSet;
20+
import java.util.List;
21+
import java.util.Objects;
22+
import java.util.Set;
23+
import java.util.stream.Collectors;
24+
25+
import org.eclipse.rdf4j.model.IRI;
26+
import org.eclipse.rdf4j.model.Value;
27+
import org.eclipse.rdf4j.query.BindingSet;
28+
import org.eclipse.rdf4j.query.QueryResults;
29+
import org.eclipse.rdf4j.query.TupleQuery;
30+
import org.eclipse.rdf4j.query.TupleQueryResult;
31+
import org.eclipse.rdf4j.repository.RepositoryConnection;
32+
import org.eclipse.rdf4j.repository.sail.SailRepository;
33+
import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection;
34+
import org.eclipse.rdf4j.rio.RDFFormat;
35+
import org.junit.jupiter.api.AfterEach;
36+
import org.junit.jupiter.api.BeforeEach;
37+
import org.junit.jupiter.api.Test;
38+
39+
/**
40+
* Local duplicates of selected {@link org.eclipse.rdf4j.testsuite.sparql.tests.SparqlMinusScopingTests} cases to ease
41+
* debugging against a concrete {@link MemoryStore} repository.
42+
*/
43+
public class MemoryStoreMinusScopingDebugTest {
44+
45+
private static final String PREFIX = "PREFIX : <http://ex/>\n";
46+
private static final String DATA_BASE_IRI = "http://ex/";
47+
48+
private SailRepository repository;
49+
50+
@BeforeEach
51+
public void setUp() {
52+
repository = new SailRepository(new MemoryStore());
53+
repository.init();
54+
}
55+
56+
@AfterEach
57+
public void tearDown() {
58+
if (repository != null) {
59+
repository.shutDown();
60+
}
61+
}
62+
63+
@Test
64+
public void T16_rhs_bind_of_outer_var_produces_unbound_then_overremoves_on_shared_subset() throws IOException {
65+
String ttl = "@prefix : <http://ex/> .\n" +
66+
":a :p 1 ; :q 1, 2 .\n" +
67+
":b :p 3 ; :q 4 .\n" +
68+
":c :p 7 .";
69+
70+
try (SailRepositoryConnection conn = repository.getConnection()) {
71+
List<BindingSet> rows = selectWithData(conn, ttl, RDFFormat.TURTLE,
72+
"SELECT ?x WHERE {\n" +
73+
" ?x :p ?n .\n" +
74+
" MINUS { BIND(?n AS ?k) ?x :q ?k }\n" +
75+
"} ORDER BY ?x");
76+
77+
assertEquals(setOf("c"), names(rows, "x"),
78+
"RHS BIND on unbound outer var must not correlate; shared-vars logic should remove :a,:b only.");
79+
}
80+
}
81+
82+
@Test
83+
public void T21_not_exists_over_optional_is_always_false_here() throws IOException {
84+
String ttl = "@prefix : <http://ex/> .\n" +
85+
":e :name \"Alice\" ; :formerName \"Alice\" .\n" +
86+
":f :name \"Carol\" .";
87+
88+
try (SailRepositoryConnection conn = repository.getConnection()) {
89+
List<BindingSet> rows = selectWithData(conn, ttl, RDFFormat.TURTLE,
90+
"SELECT ?x WHERE {\n" +
91+
" ?x :name ?n .\n" +
92+
" FILTER NOT EXISTS { OPTIONAL { ?x :formerName ?n } }\n" +
93+
"}");
94+
95+
assertEquals(List.of(), rows);
96+
}
97+
}
98+
99+
private List<BindingSet> selectWithData(RepositoryConnection conn, String data, RDFFormat format, String body)
100+
throws IOException {
101+
String sparql = PREFIX + body;
102+
103+
conn.clear();
104+
conn.add(new StringReader(data), DATA_BASE_IRI, format);
105+
106+
TupleQuery query = conn.prepareTupleQuery(sparql);
107+
try (TupleQueryResult result = query.evaluate()) {
108+
return QueryResults.asList(result);
109+
}
110+
}
111+
112+
private static Set<String> names(List<BindingSet> rows, String var) {
113+
return rows.stream()
114+
.map(bs -> bs.getValue(var))
115+
.filter(Objects::nonNull)
116+
.map(MemoryStoreMinusScopingDebugTest::name)
117+
.collect(Collectors.toCollection(LinkedHashSet::new));
118+
}
119+
120+
private static String name(Value value) {
121+
if (value instanceof IRI) {
122+
return ((IRI) value).getLocalName();
123+
}
124+
return value.stringValue();
125+
}
126+
127+
private static Set<String> setOf(String... values) {
128+
return new LinkedHashSet<>(Arrays.asList(values));
129+
}
130+
}

0 commit comments

Comments
 (0)